Skip to content

Commit 2e57db9

Browse files
committed
fix amount
1 parent 849f272 commit 2e57db9

File tree

3 files changed

+48
-8
lines changed

3 files changed

+48
-8
lines changed

program-libs/ctoken-types/src/state/solana_ctoken.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,38 @@ pub struct CompressedToken {
4040
pub extensions: Option<Vec<ExtensionStruct>>,
4141
}
4242

43+
impl CompressedToken {
44+
/// Extract amount directly from account data slice using hardcoded offset
45+
/// CompressedToken layout: mint (32 bytes) + owner (32 bytes) + amount (8 bytes)
46+
pub fn amount_from_slice(data: &[u8]) -> Result<u64, ZeroCopyError> {
47+
const AMOUNT_OFFSET: usize = 64; // 32 (mint) + 32 (owner)
48+
49+
if data.len() < AMOUNT_OFFSET + 8 {
50+
return Err(ZeroCopyError::Size);
51+
}
52+
53+
let amount_bytes = &data[AMOUNT_OFFSET..AMOUNT_OFFSET + 8];
54+
let amount = u64::from_le_bytes(
55+
amount_bytes
56+
.try_into()
57+
.map_err(|_| ZeroCopyError::Size)?
58+
);
59+
60+
Ok(amount)
61+
}
62+
63+
/// Extract amount from an AccountInfo
64+
#[cfg(feature = "solana")]
65+
pub fn amount_from_account_info(
66+
account_info: &solana_account_info::AccountInfo,
67+
) -> Result<u64, ZeroCopyError> {
68+
let data = account_info
69+
.try_borrow_data()
70+
.map_err(|_| ZeroCopyError::Size)?;
71+
Self::amount_from_slice(&data)
72+
}
73+
}
74+
4375
#[derive(Debug, PartialEq, Eq, Clone, AnchorSerialize, AnchorDeserialize)]
4476
pub struct CompressedTokenMeta {
4577
/// The mint associated with this account

sdk-libs/compressed-token-sdk/src/error.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use light_compressed_token_types::error::LightTokenSdkTypeError;
22
use light_ctoken_types::CTokenError;
33
use light_sdk::error::LightSdkError;
44
use light_sdk_types::error::LightSdkTypesError;
5+
use light_zero_copy::errors::ZeroCopyError;
56
use solana_program_error::ProgramError;
67
use thiserror::Error;
78

@@ -51,6 +52,8 @@ pub enum TokenSdkError {
5152
LightSdkError(#[from] LightSdkError),
5253
#[error(transparent)]
5354
LightSdkTypesError(#[from] LightSdkTypesError),
55+
#[error(transparent)]
56+
ZeroCopyError(#[from] ZeroCopyError),
5457
}
5558
#[cfg(feature = "anchor")]
5659
impl From<TokenSdkError> for anchor_lang::prelude::ProgramError {
@@ -89,6 +92,7 @@ impl From<TokenSdkError> for u32 {
8992
TokenSdkError::CTokenError(e) => e.into(),
9093
TokenSdkError::LightSdkTypesError(e) => e.into(),
9194
TokenSdkError::LightSdkError(e) => e.into(),
95+
TokenSdkError::ZeroCopyError(e) => e.into(),
9296
}
9397
}
9498
}

sdk-libs/compressed-token-sdk/src/instructions/compress_and_close.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ pub struct CompressAndCloseIndices {
2222
pub authority_index: u8,
2323
pub rent_recipient_index: u8,
2424
pub output_tree_index: u8,
25-
pub amount: u64,
2625
}
2726

2827
/// Find and validate all required account indices from packed_accounts
@@ -34,7 +33,6 @@ fn find_account_indices(
3433
authority: impl Into<Pubkey>,
3534
rent_recipient_pubkey: Pubkey,
3635
output_tree_pubkey: Pubkey,
37-
amount: u64,
3836
) -> Result<CompressAndCloseIndices, TokenSdkError> {
3937
let mint_pubkey = mint_pubkey.into();
4038
let owner_pubkey = owner_pubkey.into();
@@ -77,7 +75,6 @@ fn find_account_indices(
7775
authority_index,
7876
rent_recipient_index,
7977
output_tree_index,
80-
amount,
8178
})
8279
}
8380

@@ -105,13 +102,24 @@ pub fn compress_and_close_ctoken_accounts_with_indices<'info>(
105102
let mut token_accounts = Vec::with_capacity(indices.len());
106103

107104
for idx in indices {
105+
// Get the amount from the source token account
106+
let source_account = packed_accounts
107+
.get(idx.source_index as usize)
108+
.ok_or(TokenSdkError::InvalidAccountData)?;
109+
110+
let account_data = source_account
111+
.try_borrow_data()
112+
.map_err(|_| TokenSdkError::AccountBorrowFailed)?;
113+
114+
let amount = light_ctoken_types::state::CompressedToken::amount_from_slice(&account_data)?;
115+
108116
// Create CTokenAccount2 for CompressAndClose operation
109117
let mut token_account =
110118
CTokenAccount2::new_empty(idx.owner_index, idx.mint_index, idx.output_tree_index);
111119

112120
// Set up compress_and_close with actual indices
113121
token_account.compress_and_close(
114-
idx.amount,
122+
amount,
115123
idx.source_index,
116124
idx.authority_index,
117125
idx.rent_recipient_index,
@@ -191,9 +199,6 @@ pub fn compress_and_close_ctoken_accounts<'info>(
191199
light_ctoken_types::state::CompressedToken::zero_copy_at(&account_data)
192200
.map_err(|_| TokenSdkError::InvalidAccountData)?;
193201

194-
// Get the amount (full balance) - convert from zero-copy type
195-
let amount = u64::from(*compressed_token.amount);
196-
197202
// Extract pubkeys from the deserialized account
198203
let mint_pubkey = Pubkey::from(compressed_token.mint.to_bytes());
199204
let owner_pubkey = Pubkey::from(compressed_token.owner.to_bytes());
@@ -254,7 +259,6 @@ pub fn compress_and_close_ctoken_accounts<'info>(
254259
authority,
255260
rent_recipient_pubkey.ok_or(TokenSdkError::InvalidAccountData)?,
256261
output_tree_pubkey.ok_or(TokenSdkError::InvalidAccountData)?,
257-
amount,
258262
)?;
259263

260264
indices_vec.push(indices);

0 commit comments

Comments
 (0)