Lifecycle
The deposit is a VTXO at the covenant script, and every status is a reading of that one VTXO. The covenant’s whole vocabulary is two leaves, so a deposit that moved tookfulfill or it took cancel — and which one is read off the
spending transaction’s tapleaf, not inferred from what the transaction moved.
The leaf is the evidence, not the amounts. What a fill has to deliver is
the covenant’s business and is enforced when the transaction is validated;
asking what a transaction moved cannot classify one, because an asset swap’s
cancel takes the asset out of the covenant and hands it straight back, netting
to zero and reading exactly like its fill. A spend that took neither leaf, or
one that cannot be fetched yet, is left unclassified — the record keeps the
status it had and a later read decides it. Nothing sticky is written on a
guess.
cancelling is local and provisional. cancelOffer writes it before it
broadcasts, so a crash between the submit and the record leaves a marker rather
than a swap that still reads pending. It is not evidence that a cancel
happened: a fill can win the race, and whichever leaf lands is what the status
becomes. A cancel made from another device never passes through it.
recoverable is the one status no spend produces. The deposit was swept —
the batch it sat in expired before either leaf was taken — so it is a
recoverable VTXO like any
other: still yours at that script, no longer exitable unilaterally, and
recovered by settling it rather than through the covenant. Keep the script
watched; a swept deposit is money still sitting there. The restore scan is what
writes this status, on records it rebuilds — the live watcher reports spends,
and a sweep is not one.
Funding the Swap
The application derives the non-interactive swap contract from the approved terms.createOffer registers the contract and returns the type 0x03
extension; it does not broadcast a transaction.
The swap becomes discoverable when the wallet funds the derived address and
includes that extension. The packet tells solvers watching the Arkade
transaction stream how to interpret the funded output.
Persist both the encoded offer and the funding transaction identifier.
Identical terms derive the same address, so the address alone does not identify
one deposit.
What the Contract Enforces
The non-interactive swap contract binds the asset identity and minimum amount the fulfillment must deliver. Both legs settle in one Arkade transaction. The covenant reads exactly one output. A fill is any transaction whose output 0 pays your script at least the amount of the asset you named; everything else about it — how many inputs the solver brings, where its change goes — is the solver’s business. The deposit side is never inspected, which is why the same contract carries BTC, an asset, or an asset-for-asset swap. Read the fill’s two inputs together and the swap is visible: the solver’s coins pay you, your deposit pays the solver, and neither leg can happen without the other because they are the same transaction. The funding transaction carries the type0x03 packet alongside its outputs;
that is what tells watching solvers the funded output is an offer and how to
read its terms.
The two ways out are deliberately asymmetric. A fill needs no signature from
you — the covenant is the constraint, so a solver cannot take the deposit
without paying output 0, and you can be offline while it happens. A
cancellation needs no signature from the solver, so taking the deposit back
never waits on a counterparty. Neither program carries a timelock, so nothing
about the offer expires: an unfilled deposit keeps its place at the swap
address on the terms it was funded with, and there is no expired state to
unwind. The VTXO holding it still carries its batch expiry — one left resting
past that is swept rather than filled or cancelled, which is the recoverable
status above and the only exit the covenant has no leaf for.
The contract does not guarantee:
- that a solver has sufficient inventory;
- that the feed represented a fair or current market price;
- that the swap fills within a particular time;
- that an asset issuer redeems or honors the asset.
emulatorPubkey parameter). Review
Trust and Limitations
before using the flow with value.
Standing Offers
A funded contract does not wait on the person who funded it. It names the asset, the minimum amount, and the script a fill has to pay, and anything that delivers those three settles it — from any solver, at any time, with the funder offline. An exchange would call terms fixed in advance a limit order, and one waiting to be taken a resting order. This is that, held as a contract on Arkade instead of a row in a venue’s book. The delivery and the spend are the same transaction, so there is no interval in which the contract is open and the payment is owed: a fill that does not pay the named terms is not a fill, it is an invalid transaction. A fill is all-or-nothing — partial fills would need a contract that pays a remainder back into itself, which this one does not do.Price Without a Book
The terms fix a ratio: what the contract holds, against what a fill must deliver. That ratio is the price. Solvers watch resting contracts and take the ones that beat their own pricing, leaving the rest. Nothing aggregates them. Each contract is independently enforceable, so no venue holds the orders, matches them, or has to stay solvent for one to settle — the reason the pattern is worth having rather than a book with custody attached. Today the ratio comes from the market feed, not from you. The application prices the swap from the card and you approve the result before funding, so a contract rests at a price that was current when you funded it. Choosing your own ratio — an offer that waits for the market to reach it — is future work, as is any surface that ranks resting contracts as a book.Discovery and Pricing
Solver cards advertise supported pairs, amount bounds, indicative fees, and a price feed for cross-asset markets. Applications choose which cards and registries they accept. The card and feed are advisory:- they do not reserve solver inventory;
- a feed response is not a signed quote;
- the application applies its own freshness, tolerance, and eligibility policy;
- the user reviews the resulting deposit, receive amount, and fee before funding.
The maker Fields
The covenant programs and the Offer type carry maker* identifiers —
makerWP, makerPkScript, makerPublicKey. They name contract positions,
not roles: the side that funds the swap and receives the fill. Arkade Intents
deliberately avoids maker and taker as participant vocabulary; the parties are
the user and the solver.
Negotiated Asset Swaps
The client package can map a negotiated quote whose endpoints both usearkade onto the same swap terms. No reference solver serves that RFQ path
today, so current asset integrations use discovery and market-feed pricing.
Sources
- Asset swap protocol
@arkade-os/swappackage- Contract Bytecode — both leaves of this contract, opcode by opcode
- Non-Interactive Swaps