merge_coins/
merge_coins.rs1use std::{str::FromStr, time::Duration};
6
7use iota_config::{IOTA_CLIENT_CONFIG, iota_config_dir};
8use iota_faucet::FaucetError;
9use iota_json_rpc_types::IotaTransactionBlockResponseOptions;
10use iota_keys::keystore::AccountKeystore;
11use iota_sdk::wallet_context::WalletContext;
12use iota_types::{
13 base_types::ObjectID, gas_coin::GasCoin, quorum_driver_types::ExecuteTransactionRequestType,
14 transaction::Transaction,
15};
16use shared_crypto::intent::Intent;
17use tracing::info;
18
19#[tokio::main]
20async fn main() -> Result<(), anyhow::Error> {
21 let wallet = create_wallet_context(60)?;
22 let active_address = wallet
23 .active_address()
24 .map_err(|err| FaucetError::Wallet(err.to_string()))?;
25 println!("SimpleFaucet::new with active address: {active_address}");
26
27 Ok(())
42}
43
44async fn _split_coins_equally(
45 gas_coin: &str,
46 wallet: WalletContext,
47 count: u64,
48) -> Result<(), anyhow::Error> {
49 let active_address = wallet
50 .active_address()
51 .map_err(|err| FaucetError::Wallet(err.to_string()))?;
52 let client = wallet.get_client().await?;
53 let coin_object_id = ObjectID::from_str(gas_coin).unwrap();
54 let tx_data = client
55 .transaction_builder()
56 .split_coin_equal(active_address, coin_object_id, count, None, 50000000000)
57 .await?;
58
59 let signature = wallet
60 .config()
61 .keystore()
62 .sign_secure(&active_address, &tx_data, Intent::iota_transaction())
63 .unwrap();
64 let tx = Transaction::from_data(tx_data, vec![signature]);
65 let resp = client
66 .quorum_driver_api()
67 .execute_transaction_block(
68 tx.clone(),
69 IotaTransactionBlockResponseOptions::new().with_effects(),
70 Some(ExecuteTransactionRequestType::WaitForLocalExecution),
71 )
72 .await?;
73
74 println!("{:?}", resp);
75 Ok(())
76}
77
78async fn _merge_coins(gas_coin: &str, wallet: WalletContext) -> Result<(), anyhow::Error> {
79 let active_address = wallet
80 .active_address()
81 .map_err(|err| FaucetError::Wallet(err.to_string()))?;
82 let client = wallet.get_client().await?;
83 let small_coins = wallet
86 .gas_objects(active_address)
87 .await
88 .map_err(|e| FaucetError::Wallet(e.to_string()))?
89 .iter()
90 .map(|q| GasCoin::try_from(&q.1).unwrap())
92 .filter(|coin| coin.0.balance.value() <= 10000000000)
94 .collect::<Vec<GasCoin>>();
95
96 for chunk in small_coins.chunks(254) {
98 let total_balance: u64 = chunk.iter().map(|coin| coin.0.balance.value()).sum();
99
100 let mut coin_vector = chunk
101 .iter()
102 .map(|coin| *coin.id())
103 .collect::<Vec<ObjectID>>();
104
105 coin_vector.insert(0, ObjectID::from_str(gas_coin).unwrap());
107 let target = vec![active_address];
108 let target_amount = vec![total_balance];
109
110 let tx_data = client
111 .transaction_builder()
112 .pay_iota(active_address, coin_vector, target, target_amount, 1000000)
113 .await?;
114 let signature = wallet
115 .config()
116 .keystore()
117 .sign_secure(&active_address, &tx_data, Intent::iota_transaction())
118 .unwrap();
119 let tx = Transaction::from_data(tx_data, vec![signature]);
120 client
121 .quorum_driver_api()
122 .execute_transaction_block(
123 tx.clone(),
124 IotaTransactionBlockResponseOptions::new().with_effects(),
125 Some(ExecuteTransactionRequestType::WaitForLocalExecution),
126 )
127 .await?;
128 }
129 Ok(())
130}
131
132pub fn create_wallet_context(timeout_secs: u64) -> Result<WalletContext, anyhow::Error> {
133 let wallet_conf = iota_config_dir()?.join(IOTA_CLIENT_CONFIG);
134 info!("Initialize wallet from config path: {:?}", wallet_conf);
135 WalletContext::new(&wallet_conf, Some(Duration::from_secs(timeout_secs)), None)
136}