algonaut 0.8.0

A Rusty sdk for the Algorand blockchain.
Documentation

Rust algonaut

Crate Docs CI License: MIT OR Apache-2.0

A Rust SDK for the Algorand blockchain. Pre-1.0 — the API is stabilising but still moves between minor versions.

Highlights

  • Async clients for algod v2, kmd v1, and indexer v2
  • One-call transaction builders for payments, asset config / transfer / freeze / clawback, application calls, key registration, and state proofs
  • A typestate AtomicGroupBuilder — bundle transactions and compile-time-checked ARC-4 ABI calls (abi_call!), then simulate, sign, and execute
  • An open, async Signer trait: Account out of the box, or plug in an HSM, remote KMS, or WalletConnect
  • TEAL compile / disassemble + V3 source-map decoder
  • Cucumber acceptance suite that exercises the algorand-sdk-testing harness end-to-end

Quickstart: an atomic group

Bundle two payments and an ARC-4 method call into one all-or-nothing group, dry-run it with simulate, then sign and execute the very same group — the headline algonaut flow as it stands today. See examples/atomic.rs for the fully annotated version.

use algonaut::abi::abi_call;
use algonaut::algod::v2::Algod;
use algonaut::atomic::{AtomicGroupBuilder, MethodCall, TransactionWithSigner};
use algonaut::core::{AppId, MicroAlgos};
use algonaut::transaction::account::Account;
use algonaut::transaction::{Pay, Signer};
use std::sync::Arc;
use std::{env, error::Error};

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let algod = Algod::new(&env::var("ALGOD_URL")?, &env::var("ALGOD_TOKEN")?)?;

    let alice = Account::from_mnemonic(&env::var("ALICE_MNEMONIC")?)?;
    let bob = Account::from_mnemonic(&env::var("BOB_MNEMONIC")?)?;

    // A signer is shared as `Arc<dyn Signer>`: `Account` here, but any HSM,
    // remote KMS, or WalletConnect impl drops in the same way.
    let alice_signer: Arc<dyn Signer> = Arc::new(alice.clone());
    let bob_signer: Arc<dyn Signer> = Arc::new(bob.clone());

    let params = algod.suggested_params().await?;
    let app = AppId(123); // an ARC-4 `add(uint64,uint64)uint64` contract

    let alice_to_bob = Pay::new(alice.address(), bob.address(), MicroAlgos(1_000)).build(&params)?;
    let bob_to_alice = Pay::new(bob.address(), alice.address(), MicroAlgos(1_000)).build(&params)?;

    // `abi_call!` checks the signature and the argument types at compile time.
    let call = MethodCall::builder(app, alice.address(), alice_signer.clone())
        .invoke(abi_call!("add(uint64,uint64)uint64", 2u64, 3u64))
        .build(&params);

    // The typestate chain — AtomicGroupBuilder → UnsignedAtomicGroup →
    // SignedAtomicGroup — means "submit before sign" simply won't compile.
    let group = 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()?;

    // `simulate` borrows the group, so we dry-run it before touching a key.
    let sim = group.simulate(&algod).await?;
    println!("simulate ok: {} transaction(s)", sim.transaction_ids.len());

    // `sign` is async (a wallet may await user approval); `execute` submits,
    // waits for confirmation, and decodes each method call's ABI return.
    let outcome = group.sign().await?.execute(&algod).await?;
    println!("confirmed in round {:?}", outcome.confirmed_round);
    for result in &outcome.method_results {
        println!("returned: {:?}", result.return_value);
    }
    Ok(())
}

What's new since 0.4.2

algonaut rested at 0.4.2 for years; the 0.50.7 line is a ground-up modernization, and the example above is the API as it stands today:

  • 0.5 — Rust 2024 edition (MSRV 1.85); ring swapped for ed25519-dalek, so wasm32 builds need no C toolchain; workspace-wide dependency refresh; lefthook + make ci.
  • 0.6simulate and dry-run request builders, a TEAL V3 source-map decoder, and domain types that serialize to both JSON and msgpack.
  • 0.7 — identifier newtypes (AppId, AssetId, TxId) at the client boundary, block / account-resource / ledger-delta endpoints, and msgpack response decoding.
  • unreleased — an open, async Signer trait (HSM / remote KMS / WalletConnect friendly), the typestate AtomicGroupBuilder shown above, and compile-time-checked ARC-4 calls via abi_call!.

Each decision is recorded as an ADR under docs/adr/; CHANGELOG.md has the full entry-by-entry history.

Workspace layout

Crate Purpose
algonaut Top-level crate: the atomic group builder, simulate/dryrun helpers, and re-exports
algonaut_algod Generated client for the algod v2 REST API
algonaut_kmd Client for the key-management daemon
algonaut_indexer Client for the indexer v2 REST API
algonaut_core Core types: Address, MicroAlgos, Round, AppId/AssetId/TransactionId, keys, multisig
algonaut_crypto Ed25519 sign/verify (via ed25519-dalek) and BIP-39 mnemonics
algonaut_transaction Transaction builders and the open Signer trait
algonaut_abi ARC-4 ABI types, method encoding, TEAL source-map decoder
algonaut_abi_sig ARC-4 signature/type grammar shared by the macros and the runtime
algonaut_abi_macros abi_call! / abi_method! compile-time-checked ABI proc-macros
algonaut_encoding Shared serde visitors and base32/base64 helpers
algonaut_model Hand-written response models shared between the clients

Running the examples

/examples has a wide set of runnable programs.

cp examples.env .env       # ALGOD_URL, KMD_URL, INDEXER_URL, mnemonics
cargo run --example quickstart

If you see Error: NotPresent, your environment variables aren't set — cp examples.env .env and edit as needed.

Changelog

See CHANGELOG.md.

Contributing

Read the contribution guidelines before opening a PR. The pre-commit hook runs make ci; commit messages follow Conventional Commits.

Acknowledgements

This crate is based on the work of @mraof.

License

Ferris Algonaut

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Asset attribution

Ferris Algonaut is licensed under a Creative Commons Attribution 4.0 International License. Rust algonaut's logo is based on Font Awesome's icon and licensed under a Creative Commons Attribution 4.0 International License.