Skip to content

Commit

Permalink
transfer-switch/anchor - x metas for every mint fix
Browse files Browse the repository at this point in the history
  • Loading branch information
thewuhxyz committed Nov 1, 2024
1 parent 3ce2dd9 commit 1952504
Show file tree
Hide file tree
Showing 10 changed files with 246 additions and 204 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
"@solana/spl-token": "^0.4.0"
},
"devDependencies": {
"anchor-bankrun": "^0.4.0",
"solana-bankrun": "^0.3.0",
"anchor-bankrun": "^0.5.0",
"solana-bankrun": "^0.4.0",
"@types/bn.js": "^5.1.0",
"@types/chai": "^4.3.0",
"@types/mocha": "^9.0.0",
"@types/mocha": "10.0.9",
"chai": "^4.3.4",
"mocha": "^9.0.3",
"mocha": "^10.8.2",
"prettier": "^2.6.2",
"ts-mocha": "^10.0.0",
"typescript": "^4.3.5"
"typescript": "^5"
}
}
248 changes: 95 additions & 153 deletions tokens/token-2022/transfer-hook/transfer-switch/anchor/pnpm-lock.yaml

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use {crate::state::AdminConfig, anchor_lang::prelude::*};

#[derive(Accounts)]
pub struct ConfigureAdmin<'info> {
#[account(mut)]
pub admin: Signer<'info>,

/// CHECK: the new admin
#[account(mut)]
pub new_admin: UncheckedAccount<'info>,

/// To hold the address of the admin that controls switches
#[account(
init_if_needed,
payer=admin,
space=8+AdminConfig::INIT_SPACE,
seeds=[b"admin-config"],
bump
)]
pub admin_config: Account<'info, AdminConfig>,

pub system_program: Program<'info, System>,
}

