Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ERC-8183 PancakeSwap Settlement Reference Agent

A runnable reference agent (not a production service) that acts as an ERC-8183 Provider: it discovers a funded swap-intent Job, quotes via PancakeSwap aggregation, and settles a swap so the output token is delivered directly to the requester (Client) — holding no inventory and fronting no capital. Identity via ERC-8004, task interface via ERC-8183 (the official bnbagent SDK), on a local fork of BSC mainnet.

This repo is a developer example: clone it, run make demo, and read the code to see how a Job is discovered, quoted under guardrails, and settled.

What works today: end-to-end settlement via the PancakeSwap Aggregator /v1/calldata passthrough (any route: multi-hop/split) under a full deterministic guardrail suite (token safelist, slippage, tip floor, per-Job value cap, single-Job concurrency, gas precondition, re-quote, idempotency, router allowlist), with the Provider registering an ERC-8004 on-chain identity on startup (register + setAgentWallet via EIP-712, cached agentId). A pluggable natural-language intent layer (LLM → structured SwapIntent) is a documented next step.

Quickstart

make install       # create .venv, install the package + dev deps (needs uv + foundry)
make demo          # start a local BSC fork, run the whole lifecycle (WBNB→USDT), tear it down
make demo-multihop # settle a multi-hop route (CAKE→USDT, routed through ETH) via the same path
make demo-safety   # prove both legs are safe: induced swap revert + tip claimRefund
make test          # pure-core unit tests (no chain, no network)

make demo prints a summary: the swap tx, the deliverable hash, the output the Client received (≥ minOut), and the U tip released to the Provider. No manual steps, no keys, no accounts — it forks BSC with anvil against a public archive RPC.

How settlement works — two safe legs

The bnbagent ERC-8183 kernel is a single-fixed-token escrow (U / United Stables): it has no swap and no per-Job token, so the swap cannot be a single ERC-8183 Job. This agent settles it as two independently safe legs:

  1. Off-kernel swap (the Provider's own tx): pull the Client's pre-approved input, then send the calldata built by the PancakeSwap Aggregator /v1/calldata endpoint for the full route (multi-hop/split), with recipient = Client, a minOut floor of max(minOut, quote×(1−0.5%)) (never 0), and a tight deadline. The output goes straight to the Client; it never touches the agent wallet. Atomic within that tx — on revert the pulled input is refunded, so nothing is stranded. The calldata is opaque, so the trust boundary is two deterministic checks: before signing, the calldata to must be on an Aggregator-router allowlist; after the swap, the Client's output balance must have risen ≥ the floor.
  2. Tip escrow (the ERC-8183 Job): budget = the tip, denominated in U. The Provider submits the swap tx hash as the deliverable; after the 7-day dispute window a keeper verifies the Client received ≥ minOut and calls settle, releasing the tip.

A single-tx variant (a custom Solidity swap-hook that swaps and releases the tip atomically) is a documented future upgrade, not part of this sample.

Identity (ERC-8004)

On startup the Provider registers an on-chain ERC-8004 identity: register(agentURI) — where agentURI is a self-contained data: URI encoding agent-registration.json — then binds its operating wallet with setAgentWallet via an EIP-712 signature. The agentId is cached in .env and reused on later runs. The register/setAgentWallet mechanism was verified against the deployed BSC registry — including a fork quirk: the demo dev keys inherit an EIP-7702 delegation from mainnet that must be cleared before the registry's _safeMint will mint the agent NFT to them.

Module layout

agent/
  config.py      static config: safelist, router allowlist, guardrail defaults (pure)
  intent.py      SwapIntent parse + validation of untrusted input (pure)
  routing.py     Aggregator quote + calldata — fetch (network) + parse_quote/parse_calldata (pure)
  guardrails.py  deterministic accept/reject + settlement params + `to` allowlist (pure)
  chain.py       web3 construction, ABIs, signed-send, raw-calldata send, RPC resilience
  identity.py    ERC-8004 register + setAgentWallet (EIP-712) + agentId cache (on-chain)
  jobs.py        ERC8183Client wiring + funded-Job detection (on-chain)
  settlement.py  off-kernel swap (calldata passthrough) + deliverable submission (on-chain)
  __main__.py    the Provider settle-one loop (registers identity on startup)
demo/
  fork.py        anvil BSC fork bootstrap + demo-only cheatcodes (seed / warp / clear-code)
  client.py      the Client: create + fund the tip Job, approve the swap input
  evaluator.py   the keeper: verify delivery, warp past the window, settle
  run_demo.py    orchestrates the full lifecycle — the `make demo` / `make demo-multihop` targets
tests/           pure-core unit tests (no chain, no network)

Design seam: guardrails, intent, and routing's parse_quote/parse_calldata are pure — no chain, no network — so the safety-critical logic is unit-tested off-fork. On-chain writes live only in identity / jobs / settlement.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages