Skip to content

Commit 1f49556

Browse files
committed
first draft, tests are red
1 parent 3a77432 commit 1f49556

File tree

10 files changed

+190
-67
lines changed

10 files changed

+190
-67
lines changed

Cargo.lock

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

program-tests/sdk-token-test/Cargo.toml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@ test-sbf = []
1919
default = []
2020

2121
[dependencies]
22-
light-compressed-token-sdk = { workspace = true }
23-
light-sdk = { workspace = true }
24-
solana-program = { workspace = true }
25-
light-macros = { workspace = true }
22+
light-compressed-token-sdk = { workspace = true, features = ["anchor"] }
2623
anchor-lang = { workspace = true }
2724

2825
[dev-dependencies]
@@ -32,6 +29,7 @@ tokio = { workspace = true }
3229
serial_test = { workspace = true }
3330
solana-sdk = { workspace = true }
3431
anchor-spl = { workspace = true }
32+
light-sdk = { workspace = true }
3533

3634
[lints.rust.unexpected_cfgs]
3735
level = "allow"

program-tests/sdk-token-test/src/lib.rs

Lines changed: 66 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
#![allow(unexpected_cfgs)]
22

33
use anchor_lang::{prelude::*, solana_program::program::invoke, Discriminator};
4-
use light_compressed_token_sdk::cpi::{
5-
create_compressed_token_instruction, CpiAccounts, CpiInputs,
4+
use light_compressed_token_sdk::{
5+
cpi::{create_compressed_token_instruction, CpiAccounts, CpiInputs},
6+
InputTokenDataWithContext, ValidityProof,
67
};
78

89
declare_id!("5p1t1GAaKtK1FKCh5Hd2Gu8JCu3eREhJm4Q2qYfTEPYK");
@@ -15,8 +16,8 @@ pub mod sdk_token_test {
1516
pub fn compress<'info>(
1617
ctx: Context<'_, '_, '_, 'info, Generic<'info>>,
1718
output_tree_index: u8,
18-
recipient: Pubkey,
19-
mint: Pubkey, // TODO: deserialize from token account.
19+
recipient: Pubkey, // TODO: make recpient pda
20+
mint: Pubkey, // TODO: deserialize from token account.
2021
amount: u64,
2122
) -> Result<()> {
2223
let light_cpi_accounts =
@@ -40,49 +41,67 @@ pub mod sdk_token_test {
4041
Ok(())
4142
}
4243

43-
// pub fn transfer<'info>(
44-
// ctx: Context<'_, '_, '_, 'info, UpdateNestedData<'info>>,
45-
// proof: ValidityProof,
46-
// my_compressed_account: MyCompressedAccount,
47-
// account_meta: CompressedAccountMeta,
48-
// nested_data: NestedData,
49-
// ) -> Result<()> {
50-
// let mut my_compressed_account = LightAccount::<'_, MyCompressedAccount>::new_mut(
51-
// &crate::ID,
52-
// &account_meta,
53-
// my_compressed_account,
54-
// )
55-
// .map_err(ProgramError::from)?;
56-
57-
// my_compressed_account.nested = nested_data;
58-
59-
// let light_cpi_accounts = CpiAccounts::new(
60-
// ctx.accounts.signer.as_ref(),
61-
// ctx.remaining_accounts,
62-
// crate::LIGHT_CPI_SIGNER,
63-
// );
64-
65-
// let cpi_inputs = CpiInputs::new(
66-
// proof,
67-
// vec![my_compressed_account
68-
// .to_account_info()
69-
// .map_err(ProgramError::from)?],
70-
// );
71-
72-
// cpi_inputs
73-
// .invoke_light_system_program(light_cpi_accounts)
74-
// .map_err(ProgramError::from)?;
75-
76-
// Ok(())
77-
// }
78-
79-
// pub fn decompress<'info>(
80-
// ctx: Context<'_, '_, '_, 'info, WithoutCompressedAccount<'info>>,
81-
// name: String,
82-
// ) -> Result<()> {
83-
// ctx.accounts.my_regular_account.name = name;
84-
// Ok(())
85-
// }
44+
pub fn transfer<'info>(
45+
ctx: Context<'_, '_, '_, 'info, Generic<'info>>,
46+
validity_proof: ValidityProof,
47+
token_data: Vec<InputTokenDataWithContext>,
48+
output_tree_index: u8,
49+
mint: Pubkey,
50+
recipient: Pubkey,
51+
) -> Result<()> {
52+
let mut token_account = light_compressed_token_sdk::account::CTokenAccount::new(
53+
mint,
54+
ctx.accounts.signer.key(), // TODO: reconsider whether this makes sense
55+
token_data,
56+
output_tree_index,
57+
);
58+
// None is the same output_tree_index as token account
59+
let recipient_token_account = token_account.transfer(&recipient, 10, None).unwrap();
60+
61+
let cpi_inputs =
62+
CpiInputs::new(vec![token_account, recipient_token_account], validity_proof);
63+
let light_cpi_accounts =
64+
CpiAccounts::new(ctx.accounts.signer.as_ref(), ctx.remaining_accounts);
65+
66+
// TODO: add to program error conversion
67+
let instruction =
68+
create_compressed_token_instruction(cpi_inputs, &light_cpi_accounts).unwrap();
69+
let account_infos = light_cpi_accounts.to_account_infos();
70+
71+
// TODO: make invoke_signed
72+
invoke(&instruction, account_infos.as_slice())?;
73+
74+
Ok(())
75+
}
76+
77+
pub fn decompress<'info>(
78+
ctx: Context<'_, '_, '_, 'info, Generic<'info>>,
79+
validity_proof: ValidityProof,
80+
token_data: Vec<InputTokenDataWithContext>,
81+
output_tree_index: u8,
82+
mint: Pubkey,
83+
) -> Result<()> {
84+
let mut token_account = light_compressed_token_sdk::account::CTokenAccount::new(
85+
mint,
86+
ctx.accounts.signer.key(), // TODO: reconsider whether this makes sense
87+
token_data,
88+
output_tree_index,
89+
);
90+
token_account.decompress(10).unwrap();
91+
92+
let cpi_inputs = CpiInputs::new(vec![token_account], validity_proof);
93+
let light_cpi_accounts =
94+
CpiAccounts::new(ctx.accounts.signer.as_ref(), ctx.remaining_accounts);
95+
96+
// TODO: add to program error conversion
97+
let instruction =
98+
create_compressed_token_instruction(cpi_inputs, &light_cpi_accounts).unwrap();
99+
let account_infos = light_cpi_accounts.to_account_infos();
100+
// TODO: make invoke_signed
101+
invoke(&instruction, account_infos.as_slice())?;
102+
103+
Ok(())
104+
}
86105
}
87106

