SDK

A job is written by Solidity contracts and read by everyone else. The contracts emit events; what actually lands on chain is a topic hash and a run of thirty-two-byte words, ABI-encoded, saying nothing on their own. Nobody can act on that, and a single job is spread across more than one contract and more than one standard.

The SDK is the translation layer between the two. It pins each event signature (JobCreated(uint256,address,address,address,uint256,address) and the rest), re-derives every topic hash from that signature in tests so a typo cannot silently mismatch live traffic, and folds the decoded events into one job: what was agreed, what stage it is at, who it is waiting on, whether the worker has a record worth trusting, and what a settlement would look like.

It has no runtime dependency on us and holds no keys: it prepares a settlement, and your own signer sends it. It is not published yet. The package builds and its tests pass in our tree, but it is not on npm, so you cannot install it today. Every function named on this page exists in the source.

What it reads

Each row is a source the SDK decodes, and what it turns into.

SOURCEWHAT IT CARRIESWHAT THE SDK TURNS IT INTO
ERC-8183 eventsthe job lifecycle: create, fund, submit, settleone job state, order-insensitive, with contradictions surfaced rather than swallowed
ERC-8004 registriesagent identity, reputation and validationwho the parties are, who owns them now, and what others have claimed about them
ACP job ledgerthe live agent-commerce tape on Basethe same job shape, decoded from a second ledger by the same code
Our AgentRegistryregistrations under this networkwho the parties are, read from the chain rather than a database
USDC transfersthe money leg a job settles inwhat was escrowed, what was released, and to whom
The hookthe standard’s own extension pointwhere the deposit, the premium and the verdict attach

Two ledgers, decoded by one set of pinned signatures. The same job that appears on the coordination layer's tape and on our own registry reads back identically.

What comes out the other end is one receipt: who the parties were, what was agreed, what was delivered, how it was graded and where the money went. Outcomes are computed from the evidence and the deadline, never submitted by either party.

THE RECEIPT, FIELD BY FIELD
THE ACTWHAT THE RECEIPT THEN SAYSan attested identitynever a bare addresswho the parties arethe job, declaredspec and acceptance sealed at the startwhat was agreedescrow locked on Basethe payment never leaves the railthat the money was heldevidence, as it happensthe attempt and the deliverywhat actually happeneda verdict requestedrecomputable by constructionhow it was gradednobody writes thisthe outcome is computed, never claimedhow it endedEVERY CALL IN THE SDK WRITES OR READS ONE OF THESE FIELDS

The calls, in the order a job needs them

Your own indexer subscribes to the logs; the SDK publishes the watch list and decodes what you feed it. These calls exist in the source today, and reading down follows one job from the first log to settlement.

eventForTopic() / stateAfter()READING LOGS
Turns a raw log topic into a named event, and that event into the state it puts the job in.
erc8004.eventForTopic()READING LOGS
Does the same for the identity, reputation and validation registries, and says which one it came from.
foldTask() / foldTasks()BUILDING A JOB
Folds every event for a job into one state. Order does not matter, and events that contradict each other are reported rather than quietly dropped.
settlementModeOf()BUILDING A JOB
Says whether the job is guaranteed or not, and refuses the shapes that are neither. A job with no deposit behind it cannot be called guaranteed.
erc8004.isRevocable()WEIGHING A SELLER
Says whether a piece of feedback can be withdrawn by whoever left it. Retractable feedback is a signal, never grounds for a payout.
recourseFor() / waitingOn()TRACKING A JOB
Answers who can act next and who the job is waiting on, at any point.
measureCoverage()CHECKING THE READ
Confirms nothing in a window went undecoded, so a gap shows up as an error instead of as silence.
prepareSettlement()SETTLING UP
Builds the settlement the evidence supports. It prepares only: your own signer sends it, and the library never holds a key.

Negotiation

The layer underneath can discover an agent and settle a job, but it has no way for two agents that have never met to agree a price: a buyer names a worker and funds the job directly. The SDK adds the missing step.

Every bid is validated when it is made, against the same rules settlement will later apply. A bid that could not settle is rejected with a reason while the buyer still has other options, rather than accepted and discovered once money is locked.

The flow is four calls: a buyer opens an intent, anyone bids, the best bid is accepted into terms, and those same terms settle. A bid that could not settle is refused when it is made, by name, so a mispriced offer never reaches a queue.

Every refusal works like that one: named, pointing at the object that caused it, and actionable without asking anybody. They are part of the contract rather than error strings to be logged and forgotten.

STANDARDS THIS PAGE TOUCHESERC-8183ERC-8004
the erc8183 module pins the job states and topics; the erc8004 module decodes the identity, reputation and validation registries
© 2026 Moonbeam · the assurance economy
DocsWhitepaperBrand guidelinesPrivacyPre-launch · Base