Reference
Manifest & call spec
A listing's rich metadata is a JSON manifest — off-chain on Walrus, with its sha256 pinned
on-chain. The registry never trusts the body until the hash matches (manifestVerified).
#Manifest fields
{
"name": "Cetus",
"category": "Swap",
"summary": "Spot swap via Cetus AMM",
"serviceType": "0x…::adaptor::CetusAdaptor",
"packageId": "0x…",
"ops": [ /* AdaptorOp[] */ ],
"supportedCoins": ["*"],
"feeBps": 10,
"feeRecipient": "0x…",
"integrator": "acme",
"networks": ["mainnet"],
"docsUrl": "…", "repoUrl": "…", "auditUrl": "…", "appUrl": "…", "glyph": "≋"
}
| field | type | meaning |
|---|---|---|
name | string | display name (required) |
category | string | Swap | Lend | Trading | Stake | Recurring | Guardian | Other |
summary | string | one line (required) |
serviceType | string | the witness FQN 0x<pkg>::<module>::<Witness> (required) |
packageId | address | deployed adaptor package (required) |
ops | AdaptorOp[] | operations (required) |
supportedCoins | string[] | coin types, or ["*"] for any |
feeBps | number | declared integrator fee in basis points (optional) |
feeRecipient | address | who receives the fee (optional) |
integrator | string | partner id for attribution (optional) |
networks | string[] | ("testnet"|"mainnet")[] |
docsUrl / repoUrl / auditUrl / appUrl / glyph | — | optional |
#AdaptorOp
{ "kind": "swap", // swap | lend | stake | pay | custom — for UI grouping
"module": "adaptor", // Move module
"entry": "swap_a_to_b", // entry function name
"label": "Swap A → B", // human label
"intentMode": "D", // A|B|C|D (informational)
"call": { /* OpCallSpec — present ⇒ agent-EXECUTABLE; absent ⇒ discover/authorize only */ } }
#OpCallSpec
The on-chain ABI gives parameter types, not meaning — so the publisher declares each argument's role. An agent resolves it into a concrete PTB at call time.
{
"typeArgs": ["coinIn", "coinOut"], // each: "coinIn" | "coinOut" | a fixed "0x..::mod::T"
"args": [ // in order; TxContext is NOT included (PTBs supply it)
{ "kind": "wallet" },
{ "kind": "object", "id": "0x…" },
{ "kind": "amount" },
{ "kind": "minOut" },
{ "kind": "pure", "type": "u128", "value": "4295048016" },
{ "kind": "clock" }
],
"needsAmount": true, "needsCoinIn": true, "needsCoinOut": true
}
#Argument roles
| kind | resolved to (at call time) |
|---|---|
wallet | the vault object id |
amount | the user's input amount, atomic by coinIn decimals |
minOut | slippage floor, atomic by coinOut decimals (0 if absent) |
object | a fixed object id you provide (id) — pool / config / treasury / market |
clock | 0x6 |
pure | a fixed scalar — type ∈ u8 u16 u32 u64 u128 u256 bool address string, with value |
ctx | dropped — Sui PTBs provide TxContext implicitly |
#Type arguments
typeArgs are filled in order: "coinIn" / "coinOut" substitute the user's chosen coin
types; any other string is treated as a fixed type argument and used verbatim.
#Hashing (integrity)
manifest_hash = sha256( canonicalBytes )
canonicalBytes = utf8( JSON.stringify( manifest, keys sorted RECURSIVELY, no whitespace ) )
Readers fetch the Walrus blob, recompute the hash, and compare to the on-chain
manifest_hash before trusting the body. Upload exactly the canonical bytes you hashed —
otherwise manifestVerified is false.
#Validation rules (enforced by the tooling)
name,category,summary,serviceType,packageIdare required;opsnon-empty.feeBpsmust be a non-negative number; the UI flags anything above 1000 bps (10%).- An op with a
callspec must resolve everyobjectarg to a non-empty id to be executable.