NEAR PROTOCOL // THE CURRENCY OF AGENTS
RPC: TESTNET LIVE (42ms)
|
BLOCK: #184,920,411
echoes v2.4
NEAR PROTOCOL HACKATHON // AGENT GOVERNANCE
SYS_ID: ECHOES-VAULT-01

Autonomous Swarms.
Cryptographic Guardrails.

Never hand a FullAccess key to an autonomous AI agent. Echoes pairs NEAR's protocol-level FunctionCall Access Keys with a deterministic Rust Guardrail Vault—enforcing per-transaction velocity limits, cumulative agent allowances, trusted recipient allowlists, and deterministic on-chain rejection — a breaching call traps and reverts before a single yoctoNEAR leaves the vault, with owner-controlled revoke_agent that blocks the key's spending immediately — delete the key on the account for permanent lockout.

LAYER 01 // RUNTIME
Scoped ed25519 Key
Methods: spend / spend_as
LAYER 02 // VAULT
Dual Velocity Caps
0.50 Ⓝ/tx · 5.00 Ⓝ/day
LAYER 03 // REFLEX
Deterministic Revert
tx reverts before any transfer
OPEN TESTNET CONSOLE

[CONSOLE] open the Swarm Security Console → — simulate any agent spend or admin call against live testnet state, or connect MyNearWallet (testnet) / a scoped agent key to broadcast real transactions to allowance-swarm.testnet · verify on-chain: NearBlocks ↗

