-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path08-batch-transfer.rs
90 lines (81 loc) · 2.73 KB
/
08-batch-transfer.rs
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
use sp_keyring::AccountKeyring;
use std::error::Error;
use subxt::{
sp_core::sr25519::Pair,
sp_runtime::{AccountId32, MultiAddress},
DefaultConfig, PairSigner,
};
use subxt_workshop::{polkadot, with_default_client, EncodedCall, PolkadotRuntimeApi};
type BalancesCall = polkadot::runtime_types::pallet_balances::pallet::Call;
/// # Exercise 08 (A)
///
/// Implement a function to batch multiple `transfer` calls using the `utility` pallet.
///
/// ## Hint
///
/// ```
/// let calls = vec![EncodedCall::Pallet(PalletCall::extrinsic { params }];
/// ```
pub async fn batch_transfer(
_api: PolkadotRuntimeApi,
_signer: PairSigner<DefaultConfig, Pair>,
_recipients: Vec<(MultiAddress<AccountId32, ()>, u128)>,
) -> Result<(), Box<dyn Error>> {
Ok(())
}
/// # Exercise 08 (B)
///
/// See: 02-get-balance.rs
pub async fn get_balance(_api: PolkadotRuntimeApi, _account: AccountId32) -> Result<u128, Box<dyn Error>> {
Ok(Default::default())
}
#[tokio::test]
async fn should_batch_transfer() -> Result<(), Box<dyn Error>> {
use futures::future::join_all;
with_default_client(|api| async move {
let recipients = vec![
(AccountKeyring::Bob.to_account_id(), 10_000_000_000),
(AccountKeyring::Charlie.to_account_id(), 1_000_000_000),
];
let balances_before = join_all(recipients.iter().map(|(account_id, amount)| async {
Ok((
account_id.clone(),
amount.clone(),
get_balance(api.clone(), account_id.clone()).await?,
))
}))
.await
.into_iter()
.collect::<Result<Vec<_>, Box<dyn Error>>>()?;
batch_transfer(
api.clone(),
PairSigner::new(AccountKeyring::Alice.pair()),
recipients
.into_iter()
.map(|(account_id, value)| (account_id.into(), value))
.collect(),
)
.await?;
// there is probably a nicer way to write this check - bonus points for refactoring
let balances_after = join_all(
balances_before
.iter()
.map(|(account_id, amount, balance_before)| async {
Ok((
account_id.clone(),
amount.clone(),
balance_before.clone(),
get_balance(api.clone(), account_id.clone()).await?,
))
}),
)
.await
.into_iter()
.collect::<Result<Vec<_>, Box<dyn Error>>>()?;
for (account_id, amount, before, after) in balances_after {
assert_eq!(after, before + amount, "Balance was not sent to {account_id:?}!");
}
Ok(())
})
.await
}