BRC-147 Tokens

1Sat Ordinals Basket Profile for BRC-46 / BRC-100

This BRC defines the application basket profile for 1Sat Ordinals under BRC-46 / BRC-100. It reserves the basket name 1sat , specifies eligibility of outputs placed in that basket, documents the tag vocabulary and BRC-37 customInstructions schema used for display and remittance, and describes normative hold / list / transfer / import flows via existing walle

Brandon Cryderman / HandCash (brandongcryderman@gmail.com)

Implementer view

Where this fits

Profiles 1Sat assets for standard output baskets and wallet interaction.

How it connects

Relationships

Found in the source

Implementation links

These links are extracted from the upstream implementation section. Inclusion is not an OpenStandards endorsement.

Authoritative content mirror

Full upstream text

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

Abstract

This BRC defines the application basket profile for 1Sat Ordinals under BRC-46 / BRC-100. It reserves the basket name 1sat, specifies eligibility of outputs placed in that basket, documents the tag vocabulary and BRC-37 customInstructions schema used for display and remittance, and describes normative hold / list / transfer / import flows via existing wallet interface methods.

It does not redefine 1Sat Ordinals origin theory. Offline tip→origin proof is specified in the companion BRC-150.

Motivation

BRC-37 deliberately leaves customInstructions semantics to the named basket. BRC-46 enables token-like tracking in baskets but does not define a 1Sat profile. Without a shared basket name and metadata contract, wallets cannot reliably:

  1. Hold the same inscription UTXOs in a common basket.
  2. List and filter collectables for apps and UI.
  3. Transfer a 1-sat tip while preserving origin claims for the receiver.
  4. Import historical ordinals via internalizeAction with interoperable remittance.

Existing deployments (including HandCash Desktop) already use basket 1sat with overlapping tags and JSON instructions. This BRC records that convention so independent wallets can interoperate without trusting a single vendor.

