I'm using anchor to write a program that implements the transfer hook interface. One of the extra accounts is an "Authority" owned by the same program with a PDA derived from [b"authority", &seed.key().as_ref()]
. The "seed" Pubkey is stored on the "Authority" account itself.
Is it possible to construct a seed from AccountData of an Account that is NOT part of the transfer and is ONLY in the CPI?
The following code results in an AccountNotFound error during the account resolution checks.
#[account]
pub struct Authority {
pub admin: Pubkey,
pub seed: Pubkey,
pub bump: u8,
}
The ExtraAccountMetaList
is initialized with:
let metas = vec![
ExtraAccountMeta::new_with_seeds(
&[
Seed::Literal {
bytes: b"authority".to_vec(),
},
Seed::AccountData {
account_index: 5, // Index of account in ExecuteTransferHook
data_index: 8 + 32, // Index of `Authority` seed
length: 32, // Length of `Authority` seed
},
],
false,
false,
)?
];
ExtraAccountMetaList::init::<ExecuteInstruction>(&mut data, &metas)?;
Transfer hook accounts and logic is as follows:
#[derive(Accounts)]
pub struct ExecuteTransferHook<'info> {
#[account(
token::mint = mint,
token::authority = owner,
)]
pub source_token: InterfaceAccount<'info, TokenAccount>,
pub mint: InterfaceAccount<'info, Mint>,
#[account(
token::mint = mint,
)]
pub destination_token: InterfaceAccount<'info, TokenAccount>,
pub owner: UncheckedAccount<'info>,
#[account(
seeds = [META_LIST_ACCOUNT_SEED, mint.key().as_ref()],
bump
)]
pub extra_account_meta_list: UncheckedAccount<'info>,
#[account(
seeds = [b"authority", authority.seed.as_ref()],
bump = authority.bump,
)]
pub authority: Account<'info, Authority>,
}
pub fn handler(_ctx: Context<ExecuteTransferHook>) -> Result<()> {
Ok(())
}