sugar_cli/update/
set_token_standard.rs1use std::str::FromStr;
2
3use anchor_client::solana_sdk::pubkey::Pubkey;
4use anyhow::Result;
5use console::style;
6use mpl_candy_machine_core::{accounts::SetTokenStandard, AccountVersion};
7use mpl_token_metadata::{
8 instruction::MetadataDelegateRole,
9 pda::{find_collection_authority_account, find_metadata_delegate_record_account},
10};
11
12use crate::{
13 cache::load_cache,
14 candy_machine::{get_candy_machine_state, CANDY_MACHINE_ID},
15 common::*,
16 config::TokenStandard,
17 pdas::{find_candy_machine_creator_pda, find_metadata_pda, get_metadata_pda},
18 utils::*,
19};
20
21pub struct SetTokenStandardArgs {
22 pub keypair: Option<String>,
23 pub rpc_url: Option<String>,
24 pub cache: String,
25 pub token_standard: Option<TokenStandard>,
26 pub candy_machine: Option<String>,
27 pub rule_set: Option<String>,
28}
29
30pub fn process_set_token_stardard(args: SetTokenStandardArgs) -> Result<()> {
31 if args.token_standard.is_none() && args.rule_set.is_none() {
33 return Err(anyhow!(
34 "You need to specify a token standard and/or rule set."
35 ));
36 }
37
38 println!("[1/2] {}Loading candy machine", LOOKING_GLASS_EMOJI);
39
40 let candy_machine_id = if let Some(candy_machine) = args.candy_machine {
43 candy_machine
44 } else {
45 let cache = load_cache(&args.cache, false)?;
46 cache.program.candy_machine
47 };
48
49 if candy_machine_id.is_empty() {
50 return Err(anyhow!("Missing candy guard id."));
51 }
52
53 let candy_machine_id = match Pubkey::from_str(&candy_machine_id) {
54 Ok(candy_machine_id) => candy_machine_id,
55 Err(_) => {
56 let error = anyhow!("Failed to parse candy machine id: {}", candy_machine_id);
57 error!("{:?}", error);
58 return Err(error);
59 }
60 };
61
62 let sugar_config = sugar_setup(args.keypair, args.rpc_url)?;
63 let client = setup_client(&sugar_config)?;
64 let program = client.program(CANDY_MACHINE_ID);
65
66 let pb = spinner_with_style();
67 pb.set_message("Connecting...");
68
69 let candy_machine_state = get_candy_machine_state(&sugar_config, &candy_machine_id)?;
70
71 pb.finish_with_message("Done");
72
73 let message = if args.token_standard.is_some() {
74 if args.rule_set.is_some() {
75 "token standard and rule set"
76 } else {
77 "token standard"
78 }
79 } else {
80 "rule set"
81 };
82
83 println!("\n[2/2] {}Setting {}", WITHDRAW_EMOJI, message);
84
85 let pb = spinner_with_style();
86 pb.set_message("Connecting...");
87
88 let (authority_pda, _) = find_candy_machine_creator_pda(&candy_machine_id);
89 let collection_mint = candy_machine_state.collection_mint;
90 let collection_metadata = find_metadata_pda(&collection_mint);
91 let (_, collection_metadata_pda) =
92 get_metadata_pda(&candy_machine_state.collection_mint, &program)?;
93 let collection_update_authority = collection_metadata_pda.update_authority;
94
95 let collection_authority_record = if matches!(candy_machine_state.version, AccountVersion::V1) {
96 Some(find_collection_authority_account(&collection_mint, &authority_pda).0)
97 } else {
98 None
99 };
100
101 let collection_delegate_record = find_metadata_delegate_record_account(
102 &collection_mint,
103 MetadataDelegateRole::Collection,
104 &collection_update_authority,
105 &authority_pda,
106 )
107 .0;
108
109 let token_standard = if let Some(token_standard) = args.token_standard {
112 <TokenStandard as std::convert::Into<mpl_token_metadata::state::TokenStandard>>::into(
113 token_standard,
114 ) as u8
115 } else {
116 candy_machine_state.token_standard
117 };
118
119 let payer = sugar_config.keypair;
120
121 let tx = program
122 .request()
123 .accounts(SetTokenStandard {
124 candy_machine: candy_machine_id,
125 authority_pda,
126 authority: payer.pubkey(),
127 payer: payer.pubkey(),
128 collection_metadata,
129 collection_mint,
130 collection_update_authority,
131 collection_authority_record,
132 collection_delegate_record,
133 rule_set: if let Some(rule_set) = args.rule_set {
134 Some(Pubkey::from_str(&rule_set)?)
135 } else {
136 None
137 },
138 system_program: system_program::ID,
139 sysvar_instructions: sysvar::instructions::ID,
140 token_metadata_program: mpl_token_metadata::ID,
141 authorization_rules_program: None,
142 authorization_rules: None,
143 })
144 .args(mpl_candy_machine_core::instruction::SetTokenStandard { token_standard });
145
146 let sig = tx.send()?;
147
148 pb.finish_and_clear();
149 println!("{} {}", style("Signature:").bold(), sig);
150
151 Ok(())
152}