Derivative / reference tips make that contract incomplete without a named content field. Many children share one on-chain media outpoint (BRC-160 field 3, text/uri-list, ord://, OrdFS). Wallets that rebuild customInstructions from origin / name / provenance alone drop the shared pointer, and the receiver cannot load media peer-to-peer. Indexer fallback is not enough at collection scale: large 1Sat collections (e.g. Pixel Foxes at ~10M items) already find collection-filtered holder queries and related indexer endpoints unusable in practice, while per-origin /content/{origin} remains the workable path. Forwarding content in remittance is what lets a receiver fetch that body without waiting on an indexer to know the child tip.

Specification

Basket identifier

  • The basket name is the UTF-8 string 1sat.
  • Per BRC-46, wallet implementations normalize basket identifiers by trimming whitespace and lowercasing. After normalization, conforming use of this profile MUST use exactly 1sat.
  • This identifier does not use the BRC-99 reserved p prefix. It is a standard application basket under BRC-46 permissioning (grant / deny access to the basket as a whole, unless a future p -scheme supersedes that for assets).

Eligibility

An output SHOULD be placed in basket 1sat only when all of the following hold:

  1. satoshis === 1.
  2. The output is intended as a 1Sat Ordinals tip (a 1-satoshi UTXO in an inscription ownership chain), per 1Sat Ordinals.
  3. The sender or importer reasonably believes the tip belongs to a 1Sat origin (the first 1-sat outpoint carrying a valid first ord envelope on that sat).

Wallets MUST NOT place ordinary payment change or multi-sat outputs into 1sat merely to attach ordinal-looking tags.

Outputs that fail eligibility MAY still appear if a buggy sender used the basket; receivers SHOULD treat such outputs as malformed for this profile and MUST NOT present them as verified inscriptions solely because of basket membership.

Outpoint encoding

  • BRC-100 wire outpoint fields use dot form: txid.vout (see BRC-100 / BRC-36 practice).
  • 1Sat Ordinals / OrdFS commonly use underscore form: txid_vout.
  • Conforming implementations MUST treat txid.vout and txid_vout as the same outpoint when txid is 64 hex chars and vout is a non-negative decimal integer.
  • Inside this profile’s customInstructions object, origin and content MUST use underscore form. Tag values for origin:, content:, and collection: (when the value is an outpoint) MUST use underscore form. Readers MUST normalize before comparison.

Tags

Tags are optional BRC-46 / BRC-100 output tags used for filtering and display hints. They are non-authoritative for asset identity.

Tag Requirement Meaning
ordinal SHOULD on conforming transfers and imports Marks the output as an ordinal/inscription tip under this profile.
origin or origin:<outpoint> SHOULD when origin is known Claimed inscription origin. Two forms — see rules below.
content:<outpoint> SHOULD when the tip is a derivative / reference inscription Shared media outpoint for display (see content below).
type:<type>/<subtype> SHOULD when the content type is known IANA media type of the origin inscription (envelope content-type), with parameters removed — the substring before the first ; (e.g. type:image/png from image/png; charset=binary).
name:<string> MAY (legacy) Short display name in a tag. New writers SHOULD put display name in customInstructions instead (see Tags vs customInstructions). If written, implementations SHOULD truncate to ≤ 80 UTF-8 code units.
app:<string> MAY Application id for filtering (SHOULD truncate to ≤ 40). Distinct from creator:.
collection:<id> MAY Collection id for filtering.
creator:<id> MAY Creator filter key. Distinct from app:.

Rules:

  • Origin tag — One tag, two forms:
    • bare origin — this output is the origin (mint / chain start).
    • origin:<outpoint> — this output is a later tip; <outpoint> is the chain origin in underscore form (writers MUST; readers MUST still accept and normalize either form per Outpoint encoding).
    • On self-keep transfer or re-file: if the source has origin:<outpoint>, copy that tag after normalizing the value to underscore form; if the source has bare origin, the spent outpoint is the origin — write origin:<spent outpoint> in underscore form on the new output.
    • The origin tag is a wallet claim, not proof of chain membership (BRC-150).
  • type: — Describes the origin inscription’s content type, not whatever the current tip’s locking script contains. Self-keep transfers SHOULD copy type:… forward with the origin claim rather than re-deriving it from a bare transfer output. Tag matching is exact; there is no prefix or wildcard form.
  • Wallet-local list keys — Ordinary id:<key> tags (stable per-row handles for listOutputs) are defined by BRC-164, not by this profile. Conforming 1sat writers MAY stamp id: when they adopt that convention. This profile MUST NOT treat id: as origin, media, collection, or global asset identity. Receivers MUST ignore a counterparty-supplied id: and stamp their own if they adopt BRC-164.
  • Unknown tags MUST be preserved when transporting the output (BRC-37 / BRC-46 spirit). Tag query via listOutputs uses existing tags / tagQueryMode fields.

Tags vs customInstructions

Both tags and customInstructions travel with the output under BRC-46 / BRC-37. They serve different jobs:

Tags customInstructions
Role Query and filter keys (listOutputs + tags / tagQueryMode) Single remittance object: display, optional spend metadata, provenance
Case Wallet storage commonly lowercases tags JSON string values can preserve case
Authority Non-authoritative claims / local metadata Same for display fields; spend fields only describe how this wallet unlocks the lock; provenance is verified per BRC-150

Writers SHOULD:

  • Put filterable facts in tags: ordinal, origin / origin:…, type:…, content:… when useful, and when useful app:, collection:…, creator:… (plus id:… only per BRC-164).
  • Put the human display name in customInstructions.name when known (case-preserving).
  • Put shared media outpoints in customInstructions.content (and MAY mirror with tag content:…) for derivative / reference tips.

Writers SHOULD NOT rely on a name: tag as the primary display name. A name: tag remains MAY so existing deployments stay conforming; new implementations SHOULD prefer CI name and MAY omit the tag.

Readers resolving a display name SHOULD prefer customInstructions.name when present, and MAY fall back to a name: tag.

Custom instructions (BRC-37)

When present for basket 1sat, customInstructions MUST be a UTF-8 JSON object serialized as a string (matching BRC-37 examples). Conforming writers SHOULD emit:

{
  "origin": "<txid_vout>",
  "content": "<optional shared media txid_vout>",
  "name": "<display name>",
  "app": "<optional application id>",
  "provenance": { }
}
Field Type Requirement Meaning
origin string SHOULD Claimed origin outpoint (MUST underscore form when written).
content string SHOULD when known for derivatives Shared media outpoint (MUST underscore form when written). Used when this tip’s own origin envelope is a reference (e.g. BRC-160 field 3 parent, or a text/uri-list / ord:// / OrdFS /content/<outpoint> body) so receivers can load the one on-chain body without an indexer.
name string SHOULD when known Display name (case-preserving). Preferred over a name: tag.
app string MAY Application id (may mirror an app: tag for display). Distinct from tag creator:.
provenance object SHOULD on transfer when available Provenance remittance; v2 in BRC-150.

Additional JSON keys are permitted and MUST be ignored by readers that do not understand them. Readers that do not understand provenance or content MUST still store and forward the entire string unchanged (BRC-37). Spend-derivation fields a wallet uses only for its own unlock (protocolID, keyID, counterparty, …) MAY appear in the same object; they are not part of this profile’s display / provenance contract and MUST NOT be required of receivers.

Derivative / reference content

Some tips share one inscription body (many children point at one parent media outpoint). For interop:

  1. Senders SHOULD set content (and MAY set tag content:<outpoint>) when they can resolve the shared media outpoint from the tip’s origin envelope (BRC-160 field 3, or a reference body as above), or when a prior remittance already carried content.
  2. On transfer, senders that rebuild customInstructions MUST preserve an existing content value when they do not replace it with a freshly resolved one.
  3. content is a display claim. It does not change tip→origin authenticity (BRC-150 still proves the child origin). Receivers SHOULD prefer /content/<content> (or OrdFS equivalent) for media when content is present and well-formed; otherwise fall back to /content/<origin>.

Claims vs proof

  • origin, content, name, app, type:, and all tags are claims.
  • A wallet MUST NOT treat a claimed origin as proven solely because it appears in tags or customInstructions.
  • Proven tip→origin binding is defined by BRC-150 (v2). When remittance is absent or fails verification, the wallet MUST treat identity as unproven and SHOULD avoid presenting sender-supplied name / app as authoritative for that tip.

Hold and list

Applications list held tips with BRC-100 listOutputs:

{
  "basket": "1sat",
  "includeTags": true,
  "includeCustomInstructions": true
}

Optional tags / tagQueryMode filters apply as in BRC-46. Wallets MAY require basket permission per BRC-46 / BRC-100 before returning outputs.

Transfer (send)

A conforming transfer of a held 1sat tip SHOULD use BRC-100 createAction with:

  1. An input spending the current tip outpoint (satoshis === 1).
  2. An output with satoshis: 1, basket: "1sat", tags per this profile, and customInstructions as above.
  3. Prefer supplying inputBEEF / AtomicBEEF for the spent tip when available (BRC-62, BRC-95) so the new owner can validate the spend graph.
  4. Action labels MAY include 1sat for activity filtering; labels are non-normative for asset identity.

Example (non-normative shape):

{
  "description": "Send Collectable",
  "labels": ["1sat"],
  "inputs": [{ "outpoint": "<tip txid.vout>", "inputDescription": "1sat collectable" }],
  "outputs": [{
    "lockingScript": "<recipient P2PKH or other 1-sat lock>",
    "satoshis": 1,
    "outputDescription": "Collectable transfer",
    "basket": "1sat",
    "tags": ["ordinal", "origin:<txid_vout>", "type:image/png"],
    "customInstructions": "{\"origin\":\"<txid_vout>\",\"name\":\"Example\",\"provenance\":{}}"
  }]
}

Senders SHOULD attach BRC-150 provenance remittance when they can build a valid package. Senders that cannot prove origin MUST NOT present the transfer as a verified inscription transfer; they MAY still move the 1-sat UTXO, but receivers will treat identity as unproven.

Import / receive (internalizeAction)

To place an existing tip into basket 1sat, use BRC-100 internalizeAction with protocol basket insertion (BRC-46):

{
  "tx": "<AtomicBEEF bytes for the tip transaction>",
  "description": "Import 1Sat ordinal",
  "labels": ["1sat"],
  "outputs": [{
    "outputIndex": 0,
    "protocol": "basket insertion",
    "insertionRemittance": {
      "basket": "1sat",
      "tags": ["ordinal", "origin:<txid_vout>", "type:image/png"],
      "customInstructions": "{\"origin\":\"<txid_vout>\",\"name\":\"Example\"}"
    }
  }]
}

insertionRemittance.customInstructions follows the same schema as transfer. Provenance MAY be omitted on import when the importer verifies origin by other means before insertion; once transferred onward, senders SHOULD attach provenance for the new tip.

Payment separation (wallet policy guidance)

Spending or revealing 1sat basket outputs is not a BRC-29 / default-basket payment. Conforming wallets SHOULD:

  • Require distinct user authorization (or a dedicated item/basket grant) before createAction / relinquishOutput that spends 1sat outputs.
  • Not treat a general “pay” or auto-pay grant as authorization to spend 1sat tips.
  • Not fund ordinary payment outputs from 1sat basket UTXOs.

Normative module-mediated view and spend for basket 1sat are defined in BRC-165 and are out of scope for this profile.

Compatibility

  • Wallets that do not implement this profile MUST still store and forward unknown baskets’ customInstructions and tags unchanged (BRC-37).
  • This profile does not conflict with BRC-99 p baskets. BRC-165 defines scheme 1sat view/spend routing without changing this profile’s storage basket name.
  • Marketplaces (e.g. OrdLock), BSV-20/21, and mint APIs are out of scope.

Security considerations

  • Tag / metadata spoofing — Without provenance verification, a sender can attach another inscription’s origin and name. See BRC-150. A forged content only mis-points display media; it does not prove tip→origin.
  • Basket pollution — Placing non-1-sat or non-ordinal outputs in 1sat confuses list UIs; receivers should re-check satoshis and inscription rules.
  • Burn — Per 1Sat Ordinals, packing a sat into a multi-sat output ends that origin trail. Do not continue origin: claims across a burn.
  • Indexer trust — Display media URLs and collection metadata often come from indexers; this profile does not make indexers authoritative for tip→origin binding. Forwarding content reduces indexer dependence for derivative media.

Implementations

  • HandCash Desktop (reference): basket 1sat list / send / import; tags and customInstructions as above; payment grants never cover item spends.
    Source: src/wallet/collectables.ts, src/wallet/oneSatImport.ts, src/wallet/itemAccess.ts in HandCash/HANDCASH-DESKTOP.

References

  1. 1Sat Ordinals — https://docs.1satordinals.com
  2. BRC-37 — Basket and Custom Instructions Extension for Bitcoin Outpoints
  3. BRC-45 — Outputs are Tokens
  4. BRC-46 — Wallet Transaction Output Tracking (Output Baskets)
  5. BRC-62 — BEEF Transactions
  6. BRC-95 — Atomic BEEF Transactions
  7. BRC-99 — P Baskets (reserved permission schemes)
  8. BRC-100 — Unified Open BSV Wallet-to-Application Interface
  9. BRC-150 — 1Sat Provenance Remittance for Basket 1sat
  10. BRC-160 — 1Sat Ordinals — Inscription Envelopes
  11. BRC-164 — Output Identity Tags for BRC-100 Wallets (id: list keys; not defined by this profile)
  12. BRC-165 — P1Sat Permission Scheme for Basket 1sat
  13. 1Sat reference inscriptions — https://docs.1satordinals.com/reference-inscriptions