Rust algonaut

May 26, 2026 · View on GitHub

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 ARC-4 ABI calls, then simulate, sign, and execute
  • Typed contract clients generated at compile time from an ARC-4 ABI or a full ARC-56 app spec (contract!) — typed-struct args, a deploy constructor, state readers, and ARC-28 events — or compile-time-checked one-off calls with abi_call!
  • 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

Generate a typed client from an ARC-56 app spec with contract!, deploy it straight from the spec, call a method with a typed-struct argument, dry-run the group with simulate, then sign and execute the very same group — the headline algonaut flow. Raw transactions (payments, asset ops) drop into the same group via add_transaction. See examples/arc56_client.rs for the fully annotated version (events, defaults, lifecycle actions, and more).

use algonaut::Algod;
use algonaut::atomic::AtomicGroupBuilder;
use algonaut::transaction::Signer;
use algonaut::transaction::account::Account;
use std::sync::Arc;
use std::{env, error::Error};

// `contract!` reads an ARC-56 "Extended App Description" at compile time and
// generates a typed `Vault` client: a `deploy` constructor that compiles the
// spec's TEAL, the named `Pair` struct as a typed argument, one builder per ABI
// method, and `global_*` readers that decode state per the spec's declared types.
algonaut::contract!("contracts/vault.arc56.json");

#[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 sender = alice.address();

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

    let params = algod.suggested_params().await?;

    // Deploy straight from the spec: `deploy` compiles the contract's TEAL,
    // submits the app-create with the declared state schema, and hands back a
    // client bound to the new app id — no hand-managed `AppId`.
    let vault = Vault::deploy(&algod, sender, Arc::clone(&signer), &params).await?;
    println!("deployed Vault as app {}", vault.app_id().0);

    // `Pair` is the Rust struct generated for the ARC-56 `Pair`; `store` won't
    // compile unless the spec declares it and the field types line up.
    let store = vault.store(Pair { first: 2, second: 3 }).build(&params);
    let group = AtomicGroupBuilder::new().add_method_call(store).build()?;

    // `simulate` borrows the group, so we dry-run it before touching a key; then
    // `sign` (async — a wallet may await approval) and `execute` the same group.
    group.simulate(&algod).await?;
    let outcome = group.sign().await?.execute(&algod).await?;
    println!("confirmed in round {:?}", outcome.confirmed_round);

    // Global state, decoded per the key's declared ARC-56 type.
    println!("total = {:?}", vault.global_total(&algod).await?);
    Ok(())
}

What's new since 0.4.2

algonaut rested at 0.4.2 for years; the 0.50.8 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, TransactionId) at the client boundary, block / account-resource / ledger-delta endpoints, and msgpack response decoding.
  • 0.8 — an open, async Signer trait (HSM / remote KMS / WalletConnect friendly), the typestate AtomicGroupBuilder shown above, compile-time-checked ARC-4 calls via abi_call!, Cargo feature gates for clients (algod, indexer, kmd), and structured error types with full source-chaining.
  • unreleasedcontract! now generates a typed client from a full ARC-56 app spec: a deploy constructor, typed-struct arguments, global_* state readers, ARC-28 events, and a read-only simulate path, extending the earlier ARC-4 support.

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

Workspace layout

CratePurpose
algonautTop-level crate: the atomic group builder, simulate/dryrun helpers, and re-exports
algonaut_algodGenerated client for the algod v2 REST API
algonaut_kmdClient for the key-management daemon
algonaut_indexerClient for the indexer v2 REST API
algonaut_coreCore types: Address, MicroAlgos, Round, AppId/AssetId/TransactionId, keys, multisig
algonaut_cryptoEd25519 sign/verify (via ed25519-dalek) and BIP-39 mnemonics
algonaut_transactionTransaction builders and the open Signer trait
algonaut_abiARC-4 ABI types, method encoding, TEAL source-map decoder
algonaut_abi_modelPure serde data model for ARC-4 / ARC-56 app-spec JSON, shared by the runtime and the macros
algonaut_abi_sigARC-4 signature/type grammar shared by the macros and the runtime
algonaut_abi_macroscontract! client generator plus abi_call! / abi_method! compile-time-checked ABI proc-macros
algonaut_encodingShared serde visitors and base32/base64 helpers
algonaut_modelHand-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.