Consensus-Unique Name Tokens — Identity Binding and Verified Resolution
Anyone can type a name into a wallet, but nothing on Bitcoin normally stops two people from each claiming the same name, and even if a name is claimed, a payment app has no safe way to know which key it really belongs to without trusting some company or registrar in the middle. This makes it impossible to send money to a plain name like "archie" and know it will reach the right person without a domain, an account, or someone's word being taken on faith. This standard describes how a name can be made provably unique and provably tied to one key, so a wallet can resolve it and pay it safely.
Reference for an AI
Everything an assistant needs to answer questions about BRC-174 accurately, including what it depends on.
Summary
- Why
- Human-readable names need to map to exactly one identity and one holder-controlled key without relying on a registrar, certifier, or domain that could withhold, reassign, or lie about the mapping.
- What
- BRC-174 defines how to verify that a name token is unique by consensus, descends from a trusted namespace root, and is currently bound to the identity key it resolves to, so a resolver can turn a typed name into a payment destination it can trust.
- How
- A resolver looks up a name's current outpoint through an index, walks the token's spend history back to its namespace's genesis to confirm authenticity, reads the identity key locked into that output's PushDrop script, and derives a payment destination from that key using BRC-42/BRC-43, treating the index's answer as…
What this lets you do
- Resolve a human-readable name to a verified identity key
- Confirm a name token descends from a trusted namespace root rather than a lookalike
- Detect that a name's identity binding was revoked simply by the token being spent
- Rebind a held name to a new identity key by creating a new binding
- Derive a payment destination from a resolved identity key via BRC-42/BRC-43
Written by claude-sonnet-5 from the specification text. Where the two differ, the original is correct.
The specification
Abstract
Uniqueness is not free on Bitcoin: script validates transactions, not protocol semantics, so nothing inherently stops two parties from each broadcasting a valid claim to the same name.
This document specifies resolution for names whose uniqueness is instead settled in script, where a duplicate claim is an invalid transaction rather than a dispute to be arbitrated. OpNS is the reference namespace (§ 2.4).
What this is for. A user types archie into a send form, enters an amount, and presses send.
The wallet resolves archie to an identity key, derives a payment destination from that key with
BRC-42/BRC-43, and delivers the payment to
the recipient's message box (BRC-33). No domain, no registrar, no certifier and no
account with any operator stands between those three actions and a settled payment. Everything below
exists to make that one resolution safe to act on.
Four things have to hold for it to be safe, and this document keeps them apart throughout, because conflating them is how both a reader and an implementation go wrong:
- Uniqueness and control — the name token. The name is a transferable 1-satoshi token, minted by a covenant under which a second token for the same name is an invalid transaction, so uniqueness is enforced by the miners rather than arbitrated by anyone (§ 2). Whoever can spend the token controls the name. The token asserts nothing about who its holder is.
- Authenticity — descent from the namespace root. A covenant enforces uniqueness only within
its own tree, and anyone may inscribe the string
archieinto an unrelated output. A resolver therefore verifies that the output in front of it descends from the configured genesis: it walks the 1-satoshi chain back to the token's origin, then verifies that origin was minted by a character claim descending from the root (§ 4 step 3). This is the check that separates the realarchiefrom a lookalike, and without it nothing else in this document is worth anything. Because a name can never be re-minted, its origin is permanent, so this is a one-time cost per name rather than a per-payment one. - Resolvability — the identity binding. The identity binding is a PushDrop locking script on that same token's current output, carrying the identity public key the name resolves to. It is not a second token or a separate record — it is how the name token is locked right now. The locking key is derived from the asserted identity key, so a name bound to a key can be spent only by that key's holder, and a required field signature proves that holder consented to the identity binding. Two consequences: nobody can rebind a name they cannot already spend, and binding a name to a key you do not hold would surrender it to whoever does. No certifier is needed because there is nothing to take on anyone's word.
- Findability — the index. An off-chain service maps a name to its current outpoint. It is a data source, not an authority: § 4 requires the client to re-verify everything it returns, so a wrong answer fails locally instead of resolving wrongly. It can withhold or serve stale answers (§ 6); it cannot forge. Indexes are discovered through [object Object]/SLAP advertisements (BRC-101); any operator may run one and none is privileged.
Because the identity binding is the current output's locking script, spending the name token destroys the identity binding with it — no revocation list, expiry, or tombstone is needed, and no dedicated output exists solely to be indexed. Note precisely what is and is not revoked: the name survives the spend and moves to the new output, and can never be recycled or reclaimed by anyone (§ 8). Only the identity assertion ends, and only the holder can end it.
Uniqueness is settled by consensus at mint; authenticity and resolution are settled by verification at read. Neither requires a certifier, a registrar, or a domain.
Motivation
1. What a naming system has to do
- Human-readable — a person can remember it, type it, and say it aloud.
- Unique —
archiemaps to exactly one identity. - Non-fungible — the name is the holder's; no one else can claim it.
- Self-sovereign — the holder has cryptographic control of it, and can transfer it.
- Concurrently mintable — many unrelated names registered in the same block, by parties who do not know about each other and do not coordinate through anyone.
The first four are the classical statement; the fifth is what makes it a protocol rather than a demo. Properties 2 and 5 pull against each other — uniqueness invites funnelling every registration through one place, concurrency requires the opposite.
2. Three ways to make a name unique
| Approach | Who is trusted | Cost |
|---|---|---|
| A central registry | the operator | single point of failure; the operator can assign, withhold, or reassign |
| A script covenant | the protocol and Bitcoin's miners | uniqueness enforced by consensus; contention becomes a coordination problem |
| Federated indexer consensus | the protocol and the federation | many operators computing the same answer from the same chain data; residual honesty assumption |
This document recommends the covenant, composed with a federated index — and OpNS is the covenant (§ 2.4). They compose rather than compete: the covenant settles uniqueness at mint, once, at no cost to every later read; the index makes names discoverable afterwards, and no operator is canonical. A central registry is out of scope — an operator that can assign a name can withhold it. The missing piece is the specification joining the two, without which consensus-grade uniqueness at mint degrades to ordinary indexer trust at read.
3. Why verification, not reputation
Reputation does not compose across independent operators. The authors operate a wallet resolving
names through ls_identity, filtered to two hardcoded certifier keys. Searching for one real user
on 2026-08-10, decoding every certificate returned:
| Result | Source | Visible to our users |
|---|---|---|
| 3 of 7 | a certifier on our list | yes |
| 2 of 7 | a certifier not on our list | no — but attests a subject we can already see |
| 2 of 7 | the same off-list certifier | no — and no other source attests this subject |
The last row is the failure: a real participant is absent, not ranked lower, because of who vouched for them. A new source becomes visible only by persuading each wallet vendor to ship an update — a cost borne by new entrants and accruing to incumbents. Where the identity binding is provable from the locking script a wrong answer fails locally, so no index need be trusted and none excluded. Portability follows from the same fact: an identity binding held in an operator's database cannot travel, while one carried on the token's UTXO moves with the keys.
4. Sustaining the federation
Serving resolution costs bandwidth, storage, chain sync and abuse handling, for queries that earn nothing today. Someone has to pay for it, and no published standard says who. The options are per-query micropayment, a subscription or API key, or resolution bundled into a broader service by an operator that already profits from the ecosystem it feeds. The authors' position is that per-query micropayments are the natural incentive layer on this chain; § 10.1 puts the mechanism to reviewers rather than settling it here.
Related work
| System | Uniqueness enforced by | Holder-controlled |
|---|---|---|
| Paymail (BRC-28) | the domain operator | no — revocable by the domain |
| BRC-169 handles | the ecosystem host, per domain | no — host may reassign |
| ENS (Ethereum) | smart contract | yes — with annual rent, on another chain |
| Name tokens (this document) | Bitcoin script covenant | yes |
BRC-169 addresses reachability — given a handle, obtain an identity key, a messagebox and a way to pay — and scopes uniqueness to one domain, stating that "global uniqueness is neither required nor assumed." This document addresses the case where global uniqueness is required and already settled on-chain. The two compose (§ 10.7) and reuse the same payment and messaging legs (BRC-29, BRC-42, BRC-43, BRC-95, BRC-33).
Specification
The key words MUST, MUST NOT, SHOULD, SHOULD NOT and MAY are to be interpreted as described in RFC 2119.
1. Terminology
Written against OpNS (David Case / b-open-io), the deployed namespace satisfying § 2, in OpNS's own vocabulary. A different namespace meeting § 2 conforms.
- Name token — the 1-satoshi transferable output that is the name. In OpNS a
BRC-159 1Sat ordinal inscribed with the name string, content-type
application/op-ns. BRC-159 and BRC-160 apply unchanged; a name is non-fungible and unrelated to the BSV-21 fungible-token documents. - Mine tree — the structure the namespace grows in. Names are built one character at a time and every name descends from a single genesis output.
- Node — an output in the mine tree representing one prefix, carrying a bitmap of the characters already claimed beneath it.
- Character claim — a transaction spending a node to claim one character, producing the same node with that bit set, a child node for the extended prefix (the spawn), and, at the final character, the name token.
- Spawn — creation of a child node for a prefix that did not exist. Because a spawn spends the parent, two parties racing to spawn one prefix are double-spending (§ 2.3).
- Control — the ability to spend the name token. Established at mint and not publicly legible: an observer sees a locking script, not the holder's identity key.
- Identity binding — the publicly verifiable assertion of which identity public key a name
resolves to, carried as a signed PushDrop (BRC-48) on the name token's
current output (§ 3). Counterparty is
anyone, so any observer can re-derive the locking public key from the asserted identity key and confirm the match. A name may be under control without one; such a name is validly held and does not resolve. - Index — any service mapping a name to its current outpoint. An index answers where to look, never what is true (§ 4).
- Resolver — the client-side algorithm of § 4.
Binding is never used unqualified: alone it reads as control, a different relation established at mint. Identity binding is used as BRC-108, BRC-115 § 1, BRC-138 and BRC-190 use it. Likewise nothing in this document is ever described as revoked on its own. Only the identity binding is revocable, and the only way to revoke it is to spend the name token (§ 7). The name is never revoked, never expires, and can never be reclaimed or recycled by anyone (§ 8); an index entry is not revoked either, only gone stale (§ 6). Control is preferred to custody and owner, which carry regulated and legal meanings the protocol does not assert. Name, not handle: BRC-169 uses handle for a domain-scoped identifier, and these carry no domain. Origin, tip and inscription envelope are used as BRC-159 and BRC-160 define them.
2. Namespace requirements
2.1 Uniqueness
A conforming namespace MUST enforce, in script, that at most one token exists per name. A client MUST NOT treat a name as resolvable under this document if uniqueness is enforced only by indexer convention.
2.2 Namespace identification
A namespace MUST be identified by its genesis outpoint, and a conforming token MUST commit to that outpoint so a client can distinguish tokens of one namespace from lookalikes of another. The namespace root is a client configuration value that MUST be explicit and SHOULD be user-visible (§ 9).
Non-normative. Uniqueness within a namespace is a consensus property; which namespace is canonical is not, and cannot be — which is why the root is configuration rather than a constant of this document.
2.3 Concurrent registration
A conforming namespace MUST allow unrelated names to be registered concurrently, by parties who do not coordinate, such that many registrations confirm in the same block.
- Registration MUST NOT require a sequencer, coordinator, or any party whose participation is necessary for a third party's registration to proceed.
- Where two registrations contend, the contention MUST resolve as an ordinary double-spend. A namespace MUST NOT rely on any tiebreak rule evaluated outside script.
- Spawning a new node MUST be done by spending its parent node. A namespace MUST NOT allow a new part of itself to be brought into existence by a transaction that spends nothing already committed to that namespace.
Non-normative — what item 3 prevents. If a partition can be created out of nothing, two parties each creating partition 7 produce transactions that spend nothing in common: both confirm, and the namespace holds two rival partition 7s with no double-spend for consensus to see. Requiring a spawn to spend its parent turns a silent, permanent uniqueness failure into an ordinary race.
2.4 Reference namespace
This document recommends OpNS, the only deployed namespace known to the authors satisfying § 2.1–2.3, and specifies resolution against it.
| Requirement | Mechanism in OpNS |
|---|---|
| § 2.1 Uniqueness | assert(and(mask, this.claimed) == 0n, 'char already claimed') — a duplicate claim is an invalid transaction |
| § 2.2 Namespace identification | every token descends from one genesis outpoint, committed to in the inscription |
| § 2.3.1 No coordinator | any party may extend any node; no sequencer exists or is required |
| § 2.3.2 Contention is a double-spend | contending parties spend the same node output |
| § 2.3.3 Spawn spends its parent | the child node is an output of the transaction spending the parent |
Motivation properties 1, 3 and 4 also hold: names are strings over a–z, 0–9, -; a 1-satoshi
ordinal cannot be divided or duplicated; the holder controls the output and may transfer it.
Non-normative — what the covenant does and does not remove. This is easy to overclaim, so it is stated exactly. A plain 1Sat ordinal is not consensus-unique: anyone may inscribe byte-identical content in a new output and miners will accept it, because miners enforce signatures and double-spends and nothing in the ordinal layer. Uniqueness there rests on social agreement about which origin is genuine. The covenant changes that for names: a second token for the same name within one tree is an invalid transaction, and consensus enforces it. It does not prevent a rival covenant under a different genesis. So the covenant collapses a per-name ambiguity into one convention, settled once, about which tree is canonical (§ 9). It does not remove the lineage walk of § 4 step 3, and it does not remove the need for some party to supply the transaction data — only the need to trust that party.
Two limitations bear on adoption rather than conformance — the character-claim proof-of-work is fully specified and independently implementable, but the only published minting service is operated by a single party (§ 9); and a name cannot be released or recycled (§ 8). Neither affects § 3–§ 7.
2.5 Relationship to the P1Sat wallet filing (non-normative)
BRC-158, BRC-159 and BRC-160 are merged and
this document builds on them. The wallet-filing half of that series routed "OpNS rules" to separate
BRCs and listed "OpNS covenants" and "on-chain proofs that a current outpoint descends from an
origin" among what it does not define. This document is intended to be that separate BRC. The
filing's current revision — draft BRC-165, in review as
PR #229 at the time of writing — resolves the
earlier basket question (storage remains basket 1sat; p 1sat <scope> is a permission view) and
defines no OpNS-specific basket or scope, so no basket name is normative for name tokens.
Implementers SHOULD keep any basket or scope choice behind one configuration constant; nothing in
§ 3 or § 4 depends on it.
3. The identity binding
The identity binding is a signed PushDrop (BRC-48) carried on the name token's current output, however that output arose. The covenant's mint takes the locking script as a parameter, so a name MAY be minted directly to an output already carrying a binding; the two-step mint-then-bind sequence used by deployed tooling is an implementation choice, not a protocol rule.
| Item | Value |
|---|---|
| Protocol | [0, 'p 1sat'] |
| Counterparty | anyone |
| keyID | opns:{txid}_{vout} of the input spent to create this output |
forSelf | true |
fields[0] | identity public key, 33 bytes |
| Field signature | REQUIRED, same derivation |
- An identity binding MUST be signed such that the locking script's public key is reproducible by
KeyDeriver('anyone').derivePublicKey(protocol, keyID, idKey)for theidKeyinfields[0]. keyIDMUST reference the input outpoint spent to create the output carrying the binding, so a binding cannot be lifted from one token and replayed onto another.- A token MAY carry no identity binding. A client MUST treat an unbound token as a validly held name that does not resolve to an identity key, and MUST NOT fall back to any other source.
- Carrying an identity binding and being publicly discoverable are independent. A binding is valid on-chain whether or not it has ever been advertised, and a holder MAY bind a name without submitting the transaction to any index.
Non-normative — can someone else bind their key to a name I own? Not to your token. The identity binding is the locking script, so changing it means re-locking the output, which means spending it, which only its controller can do. What an attacker can do is inscribe your name into an unrelated output, bind that to their own key — a binding which verifies perfectly well on its own terms — and submit it to an index. § 4 step 3.2 is what defeats this, and it is why that check is normative. "How do I know this is the real
archie?" and "how do I stop someone binding their key to my name?" are the same question asked from the two ends.
Non-normative — an earlier deployed format binds by declaration. The OpNS author's production server stack resolves paymail bindings by reading an
opns.idKeymetadata field from the name's latest inscription — an identity key or, in the oldest form, a P2PKH address (b-open-io/1sat-stack,pkg/paymail). Writing that field requires spending the name, but the field is plain data: nothing ties the asserted key to the script that controls the name, so a holder can assert a key they do not control and a client can only take the assertion on trust. The format above closes that gap by derivation — asserting a key hands spending control to its holder, so a false assertion costs the name.
3.1 Presentation fields
Fields after fields[0] are presentation slots, positional and optional: slot 1 a UTF-8 display
name, slot 2 an avatar as a 36-byte origin outpoint.
- Trailing unset slots MUST be omitted rather than padded.
- Where a later slot is set and an earlier one is not, the earlier MUST be present as an empty push — a binding carrying only an avatar has an empty slot 1.
- Presentation slots are unattested display metadata. A client MUST NOT treat them as verified attributes of the subject and SHOULD apply the caution it applies to any self-declared name.
- A client MUST NOT reject a binding because it carries slots it does not recognize.
3.2 Extension and forward compatibility
The field layout is not closed.
- A client MUST ignore fields it does not recognize.
- A client that reconstructs an identity binding — on transfer, rebinding or any re-lock — MUST preserve unrecognized fields in their original positions and MUST NOT strip, reorder or collapse them.
- A client MUST NOT assign meaning to an unallocated slot on its own initiative.
Non-normative — why rule 2 is load-bearing. A binding is reconstructed every time the name moves, so a wallet dropping fields it does not understand destroys a future extension on the next transfer, invisibly, and the loss cannot be retrofitted. An in-flight revision to BRC-147 adds the same MUST-preserve-on-rebuild rule after wallets rebuilding
customInstructionsfrom recognized fields dropped a media pointer.
3.3 Referenced attributes
- Rich, typed or frequently-changing attributes SHOULD be referenced by outpoint rather than embedded, because every change to the binding spends the name token (§ 7.5).
- The content type of a referenced attribute comes from that inscription's envelope per BRC-160. A binding MUST NOT restate it, and a client MUST NOT prefer a type asserted in the binding over the one in the envelope.
- A referenced outpoint that does not resolve MUST be treated as an absent attribute, never as a verification failure of the identity binding itself.
3.4 Claims about keys the name does not control
This document binds a name to one identity key. A future specification may let a name carry claims about other keys or assets; the constraint below applies to any such extension and is stated here so it is not settled by accident. BRC-160's parent field is the precedent: anyone can push arbitrary bytes as field 3, but only someone who can unlock the parent output can spend it into the child mint — the spend is the proof.
- A claim about a key or asset not controlled by the name's controlling key MUST carry proof committing to this name and this binding outpoint, so it cannot be replayed onto another name.
- A client MUST NOT present such a claim as verified unless it has independently re-derived the claimed party's current control from the chain.
- Where current control cannot be established — the asset or account is not on-chain, or is held by a custodian — the claim MUST be rendered as asserted rather than verified.
The operative split is on-chain versus off-chain, not same-key versus different-key.
BRC-210 § 3.1 supplies confidence vocabulary for it, and
BRC-190 § 4.1's holdingKeys is the nearest prior art (§ 10.6).
4. Resolution
Given a name, a conforming resolver MUST:
-
Obtain a candidate current outpoint from one or more indexes (§ 5). A BRC-24 lookup returns BEEF together with the index of the output within it; the resolver MUST use that returned output index rather than searching the transaction.
-
Recover the locking script for that output from the returned BEEF, and verify the BEEF.
-
Verify the output belongs to the configured namespace (§ 2.2). This has two parts and a resolver MUST perform both:
- Tip to origin. Walk the 1-satoshi chain from this output back to its origin per BRC-159, and read the name from the origin's inscription. The inscription naming the name is at the origin, not on the current output, so a check against the current output alone is not a check at all. This part MUST be repeated on every resolution, because the tip moves whenever the name is transferred or rebound.
- Origin to namespace root. Verify that the origin output was produced by a character claim (§ 1) spending a node that itself descends from the configured genesis outpoint. A resolver MUST NOT accept an origin on the strength of its inscription alone: anyone may inscribe the same string into an unrelated output, and descent is the only thing that distinguishes the two.
A resolver obtains the transactions for both parts from any BEEF source (§ 5.4), validates every script and merkle path itself, and trusts none of them.
-
Verify the output is unspent (§ 6).
-
Decode the PushDrop. If absent, resolution yields no identity key; stop.
-
Read
idKeyfromfields[0]. -
Re-derive the expected locking public key from
idKey, the protocol and thekeyID, verify it matches the script, and verify the field signature. -
Only on success treat
idKeyas the identity key for the name.
A resolver MUST perform steps 2–7 locally. A resolver MUST NOT accept an index's assertion of the identity key without performing them, even where the index is authenticated, paid, or operated by the client vendor. This is what makes indexes replaceable. Where several indexes disagree on the current outpoint, the resolver MUST verify each candidate and MUST surface an unresolved disagreement to the user rather than silently selecting one.
A resolver MAY cache the result of step 3.2 — the mapping from a name to its origin outpoint — indefinitely, and on a cache hit MAY perform only step 3.1. It MUST NOT cache step 3.1, step 4, or the identity key beyond the freshness bound of § 6.
Non-normative — why step 3.2 is affordable, and why it is paid once. A name can never be re-minted: the claimed-character bitmap lives on the parent node and is never reset by spending the name token (§ 8), so the mapping name → origin outpoint is permanent, unique, and safe to cache forever. Two clients that each perform the walk independently derive the same 36 bytes, so the result can be compared across sources and a disagreement is detectable rather than silent. The bundle is also bounded rather than open-ended: a given character can be claimed at most once at a given node, so a node is spent at most once per character in the alphabet, and the ancestry of a name of length L is on the order of L × |alphabet| transactions — not the unbounded history that "back to genesis" usually implies. This is an analysis of the covenant's bitmap rule and has not yet been measured against mainnet.
5. Index discovery
5.1 Discovery requirements
- A resolver SHOULD discover indexes through SHIP/SLAP advertisements per BRC-101, querying the lookup service for the topic in § 5.2.
- A resolver MAY additionally use configured endpoints, and SHOULD treat these as a cold-start fallback rather than a primary source.
- A resolver MUST make its SLAP tracker set configurable.
- Because § 4 requires local verification, an index requires no reputation and a client needs no allowlist of operators. This is the operative difference from certifier-filtered resolution.
Non-normative. BRC-190 § 4.1 and BRC-210 § 8.4 state the governing principle — an indexer is not authoritative and a client MUST NOT treat it as such. BRC-210's
witnessedclass, a value "reported by an indexer and not independently re-derived", is deliberately not applied here: an index returns a location, and § 4 re-derives the identity binding from the chain at that location, so a wrong location yields a failed verification, not a wrong answer.
5.2 Topic and lookup service names
This document proposes tm_opns / ls_opns, following BRC-87. Checked
2026-08-10, listTopicManagers and listLookupServiceProviders against four SLAP trackers
(overlay-us-1.bsvb.tech, overlay-eu-1.bsvb.tech, overlay-ap-1.bsvb.tech, users.bapp.dev)
return no OpNS-related name, so the pair is unclaimed on the advertised network. BRC-87 establishes
no registry, so this is a claim rather than a reservation; an operator finding either name already
in use SHOULD raise it against this document rather than silently choosing a variant, since two
implementations on different topics cannot see each other.
5.3 Why a separate topic
Name-token resolution SHOULD NOT be folded into ls_identity or an equivalent certificate lookup. A
certificate lookup returns third-party attestations a client must evaluate against a certifier
policy; a name-token lookup returns self-proving identity bindings needing no policy. Merging them obliges
every client to decide per result which regime applies, and the natural failure is to apply the
weaker one. The certifiers parameter is meaningless for a name token and invites filtering results
that were never certifier-scoped. Clients MAY present both sources in one interface and SHOULD
distinguish them visually (§ 10.7).
5.4 The resolution index and the transaction source are different services
Two distinct things are needed at read time, and this document does not require one operator to provide both. They are named separately because calling both of them "the overlay" is what makes § 4 hard to follow.
- Resolution index — name → current outpoint. This is the
ls_opnsservice of § 5.2. It is queried on every resolution, is latency-critical, is specific to names, and is the subject of § 10.1. - Transaction source — the BEEF needed to validate § 4 steps 2 and 3. This is generic BSV data availability, served equally well by a block explorer, a transaction-streaming service, an archival overlay, or the client's own node. Nothing about it is name-specific.
A resolver MAY obtain both from the same operator and MUST trust neither. The distinction matters because the two have different cost profiles, different caching behaviour — § 4 step 3.2 is cacheable forever, the index answer is not — and therefore different answers to the question of who should pay for them.
6. Spend status and staleness
Verifying that an output is unspent is not possible under SPV, which proves inclusion and not absence. This document inherits that limitation.
- A resolver MUST obtain spend status from at least one index, and SHOULD consult more than one before a value-moving action.
- A resolver MUST record the time of the check alongside any cached result.
- Before a value-moving action a resolver MUST use a result no older than 60 seconds by default, configurable.
- If no index is reachable, a resolver MUST NOT treat an identity binding as current for a value-moving action. It MAY continue to display previously resolved data marked as unverified.
Non-normative. A dishonest index can withhold a name or serve it stale, but cannot forge an identity binding to a key it controls, because § 4 step 7 fails. A dishonest certifier can do the latter.
7. Transfer, rebinding, and revoking the identity binding
- Spending the name token spends the identity binding with it. A conforming client MUST treat a spent output's identity binding as void without requiring any separate revocation record.
- A transfer that does not reconstruct an identity binding leaves the name unbound. Clients performing transfers SHOULD make this explicit to the user.
- To rebind, the holder creates a new identity binding per § 3 on the new output.
- A resolver MUST compare a freshly resolved identity key against any stored value for that name, MUST NOT silently update it, and MUST warn before a value-moving action where it has changed.
- Every change to an identity binding, including a change to a presentation slot, spends the name token. A client MUST reconstruct the full binding per § 3, preserving unrecognized fields per § 3.2, and MUST treat cached resolutions of that name as stale from the moment the spend is broadcast.
Non-normative. Item 5 is the price of item 1: an identity binding that lives on the asset is revoked by moving the asset, and by the same fact cannot be edited without moving it — hence § 3.3. Nothing here revokes the name, which the holder keeps across every transfer and rebind.
8. Loss is permanent
Where the covenant permanently consumes a name on mint — as OpNS does, since the claimed-character bitmap lives on the parent node and is never reset by spending the name token — a lost key renders the name permanently unresolvable and unrecoverable by anyone, including the namespace operator.
- A conforming client MUST disclose this before a user acquires a name.
- A client SHOULD support export of the key material controlling name tokens as part of ordinary backup, and MUST NOT treat name tokens as a category excluded from backup because they are not spendable value.
- A client SHOULD make the trade-off below available to the user at acquisition time, so the choice between a recoverable name and a seizure-resistant one is made deliberately.
An operator able to restore a name to someone who lost their key is necessarily able to move a name away from someone who did not: recovery and seizure are one mechanism, and removing the operator removes both. Recovery is therefore a key-management problem, not a naming one — a name token is an ordinary output, so BRC-140, BRC-154 and BRC-157 apply to it unmodified.
9. Security Considerations
Namespace canonicity is convention, not consensus. Nothing prevents deploying an identical covenant under a different genesis, so a client that does not pin its namespace root can be shown a valid token from a namespace the user did not mean. § 2.2 makes the root explicit. This is a genuine weakness and is not solved here.
Indexes can withhold and go stale. They cannot forge. See § 6.
Confusable names. A covenant enforces uniqueness of bytes, not appearance; br0ndon and
brandon are distinct valid names. Clients SHOULD apply a confusability check before a value-moving
action to a name not already in the user's address book, and SHOULD reuse the skeleton algorithm of
BRC-169 § 2.3 rather than reinvent it, so two clients agree on what
constitutes a spoofing risk.
Minting centralization is out of scope but not hypothetical. Identity binding and resolution are open and implementable; minting is not specified here. Where the only available minting path is a single operator's paid service, the namespace has a liveness dependency this document does not remove.
Resolution discloses intent. Querying an index for a name tells that operator the client is about to transact with its holder. Clients SHOULD cache within a freshness bound and MAY resolve through a relay.
Unbound names are not failures. A token with no identity binding is a validly held name. Clients MUST NOT substitute any other resolution source, or an attacker who can suppress an identity binding can redirect resolution to a source they influence.
10. Open Questions — Request for Comments
Precedent for open items in a published BRC: BRC-169 § 4.5 leaves certificate-type publication "open for review"; BRC-101 labels its own status "aspirational rather than descriptive."
10.1 — How should discovery overlays be compensated? (primary) Every naming design here depends on an index someone must pay to run, and no published standard says who pays. A federation no one can afford to join is a monopoly with extra steps. Three directions: (a) per-query micropayment behind HTTP 402 via BRC-105 or a BRC-121-profiled flow — exact cost alignment, no account, but a payment round trip on a latency-critical path; (b) a prepaid credential bought with a BRC-29 payment and presented under BRC-103/BRC-104 — predictable revenue, but a credential lifecycle and a per-operator coordination cost of the kind Motivation § 2 warns about; (c) publisher-funded indexing paid at publish time so lookups stay free — fast and unauthenticated, but resembling the metered token-indexing arrangements already deployed here. In all three, the payment buys read acceleration only. An index is never in the transfer or validity path — moving a name is a plain spend that requires no operator's approval and pays no operator a fee — so no model here places a per-transfer toll on the name itself. Comment sought on whether any belongs in this document, whether a client should be required to disclose which indexes it pays, and whether a paid index can be non-privileged given that § 4 already forbids trusting one.
10.2 — Should this document define a search interface? § 4 covers exact resolution. Autocomplete is a different operation with different privacy properties, and search results carry no attestation.
10.3 — Contention on shared prefixes. § 2.3 makes spawn races safe; it does not make them rare, and human-chosen names cluster, so at volume a popular prefix becomes a retry hotspot. Comment sought on whether this needs a normative mitigation — backoff, batching several character claims into one chained transaction, or a node layout spreading claims across more outputs — or belongs to implementations. Hash-based partitioning is not a candidate unless creating a partition is itself a spend, for the reason in § 2.3.
10.4 — Should the registry maintain a shared glossary? An observation from writing a first BRC, not a proposal. Several load-bearing words carry more than one meaning across the corpus and deployed tooling: publish (an on-chain assertion in one SDK; overlay submission in common usage), binding (control, to a casual reader; an identity assertion in BRC-115 § 1), custody (control over a room in BRC-190; a regulated role in finance) and witness (a confidence class in BRC-210 § 3.1; input unlocking data in BRC-160; plus testimonial and zero-knowledge senses). BRC-87 is the narrow precedent. Comment sought on whether such a glossary is worth maintaining, and whether it belongs as a BRC or as repository documentation.
10.5 — How should the identity-binding format evolve? Two parts. (i) § 3's keyID prefix is opns:;
covering any conforming namespace suggests parameterizing it, but changing it breaks every deployed
identity binding, so it is raised rather than made. (ii) The deployed layout is positional, and a
positional slot carries no type and no namespace, so slot 3 can only mean one thing globally — which
needs an allocator, the coordination point Motivation § 2 argues against. Three directions:
(a) keep allocating slots with this registry as allocator — simplest, matches deployment,
reintroduces that point; (b) a tagged self-describing field with a namespaced type tag derived
from a string, as BRC-169 § 4.5 derives certificate types —
permissionless, but larger on-chain and still collidable; (c) one slot holding an outpoint that
addresses a key-value profile document (§ 3.3) — unlimited attributes, no allocator ever, and
the name token stops moving for profile edits, at the cost of a resolution hop. (c) is the option
the authors think is right. It must settle key collisions (namespacing, per BRC-169 § 4.5),
encoding (RFC 8785 canonicalization for JSON versus the
deterministic CBOR the in-flight BSV-21 binary specification uses), and currency — establishing that
a fetched profile is not superseded, which is the same tip-to-origin walk as § 4 step 3.1. The full
argument for (c) is available from the authors.
10.6 — Cross-key claims. § 3.4 constrains any future extension carrying claims about keys or
assets the name does not control, without specifying a mechanism. Comment sought on whether that
mechanism belongs in a follow-up document — the authors think it does, since proof-of-control,
staleness, revocation and the on-chain/off-chain split are each their own argument — and on whether
BRC-190 § 4.1's holdingKeys should be adapted to an on-chain transport rather
than a second scheme invented alongside it.
10.7 — Relationship to BRC-169. These are complementary and a wallet may implement both. Should that composition be specified — a preference order, a display rule distinguishing a consensus-unique name from a domain-scoped handle — or left to implementers?
Implementations
- The identity-binding format in § 3 is deployed and documented in the
@1sat/actionsSDK as the OpNS identity bind. This document specifies the verification and resolution rules around it; it does not invent the identity binding. - The OpNS reference overlay (
b-open-io/opns-overlay) is MIT licensed and self-hostable, which is what makes § 5 realizable rather than aspirational. - SHIP/SLAP discovery per § 5 is deployed in Hodos, a browser with a native
BRC-100 wallet, against
overlay-us-1.bsvb.tech,overlay-eu-1.bsvb.tech,overlay-ap-1.bsvb.techandusers.bapp.dev, with a stale-while-revalidate host cache. It is used today fortm_identity. - Not yet implemented by the authors: the § 4 resolver. Hodos currently resolves names through
certifier-filtered
ls_identitylookups, the design this document argues against. Disclosed so the status of § 4 is not overstated.
References
- BRC-24: Overlay Network Lookup Services (§ 4, the lookup returning BEEF)
- BRC-28: Paymail Payment Destinations (Related work)
- BRC-29: Simple Authenticated BSV P2PKH Payment Protocol
- BRC-33: PeerServ Message Relay Interface
- BRC-42: BSV Key Derivation Scheme (BKDS)
- BRC-43: Security Levels, Protocol IDs, Key IDs and Counterparties
- BRC-48: Pay to Push Drop (§ 3, the identity binding's locking script)
- BRC-87: Standardized Naming Conventions for Topic Managers and Lookup Services
- BRC-95: Atomic BEEF Transactions
- BRC-100: Wallet-to-Application Interface
- BRC-101: Diverse Facilitators and URL Protocols for SHIP and SLAP Overlay Advertisements
- BRC-103: Peer-to-Peer Mutual Authentication and Certificate Exchange Protocol
- BRC-104: HTTP Transport for BRC-103 Mutual Authentication
- BRC-105: HTTP Service Monetization Framework
- BRC-108: Identity-Linked Token Protocol
- BRC-115: Identity-Linked Deterministic Token Verification Framework (§ 1, "Identity Binding")
- BRC-121: Simple 402 Payments (§ 10.1(a))
- BRC-138: Single-Use Signed Proofs for Request Authentication
- BRC-140: Threshold Key Sharing and Backup via Shamir's Secret Sharing Scheme
- BRC-190: Access Gates for Metanet Rooms (§ 4.1: index as non-authority and
holdingKeys) - BRC-147: 1Sat Ordinals Basket Profile (§ 3.2, the MUST-preserve-on-rebuild precedent)
- BRC-154: Pluggable Backup Services for BRC-140 Share Vaults
- BRC-157: Entropy-Rooted Backup and Recovery with Mnemonics and Backup Shares
- BRC-158: Outpoint BEEF
- BRC-159: 1Sat Ordinals — Single-Satoshi Tokens and Origin Tracking (§ 4 step 3.1, the tip-to-origin walk)
- BRC-160: 1Sat Ordinals — Inscription Envelopes (§ 3.4, field 3 and "the spend is the proof")
- BRC-169: Universal Handle Addressing and Resolution for the Metanet
- BRC-210: Derived Collectibles (§ 3.1 confidence classes; § 8.4 index as non-authority)
- OpNS protocol specification: https://op0-2.gitbook.io/op-standard/protocols/op-ns
- RFC 2119: Key words for use in RFCs to Indicate Requirement Levels
- RFC 8785: JSON Canonicalization Scheme (JCS) (§ 10.5)