impl<'info> ConfigureAdmin<'info> {
pub fn is_admin(&self) -> Result<()> {
// check if we are not creating the account for the first time,
// ensure it's the admin that is making the change
//
if self.admin_config.is_initialised {
// make sure it's the admin
//
require_keys_eq!(self.admin.key(), self.admin_config.admin,);

// make sure the admin is not reentering their key
//
require_keys_neq!(self.admin.key(), self.new_admin.key());
}
Ok(())
}

pub fn configure_admin(&mut self) -> Result<()> {
self.admin_config.set_inner(AdminConfig {
admin: self.new_admin.key(), // set the admin pubkey that can switch transfers on/off
is_initialised: true, // let us know an admin has been set
});
Ok(())
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use {
crate::state::AdminConfig,
anchor_lang::{
prelude::*,
system_program::{create_account, CreateAccount},
Expand All @@ -12,24 +11,13 @@ use {
};

#[derive(Accounts)]
// #[instruction(decimals: u8)]
pub struct InitializeExtraAccountMetas<'info> {
#[account(mut)]
pub admin: Signer<'info>,
pub payer: Signer<'info>,

#[account()]
pub token_mint: InterfaceAccount<'info, Mint>,

/// CHECK: this account we use to take note of listings
#[account(
init,
payer=admin,
space=8+AdminConfig::INIT_SPACE,
seeds=[b"admin-config"],
bump
)]
pub admin_config: Account<'info, AdminConfig>,

/// CHECK: extra accoumt metas list
#[account(
mut,
Expand All @@ -42,19 +30,12 @@ pub struct InitializeExtraAccountMetas<'info> {
}

impl<'info> InitializeExtraAccountMetas<'info> {
pub fn init_admin_config(&mut self) -> Result<()> {
self.admin_config.set_inner(AdminConfig {
admin: self.admin.key(), // set the admin pubkey that can switch transfers on/off
});
Ok(())
}

pub fn initialize_extra_account_metas_list(
&self,
bumps: InitializeExtraAccountMetasBumps,
) -> Result<()> {
let account_metas = vec![
// 5 - user (sender) config account
// 5 - wallet (sender) config account
ExtraAccountMeta::new_with_seeds(
&[
Seed::AccountKey { index: 3 }, // sender index
Expand All @@ -81,7 +62,7 @@ impl<'info> InitializeExtraAccountMetas<'info> {
CpiContext::new(
self.system_program.to_account_info(),
CreateAccount {
from: self.admin.to_account_info(),
from: self.payer.to_account_info(),
to: self.extra_account_metas_list.to_account_info(),
},
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
pub mod initialise_extra_account_metas_list;
pub mod switch;
pub mod transfer_hook;
pub mod configure_admin;

pub use initialise_extra_account_metas_list::*;
pub use switch::*;
pub use transfer_hook::*;
pub use configure_admin::*;
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,43 @@ use {
#[derive(Accounts)]
#[instruction(decimals: u8)]
pub struct Switch<'info> {
/// admin that controls the switch
#[account(mut)]
pub admin: Signer<'info>,

/// CHECK: sender
/// CHECK: wallet - transfer sender
#[account(mut)]
pub user: UncheckedAccount<'info>,
pub wallet: UncheckedAccount<'info>,

/// CHECK: this account we use to take note of listings
/// admin config
#[account(
has_one=admin,
seeds=[b"admin-config"],
bump,
)]
pub admin_config: Account<'info, AdminConfig>,

/// CHECK: this account we use to take note of listings
/// the wallet (sender) transfer switch
#[account(
init_if_needed,
payer=admin,
space=8+TransferSwitch::INIT_SPACE,
seeds=[user.key().as_ref()],
seeds=[wallet.key().as_ref()],
bump,
)]
pub user_switch: Account<'info, TransferSwitch>,
pub wallet_switch: Account<'info, TransferSwitch>,

pub system_program: Program<'info, System>,
}

impl<'info> Switch<'info> {
pub fn switch(&mut self, on: bool) -> Result<()> {
self.user_switch.set_inner(TransferSwitch { on });
// toggle switch on/off for the given wallet
//
self.wallet_switch.set_inner(TransferSwitch {
wallet: self.wallet.key(),
on,
});
Ok(())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub struct TransferHook<'info> {

/// CHECK: the transfer sender
#[account()]
pub sender: UncheckedAccount<'info>,
pub wallet: UncheckedAccount<'info>,

/// CHECK: extra account metas
#[account(
Expand All @@ -39,17 +39,17 @@ pub struct TransferHook<'info> {
)]
pub extra_account_metas_list: UncheckedAccount<'info>,

/// sender transfer switch account
/// sender transfer switch
#[account(
seeds=[sender.key().as_ref()],
seeds=[wallet.key().as_ref()],
bump,
)]
pub sender_switch: Account<'info, TransferSwitch>,
pub wallet_switch: Account<'info, TransferSwitch>,
}

impl<'info> TransferHook<'info> {
pub fn assert_switch_is_on(&mut self) -> Result<()> {
if !self.sender_switch.on {
if !self.wallet_switch.on {
return err!(TransferError::SwitchNotOn);
}
Ok(())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ declare_id!("FjcHckEgXcBhFmSGai3FRpDLiT6hbpV893n8iTxVd81g");
pub mod transfer_switch {
use super::*;

pub fn configure_admin(ctx: Context<ConfigureAdmin>) -> Result<()> {
ctx.accounts.is_admin()?;
ctx.accounts.configure_admin()
}

#[interface(spl_transfer_hook_interface::initialize_extra_account_meta_list)]
pub fn create(ctx: Context<InitializeExtraAccountMetas>) -> Result<()> {
ctx.accounts
.initialize_extra_account_metas_list(ctx.bumps)?;
ctx.accounts.init_admin_config()?;
Ok(())
pub fn initialize_extra_account_metas_list(ctx: Context<InitializeExtraAccountMetas>) -> Result<()> {
ctx.accounts.initialize_extra_account_metas_list(ctx.bumps)
}

pub fn switch(ctx: Context<Switch>, on: bool) -> Result<()> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ use anchor_lang::prelude::*;
#[account]
#[derive(InitSpace)]
pub struct TransferSwitch {
pub wallet: Pubkey,
pub on: bool,
}

#[account]
#[derive(InitSpace)]
pub struct AdminConfig {
pub is_initialised: bool,
pub admin: Pubkey,
}
Loading

0 comments on commit 1952504

Please sign in to comment.