@@ -43,91 +43,88 @@ fn build_transfer_data(args: &[u8]) -> [u8; 8 + TRANSFER_ARGS_LEN] {
4343 ix_data
4444}
4545
46- impl < ' info > Withdraw < ' info > {
47- pub fn withdraw_cnft (
48- & self ,
49- ctx : & CtxWithRemaining < ' info , Withdraw < ' info > > ,
50- ) -> Result < ( ) , ProgramError > {
51- let data = ctx. data ;
52- if data. len ( ) < TRANSFER_ARGS_LEN {
53- return Err ( ProgramError :: InvalidInstructionData ) ;
54- }
55-
56- let ix_data = build_transfer_data ( & data[ 0 ..TRANSFER_ARGS_LEN ] ) ;
57-
58- // Collect proof nodes
59- let remaining = ctx. remaining_accounts ( ) ;
60- let placeholder = self . system_program . to_account_view ( ) . clone ( ) ;
61- let mut proof_views: [ AccountView ; MAX_PROOF_NODES ] =
62- core:: array:: from_fn ( |_| placeholder. clone ( ) ) ;
63- let mut proof_count = 0usize ;
64- for result in remaining. iter ( ) {
65- if proof_count >= MAX_PROOF_NODES {
66- break ;
67- }
68- proof_views[ proof_count] = result?;
69- proof_count += 1 ;
70- }
46+ pub fn handle_withdraw_cnft < ' info > (
47+ accounts : & Withdraw < ' info > , ctx : & CtxWithRemaining < ' info , Withdraw < ' info > > ,
48+ ) -> Result < ( ) , ProgramError > {
49+ let data = ctx. data ;
50+ if data. len ( ) < TRANSFER_ARGS_LEN {
51+ return Err ( ProgramError :: InvalidInstructionData ) ;
52+ }
7153
72- let total_accounts = 8 + proof_count;
73-
74- // Build instruction account metas matching mpl-bubblegum Transfer layout:
75- // tree_config, leaf_owner (signer/PDA), leaf_delegate, new_leaf_owner,
76- // merkle_tree, log_wrapper, compression_program, system_program, then proofs.
77- let sys_addr = self . system_program . address ( ) ;
78- let mut ix_accounts: [ InstructionAccount ; MAX_CPI_ACCOUNTS ] =
79- core:: array:: from_fn ( |_| InstructionAccount :: readonly ( sys_addr) ) ;
80-
81- ix_accounts[ 0 ] = InstructionAccount :: readonly ( self . tree_authority . address ( ) ) ;
82- ix_accounts[ 1 ] = InstructionAccount :: readonly_signer ( self . leaf_owner . address ( ) ) ;
83- // leaf_delegate = leaf_owner, not an additional signer
84- ix_accounts[ 2 ] = InstructionAccount :: readonly ( self . leaf_owner . address ( ) ) ;
85- ix_accounts[ 3 ] = InstructionAccount :: readonly ( self . new_leaf_owner . address ( ) ) ;
86- ix_accounts[ 4 ] = InstructionAccount :: writable ( self . merkle_tree . address ( ) ) ;
87- ix_accounts[ 5 ] = InstructionAccount :: readonly ( self . log_wrapper . address ( ) ) ;
88- ix_accounts[ 6 ] = InstructionAccount :: readonly ( self . compression_program . address ( ) ) ;
89- ix_accounts[ 7 ] = InstructionAccount :: readonly ( self . system_program . address ( ) ) ;
90-
91- for i in 0 ..proof_count {
92- ix_accounts[ 8 + i] = InstructionAccount :: readonly ( proof_views[ i] . address ( ) ) ;
54+ let ix_data = build_transfer_data ( & data[ 0 ..TRANSFER_ARGS_LEN ] ) ;
55+
56+ // Collect proof nodes
57+ let remaining = ctx. remaining_accounts ( ) ;
58+ let placeholder = accounts. system_program . to_account_view ( ) . clone ( ) ;
59+ let mut proof_views: [ AccountView ; MAX_PROOF_NODES ] =
60+ core:: array:: from_fn ( |_| placeholder. clone ( ) ) ;
61+ let mut proof_count = 0usize ;
62+ for result in remaining. iter ( ) {
63+ if proof_count >= MAX_PROOF_NODES {
64+ break ;
9365 }
66+ proof_views[ proof_count] = result?;
67+ proof_count += 1 ;
68+ }
9469
95- // Build account views
96- let sys_view = self . system_program . to_account_view ( ) . clone ( ) ;
97- let mut views: [ AccountView ; MAX_CPI_ACCOUNTS ] =
98- core:: array:: from_fn ( |_| sys_view. clone ( ) ) ;
99-
100- views[ 0 ] = self . tree_authority . to_account_view ( ) . clone ( ) ;
101- views[ 1 ] = self . leaf_owner . to_account_view ( ) . clone ( ) ;
102- views[ 2 ] = self . leaf_owner . to_account_view ( ) . clone ( ) ;
103- views[ 3 ] = self . new_leaf_owner . to_account_view ( ) . clone ( ) ;
104- views[ 4 ] = self . merkle_tree . to_account_view ( ) . clone ( ) ;
105- views[ 5 ] = self . log_wrapper . to_account_view ( ) . clone ( ) ;
106- views[ 6 ] = self . compression_program . to_account_view ( ) . clone ( ) ;
107- views[ 7 ] = self . system_program . to_account_view ( ) . clone ( ) ;
108-
109- for i in 0 ..proof_count {
110- views[ 8 + i] = proof_views[ i] . clone ( ) ;
111- }
70+ let total_accounts = 8 + proof_count;
71+
72+ // Build instruction account metas matching mpl-bubblegum Transfer layout:
73+ // tree_config, leaf_owner (signer/PDA), leaf_delegate, new_leaf_owner,
74+ // merkle_tree, log_wrapper, compression_program, system_program, then proofs.
75+ let sys_addr = accounts. system_program . address ( ) ;
76+ let mut ix_accounts: [ InstructionAccount ; MAX_CPI_ACCOUNTS ] =
77+ core:: array:: from_fn ( |_| InstructionAccount :: readonly ( sys_addr) ) ;
78+
79+ ix_accounts[ 0 ] = InstructionAccount :: readonly ( accounts. tree_authority . address ( ) ) ;
80+ ix_accounts[ 1 ] = InstructionAccount :: readonly_signer ( accounts. leaf_owner . address ( ) ) ;
81+ // leaf_delegate = leaf_owner, not an additional signer
82+ ix_accounts[ 2 ] = InstructionAccount :: readonly ( accounts. leaf_owner . address ( ) ) ;
83+ ix_accounts[ 3 ] = InstructionAccount :: readonly ( accounts. new_leaf_owner . address ( ) ) ;
84+ ix_accounts[ 4 ] = InstructionAccount :: writable ( accounts. merkle_tree . address ( ) ) ;
85+ ix_accounts[ 5 ] = InstructionAccount :: readonly ( accounts. log_wrapper . address ( ) ) ;
86+ ix_accounts[ 6 ] = InstructionAccount :: readonly ( accounts. compression_program . address ( ) ) ;
87+ ix_accounts[ 7 ] = InstructionAccount :: readonly ( accounts. system_program . address ( ) ) ;
88+
89+ for i in 0 ..proof_count {
90+ ix_accounts[ 8 + i] = InstructionAccount :: readonly ( proof_views[ i] . address ( ) ) ;
91+ }
11292
113- let instruction = InstructionView {
114- program_id : & MPL_BUBBLEGUM_ID ,
115- data : & ix_data,
116- accounts : & ix_accounts[ ..total_accounts] ,
117- } ;
118-
119- // PDA signer seeds: ["cNFT-vault", bump]
120- let bump_bytes = [ ctx. bumps . leaf_owner ] ;
121- let seeds: [ Seed ; 2 ] = [
122- Seed :: from ( b"cNFT-vault" as & [ u8 ] ) ,
123- Seed :: from ( & bump_bytes as & [ u8 ] ) ,
124- ] ;
125- let signer = Signer :: from ( & seeds as & [ Seed ] ) ;
126-
127- solana_instruction_view:: cpi:: invoke_signed_with_bounds :: < MAX_CPI_ACCOUNTS , AccountView > (
128- & instruction,
129- & views[ ..total_accounts] ,
130- & [ signer] ,
131- )
93+ // Build account views
94+ let sys_view = accounts. system_program . to_account_view ( ) . clone ( ) ;
95+ let mut views: [ AccountView ; MAX_CPI_ACCOUNTS ] =
96+ core:: array:: from_fn ( |_| sys_view. clone ( ) ) ;
97+
98+ views[ 0 ] = accounts. tree_authority . to_account_view ( ) . clone ( ) ;
99+ views[ 1 ] = accounts. leaf_owner . to_account_view ( ) . clone ( ) ;
100+ views[ 2 ] = accounts. leaf_owner . to_account_view ( ) . clone ( ) ;
101+ views[ 3 ] = accounts. new_leaf_owner . to_account_view ( ) . clone ( ) ;
102+ views[ 4 ] = accounts. merkle_tree . to_account_view ( ) . clone ( ) ;
103+ views[ 5 ] = accounts. log_wrapper . to_account_view ( ) . clone ( ) ;
104+ views[ 6 ] = accounts. compression_program . to_account_view ( ) . clone ( ) ;
105+ views[ 7 ] = accounts. system_program . to_account_view ( ) . clone ( ) ;
106+
107+ for i in 0 ..proof_count {
108+ views[ 8 + i] = proof_views[ i] . clone ( ) ;
132109 }
110+
111+ let instruction = InstructionView {
112+ program_id : & MPL_BUBBLEGUM_ID ,
113+ data : & ix_data,
114+ accounts : & ix_accounts[ ..total_accounts] ,
115+ } ;
116+
117+ // PDA signer seeds: ["cNFT-vault", bump]
118+ let bump_bytes = [ ctx. bumps . leaf_owner ] ;
119+ let seeds: [ Seed ; 2 ] = [
120+ Seed :: from ( b"cNFT-vault" as & [ u8 ] ) ,
121+ Seed :: from ( & bump_bytes as & [ u8 ] ) ,
122+ ] ;
123+ let signer = Signer :: from ( & seeds as & [ Seed ] ) ;
124+
125+ solana_instruction_view:: cpi:: invoke_signed_with_bounds :: < MAX_CPI_ACCOUNTS , AccountView > (
126+ & instruction,
127+ & views[ ..total_accounts] ,
128+ & [ signer] ,
129+ )
133130}
0 commit comments