4

For my program, I need to implement the Token2022 transfer hook. Inside the transfer hook, I need to read and write a PDA account driven from the address of the owner of the destination ATA.

EDIT: In the transfer hook I need to update 2 PDAs (user state). One is for the sender, and one is for the receiver. Everything is fine with the sender since we have it as a parameter in the transfer instruction. But we don't have the receiver's wallet address.

Here is how I initialize the PDA account

    pub user: AccountInfo<'info>,
    #[account(
        init,
        payer = _payer,
        space =  UserCampaignState::space(),
        seeds = [
            USER_CAMPAIGN_STATE_SEED.as_ref(),
            user.key().as_ref(),
        ],
        bump
    )]
    pub user_state: Account<'info, UserCampaignState>,

According to documentation, in ExtraAccountMetaList we have the owner of the source ATA (index 3), but no receiver, unfortunately.

index 0-3 are the accounts required for token transfer (source, mint, destination, owner)

So, my question is how to initialize ExtraAccountMetaList with the receiver's address and/or PDA. OR is there a workaround inside transfer_hook to get a PDA by the receiver's address and, most importantly, write in it?

Thank you in advance! I hope this will help others who struggle with receiver in transfer hook as well :)

2 Answers 2

3

The 3rd account (index 2) labeled destination_token is the recipient token account from the initial token transfer.

You should be able to access the address of the owner stored on the token account to derive the PDA.

4
  • Thanks a lot for the response! Can you share the code snippet or reference on how to do this, please? So far the only thing I have found is how to do this in JS
    – Oleh
    Commented Apr 9 at 7:07
  • From my understanding, you're talking about getting the owner in transfer_hook, right? But all accounts have to be passed from the client, so even if I can get the owner, this is impossible to mutate the account without passing it from the client.
    – Oleh
    Commented Apr 9 at 7:32
  • that's correct, since the recipient owner account is not a required account for a token transfer it won't be one of the default accounts pass to a custom transfer hook instruction. You should still be able to derive a PDA though, the owner address is stored on the token account. Can you provide some more context on what you're trying to do in your transfer hook?
    – john
    Commented Apr 9 at 14:57
  • Updated the question. Thank you for your response!
    – Oleh
    Commented Apr 10 at 7:45
0
        let destination_token_info = ctx.accounts.destination_token.to_account_info();
        let destination_token_data = destination_token_info.try_borrow_data()?;
        let destination_owner = Pubkey::try_from(&destination_token_data[32..64]).unwrap();

I think this code can help you.

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.