Skip to content

Commit

Permalink
feat: complete implementing remove mint from group
Browse files Browse the repository at this point in the history
  • Loading branch information
sunguru98 committed May 19, 2024
1 parent 753d118 commit cc42ff6
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 7 deletions.
2 changes: 2 additions & 0 deletions programs/wen_new_standard/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,6 @@ pub enum MintErrors {
InvalidFreezeAuthority,
#[msg("Invalid delegate authority.")]
InvalidDelegateAuthority,
#[msg("Invalid Token group member mint")]
InvalidTokenGroupMemberMint,
}
4 changes: 3 additions & 1 deletion programs/wen_new_standard/src/instructions/mint/group/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use anchor_spl::token_interface::{
};

use crate::{
get_bump_in_seed_form, Manager, TokenGroup, TokenGroupMember, MANAGER_SEED,
get_bump_in_seed_form, Manager, TokenGroup, TokenGroupMember, GROUP_ACCOUNT_SEED, MANAGER_SEED,
MEMBER_ACCOUNT_SEED, TOKEN22,
};

Expand All @@ -19,6 +19,8 @@ pub struct AddGroup<'info> {
#[account(
mut,
constraint = group.update_authority == authority.key(),
seeds = [GROUP_ACCOUNT_SEED, group.mint.as_ref()],
bump,
)]
pub group: Account<'info, TokenGroup>,
#[account(
Expand Down
2 changes: 2 additions & 0 deletions programs/wen_new_standard/src/instructions/mint/group/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
pub mod add;
pub mod remove;

pub use add::*;
pub use remove::*;
77 changes: 77 additions & 0 deletions programs/wen_new_standard/src/instructions/mint/group/remove.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use anchor_lang::prelude::*;

use anchor_spl::token_interface::{
group_member_pointer_update, GroupMemberPointerUpdate, Mint, Token2022,
};

use crate::{
get_bump_in_seed_form, Manager, MintErrors, TokenGroup, TokenGroupMember, GROUP_ACCOUNT_SEED,
MANAGER_SEED, MEMBER_ACCOUNT_SEED, TOKEN22,
};

#[derive(Accounts)]
#[instruction()]
pub struct RemoveGroup<'info> {
#[account(mut)]
pub payer: Signer<'info>,
#[account()]
pub authority: Signer<'info>,
#[account(
mut,
constraint = group.update_authority == authority.key(),
seeds = [GROUP_ACCOUNT_SEED, group.mint.as_ref()],
bump,
)]
pub group: Account<'info, TokenGroup>,
#[account(
mut,
has_one = mint @ MintErrors::InvalidTokenGroupMemberMint,
seeds = [MEMBER_ACCOUNT_SEED, mint.key().as_ref()],
bump,
)]
pub member: Account<'info, TokenGroupMember>,
#[account(
mut,
mint::token_program = TOKEN22
)]
pub mint: Box<InterfaceAccount<'info, Mint>>,
#[account(
seeds = [MANAGER_SEED],
bump
)]
pub manager: Box<Account<'info, Manager>>,
pub system_program: Program<'info, System>,
pub token_program: Program<'info, Token2022>,
}

impl RemoveGroup<'_> {
fn update_group_member_pointer_member_address(&self, signer_seeds: &[&[&[u8]]]) -> Result<()> {
let cpi_accounts = GroupMemberPointerUpdate {
token_program_id: self.token_program.to_account_info(),
mint: self.mint.to_account_info(),
authority: self.manager.to_account_info(),
};
let cpi_ctx = CpiContext::new_with_signer(
self.token_program.to_account_info(),
cpi_accounts,
signer_seeds,
);
group_member_pointer_update(cpi_ctx, None)?;
Ok(())
}
}

pub fn handler(ctx: Context<RemoveGroup>) -> Result<()> {
let group = &mut ctx.accounts.group;
group.decrement_size()?;

let member = &mut ctx.accounts.member;
member.close(ctx.accounts.payer.to_account_info())?;

let signer_seeds = &[MANAGER_SEED, &get_bump_in_seed_form(&ctx.bumps.manager)];

ctx.accounts
.update_group_member_pointer_member_address(&[&signer_seeds[..]])?;

Ok(())
}
5 changes: 5 additions & 0 deletions programs/wen_new_standard/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ pub mod wen_new_standard {
instructions::mint::group::add::handler(ctx)
}

/// remove mint from group
pub fn remove_mint_from_group(ctx: Context<RemoveGroup>) -> Result<()> {
instructions::mint::group::remove::handler(ctx)
}

/// add royalties to mint
pub fn add_royalties(ctx: Context<AddRoyalties>, args: UpdateRoyaltiesArgs) -> Result<()> {
instructions::mint::royalties::add::handler(ctx, args)
Expand Down
51 changes: 45 additions & 6 deletions tests/wen_new_standard.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,9 @@ describe("wen_new_standard", () => {
const groupMintKeyPair = Keypair.generate();
const groupMintPublicKey = groupMintKeyPair.publicKey;

const mintKeyPair = Keypair.generate();
const mintPublicKey = mintKeyPair.publicKey;

const [group] = PublicKey.findProgramAddressSync(
[GROUP_ACCOUNT_SEED, groupMintPublicKey.toBuffer()],
program.programId
Expand Down Expand Up @@ -700,10 +703,7 @@ describe("wen_new_standard", () => {
});

describe("after adding a mint as a member", () => {
const mintKeyPair = Keypair.generate();

const mintAuthPublicKey = wallet.publicKey;
const mintPublicKey = mintKeyPair.publicKey;
const mintTokenAccount = getAssociatedTokenAddressSync(
mintPublicKey,
mintAuthPublicKey,
Expand Down Expand Up @@ -876,13 +876,52 @@ describe("wen_new_standard", () => {
});
});

describe.skip("after removing mint as a member", () => {
describe("after removing mint as a member", () => {
const mintAuthPublicKey = wallet.publicKey;
const [member] = PublicKey.findProgramAddressSync(
[MEMBER_ACCOUNT_SEED, mintPublicKey.toBuffer()],
program.programId
);

let memberAccountInfo: AccountInfo<Buffer>;
describe("the mint", () => {
it.skip("should not point back to the group", async () => {});
before(async () => {
await program.methods
.removeMintFromGroup()
.accountsStrict({
authority: groupAuthorityPublicKey,
group,
mint: mintPublicKey,
payer: mintAuthPublicKey,
manager,
member,
systemProgram: SystemProgram.programId,
tokenProgram: TOKEN_2022_PROGRAM_ID,
})
.signers([groupAuthorityKeyPair])
.rpc({
skipPreflight: true,
preflightCommitment: "confirmed",
commitment: "confirmed",
});

memberAccountInfo = await program.account.tokenGroupMember.getAccountInfo(
member
);
});
it("should not point back to the group", async () => {
expect(memberAccountInfo).to.be.null;
});
});

describe("the group", () => {
it.skip("should have a size of 0", async () => {});
let groupAccount;
before(async () => {
groupAccount = await program.account.tokenGroup.fetch(group, "confirmed");
});
it("should be a size of 0", async () => {
expect(groupAccount.size).to.eql(0);
});
});
});
});
Expand Down

0 comments on commit cc42ff6

Please sign in to comment.