Skip to main content

r402_algorand/
lib.rs

1#![cfg_attr(docsrs, feature(doc_cfg))]
2#![cfg_attr(
3    test,
4    allow(
5        unknown_lints,
6        clippy::unused_async_trait_impl,
7        reason = "in-crate mock impls of AFIT traits have no .await"
8    )
9)]
10
11//! Algorand chain support for the x402 payment protocol.
12//!
13//! This crate implements the x402 `"exact"` scheme for Algorand: the buyer
14//! builds an atomic transaction group containing an ASA transfer and an
15//! optional facilitator-sponsored 0-amount payment that covers the group
16//! fee via fee pooling.
17//!
18//! # Features
19//!
20//! - **CAIP-2 Addressing**: `algorand:wGHE2Pwdvd7S12BL5FaOP20EGYesN73k`
21//!   and `algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDe`
22//! - **ASA Payments**: exact transfer of a token (USDC by default)
23//! - **Fee pooling**: optional 0-amount fee-payer transaction
24//! - **In-process facilitator**: algod REST verify and settle
25//!
26//! # Feature Flags
27//!
28//! - `server` — server-side price tag generation
29//! - `client` — client-side group construction and signing
30//! - `facilitator` — facilitator-side payment verification and settlement
31//! - `telemetry` — `tracing` instrumentation
32
33#[cfg(not(any(feature = "client", feature = "facilitator")))]
34use base64 as _;
35#[cfg(feature = "telemetry")]
36use tracing_core as _;
37
38/// Maximum number of top-level transactions in an Algorand atomic group.
39pub const MAX_TRANSACTION_GROUP_SIZE: usize = 16;
40
41/// Per-transaction fee cap used to bound facilitator fee-payer spend (µAlgo).
42pub const MAX_REASONABLE_FEE_PER_TXN: u64 = 5_000;
43
44/// Default first/last-valid window in rounds (`last_round + this`).
45pub const DEFAULT_VALIDITY_ROUNDS: u64 = 1_000;
46
47/// Default number of rounds to wait for confirmation after broadcast.
48pub const DEFAULT_WAIT_ROUNDS: u32 = 10;
49
50/// Default USDC decimal precision.
51pub const DEFAULT_TOKEN_DECIMALS: u8 = 6;
52
53/// Maximum acceptable fee-payer fee for a group of `group_size` transactions.
54#[must_use]
55pub fn max_reasonable_group_fee(group_size: usize) -> u64 {
56    let size = u64::try_from(group_size).unwrap_or(u64::MAX);
57    MAX_REASONABLE_FEE_PER_TXN.saturating_mul(size)
58}
59
60pub mod chain;
61pub mod exact;
62
63mod networks;
64#[cfg(any(feature = "client", feature = "facilitator"))]
65pub use chain::AlgodClient;
66#[cfg(feature = "facilitator")]
67pub use chain::AlgorandChainProvider;
68#[cfg(any(feature = "client", feature = "facilitator"))]
69pub use chain::AlgorandSigner;
70pub use exact::AlgorandExact;
71#[cfg(feature = "client")]
72pub use exact::client::AlgorandExactClient;
73pub use networks::*;