Skip to content

Provenance

What we built, and what we brought.

The hackathon asks that what you show was built during the six weeks. This is the detailed answer, including the parts that are not finished.

Every claim below names a file, a test count, or something read back from the chain. Counts come from the suites, run on 19 October 2026.

Written during the build window

The policy engine had nothing to inherit.

The team’s earlier payments work has no spending limits, no merchant allowlist and no subscription logic anywhere in it. Every file below was written for this build.

  • NuntioAccount.sol

    The account that holds the funds and decides every payment. Allowance, per payment cap, frequency limit, expiry, pause, and a merchant allowlist held separately for each spender. There is no address parameter on the paying function at all, so naming a recipient is not something a spender can express.

    • packages/contracts/src/NuntioAccount.sol
    • 1,064 lines
    • 188 tests
  • ApprovalQueue.sol

    Where a refused payment goes to ask a human. It is a separate transaction because a revert rolls back its own writes, so blocking a payment and recording that somebody asked for it cannot happen in the same call. Only the owner may agree to a request, and a request is accepted only from the spender it names.

    • packages/contracts/src/ApprovalQueue.sol
    • 800 lines
    • 108 tests
  • ServiceRegistry.sol

    Merchant lookup by id. Resolution reverts on an id nobody registered, rather than returning the zero address, which is what makes an invented recipient fail at lookup instead of sending money to a hole and minting a receipt that claims delivery.

    • packages/contracts/src/ServiceRegistry.sol
    • 205 lines
    • 30 tests
    • packages/contracts/deployments/10143.json
  • NuntioTeamFactory.sol

    Creates a sealed account and approval queue for a new team in one transaction, then hands ownership to whoever asked. Anyone signed in can create a team of their own through it, owned by their own wallet. On testnet it also created the Sandbox, the account every tester joins.

    • packages/contracts/src/NuntioTeamFactory.sol
    • 108 lines
    • 15 tests, plus 3 for its deploy script
  • CallerProbe.sol

    A throwaway diagnostic that records what a contract observes as its caller during a real transaction. It exists so that no authorization code has to assume the answer. It is state changing rather than a view, because a read reports what a node computes and not what the chain records.

    • packages/contracts/src/CallerProbe.sol
    • 130 lines
    • 9 tests
    • docs/research/CONSTANTS.md
  • The assistant

    A constrained tool caller that emits a typed payment intent and nothing else. It holds no key, builds no calldata and picks no address. The pipeline runs catalog, provider, shape, resolution and assembly in that order, and the first stage refuses a request before the model is ever called.

    • packages/agent/
    • 266 tests across 13 files
  • Service resolution in the SDK

    A lookup has four outcomes: known, unknown, suspended, and unreadable. Unreadable is the one that gets deleted, and folding it into unknown would let a rate limited node report a real merchant as invented, which is the most misleading direction that failure can take.

    • packages/sdk/src/registry.ts
    • 206 lines
    • 207 tests in the package
  • The web application

    Onboarding, policies, spenders, approvals, activity, the assistant screen, the testnet Sandbox and teams: creating your own, invitation links, and owner actions signed by the owner’s own wallet. It includes the held and declined states that the product exists to show. A blocked payment is drawn as a success state, because that is what it is. Payment history reads every account deployment through Envio HyperSync, and each payment shown is read back from its own onchain receipt.

    • apps/web/
    • 2,433 tests, plus 22 against the live chain
  • Persistence

    PostgreSQL for the state a contract cannot hold: agents, jobs, payment intents, an append-only audit trail, Sandbox joins, and the teams people create with their invitations. Duplicate intents and duplicate chain events are refused by the database itself, not by application code remembering to check. Nothing here authorizes a payment; the contract still does that.

    • packages/db/
    • 4 migrations
    • 122 tests, plus 55 against a real database
  • The agent worker

    The process that lets an assistant act while nobody is signed in. It records an intent before it signs and a transaction hash the moment one exists, so a crash mid-payment is recovered by reading the chain rather than by sending again. It runs live on mainnet and testnet: on 12 October 2026 an agent paid $0.10 of real AUSD to a demo service run by Nuntio, by itself, from a wallet holding no MON. That service is suspended now, and the worker cannot buy a quoted compute run, so on mainnet an agent has nothing to pay on its own today. It files no approval requests yet, so an agent’s payment over its limit is refused and stops there.

    • apps/worker/
    • 354 tests, plus 74 against a real database
  • Agent identity

    Each agent gets its own wallet, created by Privy under a key that only the worker holds, so the web server can set an agent up and can never sign for it. The wallet’s own policy allows payments from this account and approval requests for itself, and nothing else; the contract still decides every payment. Agents are in beta: during it, only Nuntio’s team can create one, and only on Nuntio’s own account, not yet on a team’s.

    • packages/agents/
    • 81 tests
  • The commerce gateway

    Nuntio’s own merchant, and on mainnet the only one. It signs a price, waits until the payment is final and matches that price exactly, then runs the model on 0G or buys the latest Monad block over x402, paying both from its own funds, and keeps the result. It can sign for no account. A run it cannot deliver is recorded as owed, and an operator sends the refund.

    • apps/gateway/
    • packages/commerce/
    • packages/zg-compute/
    • 407 tests, plus 27 against a real database

506 Solidity tests across 15 suites and 3,870 TypeScript tests across 280 files, all passing on 19 October 2026. Each rule the contracts enforce carries a test that it holds and a test that the invalid case is rejected.

Carried in from earlier work

Two forks are planned. Neither has landed.

