Skip to content

Commit

Permalink
Add new helper for adding the account metas
Browse files Browse the repository at this point in the history
  • Loading branch information
joncinque committed Jan 18, 2024
1 parent 2e7a20a commit 52a691e
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 15 deletions.
55 changes: 42 additions & 13 deletions token/client/src/token.rs
Expand Up @@ -2159,14 +2159,18 @@ where
&multisig_signers,
proof_location,
)?;
offchain::resolve_extra_transfer_account_metas(
offchain::add_extra_account_metas(
&mut instructions[0],
source_account,
self.get_address(),
destination_account,
source_authority,
u64::MAX,
|address| {
self.client
.get_account(address)
.map_ok(|opt| opt.map(|acc| acc.data))
},
self.get_address(),
)
.await
.map_err(|_| TokenError::AccountNotFound)?;
Expand Down Expand Up @@ -2213,14 +2217,18 @@ where
context_state_accounts,
source_decrypt_handles,
)?;
offchain::resolve_extra_transfer_account_metas(
offchain::add_extra_account_metas(
&mut instruction,
source_account,
self.get_address(),
destination_account,
source_authority,
u64::MAX,
|address| {
self.client
.get_account(address)
.map_ok(|opt| opt.map(|acc| acc.data))
},
self.get_address(),
)
.await
.map_err(|_| TokenError::AccountNotFound)?;
Expand Down Expand Up @@ -2286,14 +2294,18 @@ where
context_state_accounts,
&source_decrypt_handles,
)?;
offchain::resolve_extra_transfer_account_metas(
offchain::add_extra_account_metas(
&mut transfer_instruction,
source_account,
self.get_address(),
destination_account,
source_authority,
u64::MAX,
|address| {
self.client
.get_account(address)
.map_ok(|opt| opt.map(|acc| acc.data))
},
self.get_address(),
)
.await
.map_err(|_| TokenError::AccountNotFound)?;
Expand Down Expand Up @@ -2721,18 +2733,27 @@ where
&multisig_signers,
proof_location,
)?;
offchain::resolve_extra_transfer_account_metas(
offchain::add_extra_account_metas(
&mut instructions[0],
source_account,
self.get_address(),
destination_account,
source_authority,
u64::MAX,
|address| {
self.client
.get_account(address)
.map_ok(|opt| opt.map(|acc| acc.data))
},
self.get_address(),
)
.await
.map_err(|_| TokenError::AccountNotFound)?;
self.process_ixs_with_additional_compute_budget(&instructions, TRANSFER_WITH_FEE_COMPUTE_BUDGET, signing_keypairs).await
self.process_ixs_with_additional_compute_budget(
&instructions,
TRANSFER_WITH_FEE_COMPUTE_BUDGET,
signing_keypairs,
)
.await
}

/// Transfer tokens confidentially with fee using split proofs.
Expand Down Expand Up @@ -2776,14 +2797,18 @@ where
context_state_accounts,
source_decrypt_handles,
)?;
offchain::resolve_extra_transfer_account_metas(
offchain::add_extra_account_metas(
&mut instruction,
source_account,
self.get_address(),
destination_account,
source_authority,
u64::MAX,
|address| {
self.client
.get_account(address)
.map_ok(|opt| opt.map(|acc| acc.data))
},
self.get_address(),
)
.await
.map_err(|_| TokenError::AccountNotFound)?;
Expand Down Expand Up @@ -2874,14 +2899,18 @@ where
context_state_accounts,
&source_decrypt_handles,
)?;
offchain::resolve_extra_transfer_account_metas(
offchain::add_extra_account_metas(
&mut transfer_instruction,
source_account,
self.get_address(),
destination_account,
source_authority,
u64::MAX,
|address| {
self.client
.get_account(address)
.map_ok(|opt| opt.map(|acc| acc.data))
},
self.get_address(),
)
.await
.map_err(|_| TokenError::AccountNotFound)?;
Expand Down
59 changes: 57 additions & 2 deletions token/program-2022/src/offchain.rs
Expand Up @@ -112,14 +112,69 @@ where
decimals,
)?;

add_extra_account_metas(
&mut transfer_instruction,
source_pubkey,
mint_pubkey,
destination_pubkey,
authority_pubkey,
amount,
fetch_account_data_fn,
)
.await?;

Ok(transfer_instruction)
}

/// Offchain helper to add required account metas to an instruction, including
/// the ones required by the transfer hook.
///
/// To be client-agnostic and to avoid pulling in the full solana-sdk, this
/// simply takes a function that will return its data as `Future<Vec<u8>>` for
/// the given address. Can be called in the following way:
///
/// ```rust,ignore
/// let mut transfer_instruction = spl_token_2022::instruction::transfer_checked(
/// &spl_token_2022::id(),
/// source_pubkey,
/// mint_pubkey,
/// destination_pubkey,
/// authority_pubkey,
/// signer_pubkeys,
/// amount,
/// decimals,
/// )?;
/// add_extra_account_metas(
/// &mut transfer_instruction,
/// source_pubkey,
/// mint_pubkey,
/// destination_pubkey,
/// authority_pubkey,
/// amount,
/// fetch_account_data_fn,
/// ).await?;
/// ```
pub async fn add_extra_account_metas<F, Fut>(
instruction: &mut Instruction,
source_pubkey: &Pubkey,
mint_pubkey: &Pubkey,
destination_pubkey: &Pubkey,
authority_pubkey: &Pubkey,
amount: u64,
fetch_account_data_fn: F,
) -> Result<(), AccountFetchError>
where
F: Fn(Pubkey) -> Fut,
Fut: Future<Output = AccountDataResult>,
{
let mint_data = fetch_account_data_fn(*mint_pubkey)
.await?
.ok_or(ProgramError::InvalidAccountData)?;
let mint = StateWithExtensions::<Mint>::unpack(&mint_data)?;

if let Some(program_id) = transfer_hook::get_program_id(&mint) {
add_extra_account_metas_for_execute(
&mut transfer_instruction,
instruction,
&program_id,
source_pubkey,
mint_pubkey,
Expand All @@ -131,7 +186,7 @@ where
.await?;
}

Ok(transfer_instruction)
Ok(())
}

#[cfg(test)]
Expand Down

0 comments on commit 52a691e

Please sign in to comment.