Back to Docs
Getting Started
Staged Complexity Guide
Start with zero infrastructure in Stage 1, add real crypto in Stage 2, and go fully on-chain in Stage 3.
Stage 1
Localhost Development — Zero Infrastructure
Everything runs in-process. No Docker, no database, no crypto wallet. Use this stage to learn the protocol API and build your first agent integration.
Prerequisites
Node.js 22+ (check with node -v)
Install
npm install @aroha-sdk/core
Minimal server
import { ArohaServer, generateDid, MapNonceStore } from "@aroha-sdk/core";
// Generate a throwaway DID + keypair (dev only)
const { did, privateKey, publicKey } = generateDid();
const server = new ArohaServer({
did,
privateKey,
publicKey,
nonceStore: new MapNonceStore(), // in-memory, single process
devMode: true, // skips signature checks on loopback
});
server.handle("ArohaRequest", async (env) => {
return { result: "hello from Aroha!" };
});
await server.listen(3000);
console.log("Agent listening on http://localhost:3000");Stage 1 checklist
- ✅
generateDid()returns a DID, private key, and public key - ✅
ArohaServeraccepts and validates signed envelopes - ✅
MapNonceStoreprevents replay within the process lifetime - ✅
devMode: truerelaxes clock skew and signature checks for localhost - ✅Send a request using the TypeScript SDK client and read the response
Stage 2
Staging / Pre-Production
Add persistent DID documents, a shared nonce store (Redis), and real Ed25519 key management. Start testing with real network calls between agents.
Install
npm install @aroha-sdk/core @aroha-sdk/nonce-redis ioredis
Staging server config
import { ArohaServer } from "@aroha-sdk/core";
import { RedisNonceStore } from "@aroha-sdk/nonce-redis";
import Redis from "ioredis";
const redis = new Redis(process.env.REDIS_URL!);
const server = new ArohaServer({
did: process.env.AGENT_DID!,
privateKey: Buffer.from(process.env.AGENT_PRIVATE_KEY!, "hex"),
publicKey: Buffer.from(process.env.AGENT_PUBLIC_KEY!, "hex"),
nonceStore: new RedisNonceStore(redis, { ttlSeconds: 300 }),
clockToleranceMs: 30_000, // 30 s clock skew tolerance
// devMode omitted → defaults to false (full verification)
});
server.handle("ArohaRequest", async (env) => {
return { result: "staging response" };
});
await server.listen(Number(process.env.PORT) || 3000);Stage 2 checklist
- ✅Store
AGENT_DID,AGENT_PRIVATE_KEY, andAGENT_PUBLIC_KEYin environment variables (never commit) - ✅Replace
MapNonceStorewithRedisNonceStorefor multi-instance safety - ✅Publish a DID document to your staging domain via
did:aroha-web: - ✅Enable DNS TXT key commitment hash on your staging domain
- ✅Set
clockToleranceMsto handle real network clock skew - ✅Run the conformance test suite:
npx @aroha-sdk/conformance-tests --tier 1
Stage 3
Production
Full production deployment with on-chain settlement, EVM escrow, audit trails, and reputation scoring. Requires Tier 2 or Tier 3 conformance.
Stage 3 checklist
- ✅Key rotation procedure documented and tested (24-hour cool-down with predecessor signature chain)
- ✅Saga orchestrator deployed with persistent saga log (Postgres or equivalent)
- ✅DLQ (dead letter queue) configured for failed saga compensation steps
- ✅
@aroha-sdk/auditenabled — append-only hash-chained log with SIEM export - ✅EVM escrow contract deployed (only for external value transfer — not for internal agent-to-agent calls)
- ✅Reputation scoring enabled with Wilson lower-bound risk gate
- ✅
X-Aroha-Conformance: tier-2ortier-3header set on all responses - ✅Load test completed — validate nonce store under concurrent requests
- ✅Registry entry published to HTTP registry at
registry.aroha-labs.com
Common Mistakes
| Mistake | Problem | Fix |
|---|---|---|
| devMode: true in production | Skips all signature verification — any envelope is accepted | Remove devMode or set it to false; use env-based feature flags |
| MapNonceStore with multiple instances | Replay attacks succeed because each instance has its own nonce set | Switch to RedisNonceStore with a shared Redis cluster |
| Missing clockToleranceMs | EXPIRED_MESSAGE errors from minor NTP drift between servers | Set clockToleranceMs: 30_000 (30 s) as a safe default |
| EVM escrow for internal agent calls | High gas costs and latency for every internal capability call | Use EVM escrow only for external value transfer; use SpendingMandates internally |