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
use komodo_rpc_client::Chain;
use komodo_rpc_client::KomodoRpcApi;
use std::default::Default;
use crate::error::AirdropError;
use crate::error::ErrorKind;
#[derive(Debug, Clone)]
pub struct Snapshot {
pub chain: Chain,
pub addresses: Vec<Address>,
pub amount: f64,
}
pub struct SnapshotBuilder {
chain: Chain,
threshold: f64,
max_addresses: Option<u32>,
excluded_addresses: Option<Vec<String>>
}
#[derive(Debug, Clone)]
pub struct Address {
pub addr: String,
pub amount: f64
}
impl Snapshot {
pub fn builder() -> SnapshotBuilder {
Default::default()
}
}
impl SnapshotBuilder {
pub fn on_chain(&mut self, chain: Chain) -> &mut Self {
self.chain = chain;
self
}
pub fn using_threshold(&mut self, threshold: f64) -> &mut Self {
self.threshold = threshold;
self
}
pub fn max_addresses(&mut self, max: u32) -> &mut Self {
self.max_addresses = Some(max);
self
}
pub fn exclude_addresses(&mut self, addresses: Vec<String>) -> &mut Self {
self.excluded_addresses = Some(addresses);
self
}
pub fn build(&self) -> Result<Snapshot, AirdropError> {
let client = match &self.chain {
Chain::KMD => komodo_rpc_client::Client::new_komodo_client()?,
_ => komodo_rpc_client::Client::new_assetchain_client(&self.chain)?
};
let mut snapshot = match self.max_addresses {
Some(max) => client.get_snapshot_max(max),
None => client.get_snapshot()
}?;
if snapshot.addresses.is_empty() {
return Err(ErrorKind::EmptySnapshot.into())
}
if self.threshold > 0.0 {
snapshot.addresses = snapshot.addresses
.drain_filter(|saddress| saddress.amount > self.threshold)
.collect::<Vec<_>>();
}
let addresses = snapshot.addresses
.iter()
.filter(|address| {
let excluded_addresses = self.excluded_addresses.clone();
match excluded_addresses {
Some(vec) => !vec.contains(&address.addr),
None => return true
}
})
.map(|address| Address { addr: address.addr.clone(), amount: address.amount })
.collect::<Vec<_>>();
Ok(Snapshot {
chain: self.chain.clone(),
addresses,
amount: snapshot.total
})
}
}
impl Default for SnapshotBuilder {
fn default() -> Self {
SnapshotBuilder {
chain: Chain::KMD,
threshold: 0.0,
max_addresses: None,
excluded_addresses: None
}
}
}