The same authors shipped two payment products before this one. Here is what that gives Nuntio, stated as it stands today rather than as it is meant to end up.

  • A payment router, decided and not yet taken

    The plan is to fork the non custodial transfer router and the handle registry from the team’s earlier private EVM product, and use them as the base for moving money. That fork is not in this repository. The contracts directory holds five files and all five are listed above as new. When the fork arrives, each file it brings will carry a header naming where it came from.

    • docs/hackathon/PROVENANCE.md
    • packages/contracts/src (5 files)
  • A transaction lifecycle layer, same status

    The intent is to lift the four way outcome type that separates a revert from a timeout from an unreachable node, because Monad’s speculative state needs exactly that distinction and writing it again would be writing it worse. It has not been lifted yet.

    • docs/hackathon/PROVENANCE.md
    • 0 files in the tree
  • Conventions, reimplemented rather than copied

    What has actually crossed over is a list of rules the earlier products paid for: a version field in the first commit of every contract, a failed read that returns null instead of zero, money as base units until the render boundary, and cached balances that never authorize a payment. Those are written again here, in a different language, against a different chain.

    • CONTRIBUTING.md
    • NuntioAccount.sol VERSION
    • ApprovalQueue.sol VERSION
  • Third party code the contracts compile against

    Used, not written. These four, and the ERC-20 interface they work through, are the only external Solidity in the build today.

    • OpenZeppelin Contracts 5.7.0
    • Ownable2Step, SafeERC20, Pausable, ReentrancyGuard
  • Third party addresses recorded but not yet called

    The MetaMask delegation framework, Permit2, the x402 proxies and the Chainlink forwarders are written down with the date each was probed on chain. No code in this repository calls any of them yet, and saying otherwise would be counting a plan as a feature.

    • packages/sdk/src/addresses.ts
    • docs/research/CONSTANTS.md

Verified on chain

Deployed to Monad mainnet, checked on testnet first.

Chain id 143. These addresses come from the same file the app reads. The evidence rows under them were captured on Monad testnet, chain id 10143, before the contracts went to mainnet.

ServiceRegistry

0x91bde96d1a9765E78619396234F015ACbBd32E60View on the Monad explorer

The merchant registry on mainnet. An id nobody registered reverts here. It holds the five services Nuntio’s gateway sells, the only things to buy today: four AI models on 0G and the latest Monad block, bought over x402. It also holds the twelve demo services Nuntio ran before them, all suspended.

NuntioAccount

0xFA8B30f994c700976B6Ab575e77de78a161d4bdBView on the Monad explorer

Nuntio’s own account on mainnet: the contract that holds the money and decides every payment. A payment inside the rules settles here and a payment outside them reverts here.

ApprovalQueue

0xA910cDebf85eBD52c28f3B0448C00b659B76eD25View on the Monad explorer

Where a refused payment goes to ask the owner, bound to this account for good. Filing a request, agreeing to one and settling one are three separate transactions against this address.

CallerProbe

Not deployed

On testnet it recorded that, with the fee paid for it, the contract still sees the paying wallet as the sender, not the service that paid the fee (evidence 09).

  • All six testnet services resolve

    Each name held on chain matches the merchant name in the application’s fixtures exactly, and each slug matches the seeding script exactly. They had drifted to no overlap at all, which would have made every payment the assistant could propose revert for a reason that has nothing to do with the assistant.

    • docs/hackathon/evidence/03-every-fixture-merchant-resolves.md
    • 6 of 6
  • An id nobody registered reverts

    Asking the live registry for an invented merchant returns the selector for an unknown service followed by the 32 bytes of the id echoed back. The id the SDK decoded is identical to the one the chain returned, which is what makes the log line usable as evidence afterwards rather than only as a message.

    • docs/hackathon/evidence/01-unknown-service-reverts.md
    • 0xcab75967
  • Both refusal layers fire, and which one fires is recorded

    A merchant outside the spender’s list is refused by the schema before any network call. A merchant on the list that was never registered on chain gets past the schema and is refused by the registry. They catch different mistakes, and the second one is the one that survives an error in our own data.

    • docs/hackathon/evidence/04-two-layers-refuse-a-hallucination.md

Not done

What this page will not claim.

A provenance page that lists only the wins is not evidence of anything.

  • The flagship’s owner key lives on a server

    Owner actions on Nuntio’s own account are signed by a scoped server key. That key is bound to an ABI with no pay in it, and the single function it has that moves money takes an approval id rather than a recipient, so it can only settle something the owner already agreed to. Teams do not work this way: a team’s owner signs every owner action with their own wallet, and no server key can act for a team.

    • apps/web/lib/owner-server.ts
    • apps/web/app/api/owner/approvals/route.ts
  • No outside merchant yet: the one seller is Nuntio

    On mainnet the only things to buy are AI compute on 0G and Monad data bought over x402, sold by Nuntio’s own gateway on the Compute page, one quoted run at a time. New payment has nothing to pay until outside merchants are registered. The demo services Nuntio ran before, which paid its own wallet, are retired: old receipts still name them.

    • apps/web/lib/catalogue.ts
    • docs/research/CONSTANTS.md
  • Nothing here has been independently audited

    The contracts carry tests for each rule and for the case each rule is meant to reject. That is not the same thing as review by somebody with no stake in the answer. On mainnet that means real money: use amounts you can afford to lose.

    • 506 Solidity tests
    • 0 external reviews

Checking this yourself

  • Run forge test in packages/contracts for the Solidity counts, and pnpm -r test at the repository root for the TypeScript ones.
  • docs/hackathon/PROVENANCE.md is the in repository version of this page, and docs/hackathon/evidence/ holds the raw transcripts these summaries were taken from.
  • docs/research/CONSTANTS.md is the single source for every address, with the date each one was probed. Nothing enters the codebase without appearing there first.
  • The commit history covers the whole build window and carries the reasoning for each decision, including the ones that were later reversed.