Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit 14db758

Browse files
authored
token-2022: Execute transfer hook during confidential transfer (#6098)
* Move confidential-transfer test types for reuse * token-client: Add extra accounts for conf transfers * token-2022: Execute transfer hook in conf transfer * Test transfer hook with a confidential transfer * Featurize "confidential-hook" * Add new helper for adding the account metas * Replace self.pubkey -> self.get_address()
1 parent 3252cad commit 14db758

File tree

7 files changed

+593
-258
lines changed

7 files changed

+593
-258
lines changed

token/client/src/token.rs

Lines changed: 139 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2149,20 +2149,32 @@ where
21492149
.new_decryptable_available_balance(transfer_amount, source_aes_key)
21502150
.map_err(|_| TokenError::AccountDecryption)?;
21512151

2152-
self.process_ixs(
2153-
&confidential_transfer::instruction::transfer(
2154-
&self.program_id,
2155-
source_account,
2156-
&self.pubkey,
2157-
destination_account,
2158-
new_decryptable_available_balance,
2159-
source_authority,
2160-
&multisig_signers,
2161-
proof_location,
2162-
)?,
2163-
signing_keypairs,
2152+
let mut instructions = confidential_transfer::instruction::transfer(
2153+
&self.program_id,
2154+
source_account,
2155+
self.get_address(),
2156+
destination_account,
2157+
new_decryptable_available_balance,
2158+
source_authority,
2159+
&multisig_signers,
2160+
proof_location,
2161+
)?;
2162+
offchain::add_extra_account_metas(
2163+
&mut instructions[0],
2164+
source_account,
2165+
self.get_address(),
2166+
destination_account,
2167+
source_authority,
2168+
u64::MAX,
2169+
|address| {
2170+
self.client
2171+
.get_account(address)
2172+
.map_ok(|opt| opt.map(|acc| acc.data))
2173+
},
21642174
)
21652175
.await
2176+
.map_err(|_| TokenError::AccountNotFound)?;
2177+
self.process_ixs(&instructions, signing_keypairs).await
21662178
}
21672179

21682180
/// Transfer tokens confidentially using split proofs.
@@ -2195,22 +2207,32 @@ where
21952207
.new_decryptable_available_balance(transfer_amount, source_aes_key)
21962208
.map_err(|_| TokenError::AccountDecryption)?;
21972209

2198-
self.process_ixs(
2199-
&[
2200-
confidential_transfer::instruction::transfer_with_split_proofs(
2201-
&self.program_id,
2202-
source_account,
2203-
&self.pubkey,
2204-
destination_account,
2205-
new_decryptable_available_balance.into(),
2206-
source_authority,
2207-
context_state_accounts,
2208-
source_decrypt_handles,
2209-
)?,
2210-
],
2211-
signing_keypairs,
2210+
let mut instruction = confidential_transfer::instruction::transfer_with_split_proofs(
2211+
&self.program_id,
2212+
source_account,
2213+
self.get_address(),
2214+
destination_account,
2215+
new_decryptable_available_balance.into(),
2216+
source_authority,
2217+
context_state_accounts,
2218+
source_decrypt_handles,
2219+
)?;
2220+
offchain::add_extra_account_metas(
2221+
&mut instruction,
2222+
source_account,
2223+
self.get_address(),
2224+
destination_account,
2225+
source_authority,
2226+
u64::MAX,
2227+
|address| {
2228+
self.client
2229+
.get_account(address)
2230+
.map_ok(|opt| opt.map(|acc| acc.data))
2231+
},
22122232
)
22132233
.await
2234+
.map_err(|_| TokenError::AccountNotFound)?;
2235+
self.process_ixs(&[instruction], signing_keypairs).await
22142236
}
22152237

22162238
/// Transfer tokens confidentially using split proofs in parallel
@@ -2261,16 +2283,32 @@ where
22612283
.new_decryptable_available_balance(transfer_amount, source_aes_key)
22622284
.map_err(|_| TokenError::AccountDecryption)?;
22632285

2264-
let transfer_instruction = confidential_transfer::instruction::transfer_with_split_proofs(
2265-
&self.program_id,
2286+
let mut transfer_instruction =
2287+
confidential_transfer::instruction::transfer_with_split_proofs(
2288+
&self.program_id,
2289+
source_account,
2290+
self.get_address(),
2291+
destination_account,
2292+
new_decryptable_available_balance.into(),
2293+
source_authority,
2294+
context_state_accounts,
2295+
&source_decrypt_handles,
2296+
)?;
2297+
offchain::add_extra_account_metas(
2298+
&mut transfer_instruction,
22662299
source_account,
2267-
&self.pubkey,
2300+
self.get_address(),
22682301
destination_account,
2269-
new_decryptable_available_balance.into(),
22702302
source_authority,
2271-
context_state_accounts,
2272-
&source_decrypt_handles,
2273-
)?;
2303+
u64::MAX,
2304+
|address| {
2305+
self.client
2306+
.get_account(address)
2307+
.map_ok(|opt| opt.map(|acc| acc.data))
2308+
},
2309+
)
2310+
.await
2311+
.map_err(|_| TokenError::AccountNotFound)?;
22742312

22752313
let transfer_with_equality_and_ciphertext_validity = self
22762314
.create_equality_and_ciphertext_validity_proof_context_states_for_transfer_parallel(
@@ -2685,17 +2723,33 @@ where
26852723
// additional compute budget required for `VerifyTransferWithFee`
26862724
const TRANSFER_WITH_FEE_COMPUTE_BUDGET: u32 = 500_000;
26872725

2726+
let mut instructions = confidential_transfer::instruction::transfer_with_fee(
2727+
&self.program_id,
2728+
source_account,
2729+
destination_account,
2730+
self.get_address(),
2731+
new_decryptable_available_balance,
2732+
source_authority,
2733+
&multisig_signers,
2734+
proof_location,
2735+
)?;
2736+
offchain::add_extra_account_metas(
2737+
&mut instructions[0],
2738+
source_account,
2739+
self.get_address(),
2740+
destination_account,
2741+
source_authority,
2742+
u64::MAX,
2743+
|address| {
2744+
self.client
2745+
.get_account(address)
2746+
.map_ok(|opt| opt.map(|acc| acc.data))
2747+
},
2748+
)
2749+
.await
2750+
.map_err(|_| TokenError::AccountNotFound)?;
26882751
self.process_ixs_with_additional_compute_budget(
2689-
&confidential_transfer::instruction::transfer_with_fee(
2690-
&self.program_id,
2691-
source_account,
2692-
destination_account,
2693-
&self.pubkey,
2694-
new_decryptable_available_balance,
2695-
source_authority,
2696-
&multisig_signers,
2697-
proof_location,
2698-
)?,
2752+
&instructions,
26992753
TRANSFER_WITH_FEE_COMPUTE_BUDGET,
27002754
signing_keypairs,
27012755
)
@@ -2732,22 +2786,33 @@ where
27322786
.new_decryptable_available_balance(transfer_amount, source_aes_key)
27332787
.map_err(|_| TokenError::AccountDecryption)?;
27342788

2735-
self.process_ixs(
2736-
&[
2737-
confidential_transfer::instruction::transfer_with_fee_and_split_proofs(
2738-
&self.program_id,
2739-
source_account,
2740-
&self.pubkey,
2741-
destination_account,
2742-
new_decryptable_available_balance.into(),
2743-
source_authority,
2744-
context_state_accounts,
2745-
source_decrypt_handles,
2746-
)?,
2747-
],
2748-
signing_keypairs,
2789+
let mut instruction =
2790+
confidential_transfer::instruction::transfer_with_fee_and_split_proofs(
2791+
&self.program_id,
2792+
source_account,
2793+
self.get_address(),
2794+
destination_account,
2795+
new_decryptable_available_balance.into(),
2796+
source_authority,
2797+
context_state_accounts,
2798+
source_decrypt_handles,
2799+
)?;
2800+
offchain::add_extra_account_metas(
2801+
&mut instruction,
2802+
source_account,
2803+
self.get_address(),
2804+
destination_account,
2805+
source_authority,
2806+
u64::MAX,
2807+
|address| {
2808+
self.client
2809+
.get_account(address)
2810+
.map_ok(|opt| opt.map(|acc| acc.data))
2811+
},
27492812
)
27502813
.await
2814+
.map_err(|_| TokenError::AccountNotFound)?;
2815+
self.process_ixs(&[instruction], signing_keypairs).await
27512816
}
27522817

27532818
/// Transfer tokens confidentially using split proofs in parallel
@@ -2823,17 +2888,32 @@ where
28232888
.new_decryptable_available_balance(transfer_amount, source_aes_key)
28242889
.map_err(|_| TokenError::AccountDecryption)?;
28252890

2826-
let transfer_instruction =
2891+
let mut transfer_instruction =
28272892
confidential_transfer::instruction::transfer_with_fee_and_split_proofs(
28282893
&self.program_id,
28292894
source_account,
2830-
&self.pubkey,
2895+
self.get_address(),
28312896
destination_account,
28322897
new_decryptable_available_balance.into(),
28332898
source_authority,
28342899
context_state_accounts,
28352900
&source_decrypt_handles,
28362901
)?;
2902+
offchain::add_extra_account_metas(
2903+
&mut transfer_instruction,
2904+
source_account,
2905+
self.get_address(),
2906+
destination_account,
2907+
source_authority,
2908+
u64::MAX,
2909+
|address| {
2910+
self.client
2911+
.get_account(address)
2912+
.map_ok(|opt| opt.map(|acc| acc.data))
2913+
},
2914+
)
2915+
.await
2916+
.map_err(|_| TokenError::AccountNotFound)?;
28372917

28382918
let transfer_with_equality_and_ciphertext_valdity = self
28392919
.create_equality_and_ciphertext_validity_proof_context_states_for_transfer_with_fee_parallel(

0 commit comments

Comments
 (0)