sugar_cli/cli/
mod.rs

1use clap::{Parser, Subcommand};
2
3use crate::{
4    config::TokenStandard,
5    constants::{
6        DEFAULT_AIRDROP_LIST, DEFAULT_AIRDROP_LIST_HELP, DEFAULT_ASSETS, DEFAULT_CACHE,
7        DEFAULT_CONFIG,
8    },
9};
10
11#[derive(Parser)]
12#[clap(author, version, about)]
13pub struct Cli {
14    /// Log level: trace, debug, info, warn, error, off
15    #[clap(short, long, global = true)]
16    pub log_level: Option<String>,
17
18    #[clap(subcommand)]
19    pub command: Commands,
20}
21
22#[derive(Subcommand)]
23pub enum Commands {
24    /// Interact with the bundlr network
25    Bundlr {
26        /// Path to the keypair file, uses Sol config or defaults to "~/.config/miraland/id.json"
27        #[clap(short, long)]
28        keypair: Option<String>,
29
30        /// RPC Url
31        #[clap(short, long)]
32        rpc_url: Option<String>,
33
34        #[clap(subcommand)]
35        action: BundlrAction,
36    },
37
38    /// Manage the collection on the candy machine
39    Collection {
40        #[clap(subcommand)]
41        command: CollectionSubcommands,
42    },
43
44    /// Manage candy machine configuration
45    Config {
46        #[clap(subcommand)]
47        command: ConfigSubcommands,
48    },
49
50    /// Deploy cache items into candy machine config on-chain
51    Deploy {
52        /// Path to the config file, defaults to "config.json"
53        #[clap(short, long, default_value = DEFAULT_CONFIG)]
54        config: String,
55
56        /// Path to the keypair file, uses Sol config or defaults to "~/.config/miraland/id.json"
57        #[clap(short, long)]
58        keypair: Option<String>,
59
60        /// RPC Url
61        #[clap(short, long)]
62        rpc_url: Option<String>,
63
64        /// Path to the cache file, defaults to "cache.json"
65        #[clap(long, default_value = DEFAULT_CACHE)]
66        cache: String,
67
68        /// The optional collection address where the candymachine will mint the tokens to
69        #[clap(long)]
70        collection_mint: Option<String>,
71    },
72
73    /// Manage freeze guard actions
74    Freeze {
75        #[clap(subcommand)]
76        command: FreezeCommand,
77    },
78
79    /// Manage guards on the candy machine
80    Guard {
81        #[clap(subcommand)]
82        command: GuardCommand,
83    },
84
85    /// Generate hash of cache file for hidden settings.
86    Hash {
87        /// Path to the config file, defaults to "config.json"
88        #[clap(short, long, default_value = DEFAULT_CONFIG)]
89        config: String,
90
91        /// Path to the cache file, defaults to "cache.json"
92        #[clap(long, default_value = DEFAULT_CACHE)]
93        cache: String,
94
95        /// Compare a provided hash with a cache file to check integrity.
96        #[clap(long)]
97        compare: Option<String>,
98    },
99
100    /// Create a candy machine deployment from assets
101    Launch {
102        /// Path to the directory with the assets to upload
103        #[clap(default_value = DEFAULT_ASSETS)]
104        assets_dir: String,
105
106        /// Path to the keypair file [default: solana config or "~/.config/miraland/id.json"]
107        #[clap(short, long)]
108        keypair: Option<String>,
109
110        /// Path to the config file
111        #[clap(short, long, default_value = DEFAULT_CONFIG)]
112        config: String,
113
114        /// RPC Url
115        #[clap(short, long)]
116        rpc_url: Option<String>,
117
118        /// Path to the cache file
119        #[clap(long, default_value = DEFAULT_CACHE)]
120        cache: String,
121
122        /// Strict mode: validate against JSON metadata standard exactly
123        #[clap(long)]
124        strict: bool,
125
126        /// Skip collection validate prompt
127        #[clap(long)]
128        skip_collection_prompt: bool,
129    },
130
131    /// Mint one NFT from candy machine
132    Mint {
133        /// Path to the keypair file, uses Sol config or defaults to "~/.config/miraland/id.json"
134        #[clap(short, long)]
135        keypair: Option<String>,
136
137        /// RPC Url
138        #[clap(short, long)]
139        rpc_url: Option<String>,
140
141        /// Path to the cache file, defaults to "cache.json"
142        #[clap(long, default_value = DEFAULT_CACHE)]
143        cache: String,
144
145        /// Amount of NFTs to be minted in bulk
146        #[clap(short, long)]
147        number: Option<u64>,
148
149        /// Public key of the receiver of the minted NFT, defaults to keypair
150        #[clap(long)]
151        receiver: Option<String>,
152
153        /// Address of candy machine to mint from.
154        #[clap(long)]
155        candy_machine: Option<String>,
156    },
157    /// Airdrop NFTs from candy machine
158    Airdrop {
159        /// Path to the keypair file, uses Sol config or defaults to "~/.config/miraland/id.json"
160        #[clap(short, long)]
161        keypair: Option<String>,
162
163        /// RPC Url
164        #[clap(short, long)]
165        rpc_url: Option<String>,
166
167        /// Path to the cache file, defaults to "cache.json"
168        #[clap(long, default_value = DEFAULT_CACHE)]
169        cache: String,
170
171        /// Address of candy machine to mint from.
172        #[clap(long)]
173        candy_machine: Option<String>,
174
175        /// List of airdrop targets.
176        #[clap(long, default_value = DEFAULT_AIRDROP_LIST, help = DEFAULT_AIRDROP_LIST_HELP)]
177        airdrop_list: String,
178    },
179
180    /// Reveal the NFTs from a hidden settings candy machine
181    Reveal {
182        /// Path to the keypair file, uses Sol config or defaults to "~/.config/miraland/id.json"
183        #[clap(short, long)]
184        keypair: Option<String>,
185
186        /// RPC Url
187        #[clap(short, long)]
188        rpc_url: Option<String>,
189
190        /// Path to the cache file, defaults to "cache.json"
191        #[clap(long, default_value = DEFAULT_CACHE)]
192        cache: String,
193
194        /// Path to the config file
195        #[clap(short, long, default_value = DEFAULT_CONFIG)]
196        config: String,
197
198        /// RPC timeout to retrieve the mint list (in seconds).
199        #[clap(short, long)]
200        timeout: Option<u64>,
201    },
202
203    /// Show the on-chain config of an existing candy machine
204    Show {
205        /// Path to the keypair file, uses Sol config or defaults to "~/.config/miraland/id.json"
206        #[clap(short, long)]
207        keypair: Option<String>,
208
209        /// RPC Url
210        #[clap(short, long)]
211        rpc_url: Option<String>,
212
213        /// Path to the cache file, defaults to "cache.json"
214        #[clap(long, default_value = DEFAULT_CACHE)]
215        cache: String,
216
217        /// Address of candy machine
218        candy_machine: Option<String>,
219
220        /// Display a list of unminted indices
221        #[clap(long)]
222        unminted: bool,
223    },
224
225    /// Sign one or all NFTs from candy machine
226    Sign {
227        /// Path to the keypair file, uses Sol config or defaults to "~/.config/miraland/id.json"
228        #[clap(short, long)]
229        keypair: Option<String>,
230
231        /// RPC Url
232        #[clap(short, long)]
233        rpc_url: Option<String>,
234
235        /// Path to the cache file, defaults to "cache.json"
236        #[clap(long, default_value = DEFAULT_CACHE)]
237        cache: String,
238
239        /// Mint id for single NFT to be signed
240        #[clap(short, long)]
241        mint: Option<String>,
242
243        /// Candy machine id.
244        #[clap(long)]
245        candy_machine_id: Option<String>,
246    },
247
248    /// Upload assets to storage and creates the cache config
249    Upload {
250        /// Path to the directory with the assets to upload
251        #[clap(default_value = DEFAULT_ASSETS)]
252        assets_dir: String,
253
254        /// Path to the config file
255        #[clap(short, long, default_value = DEFAULT_CONFIG)]
256        config: String,
257
258        /// Path to the keypair file [default: solana config or "~/.config/miraland/id.json"]
259        #[clap(short, long)]
260        keypair: Option<String>,
261
262        /// RPC Url
263        #[clap(short, long)]
264        rpc_url: Option<String>,
265
266        /// Path to the cache file
267        #[clap(long, default_value = DEFAULT_CACHE)]
268        cache: String,
269    },
270
271    /// Validate JSON metadata files
272    Validate {
273        /// Assets directory to upload, defaults to "assets"
274        #[clap(default_value = DEFAULT_ASSETS)]
275        assets_dir: String,
276
277        /// Strict mode: validate against JSON metadata standard exactly
278        #[clap(long)]
279        strict: bool,
280
281        /// Skip collection prompt
282        #[clap(long)]
283        skip_collection_prompt: bool,
284    },
285
286    /// Verify uploaded data
287    Verify {
288        /// Path to the keypair file, uses Sol config or defaults to "~/.config/miraland/id.json"
289        #[clap(short, long)]
290        keypair: Option<String>,
291
292        /// RPC Url
293        #[clap(short, long)]
294        rpc_url: Option<String>,
295
296        /// Path to the cache file, defaults to "cache.json"
297        #[clap(long, default_value = DEFAULT_CACHE)]
298        cache: String,
299    },
300
301    /// Withdraw funds a from candy machine account closing it
302    Withdraw {
303        /// Address of candy machine to withdraw funds from.
304        #[clap(long)]
305        candy_machine: Option<String>,
306
307        /// Path to the keypair file, uses Sol config or defaults to "~/.config/miraland/id.json"
308        #[clap(short, long)]
309        keypair: Option<String>,
310
311        /// RPC Url
312        #[clap(short, long)]
313        rpc_url: Option<String>,
314
315        /// List available candy machines, no withdraw performed
316        #[clap(long)]
317        list: bool,
318    },
319}
320
321#[derive(Subcommand)]
322pub enum BundlrAction {
323    /// Retrieve the balance on bundlr
324    Balance,
325    /// Withdraw funds from bundlr
326    Withdraw,
327}
328
329#[derive(Subcommand)]
330pub enum ConfigSubcommands {
331    /// Interactive process to create a config file
332    Create {
333        /// Path to the config file
334        #[clap(short, long)]
335        config: Option<String>,
336
337        /// RPC Url
338        #[clap(short, long)]
339        rpc_url: Option<String>,
340
341        /// Path to the keypair file [default: solana config or "~/.config/miraland/id.json"]
342        #[clap(short, long)]
343        keypair: Option<String>,
344
345        /// Path to the directory with the assets
346        #[clap(default_value = DEFAULT_ASSETS)]
347        assets_dir: String,
348    },
349    /// Update the candy machine config on-chain
350    Update {
351        /// Path to the config file, defaults to "config.json"
352        #[clap(short, long, default_value = DEFAULT_CONFIG)]
353        config: String,
354
355        /// Path to the keypair file, uses Sol config or defaults to "~/.config/miraland/id.json"
356        #[clap(short, long)]
357        keypair: Option<String>,
358
359        /// RPC Url
360        #[clap(short, long)]
361        rpc_url: Option<String>,
362
363        /// Path to the cache file, defaults to "cache.json"
364        #[clap(long, default_value = DEFAULT_CACHE)]
365        cache: String,
366
367        /// Pubkey for the new authority
368        #[clap(short, long)]
369        new_authority: Option<String>,
370
371        /// Address of candy machine to update.
372        #[clap(long)]
373        candy_machine: Option<String>,
374    },
375    /// Set specific candy machine config values
376    Set {
377        /// Path to the keypair file, uses Sol config or defaults to "~/.config/miraland/id.json"
378        #[clap(short, long)]
379        keypair: Option<String>,
380
381        /// RPC Url
382        #[clap(short, long)]
383        rpc_url: Option<String>,
384
385        /// Path to the cache file, defaults to "cache.json"
386        #[clap(long, default_value = DEFAULT_CACHE)]
387        cache: String,
388
389        /// Token Standard to set.
390        #[clap(short, long)]
391        token_standard: Option<TokenStandard>,
392
393        /// Address of candy machine to update.
394        #[clap(long)]
395        candy_machine: Option<String>,
396
397        /// Address of the rule set to use.
398        #[clap(long)]
399        rule_set: Option<String>,
400    },
401}
402
403#[derive(Subcommand)]
404pub enum CollectionSubcommands {
405    /// Set the collection mint on the candy machine
406    Set {
407        /// Path to the keypair file, uses Sol config or defaults to "~/.config/miraland/id.json"
408        #[clap(short, long)]
409        keypair: Option<String>,
410
411        /// RPC Url
412        #[clap(short, long)]
413        rpc_url: Option<String>,
414
415        /// Path to the cache file, defaults to "cache.json"
416        #[clap(long, default_value = DEFAULT_CACHE)]
417        cache: String,
418
419        /// Path to the config file
420        #[clap(short, long, default_value = DEFAULT_CONFIG)]
421        config: String,
422
423        /// Address of candy machine to update.
424        #[clap(long)]
425        candy_machine: Option<String>,
426
427        /// Address of collection mint to set the candy machine to.
428        collection_mint: String,
429    },
430}
431
432#[derive(Subcommand)]
433pub enum GuardCommand {
434    /// Add a candy guard on a candy machine
435    Add {
436        /// Path to the keypair file, uses Sol config or defaults to "~/.config/miraland/id.json"
437        #[clap(short, long)]
438        keypair: Option<String>,
439
440        /// RPC Url
441        #[clap(short, long)]
442        rpc_url: Option<String>,
443
444        /// Path to the cache file, defaults to "cache.json"
445        #[clap(long, default_value = DEFAULT_CACHE)]
446        cache: String,
447
448        /// Path to the config file
449        #[clap(short, long, default_value = DEFAULT_CONFIG)]
450        config: String,
451
452        /// Address of the candy machine.
453        #[clap(long)]
454        candy_machine: Option<String>,
455
456        /// Address of the candy guard.
457        #[clap(long)]
458        candy_guard: Option<String>,
459    },
460    /// Remove a candy guard from a candy machine
461    Remove {
462        /// Path to the keypair file, uses Sol config or defaults to "~/.config/miraland/id.json"
463        #[clap(short, long)]
464        keypair: Option<String>,
465
466        /// RPC Url
467        #[clap(short, long)]
468        rpc_url: Option<String>,
469
470        /// Path to the cache file, defaults to "cache.json"
471        #[clap(long, default_value = DEFAULT_CACHE)]
472        cache: String,
473
474        /// Address of the candy machine.
475        #[clap(long)]
476        candy_machine: Option<String>,
477
478        /// Address of the candy guard.
479        #[clap(long)]
480        candy_guard: Option<String>,
481    },
482    /// Show the on-chain config of an existing candy guard
483    Show {
484        /// Path to the keypair file, uses Sol config or defaults to "~/.config/miraland/id.json"
485        #[clap(short, long)]
486        keypair: Option<String>,
487
488        /// RPC Url
489        #[clap(short, long)]
490        rpc_url: Option<String>,
491
492        /// Path to the cache file, defaults to "cache.json"
493        #[clap(long, default_value = DEFAULT_CACHE)]
494        cache: String,
495
496        /// Address of the candy guard.
497        #[clap(long)]
498        candy_guard: Option<String>,
499    },
500    /// Update the configuration of a candy guard
501    Update {
502        /// Path to the keypair file, uses Sol config or defaults to "~/.config/miraland/id.json"
503        #[clap(short, long)]
504        keypair: Option<String>,
505
506        /// RPC Url
507        #[clap(short, long)]
508        rpc_url: Option<String>,
509
510        /// Path to the cache file, defaults to "cache.json"
511        #[clap(long, default_value = DEFAULT_CACHE)]
512        cache: String,
513
514        /// Path to the config file
515        #[clap(short, long, default_value = DEFAULT_CONFIG)]
516        config: String,
517
518        /// Address of the candy guard.
519        #[clap(long)]
520        candy_guard: Option<String>,
521    },
522    /// Withdraw funds from a candy guard account closing it
523    Withdraw {
524        /// Path to the keypair file, uses Sol config or defaults to "~/.config/miraland/id.json"
525        #[clap(short, long)]
526        keypair: Option<String>,
527
528        /// RPC Url
529        #[clap(short, long)]
530        rpc_url: Option<String>,
531
532        /// Path to the cache file, defaults to "cache.json"
533        #[clap(long, default_value = DEFAULT_CACHE)]
534        cache: String,
535
536        /// Address of the candy guard.
537        #[clap(long)]
538        candy_guard: Option<String>,
539    },
540}
541
542#[derive(Subcommand)]
543pub enum FreezeCommand {
544    /// Initialize the freeze escrow account.
545    Initialize {
546        /// Path to the keypair file, uses Sol config or defaults to "~/.config/miraland/id.json"
547        #[clap(short, long)]
548        keypair: Option<String>,
549
550        /// RPC Url
551        #[clap(short, long)]
552        rpc_url: Option<String>,
553
554        /// Path to the cache file, defaults to "cache.json"
555        #[clap(long, default_value = DEFAULT_CACHE)]
556        cache: String,
557
558        /// Path to the config file
559        #[clap(short, long, default_value = DEFAULT_CONFIG)]
560        config: String,
561
562        /// Address of candy guard to update [defaults to cache value].
563        #[clap(long)]
564        candy_guard: Option<String>,
565
566        /// Address of candy machine to update [defaults to cache value].
567        #[clap(long)]
568        candy_machine: Option<String>,
569
570        /// Address of the destination (treasury) account.
571        #[clap(long)]
572        destination: Option<String>,
573
574        /// Candy guard group label.
575        #[clap(long)]
576        label: Option<String>,
577    },
578    /// Thaw a NFT or all NFTs in a candy guard.
579    Thaw {
580        /// Path to the keypair file, uses Sol config or defaults to "~/.config/miraland/id.json"
581        #[clap(short, long)]
582        keypair: Option<String>,
583
584        /// RPC Url
585        #[clap(short, long)]
586        rpc_url: Option<String>,
587
588        /// Path to the cache file, defaults to "cache.json"
589        #[clap(long, default_value = DEFAULT_CACHE)]
590        cache: String,
591
592        /// Path to the config file
593        #[clap(short, long, default_value = DEFAULT_CONFIG)]
594        config: String,
595
596        /// Unthaw all NFTs in the candy machine.
597        #[clap(long)]
598        all: bool,
599
600        /// Address of the NFT to thaw.
601        nft_mint: Option<String>,
602
603        /// Address of candy guard to update [defaults to cache value].
604        #[clap(long)]
605        candy_guard: Option<String>,
606
607        /// Address of candy machine to update [defaults to cache value].
608        #[clap(long)]
609        candy_machine: Option<String>,
610
611        /// Address of the destination (treaury) account.
612        #[clap(long)]
613        destination: Option<String>,
614
615        /// Candy guard group label.
616        #[clap(long)]
617        label: Option<String>,
618
619        /// Indicates to create/use a cache file for mint list.
620        #[clap(long)]
621        use_cache: bool,
622
623        /// RPC timeout to retrieve the mint list (in seconds).
624        #[clap(short, long)]
625        timeout: Option<u64>,
626    },
627    /// Unlock treasury funds after freeze is turned off or expires.
628    UnlockFunds {
629        /// Path to the keypair file, uses Sol config or defaults to "~/.config/miraland/id.json"
630        #[clap(short, long)]
631        keypair: Option<String>,
632
633        /// RPC Url
634        #[clap(short, long)]
635        rpc_url: Option<String>,
636
637        /// Path to the cache file, defaults to "cache.json"
638        #[clap(long, default_value = DEFAULT_CACHE)]
639        cache: String,
640
641        /// Path to the config file
642        #[clap(short, long, default_value = DEFAULT_CONFIG)]
643        config: String,
644
645        /// Address of candy guard to update [defaults to cache value].
646        #[clap(long)]
647        candy_guard: Option<String>,
648
649        /// Address of candy machine to update [defaults to cache value].
650        #[clap(long)]
651        candy_machine: Option<String>,
652
653        /// Address of the destination (treasury) account.
654        #[clap(long)]
655        destination: Option<String>,
656
657        /// Candy guard group label.
658        #[clap(long)]
659        label: Option<String>,
660    },
661}