ant_act/
lib.rs

1mod act;
2mod wallet;
3
4pub use act::{ActExt, TokenInfo};
5pub use wallet::{Wallet, WalletExt};
6
7#[cfg(test)]
8mod tests {
9    //	use sn_curv::elliptic::curves::ECScalar;
10    use autonomi::Wallet as EvmWallet;
11    use tracing::Level;
12
13    use autonomi::{client::payment::PaymentOption, Client, GraphEntry, PublicKey, SecretKey};
14    use ruint::aliases::U256;
15
16    use crate::*;
17
18    fn init_logging() {
19        let logging_targets = vec![
20            ("ant_bootstrap".to_string(), Level::INFO),
21            ("ant_build_info".to_string(), Level::TRACE),
22            ("ant_evm".to_string(), Level::TRACE),
23            ("ant_networking".to_string(), Level::INFO),
24            ("autonomi_cli".to_string(), Level::TRACE),
25            ("autonomi".to_string(), Level::TRACE),
26            ("evmlib".to_string(), Level::TRACE),
27            ("ant_logging".to_string(), Level::TRACE),
28            ("ant_protocol".to_string(), Level::TRACE),
29            ("ant_cli".to_string(), Level::TRACE),
30        ];
31        let mut log_builder = ant_logging::LogBuilder::new(logging_targets);
32        log_builder.output_dest(ant_logging::LogOutputDest::Stdout);
33        log_builder.format(ant_logging::LogFormat::Default);
34        let (_, _) = log_builder.initialize().expect("Init logging");
35    }
36
37    fn amount(n: u64, decimals: u8) -> U256 {
38        U256::from(n)
39            .checked_mul(
40                U256::from(10)
41                    .checked_pow(U256::from(decimals))
42                    .expect("U256 Overflow"), // TODO: error/result
43            )
44            .expect("U256 Overflow")
45    }
46
47    #[tokio::test]
48    async fn reads_balance_correctly() -> Result<(), String> {
49        //		init_logging();
50        const EVM_PRIVKEY: &str =
51            "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80";
52        const DECIMALS: u8 = 18;
53        //		let mut client = Client::init_alpha().await
54        let mut client = Client::init_local().await.map_err(|e| format!("{}", e))?;
55
56        let evm_wallet = EvmWallet::new_from_private_key(client.evm_network().clone(), EVM_PRIVKEY)
57            .map_err(|e| format!("{}", e))?;
58        let with_wallet = PaymentOption::from(evm_wallet.clone());
59        println!("EVM Address: {}", evm_wallet.address());
60        println!(
61            "ANT Balance: {}",
62            evm_wallet
63                .balance_of_tokens()
64                .await
65                .map_err(|e| format!("{}", e))?
66        );
67        println!(
68            "Gas Balance: {}",
69            evm_wallet
70                .balance_of_gas_tokens()
71                .await
72                .map_err(|e| format!("{}", e))?
73        );
74
75        let sk1 = SecretKey::random();
76        let sk2 = SecretKey::random();
77        let pk2 = sk2.public_key();
78        //		let sk = SecretKey::from_bytes(sn_bls_ckd::derive_master_sk(
79        //			hex::decode(EVM_PRIVKEY).map_err(|e| format!("{}", e))?[0..32].try_into().unwrap()
80        //		).expect("Wrong bytes").serialize().into()).expect("Wrong bytes");
81
82        // TODO: read wallet from scratchpad
83
84        let mut wallet1 = client
85            .act_wallet_get(&sk1)
86            .await?
87            .unwrap_or(Wallet::new(sk1.public_key()));
88        println!("Wallet1: {:?}", wallet1);
89
90        let issuer_key = wallet1.request(None)?;
91        println!("saving...");
92        let _ = client.act_wallet_save(&wallet1, &sk1, &with_wallet).await?;
93        println!("getting...");
94        let mut wallet1 = client
95            .act_wallet_get(&sk1)
96            .await?
97            .expect("Wallet1 expected in storage");
98        println!("Wallet1: {:?}", wallet1);
99
100        let symbol = "EACT";
101        let total_supply: U256 = amount(1_000_000, DECIMALS);
102        let (genesis_spend, token_id) = client
103            .act_create(
104                "Example Autonomi Community Token".into(),
105                symbol.into(),
106                DECIMALS,
107                total_supply,
108                issuer_key,
109                &with_wallet,
110            )
111            .await?;
112
113        // populate wallet struct
114
115        wallet1.receive(total_supply, token_id, genesis_spend)?;
116        println!("Wallet1: {:?}", wallet1);
117
118        // check balance on that key
119
120        let balance_validation = client.act_balance(&issuer_key, vec![genesis_spend]).await?;
121        println!("ACT Token issuer Balance: {}", balance_validation);
122        assert_eq!(total_supply, balance_validation);
123        assert_eq!(total_supply, wallet1.balance(token_id)?);
124
125        let balance_total = wallet1.balance_total();
126        println!("Wallet1 balance_total: {:?}", balance_total);
127        assert_eq!(1, balance_total.len());
128        assert_eq!(
129            total_supply,
130            balance_total
131                .get(&token_id)
132                .expect("Wrong token_id")
133                .clone()?
134        );
135
136        let token_info = client.act_token_info(&token_id).await?;
137        println!("ACT Token symbol: {}", token_info.symbol);
138        assert_eq!(symbol, token_info.symbol);
139
140        // request payment
141
142        let mut wallet2 = client
143            .act_wallet_get(&sk2)
144            .await?
145            .unwrap_or(Wallet::new(pk2.clone()));
146        println!("Wallet2: {:?}", wallet2);
147
148        let receive_key = wallet2.request(Some(token_id))?;
149        let _ = client.act_wallet_save(&wallet2, &sk2, &with_wallet).await?;
150        let mut wallet2 = client
151            .act_wallet_get(&sk2)
152            .await?
153            .expect("Wallet2 expected in storage");
154        println!("Wallet2: {:?}", wallet2);
155
156        // spend
157
158        let receive_amount = amount(200, DECIMALS);
159
160        let issuer_sk = sk1.derive_child(
161            &wallet1
162                .index_of_token(token_id)
163                .ok_or("Token id not found".to_string())?
164                .to_be_bytes::<32>(),
165        );
166
167        let (inputs, sum, rest_key) = wallet1.take_to_spend(token_id)?;
168        println!("Inputs: {:?}", (&inputs, sum));
169        println!("Wallet1: {:?}", wallet1);
170
171        let rest_amount = sum
172            .checked_sub(receive_amount)
173            .ok_or("Overflow".to_string())?;
174
175        let spend = GraphEntry::new(
176            &issuer_sk,
177            inputs,
178            token_id.0,
179            vec![
180                (receive_key, receive_amount.to_be_bytes()),
181                (rest_key, rest_amount.to_be_bytes()),
182            ], // all output to issuer
183        );
184        let (_paid, spend_address) = client
185            .graph_entry_put(spend, with_wallet.clone())
186            .await
187            .map_err(|e| format!("{}", e))?;
188
189        println!("Spend GraphEntry: {}", spend_address);
190        assert_eq!(&issuer_key, spend_address.owner());
191
192        wallet1.receive(rest_amount, token_id, *spend_address.owner())?;
193        let _ = client.act_wallet_save(&wallet1, &sk1, &with_wallet).await?;
194        let wallet1 = client
195            .act_wallet_get(&sk1)
196            .await?
197            .expect("Wallet1 expected in storage");
198        println!("Wallet1: {:?}", wallet1);
199
200        wallet2.receive(receive_amount, token_id, *spend_address.owner())?;
201        let _ = client.act_wallet_save(&wallet2, &sk2, &with_wallet).await?;
202        let wallet2 = client
203            .act_wallet_get(&sk2)
204            .await?
205            .expect("Wallet2 expected in storage");
206        println!("Wallet2: {:?}", wallet2);
207
208        Ok(())
209    }
210
211    // TODO: de/serialze wallet
212
213    #[test]
214    fn pk_cannot_be_arbitrary_32bytes() -> Result<(), String> {
215        // EVM txid
216        let pubkey =
217            PublicKey::from_hex("91c680f29bb12c72093642aa6750332e140753bd112097e021428d86b12ee479");
218        assert!(pubkey.is_err());
219
220        // EVM address, 20 bytes
221        let pubkey = PublicKey::from_hex("a78d8321b20c4ef90ecd72f2588aa985a4bdb684");
222        assert!(pubkey.is_err());
223
224        // 32 bytes
225        let pubkey =
226            PublicKey::from_hex("a78d8321b20c4ef90ecd72f2588aa985a4bdb684000000000000000000000000");
227        assert!(pubkey.is_err());
228
229        Ok(())
230    }
231
232    #[test]
233    fn pubkey_from_derived_sk_equals_derived_pubkey() {
234        let index = "index1_abcdef";
235        println!("index: {:?}", index);
236        let sk = SecretKey::random();
237        println!("sk: {:?}", sk);
238        let pk = sk.public_key();
239        println!("pk: {:?}", pk);
240
241        let pubkey_from_derived_sk = sk.derive_child(index.as_bytes()).public_key();
242        println!("pubkey_from_derived_sk: {:?}", pubkey_from_derived_sk);
243        let derived_pubkey = pk.derive_child(index.as_bytes());
244        println!("derived_pubkey: {:?}", derived_pubkey);
245
246        assert_eq!(pubkey_from_derived_sk, derived_pubkey);
247    }
248}