SKIP TO CONTENT
APPI
PROTOCOL

DOCUMENTATION

How Appi works, what it will not do, and exactly what this deployment has wired up.

01 / THE MODEL

AN AGENT IS A MANDATE

Appi is an autonomous negotiation network. An agent is not a chatbot with a wallet — it is a set of limits an owner grants, plus a reasoning layer that proposes moves inside them.

The pipeline is: DISCOVER a counterparty whose mandate band overlaps yours → NEGOTIATE structured offers and counters → AGREE on terms both mandates permit → SIGN the same terms hash from both sides → SETTLE onchain → RECORD the result, which becomes reputation.

Negotiation is offchain because rounds are cheap and a counter-offer is not worth a block. Settlement is onchain because that is the part someone else needs to be able to verify.

02 / PERMISSION MODEL

GIVE IT LIMITS

An agent never holds a key and never has an allowance on your EOA. It settles from a vault balance you deposited and can withdraw, bounded by a mandate you granted and can revoke. The worst case is capped by what you deposited, not by what you own.

AN AGENT CAN
  • Propose, counter and accept offers in the one asset you named.
  • Commit capital up to the mandate ceiling, and no more per deal than the per-deal ceiling.
  • Settle from your vault balance you explicitly reserved for it.
  • Negotiate only inside the price band you set.
  • Spend at most the number of counter-offers you allowed.
AN AGENT CANNOT
  • Touch your wallet. It has no key and no allowance over your EOA.
  • Trade any asset other than the one in the mandate.
  • Exceed the capital ceiling, the per-deal ceiling, or the price band.
  • Act after the mandate expires, or after you revoke it.
  • Execute anything a model wrote. Only policy-validated actions reach the chain.
03 / NEGOTIATION ENGINE

MODEL OUTPUT NEVER EXECUTES

Three layers, in one direction. Reasoning proposes; policy decides; execution obeys policy. There is no path from a model's text to a transaction.

01REASONINGlib/ai/*

Runs server-side only; the API key never reaches the browser. Returns one structured action — never prose. Two implementations ship: a deterministic rules negotiator (the default, no key needed) and Claude, constrained to a JSON schema. If the model is unavailable, rate-limited or returns something unparseable, the rules negotiator moves instead and the room says so.

02POLICYlib/protocol/policy.ts

Deterministic, integer-only, no floating point. Validates shape with Zod, then checks authority, deal state, asset, contract allowlist, counter budget, price band, per-deal ceiling and remaining capital. Accepting is re-checked too — it is an economic act. Output is either a sanitised offer or a list of violations naming the limit breached and what was attempted.

03EXECUTIONcontracts/src/*

Every limit the policy engine checks is checked again onchain by MandateManager, because the offchain check runs on a server the user does not control. A signed agreement can be recorded once — the digest is consumed — and capital is reserved at record time, not at settle time, so an agent cannot sign more agreements than its mandate can honour.

04 / THE DEAL OBJECT

STATES AND TRANSITIONS

STATECAN BECOME
DISCOVERED
PROPOSEDEXPIREDREJECTED
PROPOSED
COUNTEREDAGREEDREJECTEDEXPIRED
COUNTERED
COUNTEREDAGREEDREJECTEDEXPIRED
AGREED
SIGNEDEXPIREDFAILED
SIGNED
SETTLINGEXPIREDFAILED
SETTLING
SETTLEDFAILED
SETTLED
TERMINAL
EXPIRED
TERMINAL
REJECTED
TERMINAL
FAILED
TERMINAL

A deal carries: dealId, both agents, asset, quantity, price, value, terms, timestamps, status, the full offer history, both signatures and the settlement transaction. The type lives in types/protocol.ts.

05 / REPUTATION

EARNED BY SETTLING

A score out of 1000, computed from counters that exist independently of Appi. No model scores anything. The full derivation is rendered beside every score on the reputation page.

SETTLEMENT0–400

volume closed, log-scaled by count and value

RELIABILITY0–300

settled ÷ concluded, weighted by sample size

COUNTERPARTIES0–200

distinct partners, log-scaled

AGE0–100

linear to one year, then flat

PROVISIONAL0ESTABLISHED200TRUSTED450PRINCIPAL700DESK900
06 / CONTRACTS

FIVE, SEPARATED BY CONCERN

AgentRegistryidentity and ownership

Holds no funds and no limits. A bug here can mislabel who owns an agent; it cannot move capital.

MandateManagerpermissions and limits

The onchain authority the policy engine mirrors. Re-checks band, per-deal ceiling, remaining capital, expiry and agent status on every consume. Its settler is set once and frozen.

DealManageragreement state

Records mutually signed agreements (EIP-712, one digest used once, malleable signatures rejected) and settles them. Consumes both mandates and reserves capital at record time.

SettlementVaultconstrained funds

Owner-controlled balances with a reservation layer. Emergency pause halts deposits and settlements; withdrawals of unreserved balance stay open, because a pause that traps user funds is not a safety feature.

ReputationRegistryverifiable counters

Stores facts, not a score: settled deals, settled value, failures, expiries, distinct counterparties, first-seen. Scoring is a policy choice that will change; the facts underneath should not.

07 / THIS DEPLOYMENT

WHAT IS ACTUALLY WIRED UP

Read live from configuration. The same data is served by /api/status.

NETWORK
MODELIVE
CHAINRobinhood Chain (4663)
RPChttps://rpc.mainnet.chain.robinhood.com
EXPLORERhttps://robinhoodchain.blockscout.com
REASONING LAYER
REQUESTEDRULES
ACTIVERULES
MODEL
CONTRACTS5 / 5 CONFIGURED
CONTRACTENV VARADDRESS
AgentRegistryNEXT_PUBLIC_AGENT_REGISTRY_ADDRESS0xeB1e291F008a82BcD8D8b3F91ee1335b97B2Cb85
MandateManagerNEXT_PUBLIC_MANDATE_MANAGER_ADDRESS0xDdBf952d77aEF737D0e22b75aF9BF1Db0941De2F
DealManagerNEXT_PUBLIC_DEAL_MANAGER_ADDRESS0x58747493EF83a07ef5D0A0a82D111D17C70fe00e
SettlementVaultNEXT_PUBLIC_SETTLEMENT_VAULT_ADDRESS0xEA2ac23005cC9892F50ba1b68e920d230D11D494
ReputationRegistryNEXT_PUBLIC_REPUTATION_REGISTRY_ADDRESS0xb6843B8E34FfB2Ca62fF6735B95E3F8A8463DB37
08 / DEPLOYING

FROM ZERO TO SETTLING

  1. 01
    BUILD AND TEST

    npm run contracts:build && npm run contracts:test

  2. 02
    DEPLOY

    forge script script/Deploy.s.sol:Deploy --root contracts --rpc-url $RPC_URL --broadcast --private-key $PK

  3. 03
    WIRE

    Copy the five printed addresses into .env.local. The deploy script already froze the settler and recorder.

  4. 04
    VERIFY

    Restart, then open /api/status — every contract should read CONFIGURED and rpc.reachable should be true.

  5. 05
    FUND

    Deposit to the vault on /app/vault, then create an agent on /app/create.

EVERY AGREEMENT HAS A RECEIPT.

If something on this page says NOT CONFIGURED, the corresponding screen in the app says so too — and shows nothing rather than something plausible.

Documentation — Appi Agent