ward test report. It takes about
10–15 minutes of hands-on time, plus one manual step you can’t skip: funding two TestNet accounts
through Algorand’s captcha-gated dispensers.
Ward targets Algorand TestNet by default — no LocalNet or AlgoKit CLI install required. See
why in the decision log.
1. Prerequisites
Node.js 20+
Ward’s
engines.node field requires Node 20 or newer.Docker
Needed to self-host the facilitator via
docker-compose.yml.2. Clone and configure
.env.example documents every variable Ward’s CLI, self-hosted facilitator, and paid verification
server need — see the full breakdown in Environment Variables.
3. Generate accounts
- Generates a fresh Algorand keypair for each account Ward needs (
WARD_FUNDER,WARD_CLIENT,WARD_PAYTO,AVM_PRIVATE_KEY) and prints the address + base64 secret key for each. - Generates throwaway, well-formed EVM and SVM keys purely to satisfy the upstream facilitator example’s multi-chain startup check — they’re never funded or used to sign anything real.
.env.
4. Fund the two bootstrap accounts
Algorand’s TestNet dispensers are captcha-gated web forms, so this one step can’t be automated. Visit each dispenser and fund:1
Fund WARD_FUNDER
Send TestNet ALGO to the
WARD_FUNDER address via the
ALGO dispenser. Once funded, WARD_FUNDER
auto-funds every other account Ward needs — you only do this once per environment.2
Fund AVM_PRIVATE_KEY's address
Send TestNet ALGO to the facilitator’s own signing address (the address for
AVM_PRIVATE_KEY) via the same dispenser. This account co-signs settlement fee-payer
transactions, so it needs its own balance.5. Install dependencies
6. Boot the facilitator and verify one real payment
ward init is idempotent and:
- Boots the self-hosted facilitator via
docker-compose upand waits for its health check. - Auto-funds
WARD_CLIENTand any disposable accounts fromWARD_FUNDER. - Opts
WARD_PAYTOinto the test ASA (TestNet USDC) if a private key is available for it. - Runs one real, complete payment through
/verifyand/settleand confirms it on-chain, so nothing downstream runs against an unverified facilitator.
7. Run the full invariant suite
U1–U5, A1–A3), prints a pass/fail table, and writes:
reports/ward-report-<timestamp>.json— the full run, with reproducible evidence per invariant.reports/latest.json— always the most recent run, read byward report.
U1, U2, U3, U4, A1) fails —
safe to wire straight into CI.
8. Inspect one invariant closely
ward fuzz <id> runs a single invariant in isolation with full, verbose evidence — the fastest
way to see exactly what payload Ward sent and what the facilitator returned. A1, atomic group
integrity, is Ward’s headline invariant — see A1 for what
it proves.
Once it’s built
dist/cli/index.js is the same binary published as ward in package.json’s bin
field — use whichever entry point fits your workflow.
Next: understand what each invariant proves
Read the Invariants section before interpreting a report — a PASS or FAIL only means something
once you know exactly what was tested.

