diff --git a/CHIPs/chip-0060.md b/CHIPs/chip-0060.md new file mode 100644 index 00000000..b74b45f3 --- /dev/null +++ b/CHIPs/chip-0060.md @@ -0,0 +1,290 @@ +CHIP Number | 0060 +:-------------|:---- +Title | Titled CAT Standard +Description | A standard attaching an immutable, on-chain metadata reference (name, ticker, content hashes, creator DID, and supply commitments) to a CAT. +Author | [Evan Winget](https://github.com/EvanWinget) +Editor | [Dan Perry](https://github.com/danieljperry) +Comments-URI | [CHIPs repo, PR #205](https://github.com/Chia-Network/chips/pull/205) +Status | Draft +Category | Standards Track +Sub-Category | Primitive +Created | 2026-05-22 +Requires | [CAT2](https://chialisp.com/cats/), [CHIP-40 (`everything_with_singleton` TAIL)](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0040.md), Singleton Standard, Offer Standard. Optional layers: [DID1 (CHIP-4)](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0004.md) (creator provenance), [CHIP-56 (Fee CATs)](https://github.com/Chia-Network/chips/pull/194) (royalties), [CHIP-38 (Revocable CATs)](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0038.md) (revocability) +Replaces | None +Superseded-By | None + + +## Abstract + +A **Titled CAT** is a Chia Asset Token (CAT) with a **title**: an immutable, hash-committed, on-chain metadata reference (name, ticker, content hashes, an optional creator DID, and supply commitments) bound to the token by construction. + +A CAT already has an on-chain identity in its TAIL and the asset ID derived from it, but that identifier is opaque. The token's name, ticker, image, license, and creator DID all live off-chain, supplied by indexers and registries. Titled CAT closes this gap: it attaches a verifiable metadata reference to the CAT's existing on-chain identity with no registry. The standard is **additive and opt-in**, does not modify or deprecate CAT2, and introduces no new consensus rules or CLVM operators, only one new puzzle: the **Title Singleton** inner puzzle. + +A single committed `precision` field fixes display across the fungibility spectrum. **`precision = 1` is the indivisible case: one mojo is one whole token, shown as an integer count**, suited to trading cards, tickets, and editioned collectibles, while larger powers of ten give divisible, decimal tokens for stablecoins and fractional commodities. + + +## Definitions + +Throughout this document: + +- **Title**: The immutable on-chain metadata reference of a Titled CAT (name, ticker, precision, content hashes, optional creator DID, optional royalty and revocation config, and supply commitments). By analogy to a property *title*, it names the asset and records its provenance. +- **Title Singleton**: The singleton whose inner puzzle holds the Title and authorizes minting and melting via the associated TAIL. Its launcher ID is the asset's permanent identifier. Spent only at mint, melt, mint-close, URI-append, and ownership transfer, never on ordinary Unit transfers. +- **Title ID**: A bech32m encoding of the launcher ID, prefix `tcat`. +- **TAIL Asset ID**: The tree hash of the CHIP-40 `everything_with_singleton` TAIL curried to the Title Singleton, the CAT asset ID by which tooling identifies the token's Units. +- **Unit**: The base indivisible unit, one mojo of the CAT. Units of a title are interchangeable, and all holdings and supply counters are denominated in Units. +- **precision**: Units per whole displayed token, committed immutably (defined under *Specification*). `precision = 1` is indivisible. +- **Holder**: A wallet or coin controlling one or more Units. +- **Issuer**: The creator of a Titled CAT. Its DID, when present, is curried at creation and immutable. +- **Title Owner**: The current controller of the Title Singleton (initially the Issuer), authorized to mint, melt, close the mint, prepend URIs, and transfer the title via `transfer_title`. +- **Total Minted / Circulating Supply**: `total_minted` is the monotonic cumulative count of Units ever minted (never falls, even on melt). Circulating Supply is the count currently in existence, equal to `total_minted` minus Units melted and observable on-chain. +- **Must, required, shall / Must not, shall not / Should, recommended / Should not, not recommended / May**: as in CHIP-0005. + + +## Motivation + +A CAT is identified on-chain by its TAIL and the asset ID derived from it. That identifier is permanent and verifiable but opaque: it says nothing about what the token is called, what it represents, or who issued it. All of that lives off-chain. NFT1 (CHIP-5) shows the alternative, committing an NFT's name, creator DID, and content hash into its own coin. **The problem Titled CAT solves is that a CAT's metadata has no on-chain home bound to the asset.** + +### The metadata gap + +Because a CAT's metadata comes entirely from outside the coin, every option has a cost: + +- **Impersonation.** Anyone can mint a CAT and call it "wUSDC.b." Nothing at the protocol level separates the genuine issuer's token from a counterfeit, so users rely on off-chain allowlists. +- **Dependence on third parties.** To show a name or logo, a wallet must consult and trust an off-chain indexer or registry. The token cannot vouch for itself. +- **Registration friction.** Registries such as [CATalog (CHIP-55)](https://github.com/Yakuhito/chips/blob/xchandles/CHIPs/chip-0055.md) commit content hashes on-chain but require a registration step and a fee per asset. For an issuer with many assets (a 1,000-card game is 1,000 TAILs) that is a real, repeated cost. +- **No protocol provenance.** Nothing immutably binds a CAT to the DID that issued it. + +The same metadata reference serves the whole fungibility spectrum, from stablecoins and tokenized commodities to indivisible trading cards, tickets, and editioned collectibles, with a single `precision` field spanning the range. "Fungible within a class, distinct across classes" is well established elsewhere (notably Ethereum's ERC-1155), and Titled CAT brings it to Chia. + +### Technical feasibility + +Titled CAT needs no protocol changes. The non-royalty core uses only deployed pieces: CAT2, the CHIP-40 TAIL (Final, in production for Revocable CATs), the CHIP-38 revocation layer (Final), and the Singleton and Offer standards. The one new puzzle is the Title Singleton inner puzzle. The optional royalty path additionally relies on the CHIP-56 Fee Layer (open, PR #194). Composition is entirely at the puzzle-hash level, so no consensus or VM change is required. + + +## Backwards Compatibility + +Titled CAT introduces no breaking changes: it does not modify Chia's consensus, the CLVM, or any existing primitive. It is purely additive and opt-in, and neither replaces nor deprecates CAT2. + +A wallet that does not implement Titled CAT recognition sees a Titled CAT's Units as ordinary CATs with a recognizable TAIL pattern. It will not show the title's name, ticker, or artwork, so it never displays a misleading name, only a generic CAT. It also will not read the committed `precision` and falls back to its own default, so for a title whose `precision` differs from that default a legacy wallet and a Titled-aware wallet can show different quantities for the same coins. That divergence is treated under Security (*Precision display divergence*). + +Two alternatives are examined in the Rationale: assembling the same outcome from a plain CAT2 plus a registry (which leaves metadata extrinsic and mutable-by-default), and extending CAT2 itself to carry mandatory identity (rejected as a breaking change that would burden every CAT). + + +## Rationale + +### Title Singleton plus a CAT + +The design splits along Chia's coin-set model. Immutable metadata and supply discipline (name, ticker, precision, hashes, creator DID, royalty config, edition cap, mint state) live once, in the Title Singleton. Fungible holdings (who holds how many Units, and how they transfer and trade) are what CAT2 already represents. The CHIP-40 `everything_with_singleton` TAIL binds the two by committing the Title Singleton's launcher ID, so a Unit's Asset ID derives from that launcher ID and only the Title Singleton can authorize a Unit's existence. Metadata is therefore intrinsic, with no separate registry record and no canonical-holder ambiguity. Because the singleton participates only in mint and melt, a title with no royalty layer has the same per-transfer cost as a bare CAT2. + +### Argument for immutability + +A title's commitments are frozen by currying: name, ticker, precision, hashes, creator DID, royalty config, revocability, and edition cap can never change. This is deliberate and is most of what distinguishes a title from a registry entry. + +A coherent alternative is to make immutability optional and verifiable, letting any field be mutable and letting consumers that care check whether a given field is frozen. This standard chooses against it for two reasons. First, the failure modes are asymmetric: a hostile change to metadata after holders acquire the asset is far worse than an uncorrectable typo. Second, mandatory immutability lets a wallet or buyer verify a title once and trust it permanently. Per-field optional immutability would instead force every consumer to ask, for every field it relies on, "is this frozen, and if not, who can change it and have they?" + +URI lists are prependable (an owner may add new locations for the same hash-committed content, latest-first, never altering or removing existing entries, the NFT1 pattern), and supply state moves one way (`total_minted` only rises, `mint_closed` only flips true). When metadata genuinely must change, such as a real rebrand, the escape hatch is melt-and-mint migration. + +### DID-rooted provenance + +A curried creator DID gives a Titled CAT the provenance guarantee NFT1 provides: any Unit traces cryptographically to the issuer's DID. It does not make names unique, but it lets venues and wallets recognize the genuine issuer and disregard impostors, exactly as NFT1 collections are authenticated today. Curation can then target a list of verified DIDs rather than individual assets. + +### A single `precision` field instead of separate standards + +The base unit is always one mojo, and `precision` states how many mojos make one displayed whole token, exactly as CAT2's 1000-mojo convention does. Because metadata and divisibility are orthogonal, one standard suffices: the same Title Singleton, TAIL, and layer stack serve an indivisible trading card (`precision = 1`) and a milligram-divisible gold token (`precision = 1000`). Committing the value on-chain also removes the wallet-default disagreement that has made CAT2 amounts ambiguous (see *Precision display divergence*). `precision = 1` is guaranteed indivisible mechanically, since a coin cannot be smaller than one mojo, and wallets MUST display it as an integer count. + +### Optional fee layer and revocation layer + +Royalties and revocability are wanted by some titles and not others, so both are optional layered components rather than built in. This keeps the common case (neither) as cheap as a bare CAT2 while letting richer cases compose only what they need. Royalties are oriented to the editioned, indivisible case. Divisible fungibles generally want identity without a per-trade fee, so the Specification recommends they omit the Fee Layer (see *Royalty configuration*). + +### Why not CAT2 plus a registry? + +The closest alternative is a plain CAT2 with metadata in a registry such as CATalog, royalties via the Fee Layer, and a display flag. It reproduces much of the outcome but differs in where metadata lives, what it costs, and whether it can change: + +- **Intrinsic versus looked-up.** A title *is* the CAT's TAIL binding, read by walking the one Title Singleton the TAIL commits to, the same trustless full-node operation NFT and DID wallets already perform, with every field verifiable on-chain. The registry instead keeps metadata in a separate entry a wallet must trust the registry to resolve. +- **No per-asset registration cost.** A 1,000-card game is 1,000 registrations and fees under a registry. Under Titled CAT each title is a singleton the issuer creates to mint anyway. +- **Immutable by default.** CATalog's default updater permits changing name and ticker. A title's metadata is immutable by currying. + +This does not make registries redundant. Curation, verified-issuer lists, search, and discovery remain valuable and are better supplied by a registry than baked into a coin. The two compose: Titled CAT is a trustless metadata substrate a registry like CATalog can index and curate on top of. For a token that expects to rebrand, CAT2 plus a registry remains the right tool. + +### Relationship to NFT1 + +Titled CAT is singleton-anchored and DID-rooted, so it is fair to ask whether it subsumes NFT1. **It does not.** It is tempting to call an NFT a Titled CAT with `edition_cap = 1`, but even the 1-of-1 case is not a drop-in NFT: making a fungible Unit behave like a single item takes extra machinery (a `p2_singleton`-style check that the coin carries the right TAIL, supplied with the launcher ID, that the edition cap is one, and that the amount is exactly one). Such a title is a metadata equivalent, not a behavioral replacement. + +The deeper difference is granularity. A title puts one singleton around a whole *class* and holds balances as fungible Units, spent only at supply changes. NFT1 puts a singleton around every *item*, spent on every transfer, which is what lets each item carry distinct metadata and a DID-bound owner. Because any two Units merge into one coin, there is no per-Unit slot for distinct artwork, a serial number, or an owner. So a collection of unique artworks belongs in NFT1, while 100 identical copies of a card are one title and 100 interchangeable Units rather than 100 singletons. The boundary is individuation: once copies must be distinguished, the asset is in NFT1's domain. DID ownership follows the same line, supported for the *title* but not each *holding*, since a per-Unit owner DID would spend on every transfer and break fungibility. + +Part of this asymmetry is an NFT-side artifact, not a CAT deficiency: singletons were built for pooling and so allow only one of a thing, and a future where one mints N items under a single asset ID that must remain N coins would suit interchangeable cards and would itself want a class-level metadata reference like a title. + +### Why scope this to the primitive alone? + +This CHIP defines the primitive only. Two companions should be developed separately: a **Titled CAT Off-Chain Metadata Format** (a JSON schema for the `metadata_uri_list` document, analogous to CHIP-7), and **Titled CAT Collections** (conventions for grouping titles into a set or family). + + +## Specification + +### Title Singleton + +Each Titled CAT shall be anchored by a singleton conforming to the existing Chia Singleton Standard. The Title Singleton's launcher ID is the asset's permanent identifier. The **Title ID** shall be a bech32m encoding of the launcher ID with the human-readable prefix `tcat`. + +The Title Singleton's inner puzzle shall curry in the following values. All values marked immutable are committed at creation and may never change. The reference inner puzzle published with this CHIP is the canonical implementation. + +#### Identity (immutable) + +- **`name`**: UTF-8 string, maximum 256 bytes. The asset's full display name. Immutable. +- **`ticker`**: UTF-8 string, maximum 32 bytes. The asset's short symbol. Immutable. Tickers are not protocol-enforced as unique. Uniqueness is a curation concern. +- **`precision`**: Unsigned integer, the number of Units (mojos) per whole displayed token. Immutable. `precision = 1` selects the indivisible, integer-displayed case. Larger powers of ten (`precision ≥ 10`) make a whole token divisible into `precision` Units, displayed with decimals. Implementations SHOULD reject a `precision` that is not a power of ten. +- **`creator_did`** *(optional)*: 32-byte launcher ID of the issuer's DID singleton. Once set, immutable. If omitted, provenance is traceable only to the puzzle hash of the original Issuer. + +#### Content commitments (immutable hashes, prependable URI lists) + +Each URI list follows NFT1's pattern: the hash is a one-time commitment, while the URI list may be prepended to (latest-first) but never modified or removed. Wallets should verify fetched content against the hash before rendering. + +- **`data_hash`**: 32-byte SHA-256 hash of the asset's primary content (e.g., the card image or token logo). Immutable. +- **`data_uri_list`**: One or more URIs locating the primary content. +- **`metadata_hash`**: 32-byte SHA-256 hash of the off-chain metadata document at creation. Immutable. +- **`metadata_uri_list`**: One or more URIs locating the off-chain metadata document (richer fields per a companion metadata-format CHIP). +- **`license_hash`**: 32-byte SHA-256 hash of the licensing terms at creation. Immutable. +- **`license_uri_list`**: One or more URIs locating licensing and legal terms. + +#### Royalty configuration (present only if the fee layer is used) + +These values must match exactly the parameters curried into the CHIP-56 Fee Layer that wraps each Unit, so any wallet can reconstruct the expected Unit puzzle hash from the Title Singleton alone. + +- **`royalty_puzzle_hash`**: 32-byte puzzle hash to which royalties are directed. Immutable. +- **`royalty_basis_points`**: Unsigned integer in basis points (1 bps = 0.01%). Zero means no proportional royalty. No protocol cap. +- **`royalty_min_fee`**: Unsigned integer, the minimum royalty in mojos of the quote asset. Zero disables the floor. +- **`allow_zero_price`**: Boolean. When `false`, even direct-send transfers must declare a trade price and pay at least `royalty_min_fee`. When `true`, free transfers (gifting) are permitted. + +The Fee Layer is oriented to the indivisible, editioned case (`precision = 1`), where a royalty on resale is an established expectation. Divisible titles (`precision ≥ 10`) SHOULD set `royalty_basis_points = 0` and SHOULD NOT set `allow_zero_price: false`. A per-trade royalty interferes with the price discovery and arbitrage that fungible tokens depend on (notably automated market makers), and a floor charged on every transfer makes a circulating fungible impractical to use. A divisible Titled CAT therefore typically omits the Fee Layer entirely, carrying on-chain identity without royalties. + +#### Revocability (present only if the revocation layer is used) + +- **`revocable`**: Boolean. When `true`, every Unit is wrapped in a CHIP-38 revocation layer between the Fee Layer (or the CAT layer, if no Fee Layer) and the holder's `p2` puzzle, and any Fee Layer present is curried with `has_hidden_revoke_layer: true` and `allow_revoke_fee_bypass: true`. +- **`hidden_puzzle_hash`** *(present only if `revocable`)*: The hidden puzzle hash used by the revocation layer. Immutable. + +#### Supply commitments + +- **`edition_cap`** *(optional)*: Unsigned integer maximum on `total_minted`. If set, immutable. If omitted, supply is uncapped (subject to `mint_closed`). +- **`total_minted`**: Unsigned integer, the cumulative count of Units ever minted. Strictly monotonically increasing. Melts reduce Circulating Supply but not `total_minted`. +- **`mint_closed`**: Boolean. When `true`, no further mints are permitted, ever. May be flipped from `false` to `true` by the Title Owner. + +Wallets and explorers derive a plain-language supply state from `edition_cap` and `mint_closed` (open versus final, capped versus uncapped), with counts shown in Units divided by the title's `precision`. + +#### Title Singleton inner puzzle actions + +The inner puzzle accepts the following spend actions, identified by a selector in the solution. + +- **`mint_units(count, target_puzzle_hash)`**: Authorizes the TAIL to mint `count` Units (i.e., `count` mojos) and send them to `target_puzzle_hash` wrapped in the canonical Unit layer stack. The action derives the canonical Unit puzzle hash from the title's own immutable parameters (the TAIL Asset ID, the declared royalty and revocation layers, and `target_puzzle_hash`) and constrains issuance to coins bearing exactly that puzzle hash, so it cannot authorize a Unit assembled from a non-canonical stack (see *Mint-time stack binding* below). Requires `mint_closed == false` and, if `edition_cap` is set, `total_minted + count ≤ edition_cap`. Updates `total_minted` in the recreated singleton. +- **`melt_units(count)`**: Authorizes the TAIL to melt `count` Units presented in the same spend bundle. Melting requires both Title Singleton authorization and control of the Units, so neither Holder nor Issuer alone can destroy a Unit. This suits issuer-driven redemption (a ticket melted at venue scan, a carbon credit retired on use) while preventing an Issuer from unilaterally burning a Holder's Units. Does not decrease `total_minted`. Circulating Supply falls as the burned mojos leave the CAT supply. Titles that forbid melting omit this action. +- **`close_mint()`**: Sets `mint_closed` to `true`. Permanently disables further minting. +- **`add_uri(key, uri)`**: Prepends a URI to one of the three URI lists (`key` ∈ {`data`, `metadata`, `license`}). Does not modify any hash commitment. +- **`transfer_title(new_owner_p2_puzzle_hash, optional_new_did)`**: Transfers Title Singleton ownership. If the title has a `creator_did`, the spend follows the same DID-aware transfer pattern as NFT1. + +### Unit layer stack + +Each Unit is one mojo of a CAT2 coin whose TAIL is `everything_with_singleton` (CHIP-40), curried to the Title Singleton via the singleton module hash and the singleton struct (committing launcher ID `L`). CHIP-40's `NONCE` is fixed to zero, since each title has its own dedicated singleton and does not need the one-singleton-many-CATs case the nonce exists for. The Unit's Asset ID is therefore a deterministic function of `L` alone. The optional Fee and revocation layers, when the title declares them, nest inside: + +``` +├ CAT outer layer (cat_v2) +├── TAIL (everything_with_singleton, bound to Title Singleton L) +├──── Fee Layer (CHIP-56, present only if royalties) +├────── Revocation Layer (CHIP-38, present only if revocable) +├──────── p2 puzzle (holder's standard transaction puzzle) +``` + +Layers a title does not declare are omitted, so a minimal title is CAT/TAIL/p2 and a revocable royalty-free title places the revocation layer directly under the TAIL. The parameters curried into every Unit must match the values committed on the Title Singleton, giving wallets a complete verification path: from the Title ID, derive the expected stack and Unit puzzle hash, then check a candidate coin against it. + +**Mint-time stack binding.** A Unit's Asset ID is the hash of the TAIL alone, identical whether or not the optional layers are present, since those layers live beneath the CAT layer. Nothing at the CAT layer can distinguish a canonical Unit from one assembled with a missing or altered layer. Only the Title Singleton's `mint_units` action can: it recomputes the canonical Unit puzzle hash `H` from the title's immutable parameters and authorizes issuance only for created coins whose puzzle hash equals `H`. Because the `everything_with_singleton` TAIL delegates all issuance authorization to the Title Singleton, a coin minted with any other stack is never authorized and is not a Unit. The exact wiring (a committed announcement each issued coin asserts, or a direct assertion over created coins) is fixed by the reference inner puzzle. This derive-and-constrain step is the most security-critical code in the standard. + +**Persistence across transfers.** Mint-time binding establishes a Unit's stack. The Fee Layer, when present, must preserve it: Titled CAT relies on the CHIP-56 Fee Layer re-wrapping itself on every spend, including ordinary transfers, and rejecting any spend that drops it. A Fee Layer that let a plain transfer settle to a bare `p2` puzzle would let a holder strip the layer and produce a royalty-free coin sharing the title's Asset ID (see Security). + +### Precision and display + +- **Indivisible (`precision = 1`).** One Unit is one whole token. Wallets display an integer count, never decimals. +- **Divisible (`precision ≥ 10`).** A whole token is `precision` Units. Wallets display the Unit balance divided by `precision`, with `log10(precision)` decimal places. + +Both share the same Title Singleton, TAIL, and Unit-stack mechanics, differing only in the committed `precision` and the display rule. + +### Wallet recognition and display + +A wallet implementing this standard shall recognize a CAT coin as a Titled CAT Unit when: +1. The outer layer is `cat_v2` +2. The TAIL is `everything_with_singleton` committing some launcher ID `L` +3. `L` resolves to a Title Singleton with a valid inner puzzle +4. The Unit's inner stack matches the stack derived from the title's curried parameters + +When recognized, the wallet shall display the holding using the title's `name` and `ticker`, sourced from the Title Singleton, formatted at the title's `precision`. Wallets should verify `data_hash` against fetched content before rendering imagery, should surface the `creator_did` when present, and should display royalty configuration and revocability before any Offer involving Units is accepted. + +### Discovering a title from a Unit + +A wallet reads a coin's Asset ID cheaply from its parent's puzzle reveal, but not the launcher ID `L`. The Asset ID is the hash of the TAIL curried with `L`, and the TAIL reveal appears on-chain only at mint and melt, so recovering `L` from a transferred coin (the Alice-sends-Bob case) can otherwise require walking the lineage back to a mint. + +This is a performance problem, not a trust one. Because the Asset ID is a deterministic hash of `L`, any candidate `L` is self-verifying: a wallet recomputes the hash and checks it against the coin, so a memo, an index, or a peer can all supply `L` untrusted. Accordingly: + +- **Hint on mint and on transfer.** `mint_units` SHOULD hint each created coin with `L` (a memo), and a Titled-aware wallet SHOULD carry that hint forward when it sends Units, so an ordinary transfer to a Titled-aware recipient stays a direct lookup. This is a convention, not puzzle-enforced, since enforcing it would add a per-transfer layer and cost. +- **Resolve once, cache.** A wallet needs `L` for a given Asset ID only once and may cache it permanently, since the cached value re-verifies against the Asset ID. The cost is one-time per title, not per transfer. +- **Fallback.** Receiving Units with no hint (for example from a non-aware sender), a wallet recovers `L` by the lineage walk or from an index, both trustless, then caches. If `L` cannot be resolved at all, the Unit degrades safely to a generic CAT. + +A wallet MAY also subscribe to the Title Singleton's launcher coin for live metadata and supply updates, but a Titled CAT does not require subscription by default. + +### Offer integration + +Offers involving Titled CAT Units that carry a Fee Layer follow the CHIP-56 Offer integration pattern unchanged: the maker's wallet computes the royalty per trade price from the title's parameters, includes royalty settlement payments in the bundle, injects `SetCatTradeContext(trade_nonce, trade_prices)` into each Unit lock-leg spend, and the taker's wallet must include the royalty payments to complete the Offer. Units with no Fee Layer trade as ordinary CATs. Per-Offer royalty cost is bounded per title regardless of Unit quantity. + +### RPC calls + +Wallets may expose the following RPCs: + +- **`titled_cat_create`**: Create a title and optionally mint an initial batch (`name`, `ticker`, `precision`, the three URI/hash sets, optional `royalty_*`, `revocable`/`hidden_puzzle_hash`, `edition_cap`, `initial_mint_count`, `did_id`, `target_address`, `fee`). Returns `title_id`, `title_singleton_coin_id`, `tail_asset_id`. +- **`titled_cat_mint`** / **`_melt`** / **`_transfer`**: Mint, melt, or transfer Units (`title_id`, `count` or `amount`, `target_address`, optional `trade_price`/`fee`). Melt requires both Title Singleton authorization and control of the Units. +- **`titled_cat_close_mint`** / **`_add_uri`**: Close the mint, or prepend a URI (`title_id`, `key`, `uri`). +- **`titled_cat_get_info`** / **`_get_balances`**: Read a title's on-chain state, or the wallet's holdings aggregated per title. +- **`titled_cat_revoke`** *(revocable titles only)*: Revoke specified Units (`title_id`, `coin_ids[]`, `destination_puzzle_hash`). + + +## Test Cases + +Detailed test cases will ship with the reference implementation in `assets/chip-/tests/`. At minimum they will cover title creation across the precision range and option combinations, derived Unit puzzle hashes matching on-chain Units for each layer-stack variant, mint and melt rules (edition cap, `close_mint`, and the dual-authorization melt), ordinary transfers matching a bare CAT2 in cost, display correctness across `precision`, royalty-enforced Offer settlement, title ownership transfer and URI prepend, attempted mutation of any immutable field failing, revocable-title behavior, and safe degradation in a non-Titled-aware wallet. + + +## Reference Implementation + +The reference implementation will be provided in: + +- `chia-wallet-sdk/crates/chia-sdk-puzzles/puzzles/titled_cat_inner_puzzle.rue` will contain the Title Singleton inner puzzle, written in [Rue](https://github.com/Rigidity/rue) and compiled to CLVM. Following the convention established by the CHIP-56 Fee Layer (`fee_layer_v1.rue`), the `chia-sdk-puzzles` crate owns the Rue source alongside the embedded compiled bytes and serialized tree hash. +- `chia-wallet-sdk` will contain the typed Rust bindings and the driver layer for Title Singleton construction/spending and Unit parsing/construction. +- `chia-blockchain/chia/wallet/titled_cat/` will contain the wallet integration, RPC handlers, and indexing. + +The inner puzzle composes with the existing Singleton, CAT2, CHIP-40 TAIL, and CHIP-38 layer (Chialisp) and the CHIP-56 Fee Layer (Rue). Because each layer curries the hash of the layer it wraps, the source language is immaterial, the same mixed-language stack already in production for Revocable Fee CATs. + + +## Security + +### Duplicate Titled CAT names + +Titled CAT does not make names unique, and it does not decide which issuer is legitimate. An attacker may mint a Titled CAT with a `name` and `ticker` identical to a genuine one. Mitigations are the same as for NFT1 collections: wallets should surface the `creator_did` prominently, and wallets and marketplaces should maintain reputation overlays (verified DIDs, allowlists, denylists). + +### Precision display divergence + +A title commits `precision` on-chain, which is the correct fix for the display ambiguity that has dogged CAT2, where the 1000-mojo convention lives in wallet software as a default rather than on the coin. Every wallet that reads the title agrees on what a balance means. The residual risk is confined to the adoption window. A legacy or non-Titled-aware wallet does not read the committed `precision` and falls back to its own default, so for a title whose `precision` differs from that default it can display a different amount for the same Units than a Titled-aware wallet or explorer shows. This is dangerous in exactly the way the original CAT default was: a buyer could see an Offer priced against what looks like a far smaller or larger quantity than the maker intended and approve a trade they have misread. Safety depends on everyone agreeing on what they are looking at. Wallets and explorers SHOULD treat a recognized title's committed `precision` as authoritative and never override it with a local default, SHOULD warn when displaying Units of a title they cannot resolve, and Offer tooling SHOULD refuse to render an amount for a title whose `precision` it has not read from the chain. + +### Title Singleton key compromise or loss + +An attacker controlling the Title Singleton key (or its DID) can mint additional Units up to `edition_cap` (or without bound if uncapped), prepend URIs, transfer ownership, and close the mint. They cannot modify any immutable field or revoke held Units. Issuers should set an explicit `edition_cap`, close the mint once supply is reached, and custody the key in a vault, multisig, or hardware wallet, separate from the revocation hidden-puzzle key. + +Key *loss* is the opposite failure: with no controller the title freezes (no mint, melt, mint-close, URI prepend, or transfer), while existing Units keep transferring normally since ordinary transfers never touch the singleton. For a closed mint this is benign and even makes the cap more credible. For an open title it is a permanent loss of control, one more reason to close the mint once issuance is complete. + +### Creator DID over time + +The curried `creator_did` is immutable, but the DID singleton it names is not frozen by it. That DID can be transferred, abandoned, or compromised over the asset's life. The binding therefore proves which DID issued the title at creation, not who controls that DID today, exactly as for an NFT1 collection's creator DID. Wallets and curators should treat the DID as a provenance anchor whose reputation is tracked over time, not as a permanent endorsement. + + +## Additional Assets + +The following additional assets are anticipated as the reference implementation progresses: + +- `assets/chip-/titled_cat_inner_puzzle.rue`: canonical inner puzzle source (Rue), to be added during Draft. +- `assets/chip-/titled_cat_inner_puzzle.clsp.hex` and its tree hash: compiled CLVM bytes mirroring the source, following the CHIP-56 Fee Layer convention. + + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).