88107
#[derive(Accounts)]

program-tests/sdk-token-test/tests/test.rs

Lines changed: 91 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,25 @@
11
// #![cfg(feature = "test-sbf")]
22

3-
use anchor_lang::AccountDeserialize;
3+
use anchor_lang::{AccountDeserialize, InstructionData};
44
use anchor_spl::token::TokenAccount;
5+
use light_compressed_token_sdk::{
6+
instruction::{get_transfer_instruction_account_metas, TokenAccountsMetaConfig},
7+
token_pool::get_token_pool_pda,
8+
};
59
use light_program_test::{LightProgramTest, ProgramTestConfig, Rpc};
6-
use light_test_utils::spl::{create_mint_helper, create_token_account, mint_spl_tokens};
7-
use solana_sdk::{signature::Keypair, signer::Signer};
10+
use light_sdk::instruction::PackedAccounts;
11+
use light_test_utils::{
12+
spl::{create_mint_helper, create_token_account, mint_spl_tokens},
13+
RpcError,
14+
};
15+
use solana_sdk::{
16+
instruction::{AccountMeta, Instruction},
17+
pubkey::Pubkey,
18+
signature::{Keypair, Signature, Signer},
19+
};
820

9-
//#[serial]
1021
#[tokio::test]
11-
async fn test_create_token_account_and_mint() {
22+
async fn test_compress_spl_tokens() {
1223
// Initialize the test environment
1324
let mut rpc = LightProgramTest::new(ProgramTestConfig::new(
1425
false,
@@ -49,7 +60,7 @@ async fn test_create_token_account_and_mint() {
4960

5061
println!("Minted {} tokens to account", mint_amount);
5162

52-
// Verify the token account has the correct balance
63+
// Verify the token account has the correct balance before compression
5364
let token_account_data = rpc
5465
.get_account(token_account_keypair.pubkey())
5566
.await
@@ -63,5 +74,78 @@ async fn test_create_token_account_and_mint() {
6374
assert_eq!(token_account.mint, mint_pubkey);
6475
assert_eq!(token_account.owner, payer.pubkey());
6576

66-
println!("Test completed successfully!");
77+
println!("Verified token account balance before compression");
78+
79+
// Now compress the SPL tokens
80+
let compress_amount = 500_000; // Compress half of the tokens
81+
let recipient = payer.pubkey(); // Compress to the same owner
82+
83+
compress_spl_tokens(
84+
&mut rpc,
85+
&payer,
86+
recipient,
87+
mint_pubkey,
88+
compress_amount,
89+
token_account_keypair.pubkey(),
90+
)
91+
.await
92+
.unwrap();
93+
94+
println!("Compressed {} tokens successfully", compress_amount);
95+
96+
// TODO: Add verification of compressed token accounts
97+
// This would require checking the compressed account state tree
98+
// and verifying the token balance was reduced in the SPL account
99+
100+
println!("Compression test completed successfully!");
101+
}
102+
103+
async fn compress_spl_tokens(
104+
rpc: &mut LightProgramTest,
105+
payer: &Keypair,
106+
recipient: Pubkey,
107+
mint: Pubkey,
108+
amount: u64,
109+
token_account: Pubkey,
110+
) -> Result<Signature, RpcError> {
111+
let mut remaining_accounts = PackedAccounts::default();
112+
let token_pool_pda = get_token_pool_pda(&mint);
113+
let config = TokenAccountsMetaConfig::compress(
114+
payer.pubkey(),
115+
payer.pubkey(),
116+
token_pool_pda,
117+
token_account,
118+
false,
119+
);
120+
remaining_accounts.add_pre_accounts_signer_mut(payer.pubkey());
121+
// Add the token account to pre_accounts for the compression
122+
remaining_accounts
123+
.add_pre_accounts_metas(get_transfer_instruction_account_metas(config).as_slice());
124+
125+
let output_tree_index = rpc
126+
.get_random_state_tree_info()
127+
.unwrap()
128+
.pack_output_tree_index(&mut remaining_accounts)
129+
.unwrap();
130+
131+
let (remaining_accounts, _, _) = remaining_accounts.to_account_metas();
132+
133+
let instruction = Instruction {
134+
program_id: sdk_token_test::ID,
135+
accounts: [
136+
vec![AccountMeta::new(payer.pubkey(), true)],
137+
remaining_accounts,
138+
]
139+
.concat(),
140+
data: sdk_token_test::instruction::Compress {
141+
output_tree_index,
142+
recipient,
143+
mint,
144+
amount,
145+
}
146+
.data(),
147+
};
148+
149+
rpc.create_and_send_transaction(&[instruction], &payer.pubkey(), &[payer])
150+
.await
67151
}

sdk-libs/compressed-token-sdk/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ thiserror = { workspace = true }
1818
borsh = { workspace = true }
1919

2020
# Solana dependencies
21-
solana-pubkey = { workspace = true }
21+
solana-pubkey = { workspace = true, features = ["sha2", "curve25519"] }
2222
solana-instruction = { workspace = true }
2323
solana-account-info = { workspace = true }
2424
solana-cpi = { workspace = true }

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ pub mod account;
22
pub mod cpi;
33
pub mod error;
44
pub mod instruction;
5+
pub mod token_pool;
6+
7+
pub use light_compressed_token_types::*;
58

69
// Conditional anchor re-exports
710
#[cfg(feature = "anchor")]
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
use light_compressed_token_types::constants::{POOL_SEED, PROGRAM_ID};
2+
use solana_pubkey::Pubkey;
3+
4+
pub fn get_token_pool_pda(mint: &Pubkey) -> Pubkey {
5+
get_token_pool_pda_with_index(mint, 0)
6+
}
7+
8+
pub fn find_token_pool_pda_with_index(mint: &Pubkey, token_pool_index: u8) -> (Pubkey, u8) {
9+
let seeds = &[POOL_SEED, mint.as_ref(), &[token_pool_index]];
10+
let seeds = if token_pool_index == 0 {
11+
&seeds[..2]
12+
} else {
13+
&seeds[..]
14+
};
15+
Pubkey::find_program_address(seeds, &Pubkey::from(PROGRAM_ID))
16+
}
17+
18+
pub fn get_token_pool_pda_with_index(mint: &Pubkey, token_pool_index: u8) -> Pubkey {
19+
find_token_pool_pda_with_index(mint, token_pool_index).0
20+
}

sdk-libs/compressed-token-types/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ version = "0.1.0"
44
edition = "2021"
55

66
[features]
7-
anchor = ["anchor-lang"]
7+
anchor = ["anchor-lang", "light-compressed-account/anchor"]
88

99
[dependencies]
1010
borsh = { workspace = true }
Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1-
#[cfg(feature = "anchor")]
2-
use anchor_lang::{AnchorDeserialize, AnchorSerialize};
3-
#[cfg(not(feature = "anchor"))]
4-
use borsh::{BorshDeserialize as AnchorDeserialize, BorshSerialize as AnchorSerialize};
1+
use crate::{AnchorDeserialize, AnchorSerialize};
52

63
#[derive(Debug, Copy, Clone, AnchorSerialize, AnchorDeserialize)]
74
pub struct CpiSigner {
85
pub program_id: [u8; 32],
96
pub bump: u8,
10-
}
7+
}

sdk-libs/sdk/src/instruction/pack_accounts.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ impl PackedAccounts {
4040
self.pre_accounts.push(account_meta);
4141
}
4242

43+
pub fn add_pre_accounts_metas(&mut self, account_metas: &[AccountMeta]) {
44+
self.pre_accounts.extend_from_slice(account_metas);
45+
}
46+
4347
pub fn add_system_accounts(&mut self, config: SystemAccountMetaConfig) {
4448
self.system_accounts
4549
.extend(get_light_system_account_metas(config));

0 commit comments

Comments
 (0)