Pay-on-Proof
Outcome-based payments on Cardano: money moves only when signed real-world data (API3) proves a condition agreed in advance. One contract, any data source, nobody in the middle.
What this is, in one minute
The problem
A buyer and a seller, often two software agents, do not trust each other. Paying first risks losing the money. Paying after delivery risks never being paid. A platform in the middle ends up as the judge.
The idea
The buyer's payment goes into a smart contract with the rule written in it: pay the seller if signed data proves the outcome before a deadline, otherwise refund the buyer.
Why it holds
The data comes from an AirnodeHub (API3) provider that signs its answer. The contract checks the signature, the question asked, how old the answer is and the value. Nobody can redirect the money.
How a payment moves
- The buyer's agent asks for an escrow ("pay the creator if the post reaches 300,000 likes before 14:00") and the service answers with a price and the exact policy. The buyer's client recomputes that policy itself and pays only if it matches field by field.
- The payment lands in the contract. With Cardano's x402 "script" transfer method the payment output goes straight to our validator with the policy as its datum. No one holds it in between.
- A signed answer is the proof. The data provider signs "the post has 308,791 likes" (or the rainfall total, or any numbers an AirnodeHub source returns). The contract rebuilds the signed text, checks the signature, the question, the age and, for feeds that sign one, when the value was observed.
- The seller's keeper collects. It finds policies that pay the seller, fetches the signed answer, and submits the release. Anyone could; the money can only go to the seller named in the policy.
- Or the buyer is refunded. After the deadline only the buyer's key can take the money back, and not before.
Who can do what
| Who | Action | Allowed? |
|---|---|---|
| Anyone | Release with a valid, fresh, matching answer, paying the seller in full | yes |
| Anyone | Release but pay someone else, pay nobody, or pay a lovelace too little | no |
| Anyone | Release two policies of one seller with a single payment | no (a flaw we found in the first version, now fixed) |
| Anyone | Release with an edited value, another question, another signer, or an old answer | no |
| Buyer | Refund after the deadline | yes |
| Buyer | Refund before the deadline | no |
| Seller or a stranger | Refund (not the buyer's key) | no |
| A lying seller's server | Put another beneficiary, an easier rule or a longer deadline in the price list | refused by the buyer's client |
What it does not prove
- A signature proves what the data provider returned, not that it is true. Likes can be bought; an API can be wrong.
- It settles outcomes that data can verify: pay for the result, not for the effort. It does not judge the quality of an agent's work.
- There is no dispute process: if the data says the condition holds, the seller is paid.
- The observation time of a value is checked only for feeds that sign one (the free price feed we use as a test fixture). Rainfall and tweets sign none.
- Testnet only, not audited.
How this becomes a service
- Open and free: the contract, the verifier of API3 data and this bench. That is how others can trust it and build on it.
- The service is the keeper: it watches, buys the data and releases. It is paid only when it releases, so we earn when the customer's outcome happens.
- Premium later: campaign tools for brands (creator checks, payout plans, evidence packs, long watching windows).
- Honest about money: today we pay for the data ourselves and lose money on every job. The plan is growth first, through distribution on Masumi, not a hype cycle. The contract is open, so our edge is reliability, trust and distribution.
What is locked at the contract right now
Read from Cardano preprod through the node provider. Each row is a policy: the rule that must hold, the money held, and the deadline.
| Rule | Locked | State |
|---|
Run it live
This makes a real payment on Cardano preprod from the demo buyer wallet: 5 tADA of test money, plus a small fee. Everything below happens on chain and every step is a real transaction.
The seller's keeper
A watcher inside the service. It looks for policies that pay the seller, fetches the signed answer for each, and releases the ones whose rule holds. It is switched off unless the service starts with AUTO_RELEASE=1.
| Policy | Rule | State |
|---|
Recent jobs
Paid keeper requests (x402, 2 tADA, charged only on release), escrows accepted, and releases by the seller's keeper.
| Time (UTC) | What | Outcome |
|---|
Hire the keeper (x402 on Cardano)
For a locked policy it fetches a fresh signed answer and, if the rule holds, releases the money. You pay 2 tADA by x402 and only when it releases; if the rule is not met or anything fails, the payment is cancelled.
npx tsx src/keep-client.ts --ref <txHash>#<index>
Tamper bench
Pick a policy, paste or edit a signed response, and send it to the contract. The answer is the validator's own script evaluation on the Cardano preprod node provider. Nothing is ever sent to the chain from this page.
Change a value, the timestamp, the request hash or the signature, then send it. Load an example with the buttons.