[SONAR // GUARDRAIL PERIMETER]

Real-Time Agent Pulse Interceptor

SHIELD: ARMED
VAULT: 5.00 Ⓝ/day agent-alpha 0.20 Ⓝ/tx · 1.00 Ⓝ/day agent-beta 0.20 Ⓝ/tx · 1.00 Ⓝ/day UNREGISTERED KEY no such key on account ROGUE RECIPIENT REVERTED @ ALLOWLIST
> SONAR: idle · arm a pulse 5 GATES
[VAULT_TELEMETRY] — LIVE STATE READ FROM allowance-swarm.testnet connecting…
GLOBAL VAULT CAP [GATE 05]
1.65 / 5.00 NEAR
REMAINING RUNWAY: 3.35 NEAR
CIRCUIT BREAKER [GATE 02]
ACTIVE (UNPAUSED)

Owner: allowance-swarm.testnet

SWARM KEY REGISTRY [GATE 01 & 03]
3 ACTIVE KEYS
/
1 REVOKED BY OWNER
KEY ALLOWANCE (CHAIN): —
ALLOWLISTED DESTINATIONS [GATE 04]
UNTRUSTED TARGETS: TX REVERTED
SOURCE
github.com/xhanny6969/echoes ↗
Rust contract, CLI, agent and dashboard. MIT.
BUILD IS REPRODUCIBLE
FeZL3sAZN6Z6d4UgUJd1soy9T9XbuNubd5m8dKj1k4H6
Rebuild from contract/ and the sha256 matches the live code hash byte for byte.
REAL AGENT, TWO OUTCOMES
Same model. Hijacked vendor invoice → payout reverted at the allowlist.
[SWARM_AGENT_MATRIX]

Autonomous Agents & Scoped Access Keys

Each autonomous worker holds an isolated ed25519 key restricted strictly to spend / spend_as. Any policy violation reverts inside the contract before funds move; the owner can permanently lock a key out with revoke_agent.

SIMULATION Everything in this section runs client-side: it is a deterministic replay of the contract's gate logic, not a broadcast. The live numbers in sections 01–04 are read from the chain in your browser — direct NEAR RPC calls (or /api/state when the local dashboard server is running). Blocked transactions are shown in section 04 with real hashes.
[GUARDRAIL_SIMULATOR_&_TESTNET_CONSOLE]

Interactive 5-Gate On-Chain Verification Playground

Select any Hackathon benchmark preset below or compose a custom payload to test the deterministic Rust guardrails.
TRANSACTION PAYLOAD COMPOSER NEAR JSON-RPC / CLI
Agent Per-Tx Limit: 0.20 NEAR
Must exist in Vault Allowlist
EQUIVALENT near-cli-rs COMMAND

          
5-GATE DETERMINISTIC EXECUTION PIPELINE

NEAR Runtime + Rust Contract (allowance/contract/src/lib.rs)

READY TO VERIFY
01
GATE 01 // Protocol FunctionCall Access Key & Predecessor Guard
Verifies the ed25519 key is scoped to the target method with gas ≤ 0.25 Ⓝ and checks env::predecessor_account_id().
STANDBY
02
GATE 02 // Global Vault Circuit Breaker
Rust contract assertion: require!(!self.is_paused, "ERR_VAULT_PAUSED")
STANDBY
03
GATE 03 // Agent Registration & Active Key State
Assertion: agent.is_active == true (Owner-revoked keys can no longer transact).
STANDBY
04
GATE 04 // Trusted Recipient Allowlist Check
Assertion: self.allowlist.contains(&recipient) — On violation: revert the transfer.
STANDBY
05
GATE 05 // Dual Velocity Arithmetic (Per-Tx & Global Cap)
Assertion: amount <= agent.max_per_tx && vault_spent + amount <= vault_cap
STANDBY
EXECUTION RECEIPT TELEMETRY TX: 8xK9...p3mN
> Select a Hackathon preset above or click "EXECUTE 5-GATE ON-CHAIN VERIFICATION" to inspect the contract execution trace.
[INSTALL_IN_YOUR_AGENT]

Your agent can install this itself

Paste the prompt below into Claude Code, Cursor, Codex or any agent with a shell. It clones the repo, runs the sandbox self-test against a live testnet vault, and must come back with two on-chain outcomes: one payout accepted, one payout reverted at the allowlist. No wallet, no private key of yours, no account creation. This is a shared, rate-limited testnet sandbox—not unlimited concurrent capacity.

Install and self-test Echoes — an on-chain spending vault for AI agents (NEAR).
Work in a temp directory and do exactly this:

1. git clone --depth 1 https://github.com/xhanny6969/echoes && cd echoes
2. npm install --no-audit --no-fund
3. node echoes/sandbox.js

Expected: exactly two PASS lines —
  PASS allowlisted recipient            -> accepted on chain
  PASS recipient not on allowlist       -> reverted, log "recipient is not on the allowlist"

Then verify both transactions yourself over NEAR RPC (method "tx", sender_account_id
= the vault printed by the script) and show me the two statuses: SuccessValue and Failure.

This is a shared, rate-limited testnet sandbox; it is intended for sequential demos, not unlimited concurrent runs. Each successful test costs 0.05 N from the shared vault and consumes gas allowance. If a line says FAIL or shows cap/allowance exhaustion, stop and report it—don't loop or retry repeatedly.

Rules: do not modify the repo, do not create accounts, do not touch any key other than
the public sandbox key already in echoes/sandbox.json.
SHARED TESTNET · CAPACITY LIMIT
Everyone runs against the same vault. It's for sequential demos, not unlimited concurrent users. Each run spends 0.05 N; agent policy cap is 5 N/day, while the scoped key's separate gas allowance can also run out. If the test says FAIL or reports a cap/allowance error, the shared sandbox is busy or depleted—not proof the guardrail failed. Try later; do not keep retrying.
SANDBOX VAULT
demo.allowance-merchant.testnet
agent sandbox-worker · 0.05 N/test · 5 N/day shared cap
WHY THE KEY CAN BE PUBLIC
It is a NEAR FunctionCall key scoped to spend_as on one testnet contract. The protocol rejects every other method, the contract caps every payout, and only allowlisted recipients can be paid.
FOR PRODUCTION
Run echoes init with your own account, then hand your agent only the scoped key. Full instructions: AGENT_INSTALL.md
ROADMAP · NOT SHIPPED YET
MCP server exposing vault.spend_as as a native tool. Listed as roadmap on purpose — it is not in this repo yet.
[IMMUTABLE_AUDIT_STREAM]

Structured On-Chain & Agent Telemetry (audit.jsonl)

TIMESTAMP (UTC) AGENT / CALLER METHOD & TARGET AMOUNT VERDICT & GATE CONTRACT LOG
[04b // REJECTED_ON_CHAIN] — failed transactions the vault refused
source: nearblocks /v3 txns on allowance-swarm.testnet
BLOCK METHOD OUTCOME TX HASH
loading live rejections…
[BESPOKE_LOGO_&_BRAND_ASSETS]

Echoes Vector Identity & Repository Asset Kit

Engineered specifically around the official NEAR Protocol (#00EC97) design system. Click Download .SVG or Copy Code to drop directly into your repository's ./assets/ directory.

./assets/echoes-logo.svg 512×512
DOWNLOAD .SVG
./assets/echoes-logo-horizontal.svg 960×280
echoes GUARDRAIL VAULT ON NEAR
DOWNLOAD .SVG
./assets/echoes-logo-light.svg LIGHT + FAVICON
[TECHNICAL_DOCUMENTATION_&_FAQ]

Frequently Asked Questions (Architecture & Security)

Deep-dive technical specifications on how Echoes enforces deterministic on-chain spending boundaries on NEAR Protocol, why native access keys alone aren't enough, and how Hackathon Judges can verify the live vault.

/

At the NEAR protocol level, a FunctionCall access key carries two critical properties: (1) its native allowance (e.g., 0.25 NEAR) strictly meters execution gas fees, not outbound value transfers; and (2) protocol rules prohibit a FunctionCall key from signing transactions with a non-zero attached_deposit.

Therefore, an autonomous agent using a scoped FunctionCall key cannot directly attach NEAR tokens to pay external APIs or compute providers. Echoes bridges this architectural gap: the agent invokes spend_as with 0 attached_deposit, and the Echoes Rust Vault contract enforces stateful accounting (per-transaction limits, cumulative agent caps, global vault ceiling, and recipient allowlists) before executing Promise::new(recipient).transfer(amount) from the vault's treasury.

Because a sub-account constrains how much sits in the account — never where the money may go. Three structural gaps make "capped sub-account" a weaker guarantee than it looks:

  1. Access keys scope method names, never arguments. A NEAR access key is a tuple of (receiver_id, method_names, allowance). The runtime checks the method being called; it never parses that method's JSON arguments. A key scoped to usdc.testnet / ["ft_transfer"] is therefore a key that can move any amount to any recipient — ft_transfer({"receiver_id": "hacker-drain.testnet", "amount": "..."}) is a valid call for that key. A recipient allowlist cannot live in a key; it can only live in a contract that owns the funds.
  2. Splitting liquidity destroys the global ceiling. N sub-accounts means N independent balances. There is then no single on-chain place that enforces your real fleet-wide limit: to know the swarm spent at most 5 Ⓝ today you must aggregate off-chain — i.e. trust a keeper bot. Echoes keeps one treasury and enforces the per-agent daily cap and the vault daily cap against the same counters inside the same receipt, so the global ceiling is a storage invariant, not a monitoring claim.
  3. The balance is all-or-nothing. With a sub-account the pre-loaded balance is the only real limit, which forces a bad choice: fund it small and the agent dies mid-task on an unhelpful "insufficient balance" (or silently retries and burns gas); fund it large and one compromise takes everything at once, because nothing caps the individual transfer. Echoes separates "funded" from "spendable": the vault holds the capital, and policy decides what leaves per transaction and per day.

The Echoes answer: the agent never holds the money. It holds a FunctionCall key on allowance-swarm.testnet scoped to ["spend", "spend_as"], with no transferable allowance — protocol rules already forbid that key from attaching a deposit. Every payout must pass assert_recipient() plus the per-agent and vault arithmetic ceilings before Promise::transfer is even constructed. Worst case for a fully compromised agent key: at most per_tx NEAR, to an address you approved in advance, with the attempt sitting in get_log().

Honest limit: this protects the funds in the vault. A leaked agent key can still burn its own gas allowance on reverted calls — that is bounded by the key's gas allowance (≤ 0.25 Ⓝ) and by revoke_agent, not by Echoes' policy engine.

Every guardrail in spend_as is enforced before any transfer is scheduled. When a check fails the contract traps (Rust fail() → unreachable), so the whole receipt reverts: no Promise::transfer is ever created, spent_today is not incremented, no log entry is written, and zero yoctoNEAR moves. A prompt-injected agent therefore learns nothing and gains nothing per attempt — every retry costs it gas and fails identically.

Reverting alone would let a compromised key keep retrying forever, so Echoes adds an explicit owner-controlled kill path: revoke_agent(agent_id) flips active = false in persistent storage, and reactivate_agent / set_paused are gated by assert_owner(). Both are verifiable on this testnet account: revoke_agent and reactivate_agent transactions are listed below with block-level receipts.

Note: revocation is owner-triggered, not automatic. We deliberately did not market an "auto-revoke on breach" primitive — a contract cannot safely self-disable a key on a reverted receipt, and doing so non-atomically would require a separate keeper.

Every spend_as(amount, recipient, memo) call traverses five sequential verification gates — the agent is identified by the signer_account_pk() of the calling key, not by a passed-in id:

  1. GATE 01 (Protocol Key Scope & Predecessor): NEAR Runtime validates the ed25519 key is restricted to spend / spend_as with gas ≤ 0.25 NEAR.
  2. GATE 02 (Circuit Breaker): Asserts the vault is not paused by the owner (!self.is_paused).
  3. GATE 03 (Agent Active Status): Confirms the agent exists and agent.is_active == true.
  4. GATE 04 (Recipient Allowlist): Confirms self.allowlist.contains(&recipient). Otherwise the call reverts before any transfer is scheduled.
  5. GATE 05 (Dual Velocity Caps): Enforces three arithmetic ceilings simultaneously: amount <= agent.per_tx (0.20 Ⓝ), agent.spent_today + amount <= agent.daily (1.00 Ⓝ), amount <= vault.per_tx (0.50 Ⓝ), and vault.spent_today + amount <= vault.daily (5.00 Ⓝ).

Administrative methods (reactivate_agent, set_paused, add_to_allowlist, and register_agent) are protected by two independent barriers:

First, at the NEAR Runtime level, each agent's FunctionCall access key explicitly whitelists only ["spend", "spend_as"]. Any transaction signed by an agent key attempting to invoke reactivate_agent or set_paused is rejected by NEAR validators before WASM execution even begins (demonstrated in Preset 05). Second, inside the contract, assert_owner() verifies env::predecessor_account_id() == self.owner_id.

On NEAR Protocol, transaction nonces are tracked per AccessKey rather than per account. By provisioning a dedicated ed25519 FunctionCall Access Key for each autonomous worker in the swarm (agent-alpha, agent-beta), multiple agents can sign and broadcast transactions concurrently in the same block with zero nonce contention—while the Echoes contract atomically serializes their cumulative deductions against the shared Global Vault Cap.

Hackathon Judges can verify Echoes in three ways with zero local setup required:

  • 1. Testnet Console & 5-Gate Playground (In-Browser): Open the Swarm Security Console to simulate any agent spend or admin call against live testnet state, or connect MyNearWallet (testnet) / a scoped agent key to broadcast for real. For the gate-by-gate walkthrough, click "RUN SIMULATED SWARM DEMO" in the Hero or test all 5 presets in Section 03 and copy ready-to-run near-cli-rs commands.
  • 2. On-Chain Verification on NearBlocks Testnet Explorer: Inspect testnet.nearblocks.io/address/allowance-swarm.testnet to verify the deployed WASM contract, scoped FunctionCall access keys, and real Testnet transaction receipts.
  • 3. Python Swarm Agent Suite & audit.jsonl: Run python3 allowance/agent/swarm_demo.py or python3 allowance/agent/verify_vault_cap.py to broadcast live multi-agent transactions and generate cryptographically linked JSONL audit trails.

Echoes is architected as the foundational policy-enforcement layer for autonomous agents across the entire NEAR AI ecosystem:

  • NEAR Chain Signatures (MPC) Guardrails: Before the Echoes Vault requests a threshold signature from v1.signer-prod.testnet to sign an EVM, Bitcoin, or Solana payload on behalf of an agent, the payload must pass Echoes' 5-Gate velocity and destination allowlist checks.
  • NEP-141 stablecoin policies (USDC / USDT) — roadmap, not in this build: real agents pay in stablecoins, and today spend_as schedules only a native Promise::transfer. Shipping NEP-141 spending needs three concrete changes we have scoped but deliberately not faked: a spend_ft(amount, token, recipient, memo) path that calls ft_transfer on the token contract (with the same assert_recipient allowlist), a per-token spent_today counter keyed by token contract account, and a one-time storage_deposit so the vault can hold the token balance. Gates 02–05 already operate on plain u128 integers and are token-agnostic, so the policy struct applies per token unchanged.
  • NEAR Intents Solver Verification: Agents can submit bounded swap or compute intents where Echoes verifies maximum slippage and daily notional caps before committing solver settlement — the same counters, extended to a notional ceiling so an intent can be rejected before a solver ever quotes.