use algonaut::Algod;
use algonaut::abi::abi_call;
use algonaut::atomic::{AtomicGroupBuilder, MethodCall, TransactionWithSigner};
use algonaut::core::{AppId, MicroAlgos};
use algonaut::transaction::account::Account;
use algonaut::transaction::{Pay, Signer};
use dotenv::dotenv;
use std::env;
use std::error::Error;
use std::sync::Arc;
#[macro_use]
extern crate log;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
dotenv().ok();
env_logger::init();
info!("creating algod client");
let algod = Algod::new(&env::var("ALGOD_URL")?, &env::var("ALGOD_TOKEN")?)?;
info!("creating accounts for alice and bob");
let alice = Account::from_mnemonic(&env::var("ALICE_MNEMONIC")?)?;
let bob = Account::from_mnemonic(&env::var("BOB_MNEMONIC")?)?;
let alice_signer: Arc<dyn Signer> = Arc::new(alice.clone());
let bob_signer: Arc<dyn Signer> = Arc::new(bob.clone());
info!("retrieving suggested params");
let params = algod.suggested_params().await?;
let app_id = AppId(123);
info!("building the two payment legs");
let alice_to_bob =
Pay::new(alice.address(), bob.address(), MicroAlgos(1_000)).build(¶ms)?;
let bob_to_alice =
Pay::new(bob.address(), alice.address(), MicroAlgos(1_000)).build(¶ms)?;
info!("building the method call add(2, 3)");
let call = MethodCall::builder(app_id, alice.address(), alice_signer.clone())
.invoke(abi_call!("add(uint64,uint64)uint64", 2u64, 3u64))
.build(¶ms);
info!("composing the atomic group");
let unsigned = AtomicGroupBuilder::new()
.add_transaction(TransactionWithSigner::new(alice_to_bob, alice_signer))
.add_transaction(TransactionWithSigner::new(bob_to_alice, bob_signer))
.add_method_call(call)
.build()?;
info!("simulating (dry run) before signing");
let sim = unsigned.simulate(&algod).await?;
info!(
"simulate ok: {} transaction(s), {} method result(s)",
sim.transaction_ids.len(),
sim.method_results.len()
);
info!("signing and executing the group");
let outcome = unsigned.sign().await?.execute(&algod).await?;
info!("group confirmed in round {:?}", outcome.confirmed_round);
for (i, result) in outcome.method_results.iter().enumerate() {
info!("method call {i} returned: {:?}", result.return_value);
}
Ok(())
}