sugar_cli/freeze/
initialize.rs

1use mpl_candy_guard::{
2    accounts::Route as RouteAccount, guards::FreezeInstruction, instruction::Route,
3    instructions::RouteArgs, state::GuardType,
4};
5
6use super::*;
7
8pub struct InitializeArgs {
9    pub keypair: Option<String>,
10    pub rpc_url: Option<String>,
11    pub cache: String,
12    pub config: String,
13    pub candy_guard: Option<String>,
14    pub candy_machine: Option<String>,
15    pub destination: Option<String>,
16    pub label: Option<String>,
17}
18
19pub fn process_initialize(args: InitializeArgs) -> Result<()> {
20    let sugar_config = sugar_setup(args.keypair.clone(), args.rpc_url.clone())?;
21    let client = setup_client(&sugar_config)?;
22    let program = client.program(mpl_candy_guard::ID);
23
24    // candy guard id specified takes precedence over the one from the cache
25    let candy_guard_id = match args.candy_guard {
26        Some(ref candy_guard_id) => candy_guard_id.to_owned(),
27        None => {
28            let cache = load_cache(&args.cache, false)?;
29            cache.program.candy_guard
30        }
31    };
32
33    // candy machine id specified takes precedence over the one from the cache
34    let candy_machine_id = match args.candy_machine {
35        Some(ref candy_machine_id) => candy_machine_id.to_owned(),
36        None => {
37            let cache = load_cache(&args.cache, false)?;
38            cache.program.candy_machine
39        }
40    };
41
42    let candy_guard = Pubkey::from_str(&candy_guard_id)
43        .map_err(|_| anyhow!("Failed to parse candy guard id: {}", &candy_guard_id))?;
44
45    let candy_machine = Pubkey::from_str(&candy_machine_id)
46        .map_err(|_| anyhow!("Failed to parse candy machine id: {}", &candy_guard_id))?;
47
48    println!(
49        "{} {}Loading freeze guard information",
50        style("[1/2]").bold().dim(),
51        LOOKING_GLASS_EMOJI
52    );
53
54    let pb = spinner_with_style();
55    pb.set_message("Connecting...");
56
57    // destination address specified takes precedence over the one from the cache
58    let destination_address = match args.destination {
59        Some(ref destination_address) => Pubkey::from_str(destination_address).map_err(|_| {
60            anyhow!(
61                "Failed to parse destination address: {}",
62                &destination_address
63            )
64        })?,
65        None => get_destination(
66            &program,
67            &candy_guard,
68            get_config_data(&args.config)?,
69            &args.label,
70        )?,
71    };
72
73    // sanity check: loads the PDA
74    let (freeze_escrow, _) = find_freeze_pda(&candy_guard, &candy_machine, &destination_address);
75    let account_data = program
76        .rpc()
77        .get_account_data(&freeze_escrow)
78        .map_err(|_| anyhow!("Could not load freeze escrow"))?;
79
80    if !account_data.is_empty() {
81        return Err(anyhow!("Freeze escrow already initialized"));
82    }
83
84    pb.finish_with_message("Done");
85
86    println!(
87        "\n{} {}Initializing freeze escrow",
88        style("[2/2]").bold().dim(),
89        MONEY_BAG_EMOJI
90    );
91
92    let pb = spinner_with_style();
93    pb.set_message("Sending initialize transaction...");
94
95    let signature = initialize(
96        &program,
97        &candy_guard,
98        &candy_machine,
99        &destination_address,
100        &args.label,
101    )?;
102
103    pb.finish_with_message(format!("{} {}", style("Signature:").bold(), signature));
104
105    Ok(())
106}
107
108pub fn initialize(
109    program: &Program,
110    candy_guard_id: &Pubkey,
111    candy_machine_id: &Pubkey,
112    destination: &Pubkey,
113    label: &Option<String>,
114) -> Result<Signature> {
115    let mut remaining_accounts = Vec::with_capacity(4);
116    let (freeze_pda, _) = find_freeze_pda(candy_guard_id, candy_machine_id, destination);
117    remaining_accounts.push(AccountMeta {
118        pubkey: freeze_pda,
119        is_signer: false,
120        is_writable: true,
121    });
122    remaining_accounts.push(AccountMeta {
123        pubkey: program.payer(),
124        is_signer: true,
125        is_writable: false,
126    });
127    remaining_accounts.push(AccountMeta {
128        pubkey: system_program::id(),
129        is_signer: false,
130        is_writable: false,
131    });
132
133    let builder = program
134        .request()
135        .accounts(RouteAccount {
136            candy_guard: *candy_guard_id,
137            candy_machine: *candy_machine_id,
138            payer: program.payer(),
139        })
140        .accounts(remaining_accounts)
141        .args(Route {
142            args: RouteArgs {
143                data: vec![FreezeInstruction::Initialize as u8],
144                guard: GuardType::FreezeSolPayment,
145            },
146            label: label.to_owned(),
147        });
148    let sig = builder.send()?;
149
150    Ok(sig)
151}