1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
use std::{str::FromStr, thread::sleep, time::Duration};
pub use anchor_client::solana_sdk::hash::Hash;
use anchor_client::{
solana_sdk::{
program_pack::{IsInitialized, Pack},
pubkey::Pubkey,
},
Program,
};
pub use anyhow::{anyhow, Result};
use console::{style, Style};
use dialoguer::theme::ColorfulTheme;
pub use indicatif::{ProgressBar, ProgressStyle};
use solana_client::rpc_client::RpcClient;
use spl_token::state::{Account, Mint};
use crate::config::data::Cluster;
pub const DEVNET_HASH: &str = "EtWTRABZaYq6iMfeYKouRu166VU2xqa1wcaWoxPkrZBG";
pub const MAINNET_HASH: &str = "5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d";
pub fn get_cluster(rpc_client: RpcClient) -> Result<Cluster> {
let devnet_hash = Hash::from_str(DEVNET_HASH).unwrap();
let mainnet_hash = Hash::from_str(MAINNET_HASH).unwrap();
let genesis_hash = rpc_client.get_genesis_hash()?;
if genesis_hash == devnet_hash {
Ok(Cluster::Devnet)
} else if genesis_hash == mainnet_hash {
Ok(Cluster::Mainnet)
} else {
Err(anyhow!(format!(
"Genesis hash '{}' doesn't match supported Solana clusters for Candy Machine",
genesis_hash
)))
}
}
pub fn check_spl_token(program: &Program, input: &str) -> Result<Mint> {
let pubkey = Pubkey::from_str(input)?;
let token_data = program.rpc().get_account_data(&pubkey)?;
if token_data.len() != 82 {
return Err(anyhow!("Invalid spl-token passed in."));
}
let token_mint = Mint::unpack_from_slice(&token_data)?;
if token_mint.is_initialized {
Ok(token_mint)
} else {
Err(anyhow!(format!(
"The specified spl-token is not initialized: {}",
input
)))
}
}
pub fn check_spl_token_account(program: &Program, input: &str) -> Result<()> {
let pubkey = Pubkey::from_str(input)?;
let ata_data = program.rpc().get_account_data(&pubkey)?;
let ata_account = Account::unpack_unchecked(&ata_data)?;
if IsInitialized::is_initialized(&ata_account) {
Ok(())
} else {
Err(anyhow!(format!(
"The specified spl-token account is not initialized: {}",
input
)))
}
}
pub fn spinner_with_style() -> ProgressBar {
let pb = ProgressBar::new_spinner();
pb.enable_steady_tick(120);
pb.set_style(
ProgressStyle::default_spinner()
.tick_strings(&[
"▹▹▹▹▹",
"▸▹▹▹▹",
"▹▸▹▹▹",
"▹▹▸▹▹",
"▹▹▹▸▹",
"▹▹▹▹▸",
"▪▪▪▪▪",
])
.template("{spinner:.dim} {msg}"),
);
pb
}
pub fn wait_with_spinner_and_countdown(seconds: u64) {
let pb = spinner_with_style();
pb.enable_steady_tick(120);
for i in 0..seconds {
pb.set_message(
style(format!("Waiting {} seconds...", seconds - i))
.dim()
.to_string(),
);
sleep(Duration::from_secs(1));
}
pb.finish_and_clear();
}
pub fn progress_bar_with_style(len: u64) -> ProgressBar {
let pb = ProgressBar::new(len);
pb.tick();
pb.enable_steady_tick(1000);
pb.set_style(
ProgressStyle::default_bar().template("[{elapsed_precise}] {msg}{wide_bar} {pos}/{len}"),
);
pb
}
pub fn get_dialoguer_theme() -> ColorfulTheme {
ColorfulTheme {
prompt_style: Style::new(),
checked_item_prefix: style("✔".to_string()).green().force_styling(true),
unchecked_item_prefix: style("✔".to_string()).black().force_styling(true),
..Default::default()
}
}