2

I'm trying to understand how the transfer hook works in the token 2022 program. I have deployed a program that implements the Execute and InitializeExtraAccountMetas functions (they both currently do nothing), and have been able to create tokens that reference that program in the transfer hook extension, but how do I actually make use of it during a transfer?

Calling the TransferChecked function fails with the following error:

https://explorer.solana.com/tx/5gvoeqwsWa6D6v4pKB91SbDBrmpoqmjggJyriiKV4vg63mTtrtDNXPVAjjvEBU23ANd7SZUsjxS9vS7y1RNBMwP?cluster=devnet

Program logged: "Instruction: TransferChecked" Program logged: "Error: Lamport balance below rent-exempt threshold" Program consumed: 12796 of 575094 compute units Program returned error: "custom program error: 0x0"

I don't really understand what account it refers to, certainly none of the token accounts, or the transfer hook program.. but i'm also just totally confused about how this works at all. TransferChecked doesn't have an option to include the transfer hook program i deployed, so how can it get called in the first place?

Thanks for any help you can offer!

1 Answer 1

2

In order to create a correct transfer instruction, you must fetch all of the additional required accounts and add them to the instruction. The Rust crates currently expose some helpers to make this easier, found in offchain.rs

Here's an example using it:

            let mut instruction = spl_token_2022::instruction::transfer_checked(
                &spl_token_2022::id(),
                source,
                mint,
                destination,
                authority,
                &multisig_signers,
                amount,
                decimals,
            )?;
            spl_token_2022::offchain::resolve_extra_transfer_account_metas(
                &mut instruction,
                |address| {
                    rpc_client
                        .get_account(address)
                        .map_ok(|opt| opt.map(|acc| acc.data))
                },
                mint,
            )
            .await.unwrap();
            // add the instruction to a transaction, sign and send!

Lifted from the token client: https://github.com/solana-labs/solana-program-library/blob/5a07a106b38b3107c4c89da1015d458ac9dcc5fe/token/client/src/token.rs#L907

Side note: I'll get around to adding these helpers and more docs to make it clearer. This is still very bleeding edge, sorry!

3
  • Hi, thanks for this. Do i need to be running a certain version of solana to make use of this? I can't actually find any reference to the map_ok function, i get an error "there is a method with a similar name: map_or", and searching in the solana git repo i can't find where this is defined. Aug 17, 2023 at 12:13
  • Hi again, i added in the futures crate to get access to map_ok, but i get the following: the method map_ok exists for enum Result<Account, ClientError>, but its trait bounds were not satisfied the following trait bounds were not satisfied: Result<solana_sdk::account::Account, solana_client::client_error::ClientError>: TryFuture which is required by `Result<solana_sdk::account::Account (it continues on). Do you have any idea what i need to do to make this work Aug 17, 2023 at 12:38
  • it's alive!! thanks, have managed to make it all work Aug 17, 2023 at 15:43

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.