Mandate
NEAR HACKATHON 2026 · AI Security & Defense

An AI agent that can propose trades, but cannot move the money.

Mandate splits the agent from the authority. The agent runs in a TEE and proposes swaps. A NEAR smart contract holds the only key to the treasury on NEAR Intents, and signs a trade only after checking it against the owner's rules. This page states exactly what is built, what is proven on mainnet, and what is not done yet.

Core risk proven on mainnet Trade rules built and tested On-chain trade flow: in progress (M3) Agent on OutLayer: not started (M4) No live trade yet
Trust model

Who can do what, and what enforces it

Each row names the mechanism that enforces the limit. "Nothing" means the limit is a promise, not a guarantee.

Bypass the contract's checks on a trade, because trades go through the gates regardless
ActorCanCannotEnforced by
OwnerSet the mandate, pause, unpauseContract: set_mandate needs a full-access key and 1 yocto
Agent (TEE, planned)Propose a swapSign, withdraw, change the mandate, bypass a gateContract. The agent has no key.
Keeper (planned)Trigger steps, delay a tradeChange a trade, sign anythingContract. The signed bytes fix amounts, deadline and nonce.
SolverFill a signed trade at or above the minimumTake more than the signed token_diffNEAR Intents verifier
Signer (MPC)Sign a payload the contract asks forBe asked by anyone but the vault contractChain Signatures: the derived key is bound to the contract account
Anyone with agent accessStop tradingMove fundsContract (see the rows above)
Flow

One trade, six steps

The trade passes two transactions by design: a decision, then an execution. Each step says whether it exists today.

  1. Decision. The agent reads the market and proposes a swap with a minimum output.

    Runs inside an OutLayer TEE, pinned by code hash. Results are returned to the contract by yield and resume.

    planned · M4
  2. Balances and prices. The contract reads the vault's balances on intents.near and a fresh oracle price.

    Stale prices are rejected. Oracle feed format is still to be confirmed.

    planned · M3
  3. Mandate check. Nine gates, in a fixed order. The first closed gate rejects the trade with a named code.

    Exact 256-bit USD math. Each rule has boundary tests and a property test.

    built · tested
  4. Intent bytes. The contract builds the exact raw_ed25519 payload with a V1 expirable nonce.

    Proven: the same bytes built by the vault's code pass mainnet simulate_intents checks.

    built · proven
  5. Signature. The contract asks the MPC network for an Ed25519 signature over those bytes.

    Proven on testnet: the signature is accepted by mainnet intents.near. The vault wiring is not done.

    proven parts · wiring M3
  6. Settlement. A solver publishes the signed intent and settles atomically.

    Not run for a real trade yet.

    planned · M5
Evidence

Each claim, its evidence, and how to reproduce it

Only claims marked "proven" or "tested" have evidence you can rerun. The rest are plans.

ClaimStatusEvidence
A contract can get an MPC signature that intents.near accepts as its own intent.R1 · part 2 proven on mainnet Testnet MPC signature, verified locally, then checked with simulate_intents on mainnet. Report: docs/spikes/R1.md. Rerun: spikes/r1-part2.sh
A payload built by the vault's own code passes signature, nonce and salt checks. proven on mainnet Valid V1 nonce with the live salt fails only on balance. A fake salt is rejected with invalid salt. Rerun: cargo run --release in spikes/r1-intents-signing
A tampered intent is rejected. proven on mainnet Payload changed after signing: invalid signature. Wrong verifying_contract: rejected.
Nine mandate gates reject each violation with a named code. unit and property tests Boundary tests per gate. A property test re-derives every rule for 20,000 random trades. A coverage guard checks that approvals and every rejection type occur. Rerun: cargo test -p mandate-vault engine::
Owner controls work on a real chain: re-init blocked, non-owner rejected, pause and unpause. sandbox test Deployed to a local NEAR sandbox and called through transactions. Rerun: ./scripts/verify.sh --integration
The vault registers its MPC-derived key on the real intents.near contract, using predecessor auth. sandbox test The exact mainnet intents.near wasm runs in a local sandbox. The test reads the key back from it and refuses a second registration. The MPC signer there is a stand-in that enforces the call convention. Fixture check: scripts/fetch-intents-fixture.sh. Rerun: ./scripts/verify.sh --integration
The vault's trading flow runs end to end on a chain. not yet Milestone M3. No evidence exists yet, and none is claimed.
The agent runs in a verifiable TEE. not yet Milestone M4. No attestation exists yet.
Verify it yourself

Three commands, about ten minutes

You need Rust (installed automatically from rust-toolchain.toml) and Python 3. No keys, no accounts, no funds.

1 · Contract rules and sandbox
$ ./scripts/verify.sh --integration
==> Formatting ... ok
==> Lints (warnings are errors) ... ok
test result: ok. 75 passed; 0 failed
test owner_controls_on_a_real_chain ... ok
All checks passed.
2 · Signature checks on live mainnet
$ cd spikes/r1-intents-signing && cargo run --release
[PASS] valid signature, no intents
[PASS] payload modified after signing
[PASS] wrong verifying_contract
[PASS] valid token_diff, unfunded account
[PASS] vault-built token_diff, V1 nonce with live salt
[PASS] vault-built token_diff, salt never issued
R1 part 1: all 6 cases behaved as expected.
3 · The dashboard (sample data)
$ cd web/dashboard && python3 -m http.server 8767
open http://localhost:8767/index.html

The dashboard renders scenarios from fixed sample data. It does not query the chain, so use steps 1 and 2 to check the claims.

Not done

What is missing, stated plainly

Source and history

Commits, pull requests and the R1 report are in the repository. The repository is private until submission.

Chain references

Verifier: intents.near · MPC signer: v1.signer. Anyone can read both on-chain.