2

I want to build a program using transfer-hooks that creates(or get) a PDA when a user makes a transaction using the signer public key as a seed.

I'm using this code as a template : https://github.com/0ximalice/spl-token-2022-transfer-hook-anchor/blob/main/programs/transferhook/src/lib.rs

Issue is that you have to hardcode the accounts and add them to your list of extra_accounts_meta.

I'm unsure it's possible, so I am asking if there is work around that lets the dynamically add the correct accounts needed for the transfer?

There is a small section mentioning it (I think) here, but I have trouble understanding it : https://github.com/solana-labs/solana-program-library/blob/master/libraries/tlv-account-resolution/README.md#types-of-required-accounts

2 Answers 2

4

Yes, you can dynamically derive pdas in the list of extra_accounts_meta! Here is an example Anchor program you can reference.

You can also reference the examples here created by Jonas, which include 3 examples of Anchor transfer hook programs.

If the pda seeds are addresses of other accounts, you reference them by index.

For example, these lines here:


// index 0-3 are the accounts required for token transfer (source, mint, destination, owner)
// index 4 is address of ExtraAccountMetaList account
let account_metas = vec![
    // index 5, wrapped SOL mint
    ExtraAccountMeta::new_with_pubkey(&ctx.accounts.wsol_mint.key(), false, false)?,
    // index 6, token program
    ExtraAccountMeta::new_with_pubkey(&ctx.accounts.token_program.key(), false, false)?,
    // index 7, associated token program
    ExtraAccountMeta::new_with_pubkey(
        &ctx.accounts.associated_token_program.key(),
        false,
        false,
    )?,
    // index 8, delegate PDA
    ExtraAccountMeta::new_with_seeds(
        &[Seed::Literal {
            bytes: "delegate".as_bytes().to_vec(),
        }],
        false, // is_signer
        false,  // is_writable
    )?,
    // index 9, delegate wrapped SOL token account
    ExtraAccountMeta::new_external_pda_with_seeds(
        7, // associated token program index
        &[
            Seed::AccountKey { index: 8 }, // owner index (delegate PDA)
            Seed::AccountKey { index: 6 }, // token program index
            Seed::AccountKey { index: 5 }, // wsol mint index
        ],
        false, // is_signer
        true,  // is_writable
    )?,
    // index 10, sender wrapped SOL token account
    ExtraAccountMeta::new_external_pda_with_seeds(
        7, // associated token program index
        &[
            Seed::AccountKey { index: 3 }, // owner index
            Seed::AccountKey { index: 6 }, // token program index
            Seed::AccountKey { index: 5 }, // wsol mint index
        ],
        false, // is_signer
        true,  // is_writable
    )?,
];
1

May be i don't get your question properly, but i think you have to create a pda per user, and put the user public key in the seeds.

then when you call your program, just add this pda address and you will be able to update the counter.

take care that your pda needs to be initialized first before being able to use it (may be create an instruction that only creates the pda, and add it if necessary in th transaction)

EDIT :

in the github you have this :

seeds = [b"extra-account-metas", mint.key().as_ref()],

meaning the seeds are derived from hard coded string "extra-account-meta" and from the mint address (dynamic). You can use any account instead of mint address, like "source" for example. Is that what you need ?

Or is the problem that in InitializeExtraAccountMetaList you don't have access to user's public key ?

3
  • Sorry for the lack of clarity, I have edited the question. I want to use transfer-hooks that let's you add additional logic on token transfers. For that you need to initialize extra_account_meta, the additionnal accounts that are needed to run the additionnal logic on transfers. Only issue is that I can only hardcode the required PDA. My goal would be that when a user makes a transaction, the logic in the transferhook get/creates a PDA based on the signer pubkey of the transaction and increments it's counter.
    – PandaPanda
    Jan 16 at 15:39
  • edited my answer ;)
    – Effe2
    Jan 16 at 20:44
  • You can pass a seed in the tlv pda resolution. Fixed thx!
    – PandaPanda
    Jan 17 at 20:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.