From e95f259f7926ef9e0c2b4ee4a052e1a3e1c48fcc Mon Sep 17 00:00:00 2001 From: GenericCPU Date: Mon, 10 Aug 2026 19:05:27 -0300 Subject: [PATCH 1/3] docs(tokens/0147): define content for derivative remittance interop Shared media outpoint in customInstructions/tags so peer wallets preserve Kit-Kat-style reference tips without dropping display on rebuild. Co-authored-by: Cursor --- tokens/0147.md | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/tokens/0147.md b/tokens/0147.md index 7a25df5a..0174986a 100644 --- a/tokens/0147.md +++ b/tokens/0147.md @@ -54,6 +54,7 @@ Tags are optional BRC-46 / BRC-100 output tags used for filtering and display hi |-----|-------------|---------| | `ordinal` | SHOULD on conforming transfers and imports | Marks the output as an ordinal/inscription tip under this profile. | | `origin:` | SHOULD when origin is known | Claimed inscription origin (`dot` or `underscore` form). | +| `content:` | SHOULD when the tip is a derivative / reference inscription | Shared media outpoint for display (see `content` below). | | `name:` | MAY | Short display name (implementations SHOULD truncate to ≤ 80 UTF-8 code units when writing). | | `app:` | MAY | Creator / application id for filtering (SHOULD truncate to ≤ 40). | | `collection:` / `collectionId:` | MAY | Collection filter keys (synonyms). | @@ -68,6 +69,7 @@ When present for basket `1sat`, `customInstructions` MUST be a **UTF-8 JSON obje ```json { "origin": "", + "content": "", "name": "", "app": "", "provenance": { } @@ -77,15 +79,24 @@ When present for basket `1sat`, `customInstructions` MUST be a **UTF-8 JSON obje | Field | Type | Requirement | Meaning | |-------|------|-------------|---------| | `origin` | string | SHOULD | Claimed origin outpoint (underscore form preferred). | +| `content` | string | SHOULD when known for derivatives | Shared **media** outpoint (underscore form preferred). Used when this tip’s own origin envelope is a reference (e.g. [BRC-160](./0160.md) field 3 parent, or a `text/uri-list` / `ord://` / OrdFS `/content/` body) so receivers can load the one on-chain body without an indexer. | | `name` | string | MAY | Display name. | | `app` | string | MAY | Creator / application id. | | `provenance` | object | SHOULD on transfer when available | Provenance remittance; v2 in [BRC-150](./0150.md). | -Additional JSON keys are permitted and MUST be ignored by readers that do not understand them. Readers that do not understand `provenance` MUST still store and forward the entire string unchanged ([BRC-37](../outpoints/0037.md)). +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](../outpoints/0037.md)). + +#### 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:`) when they can resolve the shared media outpoint from the tip’s origin envelope ([BRC-160](./0160.md) 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](./0150.md) still proves the child origin). Receivers SHOULD prefer `/content/` (or OrdFS equivalent) for media when `content` is present and well-formed; otherwise fall back to `/content/`. #### Claims vs proof -* `origin`, `name`, `app`, and all tags are **claims**. +* `origin`, `content`, `name`, `app`, 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](./0150.md) (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. @@ -173,10 +184,10 @@ Normative fine-grained asset permission schemes remain [BRC-99](../wallet/0099.m ## Security considerations -* **Tag / metadata spoofing** — Without provenance verification, a sender can attach another inscription’s `origin` and `name`. See [BRC-150](./0150.md). +* **Tag / metadata spoofing** — Without provenance verification, a sender can attach another inscription’s `origin` and `name`. See [BRC-150](./0150.md). 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. +* **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 @@ -194,3 +205,5 @@ Normative fine-grained asset permission schemes remain [BRC-99](../wallet/0099.m 7. [BRC-99](../wallet/0099.md) — P Baskets (reserved permission schemes) 8. [BRC-100](../wallet/0100.md) — Unified Open BSV Wallet-to-Application Interface 9. [BRC-150](./0150.md) — 1Sat Provenance Remittance for Basket `1sat` +10. [BRC-160](./0160.md) — 1Sat Ordinals — Inscription Envelopes +11. 1Sat reference inscriptions — From 98765c24331c0cb1fda97ca7d2733f047b865dc6 Mon Sep 17 00:00:00 2001 From: GenericCPU Date: Wed, 12 Aug 2026 21:24:13 -0300 Subject: [PATCH 2/3] docs(tokens/0147): motivate content from indexer-scale reality Pixel Foxes-scale collections already find collection holder queries unusable; forwarding content in remittance is what keeps derivative media peer-to-peer. Co-authored-by: Cursor --- tokens/0147.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tokens/0147.md b/tokens/0147.md index 0174986a..10364538 100644 --- a/tokens/0147.md +++ b/tokens/0147.md @@ -19,6 +19,8 @@ It does **not** redefine 1Sat Ordinals origin theory. Offline tip→origin proof 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 From 81b67be420eb4837d99fd9ed1724b2d188d7a97a Mon Sep 17 00:00:00 2001 From: GenericCPU Date: Wed, 12 Aug 2026 21:31:51 -0300 Subject: [PATCH 3/3] docs(tokens/0147): settle tags/CI and defer id: to BRC-164 Absorb the 1sat-specific clarifications from the draft 147 tags PR (origin forms, type:, tags vs CI, name-in-CI) into this branch so 147 needs no follow-up PR. Wallet-local id: list keys stay in BRC-164. Co-authored-by: Cursor --- tokens/0147.md | 55 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 12 deletions(-) diff --git a/tokens/0147.md b/tokens/0147.md index 10364538..5d3405bd 100644 --- a/tokens/0147.md +++ b/tokens/0147.md @@ -55,14 +55,44 @@ Tags are optional BRC-46 / BRC-100 output tags used for filtering and display hi | Tag | Requirement | Meaning | |-----|-------------|---------| | `ordinal` | SHOULD on conforming transfers and imports | Marks the output as an ordinal/inscription tip under this profile. | -| `origin:` | SHOULD when origin is known | Claimed inscription origin (`dot` or `underscore` form). | +| `origin` or `origin:` | SHOULD when origin is known | Claimed inscription origin. Two forms — see rules below. | | `content:` | SHOULD when the tip is a derivative / reference inscription | Shared media outpoint for display (see `content` below). | -| `name:` | MAY | Short display name (implementations SHOULD truncate to ≤ 80 UTF-8 code units when writing). | -| `app:` | MAY | Creator / application id for filtering (SHOULD truncate to ≤ 40). | +| `type:/` | 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:` | MAY (legacy) | Short display name in a tag. New writers SHOULD put display name in `customInstructions` instead (see [Tags vs customInstructions](#tags-vs-custominstructions)). If written, implementations SHOULD truncate to ≤ 80 UTF-8 code units. | +| `app:` | MAY | Application / creator id for filtering (SHOULD truncate to ≤ 40). | | `collection:` / `collectionId:` | MAY | Collection filter keys (synonyms). | | `creator:` / `author:` | MAY | Creator filter keys (synonyms of / complements to `app:`). | -Unknown tags MUST be preserved when transporting the output ([BRC-37](../outpoints/0037.md) / BRC-46 spirit). Tag query via `listOutputs` uses existing `tags` / `tagQueryMode` fields. +Rules: + +* **Origin tag** — One tag, two forms: + * bare `origin` — this output **is** the origin (mint / chain start). + * `origin:` — this output is a later tip; `` is the chain origin (`dot` or `underscore` form; readers MUST treat both as the same outpoint per [Outpoint encoding](#outpoint-encoding)). + * On self-keep transfer or re-file: if the source has `origin:`, copy that tag unchanged; if the source has bare `origin`, the spent outpoint **is** the origin — write `origin:` on the new output. + * The origin tag is a wallet **claim**, not proof of chain membership ([BRC-150](./0150.md)). +* **`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:` 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](../outpoints/0037.md) / 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](../wallet/0046.md) / [BRC-37](../outpoints/0037.md). 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](./0150.md) | + +**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](../outpoints/0037.md)) @@ -73,7 +103,7 @@ When present for basket `1sat`, `customInstructions` MUST be a **UTF-8 JSON obje "origin": "", "content": "", "name": "", - "app": "", + "app": "", "provenance": { } } ``` @@ -82,11 +112,11 @@ When present for basket `1sat`, `customInstructions` MUST be a **UTF-8 JSON obje |-------|------|-------------|---------| | `origin` | string | SHOULD | Claimed origin outpoint (underscore form preferred). | | `content` | string | SHOULD when known for derivatives | Shared **media** outpoint (underscore form preferred). Used when this tip’s own origin envelope is a reference (e.g. [BRC-160](./0160.md) field 3 parent, or a `text/uri-list` / `ord://` / OrdFS `/content/` body) so receivers can load the one on-chain body without an indexer. | -| `name` | string | MAY | Display name. | -| `app` | string | MAY | Creator / application id. | +| `name` | string | SHOULD when known | Display name (case-preserving). Preferred over a `name:` tag. | +| `app` | string | MAY | Application / creator id (may mirror an `app:` tag for display). | | `provenance` | object | SHOULD on transfer when available | Provenance remittance; v2 in [BRC-150](./0150.md). | -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](../outpoints/0037.md)). +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](../outpoints/0037.md)). 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 @@ -98,7 +128,7 @@ Some tips share one inscription body (many children point at one parent media ou #### Claims vs proof -* `origin`, `content`, `name`, `app`, and all tags are **claims**. +* `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](./0150.md) (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. @@ -137,7 +167,7 @@ Example (non-normative shape): "satoshis": 1, "outputDescription": "Collectable transfer", "basket": "1sat", - "tags": ["ordinal", "origin:", "name:Example"], + "tags": ["ordinal", "origin:", "type:image/png"], "customInstructions": "{\"origin\":\"\",\"name\":\"Example\",\"provenance\":{}}" }] } @@ -159,7 +189,7 @@ To place an existing tip into basket `1sat`, use BRC-100 `internalizeAction` wit "protocol": "basket insertion", "insertionRemittance": { "basket": "1sat", - "tags": ["ordinal", "origin:"], + "tags": ["ordinal", "origin:", "type:image/png"], "customInstructions": "{\"origin\":\"\",\"name\":\"Example\"}" } }] @@ -208,4 +238,5 @@ Normative fine-grained asset permission schemes remain [BRC-99](../wallet/0099.m 8. [BRC-100](../wallet/0100.md) — Unified Open BSV Wallet-to-Application Interface 9. [BRC-150](./0150.md) — 1Sat Provenance Remittance for Basket `1sat` 10. [BRC-160](./0160.md) — 1Sat Ordinals — Inscription Envelopes -11. 1Sat reference inscriptions — +11. BRC-164 — Output Identity Tags for BRC-100 Wallets (`id:` list keys; not defined by this profile) +12. 1Sat reference inscriptions —