HTTP API
All JSON. Write helpers are keyless — they return drafts + unsigned register()
params; you sign. Machine-readable: OpenAPI 3.1 · try it in
the Swagger explorer. Always-current prose:
/llms/api.md.
Base: a Sup host ($SUP). All endpoints accept a network of testnet (default) or
mainnet.
#Discover
#GET /api/adaptors?network=testnet
The live catalog.
{ "network": "testnet", "count": 3, "adaptors": [ {
"serviceType": "0x…::adaptor::CetusAdaptor",
"packageId": "0x…", "publisher": "0x…",
"manifestUri": "walrus://…", "manifestHash": "…", "version": 1, "updatedAtMs": 0,
"manifest": { /* AdaptorManifest, see /docs/manifest */ },
"manifestVerified": true, "source": "registry",
"usage": { "actions": 0, "uniqueWallets": 0, "lastActionMs": 0 },
"reviews": { "count": 1, "avg": 3, "verifiedCount": 0, "verifiedAvg": 0, "lastMs": 0 }
} ] }
#GET /api/adaptors/schema
The manifest + call-spec shape and the registry ids per network. Use it to discover the
registryObject / registryPackage to call register() against.
#Publish helpers
#POST /api/adaptors/introspect
// request
{ "packageId": "0x…", "network": "testnet" }
// response
{ "witnesses": [ { "module": "adaptor", "name": "CetusAdaptor", "serviceType": "0x…" } ],
"ops": [ { "module": "adaptor", "entry": "swap_a_to_b", "fqn": "0x…",
"touchesWallet": true, "paramCount": 8, "typeParamCount": 2,
"params": [ { "typeStr": "&mut Wallet", "role": "wallet" }, … ] } ],
"modules": ["adaptor"] }
Each op param gets a guessed role: wallet | amount | minOut | object | clock | pure | ctx.
#POST /api/adaptors/infer
// request
{ "packageId": "0x…", "entry": "swap_a_to_b", "network": "mainnet" }
// response
{ "entry": "swap_a_to_b", "samples": 3, "sampleTypeArgs": ["0x…", "0x…"],
"args": [
{ "objectCandidates": [], "singleton": false, "pureCandidates": [] }, // wallet
{ "objectCandidates": ["0xdaa4…"], "singleton": true, "pureCandidates": [] }, // config
{ "objectCandidates": ["0x51e8…","0x…"], "singleton": false, "pureCandidates": [] }, // pool
…
] }
Args align to the op's non-ctx parameters in order.
#POST /api/adaptors/draft
// request
{ "packageId": "0x…", "name": "MySwap", "summary": "…", "category": "Swap",
"witness": "0x…?", "network": "testnet", "upload": true,
"feeBps": 10, "feeRecipient": "0x…", "integrator": "acme" }
// response
{ "network": "testnet", "serviceType": "0x…", "ops": 2, "executableOps": 2,
"manifestHash": "…", "manifestUri": "walrus://… | null",
"manifest": { /* … */ },
"register": { // UNSIGNED — sign with your own wallet
"deployed": true,
"target": "0x…::registry::register",
"arguments": [
{ "kind": "object", "value": "0x<registryObject>" },
{ "kind": "address", "value": "0x<packageId>" },
{ "kind": "string", "value": "0x…::adaptor::CetusAdaptor" },
{ "kind": "string", "value": "walrus://…" },
{ "kind": "vector<u8>", "value": "<hashHex>", "encoding": "hex" },
{ "kind": "object", "value": "0x6" }
] } }
With upload:true the manifest is pinned to Walrus and manifestUri is filled; otherwise
upload it yourself and substitute the walrus://<blobId> into the register args.
#Errors
{ "error": "…" } with the matching status:
| status | meaning |
|---|---|
| 400 | bad / missing input |
| 401 | unauthorized (admin/api-key endpoints) |
| 404 | package or op not found |
| 429 | rate limited (when KV is enabled) — see retry-after |
| 500 / 502 | upstream (RPC / Walrus) failure |
| 503 | a feature needs KV configured |
#Rate-limit headers
When the host enables KV, every response carries x-ratelimit-limit,
x-ratelimit-remaining, x-ratelimit-reset. Anonymous callers are limited per IP; an API
key raises the limit. See Rate limits & webhooks.