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

Commit 049a89f

Browse files
token-2022: Add confidential transfer with fee instruction (#2988)
* token-2022: add separate transfer with fee instruction * token-2022: add `TransferWithFee` client code * apply twoxtx patch * token-2022: add brief tests for transfer with fee * Revert "apply twoxtx patch" This reverts commit ce09d1f. * token-2022: cargo fmt * token-2022: uncommenting the rest of the tests * token-2022: cargo fmt * token-2022: temporarily reverting to 5f89521 * token-2022: minor * token-2022: clippy * token-2022: apply twoxtx patch * token-2022: fix transfer with fee test * Revert "token-2022: apply twoxtx patch" This reverts commit 577e63c. * token-2022: simplify fee parameter for zkp on client * token-2022: fix build
1 parent b5e301b commit 049a89f

File tree

5 files changed

+439
-59
lines changed

5 files changed

+439
-59
lines changed

Cargo.lock

Lines changed: 39 additions & 51 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

token/client/src/token.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::client::{ProgramClient, ProgramClientError, SendTransaction};
22
use solana_program_test::tokio::time;
33
use solana_sdk::{
44
account::Account as BaseAccount,
5+
epoch_info::EpochInfo,
56
hash::Hash,
67
instruction::Instruction,
78
program_error::ProgramError,
@@ -22,6 +23,7 @@ use spl_token_2022::{
2223
solana_zk_token_sdk::{
2324
encryption::{auth_encryption::*, elgamal::*},
2425
errors::ProofError,
26+
instruction::transfer_with_fee::FeeParameters,
2527
},
2628
state::{Account, AccountState, Mint},
2729
};
@@ -1148,6 +1150,80 @@ where
11481150
.await
11491151
}
11501152

1153+
/// Transfer tokens confidentially with fee
1154+
#[allow(clippy::too_many_arguments)]
1155+
pub async fn confidential_transfer_transfer_with_fee<S2: Signer>(
1156+
&self,
1157+
source_token_account: &Pubkey,
1158+
destination_token_account: &Pubkey,
1159+
source_token_authority: &S2,
1160+
amount: u64,
1161+
source_available_balance: u64,
1162+
source_elgamal_keypair: &ElGamalKeypair,
1163+
new_source_decryptable_available_balance: AeCiphertext,
1164+
epoch_info: &EpochInfo,
1165+
) -> TokenResult<T::Output> {
1166+
let source_state = self.get_account_info(source_token_account).await.unwrap();
1167+
let source_extension =
1168+
source_state.get_extension::<confidential_transfer::ConfidentialTransferAccount>()?;
1169+
1170+
let destination_state = self
1171+
.get_account_info(destination_token_account)
1172+
.await
1173+
.unwrap();
1174+
let destination_extension = destination_state
1175+
.get_extension::<confidential_transfer::ConfidentialTransferAccount>(
1176+
)?;
1177+
1178+
let mint_state = self.get_mint_info().await.unwrap();
1179+
let transfer_fee_config = mint_state
1180+
.get_extension::<transfer_fee::TransferFeeConfig>()
1181+
.unwrap();
1182+
1183+
let fee_parameters = transfer_fee_config.get_epoch_fee(epoch_info.epoch);
1184+
1185+
let ct_mint = mint_state
1186+
.get_extension::<confidential_transfer::ConfidentialTransferMint>()
1187+
.unwrap();
1188+
1189+
let proof_data = confidential_transfer::instruction::TransferWithFeeData::new(
1190+
amount,
1191+
(
1192+
source_available_balance,
1193+
&source_extension.available_balance.try_into().unwrap(),
1194+
),
1195+
source_elgamal_keypair,
1196+
(
1197+
&destination_extension.encryption_pubkey.try_into().unwrap(),
1198+
&ct_mint.auditor_pubkey.try_into().unwrap(),
1199+
),
1200+
FeeParameters {
1201+
fee_rate_basis_points: u16::from(fee_parameters.transfer_fee_basis_points),
1202+
maximum_fee: u64::from(fee_parameters.maximum_fee),
1203+
},
1204+
&ct_mint
1205+
.withdraw_withheld_authority_pubkey
1206+
.try_into()
1207+
.unwrap(),
1208+
)
1209+
.map_err(TokenError::Proof)?;
1210+
1211+
self.process_ixs(
1212+
&confidential_transfer::instruction::transfer_with_fee(
1213+
&self.program_id,
1214+
source_token_account,
1215+
destination_token_account,
1216+
&self.pubkey,
1217+
new_source_decryptable_available_balance,
1218+
&source_token_authority.pubkey(),
1219+
&[],
1220+
&proof_data,
1221+
)?,
1222+
&[source_token_authority],
1223+
)
1224+
.await
1225+
}
1226+
11511227
/// Applies the confidential transfer pending balance to the available balance
11521228
pub async fn confidential_transfer_apply_pending_balance<S2: Signer>(
11531229
&self,

0 commit comments

Comments
 (0)