BRC-254 Tokens

Market Offers and Direct Swaps for Wallet Assets

This document specifies how a wallet sells an asset it holds, on a public market or to one counterparty. The seller need not be online at the sale, and no index holds keys. There is one offer mechanism. The seller signs the input that spends the asset with SIGHASH_SINGLE ANYONECANPAY FORKID ( 0xC3 ). That signature commits to the output at the same index, wh

Brandon Cryderman / HandCash (brandongcryderman@gmail.com) Status: Open

How it connects

Relationships

Authoritative content mirror

Full upstream text

View source ↗
Rendered from tokens/0254.md at the indexed upstream commit

Abstract

This document specifies how a wallet sells an asset it holds, on a public market or to one counterparty. The seller need not be online at the sale, and no index holds keys.

There is one offer mechanism. The seller signs the input that spends the asset with SIGHASH_SINGLE | ANYONECANPAY | FORKID (0xC3). That signature commits to the output at the same index, which pays the seller. Anyone can complete the transaction, but only by paying that output exactly. Nobody can take the asset for less, and the seller does not need to be present.

The offer can be published in two ways:

  • market: a BRC-48 offer token on an overlay, with a market fee whose output the token's own signature binds;
  • direct: the same signed input handed to one buyer as JSON, with no index, no fee, and a price in satoshis or in another asset.

The mechanism covers five asset filings:

