Overview
Three transactions matter. The seller signs the first two at listing time and pays nothing; nothing is broadcast until a buyer appears. The third exists only as an escape hatch.
Listing
Listing costs the seller nothing and produces no broadcast. The client builds TX1 and TX2 from the server's template, verifies every field against pinned constants, and asks the wallet for two signatures in one prompt.
TX1: passthrough
The postage moves whole and the inscribed sat keeps its offset, so an inscription sitting at the bottom of its UTXO is as safe as one at the top. A zero-fee transaction cannot confirm on its own; it confirms only as the parent of a fee-paying TX2, so an escrow can never be stranded by a listing that no one buys. The 12-sat variant exists so that relays which enforce a 0.1 sat/vB floor without package evaluation, such as mempool.space, still accept the parent.
PSBT fields the client sets on input 0 before signing: witness_utxo, tap_internal_key (the seller's key for a native Taproot input) and sighash_type = SIGHASH_DEFAULT. The client rejects a template whose input, output count, fee or destination script differ from the rules above.
TX2: sale template
The seller signs input 0 on the sale leaf with SIGHASH_SINGLE | SIGHASH_ANYONECANPAY (0x83, a 65-byte signature). That commits to “this escrow pays me this amount at this index” and to nothing else, so the signature can be dropped into any larger transaction that also carries the co-signature, at any input position whose output index matches.
PSBT fields on input 0: witness_utxo, tap_internal_key = NUMS, tap_merkle_root, tap_scripts = [(sale leaf, control block)], sighash_type = 0x83. The internal key is the BIP-341 unspendable point, so a wallet that prefers key-path signing has no key path to fall back to and produces a leaf signature like everyone else.
The server stores the two signatures and the escrow price. Repricing replaces TX2's signature only; TX1 is unchanged. Delisting deletes both. Nothing touches the chain.
Recovery path
TX3 is not presigned. If TX1 ever confirms without a sale (a buyer's package was mined with a different link, or a relay accepted the 12-sat parent on its own), the seller requests a recovery PSBT that spends the escrow through the recovery leaf. Its single input carries sequence = 144, so it is valid 144 blocks (about one day) after TX1 confirmed, and needs only the seller's key.
Sale
A purchase of n items is a chain of n single-item sales, each broadcast as a two-transaction package [TX1_i, TX2_i]. Link i (0-based) has these inputs and outputs; k is the number of leading buyer inputs, so the escrow sits at input k and the payout at output k.
The seller's payout index equals the escrow's input index because of SIGHASH_SINGLE; every other output is under the buyer's control. The inscription output reuses the escrow's postage, so the sat offset is again unchanged.
The buyer signs every link and submits them in order. The server verifies each link byte-for-byte against its own template, adds the co-signature (the co-signer key is used only here, never at build time), finalizes the escrow witness [cosigner_sig, seller_sig, sale leaf, control block], checks every input under consensus rules, and relays with submitpackage([TX1_i, TX2_i]). The parent is never sent alone, and a package our node does not accept is reported to the buyer as failed. The package is then relayed best-effort to mempool.space's package endpoint and other public nodes.
Package relay
There are no anchor UTXOs and no venue-funded fee bumps. TX1 pays no fee, so nothing in the mempool can be replaced to steal the item: a competing buyer would need their own link carrying the same seller signature and our co-signature, and the server co-signs a given escrow for at most one armed sale at a time, with at most 12 armed chains per buyer address. If a buyer's package lingers at a low fee rate, the buyer can rebuild at a higher rate; if it never confirms, the listing simply stays live.
Passthrough Tapscript
tr(
NUMS,
{
<S> OP_CHECKSIG <C> OP_CHECKSIGADD 2 OP_NUMEQUAL, # sale leaf
144 OP_CHECKSEQUENCEVERIFY OP_DROP <S> OP_CHECKSIG # recovery leaf
}
)Sis the seller's x-only key;Cis the Ordinals Wallet co-signer key, pinned in the client.- Sale leaf: seller and co-signer together. The co-signer key alone can move nothing; with a compromised API it can at most complete a sale at the listed price to a buyer who paid it, or refuse to sign.
- Recovery leaf: seller alone, 144 blocks after the escrow confirms.
Both the client and ord's sale classifier reconstruct this tree from the seller's key and the pinned co-signer key, so a template whose escrow script does not match is rejected before the wallet is asked to sign.
Verify it yourself
Two constants and one mined purchase are enough to check every claim on this page against the chain.
1d08b7c71f6f1e97a0a4cf005db7a977c85e34652a0c9365842aee25997c7deePinned in the app. A listing or purchase whose escrow uses any other key is refused before signing.50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0The unspendable point from BIP-341. It guarantees there is no key-path spend.