1use borsh::{BorshDeserialize, BorshSerialize};
9
10pub const CREATE_TOKEN_METADATA_DISCRIMINATOR: [u8; 8] = [221, 80, 176, 37, 153, 188, 160, 68];
11
12#[derive(Debug)]
14pub struct CreateTokenMetadata {
15 pub admin: solana_program::pubkey::Pubkey,
16
17 pub perpetuals: solana_program::pubkey::Pubkey,
18
19 pub pool: solana_program::pubkey::Pubkey,
20
21 pub transfer_authority: solana_program::pubkey::Pubkey,
22
23 pub metadata: solana_program::pubkey::Pubkey,
24
25 pub lp_token_mint: solana_program::pubkey::Pubkey,
26
27 pub token_metadata_program: solana_program::pubkey::Pubkey,
28
29 pub system_program: solana_program::pubkey::Pubkey,
30
31 pub rent: solana_program::pubkey::Pubkey,
32}
33
34impl CreateTokenMetadata {
35 pub fn instruction(
36 &self,
37 args: CreateTokenMetadataInstructionArgs,
38 ) -> solana_program::instruction::Instruction {
39 self.instruction_with_remaining_accounts(args, &[])
40 }
41 #[allow(clippy::arithmetic_side_effects)]
42 #[allow(clippy::vec_init_then_push)]
43 pub fn instruction_with_remaining_accounts(
44 &self,
45 args: CreateTokenMetadataInstructionArgs,
46 remaining_accounts: &[solana_program::instruction::AccountMeta],
47 ) -> solana_program::instruction::Instruction {
48 let mut accounts = Vec::with_capacity(9 + remaining_accounts.len());
49 accounts.push(solana_program::instruction::AccountMeta::new(
50 self.admin, true,
51 ));
52 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
53 self.perpetuals,
54 false,
55 ));
56 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
57 self.pool, false,
58 ));
59 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
60 self.transfer_authority,
61 false,
62 ));
63 accounts.push(solana_program::instruction::AccountMeta::new(
64 self.metadata,
65 false,
66 ));
67 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
68 self.lp_token_mint,
69 false,
70 ));
71 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
72 self.token_metadata_program,
73 false,
74 ));
75 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
76 self.system_program,
77 false,
78 ));
79 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
80 self.rent, false,
81 ));
82 accounts.extend_from_slice(remaining_accounts);
83 let mut data = borsh::to_vec(&CreateTokenMetadataInstructionData::new()).unwrap();
84 let mut args = borsh::to_vec(&args).unwrap();
85 data.append(&mut args);
86
87 solana_program::instruction::Instruction {
88 program_id: crate::PERPETUALS_ID,
89 accounts,
90 data,
91 }
92 }
93}
94
95#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, PartialEq)]
96#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
97pub struct CreateTokenMetadataInstructionData {
98 discriminator: [u8; 8],
99}
100
101impl CreateTokenMetadataInstructionData {
102 pub fn new() -> Self {
103 Self {
104 discriminator: [221, 80, 176, 37, 153, 188, 160, 68],
105 }
106 }
107}
108
109impl Default for CreateTokenMetadataInstructionData {
110 fn default() -> Self {
111 Self::new()
112 }
113}
114
115#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, PartialEq)]
116#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
117pub struct CreateTokenMetadataInstructionArgs {
118 pub name: String,
119 pub symbol: String,
120 pub uri: String,
121}
122
123#[derive(Clone, Debug, Default)]
137pub struct CreateTokenMetadataBuilder {
138 admin: Option<solana_program::pubkey::Pubkey>,
139 perpetuals: Option<solana_program::pubkey::Pubkey>,
140 pool: Option<solana_program::pubkey::Pubkey>,
141 transfer_authority: Option<solana_program::pubkey::Pubkey>,
142 metadata: Option<solana_program::pubkey::Pubkey>,
143 lp_token_mint: Option<solana_program::pubkey::Pubkey>,
144 token_metadata_program: Option<solana_program::pubkey::Pubkey>,
145 system_program: Option<solana_program::pubkey::Pubkey>,
146 rent: Option<solana_program::pubkey::Pubkey>,
147 name: Option<String>,
148 symbol: Option<String>,
149 uri: Option<String>,
150 __remaining_accounts: Vec<solana_program::instruction::AccountMeta>,
151}
152
153impl CreateTokenMetadataBuilder {
154 pub fn new() -> Self {
155 Self::default()
156 }
157 #[inline(always)]
158 pub fn admin(&mut self, admin: solana_program::pubkey::Pubkey) -> &mut Self {
159 self.admin = Some(admin);
160 self
161 }
162 #[inline(always)]
163 pub fn perpetuals(&mut self, perpetuals: solana_program::pubkey::Pubkey) -> &mut Self {
164 self.perpetuals = Some(perpetuals);
165 self
166 }
167 #[inline(always)]
168 pub fn pool(&mut self, pool: solana_program::pubkey::Pubkey) -> &mut Self {
169 self.pool = Some(pool);
170 self
171 }
172 #[inline(always)]
173 pub fn transfer_authority(
174 &mut self,
175 transfer_authority: solana_program::pubkey::Pubkey,
176 ) -> &mut Self {
177 self.transfer_authority = Some(transfer_authority);
178 self
179 }
180 #[inline(always)]
181 pub fn metadata(&mut self, metadata: solana_program::pubkey::Pubkey) -> &mut Self {
182 self.metadata = Some(metadata);
183 self
184 }
185 #[inline(always)]
186 pub fn lp_token_mint(&mut self, lp_token_mint: solana_program::pubkey::Pubkey) -> &mut Self {
187 self.lp_token_mint = Some(lp_token_mint);
188 self
189 }
190 #[inline(always)]
192 pub fn token_metadata_program(
193 &mut self,
194 token_metadata_program: solana_program::pubkey::Pubkey,
195 ) -> &mut Self {
196 self.token_metadata_program = Some(token_metadata_program);
197 self
198 }
199 #[inline(always)]
201 pub fn system_program(&mut self, system_program: solana_program::pubkey::Pubkey) -> &mut Self {
202 self.system_program = Some(system_program);
203 self
204 }
205 #[inline(always)]
207 pub fn rent(&mut self, rent: solana_program::pubkey::Pubkey) -> &mut Self {
208 self.rent = Some(rent);
209 self
210 }
211 #[inline(always)]
212 pub fn name(&mut self, name: String) -> &mut Self {
213 self.name = Some(name);
214 self
215 }
216 #[inline(always)]
217 pub fn symbol(&mut self, symbol: String) -> &mut Self {
218 self.symbol = Some(symbol);
219 self
220 }
221 #[inline(always)]
222 pub fn uri(&mut self, uri: String) -> &mut Self {
223 self.uri = Some(uri);
224 self
225 }
226 #[inline(always)]
228 pub fn add_remaining_account(
229 &mut self,
230 account: solana_program::instruction::AccountMeta,
231 ) -> &mut Self {
232 self.__remaining_accounts.push(account);
233 self
234 }
235 #[inline(always)]
237 pub fn add_remaining_accounts(
238 &mut self,
239 accounts: &[solana_program::instruction::AccountMeta],
240 ) -> &mut Self {
241 self.__remaining_accounts.extend_from_slice(accounts);
242 self
243 }
244 #[allow(clippy::clone_on_copy)]
245 pub fn instruction(&self) -> solana_program::instruction::Instruction {
246 let accounts =
247 CreateTokenMetadata {
248 admin: self.admin.expect("admin is not set"),
249 perpetuals: self.perpetuals.expect("perpetuals is not set"),
250 pool: self.pool.expect("pool is not set"),
251 transfer_authority: self
252 .transfer_authority
253 .expect("transfer_authority is not set"),
254 metadata: self.metadata.expect("metadata is not set"),
255 lp_token_mint: self.lp_token_mint.expect("lp_token_mint is not set"),
256 token_metadata_program: self.token_metadata_program.unwrap_or(
257 solana_program::pubkey!("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"),
258 ),
259 system_program: self
260 .system_program
261 .unwrap_or(solana_program::pubkey!("11111111111111111111111111111111")),
262 rent: self.rent.unwrap_or(solana_program::pubkey!(
263 "SysvarRent111111111111111111111111111111111"
264 )),
265 };
266 let args = CreateTokenMetadataInstructionArgs {
267 name: self.name.clone().expect("name is not set"),
268 symbol: self.symbol.clone().expect("symbol is not set"),
269 uri: self.uri.clone().expect("uri is not set"),
270 };
271
272 accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts)
273 }
274}
275
276pub struct CreateTokenMetadataCpiAccounts<'a, 'b> {
278 pub admin: &'b solana_program::account_info::AccountInfo<'a>,
279
280 pub perpetuals: &'b solana_program::account_info::AccountInfo<'a>,
281
282 pub pool: &'b solana_program::account_info::AccountInfo<'a>,
283
284 pub transfer_authority: &'b solana_program::account_info::AccountInfo<'a>,
285
286 pub metadata: &'b solana_program::account_info::AccountInfo<'a>,
287
288 pub lp_token_mint: &'b solana_program::account_info::AccountInfo<'a>,
289
290 pub token_metadata_program: &'b solana_program::account_info::AccountInfo<'a>,
291
292 pub system_program: &'b solana_program::account_info::AccountInfo<'a>,
293
294 pub rent: &'b solana_program::account_info::AccountInfo<'a>,
295}
296
297pub struct CreateTokenMetadataCpi<'a, 'b> {
299 pub __program: &'b solana_program::account_info::AccountInfo<'a>,
301
302 pub admin: &'b solana_program::account_info::AccountInfo<'a>,
303
304 pub perpetuals: &'b solana_program::account_info::AccountInfo<'a>,
305
306 pub pool: &'b solana_program::account_info::AccountInfo<'a>,
307
308 pub transfer_authority: &'b solana_program::account_info::AccountInfo<'a>,
309
310 pub metadata: &'b solana_program::account_info::AccountInfo<'a>,
311
312 pub lp_token_mint: &'b solana_program::account_info::AccountInfo<'a>,
313
314 pub token_metadata_program: &'b solana_program::account_info::AccountInfo<'a>,
315
316 pub system_program: &'b solana_program::account_info::AccountInfo<'a>,
317
318 pub rent: &'b solana_program::account_info::AccountInfo<'a>,
319 pub __args: CreateTokenMetadataInstructionArgs,
321}
322
323impl<'a, 'b> CreateTokenMetadataCpi<'a, 'b> {
324 pub fn new(
325 program: &'b solana_program::account_info::AccountInfo<'a>,
326 accounts: CreateTokenMetadataCpiAccounts<'a, 'b>,
327 args: CreateTokenMetadataInstructionArgs,
328 ) -> Self {
329 Self {
330 __program: program,
331 admin: accounts.admin,
332 perpetuals: accounts.perpetuals,
333 pool: accounts.pool,
334 transfer_authority: accounts.transfer_authority,
335 metadata: accounts.metadata,
336 lp_token_mint: accounts.lp_token_mint,
337 token_metadata_program: accounts.token_metadata_program,
338 system_program: accounts.system_program,
339 rent: accounts.rent,
340 __args: args,
341 }
342 }
343 #[inline(always)]
344 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
345 self.invoke_signed_with_remaining_accounts(&[], &[])
346 }
347 #[inline(always)]
348 pub fn invoke_with_remaining_accounts(
349 &self,
350 remaining_accounts: &[(
351 &'b solana_program::account_info::AccountInfo<'a>,
352 bool,
353 bool,
354 )],
355 ) -> solana_program::entrypoint::ProgramResult {
356 self.invoke_signed_with_remaining_accounts(&[], remaining_accounts)
357 }
358 #[inline(always)]
359 pub fn invoke_signed(
360 &self,
361 signers_seeds: &[&[&[u8]]],
362 ) -> solana_program::entrypoint::ProgramResult {
363 self.invoke_signed_with_remaining_accounts(signers_seeds, &[])
364 }
365 #[allow(clippy::arithmetic_side_effects)]
366 #[allow(clippy::clone_on_copy)]
367 #[allow(clippy::vec_init_then_push)]
368 pub fn invoke_signed_with_remaining_accounts(
369 &self,
370 signers_seeds: &[&[&[u8]]],
371 remaining_accounts: &[(
372 &'b solana_program::account_info::AccountInfo<'a>,
373 bool,
374 bool,
375 )],
376 ) -> solana_program::entrypoint::ProgramResult {
377 let mut accounts = Vec::with_capacity(9 + remaining_accounts.len());
378 accounts.push(solana_program::instruction::AccountMeta::new(
379 *self.admin.key,
380 true,
381 ));
382 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
383 *self.perpetuals.key,
384 false,
385 ));
386 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
387 *self.pool.key,
388 false,
389 ));
390 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
391 *self.transfer_authority.key,
392 false,
393 ));
394 accounts.push(solana_program::instruction::AccountMeta::new(
395 *self.metadata.key,
396 false,
397 ));
398 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
399 *self.lp_token_mint.key,
400 false,
401 ));
402 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
403 *self.token_metadata_program.key,
404 false,
405 ));
406 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
407 *self.system_program.key,
408 false,
409 ));
410 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
411 *self.rent.key,
412 false,
413 ));
414 remaining_accounts.iter().for_each(|remaining_account| {
415 accounts.push(solana_program::instruction::AccountMeta {
416 pubkey: *remaining_account.0.key,
417 is_signer: remaining_account.1,
418 is_writable: remaining_account.2,
419 })
420 });
421 let mut data = borsh::to_vec(&CreateTokenMetadataInstructionData::new()).unwrap();
422 let mut args = borsh::to_vec(&self.__args).unwrap();
423 data.append(&mut args);
424
425 let instruction = solana_program::instruction::Instruction {
426 program_id: crate::PERPETUALS_ID,
427 accounts,
428 data,
429 };
430 let mut account_infos = Vec::with_capacity(10 + remaining_accounts.len());
431 account_infos.push(self.__program.clone());
432 account_infos.push(self.admin.clone());
433 account_infos.push(self.perpetuals.clone());
434 account_infos.push(self.pool.clone());
435 account_infos.push(self.transfer_authority.clone());
436 account_infos.push(self.metadata.clone());
437 account_infos.push(self.lp_token_mint.clone());
438 account_infos.push(self.token_metadata_program.clone());
439 account_infos.push(self.system_program.clone());
440 account_infos.push(self.rent.clone());
441 remaining_accounts
442 .iter()
443 .for_each(|remaining_account| account_infos.push(remaining_account.0.clone()));
444
445 if signers_seeds.is_empty() {
446 solana_program::program::invoke(&instruction, &account_infos)
447 } else {
448 solana_program::program::invoke_signed(&instruction, &account_infos, signers_seeds)
449 }
450 }
451}
452
453#[derive(Clone, Debug)]
467pub struct CreateTokenMetadataCpiBuilder<'a, 'b> {
468 instruction: Box<CreateTokenMetadataCpiBuilderInstruction<'a, 'b>>,
469}
470
471impl<'a, 'b> CreateTokenMetadataCpiBuilder<'a, 'b> {
472 pub fn new(program: &'b solana_program::account_info::AccountInfo<'a>) -> Self {
473 let instruction = Box::new(CreateTokenMetadataCpiBuilderInstruction {
474 __program: program,
475 admin: None,
476 perpetuals: None,
477 pool: None,
478 transfer_authority: None,
479 metadata: None,
480 lp_token_mint: None,
481 token_metadata_program: None,
482 system_program: None,
483 rent: None,
484 name: None,
485 symbol: None,
486 uri: None,
487 __remaining_accounts: Vec::new(),
488 });
489 Self { instruction }
490 }
491 #[inline(always)]
492 pub fn admin(&mut self, admin: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
493 self.instruction.admin = Some(admin);
494 self
495 }
496 #[inline(always)]
497 pub fn perpetuals(
498 &mut self,
499 perpetuals: &'b solana_program::account_info::AccountInfo<'a>,
500 ) -> &mut Self {
501 self.instruction.perpetuals = Some(perpetuals);
502 self
503 }
504 #[inline(always)]
505 pub fn pool(&mut self, pool: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
506 self.instruction.pool = Some(pool);
507 self
508 }
509 #[inline(always)]
510 pub fn transfer_authority(
511 &mut self,
512 transfer_authority: &'b solana_program::account_info::AccountInfo<'a>,
513 ) -> &mut Self {
514 self.instruction.transfer_authority = Some(transfer_authority);
515 self
516 }
517 #[inline(always)]
518 pub fn metadata(
519 &mut self,
520 metadata: &'b solana_program::account_info::AccountInfo<'a>,
521 ) -> &mut Self {
522 self.instruction.metadata = Some(metadata);
523 self
524 }
525 #[inline(always)]
526 pub fn lp_token_mint(
527 &mut self,
528 lp_token_mint: &'b solana_program::account_info::AccountInfo<'a>,
529 ) -> &mut Self {
530 self.instruction.lp_token_mint = Some(lp_token_mint);
531 self
532 }
533 #[inline(always)]
534 pub fn token_metadata_program(
535 &mut self,
536 token_metadata_program: &'b solana_program::account_info::AccountInfo<'a>,
537 ) -> &mut Self {
538 self.instruction.token_metadata_program = Some(token_metadata_program);
539 self
540 }
541 #[inline(always)]
542 pub fn system_program(
543 &mut self,
544 system_program: &'b solana_program::account_info::AccountInfo<'a>,
545 ) -> &mut Self {
546 self.instruction.system_program = Some(system_program);
547 self
548 }
549 #[inline(always)]
550 pub fn rent(&mut self, rent: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
551 self.instruction.rent = Some(rent);
552 self
553 }
554 #[inline(always)]
555 pub fn name(&mut self, name: String) -> &mut Self {
556 self.instruction.name = Some(name);
557 self
558 }
559 #[inline(always)]
560 pub fn symbol(&mut self, symbol: String) -> &mut Self {
561 self.instruction.symbol = Some(symbol);
562 self
563 }
564 #[inline(always)]
565 pub fn uri(&mut self, uri: String) -> &mut Self {
566 self.instruction.uri = Some(uri);
567 self
568 }
569 #[inline(always)]
571 pub fn add_remaining_account(
572 &mut self,
573 account: &'b solana_program::account_info::AccountInfo<'a>,
574 is_writable: bool,
575 is_signer: bool,
576 ) -> &mut Self {
577 self.instruction
578 .__remaining_accounts
579 .push((account, is_writable, is_signer));
580 self
581 }
582 #[inline(always)]
587 pub fn add_remaining_accounts(
588 &mut self,
589 accounts: &[(
590 &'b solana_program::account_info::AccountInfo<'a>,
591 bool,
592 bool,
593 )],
594 ) -> &mut Self {
595 self.instruction
596 .__remaining_accounts
597 .extend_from_slice(accounts);
598 self
599 }
600 #[inline(always)]
601 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
602 self.invoke_signed(&[])
603 }
604 #[allow(clippy::clone_on_copy)]
605 #[allow(clippy::vec_init_then_push)]
606 pub fn invoke_signed(
607 &self,
608 signers_seeds: &[&[&[u8]]],
609 ) -> solana_program::entrypoint::ProgramResult {
610 let args = CreateTokenMetadataInstructionArgs {
611 name: self.instruction.name.clone().expect("name is not set"),
612 symbol: self.instruction.symbol.clone().expect("symbol is not set"),
613 uri: self.instruction.uri.clone().expect("uri is not set"),
614 };
615 let instruction = CreateTokenMetadataCpi {
616 __program: self.instruction.__program,
617
618 admin: self.instruction.admin.expect("admin is not set"),
619
620 perpetuals: self.instruction.perpetuals.expect("perpetuals is not set"),
621
622 pool: self.instruction.pool.expect("pool is not set"),
623
624 transfer_authority: self
625 .instruction
626 .transfer_authority
627 .expect("transfer_authority is not set"),
628
629 metadata: self.instruction.metadata.expect("metadata is not set"),
630
631 lp_token_mint: self
632 .instruction
633 .lp_token_mint
634 .expect("lp_token_mint is not set"),
635
636 token_metadata_program: self
637 .instruction
638 .token_metadata_program
639 .expect("token_metadata_program is not set"),
640
641 system_program: self
642 .instruction
643 .system_program
644 .expect("system_program is not set"),
645
646 rent: self.instruction.rent.expect("rent is not set"),
647 __args: args,
648 };
649 instruction.invoke_signed_with_remaining_accounts(
650 signers_seeds,
651 &self.instruction.__remaining_accounts,
652 )
653 }
654}
655
656#[derive(Clone, Debug)]
657struct CreateTokenMetadataCpiBuilderInstruction<'a, 'b> {
658 __program: &'b solana_program::account_info::AccountInfo<'a>,
659 admin: Option<&'b solana_program::account_info::AccountInfo<'a>>,
660 perpetuals: Option<&'b solana_program::account_info::AccountInfo<'a>>,
661 pool: Option<&'b solana_program::account_info::AccountInfo<'a>>,
662 transfer_authority: Option<&'b solana_program::account_info::AccountInfo<'a>>,
663 metadata: Option<&'b solana_program::account_info::AccountInfo<'a>>,
664 lp_token_mint: Option<&'b solana_program::account_info::AccountInfo<'a>>,
665 token_metadata_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
666 system_program: Option<&'b solana_program::account_info::AccountInfo<'a>>,
667 rent: Option<&'b solana_program::account_info::AccountInfo<'a>>,
668 name: Option<String>,
669 symbol: Option<String>,
670 uri: Option<String>,
671 __remaining_accounts: Vec<(
673 &'b solana_program::account_info::AccountInfo<'a>,
674 bool,
675 bool,
676 )>,
677}