sugar_cli/update/
process.rs1use std::str::FromStr;
2
3use anchor_client::solana_sdk::pubkey::Pubkey;
4use anyhow::Result;
5use console::style;
6use mpl_candy_machine_core::{
7 accounts as nft_accounts, instruction as nft_instruction, CandyMachineData,
8};
9
10use crate::{
11 cache::load_cache,
12 candy_machine::{get_candy_machine_state, CANDY_MACHINE_ID},
13 common::*,
14 config::{data::ConfigData, parser::get_config_data},
15 utils::{assert_correct_authority, spinner_with_style},
16};
17
18pub struct UpdateArgs {
19 pub keypair: Option<String>,
20 pub rpc_url: Option<String>,
21 pub cache: String,
22 pub new_authority: Option<String>,
23 pub config: String,
24 pub candy_machine: Option<String>,
25}
26
27pub fn process_update(args: UpdateArgs) -> Result<()> {
28 let sugar_config = sugar_setup(args.keypair, args.rpc_url)?;
29 let client = setup_client(&sugar_config)?;
30 let config_data = get_config_data(&args.config)?;
31
32 let candy_machine_id = match args.candy_machine {
34 Some(candy_machine_id) => candy_machine_id,
35 None => {
36 let cache = load_cache(&args.cache, false)?;
37 cache.program.candy_machine
38 }
39 };
40
41 let candy_pubkey = match Pubkey::from_str(&candy_machine_id) {
42 Ok(candy_pubkey) => candy_pubkey,
43 Err(_) => {
44 let error = anyhow!("Failed to parse candy machine id: {}", candy_machine_id);
45 error!("{:?}", error);
46 return Err(error);
47 }
48 };
49
50 println!(
51 "{} {}Loading candy machine",
52 style("[1/2]").bold().dim(),
53 LOOKING_GLASS_EMOJI
54 );
55 println!("{} {}", style("Candy machine ID:").bold(), candy_machine_id);
56
57 let pb = spinner_with_style();
58 pb.set_message("Connecting...");
59
60 let candy_machine_state = get_candy_machine_state(&sugar_config, &candy_pubkey)?;
61 let candy_machine_data = create_candy_machine_data(&config_data, &candy_machine_state.data)?;
62
63 pb.finish_with_message("Done");
64
65 assert_correct_authority(
66 &sugar_config.keypair.pubkey(),
67 &candy_machine_state.authority,
68 )?;
69
70 println!(
71 "\n{} {}Updating configuration",
72 style("[2/2]").bold().dim(),
73 COMPUTER_EMOJI
74 );
75
76 let program = client.program(CANDY_MACHINE_ID);
77 let builder = program
78 .request()
79 .accounts(nft_accounts::Update {
80 candy_machine: candy_pubkey,
81 authority: program.payer(),
82 })
83 .args(nft_instruction::Update {
84 data: candy_machine_data,
85 });
86
87 let pb = spinner_with_style();
88 pb.set_message("Sending update transaction...");
89
90 let update_signature = builder.send()?;
91
92 pb.finish_with_message(format!(
93 "{} {}",
94 style("Update signature:").bold(),
95 update_signature
96 ));
97
98 if let Some(new_authority) = args.new_authority {
99 let pb = spinner_with_style();
100 pb.set_message("Sending update authority transaction...");
101
102 let new_authority_pubkey = Pubkey::from_str(&new_authority)?;
103 let builder = program
104 .request()
105 .accounts(nft_accounts::SetAuthority {
106 candy_machine: candy_pubkey,
107 authority: program.payer(),
108 })
109 .args(nft_instruction::SetAuthority {
110 new_authority: new_authority_pubkey,
111 });
112
113 let authority_signature = builder.send()?;
114 pb.finish_with_message(format!(
115 "{} {}",
116 style("Authority signature:").bold(),
117 authority_signature
118 ));
119 }
120
121 Ok(())
122}
123
124fn create_candy_machine_data(
125 config: &ConfigData,
126 candy_machine: &CandyMachineData,
127) -> Result<CandyMachineData> {
128 let hidden_settings = config.hidden_settings.as_ref().map(|s| s.to_candy_format());
129
130 let creators = config
131 .creators
132 .clone()
133 .into_iter()
134 .map(|c| c.to_candy_format())
135 .collect::<Result<Vec<mpl_candy_machine_core::Creator>>>()?;
136
137 let data = CandyMachineData {
138 symbol: config.symbol.clone(),
139 seller_fee_basis_points: config.seller_fee_basis_points,
140 max_supply: 0,
141 is_mutable: config.is_mutable,
142 creators,
143 hidden_settings,
144 config_line_settings: candy_machine.config_line_settings.clone(),
145 items_available: config.number,
146 };
147 Ok(data)
148}