Skip to content

Commit 725254c

Browse files
authored
add pending balance and tests for confidetial transfer extension (#471)
* add pending balance and tests for confidetial transfer extension * moved tests, added functions to legacy * improve tests, fix lints * updated solana.dic, fixed test
1 parent ce5539f commit 725254c

File tree

5 files changed

+818
-0
lines changed

5 files changed

+818
-0
lines changed

clients/rust-legacy/src/token.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4037,6 +4037,80 @@ where
40374037
));
40384038
self.process_ixs(&instructions, signing_keypairs).await
40394039
}
4040+
4041+
/// Get the pending balance for a confidential transfer account.
4042+
///
4043+
/// This decrypts and combines the low 16 bits and high 48 bits of the pending balance
4044+
/// into a single u64 value.
4045+
pub async fn confidential_transfer_get_pending_balance(
4046+
&self,
4047+
account: &Pubkey,
4048+
elgamal_secret_key: &ElGamalSecretKey,
4049+
) -> TokenResult<u64> {
4050+
let account_info = self.get_account_info(account).await?;
4051+
let confidential_transfer_account =
4052+
account_info.get_extension::<ConfidentialTransferAccount>()?;
4053+
let account_info = ApplyPendingBalanceAccountInfo::new(confidential_transfer_account);
4054+
4055+
account_info
4056+
.get_pending_balance(elgamal_secret_key)
4057+
.map_err(|_| TokenError::AccountDecryption)
4058+
}
4059+
4060+
/// Get the available balance for a confidential transfer account.
4061+
///
4062+
/// This decrypts the decryptable available balance using the provided AES key.
4063+
pub async fn confidential_transfer_get_available_balance(
4064+
&self,
4065+
account: &Pubkey,
4066+
aes_key: &AeKey,
4067+
) -> TokenResult<u64> {
4068+
let account_info = self.get_account_info(account).await?;
4069+
let confidential_transfer_account =
4070+
account_info.get_extension::<ConfidentialTransferAccount>()?;
4071+
let account_info = ApplyPendingBalanceAccountInfo::new(confidential_transfer_account);
4072+
4073+
account_info
4074+
.get_available_balance(aes_key)
4075+
.map_err(|_| TokenError::AccountDecryption)
4076+
}
4077+
4078+
/// Get the total balance (pending and available) for a confidential transfer account.
4079+
///
4080+
/// This combines both pending and available balances with overflow protection.
4081+
pub async fn confidential_transfer_get_total_balance(
4082+
&self,
4083+
account: &Pubkey,
4084+
elgamal_secret_key: &ElGamalSecretKey,
4085+
aes_key: &AeKey,
4086+
) -> TokenResult<u64> {
4087+
let account_info = self.get_account_info(account).await?;
4088+
let confidential_transfer_account =
4089+
account_info.get_extension::<ConfidentialTransferAccount>()?;
4090+
let account_info = ApplyPendingBalanceAccountInfo::new(confidential_transfer_account);
4091+
4092+
account_info
4093+
.get_total_balance(elgamal_secret_key, aes_key)
4094+
.map_err(|e| match e {
4095+
spl_token_2022::error::TokenError::Overflow => TokenError::AccountDecryption,
4096+
_ => TokenError::AccountDecryption,
4097+
})
4098+
}
4099+
4100+
/// Check if a confidential transfer account has any pending balance.
4101+
///
4102+
/// This checks whether the pending_balance_credit_counter is greater than zero.
4103+
pub async fn confidential_transfer_has_pending_balance(
4104+
&self,
4105+
account: &Pubkey,
4106+
) -> TokenResult<bool> {
4107+
let account_info = self.get_account_info(account).await?;
4108+
let confidential_transfer_account =
4109+
account_info.get_extension::<ConfidentialTransferAccount>()?;
4110+
let account_info = ApplyPendingBalanceAccountInfo::new(confidential_transfer_account);
4111+
4112+
Ok(account_info.has_pending_balance())
4113+
}
40404114
}
40414115

40424116
/// Calculates the maximum chunk size for a zero-knowledge proof record

0 commit comments

Comments
 (0)