Filing Asset Defined by Class
1sat a 1Sat ordinal item BRC-147, authenticity BRC-150 Not a token; outside BRC-251
bntft Bitcoin Native Token units Draft BRC-255 (#335) BNT
bntnft a Bitcoin Native Token item Draft BRC-255 (#335) BNT
iptft Issuer-Permissioned Token units Draft BRC-253 (#333) IPT
iptnft an Issuer-Permissioned Token item Draft BRC-253 (#333) IPT

The two token classes are those of draft BRC-251 (#320). A BNT sale needs nobody but the seller and the buyer. The buyer checks the lot back to its deploy, and no index or issuer takes part. An IPT sale also needs the asset's acceptor to countersign it (§6) until the asset is released. A market MUST NOT label an IPT offer as a BNT, and SHOULD label each offer with its class.

Every key a party signs with is a BRC-42 child it reaches through BRC-100 getPublicKey / createSignature. A token lot and a bought token sit on holder keys of their format. The seller payout, a 1sat lot, pads, plain buyer outputs and the offer token sit on BRC-29 children. The offer, intent and receipt signatures use BRC-43 protocol keys. A BRC-100 wallet never signs with its identity key, so nothing here locks to an identity address or is signed by an identity key.

Motivation

Wallet assets are traded today through ad hoc listing formats. Each has its own rules for what the seller signed, what the buyer must pay and how an index decides that a listing is still live. Two weaknesses are common:

  • Unbound signatures. A seller signs the asset input with SIGHASH_NONE | ANYONECANPAY, so anyone who holds the listing can take the asset and pay nothing.
  • Index trust. The buyer relies on an index to say that the asset is genuine, the price is right and the fee goes where the seller agreed.

BRC-197 defines one covenant family for accumulating right-of-sale listings. It is a different model: a reusable listing UTXO with a purchase increment. BRC-207 auctions need processors to coordinate, and no processor does. Neither covers a plain fixed-price sale of an item or a token lot, or a swap of one asset for another.

This document makes four guarantees:

  1. The seller's signature can only be used in a transaction that pays the seller what the seller asked.
  2. The fee output is bound by a signature in the seller's offer token, so a buyer cannot skip the fee and an index cannot raise it.
  3. The buyer checks everything, including the asset's authenticity, from the transaction and a listing proof, before paying. The index only helps buyers find offers.
  4. A seller cancels by spending what it listed.

Relationship to other documents

Concern Document
Offer token encoding BRC-48 Pay to Push Drop
Overlay submission and lookup BRC-22, BRC-24, names per BRC-87
Transaction packages BRC-95 Atomic BEEF, BRC-62 BEEF
Item authenticity proof BRC-150 v2
The BNT and IPT classes Draft BRC-251 (#320)
BNT outputs, holder keys, proof package and validity Draft BRC-255 (#335) §1, §6 to §8; short proofs, draft BRC-252 (#321)
IPT outputs, acceptance, sender-funded trades, release Draft BRC-253 (#333) §2, §5, §6, §9
Optional delivery to the counterparty BRC-33, BRC-78
Wallet permissions BRC-100, BRC-99
Keys BRC-42, BRC-43, BRC-29

Specification

The key words MUST, MUST NOT, SHOULD and MAY are used as in RFC 2119. Outpoints are written txid_vout, with a lowercase hex txid. Every integer in this document is unsigned.

1. The seller signature

The seller's offer is an unlocking script for the input that spends the listed asset. That unlocking script carries a signature with sighash byte 0xC3 (SINGLE | ANYONECANPAY | FORKID). The signature commits to:

  • the listed input itself;
  • the output at the same index as that input (the bound output).

It commits to no other input or output. A buyer adds its own inputs, the buyer output and change, then broadcasts. A BRC-100 wallet makes such a signature with createSignature, hashToDirectlySign set to the double SHA-256 of the input's sighash preimage (BIP-143 with FORKID) under that sighash type, for the key's protocol, key ID and counterparty, and passes the unlocking script to signAction. No key leaves the wallet.

Rules:

  1. A seller MUST sign the listed input with 0xC3. A wallet MUST refuse to complete an offer whose listed-input signature uses any other sighash byte. The sighash byte 0x82 / 0xC2 (NONE | ANYONECANPAY) lets anyone take the asset.
  2. The bound output MUST pay the seller the full price. A wallet MUST check the bound output against the advertised price before signing anything of its own.
  3. The listed output MUST hold exactly what is offered. A wallet that holds more units than it lists first splits them in the listing transaction (§2), so the signature never covers a remainder.

The signature fixes the bound output's position, so input order matters. §5 fixes it for each filing.

2. Listing transaction

A market listing is a transaction the seller broadcasts:

Output Content
0 The listed asset, held by the seller, carrying exactly the listed units, 1 satoshi
1 The offer token (§3), 1 satoshi (the deposit)
2… Change: token change, satoshi change

Input 0 MUST spend the asset being listed, a 1-satoshi output. Other inputs fund the transaction or add units.

Seller keys. For each listing the seller draws one fresh BRC-29 derivation prefix and two suffixes, and derives two self children (BRC-29 protocol [2, "3241645161d8"], key ID "<prefix> <suffix>", counterparty its own identity key):

  • the listing key, which holds a 1sat lot (output 0) and locks the offer token (field 19);
  • the payout key, whose address receives the seller payment (field 4).

The seller keeps both remittances with the listed output, so it needs nothing else to cancel or collect. The two keys MUST differ from each other and from the identity key.

How output 0 is held depends on the filing:

  • 1sat: a P2PKH lock to the address of the listing key (field 19). The item's satoshi stays the first satoshi of output 0.
  • bntft / bntnft: a BRC-255 held output of the listed units under a fresh bnt holder key of the seller's own (BRC-255 §8). Units the seller holds beyond the lot go to a held output at index 2 or later. The listing transaction is an ordinary BRC-255 transfer to self.
  • iptft / iptnft: a BRC-253 countersigned output of the listed units under a fresh ipt holder key of the seller's own (BRC-253 §2). The listing transaction is a BRC-253 transfer to self, so the acceptor countersigns it like any other transfer.

A seller that lists an asset it already holds at the right lock and amount MAY skip the listing transaction for direct offers (§10). A market listing always has one, because the offer token must sit in output 1 of the same transaction as the asset.

3. Offer token

The offer token is a BRC-48 PushDrop output locked to the listing key: <listingKey> OP_CHECKSIG <fields…> <signature> OP_2DROP×10 OP_DROP. It holds 21 pushed fields:

# Field Encoding
0 magic UTF-8 1SAT-MARKET
1 version 1 byte, 2
2 item vout 4 bytes big-endian, 0
3 seller identity key 33-byte compressed public key
4 seller payout address UTF-8 mainnet P2PKH address of the payout key (§2)
5 seller payout commitment SHA-256 of the P2PKH locking script of field 4
6 gross price 8 bytes big-endian, satoshis, at least 20
7 fee identity key 33-byte compressed public key
8 fee payout address UTF-8 mainnet P2PKH address
9 fee payout commitment SHA-256 of the P2PKH locking script of field 8
10 fee basis points 2 bytes big-endian, 0 to 10000
11 exact fee 8 bytes big-endian, floor(price × bps / 10000)
12 proof hash 32 bytes, SHA-256 of the listing proof (§4)
13 proof size 4 bytes big-endian, bytes of the listing proof
14 proof version 1 byte, 2
15 expires at 8 bytes big-endian, Unix milliseconds, 0 for none
16 nonce 16 random bytes
17 deposit 8 bytes big-endian, 1
18 messagebox UTF-8 HTTPS URL of the seller's BRC-33 box, or empty
19 listing key 33-byte compressed public key (§2)
20 signature DER ECDSA over the concatenation of fields 0–19, by the seller's offer signing key (rule 3)

Rules:

  1. Every push MUST be minimal. A field of one byte from 1 to 16 is OP_1…OP_16, 0x81 is OP_1NEGATE, and an empty field is OP_0. Otherwise the offer token cannot be spent under the MINIMALDATA policy, and a seller could never cancel it.
  2. Field 4 MUST NOT be the address of field 3, and field 19 MUST NOT equal field 3. Field 8 is the operator's choice of payout address and need not be field 7's address. Fields 5 and 9 MUST match their addresses.
  3. The offer signing key is the BRC-42 child of field 3 for protocol [2, "1sat market offer"], key ID 1, counterparty anyone: what BRC-100 createSignature uses for those arguments. Anyone derives its public key from field 3 alone. The PushDrop lock key MUST equal field 19, and field 20 MUST verify under the offer signing key. A reader that finds either mismatch MUST treat the output as not an offer.
  4. The fee terms (fields 7–11) are the market operator's. An index MAY refuse offers whose terms differ from its own (§8). A buyer MUST pay the terms in the token, never terms the index reports.

Version 1. Offers written before version 2 carry 20 fields: no listing key, field 4 the address of field 3, the token locked to field 3, and field 19 a signature by the identity key itself. A reader MAY still settle and index version 1 offers already on chain, holding output 0 to field 3's address (§2, §8). A wallet MUST NOT write one. A BRC-100 wallet cannot sign as its identity key, so it could neither cancel such an offer nor collect its payout.

4. Listing proof

The listing proof is a JSON value. Its canonical form sorts keys, carries no undefined and uses minimal number formatting. Field 12 is the SHA-256 of that canonical form, and field 13 is its length in bytes. The listing proof travels beside the transaction (§8) or is fetched by hash. The buyer MUST recompute both fields before trusting the proof.

Filing Proof
1sat The complete BRC-150 v2 provenance of the item, from origin to the spent tip. An incomplete proof MUST NOT be published, and a wallet MUST NOT truncate one to fit.
bntft / bntnft { "v": 255, "assetId", "kind": "token" | "item", "amt", "package" }, where package is the BRC-255 §6 proof package whose subject is the listing transaction.
iptft / iptnft { "v": 253, "assetId", "kind": "token" | "item", "amt" }.

amt is "1" for an item. For every token filing the proof is valid when output 0 is an output of assetId carrying amt units with 1 satoshi, kind matches the deploy, and output 1 is the offer token. A buyer validates a BNT lot under BRC-255 §7 from the package, asking the seller for what it lacks as BRC-252 allows. An IPT listing transaction is itself an accepted transfer, so a buyer resolves output 0 under BRC-253 §11 from the listing transaction and the deploy alone.

5. Settlement layouts

A settlement spends output 0 and output 1 of the listing transaction. There are two layouts. In both, the listed input is signed over the seller payment and the offer input over the market fee.

token-v2 applies to bntft, bntnft, iptft and iptnft. The asset travels in its script, so the buyer output can sit anywhere:

Index Input Output
0 listed asset (0xC3) seller payment
1 offer token (0xC3) market fee
2… buyer funding buyer asset output, then change from 3

ordinal-v2 applies to 1sat. An ordinal follows its satoshi, so two buyer pad inputs come first. Output 0 returns exactly their satoshis, which puts the item's satoshi in output 1:

Index Input Output
0 buyer pad pad return, exactly the satoshis of inputs 0 and 1
1 buyer pad buyer item output, 1 satoshi
2 listed item (0xC3) seller payment
3 offer token (0xC3) market fee
4… buyer funding change

The amounts are:

  • Market fee: floor(price × bps / 10000), field 11.
  • Seller payment: price − fee + deposit. The 1-satoshi deposit of the offer token goes back to the seller.
  • Buyer pays: the gross price plus the network fee. The market fee is included in the price.

The seller signs both inputs when it lists, without waiting for a buyer. The unlocks travel as:

{
  "version": 2,
  "layout": "token-v2",
  "itemUnlockingScript": "<hex>",
  "offerUnlockingScript": "<hex>",
  "itemSighash": "SINGLE|ANYONECANPAY",
  "offerSighash": "SINGLE|ANYONECANPAY",
  "sellerSats": 9501,
  "feeSats": 500
}

Rules:

  1. Both unlocking scripts MUST end in a 0xC3 sighash byte, and layout MUST be the layout of the asset's filing. Anything else MUST be refused, because version 1 unlocks signed the item NONE | ANYONECANPAY.
  2. The offer input's unlock is a signature only, because the PushDrop lock is <key> OP_CHECKSIG.
  3. A 1sat buyer MUST use two pads it controls, each a P2PKH output on a BRC-29 child of its own, and MUST keep them out of ordinary funding so the pads never carry an item.
  4. A wallet MUST NOT publish an offer whose unlocks it could not build. A listing without unlocks would need the seller online, and this document does not define that path.

6. Settling each filing

1sat, bntft and bntnft. The buyer completes the transaction alone:

  1. Verify the offer token (§3) and the listing proof (§4).
  2. Rebuild the bound outputs from the token's fields and check that the unlocks verify against them.
  3. Add pads (for 1sat), funding, the buyer output and change.
  4. Sign its own inputs and broadcast.

For 1sat the buyer output is a P2PKH lock on a fresh BRC-29 self child of the buyer. For a BNT it is a held output of exactly the listed units under a fresh bnt holder key of the buyer's own. The buyer keeps the remittance with the output, and files the BNT output once the settlement validates under BRC-255 §7.

iptft and iptnft. The seller's 0xC3 signature is the holder half of the listed input, a market listing as BRC-253 §6 defines it. The buyer completes the transaction, then asks the asset's acceptor to countersign it as a sender-funded trade (BRC-253 §6):

  1. The buyer output is held under a fresh ipt holder key of the buyer's. The request lists it with the buyer's BRC-69 linkage, sealed to each acceptor it is sent to (BRC-253 §5).
  2. The request carries "funding": "sender". The acceptor adds no input and replies cosigned with its countersignature per asset input, so the transaction stays exactly as the seller's and buyer's signatures fixed it.
  3. The acceptor applies its policy to the seller as sender and the buyer as recipient. A refusal is final for that request, and nothing has been broadcast.
  4. Sales never block each other, because a sale and any other request that share a plain input cannot both be mined. A buyer that goes silent cannot freeze a listing.
  5. The buyer credits the lot once the settlement is mined (BRC-253 §11).

After a BRC-253 release the buyer completes the release branch of the listed input itself (BRC-253 §9), and no acceptor takes part.

7. Cancel

The seller cancels by spending output 0 and output 1 together, with output 0 of the cancel returning the asset to the seller, 1 satoshi, and signing the offer input SIGHASH_ALL | FORKID (0x41):

  • 1sat: output 0 is a P2PKH lock to a fresh BRC-29 self child of the seller;
  • bntft / bntnft: output 0 is a held output of the same asset and units under a fresh bnt holder key of the seller's;
  • iptft / iptnft: output 0 is a countersigned output of the same asset and units under a fresh ipt holder key of the seller's, countersigned like any transfer.

Only the listing key can sign the offer input, and an 0x41 signature commits to every output. It therefore proves the seller built the cancel, wherever output 0 goes. A cancel returning output 0 to the payout address (field 4) is recognised without it.

Spending the listed output is the only way to stop sales. If the seller spends the offer token alone, the offer is withdrawn from the index, but the list-time signature on output 0 still lets anyone buy it by paying the seller payment output (without the market fee). A wallet that means "stop selling" MUST spend output 0.

8. Overlay

A market index is a BRC-22 topic manager named tm_1sat_market, with a BRC-24 lookup service named ls_1sat_market.

Submission. A submission is BEEF framed as VarInt(BEEF length) || BEEF || canonical JSON, with the header x-includes-off-chain-values: true. The JSON is the context:

Event Context
listing { "assetType": "ordinal" | "bntft" | "bntnft" | "iptft" | "iptnft", "amt"?, "provenance": <listing proof>, "settlementUnlocks": <§5> }
settlement { "buyerIdentityKey", "buyerAddress"? }: buyerAddress is the address a 1sat buyer output pays, a BRC-29 child of the buyer; without it the index assumes the identity key's address (version 1 buyers). A token buyer output is read from the settlement

Admitting a listing. A topic manager admits outputs 0 and 1 of a listing only when all of these hold:

  • input 0 spends a 1-satoshi asset output, and output 0 is held as §2 requires: for 1sat, by the address of the offer's lock key (field 19, or field 3 for version 1); for a token, as an output of the same asset as input 0 under the same clause apart from its holder key;
  • the offer token parses and verifies (§3), and its fee terms are the ones this index accepts;
  • the listing proof matches fields 12–14, and verifies for its filing (§4);
  • assetType agrees with output 0: its marker is bnt exactly when assetType is bntft or bntnft, and ipt exactly when it is iptft or iptnft, and its kind matches;
  • for a token, the listed units match the proof and amt, and the transaction conserves the asset (BRC-255 §4);
  • the settlement unlocks, when present, are the bound v2 form for the filing, and the listed input's unlock verifies against output 0;
  • the scripts verify and the outputs do not exceed the inputs.

Lifecycle. A transaction that spends an admitted offer is classified, and the offer is then removed:

  • settled: both inputs are spent at the indexes of one v2 layout, before the expiry. The buyer output, the seller payment and the market fee are exact, and for 1sat the pads return exactly.
  • cancelled: both inputs are spent at 0 and 1 and the offer input is signed 0x41, or output 0 returns the asset to the payout address (§7); or the offer token alone is spent.
  • item moved: output 0 is spent without the offer token.

Lookup modes are active, exact, seller, origin (an origin outpoint or a proof hash), collection, collectionName and history. Results are output-list rows carrying the BEEF, the output index and the context.

The index holds no keys, moves no asset, and never decides whether an asset is valid. A buyer MUST verify each offer itself (§6). A dishonest index can hide an offer, or show one that is already spent, which wastes a buyer's attempt. It cannot make a buyer pay for something it does not receive.

9. Purchase intent and settlement receipt

An index MAY keep sale bookkeeping. The two records below are statements the index cannot forge, and neither one gates a settlement.

Neither record gates the seller's funds either. The payout key is the seller's own child (§2), so a seller never needs a buyer message to collect. It reads the payout address of each listing it holds and files any output there under the payout remittance. A buyer that settles and sends nothing has still paid. The seller keeps that remittance on the offer output, so an install restored from backup still finds its sales.

  • Purchase intent: signed by the buyer before it builds the settlement. Its preimage is these lines joined by \n: HandCash-Market-Purchase-Intent-v1, intentId, outpoint, buyer, seller, priceSats, feeSats, totalSats, proofHash, createdAt, expiresAt (empty for none), nonce.
  • Settlement receipt: signed by the seller after it sees the settlement. Its preimage is these lines joined by \n: HandCash-Market-Settlement-Receipt-v1, receiptId, intentId, outpoint, buyer, seller, settlementTxid, sellerOutputIndex, feeOutputIndex, settledAt, then buyerAddress when the receipt carries one. buyerAddress is the address the buyer output pays (§6), read from the settlement. An index checks that output against it, and against the buyer identity key's address only when it is absent.

Each signature is ECDSA over the SHA-256 of the UTF-8 preimage, encoded as 64 bytes r || s in hex, by the signer's BRC-42 child for protocol [2, "1sat market record"], key ID 1, counterparty anyone (BRC-100 createSignature with those arguments). A verifier derives that key from the signer's identity key. It MAY also accept a signature by the identity key itself, which records written before this rule carry. A receipt's output indexes MUST be the seller and fee indexes of one v2 layout.

10. Direct offers

A direct offer is the same signed input given to one buyer, with no offer token and no fee:

{
  "protocol": "handcash-direct-offer",
  "v": 1,
  "offerId": "<txid>.<vout>",
  "seller": "<identity key>",
  "payTo": "<address of a BRC-29 child of the seller>",
  "give": { "filing", "assetId"?, "amount", "dec"?, "sym"?, "icon"?, "lockingScript" },
  "want": { "kind": "sats", "sats" } | { "kind": "asset", "filing", "assetId", "amount", "lockingScript", "sym"?, "dec"? },
  "sellerUnlockingScript": "<hex, 0xC3>",
  "proof": <the §4 listing proof of the lot>,
  "beefB64": "<optional BRC-95 Atomic BEEF of the lot>",
  "createdAt": 0
}

offerId is the listed lot. give.filing is one of the five filings, and assetId is absent only for 1sat. Every field the seller signed is fixed. Changing one breaks the signature. The layouts are:

Layout Inputs Outputs
direct-token (bntft, bntnft, iptft, iptnft) 0 lot (0xC3), then buyer inputs 0 price to the seller, 1 buyer asset output, then change
direct-ordinal (1sat) 0, 1 buyer pads, 2 item (0xC3), then buyer inputs 0 pad return, 1 buyer item output, 2 price to the seller, then change

The want is paid in one of two ways:

  • sats: output 0 (or 2) is a P2PKH payment of sats to payTo.
  • asset: the bound output is want.lockingScript: an output of amount units of assetId under a fresh holder key of the seller's own, of the format of want.filing. The seller wrote it and keeps its remittance. A buyer MUST check that it is such an output before paying it.

Rules:

  1. An offer MUST exchange two different assets.
  2. An IPT lot (give.filing is iptft / iptnft) settles as in §6: the buyer asks the lot's acceptor to countersign a sender-funded request. A BNT lot needs no one.
  3. An IPT want needs the seller's receive output proven to the acceptor of the wanted asset before the buyer pays it. The offer then carries wantLinkage: the seller's BRC-69 linkage for the bound output's holder key, sealed to each acceptor of the wanted asset (BRC-253 §5). The buyer forwards it in its request. A wallet MUST refuse an IPT want without wantLinkage.
  4. When both sides are IPT under different acceptors, the request is sender-funded and goes to both. Each acceptor countersigns its own asset inputs over the same final transaction, and either one's refusal ends it.
  5. An asset that is neither 1sat, BNT nor IPT MUST NOT be offered under this document.
  6. The seller collects by filing output 0 (or 2) from the purchase txid. Delivery of that txid over a message box is optional and never gates the purchase. The seller cancels by spending the lot.

11. Permissions

Listing, buying, cancelling, creating a direct offer, buying one and collecting proceeds each spend or lock wallet value. A BRC-100 wallet MUST ask the user to approve each call, showing the asset, the units, the price and the counterparty or index. A satoshi payment grant, an auto-pay limit or a generic basket grant MUST NOT approve it.

Reading what a wallet holds for a storefront uses the BRC-99 view grants of each filing: p bntft … and p bntnft … (BRC-255 §10), p iptft … and p iptnft … (BRC-253 §13), and p 1sat … under BRC-165. A view grant never lets an application list or sell: every listing, purchase and cancel is a wallet action the user approves.

Security considerations

  • Unbound signatures. A NONE | ANYONECANPAY signature on the listed input gives the asset to anyone who holds the offer. Rule 1 of §1 is the defence, and an index and a buyer MUST both enforce it.
  • Fee bypass. The fee output is bound only by the offer token's signature. A buyer that leaves out the offer input can pay the seller and skip the fee. The index does not see that settlement as a sale. It classifies it as item moved. The seller is still paid in full.
  • Stale offers. An offer stays valid until output 0 is spent. A seller that wants to stop sales MUST spend it (§7). The expiry in field 15 is enforced by the index and by buyers, not by Script.
  • Ordinal loss. A 1sat settlement that does not return the pads exactly moves the item's satoshi into the wrong output. A wallet MUST build and check the pad return before signing.
  • Proof size. A 1sat proof can be large. A seller MUST NOT shorten one to fit an index's budget. A proof that does not fit is not published, and the item stays unlisted.
  • IPT sales. The acceptor sees the sale before it exists and can refuse it. That is the purpose of the class. A refusal costs the buyer nothing, because nothing was broadcast.
  • BNT lots. The buyer validates the lot to its deploy before paying (§4). An index cannot pass off an invalid lot, because the buyer never takes the index's word for validity.
  • Index trust. The index decides what buyers see, but not what they pay. A buyer that skips §6 trusts the index for the asset's identity, which this document forbids.
  • Identity-key custody. An output on an identity address, or a signature that must come from the identity key, can only be produced by a wallet that exposes its root key. Version 1 offers did both. Version 2 keeps every seller and buyer key a BRC-42 child, so the offer is portable across BRC-100 wallets. A seller that loses the remittance of its listing or payout key can no longer cancel or collect. The remittance is custody.
  • Derived outputs and scans. A BRC-29 child is not found by scanning the identity address. A wallet MUST NOT treat a listed lot, payout, pad or bought output as gone because an address scan does not show it.

Implementations

HandCash Desktop (unreleased) and the HandCash market (handcash-market, with the BRC-CLOUD index) implement 1sat market listings, purchases and cancels with the ordinal-v2 layout, the version 2 offer token on BRC-29 seller keys, BRC-29 buyer outputs and pads, BRC-150 listing proofs, overlay admission and the lifecycle (version 1 offers still read), and intents and receipts signed under 1sat market record (identity-key records still verify).

The token filings of this revision (bntft, bntnft, iptft, iptnft) and direct offers are specified but not yet implemented. The market still lists tokens under the retired encodings and is moving them to these filings. The desktop has removed its listing support for those encodings.

References

  1. BRC-48 — Pay to Push Drop
  2. BRC-22 — Overlay Network Data Synchronization
  3. BRC-24 — Overlay Network Lookup Services
  4. BRC-87 — Naming Conventions for Topic Managers and Lookup Services
  5. BRC-62 — Background Evaluation Extended Format (BEEF)
  6. BRC-95 — Atomic BEEF Transactions
  7. BRC-147 — 1Sat Ordinals Basket Profile
  8. BRC-150 — 1Sat Provenance Remittance
  9. Draft BRC-251 (#320) — Bitcoin Native Tokens (BNT): Definition and Wallet Duties
  10. Draft BRC-252 (#321) — Short Proofs for Bitcoin Native Tokens
  11. Draft BRC-253 (#333) — Issuer-Permissioned Tokens (IPT): Countersigned Tokens and Items
  12. Draft BRC-255 (#335) — Bitcoin Native Tokens (BNT): Compact Format
  13. BRC-69 — Revealing Key Linkages
  14. BRC-33 — PeerServ Message Relay Interface
  15. BRC-78 — Portable Encrypted Messages
  16. BRC-99 — P Baskets
  17. BRC-100 — Wallet Interface
  18. BRC-165 — P1Sat Permission Scheme
  19. BRC-197 — Accumulating Right-of-Sale Listings and Purchase Orders
  20. BRC-207 — 1Color Wallet Module
  21. BRC-42 — BSV Key Derivation Scheme
  22. BRC-43 — Security Levels, Protocol IDs, Key IDs and Counterparties
  23. BRC-29 — Simple Authenticated BSV P2PKH Payment Protocol