@@ -67,11 +67,43 @@ pub struct CreateMint {
6767 pub seed : Option < Keypair > ,
6868}
6969
70- fn build_token_metadata_extensions (
71- token_metadata : Option < & TokenMetadata > ,
70+ pub async fn create_mint_instructions < R : Rpc + Indexer > (
71+ rpc : & R ,
72+ create_mint : & CreateMint ,
73+ payer : Pubkey ,
7274 mint_authority : Pubkey ,
73- ) -> Option < Vec < ExtensionInstructionData > > {
74- token_metadata. map ( |metadata| {
75+ ) -> Result < Vec < Instruction > , RpcError > {
76+ let mint_seed_pubkey = create_mint. seed . as_ref ( ) . map ( |seed| seed. pubkey ( ) ) . ok_or_else ( || {
77+ RpcError :: CustomError (
78+ "create_mint_instructions requires CreateMint.seed = Some(Keypair) so caller can sign; use execute() for auto-generated seed" . to_string ( ) ,
79+ )
80+ } ) ?;
81+
82+ let address_tree = rpc. get_address_tree_v2 ( ) ;
83+ let output_queue = rpc. get_random_state_tree_info ( ) ?. queue ;
84+
85+ // Derive compression address
86+ let compression_address = derive_mint_compressed_address ( & mint_seed_pubkey, & address_tree. tree ) ;
87+
88+ // Find mint PDA
89+ let ( mint, bump) = find_mint_address ( & mint_seed_pubkey) ;
90+
91+ // Get validity proof for the address
92+ let rpc_result = rpc
93+ . get_validity_proof (
94+ vec ! [ ] ,
95+ vec ! [ AddressWithTree {
96+ address: compression_address,
97+ tree: address_tree. tree,
98+ } ] ,
99+ None ,
100+ )
101+ . await
102+ . map_err ( |e| RpcError :: CustomError ( format ! ( "Failed to get validity proof: {}" , e) ) ) ?
103+ . value ;
104+
105+ // Build extensions if token metadata is provided
106+ let extensions = create_mint. token_metadata . as_ref ( ) . map ( |metadata| {
75107 let additional_metadata = metadata. additional_metadata . as_ref ( ) . map ( |items| {
76108 items
77109 . iter ( )
@@ -97,44 +129,11 @@ fn build_token_metadata_extensions(
97129 additional_metadata,
98130 } ,
99131 ) ]
100- } )
101- }
102-
103- async fn build_create_mint_instructions < R : Rpc + Indexer > (
104- rpc : & R ,
105- decimals : u8 ,
106- freeze_authority : Option < Pubkey > ,
107- token_metadata : Option < & TokenMetadata > ,
108- mint_seed_pubkey : Pubkey ,
109- payer : Pubkey ,
110- mint_authority : Pubkey ,
111- ) -> Result < ( Vec < Instruction > , Pubkey ) , RpcError > {
112- let address_tree = rpc. get_address_tree_v2 ( ) ;
113- let output_queue = rpc. get_random_state_tree_info ( ) ?. queue ;
114-
115- // Derive compression address
116- let compression_address = derive_mint_compressed_address ( & mint_seed_pubkey, & address_tree. tree ) ;
117-
118- // Find mint PDA
119- let ( mint, bump) = find_mint_address ( & mint_seed_pubkey) ;
120-
121- // Get validity proof for the address
122- let rpc_result = rpc
123- . get_validity_proof (
124- vec ! [ ] ,
125- vec ! [ AddressWithTree {
126- address: compression_address,
127- tree: address_tree. tree,
128- } ] ,
129- None ,
130- )
131- . await
132- . map_err ( |e| RpcError :: CustomError ( format ! ( "Failed to get validity proof: {}" , e) ) ) ?
133- . value ;
132+ } ) ;
134133
135134 // Build params
136135 let params = CreateMintInstructionParams {
137- decimals,
136+ decimals : create_mint . decimals ,
138137 address_merkle_tree_root_index : rpc_result. addresses [ 0 ] . root_index ,
139138 mint_authority,
140139 proof : rpc_result. proof . 0 . ok_or_else ( || {
@@ -143,8 +142,8 @@ async fn build_create_mint_instructions<R: Rpc + Indexer>(
143142 compression_address,
144143 mint,
145144 bump,
146- freeze_authority,
147- extensions : build_token_metadata_extensions ( token_metadata , mint_authority ) ,
145+ freeze_authority : create_mint . freeze_authority ,
146+ extensions,
148147 rent_payment : 16 , // ~24 hours rent
149148 write_top_up : 766 , // ~3 hours per write
150149 } ;
@@ -157,36 +156,10 @@ async fn build_create_mint_instructions<R: Rpc + Indexer>(
157156 address_tree. tree ,
158157 output_queue,
159158 )
160- . instruction ( )
161- . map_err ( |e| RpcError :: CustomError ( format ! ( "Failed to create instruction: {}" , e) ) ) ?;
162-
163- Ok ( ( vec ! [ instruction] , mint) )
164- }
165-
166- pub async fn create_mint_instructions < R : Rpc + Indexer > (
167- rpc : & R ,
168- create_mint : & CreateMint ,
169- payer : Pubkey ,
170- mint_authority : Pubkey ,
171- ) -> Result < Vec < Instruction > , RpcError > {
172- let mint_seed_pubkey = create_mint. seed . as_ref ( ) . map ( |seed| seed. pubkey ( ) ) . ok_or_else ( || {
173- RpcError :: CustomError (
174- "create_mint_instructions requires CreateMint.seed = Some(Keypair) so caller can sign; use execute() for auto-generated seed" . to_string ( ) ,
175- )
176- } ) ?;
177-
178- let ( instructions, _) = build_create_mint_instructions (
179- rpc,
180- create_mint. decimals ,
181- create_mint. freeze_authority ,
182- create_mint. token_metadata . as_ref ( ) ,
183- mint_seed_pubkey,
184- payer,
185- mint_authority,
186- )
187- . await ?;
159+ . instruction ( )
160+ . map_err ( |e| RpcError :: CustomError ( format ! ( "Failed to create instruction: {}" , e) ) ) ?;
188161
189- Ok ( instructions )
162+ Ok ( vec ! [ instruction ] )
190163}
191164
192165impl CreateMint {
@@ -214,23 +187,87 @@ impl CreateMint {
214187 payer : & Keypair ,
215188 mint_authority : & Keypair ,
216189 ) -> Result < ( Signature , Pubkey ) , RpcError > {
217- let CreateMint {
218- decimals,
219- freeze_authority,
220- token_metadata,
221- seed,
222- } = self ;
223- let mint_seed = seed. unwrap_or_else ( Keypair :: new) ;
224- let ( instructions, mint) = build_create_mint_instructions (
225- rpc,
226- decimals,
227- freeze_authority,
228- token_metadata. as_ref ( ) ,
190+ let mint_seed = self . seed . unwrap_or_else ( Keypair :: new) ;
191+ let address_tree = rpc. get_address_tree_v2 ( ) ;
192+ let output_queue = rpc. get_random_state_tree_info ( ) ?. queue ;
193+
194+ // Derive compression address
195+ let compression_address =
196+ derive_mint_compressed_address ( & mint_seed. pubkey ( ) , & address_tree. tree ) ;
197+
198+ // Find mint PDA
199+ let ( mint, bump) = find_mint_address ( & mint_seed. pubkey ( ) ) ;
200+
201+ // Get validity proof for the address
202+ let rpc_result = rpc
203+ . get_validity_proof (
204+ vec ! [ ] ,
205+ vec ! [ AddressWithTree {
206+ address: compression_address,
207+ tree: address_tree. tree,
208+ } ] ,
209+ None ,
210+ )
211+ . await
212+ . map_err ( |e| RpcError :: CustomError ( format ! ( "Failed to get validity proof: {}" , e) ) ) ?
213+ . value ;
214+
215+ // Build extensions if token metadata is provided
216+ let extensions = self . token_metadata . map ( |metadata| {
217+ let additional_metadata = metadata. additional_metadata . map ( |items| {
218+ items
219+ . into_iter ( )
220+ . map ( |( key, value) | AdditionalMetadata {
221+ key : key. into_bytes ( ) ,
222+ value : value. into_bytes ( ) ,
223+ } )
224+ . collect ( )
225+ } ) ;
226+
227+ vec ! [ ExtensionInstructionData :: TokenMetadata (
228+ TokenMetadataInstructionData {
229+ update_authority: Some (
230+ metadata
231+ . update_authority
232+ . unwrap_or_else( || mint_authority. pubkey( ) )
233+ . to_bytes( )
234+ . into( ) ,
235+ ) ,
236+ name: metadata. name. into_bytes( ) ,
237+ symbol: metadata. symbol. into_bytes( ) ,
238+ uri: metadata. uri. into_bytes( ) ,
239+ additional_metadata,
240+ } ,
241+ ) ]
242+ } ) ;
243+
244+ // Build params
245+ let params = CreateMintInstructionParams {
246+ decimals : self . decimals ,
247+ address_merkle_tree_root_index : rpc_result. addresses [ 0 ] . root_index ,
248+ mint_authority : mint_authority. pubkey ( ) ,
249+ proof : rpc_result. proof . 0 . ok_or_else ( || {
250+ RpcError :: CustomError ( "Validity proof is required for create_mint" . to_string ( ) )
251+ } ) ?,
252+ compression_address,
253+ mint,
254+ bump,
255+ freeze_authority : self . freeze_authority ,
256+ extensions,
257+ rent_payment : 16 , // ~24 hours rent
258+ write_top_up : 766 , // ~3 hours per write
259+ } ;
260+
261+ // Create instruction
262+ let instruction = CreateMintInstruction :: new (
263+ params,
229264 mint_seed. pubkey ( ) ,
230265 payer. pubkey ( ) ,
231- mint_authority. pubkey ( ) ,
266+ address_tree. tree ,
267+ output_queue,
232268 )
233- . await ?;
269+ . instruction ( )
270+ . map_err ( |e| RpcError :: CustomError ( format ! ( "Failed to create instruction: {}" , e) ) ) ?;
234271
235272 // Build signers list
236273 let mut signers: Vec < & Keypair > = vec ! [ payer, & mint_seed] ;
@@ -240,7 +277,7 @@ impl CreateMint {
240277
241278 // Send transaction
242279 let signature = rpc
243- . create_and_send_transaction ( & instructions , & payer. pubkey ( ) , & signers)
280+ . create_and_send_transaction ( & [ instruction ] , & payer. pubkey ( ) , & signers)
244281 . await ?;
245282
246283 Ok ( ( signature, mint) )
0 commit comments