Skip to content

Commit 4628bfc

Browse files
upd create mint
1 parent 790f0c9 commit 4628bfc

1 file changed

Lines changed: 122 additions & 85 deletions

File tree

sdk-libs/token-client/src/actions/create_mint.rs

Lines changed: 122 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -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

192165
impl 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

Comments
 (0)