# Atomicals and ARC-20 > The working reference for Atomicals digital objects, ARC-20 tokens, and the Universe services that expose them. > Documentation version: 2026.08 > Home: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/ > Full content: /atomicals-and-arc-20/llms-full.txt > Page manifest: /atomicals-and-arc-20/manifest.json > Raw Markdown for any page: /atomicals-and-arc-20/raw/.md > Verified: 2026-08-31 ## How to read this documentation Three layers are never mixed, and every page states which one it describes: - Protocol behavior: what a pinned Atomicals validator revision does. - Universe implementation: what a Bitcoin Universe service actually exposes today. - Proposed or experimental: what exists but is not live. A protocol capability is not automatically a product feature. A product feature is not automatically protocol behavior. A proposal is not an implementation. ## Normative sources, in authority order 1. Executed source code, conformance tests, generated inventories, schemas, and runtime contracts at an exact revision. 2. Final or Living Atomicals Improvement Proposals. 3. The Atomicals reference implementation at an exact commit or release. 4. Official Atomicals protocol and CLI documentation. 5. Universe implementation documentation at an exact revision. 6. Third-party integrations, always non-normative. Explanatory prose, including this documentation, is never independent consensus. ## Pinned sources - Atomicals ElectrumX (protocol): https://github.com/atomicals/atomicals-electrumx at v1.5.2.0 - Atomicals JavaScript CLI (protocol): https://github.com/atomicals/atomicals-js at 1333565efbfe5ca4bdb8443a94d72e9f8534c2c4 - Atomicals protocol guide (protocol): https://github.com/atomicals-community/atomicals-guide at unversioned - Atomicals Improvement Proposals (protocol): https://github.com/atomicals-community/aips at be08d7856db7c55c2bfb7c2c08f88a25f1c781f8 - Universe ARC-20 index and Marketplace v1 authority (universe): https://github.com/bitcoinuniverseio/index-atomicals at 670030e500710aaef77410540768a87a138d8134 - Universe Atomicals NFT, Realm, and Subrealm index (universe): https://github.com/bitcoinuniverseio/index-atomicals-nfts-and-realms at 1d9109c68d95d5985632a60d6596b3612d3f6ef1 - Ordex marketplace contract (universe): https://github.com/bitcoinuniverseio/ordex at 2f7d8d3ec59fac534f545bf03ed0d41878f91a0e - Bitcoin Inscribe (universe): https://github.com/bitcoinuniverseio/inscribe at unversioned - Atomicals Virtual Machine interpreter (protocol): https://github.com/atomicals/avm-interpreter at c185e6216a3ea2cb2e011e508033ca535ece3472 - Ordinals and Runes reference indexer (ord) (protocol): https://github.com/ordinals/ord at 899e309424dd60e1c8065a7727a76d9b675a6ac4 - BRC-20 experiment specification (domo) (third-party): https://domo-2.gitbook.io/brc-20-experiment at unversioned - Bitcoin Stamps and SRC-20 reference indexer (third-party): https://github.com/stampchain-io/btc_stamps at 8a7365bf951a66f3a5e25dc15e8702f65b5d23d8 - Alkanes and Protorunes reference implementation (third-party): https://github.com/kungfuflex/alkanes-rs at 62511e9371a3f9e448841140c51cfe428cfcb955 - Counterparty reference library (third-party): https://github.com/CounterpartyXCP/counterparty-lib at 4f39fe25a266e44ccddd0eb50d97d2b8759d2b57 - RGB core consensus library (third-party): https://github.com/RGB-WG/rgb-core at 388d9c386117cf74f67f185b65adf946e775091c ## The ARC-20 model in seven statements 1. One ARC-20 unit is one satoshi in an output a validator recognises as coloured. 2. Supply is therefore measured in satoshis and bounded by real bitcoin. 3. Issuance is direct, fixed decentralised, or activation gated perpetual. 4. A ticker is a globally allocated name resolved to exactly one Atomical. It is not identity. 5. A transfer is an allocation over the transaction's inputs and outputs, in order. 6. Value that cannot be placed in an eligible output is destroyed. The transaction still confirms. 7. Coloured output totals can never exceed coloured input totals. ## Executed allocation vectors Engine: conformance/allocation.mjs, implemented from atomicals-electrumx-1.5.2.0 at 8df23747835c20230fc8b8097d469e7a1d97c3e0. Vectors: /atomicals-and-arc-20/conformance/vectors/arc20-allocation.json - clean-split: Both outputs are exactly covered, so nothing is left to place and nothing burns. - oversized-next-output: Output zero takes 700. The next output is 546 satoshis, larger than the 500 units left, so the remainder is destroyed. - exact-single-output: One output exactly equal to the coloured value takes everything. - first-output-too-large: Nothing can be placed at all, so the entire coloured value is destroyed. - too-few-outputs: Every output is covered but value is still left over, so the leftover burns. - unspendable-output-skipped: A provably unspendable output is passed over and consumes no coloured value. - combine-two-lots: Two coloured inputs of the same token are summed before allocation and land in one output. - two-tokens-sequential-slots: The first token fills the outputs it needs, then the next token starts after the last slot the first one used. - two-tokens-non-clean-fallback: When the sequential assignment cannot be made cleanly, the reference builder restarts every token from output zero. Both tokens then contend for the same outputs and value burns. - dust-remainder-burns: Sending 1000 units from a 1200 unit lot with a 200 satoshi change output fails, because 200 is placed only if it fits after the 1000 is taken. Here it does fit, so nothing burns. Compare with the next case. - change-output-too-large: The same intent with a 546 satoshi change output destroys the 200 unit remainder, because 546 does not fit in 200. - custom-coloring-partial-fill: With custom coloring active the builder attaches an output even when the value does not cover it fully, and the last output receives only what is left. - suite-exact-single-output: The token exactly fills the only output, so nothing is left over and the assignment is clean. - suite-partially-colored-carry-forward: Since height 848484 an output can carry fewer token units than satoshis. The 500 units land on an 11000 satoshi output and nothing burns. Reported as not cleanly assigned because the output is only partly coloured. - suite-consolidation-burn: The classic consolidation accident: everything beyond the first output is destroyed. - suite-output-over-balance: Under exact-cover rules an output has to be fully covered. Being one satoshi short colours nothing at all. The same shape under current rules colours the output partially and burns nothing, which is why the rule changed. - suite-one-unit-over: The single leftover unit is the miner fee, and it is burned token supply. - suite-merged-inputs-single-output: The pool is 1455, the output takes 1454, and the remaining unit is burned. - suite-no-atomicals: Spending no token-bearing input produces an empty blueprint. An implementation must not fabricate assignments for an uncoloured transaction. - fee-taken-from-colored-value: The outputs total 200 satoshis less than the coloured input, and those 200 units are destroyed rather than returned. Pay the fee from a plain bitcoin input instead. - only-unspendable-outputs: Unspendable outputs are skipped by regular assignment, so a transaction whose only output is an OP_RETURN leaves the balance nowhere to land. - split-skip-amount: The y payload names satoshis to pass over before a token starts colouring, which is how two tokens sharing one input get separated. Here output 0 satisfies the skip, the token colours output 1, and the value beyond it burns. - custom-color-over-request-clamped: The payload asks for more than either token holds. Each request is clamped to the output value and then to the remaining balance, so no inflation is possible. - custom-color-unassigned-value-burns: The payload directs 400 units at output 0 and says nothing about the rest, so the remaining 600 units are destroyed. Custom colouring places value explicitly; it does not carry a remainder forward. ## What is never claimed here - No price, market, ranking, investment, legal, or tax statement. - Metadata is never authenticity. A ticker is never creator identity. A listing is never ownership. - An indexer result is version scoped, never consensus. - A configured service is never automatically ready. - A proposal is never an implemented feature. ## Machine readable outputs - /atomicals-and-arc-20/llms.txt - /atomicals-and-arc-20/llms-full.txt - /atomicals-and-arc-20/manifest.json - /atomicals-and-arc-20/specification.md - /atomicals-and-arc-20/sources.md - /atomicals-and-arc-20/contracts/openapi/arc20.json - /atomicals-and-arc-20/contracts/openapi/atomicals-nfts-realms.json - /atomicals-and-arc-20/contracts/openapi/marketplace-v1.json - /atomicals-and-arc-20/contracts/schemas/common.schema.json - /atomicals-and-arc-20/contracts/source-manifest.json - /atomicals-and-arc-20/contracts/cli-inventory.json - /atomicals-and-arc-20/contracts/aip-registry.json - /atomicals-and-arc-20/contracts/avm-opcodes.json - /atomicals-and-arc-20/contracts/ecosystem.json - /atomicals-and-arc-20/conformance/vectors/arc20-allocation.json - /atomicals-and-arc-20/changelog.xml - /atomicals-and-arc-20/sitemap.xml --- # Atomicals and ARC-20 URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/ Page ID: home Applicability: editorial Authority: none Networks: mainnet Sources: none Verified: 2026-08-31 ## Where the protocol stands today ## Start where you are ## Learn, simulate, verify, reproduce One journey covers everything this platform does. Understand a rule in the protocol pages. Replay it deterministically in a browser tool. Check an implementation against the executed conformance vectors. Then reproduce the whole workflow yourself with the CLI and the pinned sources. ## Everything on the platform ## Why every claim carries a revision This platform separates three things that other material blurs together: A protocol capability is not automatically a product feature. Each page states which layer it describes, at which source revision, and when that was last checked. The context strip under the site header repeats it on every page, and the drawer behind it opens the exact source paths. ## Versions and verification See [Versions](releases/versions/) for the full manifest and how drift is handled. ## AVM is beta The AVM interpreter material on this platform describes a pinned beta revision. Executing samples locally is supported. Nothing here is evidence of deployment by Bitcoin Universe, and no page will describe AVM as live or production-ready until a verified source set says so. Start at [AVM overview](protocol/avm/overview/). ## Built for machines too Every page has a raw Markdown twin, a stable page ID, and a source record. The site also publishes `llms.txt`, `llms-full.txt`, a page manifest, JSON Schemas, OpenAPI documents, and a read-only MCP server so an agent can read this documentation without scraping HTML. See [AI and agent access](reference/ai-access/). ## What we will not tell you No price talk. No rankings. No investment, legal, or tax advice. No claim that a ticker proves who made something, that metadata proves authenticity, or that a marketplace listing proves ownership. Where evidence is missing, the page says so instead of guessing. --- # AI and agent access URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/ai/ Page ID: ai Applicability: editorial Authority: none Networks: mainnet Sources: atomicals-electrumx-1.5.2.0 Verified: 2026-09-02 Limitations: - Ask Atomicals is deterministic retrieval over this documentation. It is not a model and it does not generate text. - Answers cite the verified source set only. Nothing here blends revisions. Ask Atomicals retrieves sentence-level passages from this documentation and quotes them with citations. It never invents a response to fill an empty result, and it runs entirely in your browser with no external request by default. ## Install the Agent Skill The Agent Skill packages the same routing, source rules, and safety constraints for coding agents: ``` # Download the release archive from the releases page, or build it from source: npm run skills:validate # -> dist-skills/atomicals-and-arc20-skill.tar with a sha256 checksum ``` The skill instructs agents to answer only from pinned sources, to distinguish protocol, implementation, proposal, and experimental claims, and to refuse key collection and mainnet mutation. See skills/atomicals-and-arc20/SKILL.md in the repository. ## Connect an MCP client The documentation publishes two MCP transports built on one shared core: **Local stdio** (works offline against the built artifacts): ```json { "command": "npx", "args": ["@bitcoin-universe/atomicals-docs-mcp", "--artifacts", "/path/to/dist"] } ``` **Hosted Streamable HTTP** (stateless, read-only): ```json { "url": "https://mcp.bitcoinuniverse.io/atomicals-and-arc-20/mcp", "transport": "streamable-http" } ``` Configuration snippets are generated and tested in CI for Codex, Claude Code, Cursor, and generic clients: see [reference/mcp](/reference/mcp/). The service performs no mutations, no outbound requests, and holds no credentials; its capability manifest lives at `/.well-known/mcp-manifest.json`. ## Page-level AI actions Every page's action menu carries copy actions for source-pinned context, canonical citations, workflow context, SDK examples, MCP configuration, and raw Markdown. Agents get exactly the context a human reader sees. --- # Contribute URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/contribute/ Page ID: contribute/index Applicability: editorial Authority: none Networks: none Sources: none Verified: 2026-08-31 ## Where content belongs | Content | Repository | | --- | --- | | Atomicals protocol, ARC-20, NFTs, Containers, Realms, AVM, AIPs | This repository | | Public developer and API documentation for Universe Atomicals services | This repository | | Public schemas, OpenAPI, examples, source ledger, conformance, LLM files, MCP package | This repository | | Private architecture, deployment, credentials handling, capacity, monitoring, recovery | `docs-dev-atomicals` and `docs-dev-atomicals-nfts-and-realms` | | Core-specific user workflows | `docs-core` | | Inscribe-specific product workflows | `docs-inscribe` | Passwords, tokens, private keys, seed phrases, bearer credentials, HMAC secrets, private RPC URLs, private indexer origins, SSH endpoints, private hostnames, database credentials, internal network topology, recovery secrets, operator-only command history, or customer data. Secret scanning runs in CI, and it is the last line, not the first. ## The one rule that matters most **Never present protocol behavior and Universe behavior as the same thing.** Every page declares its applicability in frontmatter, and that declaration drives the panel readers see. ## Quick start ```bash npm install npm run generate npm run check npm test npm run build ``` `npm run generate` regenerates every derived artefact. If it changes a committed file, commit that change: CI fails when generation leaves the repository dirty. ## Reporting a problem | Template | Use it for | | --- | --- | | Documentation defect | A typo, a broken link, an unclear passage | | Incorrect protocol claim | A statement that does not match the source | | API mismatch | A documented route that does not match the runtime | | Translation defect | A wrong or stale translation | | Accessibility defect | Anything that fails WCAG 2.2 AA | | Broken external integration | A link or an ecosystem record that is wrong | | New AIP | A proposal to add to the register | | Source version update | A pinned revision that should move | Include the page ID from the source panel. It is stable across locales and versions. --- # Adding an API URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/contribute/adding-an-api/ Page ID: contribute/adding-an-api Applicability: editorial Authority: none Networks: none Sources: none Verified: 2026-08-31 ## The five artefacts 1. **A sanitized route inventory** in `contracts/routes/`, exported by the runtime repository. 2. **An OpenAPI 3.1 document** in `contracts/openapi/`. 3. **Schema definitions** in `contracts/schemas/common.schema.json`, reused rather than duplicated. 4. **A reference page** under `reference/api/` that renders the inventory and explains the guarantees. 5. **A source manifest entry** so the revision is recorded. ## The checks that bind them | Check | What it prevents | | --- | --- | | Inventory equals documented paths, in both directions | A documented route that does not exist, and a runtime route that is undocumented | | Inventory revision equals the manifest revision | An inventory drifting from its recorded source | | Operation identifiers unique across all documents | Collisions in a generated client | | Every operation has a summary, a declared tag, and responses | A stub masquerading as documentation | | Every response example validates against its schema | An example that would never be returned | | Deprecated routes name a replacement | A dead end | | No production host or routable address | A credential pointed at production from a browser | ## Order of work 1. Export the sanitized inventory from the runtime repository. It must contain no hostname, credential, or internal topology. 2. Add the source manifest entry with the exact revision. 3. Commit the inventory here. 4. Write the OpenAPI document, reusing schema definitions. 5. Run `npm test`. The inventory check will tell you exactly what is missing on either side. 6. Write the reference page. 7. Regenerate the client with `npm run generate`. ## Schema rules - Satoshi and protocol quantities are decimal strings with a pattern. Never numbers. - Identifiers carry their pattern. An Atomical ID and a location are different types. - Every definition carries a description, and at least one example where a value is representable. - Reuse before adding. A near-duplicate definition is a future inconsistency. ## Internal routes Document them, marked as internal and not publicly reachable, so integrators understand the boundary. Never include a credential value, a hostname, or anything that would let someone reach them. ## Examples Every example must validate against its own schema, and CI enforces it. An example is documentation people copy, so a wrong one is worse than none. --- # Conformance vectors URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/contribute/conformance-vectors/ Page ID: contribute/conformance-vectors Applicability: editorial Authority: none Networks: none Sources: none Verified: 2026-08-31 ## The rule A vector is evidence only if it is executed. This documentation never publishes an unexecuted vector as conformance material. ## Where the pieces live | Piece | Path | | --- | --- | | Engine | `conformance/allocation.mjs` | | Vectors | `conformance/vectors/arc20-allocation.json` | | Tests | `tests/conformance-allocation.test.mjs` | | Rendered table | `site/src/components/VectorTable.astro` | The prose, the [allocation visualizer](/tools/allocation-visualizer/), and the tests all call the same engine, so they cannot disagree. ## Adding a case 1. Derive it from the source. Name the exact functions and lines it comes from. 2. Add it to the vector file with an `id`, a `title`, a `description`, `options`, `inputs`, `outputs`, and `expected`. 3. Run `node --test tests/conformance-allocation.test.mjs`. 4. If it fails, decide which is wrong: your expectation, or the engine. If the engine is wrong against the source, fix the engine and say so in the pull request. 5. Reference the case from the relevant page with ``. ## Changing the engine The engine is implemented directly from the pinned reference revision. Changing it is a change to what this documentation claims the protocol does. A pull request that changes it must: - name the exact source functions and lines the change follows; - keep every existing vector passing, or explain precisely why one changed; - update the source manifest if the pinned revision moved. ## What not to add - A case whose expectation you assumed rather than derived. - A case that needs a live chain or a live service. Document it as an expectation on the [conformance page](/reference/conformance/) instead, in the coverage table. - A case copied from another repository's vector set. Link that set rather than duplicating it. --- # Content model URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/contribute/content-model/ Page ID: contribute/content-model Applicability: editorial Authority: none Networks: none Sources: none Verified: 2026-08-31 Every page carries a `provenance` block. It is validated by the content schema, and it drives the panel readers see. Nothing in the panel is hand written next to the content. ## Required fields | Field | Meaning | | --- | --- | | `pageId` | Stable identity. Never reused, never renamed without a redirect | | `area` | One of start, protocol, guides, develop, reference, tools, ecosystem, releases, contribute | | `audience` | Who the page is for. At least one value | | `applicability` | Which layer the page describes. See below | | `authority` | What kind of source establishes it | | `networks` | Which networks the page applies to. At least one | | `verified` | The date the content was last checked, as an ISO date | ## Optional fields | Field | Use | | --- | --- | | `sources` | Entries from the source manifest, with an optional path key and note | | `docsVersion` | The documentation version. Defaults to the current one | | `activation` | The activation boundary, when the behavior has one | | `owner` and `reviewers` | Ownership | | `tags` | Grouping | | `limitations` | Known limitations, shown in the panel | | `deprecated` | Since, reason, replacement, and sunset | | `translationSourceHash` | On a translation only. The hash of the English source it was made from | | `hideProvenance` | For purely navigational pages with no source-sensitive claim | ## Applicability values | Value | Use when the page describes | | --- | --- | | `protocol-behavior` | The Atomicals protocol at a pinned revision | | `universe-implementation` | What a Universe service actually does today | | `experimental` | Beta or unreleased behavior | | `proposed` | A proposal, with nothing implemented by virtue of existing | | `deprecated` | Something still reachable but scheduled for removal | | `unavailable` | A capability no Universe surface exposes | | `third-party` | Material operated by someone else, non-normative | | `editorial` | Navigation or explanation with no source-sensitive claim | Choosing `protocol-behavior` for something a Universe service does, or the reverse, is the most serious content error possible here. It is the failure this whole system exists to prevent. ## Authority values | Value | Meaning | | --- | --- | | `executed-source` | Backed by executed code or tests at a pinned revision | | `aip` | An Atomicals Improvement Proposal | | `reference-implementation` | The Atomicals reference implementation | | `official-documentation` | Official Atomicals documentation | | `universe-implementation` | Universe implementation documentation | | `third-party` | Non-normative third-party material | | `none` | No normative source. Navigation only | ## Rules CI enforces 1. Every `sources` entry names an id that exists in `contracts/source-manifest.json`. 2. Every `verified` date is a valid ISO date, and a date older than 180 days is flagged in the panel. 3. Every `pageId` is unique across the site. 4. A translated page must carry `translationSourceHash`. 5. Every required localised page exists in every configured locale. 6. Code blocks and identifiers must be identical between a translation and its English source. ## Writing rules - Say which layer a statement describes, always. - Pin a source revision for anything version sensitive. - State a limitation rather than omitting it. - Never call a proposal implemented. - Never present metadata as authenticity, a ticker as identity, or a listing as ownership. - No price talk, rankings, investment, legal, or tax advice. - Never use the words guaranteed, risk-free, backed, collateralised, price floor, or redemption as claims. --- # Ecosystem records URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/contribute/ecosystem-records/ Page ID: contribute/ecosystem-records Applicability: editorial Authority: none Networks: none Sources: none Verified: 2026-08-31 ## The evidence rule A record's availability state comes from a reachable source, checked on a date. Nothing else counts. | Not evidence | Why | | --- | --- | | Another directory lists it | That directory has the same problem | | It was active last year | Last year is not now | | A social media post | Not a reachable source for a service state | | It looks abandoned | Looking abandoned is not evidence of anything | | A request timed out | That produces `unreachable`, nothing stronger | ## Required fields | Field | Notes | | --- | --- | | `id` | Stable, kebab case | | `name` | As the operator writes it | | `category` | One of the registry categories | | `official` | True only for Atomicals project resources | | `operator` | Who runs it | | `supports` | Which Atomicals products | | `networks` | Which networks | | `custody` | self-custody, custodial, non-custodial-service, or not-applicable | | `repository` and `url` | Where verifiable. Null where not | | `availability` | One of the declared states | | `evidence` | What established the state, specifically | | `lastVerified` | The date it was checked | | `securityNotes` | What a reader should know before using it | | `deprecation` | Null, or the operator's own statement | ## The states `verified-active`, `degraded`, `unreachable`, `deprecated`, `closed`, `unknown`. Their exact meanings are on the [registry](/ecosystem/). Three rules: 1. A network failure produces `unreachable`, never `deprecated` or `closed`. 2. Conflicting evidence produces `unverified`, never a guess. 3. Only an operator's own reachable statement produces `deprecated` or `closed`. ## Why a gap is acceptable The registry currently has no individual third-party marketplace or explorer records, because none were checked against a reachable source during the review. That gap is stated on the page. A guessed record is worse than a missing one, because a reader acts on it. ## Adding a record Open a pull request adding the entry to `contracts/ecosystem.json`, with the evidence and the date. CI validates the shape. A human checks the evidence. ## No endorsement Listing is not endorsement. A `securityNotes` field is required, and it should say what a reader needs to know, including custody and any known limitation. --- # Releasing URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/contribute/releasing/ Page ID: contribute/releasing Applicability: editorial Authority: none Networks: none Sources: none Verified: 2026-08-31 ## The gates, in order | Gate | Proves | | --- | --- | | Clean install from the lockfile | The dependency set is reproducible | | Type check | The site and packages type check strictly | | Generation is clean | Every derived artefact matches its source. A dirty tree fails | | Contract checks | OpenAPI, schemas, inventories, and examples all agree | | Conformance vectors | The documented protocol behavior is executed, not asserted | | Unit tests | Loaders, manifests, translations, and generated artefacts behave | | Production build | The site builds statically, with search | | Link and anchor checks | No broken internal link, anchor, image, or duplicate page ID | | Compatibility route checks | Every preserved legacy route exists and is generated | | Accessibility checks | No axe violation across the required matrix | | Performance budgets | The budgets fail the build, they do not merely report | | Secret scanning and dependency audit | No secret, no high or critical vulnerability | | Browser tests | Navigation, search, tools, deep links, and locales work | | Visual review | Changed baselines are reviewed, never auto-accepted | Each is a separate job, so a failure names the thing that failed rather than the last command in a chain. ## Generation is a gate, not a step `npm run generate` regenerates the CLI inventory, the AIP registry, the AVM opcodes, the legacy compatibility artefacts, the LLM files, the page manifest, the sitemap, and the changelog feed. CI runs it and fails if the working tree is dirty afterwards. That is what makes "generated artefacts are reproducible" a fact rather than a hope. ## Runners CI runs only on approved self-hosted runners or the approved cloud configuration. GitHub-hosted runner labels are never used, and a workflow that introduces one fails review. ## Private source checks Public pull request validation never depends on a private repository credential. Committed sanitized manifests and public contracts are enough to validate an untrusted pull request. A separate trusted, scheduled workflow compares against private sources with a least-privilege read-only credential, and never runs with secrets on untrusted fork code. Detected drift opens or updates a concrete issue or pull request with the changed contract, the affected pages, and the source revision. No automated job rewrites normative prose and merges it without review. ## Deployment The built site is committed at the repository root and served from the default branch. That gives three properties: 1. The deployed bytes are in version control. 2. The Inscribe submodule receives the same artefacts the site serves. 3. Deployment does not depend on a build running at publish time. ## After deployment Verify the real origin, not a local build: status codes, canonical links, navigation, search, raw Markdown, LLM files, compatibility routes, contract downloads, locale routes, mobile behavior, accessibility, and performance. A local build passing is not a release. --- # Translations URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/contribute/translations/ Page ID: contribute/translations Applicability: editorial Authority: none Networks: none Sources: none Verified: 2026-08-31 ## English is the source Every translation is made from the English page, and records the hash of the English body it was made from in `translationSourceHash`. When the English body changes, the recorded hash no longer matches, and the site shows a notice on the translated page automatically. Nobody has to remember to flag it. ## The required set Eight locales are configured: English, Portuguese, Spanish, French, Japanese, Russian, Simplified Chinese, and Traditional Chinese. A defined set of core pages must exist in every locale, listed in `site/src/data/site.json` under `requiredLocalizedPages`. CI fails when one is missing. Pages outside that set fall back to English, and Starlight shows a fallback notice, which is honest rather than pretending a translation exists. ## What is never translated | Never translated | Why | | --- | --- | | Operation names such as `ft`, `dft`, `dmt`, `nft`, `mod`, `sl` | They are protocol literals | | Schema property names | They are wire format | | Route paths and query parameter names | They are the contract | | Header names | They are the contract | | Error codes | Clients branch on them | | Hashes, transaction ids, Atomical ids | They are data | | Code blocks, in full | Copying a translated identifier breaks the reader's build | | Product and repository names | They are names | CI compares code blocks between a translation and its English source and fails on a mismatch. ## Shared glossary The [glossary](/start/glossary/) is the reference for every term. Translate a term the same way everywhere, and add the English term in brackets on first use in a page when the translation is not already established. ## Prohibited mistranslations | English | Do not translate as | | --- | --- | | burn | spend, lose, send | | candidate | owner, holder | | verified winner | applicant, requester | | coloured output | any word implying it is ordinary bitcoin | | ready | running, live, configured | | deprecated | removed, deleted | | proposed | planned, upcoming, coming soon | | partial coverage | complete, full | Each pair exists because the wrong word changes what a reader will do. ## Adding a translation 1. Copy the English page into the locale directory. 2. Translate the prose. Leave every code block, identifier, and route untouched. 3. Compute the English body hash and record it in `translationSourceHash`. 4. Keep the same `pageId`. 5. Run `npm run check`. ## Reviewing a translation - Does every status word still mean exactly what it means in English? - Are all code blocks byte-identical to the English source? - Are the safety warnings as strong as the English ones? A softened warning is a defect. - Does it read as though a person wrote it? Do not merge an obviously machine-produced translation with inconsistent terminology. --- # Architecture overview URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/develop/ Page ID: develop/index Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals, universe-index-atomicals-nfts-and-realms Verified: 2026-08-31 Limitations: - Deployment topology, credentials, capacity, and monitoring are private operational material and are not published here. ## The services | Service | Authoritative for | Read | | --- | --- | --- | | Atomicals ElectrumX | Protocol interpretation of blocks | [ElectrumX reference](/reference/electrumx/) | | ARC-20 index and feed | Verified tickers, holders, confirmed activity | [ARC-20 API](/reference/api/arc20/) | | NFT and Realm index | Plain NFTs, Realms, Subrealms | [NFT and Realm API](/reference/api/atomicals-nfts-realms/) | | Marketplace v1 authority | Listings, reservations, purchases, settlements | [Marketplace v1](/reference/api/marketplace-v1/) | | Ordex contract | Marketplace contract, SDK, conformance | [Ordex](/reference/api/ordex/) | All Bitcoin and Atomicals data comes from Universe-operated nodes, indexes, and databases. No third-party blockchain data provider sits in any production path. ## What each index is not - Not a validator. Both indexes project what an Atomicals provider reports. - Not complete. Each declares its projection, and each excludes asset kinds on purpose. - Not final. Every answer is scoped to a generation and a chain position. ## Projections The NFT and Realm read model declares its projection explicitly: - **Included:** plain NFT, Realm, Subrealm. - **Excluded:** FT, DFT, Container, DMItem. Fungible tokens are served by the ARC-20 side. Containers and DMINT items are not projected by either. ## Read next | Topic | Page | | --- | --- | | Where data comes from and what it costs to trust | [Data flow](/develop/data-flow/) | | How to decide which answer to believe | [Source of truth](/develop/source-of-truth/) | | Generations, checkpoints, and rollback | [Consistency and reorgs](/develop/consistency-and-reorgs/) | | Identifiers, networks, and protocol IDs | [Identifiers and networks](/develop/identifiers-and-networks/) | | Authentication across the services | [Authentication](/develop/authentication/) | | Error envelopes | [Errors](/develop/errors/) | | Cursors and paging | [Pagination and cursors](/develop/pagination-and-cursors/) | | Safe retries and tracing | [Idempotency and request IDs](/develop/idempotency-and-request-ids/) | | Readiness against configured | [Readiness and freshness](/develop/readiness-and-freshness/) | | Rate limits where they exist | [Rate limits](/develop/rate-limits/) | | Versioning and deprecation | [Versioning and deprecation](/develop/versioning-and-deprecation/) | | Moving between versions | [Migration](/develop/migration/) | --- # Authentication URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/develop/authentication/ Page ID: develop/authentication Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals, universe-index-atomicals, universe-index-atomicals-nfts-and-realms Verified: 2026-08-31 Limitations: - No credential values appear in this documentation. Secrets are provisioned out of band and are never published. Every token, secret, and key named on this page is a name, not a value. Values are provisioned out of band. Never place one in browser-delivered code, a query string, or a public repository. ## The scheme per surface | Surface | Scheme | | --- | --- | | Liveness, readiness, version | None | | ARC-20 feed | Bearer token | | Operator poll and refresh | An admin token header | | NFT and Realm read routes | None on the routes themselves | | NFT and Realm refresh and rollback | An admin token header | | Token explorer pages | Per-protocol authorisation | | Marketplace reads | Bearer token | | Marketplace public mutations | Bearer token plus a replay-resistant request signature | | Marketplace owner actions | A short lived owner session, issued after a BIP-322 proof | | Marketplace internal routes | A separate internal bearer and a separate internal signature | ## The Marketplace request signature Public mutations use a lowercase hex HMAC-SHA256 over a fixed string: ```text v1\n{timestamp}\n{nonce}\n{method}\n{path}\n{sha256(exact_body_bytes)} ``` Headers: `X-Marketplace-Key-Id`, `X-Marketplace-Timestamp`, `X-Marketplace-Nonce`, and `X-Marketplace-Signature`. Mutations also require `Idempotency-Key`. Three properties follow: - The signature covers the exact body bytes, so re-serialising the body invalidates it. - The timestamp and nonce make replay detectable. - The path is covered, so a signature cannot be moved between routes. ## Owner sessions An owner session is issued only after a BIP-322 simple proof for P2WPKH or key-path P2TR. It proves control of the address without moving anything, and it is short lived by design. An owner session is not a signature on a settlement transaction. Those are separate steps. ## Separation of secrets The services use distinct secrets for distinct jobs: a source bearer, an admin token, a cursor signing secret, a request HMAC secret, an internal execution bearer, and an internal execution HMAC secret. The two HMAC secrets must be distinct. Reusing one secret across two jobs collapses two independent controls into one. ## What must never happen - A bearer token in browser-delivered code. - A credential in a query string or a URL fragment. - An internal route exposed to the public internet. - A production credential in an API explorer. - A secret in a repository, a build artefact, or a log line. The [API explorer](/tools/api-explorer/) in this documentation defaults to schema and copy-only examples for exactly this reason. ## Source [Marketplace v1](/reference/api/marketplace-v1/) and [errors](/develop/errors/). --- # Consistency and reorgs URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/develop/consistency-and-reorgs/ Page ID: develop/consistency-and-reorgs Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals-nfts-and-realms, universe-index-atomicals Verified: 2026-08-31 ## Generations A generation is an immutable snapshot of an index at one consistent chain position. Answers are served from the active generation, and the identifier is returned with every response. Why immutability matters: a consumer that recorded a generation identifier can tell the difference between "the data changed" and "I am looking at a different snapshot". ## Checkpoints A checkpoint records the chain position a generation was built from, including block hashes. When the chain moves under the index, the checkpoint is what makes a correct rebuild possible. ## Reorg handling The ARC-20 side rescans each changed tip under identical before and after Bitcoin and Atomicals tips. Missing unfinalised events produce explicit invalidations. Changes to finalised blocks, events, or ticker identity fail closed rather than being silently accepted. Historical headers outside the configured reorg window are reused from a durable journal. The NFT and Realm side publishes a complete generation only when the declared source-row coverage is exact, and rejects a count shrink or an incomplete page. A generation spanning more than one provider tip is published explicitly as mixed and stale. ## Rollback An operator can roll the active pointer back to an earlier generation. That is an operational action, not a consumer action, and it changes which snapshot readers see. A consumer detects it by the generation identifier changing to one it has seen before. ## What a consumer must do 1. Read the generation identifier and indexed height with every answer. 2. Store both alongside any cached result. 3. Treat a generation change as a signal to re-read, not as noise. 4. Never merge results from two different generations into one view. 5. Do not act on a result computed inside the reorg window for a significant amount. 6. Handle `stale` and `mixedTip` explicitly rather than rendering the numbers anyway. ## Pagination across a reorg A cursor refers to a position inside a generation. When the generation changes, the cursor is no longer valid for the new one. Restart the listing rather than continuing with a stale cursor. See [pagination and cursors](/develop/pagination-and-cursors/). ## Source [Confirmation and reorgs](/protocol/core/confirmation-and-reorgs/). --- # Data flow URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/develop/data-flow/ Page ID: develop/data-flow Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals-nfts-and-realms, universe-index-atomicals Verified: 2026-08-31 ## The hops 1. **Bitcoin Core** produces blocks. Universe operates the node. 2. **Atomicals ElectrumX** reads blocks and applies the protocol rules. This is where protocol interpretation happens. 3. **A Universe index** scans the provider, builds a materialised read model, and publishes it as an immutable generation. 4. **A product** reads the index through a public API. Each hop can be behind the one before it. A consumer must know which position each answer came from. ## What can be stale, per hop | Hop | Can be stale because | | --- | --- | | Bitcoin Core | Normal block propagation | | ElectrumX | Still processing a block, or a reorg | | Index | Scan in progress, or generation build in progress | | Product cache | Cached an answer without its generation | The last row is the one under your control, and the one most often responsible for a wrong screen. ## What the ARC-20 side guarantees The scan is all or nothing. Holder rows are aggregated by address and must sum exactly to circulating supply. A mismatch, a null address, a truncated page sequence, a changing declared total, or a changing chain tip aborts the entire poll. No partial authoritative snapshot is ever committed. That is why an answer is either complete or absent, rather than plausible and wrong. ## What the NFT and Realm side guarantees NFT, Realm, and Subrealm rows share one provider scan, one generation, one checkpoint, and one active pointer. Publication requires exact final declared source-row coverage and rejects a count shrink or an incomplete page. A generation that spans more than one provider tip is published explicitly as mixed and stale, without a single indexed height, rather than pretending to be consistent. ## What to record with every answer | Field | Why | | --- | --- | | Generation identifier | So you can detect a rebuild | | Indexed height | So you know the chain position | | Source revision | So a behavior difference is explainable | | Request identifier | So a support question is traceable | | Stale and mixed-tip flags | So you know whether to act on it | Storing an Atomicals result without those five makes any later disagreement unexplainable. ## Source [Consistency and reorgs](/develop/consistency-and-reorgs/) and [readiness and freshness](/develop/readiness-and-freshness/). --- # Errors URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/develop/errors/ Page ID: develop/errors Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals-nfts-and-realms Verified: 2026-08-31 ## The envelope Errors are returned as JSON with a stable shape: a machine-readable code, a human-readable message, and the request identifier. The request identifier is the field to log. ## Status codes and what they mean | Status | Meaning | Retry | | --- | --- | --- | | 400 | The request was malformed or a value was invalid | No, fix the request | | 401 | Missing or invalid credentials | No | | 403 | Authenticated but not permitted | No | | 404 | Route not found, or the asset is not in the active generation | Depends. Check readiness first | | 405 | Method not allowed on a known route | No | | 409 | A conflict, such as an idempotency mismatch | No, inspect the conflict | | 414 | The request URL is too long | No | | 429 | Rate limited, where a limit is implemented | Yes, with backoff | | 500 | An unexpected server error | Yes, with backoff | | 503 | Not ready, unavailable, or degraded | Yes, after checking readiness | ## The 404 that is not an error A 404 on an asset route can mean the asset does not exist, or that it is not in the active generation, or that it is outside this projection. Those are different. Check `/ready` and the projection before concluding anything is missing. See [unavailable index against empty balance](/guides/unavailable-indexer-vs-empty-balance/). ## Named codes you will see | Code | Meaning | | --- | --- | | `NFT_NOT_FOUND` | No plain NFT with that Atomical ID in the active generation | | `REALM_NOT_FOUND` | No Realm or Subrealm with that Atomical ID in the active generation | | `ASSET_NOT_FOUND` | No asset of any projected type with that Atomical ID | | `NFT_MEDIA_NOT_FOUND` | The asset exists, the requested media field does not | | `METHOD_NOT_ALLOWED` | Known route, wrong method. The `allow` header names the right one | | `METRICS_DISABLED` | Metrics are turned off on this deployment | | `NOT_FOUND` | The route itself does not exist | ## Validation errors Validation failures carry a specific reason rather than a generic message. A malformed Atomical ID, an out-of-range page, an unsupported `kind` filter, and a malformed media field name each report what was wrong. Unicode and IDNA name errors are surfaced explicitly rather than being flattened into a generic validation failure. ## What a client should do 1. Log the request identifier with every failure. 2. Distinguish client mistakes from service states before retrying. 3. Retry only 429, 500, and 503, with exponential backoff and jitter. 4. On 503, read `/ready` and use its reason rather than retrying blindly. 5. Never treat 404 as "the asset was destroyed". ## Source [Readiness and freshness](/develop/readiness-and-freshness/) and [NFT and Realm API](/reference/api/atomicals-nfts-realms/). --- # Idempotency and request IDs URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/develop/idempotency-and-request-ids/ Page ID: develop/idempotency-and-request-ids Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals, universe-index-atomicals-nfts-and-realms Verified: 2026-08-31 ## Request identifiers Every response carries a request identifier. It is the field to log, and the field to quote in a support question. Log it on success as well as on failure. A wrong result you cannot trace is much harder to explain than a failure you can. ## Idempotency keys Marketplace mutations require an `Idempotency-Key`. It makes a retry safe: the same key for the same request returns the same result rather than performing the action twice. Rules: 1. Generate one key per logical action, not per HTTP attempt. 2. Reuse it for every retry of that action. 3. Never reuse it for a different action. 4. Store it with your own record of the action, so a retry after a restart uses the same key. 5. Treat a conflict as a signal that the key was reused for different content, and inspect rather than retrying. ## Idempotency scope Keys are scoped per protocol lane. The four Marketplace authorities are isolated, so a key used in one lane does not collide with the same key in another. ## Replay protection Public mutations also carry a timestamp and a nonce inside the signed string, which makes replay of a captured request detectable. Idempotency and replay protection solve different problems: | Control | Prevents | | --- | --- | | Idempotency key | Your own retry performing the action twice | | Timestamp and nonce | Someone else replaying a captured request | You need both. ## A safe retry loop 1. Generate and persist an idempotency key. 2. Send the request. 3. On 429, 500, or 503, wait with exponential backoff and jitter, then retry with the same key. 4. On 409, stop and inspect. Do not retry with a new key hoping it works. 5. On success, record the result and the request identifier. 6. Bound the number of attempts. ## Source [Authentication](/develop/authentication/) and [errors](/develop/errors/). --- # Identifiers and networks URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/develop/identifiers-and-networks/ Page ID: develop/identifiers-and-networks Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals, universe-index-atomicals-nfts-and-realms Verified: 2026-08-31 ## Protocol identifiers The Marketplace router exposes four isolated protocol authorities. These exact strings are the identifiers: | Identifier | Asset kind | | --- | --- | | `arc20` | Fungible ARC-20 tokens | | `atomicals_nft` | Plain non-fungible Atomicals | | `realms` | Top-level Realms | | `subrealms` | Subrealms | Every route, cursor, idempotency scope, listing, offer, order, reservation, browse query, and status count is scoped to one of these. Non-ARC-20 storage keys are prefixed internally, and the prefix is never returned as a public asset ID. ## Asset identifiers | Identifier | Shape | Use | | --- | --- | --- | | Atomical ID | `i` | The primary key | | Compact Atomical ID | The compact wire form | Payloads and marketplace collateral | | Location | `:` | Current custody, never a key | | Ticker | A lowercase name | Display, always alongside the resolved ID | See [identifiers and numbers](/protocol/core/identifiers/). ## Network identifiers Responses carry the network they apply to. A result for one network says nothing about another, because activation conditions differ. See [activation boundaries](/protocol/core/activation-boundaries/). ## Route prefixes Universe indexer routes follow the pattern `//`, where the prefix is the indexer repository name with the `index-` prefix removed. Versioned API surfaces additionally use a `/v1/` segment. The exact inventory for each service is in its reference page: - [ARC-20 API](/reference/api/arc20/) - [NFT and Realm API](/reference/api/atomicals-nfts-realms/) - [Marketplace v1](/reference/api/marketplace-v1/) ## What never to derive - Never derive identity from a ticker, realm name, or container name. - Never derive a route from a display name. - Never assume a protocol identifier is interchangeable with another lane. - Never treat a location as stable. --- # Migration URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/develop/migration/ Page ID: develop/migration Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals, universe-ordex Verified: 2026-08-31 ## The general procedure 1. Record your current pins: validator revision, network, service revisions, schema versions, and documentation version. 2. Read the [changelog](/releases/) between your pins and the target. 3. Read the [migration guides](/releases/migrations/) for every breaking change in that range. 4. Re-run the [conformance vectors](/reference/conformance/) against the target combination. 5. Regenerate your client from the target OpenAPI document. 6. Diff the generated types. Anything that changed shape is work. 7. Test against the target in a non-production environment. 8. Move, then verify with real reads before switching traffic. Step four is the one that catches interpretation changes a type diff cannot show. ## Marketplace route migration | Old | New | | --- | --- | | `POST /buys` | `POST /reservations` and `POST /purchases/prepare` | | `POST /orders/{orderId}/reconcile` | `POST /settlements/{orderId}/reconcile` | The legacy aliases remain available. New integrations use the reservation, purchase, and settlement routes, which separate the steps that were previously merged. ## Client regeneration The [TypeScript client](/reference/client-sdk/) is generated from the OpenAPI documents. Regenerate rather than hand-editing, and let the type checker find the call sites that changed. ## Schema migration JSON Schemas carry a version. When a schema version changes: 1. Validate your stored records against the new schema. 2. Fix what fails before switching. 3. Keep the old schema available until nothing reads the old records. ## What not to do - Do not migrate by catching the errors that appear in production. - Do not skip the conformance run because the types compiled. - Do not assume a route rename preserves behavior. - Do not migrate the validator revision and the API revision in one step. Move one, verify, move the other. ## Source [Versioning and deprecation](/develop/versioning-and-deprecation/) and [migrations](/releases/migrations/). --- # Pagination and cursors URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/develop/pagination-and-cursors/ Page ID: develop/pagination-and-cursors Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals, universe-index-atomicals-nfts-and-realms Verified: 2026-08-31 ## Cursors are opaque and signed A cursor is an opaque token. Do not parse it, construct one, or modify one. The ARC-20 feed signs cursors with a dedicated secret, separate from the bearer token, so a tampered cursor is rejected rather than silently misinterpreted. ## What a cursor binds to A cursor refers to a position inside an immutable generation. It also preserves the page and holder chunk sizes it was created with. Two consequences: 1. **A cursor is only valid for its generation.** When the generation changes, restart the listing. 2. **Changing the page size mid-listing does not work.** The cursor already carries the sizes. ## Bootstrap cursors A cursor-free request against the ARC-20 feed may need to build an immutable generation first. In that case the service copies a bounded number of rows and returns a retryable unavailable response until the generation is ready. Retries resume and reuse the same source fingerprint. Source movement abandons an unfinished generation. That bounds writer time and stops repeated requests from duplicating complete histories. A client must therefore treat a retryable unavailable response as normal during bootstrap, not as a failure. ## Paging patterns | Surface | Pattern | | --- | --- | | Asset listings | Cursor plus limit | | Holder listings | Page number plus limit | | History | Limit, bounded | | Feed pages | Signed cursor plus limit | Where a `truncated` flag is returned, honour it. It means there was more and the response stopped, not that there was nothing more. ## Rules for a client 1. Treat the cursor as opaque. 2. Restart the listing when the generation identifier changes. 3. Never merge pages from two generations into one result set. 4. Handle a retryable unavailable response during bootstrap with backoff. 5. Respect `truncated` rather than assuming the list ended. 6. Bound your own total page count so a loop cannot run forever. ## Source [Consistency and reorgs](/develop/consistency-and-reorgs/) and [ARC-20 API](/reference/api/arc20/). --- # Rate limits URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/develop/rate-limits/ Page ID: develop/rate-limits Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals-nfts-and-realms, universe-index-atomicals Verified: 2026-08-31 Limitations: - This page documents limits only where they are implemented. Where a service has no limit, it says so rather than inventing a policy. ## What exists today | Surface | Rate limit | | --- | --- | | NFT and Realm read routes | No request rate limit is implemented on the service itself | | ARC-20 feed | Bounded generation build work per request, which paces cold bootstrap | | Marketplace routes | Replay protection and idempotency, which are not rate limits | Where no limit is implemented, the constraint is the deployment in front of the service, not the service. Do not read the absence of a limit as permission to hammer it. ## The bounded work that does exist The ARC-20 feed copies at most a configured number of rows per cursor-free request while building an immutable generation, and returns a retryable unavailable response until the generation is ready. That bounds writer time and prevents repeated requests from duplicating complete histories. A client must handle that retryable response as normal, with backoff. ## Behave well anyway 1. Cache read results together with their generation identifier. 2. Re-read on a generation change, not on a timer. 3. Use cursors and honour the page sizes the cursor carries. 4. Back off exponentially with jitter on 429, 500, and 503. 5. Bound concurrency per host rather than fanning out without limit. 6. Never poll a readiness endpoint faster than you would act on a change. 7. Prefer one request that returns what you need over many that each return part of it. ## If a 429 appears A limit exists in front of the service. Back off, honour any retry hint, and reduce concurrency. Do not retry immediately with the same rate. ## Source [Pagination and cursors](/develop/pagination-and-cursors/) and [readiness and freshness](/develop/readiness-and-freshness/). --- # Readiness and freshness URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/develop/readiness-and-freshness/ Page ID: develop/readiness-and-freshness Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals-nfts-and-realms, universe-index-atomicals Verified: 2026-08-31 ## A configured source is not a healthy source Configuration means someone wrote a setting. Readiness means the service can currently answer correctly. They are unrelated. ## The endpoints | Endpoint | Answers | | --- | --- | | `GET /live` | Is the process running? | | `GET /ready` | Can it answer correctly, and if not, why? | | `GET /health` | What is the state, including `unavailable`? | | `GET /version` | Which service and provider revisions? | | `GET /metrics` | Operational metrics, where enabled | `/live` returning 200 says nothing about whether an answer would be correct. Read `/ready`. ## What readiness actually checks The NFT and Realm read model reports ready only when all of the following hold: - a generation identifier exists; - the indexed height is a safe integer; - the view is not stale; - the tip is not mixed; - the integrity check has not failed. When any fails, the response is 503 with the reason, the state, the source, the network, the generation identifier, the indexed height, the source revision, and the counts. That response is designed to be actionable rather than merely negative. ## The six states | State | Meaning | What a caller does | | --- | --- | --- | | Configured | A setting exists | Nothing. Wait for readiness | | Live | The process is running | Nothing. Check readiness | | Ready | Can answer correctly | Proceed | | Degraded | Answering from an incomplete view | Do not act on the answer | | Stale | Answering from an old chain position | Check the indexed height | | Mixed tip | The generation spans more than one provider tip | Do not act on the answer | ## Declared coverage The ARC-20 source declares `partial` coverage with an explicit reason: confirmed authoritative history and complete proven holder snapshots are indexed, but the shipped adapter has no exhaustive mempool feed with stable pending lifecycle and disappearance handling. That limitation is about pending activity. It does not weaken the confirmed scan or the holder proof requirements. Read the declared coverage rather than assuming completeness. ## For product builders Render the state, never a misleading zero: - "We cannot reach the index right now" for unavailable. - "Showing data from block N" for stale. - "This view does not cover that asset type" for out of scope. - "No assets found" only when ready and genuinely empty. ## Production resilience The production read service runs on the dedicated Universe indexer host and binds only to its local interface. A supervised private compatibility tunnel keeps existing application routes available during infrastructure changes, while automatic restart and health checks restore both the indexer and its private route without manual intervention. Endpoint consumers still apply the readiness and freshness rules above: resilience of the service does not exempt a caller from declaring coverage and lag. ## Source [Unavailable index against empty balance](/guides/unavailable-indexer-vs-empty-balance/). --- # Source of truth URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/develop/source-of-truth/ Page ID: develop/source-of-truth Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-guide, atomicals-electrumx-1.5.2.0 Verified: 2026-08-31 ## The order 1. Executed source code, conformance tests, generated route inventories, schemas, deployment manifests, and runtime contracts, at an exact revision. 2. Final or Living Atomicals Improvement Proposals applicable to the feature. 3. The official Atomicals reference implementation or released validator, at an exact commit or release. 4. Official Atomicals protocol and CLI documentation. 5. Universe implementation documentation, at an exact revision. 6. Third-party integrations, always identified as third-party and non-normative. Explanatory prose is never independent consensus, including this documentation. ## What that means in practice | Question | Answered by | | --- | --- | | What does this transaction do? | The validator revision you run, at that height | | Is this rule active? | The activation condition for your network | | What does this API return? | The service contract at its deployed revision | | Is this proposal implemented? | Implementation evidence, never the proposal itself | | Does this product support it? | The product's own statement, dated | ## Resolving a disagreement Do not vote. Check, in order: 1. Same network? 2. Same chain position, or is one behind? 3. Same validator revision? 4. Is the behavior activation sensitive at that height? 5. Same projection? Only when all five match does a disagreement mean one source is wrong. Until then it is a version, position, or scope difference. ## For anything with value at stake Compare more than one compatible source, and treat any disagreement as a hold rather than a tie-break. Record the revision and generation of each answer so the difference can be explained afterwards. ## What this documentation does Every source-sensitive page carries a source panel with the repository, the exact revision, the path, the applicable networks, the last verified date, and the known limitations. Where evidence is missing, the page says so rather than guessing. See [networks and versions](/start/networks-and-versions/). --- # Versioning and deprecation URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/develop/versioning-and-deprecation/ Page ID: develop/versioning-and-deprecation Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals, universe-index-atomicals-nfts-and-realms Verified: 2026-08-31 ## Five things are versioned separately | Axis | Where it appears | | --- | --- | | Protocol reference baseline | The pinned validator revision | | Universe API surface | The `/v1/` segment and the service revision | | Marketplace contract | The Marketplace v1 route and signing contract | | Generated schemas | A version field inside each schema | | Documentation | The documentation version on every page | Never assume two of them move together. ## Reading a service version `GET /version` returns the service name and version, the source revision and its evidence, the declared Git revision where available, the runtime version, the pinned provider version, tag, commit, and required AIPs, the projection name, and the asset types covered. Record all of it with anything you cache. ## What counts as breaking - Removing a route, a field, or an enum value. - Changing the type or meaning of an existing field. - Changing a default that alters results. - Tightening validation so a previously accepted request is refused. - Changing an identifier's shape. Adding an optional field or a new route is not breaking, so build clients that ignore unknown fields. ## Deprecation A deprecated capability still works and is scheduled for removal. Every deprecation carries the old behavior, the new behavior, the effective version, migration instructions, the compatibility impact, and the source evidence. Current example: the legacy Marketplace `/buys` and `/orders/{orderId}/reconcile` aliases remain available, and new integrations use `/reservations`, `/purchases`, and `/settlements`. ## What a deprecation does not promise It does not promise the old behavior is identical to the new one. Read the migration note rather than assuming a rename. ## Where changes are published | Artefact | Contains | | --- | --- | | [Releases](/releases/) | Human readable changelog | | [Versions](/releases/versions/) | The compatibility matrix | | [Deprecations](/releases/deprecations/) | What is scheduled for removal, and when | | [Migrations](/releases/migrations/) | Step by step moves between versions | | The changelog feed | A machine readable feed of the same | ## Source [Migration](/develop/migration/) and [releases](/releases/). --- # Ecosystem registry URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/ecosystem/ Page ID: ecosystem/index Applicability: third-party Authority: third-party Networks: mainnet Sources: none Verified: 2026-08-31 Limitations: - Listing is not endorsement. - Availability is recorded only from a reachable source. Where none established a state, the record says unknown. - A network failure produces unreachable, never deprecated or closed. A record exists so you can find something and judge it. It is not a recommendation, a security review, or a statement that a product is safe to use with your assets. ## How a status is decided | State | What it means | | --- | --- | | `verified-active` | A reachable source established that it is operating | | `degraded` | Reachable, and a reachable source established that it is not fully operating | | `unreachable` | Could not be reached at the last check. This is not evidence of closure | | `deprecated` | A reachable source from the operator established that it is being retired | | `closed` | A reachable source from the operator established that it has shut down | | `unknown` | No reachable source established any state | Three rules follow, and they are the reason this registry is shorter than an aggregated directory: 1. **A network failure is not closure.** It produces `unreachable`, and nothing stronger. 2. **Conflicting evidence produces `unverified`,** never a guess. 3. **An old directory entry is not evidence.** A record is not listed as active because someone else listed it. ## The registry ## What is deliberately absent Third-party marketplaces and explorers are not individually listed. No reachable source was checked for any of them during this review, and listing one from an older directory would assert a state we did not establish. That is a gap, and saying so is better than filling it with guesses. To add a record, open an issue with the evidence. ## Adding or correcting a record See [ecosystem records](/contribute/ecosystem-records/). A record needs a category, an operator, a custody model, a reachable source for its status, and the date it was checked. Records without evidence are not merged. ## Before you use anything listed here 1. A listing on any marketplace is not evidence of ownership. Ownership is verified at settlement, against the chain. 2. A wallet that cannot show you outpoints is not safe for Atomicals. See [choose a wallet](/guides/choose-a-wallet/). 3. An indexer answer is version scoped. Ask which revision produced it. See [indexer dependency](/protocol/core/indexer-dependency/). 4. Nothing on this page changes the rules in [safety fundamentals](/start/safety-fundamentals/). --- # Guides URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/ Page ID: guides/index Applicability: editorial Authority: none Networks: mainnet Sources: none Verified: 2026-08-31 Every guide here follows the same shape, so you always know what you are about to do before you do it. | Section | What it tells you | | --- | --- | | Before you start | Prerequisites, supported networks, and current support status | | What you need | Exact inputs | | What happens | Expected outputs and what your wallet will ask | | Cost | Fee behavior for this specific action | | Check before signing | The safety checks for this action | | If it fails | Named failure cases and what each means | | After broadcast | How to verify the result, and reorg considerations | | Source | The normative page behind the procedure | Never share a seed phrase, private key, or wallet export file. Never let a general purpose Bitcoin wallet select fee inputs from a set that includes your coloured outputs. ## Set up ## Inspect ## Issue and mint ## Move and recover ## Trade --- # Avoid burns URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/avoid-burns/ Page ID: guides/avoid-burns Applicability: protocol-behavior Authority: executed-source Networks: mainnet Sources: atomicals-electrumx-1.5.2.0 Verified: 2026-08-31 Limitations: - A confirmed burn is permanent. This procedure prevents burns. Nothing reverses one. ## Before you start - Supported networks: mainnet. - Status: protocol behavior. - Prevention is the only control. There is no recovery. ## The procedure 1. Work in outpoints and satoshis. Never in a token amount box. 2. Move one token per transaction unless you have modelled the multi token case. 3. Always include a coloured change output when the lot exceeds what you are sending. 4. Size the change output to **exactly** the remainder. 5. Model the exact input and output set, in order, before building. 6. Confirm the computed burn figure is zero. 7. Add the fee inputs and cardinal change, then model again. 8. Confirm the burn figure is still zero. 9. Compare the wallet prompt to your model, line by line, before signing. Steps seven and eight are the ones people skip, and they are where wallet-added change silently changes the result. ## The four shapes, executed | Shape | Prevention | | --- | --- | | Next output too large | Size change to exactly the remainder | | Not enough outputs | Always include coloured change | | First output larger than the lot | Never send a small lot into a large first payment | | Multi token fallback | One token per transaction | An exchange deposit address, a plain Bitcoin wallet, or any service without Atomicals support spends the output as ordinary bitcoin. The units are gone, and no burn record will comfort you. Check the destination supports Atomicals before you send. ## The one case where a burn is deliberate Destroying units on purpose is a valid action. Do it explicitly: build the transaction that burns exactly what you intend, confirm the figure, and record why. Never rely on an accidental burn. ## After broadcast Read the transaction through a source that reports burns and confirm the figure is what you expected. Compare the coloured input total against the sum of coloured output totals. ## Source [Burns](/protocol/arc20/burns/) and [allocation](/protocol/arc20/allocation/). --- # Buy on the marketplace URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/buy-on-marketplace/ Page ID: guides/buy-on-marketplace Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals, universe-ordex Verified: 2026-08-31 Limitations: - Action gates default to off. Buy execution additionally requires an exact fee script to be configured on the deployment. ## Before you start - Supported networks: mainnet. - Status: Universe implementation. - Your funding inputs must be confirmed and uncoloured. Spending a coloured output to fund a purchase loses those units. ## The lifecycle 1. **Read the listing.** Record the Atomical ID, the price, and the exact payment script. 2. **Reserve.** A reservation holds the listing while you prepare. Read the reservation back. 3. **Prepare the purchase.** The service builds the settlement transaction and returns what you must sign. 4. **Sign.** With the exact scope the prepare step specifies. 5. **Validate signed.** The service checks your signed material against the blueprint before anything is broadcast. 6. **Broadcast.** Only after validation passes. 7. **Verify settlement.** See [verify settlement](/guides/verify-settlement/). ## What is validated before broadcast - The seller still controls the asset, at a stable checkpoint. - Your funding inputs are confirmed, uncoloured in both the script hash view and location history, and of a supported type. - The Atomicals blueprint assigns the selected asset cleanly to the buyer output, with no operation, no mixed Atomical ID, and no burn. - Heights and hashes on both sides are unchanged across the bracket. Anything else fails closed. ## Check before signing | Check | Why | | --- | --- | | The Atomical ID matches the listing | A ticker or name is not identity | | The price is exactly what you agreed | Including any disclosed marketplace fee | | Your funding inputs are cardinal | Or you spend an asset to buy one | | Every output is visible with script and value | You cannot verify what you cannot see | | The signature scope | It must not let outputs change after you sign | ## If it fails | Failure | Meaning | | --- | --- | | Reservation expired | Reserve again. The listing may be gone | | Stale ownership | The seller moved the asset. Nothing was spent | | Mixed collateral | The seller's output carries more than the asset | | Checkpoint drift | The chain moved mid-check. Retry | | Validation failed | Do not broadcast. Start again | A failure before broadcast costs nothing. ## Fees The price, the settlement transaction fee, and any disclosed marketplace fee. The flow must show the breakdown before your final confirmation. ## Source [Marketplace v1](/reference/api/marketplace-v1/) and [transfers and swaps](/protocol/arc20/transfers-and-swaps/). --- # Choose a wallet URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/choose-a-wallet/ Page ID: guides/choose-a-wallet Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0 Verified: 2026-08-31 Limitations: - This page describes required capabilities. It does not endorse any product. See the ecosystem registry for evidence based records. ## Before you start - Supported networks: mainnet. - Status: protocol behavior. These requirements come from how allocation works, not from any product. - You do not need to move anything to run these tests. ## The capabilities that matter | Capability | Why it matters | If missing | | --- | --- | --- | | Lists outpoints, not just address totals | You cannot reason about allocation without outpoints | Unusable for Atomicals | | Marks coloured outputs per Atomical | So you know which outputs carry value | Unusable | | Excludes coloured outputs from fee selection | Prevents the most common loss | Unusable | | Shows expected units per output before signing | Lets you catch a burn before it happens | High risk | | Shows the burn figure | Makes the failure visible | High risk | | Preserves input and output order | Reordering changes the allocation result | High risk | | Shows the signature hash flag | Lets you refuse an unexpected scope | Risky for swaps | | Names its data source and freshness | Lets you judge how current the answer is | Inconvenient | ## The ten minute test 1. Ask the wallet to show your unspent outputs. If it only shows a balance, stop here. 2. Confirm it marks which outputs carry Atomicals, and which Atomical each carries. 3. Start a plain BTC send while holding coloured outputs. It should exclude them, or warn clearly. 4. Start an ARC-20 transfer. It should show, per output, the satoshi value and expected units. 5. Deliberately set a change output larger than the remainder. It should show a non-zero burn figure and require a second confirmation. 6. Cancel everything. You have not spent anything. A wallet that fails step one or three is not suitable for holding Atomicals. ## Check before signing Nothing here signs anything. If a wallet asks for a seed phrase, private key, or wallet export file at any point in this test, stop and do not continue with that product. ## If it fails Move the assets to a wallet that passes, using a transaction you modelled first with the [allocation visualizer](/tools/allocation-visualizer/). Do the move from the safer side: build the transaction in a tool you trust and sign it, rather than letting the unsafe wallet choose inputs. ## After Keep a dedicated cardinal pool for fees. See [prepare BTC and UTXOs](/guides/prepare-utxos/). ## Source [Wallet safety](/protocol/arc20/wallet-safety/) and [wallet integration](/reference/wallet-integration/). Product records with last-verified dates are in the [ecosystem registry](/ecosystem/). --- # Claim a Realm URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/claim-a-realm/ Page ID: guides/claim-a-realm Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-js-cli, atomicals-electrumx-1.5.2.0 Verified: 2026-08-31 ## Before you start - Supported networks: mainnet. - Status: protocol behavior. The Universe read model exposes realm resolution and hierarchy. - A request is not a name. It becomes one only when the rules resolve it. ## Check first 1. Search for the name. `find-realms`, `get-realm`, and `realm-info` read the current state. 2. Check for existing candidates for the same name. 3. Check for confusable variants that already exist. See [Unicode and confusable names](/protocol/realms/unicode-and-idna/). 4. Confirm the name passes validation for your target rule set. ## The command ```text yarn cli mint-realm ``` Options include `--satsoutput`, `--initialowner`, `--container`, `--bitworkc`, `--bitworkr`, `--funding`, `--satsbyte`, `--rbf`. See the [CLI reference](/reference/cli/#mint-realm). ## Cost Two Bitcoin fees, grinding if you set Bitwork, and the output value that will carry the Realm. ## Check before signing - The name is exactly the string you intend, character by character. - No confusable variant is already claimed by someone else. - The output value is above the dust threshold. - The funding input is cardinal. ## After broadcast 1. Confirm, then wait for indexing. 2. Read the resolution. Confirm you are the **verified winner**, not a pending or losing candidate. 3. Record the Atomical ID. 4. Move the output into your protected pool. Losing that output loses the name. 5. If you plan to allow Subrealms, configure the rules deliberately. See [claim a Subrealm](/guides/claim-a-subrealm/). ## If you did not win Another claim resolved first. Your Atomical exists without the name. Do not present it as the Realm. ## Source [Realms](/protocol/realms/overview/) and [candidates and winners](/protocol/core/candidates-and-winners/). --- # Claim a Subrealm URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/claim-a-subrealm/ Page ID: guides/claim-a-subrealm Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-js-cli, atomicals-electrumx-1.5.2.0 Verified: 2026-08-31 Limitations: - Rules can be changed by the parent. Read them at the height you are claiming at, not from a cached page. ## Before you start - Supported networks: mainnet. - Status: protocol behavior. - The parent controls the rules and can enable or disable claiming. ## The procedure 1. Read the parent Realm's current Subrealm rules, at a current height. 2. Confirm Subrealm claiming is enabled. 3. Confirm the name is available and has no competing candidate. 4. Build a claim that satisfies every rule, including the payment output and its marker if a payment is required. 5. Mint: ```text yarn cli mint-subrealm ``` 6. Confirm and wait for indexing. 7. Confirm you are the verified winner. ## Payments Where a rule requires payment, all of the following must be true in the same transaction: - the payment goes to the exact output the rule specifies; - the amount is exact; - the payment marker is present and well formed. Paying the right amount to the wrong script makes the claim invalid, and the fee is spent. ## Check before signing - The rules you built against are the rules currently published. - The payment output script and value are exactly as required. - The payment marker is present. - The name is exactly the string you intend. ## If it fails | Failure | Meaning | | --- | --- | | Claiming disabled | The parent turned it off | | Rule not satisfied | Re-read the rules and rebuild | | Payment wrong | Invalid claim, fee spent | | Already claimed | Another claim won | | Pending, not resolved | Wait. Do not present it as owned | ## After Record the Atomical ID and move the output into your protected pool. ## Source [Subrealms](/protocol/realms/subrealms/) and [claims and rules](/protocol/realms/claims-and-rules/). --- # Confirmations and reorgs URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/confirmations-and-reorgs/ Page ID: guides/confirmations-and-reorgs Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, universe-index-atomicals-nfts-and-realms Verified: 2026-08-31 ## Two questions, two answers **Did Bitcoin confirm it?** A block contains it, at some depth. **Did the Atomicals operation succeed?** A validator applied the rules and produced a result, at a chain position. Both must be answered. Neither implies the other. ## The three states you will see | State | Meaning | Safe to act on | | --- | --- | --- | | Broadcast, unconfirmed | In a mempool somewhere | No | | Confirmed, not yet indexed | In a block, no Atomicals result yet | No | | Confirmed and indexed at a stable generation | A validator produced a result | Depends on depth and value | ## What a reorg changes A reorg replaces blocks, so everything computed from them is suspect: mints, name resolutions, transfers, burns, and mint quota positions. A well-built index does not patch these in place. It invalidates the affected generation and rebuilds from a checkpoint. That is why a generation identifier is worth recording. ## What to do 1. Read the generation identifier and indexed height with every answer. 2. For a small amount, one confirmation plus indexing is usually enough. 3. For a significant amount, wait for depth appropriate to the value, then re-read. 4. Re-read after any reported generation change, not only after an obvious reorg. 5. Never cache an Atomicals result without also caching the generation it came from. ## Product state against protocol state A product can label an action `confirmed` when it has broadcast and seen one confirmation. That is a product state, not a statement about depth, reorg safety, or indexer finality. Read the field definition before mapping it into your own model. ## Source [Confirmation and reorgs](/protocol/core/confirmation-and-reorgs/) and [consistency and reorgs](/develop/consistency-and-reorgs/). --- # Create a Container URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/create-a-container/ Page ID: guides/create-a-container Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-js-cli, atomicals-electrumx-1.5.2.0 Verified: 2026-08-31 Limitations: - No Universe read projection exposes Containers. Verification of your own collection uses the reference CLI or a compatible indexer. ## Before you start - Supported networks: mainnet. - Status: protocol behavior. Not exposed by the Universe read projection. - The Container name is a globally allocated name and follows the candidate model. ## The procedure 1. Choose the Container name. Check it is not confusable with an existing one. 2. Mint it: ```text yarn cli mint-container ``` 3. Confirm on Bitcoin, then wait for indexing. 4. Confirm the name resolved to **your** Atomical ID and is not still a candidate. 5. Record the Container Atomical ID. Publish that, not just the name. 6. Do not open item minting yet. First prepare and seal the manifest. See [create DMINT items](/guides/create-dmint-items/). ## Reading it back | Command | Reads | | --- | --- | | `get-container` | The Container | | `get-container-items` | Items claimed against it | | `summary-containers` | An overview | | `find-containers` | Discovery | See the [CLI reference](/reference/cli/). ## Check before signing - The name string is exactly what you intend. - You are on the network you think you are. - The funding input is cardinal. - The metadata contains nothing you cannot stand behind permanently. ## If the name does not resolve to you Another claim won it. Your Atomical exists but does not hold the name. Do not publish it as the collection. Start again with a different name, or resolve the dispute before minting items. ## After Publish the Container Atomical ID everywhere the name appears, so buyers can verify membership rather than trusting a label. ## Source [Containers](/protocol/containers/overview/) and [candidates and winners](/protocol/core/candidates-and-winners/). --- # Create DMINT items URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/create-dmint-items/ Page ID: guides/create-dmint-items Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-js-cli, atomicals-electrumx-1.5.2.0 Verified: 2026-08-31 Limitations: - Sealing is permanent. A manifest sealed with a mistake cannot be corrected. ## Before you start - Supported networks: mainnet. - Status: protocol behavior. - You need a Container whose name already resolved to your Atomical ID. See [create a Container](/guides/create-a-container/). Seal first, then open minting. A manifest that can still be edited while people mint against it makes every verification meaningless. ## The procedure 1. Assemble the final item set in a folder. Final means final. 2. Build the manifest: ```text yarn cli prepare-dmint ``` 3. Prepare the item files with `prepare-dmint-items`. 4. Verify locally that every item you intend to allow is in the manifest, and nothing else is. 5. Attach it: ```text yarn cli enable-dmint ``` 6. **Read the manifest back from the chain** and compare it byte for byte with what you built. 7. Only then seal: ```text yarn cli seal ``` 8. Publish the Container Atomical ID, the sealed state, and the manifest. 9. Open minting at or after the mint height. Step six is the one people skip. Read back what is actually on chain before making it permanent. ## What claimants do ```text yarn cli mint-item ``` They can check first with `validate-container-item`, without minting. ## Failure states for a claimant | State | Cause | | --- | --- | | Item not in the manifest | Wrong identifier | | Digest mismatch | Content differs from the manifest entry | | Before mint height | Claimed too early | | Bitwork not satisfied | Grinding incomplete | | Payment missing or wrong | A payment rule was not satisfied | | Already claimed | Someone else won the race | Every one of those produced a confirmed Bitcoin transaction and cost a fee. ## After Verify a sample of minted items against the manifest yourself, and publish the verified item count alongside the manifest total. ## Source [DMINT](/protocol/containers/dmint/) and [sealing and rules](/protocol/containers/sealing-and-rules/). --- # Deploy a fixed DFT URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/deploy-fixed-dft/ Page ID: guides/deploy-fixed-dft Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-js-cli, atomicals-electrumx-1.5.2.0 Activation: Mint count limits have legacy and later density variants. Check the limit active on your target network. Verified: 2026-08-31 ## Before you start - Supported networks: mainnet. - Status: protocol behavior. Universe products expose decentralised deploy and mint flows. - The parameters are permanent. There is no edit. ## What you need | Parameter | Constraint at the pinned revision | | --- | --- | | Ticker | Validated by the active ticker rule | | `mint_amount` | 546 through 100 000 000 satoshis | | `max_mints` | At least 1. The maximum is activation dependent | | `mint_height` | 0 through 10 000 000 | | Metadata file | Optional JSON | | `mint_bitworkc` | Optional commit work for claimants | ## The command ```text yarn cli init-dft ``` There is also `init-dft-fixed`. See the [CLI reference](/reference/cli/#init-dft). ## Choosing the parameters **`mint_amount`.** This is what each claimant locks in output zero. Small amounts make minting cheap and produce many dust-sized lots. Large amounts make minting expensive and produce few large lots. Pick with the transfers people will actually make in mind. **`max_mints`.** Multiply by `mint_amount` to get nominal maximum issuance, which is bitcoin that would be locked if the ceiling were reached. Check the value against the limit active on your network before deploying. **`mint_height`.** Give yourself enough room to publish the deployment before claiming opens. **Mint Bitwork.** Raises the cost of automated claiming. It also raises the cost for everyone. Model it with the [Bitwork estimator](/tools/bitwork-estimator/). ## Check before signing - Every parameter is within the range active on your target network. - `mint_amount * max_mints` is the issuance you actually intend. - The ticker string is exactly right. - You are deploying on the network you think you are. ## After broadcast 1. Confirm, then wait for indexing. 2. Confirm the ticker resolved to your Atomical ID. 3. Publish the resolved Atomical ID, not just the name, so claimants can verify. 4. Verify the deployment reads back exactly as you intended before telling anyone to mint. ## Source [Fixed DFT deployment](/protocol/arc20/fixed-dft/). --- # Deploy a perpetual DFT URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/deploy-perpetual-dft/ Page ID: guides/deploy-perpetual-dft Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-js-cli, atomicals-electrumx-1.5.2.0 Activation: Perpetual mode is activation gated. Confirm it is active on your target network before deploying. Verified: 2026-08-31 Limitations: - Do not publish a supply cap unless the deployment configures a global maximum. ## Before you start - Supported networks: mainnet, subject to activation. - Status: protocol behavior, activation gated. - Confirm perpetual mode is active on your target network first. If it is not, the deployment will not behave as you expect. ## The command ```text yarn cli init-dft-perpetual ``` See the [CLI reference](/reference/cli/#init-dft-perpetual). ## What is different from fixed | Aspect | Fixed | Perpetual | | --- | --- | --- | | Availability | Generally available | Activation gated | | Bitwork | Set once | Progresses over time | | Mint count | Bounded by `max_mints` | Governed by progression parameters | | Supply cap | Always computable | Only if a global maximum is configured | ## The display rule If the deployment configures a global maximum, publish it. If it does not, publish "no configured maximum" rather than computing a number as if the deployment were fixed. A user interface that prints an invented cap misleads every claimant who reads it. ## Check before signing - Perpetual mode is active on this network at this height. - The progression parameters produce a cost curve you actually want. - You know whether a global maximum is configured, and you will publish that honestly. - The ticker string is exactly right. ## After broadcast 1. Confirm and wait for indexing. 2. Read the deployment back and confirm the mode is recorded as perpetual. 3. Read the current Bitwork requirement and note that it will change. 4. Publish the resolved Atomical ID and the current requirement, with the height you read it at. ## For claimants Read the requirement at the height you are targeting, not from a cached page. A claim built against a stale requirement fails and still costs a fee. ## Source [Perpetual DFT](/protocol/arc20/perpetual-dft/). --- # Direct FT issuance URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/direct-ft-issuance/ Page ID: guides/direct-ft-issuance Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-js-cli, atomicals-electrumx-1.5.2.0 Verified: 2026-08-31 Limitations: - No Universe product surface exposes direct FT issuance. This procedure uses the reference CLI. ## Before you start - Supported networks: mainnet. - Status: protocol behavior. **Not exposed by any Universe product.** Use the reference CLI. - You need the reference CLI, a funded wallet it controls, and the full supply in bitcoin. ## What you need | Input | Notes | | --- | --- | | A ticker | Lowercase, validated against the active rule. See [tickers](/protocol/arc20/tickers-and-candidates/) | | The supply | In units, which is also the satoshi value output zero must carry | | A metadata file | Optional JSON. Treat everything in it as public and unverified | | Funding | The supply, plus commit and reveal fees, plus grinding cost | ## The command ```text yarn cli mint-ft ``` Useful options: `--bitworkc`, `--bitworkr`, `--initialowner`, `--parent`, `--parentowner`, `--funding`, `--satsbyte`, `--rbf`, `--disablechalk`. See the [CLI reference](/reference/cli/#mint-ft) and the [command builder](/tools/cli-builder/). ## What happens 1. A commit transaction pays into a Taproot output committing to the envelope. 2. If Bitwork is set, the commit is ground until its transaction id matches. 3. A reveal transaction spends it, exposing the envelope. 4. Output zero of the reveal carries the whole supply in satoshis. ## Cost The supply itself is locked in output zero. On top: two Bitcoin fees, and grinding time if you set Bitwork. A supply of 100 000 000 units requires one bitcoin in that output. ## Check before signing - The ticker string is exactly what you intend, character by character. - The supply figure matches the satoshis you are committing. - The metadata contains nothing private and nothing you cannot stand behind. - The funding source is cardinal. - You have enough left to pay the reveal fee after the commit. ## If it fails | Failure | Meaning | | --- | --- | | Ticker rejected | The name failed the active rule | | Reveal underfunded | The commit did not carry enough. Fund more and start again | | Ticker already claimed | Another Atomical won the name. Your mint may exist without the ticker | | Bitwork not met | The grind did not complete for the target | ## After broadcast 1. Confirm on Bitcoin. 2. Wait for indexing. 3. Confirm the ticker resolved to **your** Atomical ID and not to a competing candidate. 4. Record the Atomical ID. 5. Plan your lot structure before the first distribution. See [split and combine](/guides/split-and-combine-arc20/). ## Source [Direct issuance](/protocol/arc20/direct-issuance/). --- # Fees and costs URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/fees-and-costs/ Page ID: guides/fees-and-costs Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-js-cli, universe-index-atomicals Verified: 2026-08-31 Limitations: - Marketplace fee amounts are deployment configuration, not protocol behavior. Read the fee disclosure in the flow you are using. ## Before you start - Supported networks: mainnet. - Status: protocol behavior for the transaction costs, Universe implementation for marketplace fees. ## What you pay, by action | Action | Costs | | --- | --- | | Ordinary transfer | One Bitcoin fee | | Mint or deploy | Commit fee, reveal fee, and grinding time if Bitwork applies | | DMT claim | Commit fee, reveal fee, grinding, and the mint amount locked in output zero | | Splat | One Bitcoin fee plus a dust-safe value per separated output | | Marketplace listing | Usually no Bitcoin transaction until settlement | | Marketplace purchase | The price, the settlement transaction fee, and any disclosed marketplace fee | ## The costs people forget **The reveal fee scales with your payload.** Embedding a large file makes the reveal transaction large. Estimate the reveal size with the real bytes before grinding. **Grinding invalidates your fee estimate.** A successful grind changed the transaction, so recompute the fee afterwards. **A failed mint still costs a fee.** A claim that misses the quota, the height, or the Bitwork still produced a confirmed Bitcoin transaction. See [decentralised mint claims](/protocol/arc20/decentralized-mint/). **Locked value is not a fee, but it is money.** A DMT claim locks `mint_amount` satoshis in output zero. That is the token, not a cost, but it leaves your spendable balance. **Dust-safe outputs.** Every coloured output must be above the relay dust threshold for its script type. Separating five Atomicals means five such outputs. ## Reducing cost 1. Reference shared bytes instead of embedding them again. See [references and recursion](/protocol/core/references-and-recursion/). 2. Store a compact source format rather than a large raster. 3. Choose a Bitwork prefix you can actually afford to grind. Use the [Bitwork estimator](/tools/bitwork-estimator/). 4. Act at a lower fee rate when the action is not time sensitive. 5. Avoid transactions that need to be rebuilt because a change output was the wrong size. ## Marketplace fees Buyer and seller fees are deployment configuration. The flow you are using must disclose them before you commit. If a flow does not show the fee breakdown before the final confirmation, stop. ## Source [Bitwork](/protocol/core/bitwork/), [commit and reveal](/protocol/core/commit-and-reveal/), and [Marketplace v1](/reference/api/marketplace-v1/). --- # Inspect an ARC-20 ticker URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/inspect-a-ticker/ Page ID: guides/inspect-a-ticker Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals, atomicals-electrumx-1.5.2.0 Verified: 2026-08-31 Limitations: - Resolution is computed at a chain position. Re-resolve before acting rather than trusting a cached answer. ## Before you start - Supported networks: mainnet. - Status: Universe implementation for resolution and details. - Read only. Do this before every purchase, mint, or transfer involving a ticker. ## The procedure 1. Resolve the ticker to a **verified winning Atomical ID**. If it resolves to a candidate rather than a winner, stop. 2. Read the token details for that Atomical ID, not for the name. 3. Read the deployment parameters: mode, mint amount, maximum mints, mint height, Bitwork. 4. Read issuance to date from claim records, not from the parameters. 5. Read the holder distribution, and note that holder rows must sum exactly to circulating supply. 6. Read confirmed activity. Note that pending activity coverage is limited. 7. Record the generation identifier and the indexed height. ## The check people skip Compare the Atomical ID, not the name. Two tickers can render identically and be different strings, and a name can resolve to a different Atomical after a candidate resolves. Write the Atomical ID down. Compare it against the one in any listing, mint interface, or message before you act. See [Unicode and confusable names](/protocol/realms/unicode-and-idna/). ## What each figure means | Figure | Meaning | | --- | --- | | Maximum issuance | `mint_amount * max_mints`. A ceiling, not a supply | | Claims made | Valid claims counted from records | | Circulating supply | Coloured value actually held, after burns | | Holders | Addresses holding, aggregated from proven snapshots | | Activity | Confirmed deployment, mint, transfer, burn, and protocol operations | Circulating supply is not claims multiplied by mint amount, because units can burn after minting. ## If the answer is empty That may mean the ticker does not exist, or that the index is unavailable, or that the projection does not cover this asset type. They are different. See [unavailable index against empty balance](/guides/unavailable-indexer-vs-empty-balance/). ## Source [Tickers and candidates](/protocol/arc20/tickers-and-candidates/) and [ARC-20 API](/reference/api/arc20/). --- # Inspect an address URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/inspect-an-address/ Page ID: guides/inspect-an-address Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals, universe-index-atomicals-nfts-and-realms Verified: 2026-08-31 ## Before you start - Supported networks: mainnet. - Status: Universe implementation for the read views. The underlying model is protocol behavior. - Read only. Nothing here spends anything. ## What you need The address, and a data source that reports outpoints. ## The procedure 1. Read the portfolio balances view for the address. 2. Read the coloured UTXO view for the same address. This is the one that matters. 3. For each coloured outpoint, record: the txid and vout, the satoshi value, and the Atomical ID or IDs it carries. 4. Note any outpoint carrying more than one Atomical. That is a mixed output. See [splat and mixed outputs](/protocol/nft/splat-and-mixed-outputs/). 5. Record the generation identifier and indexed height the answer came from. ## What a balance figure hides | The total says | It does not say | | --- | --- | | 1 246 units | How many outputs that is, or their sizes | | One token | Whether any output also carries something else | | A number | Whether any output is below the dust threshold | | A current figure | Which generation and height produced it | You cannot plan a transfer from a total. You can only plan one from outpoints. ## Reading the response Every Universe response carries a request identifier, a generation identifier, and freshness metadata. Record them. When something looks wrong later, those three fields are what makes the difference explainable. See [readiness and freshness](/develop/readiness-and-freshness/). ## If it fails An empty result and an unavailable service look the same in a user interface and mean opposite things. Read [unavailable index against empty balance](/guides/unavailable-indexer-vs-empty-balance/). ## Source [UTXO ownership](/protocol/core/utxo-ownership/) and [ARC-20 API](/reference/api/arc20/). --- # Inspect an Atomical URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/inspect-an-atomical/ Page ID: guides/inspect-an-atomical Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals-nfts-and-realms, atomicals-js-cli Verified: 2026-08-31 ## Before you start - Supported networks: mainnet. - Status: Universe implementation for the read model, protocol behavior for the underlying facts. - Read only. ## What you need The Atomical ID, in the form `i`. If you only have a name, resolve it first. See [inspect a ticker](/guides/inspect-a-ticker/). ## The procedure 1. Read the asset by Atomical ID. 2. Confirm the type and subtype. A plain NFT, a Realm, a Subrealm, a Container, and a DMINT item are different things. 3. Read the current location and owner script. 4. Read the history. Look at what changed and when, not only at the current state. 5. Check the sealed flag. Unsealed state can change. 6. Read the metadata, and treat every field as unverified. 7. Record the generation identifier and indexed height. ## Reference CLI equivalents | Command | Reads | | --- | --- | | `get` | The Atomical | | `location` | Current location | | `state` and `state-history` | State, now and over time | | `tx-history` | Transaction history | | `at-location` | What is at an outpoint | | `ftinfo` | Fungible token details | See the [CLI reference](/reference/cli/). ## What to be careful about - **The number is not the identity.** Key on the Atomical ID. - **Metadata proves nothing.** See [metadata trust](/protocol/core/metadata-trust/). - **A media file is hostile input.** Do not render it in a trusted context. - **A name in the payload is not the name it won.** Resolve names separately. ## After If you are about to act on what you read, re-read at a current generation immediately before acting. A location read minutes ago can be stale. ## Source [Atomicals digital objects](/protocol/core/digital-objects/) and [NFT and Realm API](/reference/api/atomicals-nfts-realms/). --- # List an ARC-20 lot URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/list-an-arc20-lot/ Page ID: guides/list-an-arc20-lot Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals Verified: 2026-08-31 Limitations: - Every marketplace action gate defaults to off. A capability being documented is not a statement that it is enabled on a deployment. ## Before you start - Supported networks: mainnet. - Status: Universe implementation. Action gates default to off. - Your lot must be a clean, unmixed coloured output. ## The lifecycle 1. **Challenge.** Request an authentication challenge. 2. **Verify.** Prove control of the owner address with a BIP-322 simple proof for P2WPKH or key-path P2TR. This issues a short lived owner session. It does not move anything. 3. **Prepare.** Submit the listing intent. The authority resolves the ticker to its verified winner and verifies the collateral against Bitcoin Core and the Atomicals provider, under one stable checkpoint. 4. **Sign.** Sign what the prepare step returned, with the exact scope it specifies. 5. **Finalise.** Submit the signed material. The listing becomes active. ## What the authority checks before accepting your lot The 9 October 2026 source repair is awaiting functional qualification and release. The sale consumes the whole selected Bitcoin output; exact token quantity is recorded separately from its Bitcoin value. A verified single-FT allocation smaller than collateral remains eligible; missing quantities and mixed or ambiguous allocations do not. Protocol validity alone does not bypass the marketplace's ownership, confirmation, checkpoint and signature checks. Marketplace v1 accepts `priceAtomic` per token and calculates the lot total as `priceAtomic` times `quantityAtomic`. Core Portfolio's signed-offer lane instead accepts a whole-lot `priceSats` total. For 600 tokens on 1,000 sats collateral, a 1,200-sat total means 2 sats per token. Bitcoin output and payout checks retain their exact satoshi values. The candidate does not establish mainnet activation or a completed test-network journey. Private Signet requires challenge, rule profile, interpreter artifact and isolated database attestation. Funded real-wallet flows and publisher gates remain outstanding; listing gates stay closed where qualification is missing. - The ticker resolves to its verified Atomical FT winner. - Bitcoin Core reports a confirmed, live output with the exact value and owner script. - The Atomicals provider reports exactly that location, script, value, and one authoritative FT. - The script hash view reports exactly one active row with the exact positive token amount for that Atomical; Bitcoin collateral is checked independently. - Heights and hashes on both sides stay unchanged across the verification bracket. Any disagreement, or any movement mid-check, fails the request closed. ## Always rejected Mixed collateral, spent outputs, checkpoint drift, ambiguous balances, Atomicals operations, burns, and output assignments that do not move the exact selected Atomical. ## Check before signing - The asset in the listing is the Atomical ID you intend, not just the ticker. - The price and the exact payment script are what you agreed. - The signature scope binds the payment output exactly. - The listing does not spend anything now. Only settlement does. ## If it fails | Failure | Meaning | | --- | --- | | Owner session missing or expired | Redo the challenge and verify steps | | Mixed collateral | Separate the output first | | Checkpoint drift | The chain moved mid-check. Retry | | Gate disabled | Listing is not enabled on this deployment | ## After Read the listing back and confirm the asset, price, and payment script. Your lot stays in your control until a settlement transaction is signed and broadcast. ## Source [Marketplace v1](/reference/api/marketplace-v1/) and [transfers and swaps](/protocol/arc20/transfers-and-swaps/). --- # List an NFT, Realm, or Subrealm URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/list-an-nft-or-realm/ Page ID: guides/list-an-nft-or-realm Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals Verified: 2026-08-31 ## Before you start - Supported networks: mainnet. - Status: Universe implementation. Action gates default to off. - The asset must sit alone on its output. Mixed collateral is rejected. ## The lanes | Lane | Accepts | Rejects | | --- | --- | --- | | `atomicals_nft` | A plain NFT by authoritative compact Atomical ID | Realm, Subrealm, FT, Container, and item subtypes | | `realms` | A Realm | Anything that is not the verified name winner | | `subrealms` | A Subrealm | Anything that is not the verified name winner | `quantityAtomic` is always `1` for all three. A name and an object are indivisible. ## The extra check for names Before every mutation, the Realm and Subrealm lanes resolve the verified name winner and confirm the offered Atomical is that winner. A name can move between Atomicals through candidate resolution, so an Atomical that used to hold a name is not the name. ## The lifecycle Identical to an ARC-20 lot: challenge, verify with BIP-322, prepare, sign, finalise. See [list an ARC-20 lot](/guides/list-an-arc20-lot/). ## Before listing, separate the asset If the output carries more than one Atomical, splat first. A mixed output cannot be listed. ```text yarn cli splat ``` See [splat and mixed outputs](/protocol/nft/splat-and-mixed-outputs/). ## Check before signing - The Atomical ID in the listing is the one you intend. - For a name, the resolution currently points at that Atomical. - The output carries nothing else. - The price and exact payment script are correct. - The signature scope binds the payment output exactly. ## After Read the listing back. Re-check the name resolution before settlement, not only at listing time. ## Source [NFT marketplace behavior](/protocol/nft/marketplace/) and [Realm marketplace behavior](/protocol/realms/marketplace/). --- # Mint an Atomicals NFT URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/mint-an-nft/ Page ID: guides/mint-an-nft Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-js-cli, atomicals-electrumx-1.5.2.0 Verified: 2026-08-31 ## Before you start - Supported networks: mainnet. - Status: protocol behavior. - The bytes you embed are permanent and public. ## What you need | Input | Notes | | --- | --- | | The payload | A file, or a JSON document | | Media, if any | Optimised before minting. Reveal fees scale with size | | An output value | Above the relay dust threshold for the script type | | Funding | Two fees plus the output value plus grinding cost | ## The commands ```text yarn cli mint-nft yarn cli mint-nft-json ``` Options include `--satsoutput`, `--initialowner`, `--parent`, `--parentowner`, `--bitworkc`, `--bitworkr`, `--funding`, `--satsbyte`, `--rbf`. See the [CLI reference](/reference/cli/#mint-nft). ## Permanent decisions | Decision | Why | | --- | --- | | The Atomical ID | Assigned at mint | | Embedded bytes | They are in a block | | Parent linkage | Set at mint | | A name request | A different name means a different mint | Everything else is state and can change until you seal. ## Reducing cost 1. Reference shared bytes rather than embedding them per item. 2. Prefer a compact source format such as optimised SVG. 3. Estimate the reveal size with the real bytes before choosing a Bitwork prefix. ## Check before signing - The payload contains nothing private. - The media is the final version. There is no replacing it. - The output value is above the dust threshold and is a value you are content to lock. - The funding input is cardinal. - Enough remains after the commit to pay the reveal. ## After broadcast 1. Confirm, then wait for indexing. 2. Confirm the type and subtype are what you expected. 3. Record the Atomical ID. 4. Move it into your protected pool. 5. Seal only when you are certain. There is no unseal. ## Source [Minting an NFT](/protocol/nft/minting/) and [metadata and media](/protocol/nft/metadata-and-media/). --- # Mint ARC-20 URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/mint-arc20/ Page ID: guides/mint-arc20 Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-js-cli, atomicals-electrumx-1.5.2.0 Verified: 2026-08-31 Limitations: - A confirmed Bitcoin transaction is not a successful mint. Quota, height, and Bitwork are checked by the validator, not by Bitcoin. ## Before you start - Supported networks: mainnet. - Status: protocol behavior. Universe products expose decentralised mint flows. - You need funding for two fees plus the mint amount locked in output zero. In a contested mint the quota fills. Every claim after the last valid one is a confirmed Bitcoin transaction that cost a fee and produced nothing. ## Check before you build 1. Resolve the ticker to a **verified winning Atomical ID**. 2. Confirm the Atomical ID matches the one the project published. 3. Read the deployment: mode, mint amount, maximum mints, mint height, Bitwork. 4. Read claims made so far, with the height that figure came from. 5. Confirm the current height is at or past `mint_height`. 6. Confirm the current Bitwork requirement, especially for a perpetual deployment. If claims made is already at the maximum, stop. There is nothing left to claim. ## The command ```text yarn cli mint-dft ``` Useful options: `--current`, `--initialowner`, `--funding`, `--satsbyte`, `--rbf`, `--disablechalk`. See the [CLI reference](/reference/cli/#mint-dft). ## What happens 1. Commit transaction, ground if commit Bitwork applies. 2. Reveal transaction, ground if reveal Bitwork applies. 3. Output zero of the reveal carries exactly `mint_amount` satoshis. Exactly. Not at least. ## Cost Two Bitcoin fees, grinding time, and `mint_amount` satoshis locked in output zero. In a contested mint, fee rates rise, so budget above the current rate. ## If it fails | Failure | Meaning | | --- | --- | | Quota already full | The claim is invalid. The fee is spent | | Before `mint_height` | Invalid. Wait and try again | | Bitwork not met | The grind targeted the wrong requirement | | Wrong output zero amount | Invalid. It must be exact | | Ticker was a candidate, not a winner | You minted against something that does not hold the name | ## After broadcast 1. Confirm on Bitcoin. 2. Wait for indexing at that height. 3. Read the claim result. A confirmed transaction is not a successful mint. 4. If valid, read your new coloured outpoint and record it. 5. Move it into your protected pool. See [protect coloured outputs](/guides/protect-colored-outputs/). ## Source [Decentralised mint claims](/protocol/arc20/decentralized-mint/). --- # Offers URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/offers/ Page ID: guides/offers Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals Verified: 2026-08-31 ## Before you start - Supported networks: mainnet. - Status: Universe implementation. Offer gates default to off, and buy or offer execution additionally requires an exact fee script to be configured. - An offer is an intention, not a transfer. ## Making an offer 1. Obtain an owner session for the funding address. 2. Submit the offer with the asset, the amount, and any expiry. 3. Sign what the service returns, with the exact scope it specifies. Your funds are not moved by making an offer. They move only when a settlement transaction is signed and broadcast. ## Cancelling Call the cancel step for the offer identifier, with a current owner session. Cancel before the offer is accepted. Once acceptance begins, the flow moves to settlement. ## Accepting an offer As the asset owner: 1. Obtain an owner session. 2. Read the offer: the exact asset, the exact amount, and the exact payment script. 3. Confirm the asset is the Atomical ID you intend, not just a name or a ticker. 4. Accept, then sign what the service returns. 5. Verify settlement. ## What the authority checks The same independent views must agree as for a listing: verified name or ticker winner, Bitcoin Core, the Atomicals provider, and an unchanged checkpoint across the bracket. Buyer funding inputs must be confirmed and uncoloured. ## Check before signing | Check | Why | | --- | --- | | The Atomical ID | Names and tickers can be confusable | | The exact amount | Not a rounded display figure | | The exact payment script | So the payment cannot be redirected | | The signature scope | It must bind the payment output exactly | | Your funding inputs are uncoloured | Or you spend an asset to fund a purchase | ## If it fails | Failure | Meaning | | --- | --- | | Offer expired | Make a new one | | Asset moved | The owner moved it. The offer cannot settle | | Funding input coloured | Use cardinal funds | | Gate disabled | Offers are not enabled on this deployment | ## After Verify settlement. See [verify settlement](/guides/verify-settlement/). ## Source [Marketplace v1](/reference/api/marketplace-v1/). --- # Prepare BTC and protected UTXOs URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/prepare-utxos/ Page ID: guides/prepare-utxos Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0 Verified: 2026-08-31 ## Before you start - Supported networks: mainnet. - Status: protocol behavior. - You need a wallet that lists outpoints and can target a specific one. See [choose a wallet](/guides/choose-a-wallet/). ## What you need - Ordinary bitcoin, in outputs that carry no Atomicals. - A clear picture of which of your outputs are coloured. ## The procedure 1. List every unspent output and label each one coloured or cardinal. 2. If any output is unknown, treat it as coloured until a source confirms otherwise. 3. Create a cardinal pool: several ordinary outputs sized to cover a few transactions each at current fee rates. 4. Keep the pool separate. Do not let it be consolidated with coloured outputs. 5. Size your coloured lots for the transfers you expect. Several right-sized lots are safer than one large one. ## How many cardinal outputs Enough that you never have to reach for a coloured one. A practical starting point is three to five outputs, each covering a typical transaction fee with margin. Refill the pool before it runs low, not during an urgent action. ## Cost One ordinary transaction to create the pool. No Atomicals operation is involved, so no commit and reveal pair, and no grinding. ## Check before signing - Every input to the pool-building transaction is cardinal. - No coloured output appears anywhere in the input list. - The change output is cardinal. ## If it fails If the wallet insists on selecting a coloured input, it cannot do this safely. Change wallet first. ## After broadcast Confirm the new outputs are cardinal in your data source before relying on them. A freshly created output is cardinal by construction if all its inputs were cardinal. ## Source [UTXO ownership and location](/protocol/core/utxo-ownership/) and [the unit model](/protocol/arc20/unit-model/). --- # Protect coloured outputs URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/protect-colored-outputs/ Page ID: guides/protect-colored-outputs Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0 Verified: 2026-08-31 ## Before you start - Supported networks: mainnet. - Status: protocol behavior. - Nothing here spends anything. ## The problem in one sentence An ordinary Bitcoin wallet sees satoshis, so it will happily spend the output carrying your asset to pay a fee. ## The three habits **1. Two pools, always.** Coloured outputs in one place, cardinal outputs in another. Never let a tool choose across both. **2. Freeze what you can.** If the wallet supports marking outputs as unspendable, mark every coloured output. If it does not, keep them in a separate wallet entirely. **3. Never consolidate blindly.** Consolidation is an allocation event. It merges lots, can create mixed outputs, and can burn value. Model it first. ## What to check every time | Before you sign | What to confirm | | --- | --- | | The input list | Every input is the one you meant to spend | | The fee source | A cardinal input, not the asset | | Output values | In satoshis, sized deliberately | | Expected units | Per output, matching your intent | | Burn figure | Zero | ## The specific traps - **Send max.** Sweeps everything, including coloured outputs. - **Fee bump on an old transaction.** Can pull in new inputs. - **Automatic consolidation.** Some wallets do it in the background. - **Exchange deposits.** A deposit address is an ordinary Bitcoin address. Sending a coloured output there spends it as ordinary bitcoin. There is no recovery. ## If something already moved Read [verify a transaction](/guides/verify-a-transaction/) to find out exactly what happened, then [recover from a rejection](/guides/recover-from-a-rejection/) if it has not broadcast yet. A confirmed burn cannot be reversed. ## Source [Wallet safety](/protocol/arc20/wallet-safety/) and [burns](/protocol/arc20/burns/). --- # Recover from a rejection URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/recover-from-a-rejection/ Page ID: guides/recover-from-a-rejection Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0 Verified: 2026-08-31 ## First, find out which situation you are in | Situation | Recoverable | | --- | --- | | Built, not signed | Yes. Discard and rebuild | | Signed, not broadcast | Yes. Discard and rebuild | | Broadcast, rejected by the node | Yes. Nothing happened | | Broadcast, in a mempool, unconfirmed | Sometimes. Replacement may be possible | | Confirmed, Atomicals result wrong | No. The allocation is final | | Commit broadcast, reveal never sent | Yes. Rebuild the reveal | ## Rejected before broadcast Nothing happened on chain. Read the rejection reason and rebuild. | Reason | Fix | | --- | --- | | Fee too low | Raise the fee rate | | Dust output | Raise the output value above the relay threshold | | Missing input information | The builder did not supply previous output data | | Signature invalid | Wrong key, wrong flag, or a modified transaction | | Non-standard script | Use a standard output type | ## Unconfirmed in a mempool If the transaction signalled replaceability, a replacement may be possible. Do not build one casually: a replacement is a different transaction with a different allocation. 1. Model the replacement's allocation before building it. 2. Confirm the burn figure is zero. 3. Confirm no input was pulled in that you did not intend. 4. Raise the fee enough to actually replace. If it did not signal replaceability, you wait. ## Commit sent, reveal missing The value sits in a Taproot output that only your key material can spend. Rebuild the reveal with the same key material and the same envelope, and broadcast it. Do not build a different envelope: the commit committed to that exact script. If the commit did not carry enough to cover the reveal fee, you may need to fund the reveal from an additional cardinal input, if your builder supports that. ## Confirmed with a wrong result The allocation is final. Record what happened, work out which step of [avoid burns](/guides/avoid-burns/) was skipped, and change the procedure. ## Never do this while recovering - Never paste a seed phrase or private key into a recovery tool. - Never accept help from someone who asks for one. - Never rebroadcast a transaction you have not re-modelled. ## Source [Commit and reveal](/protocol/core/commit-and-reveal/) and [verify a transaction](/guides/verify-a-transaction/). --- # Resolve Unicode names URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/resolve-unicode-names/ Page ID: guides/resolve-unicode-names Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, universe-index-atomicals-nfts-and-realms Verified: 2026-08-31 Limitations: - Confusable detection reduces risk. What looks alike depends on the font and the reader, so it cannot eliminate it. ## Before you start - Supported networks: mainnet. - Status: protocol behavior for the rules, Universe implementation for the resolution service. - Do this before paying to any name. ## The procedure 1. Take the exact bytes of the name, not a rendering of it. 2. Normalise it for comparison. Keep the original bytes separately. 3. Resolve the normalised form to an Atomical ID. 4. Read that Atomical's current location and owner script. 5. Compare the name against names you already use. Look for mixed scripts and confusable characters. 6. Display the resolved address to whoever is about to act, and get their confirmation. ## Three forms, three uses | Form | Use | | --- | --- | | Exact minted bytes | Identity, storage, and what the validator saw | | Normalised form | Comparison, deduplication, confusable detection | | Display form | What a reader sees, escaped and marked when risky | Never store only the normalised form, and never display it as if it were the name. ## Warning signs - The name mixes scripts, for example Latin and Cyrillic characters in one word. - The name uses combining marks where a precomposed character is usual. - The name contains bidirectional control characters. - The name is one character different from one you already trust. - The name arrived in a message rather than from a source you control. ## If validation fails A rejected name should tell you which character and which rule. The Universe read model surfaces Unicode and IDNA errors explicitly rather than returning a generic failure, so read the error rather than guessing. ## Source [Unicode, IDNA, and confusable names](/protocol/realms/unicode-and-idna/) and [Paynames](/protocol/realms/paynames/). --- # Split and combine ARC-20 URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/split-and-combine-arc20/ Page ID: guides/split-and-combine-arc20 Applicability: protocol-behavior Authority: executed-source Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-js-cli Activation: Custom coloring with the z operation is activation gated. Verified: 2026-08-31 ## Before you start - Supported networks: mainnet. - Status: protocol behavior. Custom coloring is activation gated. - Both operations are allocation events. Model them before building. ## Combining Combining is ordinary allocation: several coloured inputs of the same token, one output large enough to take the whole sum. 1. List the lots to combine and add their values. 2. Create one output with exactly that satoshi value. 3. Fund the fee from a cardinal input, with a cardinal change output. 4. Model it. The burn figure must be zero. 5. Sign and broadcast. **Combine only lots of the same token.** Mixing tokens creates a multi token transaction subject to the output zero fallback. **Think ahead.** One large lot makes every future partial transfer depend on getting the change output size exactly right. Several right-sized lots are easier to move safely. ## Splitting Split is the `y` operation. It skips a total amount of value before colouring begins, which is what lets a builder separate several tokens sharing one input. ```text yarn cli split ``` The payload keys the skip amount by the compact Atomical ID it applies to. That is an implementation specific structure. Build it with a compatible library, never by hand from a user interface field. ## Custom coloring Custom coloring is the `z` operation and is activation gated. Where active, it attaches outputs even when the remaining value does not cover them fully, and the last attached output receives what is left rather than nothing. ```text yarn cli custom-color ``` Do not assume it is available. Read the active rule set for your network and height. ## Check before signing - Every coloured input is a lot you intend to spend. - Output values in satoshis sum the way you expect. - The burn figure is zero. - The fee comes from a cardinal input. - You modelled again after adding fee inputs and change. ## After broadcast Confirm, wait for indexing, and read your new lot structure. Record the new outpoints. ## Source [Split and combine](/protocol/arc20/split-and-combine/) and [allocation](/protocol/arc20/allocation/). --- # Transfer ARC-20 URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/transfer-arc20/ Page ID: guides/transfer-arc20 Applicability: protocol-behavior Authority: executed-source Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-js-cli Verified: 2026-08-31 Limitations: - The Universe visible transfer surface does not construct partial recipient allocations or coloured change from an amount field. Use a compatible builder that works in outpoints and output values. ## Before you start - Supported networks: mainnet. - Status: protocol behavior. - You need a wallet or builder that works in outpoints and satoshi values, not in an amount field. Sizes are in satoshis, not in a token amount box. Get one wrong and the remainder burns. ## The shape that works | Position | Contents | | --- | --- | | Input 0 | The coloured lot | | Input 1 and later | Cardinal inputs for the fee | | Output 0 | The recipient, sized to exactly the units you are sending | | Output 1 | Coloured change, sized to exactly the remainder | | Output 2 | Cardinal change, if any | ## The procedure 1. List your coloured outpoints and pick the lot to spend. 2. Decide the amount to send. That number is also the satoshi value of output 0. 3. Compute the remainder: lot value minus amount sent. That is the satoshi value of output 1. 4. Model the exact input and output set in the [allocation visualizer](/tools/allocation-visualizer/). 5. Confirm the burn figure is zero. 6. Add cardinal inputs for the fee and a cardinal change output last. 7. Re-model with the fee inputs and outputs included. The burn figure must still be zero. 8. Build the transaction, preserving your input and output order. 9. Compare the wallet prompt to your model, line by line. 10. Sign and broadcast. ## Why step seven exists Adding a fee input or a change output changes the output set, and the allocation walks outputs in order. A transfer that was clean before the wallet added change can burn after it. ## The two vectors that show the risk Same intent, same lot, same amount sent. The only difference is the change output size, and one of them destroys 200 units. ## Cost One Bitcoin fee, paid from a cardinal input. No commit and reveal pair, and no grinding, for an ordinary transfer. ## If it fails - The wallet will not let you set output values in satoshis: use a different builder. - The wallet reorders outputs: use a different builder. Order is meaning. - The burn figure is not zero: change the output sizes, do not proceed. ## After broadcast Confirm, wait for indexing, read the asset location, and check the recorded burn figure. See [verify a transaction](/guides/verify-a-transaction/). ## Source [Allocation](/protocol/arc20/allocation/) and [burns](/protocol/arc20/burns/). --- # Unavailable index or empty balance URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/unavailable-indexer-vs-empty-balance/ Page ID: guides/unavailable-indexer-vs-empty-balance Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals-nfts-and-realms, universe-index-atomicals Verified: 2026-10-07 A zero on a screen is a statement about a service, not about the chain. Before concluding anything is missing, find out which of the states below you are actually in. ## The states, and what each means | State | What it means | What to do | | --- | --- | --- | | Ready, result empty | The service answered, and there is nothing there | Check the address and asset type | | Unavailable | The service cannot answer at all | Wait and retry. Nothing is lost | | Degraded | Answering, but not from a complete view | Do not act on the answer | | Stale | Answering from an old chain position | Check the indexed height | | Mixed tip | The generation spans more than one provider tip | Do not act on the answer | | Not covered | This asset type is not in this projection | Use the right service | | Configured but not ready | Set up, not yet able to answer | Wait for readiness | ## How to tell them apart Every Universe read service exposes readiness separately from liveness: - `GET /live` says the process is running. - `GET /ready` says whether it can answer correctly, and why not when it cannot. - `GET /health` gives the state, which can be `unavailable`. - `GET /version` gives the service and provider revisions. Read `/ready` before concluding anything from an empty result. It reports the generation identifier, the indexed height, whether the view is stale, and whether the tip is mixed. ## While an index is recovering A restored database still needs integrity checks, a successful application start, and synchronization before its answers can be treated as current. Download completion and a running process are separate from readiness. If a service is restoring or catching up, show that state and its indexed height. Do not show an unavailable response as an empty balance, treat an older height as the chain tip, or substitute an external blockchain provider. Recovery reuses the existing Universe-operated indexer and its protected runtime; it does not change asset ownership or protocol rules. Wait for the service's readiness and freshness checks before using recovered results for a transaction or market decision. A recovery in progress is not a statement that an asset is missing. ## Projection coverage An empty answer can simply mean the asset type is out of scope. The Universe NFT and Realm read model projects plain NFTs, Realms, and Subrealms, and excludes fungible tokens, Containers, and DMINT items by declaration. Asking it about a Container returns nothing, correctly. {/* IMPLEMENTATION-HANDOFF [ARC20-WP05] annotation ARC20-D07 Status: ANNOTATED only. No fix, acceptance or production release is claimed. Coverage: ARC20-COV-DOCS, ARC20-COV-INVENTORY, ARC20-COV-COUNT, ARC20-COV-RECOVERY. Defects: ARC20-DEF-F01, ARC20-DEF-F04. Prerequisites: ARC20-WP01, ARC20-WP02, ARC20-WP04. 1. After acceptance, add the ARC-20 balance-summary versus current-output inventory distinction. A visible balance or a missing count defaulted to one does not prove an output is currently available; unknown must not become zero tokens, no holdings, or a measured UTXO count. 2. Explain retry for an unavailable inventory while earlier rows remain, without treating retained data as current transaction evidence. Restore, catch-up and process liveness remain separate from fresh protocol readiness. 3. Keep Universe implementation claims separate from protocol behavior. Use only owned blockchain sources; no external fallback or network-switch workaround. Isolated Testnet4 evidence must not imply mainnet availability. 4. Pin and verify the accepted source before changing visible text, verified dates, applicability or network declarations. Update translations/exports through the maintained generators, never by editing generated raw pages. Verify later: npm run generate, npm run check, npm test and npm run build; retain the generation/build-clean gates on the owned runner fleet. Rollback: restore prose and generated exports from the same verified source; do not alter the current recovery guide's visible claims in this prep stage. END IMPLEMENTATION-HANDOFF ARC20-D07 */} ## For product builders The Core ARC-20 repair candidate prepared on 9 October 2026 separates balance summary, current output inventory and seller-book reads. A missing UTXO count stays unknown. A readable summary cannot authorize listing while inventory is unavailable; retained rows are display evidence until fresh checks succeed. The candidate offers independent lot and seller-book retries. Read retry does not sign again and is separate from resolving an earlier mutation's unknown outcome under its original request key. Component coverage is not a current mainnet readiness receipt. Funded wallet flows, consumer source qualification, private Signet challenge, rules, interpreter and isolated database attestation and publisher gates remain outstanding. Do not use another network or a public data provider as an outage workaround. The existing verified dates and recovery history remain unchanged. Never render an unavailable service as a zero balance. Render the state: - "We cannot reach the index right now" for unavailable. - "Showing data from block N" for stale. - "This view does not cover that asset type" for out of scope. - "No assets found" only when the service is ready and the result is genuinely empty. ## Source [Readiness and freshness](/develop/readiness-and-freshness/) and [indexer dependency](/protocol/core/indexer-dependency/). --- # Update or remove a listing URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/update-or-remove-a-listing/ Page ID: guides/update-or-remove-a-listing Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals Verified: 2026-08-31 ## Before you start - Supported networks: mainnet. - Status: Universe implementation. Action gates default to off. - You need a current owner session. Sessions are short lived. ## Update a price 1. Obtain an owner session through the challenge and verify steps. 2. Call the update prepare step for the listing. 3. Sign what it returns, with the exact scope it specifies. 4. Call the update finalise step. The authority re-verifies collateral at a fresh checkpoint. A price change is not a metadata edit: the asset is checked again. ## Delist 1. Obtain an owner session. 2. Call the delist step for the listing. Delisting removes the offer to sell. It does not move anything on chain, because a listing never moved anything in the first place. ## Idempotency Mutations require an idempotency key. Reusing the same key for the same request is safe and returns the same result rather than performing the action twice. Use a fresh key for a genuinely new request. See [idempotency and request IDs](/develop/idempotency-and-request-ids/). ## If it fails | Failure | Meaning | | --- | --- | | Session expired | Redo the challenge and verify steps | | Asset moved | The collateral is no longer where the listing said. Relist | | Checkpoint drift | The chain moved mid-check. Retry | | Reservation active | A buyer holds a reservation. Wait for it to expire or settle | | Gate disabled | The action is not enabled on this deployment | ## Check before signing - The listing identifier is the one you intend. - The new price and payment script are correct. - The signature scope is what the prepare step specified. ## After Read the listing back and confirm the new state. If you delisted, confirm it no longer appears in the listing view. ## Source [Marketplace v1](/reference/api/marketplace-v1/). --- # Verify a transaction URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/verify-a-transaction/ Page ID: guides/verify-a-transaction Applicability: protocol-behavior Authority: executed-source Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, universe-index-atomicals-nfts-and-realms Verified: 2026-08-31 ## Before you start - Supported networks: mainnet. - Status: protocol behavior for the allocation result, Universe implementation for the read views. - Do the pre-signing half every time. It is the only part that can still prevent a loss. ## Before signing 1. List every input, with its outpoint, satoshi value, and coloured state. 2. List every output, with its script and satoshi value, in order. 3. Compute the expected allocation for that exact input and output set. Use the [allocation visualizer](/tools/allocation-visualizer/). 4. Confirm the burn figure is zero, or that any burn is deliberate. 5. Confirm no output pays an address you did not intend. 6. Confirm the fee comes from a cardinal input. 7. Confirm the signature hash flag matches what the builder said it would use. 8. Compare all of it against the wallet prompt, line by line. If any line differs from your expectation, do not sign. ## After broadcast 1. Wait for Bitcoin confirmation. 2. Wait for the index to reach that height and report a stable generation. 3. Read each moved asset by Atomical ID and confirm its current location matches the output you intended. 4. Read the transaction through a source that reports burns, and confirm the burn figure. 5. Compare the coloured input total against the sum of coloured output totals. Any difference is a burn. 6. Record the generation identifier alongside the result. ## What a block explorer tells you That the bytes are in a block. Nothing about validity, allocation, or burns. An ordinary explorer does not evaluate Atomicals rules. ## Reorg considerations A result computed inside the reorg window is not settled. For anything with value at stake, wait for depth appropriate to the amount, then re-read rather than trusting the first answer. See [confirmations and reorgs](/guides/confirmations-and-reorgs/). ## If the result is wrong - Not yet broadcast: [recover from a rejection](/guides/recover-from-a-rejection/). - Broadcast but unconfirmed: replacement may be possible if the transaction signalled it. Do not build a replacement without modelling its allocation first. - Confirmed with a burn: the units are gone. Record what happened and change the procedure that produced it. ## Source [Allocation](/protocol/arc20/allocation/) and [burns](/protocol/arc20/burns/). --- # Verify settlement URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/verify-settlement/ Page ID: guides/verify-settlement Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals Verified: 2026-08-31 ## Before you start - Supported networks: mainnet. - Status: Universe implementation. - A settlement status is a product state. Verify the chain and the index separately. ## The procedure 1. Read the settlement record for the order. Note the settlement transaction id. 2. Confirm that transaction on Bitcoin. 3. Wait for the index to reach that height and report a stable generation. 4. Read the asset by Atomical ID and confirm its current location is an output you control. 5. Confirm the payment output paid the expected script and value. 6. Confirm the transaction recorded no burn. 7. Record the generation identifier alongside the result. Step four is the one that matters. A settlement status without a confirmed location change is not a completed trade. ## What each side verifies | Party | Verifies | | --- | --- | | Buyer | The asset is now at an output they control, and no burn occurred | | Seller | The payment output paid the exact script and value they signed for | ## Reconciliation The service exposes a settlement read for each order, and an operator-only reconcile action. Reconciliation is for resolving a service-side record against the chain. It is not a way to undo a confirmed settlement. ## If something is wrong | Symptom | What it means | | --- | --- | | Settled status, asset not moved | Read the settlement transaction. It may not have confirmed | | Asset moved, payment missing | Read the payment output. This should be impossible under exact binding | | Neither moved | Nothing settled. Nothing was spent | | Index behind | Wait for the height. Do not conclude anything yet | ## Reorg considerations A settlement confirmed inside the reorg window is not final. For a significant amount, wait for depth appropriate to the value and re-read rather than trusting the first answer. ## Source [Marketplace v1](/reference/api/marketplace-v1/) and [confirmations and reorgs](/guides/confirmations-and-reorgs/). --- # Wallet signing failures URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/guides/wallet-signing-failures/ Page ID: guides/wallet-signing-failures Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals Verified: 2026-08-31 Limitations: - Provider capabilities vary between wallets and versions. Discover capability before building, rather than after a failure. ## The four categories Almost every signing failure is one of these. **Capability.** The wallet does not support the thing you asked for: a script type, a signature hash flag, a PSBT feature, or message signing. **Encoding.** The PSBT is a form the wallet cannot read, or is missing information it needs. **Scope.** The signature hash flag is not one the wallet will produce, or not one you should accept. **State.** The wallet is locked, disconnected, on the wrong network, or on a different account. ## Diagnosing, in order 1. **Is the wallet unlocked and connected?** Reconnect and try again. 2. **Is it on the right network?** A mainnet PSBT presented to a testnet account fails. 3. **Is the account the one that owns the input?** Check the derivation path. 4. **Does the input carry everything the wallet needs?** Previous output script and value, derivation information, and for Taproot the internal key and merkle root. 5. **Is the signature hash flag supported?** Ask the provider what it supports rather than guessing. 6. **Is the PSBT encoding one the provider accepts?** Providers differ on hex against base64. 7. **Is it sign only or sign and broadcast?** Some providers broadcast automatically. Know which before you sign. ## What you should refuse to sign - A PSBT whose outputs you cannot see in full, with scripts and values. - A signature hash flag that does not commit to the outputs you care about. - A swap where the payment output to you is not bound exactly. - Anything where the wallet cannot tell you which inputs are coloured. ## For integrators Discover capability first. Ask the provider what script types, flags, and encodings it supports, then build for that. Normalise errors so a user sees the category rather than a raw provider message. See [wallet integration](/reference/wallet-integration/). ## After a failed signature Nothing was broadcast, so nothing happened. Rebuild for the capability the wallet actually has, or use a different wallet. ## Source [PSBT requirements](/protocol/arc20/psbt-requirements/) and [wallet safety](/protocol/arc20/wallet-safety/). --- # Offline URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/offline/ Page ID: offline Applicability: editorial Authority: none Networks: none Sources: none Verified: 2026-09-02 Credentials, user-supplied endpoints, live API responses, imported UTXO data, question history, and local lab information are never written to the offline cache. The service worker handles same-origin static assets only. ## Install the app Use your browser's install action, or the install prompt this site raises after the first visit. The installed app carries the current documentation build, offline search over everything you have read, and every tool that runs without a network: the allocation visualizer, transaction inspector, Bitwork estimator, Protocol Lab, and UTXO Safety Planner. The offline bar at the bottom of every page shows offline status, announces documentation version updates, and can remove all offline data on request. ## Protocol packs Versioned archives bundle the documentation and machine-readable artifacts for fully offline use, with SHA-256 checksums, a software bill of materials, and build provenance: | Pack | Contents | | --- | --- | | Full | Documentation, raw Markdown, search index, contracts, clients, skills, agent material | | Docs | Documentation and offline search only | | Developer | Contracts, conformance vectors, overlays, generated clients | | AI agent | Agent Skill, workflow catalog, answer index, manifests | Regenerate from source with `npm run packs:generate`. Archives and their `.sha256` files appear in `dist-packs/`, and release versions ship with each repository release. ## Offline test gate The offline experience is verified by a browser test with network access disabled: cached navigation, offline search, and the static tools must all work without a connection. --- # Protocol Atlas URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol-atlas/ Page ID: protocol-atlas Applicability: editorial Authority: none Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, ordinals-ord, brc-20-spec, bitcoin-stamps, alkanes-alkanes-rs, counterparty-lib, rgb-core Verified: 2026-09-02 Limitations: - The TAP row records unknown because no verifiable official source was reachable during verification. It upgrades the moment one is. - Comparative rows for third-party protocols describe their reference implementations at pinned revisions; they are context, not endorsements. - No row implies that any protocol is better than another. The decision explorer compares requirements; it never ranks. No prices. No market data. No rankings. No claim that any protocol is superior. Every cell is an evidence object with a status and a pinned revision: where evidence is missing, the cell says unknown instead of guessing. The Protocol Atlas compares Atomicals, ARC-20, AVM, Ordinals, Runes, BRC-20, Bitcoin Stamps and SRC-20, TAP, Alkanes and Protorunes, Counterparty, and RGB. The dataset behind every view is [machine-readable](../../contracts/protocol-atlas/atlas.json) and validated against a published JSON Schema, so the page, the exports, and the MCP resources all describe the same evidence. Four views cover one dataset: 1. **Matrix.** Column selection, search, status filters, compact or detailed cells, comparison of up to four protocols side by side, and CSV or JSON export. The state is shareable through the URL. 2. **Relationship map.** Which shared Bitcoin primitive each protocol builds on, with a table equivalent. Edges never imply lineage that a pinned source does not support. 3. **Timeline.** Activation points the sources support. The AVM marker is a pinned beta interpreter, deliberately not drawn as a deployment. 4. **Decision explorer.** Concrete neutral questions about your requirements, answered with a transparent match and miss list per protocol. It compares; it does not recommend. ## How evidence works here Every fact in the dataset carries `value`, `status`, `sourceId`, `sourceRevision`, `verifiedAt`, and optional notes. Statuses are `verified`, `implementation-specific`, `proposal`, `experimental`, `unknown`, and `conflicting`. Cell rendering shows unknown and conflicting exactly as recorded. The [source manifest](sources/) holds the pinned repositories and revisions. Where this page and a protocol's own documentation disagree, the disagreement is recorded as a status rather than resolved by an editor. --- # Atomicals Improvement Proposals URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/aips/ Page ID: protocol/aips Applicability: proposed Authority: aip Networks: mainnet Sources: atomicals-aips, universe-index-atomicals-nfts-and-realms Verified: 2026-08-31 Limitations: - The register reflects the vendored snapshot at the pinned revision. A proposal added upstream since then is not shown until the snapshot is refreshed by CI. - An AIP is never marked implemented because it exists. Only the evidence file can establish that. An AIP is a design document. It proposes something. It does not, by existing, change any implementation. Nothing here is labelled implemented unless a row in `contracts/aip-implementation-evidence.json` names the source that establishes it. Where no evidence exists, the register says so plainly. ## The register The register is generated by `scripts/generate-aip-registry.mjs` from a vendored snapshot of the proposals plus the evidence file. Neither the table nor the evidence is hand maintained on this page. ## The status model An AIP sits in exactly one status. The generator rejects any value outside this set. | Status | Meaning | | --- | --- | | Idea | Not yet submitted as a formal draft | | Draft | Formally submitted and under development | | Review | Ready for peer review | | Last Call | Final review window before acceptance | | Final | Accepted as a standard | | Stagnant | Inactive for an extended period | | Withdrawn | Withdrawn by the authors | | Living | Continually updated, never final | ## Conformance levels Separate from AIP status, and about implementations rather than the proposal. | Level | Meaning | | --- | --- | | `proven` | An executed test or a runtime contract check establishes the behavior at a pinned revision | | `claimed` | An implementation reports it. Nothing here executes a check against that claim | | `none` | No implementation evidence was located | A Draft AIP can have `proven` conformance, and a Final AIP can have `none`. The two axes are independent, and collapsing them is how a proposal ends up described as a shipped feature. ## What the Universe index actually checks The Universe NFT and Realm index requires its Atomicals provider to report the exact AIP set `[1, 3]` during the provider handshake, and refuses the provider otherwise. That is a real runtime contract check, and it is the evidence recorded for AIP-3. It proves the provider reports that set. It is not an independent re-verification of the serialisation change the proposal describes. ## Proposing a change to the register The register follows the upstream proposals. To correct implementation evidence, open an issue in the [documentation repository](https://github.com/bitcoinuniverseio/atomicals-and-arc-20/issues) using the **new AIP** or **source version update** template, and include the source and revision that establishes the claim. --- # Allocation URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/arc20/allocation/ Page ID: protocol/arc20/allocation Applicability: protocol-behavior Authority: executed-source Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-electrumx-1.5.2.0 Activation: Custom coloring with the z operation is activation gated. Normal allocation is not. Verified: 2026-08-31 Limitations: - The engine behind these vectors models normal allocation. It is explanatory and never a substitute for validating a concrete transaction against your target validator revision. Allocation is the single most important rule in ARC-20. It decides which output receives which units, and what is destroyed. ## The rule 1. Collect the coloured value carried by the transaction's inputs, summed per token. 2. Order the tokens. FIFO ordering uses the first input index that carries each token, then the Atomical ID. Legacy ordering uses the Atomical ID alone. 3. For each token in that order, walk the outputs starting at the first slot not already used. 4. Skip provably unspendable outputs entirely. They consume nothing. 5. Assign an output **only if its whole satoshi value fits** in the value still to place. 6. If it fits, that output is coloured for its full satoshi value, and the remaining value drops by that amount. 7. If the next output does not fit, stop. Whatever is left is burned. 8. If any token could not be placed cleanly, the builder discards the sequential plan and restarts every token from output zero. 9. Coloured output totals can never exceed coloured input totals. ## What "fits" means, precisely An output fits when `output.value <= remaining`. Nothing is ever partially filled under normal allocation. An output either takes its full satoshi value in units, or it takes nothing. Step seven is not an error path. The Bitcoin transaction is valid and confirms. See [burns](/protocol/arc20/burns/). ## Executed vectors Every row below is computed at build time by the same engine the conformance tests run. The numbers on this page cannot drift from the vector set. The vector set lives at `conformance/vectors/arc20-allocation.json` and its engine at `conformance/allocation.mjs`. See [conformance](/reference/conformance/). ## The output zero fallback Step eight surprises people. When the sequential plan cannot place a token cleanly, the reference builder throws away the whole plan and restarts every token from output zero. With more than one token in the transaction, that can move value you thought was settled and can burn a token that would otherwise have been fine. The `two-tokens-non-clean-fallback` vector above shows it. Build transactions that never trigger it. ## No inflation Coloured output totals can never exceed coloured input totals. A blueprint that tries is rejected. This is the one rule that cannot be worked around by output arrangement. ## What changes the result | Input | Effect | | --- | --- | | Coloured input value | The total to place | | Input order | Token ordering under FIFO | | Output order | Which slot is considered next | | Output satoshi values | Whether each output fits | | Unspendable outputs | Skipped, consuming nothing | | Active rule set | Whether custom coloring applies | | Number of distinct tokens | Whether the fallback can trigger | --- # ARC-20 Bitwork requirements URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/arc20/bitwork-requirements/ Page ID: protocol/arc20/bitwork-requirements Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-js-cli Verified: 2026-08-31 Four Bitwork fields appear around ARC-20. They apply to different transactions and different people. | Field | Applies to | Set by | | --- | --- | --- | | `bitworkc` | The deployer's own commit transaction | The deployer, per invocation | | `bitworkr` | The deployer's own reveal transaction | The deployer, per invocation | | `mint_bitworkc` | Every claimant's commit transaction | The deployment, for everyone | | `mint_bitworkr` | Every claimant's reveal transaction | The deployment, for everyone | The two `mint_` fields are the ones that matter to a minter. They come from the deployment and apply to every claim, regardless of what the deployer paid for their own transactions. ## Reading them correctly 1. Read the deployment record, not the deployer's transaction. 2. For a perpetual deployment, read the current requirement rather than the initial one. 3. Apply the commit requirement to the commit transaction id and the reveal requirement to the reveal transaction id. They are separate searches. 4. Recompute your fee estimate after a successful grind, because grinding changed the transaction. ## Cost Each extra hexadecimal character multiplies expected attempts by sixteen. See [Bitwork](/protocol/core/bitwork/) for the table and the [Bitwork estimator](/tools/bitwork-estimator/) to model a specific prefix. ## CLI options From the generated inventory, the relevant flags are `--bitworkc`, `--bitworkr`, `--mintbitworkr`, and `--disablechalk`. See the [CLI reference](/reference/cli/). ## What Bitwork does not do It does not reserve the ticker, prove identity, guarantee your claim wins the quota race, or make the mint fair. It raises the cost of spam. --- # Burns URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/arc20/burns/ Page ID: protocol/arc20/burns Applicability: protocol-behavior Authority: executed-source Networks: mainnet Sources: atomicals-electrumx-1.5.2.0 Verified: 2026-08-31 Limitations: - A confirmed burn is permanent. Nothing in this documentation can reverse one. A burn is coloured value that a validator could not place in any eligible output. It is recorded as destroyed. The Bitcoin transaction that caused it is valid, mined, and confirmed. Burned units do not go anywhere. There is no address that holds them and no procedure that returns them. Prevention is the only control. ## The four shapes that cause a burn ### 1. The next output is too large The most common. You have 500 units left to place and the next output is 546 satoshis. It does not fit, so the 500 units are destroyed. **Prevention.** Size the change output to exactly the remainder you intend to keep. ### 2. There are not enough outputs Every output was covered and value is still left. Nothing remains to place it in. **Prevention.** Always include a coloured change output when the inputs exceed what you are sending. ### 3. The first output is larger than the whole lot Nothing can be placed at all, so the entire lot burns. **Prevention.** Never send a small coloured lot into a transaction whose first output is a large cardinal payment. ### 4. The fallback rearranged a multi token transaction One token could not be placed cleanly, so the builder restarted every token from output zero and a different token lost its slot. **Prevention.** Move one token per transaction unless you have modelled the multi token case. ## Executed cases ## The checks that prevent all four 1. Compute the expected assignment before signing, not after. 2. Confirm the burn figure is zero. 3. Size every coloured output deliberately, in satoshis. 4. Keep fee inputs cardinal and separate. 5. Move one token per transaction unless you have a reason not to. 6. Re-check after any change to the output set, including a wallet adding change. Use the [allocation visualizer](/tools/allocation-visualizer/) to do steps one and two. ## Detecting a burn after the fact A validator records burns per transaction. Read the transaction through a source that reports them, and compare the coloured input total against the sum of coloured output totals. Any difference is a burn. The Universe ARC-20 activity feed publishes burn records among its confirmed activity. See [ARC-20 API](/reference/api/arc20/). --- # Decentralised mint claims URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/arc20/decentralized-mint/ Page ID: protocol/arc20/decentralized-mint Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-js-cli Verified: 2026-08-31 Limitations: - Claim validity depends on the state of the deployment at the height of the claim. A claim built against stale deployment state can confirm and still be invalid. A claim is the `dmt` operation. It mints exactly the deployment's `mint_amount` into output zero, if every condition is satisfied. ## The reference command ```text yarn cli mint-dft ``` Options from the generated inventory include `--current`, `--initialowner`, `--funding`, `--satsbyte`, `--rbf`, `--disablechalk`. See the [CLI reference](/reference/cli/#mint-dft). ## Conditions for a valid claim 1. The claim occurs at or after the deployment's `mint_height`. 2. The relevant commit and activation constraints are satisfied. 3. The configured mint quota is not already exhausted. 4. Any `mint_bitworkc` or `mint_bitworkr` requirement is met. 5. Output zero carries exactly `mint_amount` satoshis. Condition five is exact. Not at least, not approximately. Exactly. ## Why a confirmed claim can be worthless Conditions one, three, and four are evaluated by the validator, not by Bitcoin. A claim that misses any of them still produces a confirmed Bitcoin transaction that cost a fee and minted nothing. The most common case is condition three. In a contested mint, many claimants broadcast at once and the quota fills. Every claim after the last valid one is a confirmed transaction with no units. ## What a minter should check first | Check | Why | | --- | --- | | The ticker resolves to a verified winner | Otherwise you are minting against a candidate | | The deployment's Atomical ID | Names can be confusable. IDs are not | | Claims already made against the quota | To know whether any remain | | The exact `mint_amount` | Your output zero must match it exactly | | The Bitwork requirement | It comes from the deployment, not from you | | Current fee rates | Contested mints get expensive | ## What a product must display - The resolved Atomical ID next to the ticker. - Claims made against the maximum, with the height the figure was computed at. - The exact amount output zero will carry. - The Bitwork requirement, if any. - A clear statement that a confirmed transaction is not a successful mint. ## After the claim Wait for confirmation, then for the index to reach that height, then read the result. A claim that looks successful in a mempool view can still lose the quota race. See [confirmation and reorgs](/protocol/core/confirmation-and-reorgs/). --- # Direct FT issuance URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/arc20/direct-issuance/ Page ID: protocol/arc20/direct-issuance Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-js-cli, atomicals-guide Verified: 2026-08-31 Limitations: - No Universe product surface exposes direct FT issuance. This page documents protocol behavior only. Direct issuance is the `ft` operation. It creates the whole supply of a token in one commit and reveal pair, and places all of it in output zero of the reveal transaction. ## The reference command ```text yarn cli mint-ft ``` Common options from the generated inventory: `--bitworkc`, `--bitworkr`, `--initialowner`, `--parent`, `--parentowner`, `--funding`, `--satsbyte`, `--rbf`, `--disablechalk`. See the [CLI reference](/reference/cli/#mint-ft). ## What the supply figure means Because one unit is one satoshi, the supply argument is also the satoshi value that output zero must carry. A direct mint of 100 000 000 units requires a 100 000 000 satoshi output, which is one bitcoin. | Supply | Satoshis needed in output zero | | --- | --- | | 21 000 | 21 000 | | 1 000 000 | 1 000 000 | | 100 000 000 | 100 000 000, one bitcoin | | 2 100 000 000 | 2 100 000 000, twenty one bitcoin | That constraint is the whole point. A direct supply cannot be conjured. It is bitcoin you actually committed. ## What it is not Direct issuance is a colouring model. It does not create: - collateral; - a redemption right; - a price floor; - a peg to anything. Do not describe it in those terms, and do not accept a product that does. ## Ticker rules The pinned validator accepts direct FT tickers matching lowercase `[a-z0-9]{1,21}`. That is a source-revision fact. Validate against the exact active target rather than hardcoding it. See [tickers and candidates](/protocol/arc20/tickers-and-candidates/). ## After the mint Output zero holds the whole supply as one coloured lot. Before distributing anything, decide the lot structure you want and model each split. A single large lot is easy to burn when the first transfer gets its change output size wrong. See [allocation](/protocol/arc20/allocation/) and [split and combine](/protocol/arc20/split-and-combine/). ## Universe status Not exposed. Universe products offer decentralised deploy and mint flows, not direct `mint-ft` issuance. See [status and known limitations](/start/status-and-limitations/). --- # Fixed DFT deployment URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/arc20/fixed-dft/ Page ID: protocol/arc20/fixed-dft Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-electrumx-1.5.2.0, atomicals-js-cli Activation: Mint count limits have legacy and later density variants. The applicable limit depends on the active rule set. Verified: 2026-08-31 Limitations: - Do not present a fixed deployment as valid without checking the target network's active rules. A fixed DFT deployment is the `dft` operation. It does not create units. It publishes the rules that later `dmt` claims must satisfy. ## The reference command ```text yarn cli init-dft ``` There is also `init-dft-fixed`. See the [CLI reference](/reference/cli/#init-dft). ## Deployment parameters at the pinned revision | Field | Meaning | Pinned behavior | | --- | --- | --- | | `request_ticker` | The ticker requested | Validated by the active ticker rule | | `mint_height` | Earliest block height for claims | Integer from 0 through 10 000 000 | | `mint_amount` | Satoshis each valid claim places in output zero | 546 through 100 000 000 | | `max_mints` | Number of valid fixed mode claims | At least 1. The maximum is activation dependent | | `mint_bitworkc` | Optional commit Bitwork for claimants | Evaluated by the active implementation | | `mint_bitworkr` | Optional reveal Bitwork for claimants | Evaluated by the active implementation | ## Nominal maximum issuance ```text maximum issuance = mint_amount * max_mints ``` This is a ceiling on what claims can produce. It is not a promise the ceiling is reached, and it is not a circulating supply figure. Report actual issuance from claim records, never from the deployment parameters alone. ## What a client must check before showing a deployment as valid 1. The ticker resolved to a verified winner, not just a request. 2. `mint_height` is within the accepted range for the active rules. 3. `mint_amount` is within the accepted range for the active rules. 4. `max_mints` is within the limit active on that network at that height. 5. Any Bitwork requirement is read from the deployment, not assumed. 6. The active rule set is the one your target validator runs. Skipping step four is the common failure. The pinned source has legacy and density-activation mint count limits, and a deployment valid under one is not valid under the other. ## Displaying progress | Figure | Where it comes from | | --- | --- | | Maximum issuance | `mint_amount * max_mints` | | Claims made | Counted valid `dmt` claims | | Circulating | Sum of coloured value actually held, after burns | | Remaining | `max_mints` minus claims made | Circulating is not claims multiplied by mint amount, because units can burn after they are minted. --- # Metadata and decimals URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/arc20/metadata-and-decimals/ Page ID: protocol/arc20/metadata-and-decimals Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-guide, atomicals-electrumx-1.5.2.0 Verified: 2026-08-31 ARC-20 metadata is an optional JSON object supplied by the minter. Common fields are `name`, `desc`, `image`, `decimals`, `links`, and `legal`. ## Treat all of it as untrusted Metadata is arbitrary content written by whoever minted the token. It is never checked. See [metadata trust boundaries](/protocol/core/metadata-trust/) for the renderer and interface rules. | Field | What it does | What it proves | | --- | --- | --- | | `name` | A display label | Nothing | | `desc` | A description | Nothing | | `image` | A media reference | Nothing about rights or origin | | `links` | Social or site links | Nothing about affiliation | | `legal` | Legal text | Nothing enforceable is created by writing it | | `decimals` | Display formatting | Nothing about the unit model | ## The decimals rule **`decimals` is presentation metadata. It never creates sub-satoshi units.** Native ARC-20 quantities are integers, always. A token with `decimals` of 8 and 100 000 000 native units may be displayed as 1.00000000. On chain there are 100 000 000 coloured satoshis. ### The bug this prevents A product reads `decimals` of 8, divides every native quantity by 100 000 000 for display, and then feeds a formatted figure back into a transfer builder. The builder now asks for a fraction of a satoshi, or rounds to something the user did not intend. ### The rule that prevents it 1. Store and compute in native integer units only. 2. Format for display at the last moment, in the view layer. 3. Never parse a formatted figure back into a quantity. 4. Never let a formatted figure reach a transaction builder. 5. Treat a missing `decimals` as zero, not as a default of eight. ## Sanitisation Before displaying any metadata field: - escape it, always; - strip or refuse markup; - validate that link targets are absolute HTTP or HTTPS URLs; - mark external links as external and do not follow them automatically; - check the name for confusable characters against tokens the user already holds. --- # ARC-20 URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/arc20/overview/ Page ID: protocol/arc20/overview Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-electrumx-1.5.2.0, atomicals-guide Verified: 2026-08-31 Limitations: - This is a compatibility guide, not an independent consensus specification. The Atomicals specification is defined in code. ARC-20 is the Atomicals fungible token model on Bitcoin. One unit is one coloured satoshi. Everything else follows from that. ## The complete model in seven statements 1. A unit is a satoshi in an output a validator recognises as coloured for a token. 2. Supply is therefore measured in satoshis, and is bounded by real bitcoin. 3. Issuance happens once, directly, or repeatedly through a deployment others mint against. 4. A ticker is a globally allocated name resolved to exactly one Atomical. 5. A transfer is an allocation over the transaction's inputs and outputs, in order. 6. Value that cannot be placed in an eligible output is destroyed. 7. Coloured output totals can never exceed coloured input totals. Read [burns](/protocol/arc20/burns/) before you build or sign anything. ## Where each rule is documented | Area | Page | | --- | --- | | The unit model and why decimals do not create fractions | [Unit model](/protocol/arc20/unit-model/) | | Ticker allocation, candidates, and verified winners | [Tickers and candidates](/protocol/arc20/tickers-and-candidates/) | | One step issuance of a complete supply | [Direct issuance](/protocol/arc20/direct-issuance/) | | Deployments with a fixed number of mints | [Fixed DFT](/protocol/arc20/fixed-dft/) | | Claiming a mint against a deployment | [Decentralised mint](/protocol/arc20/decentralized-mint/) | | Activation gated progressive deployments | [Perpetual DFT](/protocol/arc20/perpetual-dft/) | | Work requirements on commit and reveal | [Bitwork requirements](/protocol/arc20/bitwork-requirements/) | | Optional metadata and presentation decimals | [Metadata and decimals](/protocol/arc20/metadata-and-decimals/) | | How value is placed into outputs | [Allocation](/protocol/arc20/allocation/) | | Separating and recombining coloured lots | [Split and combine](/protocol/arc20/split-and-combine/) | | How value is destroyed | [Burns](/protocol/arc20/burns/) | | Moving tokens and swapping them atomically | [Transfers and swaps](/protocol/arc20/transfers-and-swaps/) | | What a PSBT must contain | [PSBT requirements](/protocol/arc20/psbt-requirements/) | | What a wallet must do to be safe | [Wallet safety](/protocol/arc20/wallet-safety/) | | The status of Substantiation Factor material | [Substantiation Factor](/protocol/arc20/substantiation-factor/) | ## What ARC-20 is not - Not an ERC-20 contract. There is no contract and no account. - Not an inscription balance. Value is the satoshi value of outputs, not a number written in text. - Not a claim on anything. Nothing backs a unit unless a separate legal arrangement exists, and none is created by minting. - Not an ARC-721 standard. No official source located during review establishes one. ## Universe product boundary The protocol supports direct `mint-ft` issuance. No Universe product surface exposes it today. Universe exposes verified ticker resolution, token details, holders, confirmed activity, portfolio balances, coloured UTXOs, and Marketplace v1 flows. See [status and known limitations](/start/status-and-limitations/). --- # Perpetual DFT URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/arc20/perpetual-dft/ Page ID: protocol/arc20/perpetual-dft Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-js-cli Activation: Perpetual mode is activation gated. It is not available on every network at every height. Verified: 2026-08-31 Limitations: - Do not display a fixed supply cap for a perpetual deployment unless the actual deployment and the active implementation establish one. Perpetual DFT is not a fixed deployment with a very large `max_mints`. The pinned implementation treats it as a separate, activation gated mode with its own parameters. ## What is different | Aspect | Fixed DFT | Perpetual DFT | | --- | --- | --- | | Availability | Generally available | Activation gated | | Bitwork | Set once by the deployment | Progresses through a vector over time | | Mint count | Bounded by `max_mints` | Governed by progression parameters | | Supply cap | `mint_amount * max_mints` | Optional global maximum, which may be absent | | Display | A cap can be shown | A cap must not be invented | ## The reference command ```text yarn cli init-dft-perpetual ``` See the [CLI reference](/reference/cli/#init-dft-perpetual). ## The mistake to avoid A user interface that reads perpetual parameters and prints a supply cap computed as if the deployment were fixed will print a wrong number. It may print a number where none exists. Read the actual deployment and the target implementation before calculating or displaying any cap. When no global maximum is configured, say that plainly instead of showing a figure. ## Progressing Bitwork The requirement changes as minting progresses, which means: - a claimant's grinding cost is not constant; - a claim built against a stale requirement fails; - a product that caches the requirement will mislead its users. Read the requirement at build time, for the height you are targeting. See [Bitwork](/protocol/core/bitwork/). ## What a product must display 1. That the deployment is perpetual, labelled as such. 2. The current Bitwork requirement and when it was read. 3. The global maximum if one is configured, and a clear "no configured maximum" if not. 4. Issuance to date, computed from claim records. 5. The activation state of perpetual mode on the target network. --- # PSBT requirements URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/arc20/psbt-requirements/ Page ID: protocol/arc20/psbt-requirements Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: universe-index-atomicals, atomicals-electrumx-1.5.2.0 Verified: 2026-08-31 Limitations: - Wallet support for specific signature hash flags and PSBT encodings varies. Verify capability before building, not after a signing failure. A PSBT is the exchange format between a service that builds a transaction and a wallet that signs it. For Atomicals, a PSBT that omits context is a PSBT that cannot be signed safely. ## What every input must carry | Field | Why | | --- | --- | | The previous output script and value | So the wallet can verify what it is spending | | Whether the input is coloured, and for which Atomical | So the wallet can warn before spending an asset | | The signature hash flag to use | So the signer commits to the intended scope | | Derivation information for the signing key | So the wallet can find the key | | Tap internal key and merkle root for Taproot inputs | So key-path signing works | ## What every output must carry | Field | Why | | --- | --- | | Exact script | So the recipient cannot be redirected | | Exact value in satoshis | So allocation is deterministic | | The expected coloured assignment | So the signer can compare against their intent | ## Signature hash flags A flag that does not commit to all outputs lets someone else change the outputs after you sign. For a swap, the seller's signature must commit to the exact output that pays them. A builder must state, per input, which flag it expects. A wallet must show which flag it is about to use. A signer must reject a flag they did not expect. ## Ordering Input order and output order are part of the meaning. A wallet or library that reorders inputs or outputs for canonicalisation changes the allocation result. Do not reorder an Atomicals PSBT. ## Protected outputs A wallet must refuse to select a coloured output for fees unless the user explicitly approved spending that asset. This is the single most valuable wallet feature for Atomicals. See [wallet safety](/protocol/arc20/wallet-safety/). ## Validation before signing Before presenting a PSBT for signature, a builder should: 1. Resolve every input's coloured state at a stable chain position. 2. Compute the expected allocation for the exact output set. 3. Assert the burn total is zero, or make the intended burn explicit. 4. Assert no unexpected Atomicals operation is present. 5. Assert output totals do not exceed input totals per token. 6. Record the chain position, and re-validate if it moved. The [transaction inspector](/tools/transaction-inspector/) performs a read-only version of steps one to five locally, without uploading anything. --- # Split and combine URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/arc20/split-and-combine/ Page ID: protocol/arc20/split-and-combine Applicability: protocol-behavior Authority: executed-source Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-js-cli Activation: Custom coloring with the z operation is activation gated and must not be assumed universally available. Verified: 2026-08-31 Limitations: - Split and custom coloring payload shapes are implementation specific. Do not hand-assemble them from a user interface amount field. ## Combining Combining is not an operation. It is ordinary allocation with several coloured inputs of the same token and one output large enough to take the whole sum. The `combine-two-lots` case in the [allocation vectors](/protocol/arc20/allocation/) shows it: 700 units plus 500 units into a 1200 satoshi output, cleanly, with nothing burned. Two cautions: - Combining tokens that are **not** the same is not combining. It creates a multi token transaction subject to the output zero fallback. - Combining collapses your lot structure. If you later need a 500 unit transfer and hold one 1200 unit lot, you now depend on getting the change output size exactly right. ## Splitting Split is the `y` operation. At the pinned revision it lets a builder skip a total amount of value before it begins colouring outputs, which is what makes it possible to separate several tokens that share one input. The payload keys the skip amount by the compact Atomical ID of the token it applies to. That is an implementation specific structure, not a general purpose amount field. The reference CLI exposes `split `. See the [CLI reference](/reference/cli/). ## Custom coloring Custom coloring is the `z` operation and is activation gated. Where it is active, the builder attaches outputs even when the remaining value does not cover them fully, and the last attached output receives only what is left rather than nothing. The `custom-coloring-partial-fill` case in the [allocation vectors](/protocol/arc20/allocation/) shows the difference: the same transaction that burns 500 units under normal allocation places them as a partial fill under custom coloring. Never assume custom coloring is available. Read the active rule set for the network and height you are targeting. See [activation boundaries](/protocol/core/activation-boundaries/). The reference CLI exposes `custom-color`. See the [CLI reference](/reference/cli/). ## Splat is not a fungible operation The `x` splat operation belongs to the non-fungible branch. It separates multiple Atomicals held at one output. It is not a general ARC-20 transfer or split mechanism. See [splat and mixed outputs](/protocol/nft/splat-and-mixed-outputs/). ## Practical lot management | Goal | Approach | | --- | --- | | Keep transfers simple | Hold several lots sized for the transfers you expect | | Reduce fee cost | Combine, but only after you know your future split sizes | | Move part of a lot | Send plus a change output sized to the exact remainder | | Separate tokens at one input | Split, with a payload built by a compatible library | | Avoid the fallback | One token per transaction | --- # Substantiation Factor URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/arc20/substantiation-factor/ Page ID: protocol/arc20/substantiation-factor Applicability: proposed Authority: none Networks: mainnet Sources: none Verified: 2026-08-31 Limitations: - No applicable source revision or conformance suite was located that establishes Substantiation Factor as implemented behavior. This page therefore states status only. Substantiation Factor material is preliminary. Nothing about it is protocol behavior, Universe implementation, or a supported product capability at the verified date on this page. ## What status means here This documentation labels a capability by evidence, not by intent. To move Substantiation Factor material out of `Proposed`, all of the following would be required: 1. An applicable source revision that implements it, pinned by commit or release. 2. A statement of which networks and activation conditions apply. 3. Deterministic conformance vectors that execute against that revision. 4. A record of what the vectors prove and what they do not. 5. Either a Universe implementation revision that exposes it, or an explicit statement that no product surface does. None of those exist at the verified date. ## What must not be claimed in the meantime - That units are backed, collateralised, redeemable, or price supported. - That any substantiation figure is computed from chain data by a Universe service. - That a product feature depends on it. - That an integration should read a field for it. If you encounter material presenting Substantiation Factor as live behavior, treat it as unverified and report it as an [incorrect protocol claim](https://github.com/bitcoinuniverseio/atomicals-and-arc-20/issues). ## What ARC-20 actually is One coloured satoshi is one unit. Supply is bitcoin you committed. Nothing else is created by minting. See [the unit model](/protocol/arc20/unit-model/). --- # Tickers and candidates URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/arc20/tickers-and-candidates/ Page ID: protocol/arc20/tickers-and-candidates Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-electrumx-1.5.2.0, atomicals-guide Verified: 2026-08-31 Limitations: - The ticker character rule is a fact about the pinned revision. Validate names against the exact active target rather than hardcoding a display rule. A ticker is a globally allocated ARC-20 name. It is requested inside a mint payload as `request_ticker`, and the rules decide whether that request becomes a verified winner. ## The name rule at the pinned revision The pinned validator accepts direct FT tickers matching lowercase `[a-z0-9]{1,21}`. That is a source-revision fact. It is not a promise that every historical or future validator uses the same rule. A builder must validate names against the exact active target. ## Requested, candidate, verified | Field | Meaning | | --- | --- | | `request_ticker` | The name asked for in the mint payload | | Ticker status | Whether the request is pending, a candidate, a winner, or a loser | | Ticker | The name only after resolution succeeded | | Atomical ID | The object that actually holds the name | The ARC-20 guide states a ticker is claimed after three confirmations. Treat that as guide guidance and check the active revision for the exact rule. ## What winning a ticker means It means the rules resolved one Atomical as holding that name. That is all. It does not mean: - the minter is who they say they are; - the metadata is accurate; - the supply is what a website claims; - a similar-looking name belongs to the same person. ## What a product must do 1. Resolve every ticker to an Atomical ID and store that ID. 2. Display the Atomical ID wherever a user makes a decision. 3. Show pending requests as candidates, never as owned. 4. Show the full candidate set when more than one request exists. 5. Warn on visually confusable names. 6. Re-resolve after a reorg. ## The Universe resolution path The Universe ARC-20 source discovers every ticker candidate without an upstream verified-only filter, then resolves each name through the Atomicals provider. Only the verified winning Atomical ID is published. The reference exposed to products is the lower-case ticker, and the winning compact Atomical ID is retained in protocol details. See [ARC-20 API](/reference/api/arc20/). --- # Transfers and swaps URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/arc20/transfers-and-swaps/ Page ID: protocol/arc20/transfers-and-swaps Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, universe-index-atomicals Verified: 2026-08-31 Limitations: - Swap safety depends on the signature hash flags and the exact outputs each party commits to. A swap constructed without exact output binding is not safe to sign. ## Ordinary transfer An ordinary transfer spends coloured inputs and arranges outputs so allocation places the units where you intend. There is no transfer operation in the normal case. The arrangement is the transfer. The shape that works: | Position | Contents | | --- | --- | | Input 0 | The coloured lot being moved | | Input 1 and later | Cardinal inputs funding the fee | | Output 0 | The recipient, sized to the exact units being sent | | Output 1 | Coloured change, sized to the exact remainder | | Output 2 | Cardinal change, if any | Get output sizes wrong and units burn. See [burns](/protocol/arc20/burns/). The reference CLI exposes `transfer-ft ` and `transfer-builder`. See the [CLI reference](/reference/cli/#transfer-ft). ## Atomic swap A swap moves an asset and its payment in one transaction, so neither side can take one without giving the other. Both parties sign the same transaction. ### What makes it safe **Exact output binding.** The seller's signature must commit to the exact output that pays them: the exact script and the exact value. A signature that leaves the payment output free lets a buyer redirect it. **Ownership proof separate from signing.** The seller proves control of the asset before the transaction is built, without moving anything. That is what BIP-322 is for. See [wallet integration](/reference/wallet-integration/). **Pre-broadcast validation.** Before broadcast, the whole blueprint is validated against the Atomicals rules: the selected asset must move to the buyer cleanly, with no operation, no mixed Atomical ID, and no burn. If your wallet cannot show every input and every output with its script and value, do not sign. A swap PSBT that hides one output is a swap you do not control. ### What is rejected The Universe Marketplace authority rejects, across all four protocol lanes: - mixed collateral; - spent outputs; - checkpoint drift between verification and execution; - ambiguous balances; - Atomicals operations inside the swap; - burns; - output assignments that do not move the exact selected Atomical. See [Marketplace v1](/reference/api/marketplace-v1/). ## Buyer funding inputs Buyer funding inputs must be confirmed and uncoloured. The Universe authority requires them to be confirmed P2WPKH or key-path P2TR outputs, and to be uncoloured in both the active script hash view and location history. A buyer who funds a purchase with a coloured output loses those units. ## After the swap Verify the result the same way you verify any transfer: confirmation, then indexing, then read the asset location and check for burns. See [verify a transaction](/guides/verify-a-transaction/). --- # The unit model URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/arc20/unit-model/ Page ID: protocol/arc20/unit-model Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-guide Verified: 2026-08-31 ## The rule One ARC-20 unit is one satoshi in an output a validator recognises as coloured for that token. Native quantities are integers. There is no smaller division. ## What follows immediately **Supply is satoshis.** A token with 100 000 000 units required 100 000 000 satoshis, which is one bitcoin, to exist. Large supplies are expensive by construction. **Dust limits apply.** An output that Bitcoin will not relay cannot carry units. In practice a coloured output must be at or above the relay dust threshold for its script type. **Balances are sums, not stored values.** A wallet total is the sum of the coloured outputs it can spend. Nothing on chain stores that total. **Spending is all or nothing per output.** There is no partial spend. Moving part of a lot means building a transaction whose outputs receive the split you want. ## Worked numbers | Deployment | Mint amount | Max mints | Nominal maximum issuance | Bitcoin required | | --- | --- | --- | --- | --- | | Small | 1 000 sats | 10 000 | 10 000 000 units | 0.1 BTC | | Medium | 10 000 sats | 21 000 | 210 000 000 units | 2.1 BTC | | Large | 100 000 sats | 21 000 | 2 100 000 000 units | 21 BTC | Nominal maximum issuance is `mint_amount * max_mints`. It is a ceiling on what claims can produce, not a promise that the ceiling is reached. ## Decimals `decimals` is optional metadata that tells a wallet how to format a number for a reader. A token with 100 000 units and `decimals` of 2 may be displayed as 1 000.00. The chain still holds 100 000 integer units in 100 000 coloured satoshis. Never divide a native quantity by a power of ten before doing arithmetic on it, and never let a formatted figure enter a transaction builder. See [metadata and decimals](/protocol/arc20/metadata-and-decimals/). ## Dust and safety A coloured output near the dust threshold is fragile. Any transfer that needs to leave a remainder smaller than the threshold cannot place that remainder in a new output, so it burns. Practical guidance: - Keep lots at sizes that divide cleanly for the transfers you expect. - Prefer a small number of larger lots over many dust-sized lots. - Model any split before building it. See [allocation visualizer](/tools/allocation-visualizer/). --- # Wallet safety URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/arc20/wallet-safety/ Page ID: protocol/arc20/wallet-safety Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0 Verified: 2026-08-31 An ordinary Bitcoin wallet is dangerous for Atomicals not because it is badly built, but because it is correctly built for a different problem. It sees satoshis and optimises fees. ## What a wallet must do 1. **Identify coloured outputs.** Per outpoint, with the Atomical ID, not as an address total. 2. **Exclude them from automatic coin selection.** Always, unless the user explicitly chose to spend that asset. 3. **Keep a cardinal pool.** Ordinary outputs reserved for fees. 4. **Preview the allocation.** Before signing, show every output, its satoshi value, and its expected coloured assignment. 5. **Show the burn figure.** Zero should be the normal case, and a non-zero figure should require a deliberate confirmation. 6. **Preserve input and output order.** Never reorder for canonicalisation. 7. **Show the signature hash flag.** And refuse flags the user did not expect. 8. **Report its data source.** Which index, which revision, how fresh. ## What a wallet must never do - Never sweep or consolidate without showing the allocation result. - Never choose a coloured output for a fee silently. - Never display a token balance without the resolved Atomical ID available. - Never round a native quantity using `decimals` before building a transaction. - Never ask for a seed phrase or private key to display a balance. ## How to test the wallet you use | Test | Pass | | --- | --- | | Ask it to show your outputs | It lists outpoints and marks coloured ones | | Try to send BTC while holding coloured outputs | It excludes them or warns clearly | | Build a partial transfer | It shows expected units per output before signing | | Build a transfer with a bad change size | It shows a non-zero burn figure and asks again | | Check the source | It names the index and its freshness | If a wallet fails the first test, it is not suitable for holding Atomicals. See [choose a wallet](/guides/choose-a-wallet/). ## For integrators Capability discovery matters. Ask the provider what it supports before building a transaction for it, rather than discovering a gap through a signing failure. See [wallet integration](/reference/wallet-integration/). --- # AVM opcodes URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/avm/opcodes/ Page ID: protocol/avm/opcodes Applicability: experimental Authority: reference-implementation Networks: none Sources: atomicals-avm-interpreter Verified: 2026-08-31 Limitations: - The status column reflects the upstream source comment only. It is not a Universe verification result. - Opcodes with no upstream annotation are shown as such rather than assumed working. This inventory is generated from the interpreter's opcode enumeration. It is not hand maintained, so it cannot drift from the source. `tested upstream` means the source comment marks the opcode as tested by the interpreter's own suite. It does not mean any Universe service executes it, and it does not mean the opcode is active on any network. ## Authorisation Signature checking is replaced. The ordinary Bitcoin signature opcodes are removed and a custom authorisation opcode is used instead. ## Introspection Opcodes that read the transaction being evaluated. ## State storage Key and value storage private to a contract. ## Fungible tokens Deposit, withdrawal, and inspection of ARC-20 balances held by a contract. ## Non-fungible tokens Deposit, withdrawal, and inspection of non-fungible objects held by a contract. ## Block information ## Hashing ## Large numbers The interpreter adds support for arbitrarily large numbers, so arithmetic is not bounded the way Bitcoin script bounds it. Any integration must treat numeric results as arbitrary precision rather than assuming a fixed width. --- # AVM URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/avm/overview/ Page ID: protocol/avm/overview Applicability: experimental Authority: reference-implementation Networks: none Sources: atomicals-avm-interpreter, atomicals-avm-interpreter, universe-index-atomicals, universe-inscribe Verified: 2026-09-26 Limitations: - AVM contract transactions are being validated on Bitcoin Testnet4 only, from activation height 27000. Nothing here is a mainnet claim. - Mainnet AVM writes are not enabled in production. - The indexer readiness report is not a published conformance statement. - Upstream test annotations describe the interpreter's own test suite, not production deployment. Four separate things are called "the AVM". They have four different statuses. Treating any of them as production mainnet support would be wrong. ## The four layers | Layer | Status | What exists | | --- | --- | --- | | Architectural whitepaper concepts | Proposed | A design document describing a system | | Official beta interpreter | Experimental or beta | Working code with its own test suite | | Universe runtime integration | Testnet4 only | AVM Studio at `/avm-studio`, the `/avm/*` API, and the `blockchain.atomicals.avm.*` RPCs. No mainnet writes | | Universe runtime attestation | Readiness only | An indexer readiness report. No published conformance statement | ## What the interpreter is A modified Bitcoin script interpreter, distributed as a library and a command line tool. The upstream project describes it as a sandbox invoked per contract that simulates execution of a Bitcoin script program. The caller provides state inputs, scripts, and block variables, and updated state is returned as CBOR encoded structures. Key differences from Bitcoin script, as described upstream: - most originally disabled opcodes are re-enabled, including concatenation, multiplication, division, and shifts; - arbitrarily large numbers are supported; - new opcodes handle deposit and withdrawal of non-fungible objects and ARC-20 tokens; - new opcodes read and write private state storage; - a hashing opcode provides additional digest algorithms; - signature checking is replaced by a custom authorisation opcode. ## Read next | Topic | Page | | --- | --- | | The generated opcode inventory | [Opcodes](/protocol/avm/opcodes/) | | State, execution inputs, and outputs | [State and execution](/protocol/avm/state-and-execution/) | | Threat model, resource limits, and what is unverified | [Status and limitations](/protocol/avm/status-and-limitations/) | ## What this documentation will not do It will not describe AVM behavior as available, supported, or production ready. It will not describe Testnet4 validation as mainnet support. It will not present whitepaper concepts as implemented behavior. The Universe AVM surfaces exist for validation on Bitcoin Testnet4, from activation height 27000. Signet cannot carry AVM with the pinned indexer. Mainnet AVM writes are not enabled in production. A network becomes supported only when a pinned revision, activation conditions, and executed conformance vectors exist for it. See [AVM status and limitations](/protocol/avm/status-and-limitations/) and [status and known limitations](/start/status-and-limitations/). --- # AVM state and execution URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/avm/state-and-execution/ Page ID: protocol/avm/state-and-execution Applicability: experimental Authority: reference-implementation Networks: none Sources: atomicals-avm-interpreter, atomicals-avm-interpreter Verified: 2026-08-31 Limitations: - This page describes the upstream beta interpreter's model. No Universe deployment runs it, so none of it is verified against Universe infrastructure. ## The execution model The interpreter is a sandbox invoked per contract. Upstream describes the entry point as a library function that verifies a script for the AVM, with the caller supplying state inputs, scripts, and current block information. On success, updated state variables are returned as CBOR encoded structures. Three consequences follow: 1. **The caller owns state.** The interpreter does not persist anything. Whatever calls it must store and supply state. 2. **The boundary is CBOR.** Inputs and outputs cross the boundary as encoded structures, not as language objects. 3. **Execution is per contract.** There is no shared global machine. ## What a call needs | Input | Purpose | | --- | --- | | The contract script | What to execute | | The unlocking script | The caller's side of the call | | State inputs | The contract's stored key and value data | | Token tables | Fungible balances and non-fungible objects the contract holds | | Block information | So the script can read chain context | | Authorisation signatures | So the custom authorisation opcode can validate the caller | ## What a call returns - Success or failure. - Updated state, CBOR encoded. - Updated token tables, including any deposits or withdrawals marked during execution. - Any outputs marked for withdrawal. ## State hashes A state hash lets an independent party check that a claimed post-execution state matches what an honest execution would produce. Without one, a caller must re-execute to verify. Any integration that stores AVM state must record the hash alongside it, and must record which interpreter revision produced it. ## Deposits and withdrawals Separate opcodes add fungible balance and non-fungible objects to a contract's internal tables, and mark outputs for withdrawal. The mechanics differ from ordinary Atomicals transfers, because value moves into and out of a contract's internal accounting rather than directly between outputs. Nothing here is exposed by any Universe service. See [status and limitations](/protocol/avm/status-and-limitations/). ## Virtual assets The whitepaper describes virtual unspent output concepts. Those are architectural concepts in a design document. They are not implemented behavior on the basis of appearing there. --- # AVM status and limitations URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/avm/status-and-limitations/ Page ID: protocol/avm/status-and-limitations Applicability: experimental Authority: reference-implementation Networks: testnet Sources: atomicals-avm-interpreter, universe-index-atomicals, universe-inscribe Activation: Bitcoin Testnet4 height 27000 Verified: 2026-09-26 Limitations: - AVM contract transactions are being validated on Bitcoin Testnet4 only. Nothing here is a mainnet claim. - Mainnet AVM writes are not enabled in production. - Signet cannot carry AVM with the pinned indexer, because its Signet network inherits the testnet3 activation heights. - The indexer readiness report attests the interpreter, the indexer revision, and a canary state hash. It is not a published conformance statement. ## Status, layer by layer | Layer | Status | Evidence | | --- | --- | --- | | Whitepaper concepts | Proposed | A design document exists | | Beta interpreter | Experimental | Source at a pinned revision with its own test annotations | | Opcode set | Experimental | Generated from the pinned source. See [opcodes](/protocol/avm/opcodes/) | | Universe indexer | Experimental | Six AVM RPCs, [listed below](#indexer) | | Universe integration | Experimental | Inscribe AVM Studio and the `/avm/*` API | | Universe attestation | Readiness report | No conformance statement | | Supported networks | Testnet4 only | From height 27000. No Signet. No mainnet writes | :::danger[What must never be said] That the AVM is live on mainnet. That Universe supports AVM contracts on mainnet. That Testnet4 validation is production support. That a whitepaper concept is implemented. That an opcode marked tested upstream is production verified. ::: ## Indexer RPCs, each prefixed `blockchain.atomicals.avm.`: - `capabilities` - `status` - `get_state` - `get_state_history` - `get_state_hash` - `get_execution` The readiness report shows activation, the exact tip, schema 2, the attested native interpreter, the attested indexer revision, and a canary state hash. An inherited guard in `create_or_delete_atomical` dropped every PROTOCOL (`def`) and CONTRACT (`new`) create, so no AVM protocol or contract was indexed. The fix admits both after activation. It is in review and not yet released. ## Threat model for anyone considering it **Untrusted contract code.** A contract script is attacker supplied. Re-enabled opcodes such as concatenation, multiplication, and shifts, combined with arbitrarily large numbers, make unbounded memory and time growth reachable unless the host bounds them. **Unbounded numbers.** Arbitrary precision arithmetic means a small script can request very large allocations. **Unbounded state.** State storage opcodes let a contract write data. Without a host-enforced limit, storage grows without bound. **Determinism.** Every independent evaluator must reach the same result. Any dependence on host memory layout, iteration order, or locale breaks verification. **State substitution.** A caller supplies state. Without a state hash bound to a revision, a dishonest caller can supply state that never resulted from honest execution. **Withdrawal correctness.** Opcodes mark outputs for withdrawal. A host that applies those marks without independent validation is trusting the contract it just ran. ## Resource controls a host would need 1. A hard limit on execution steps. 2. A hard limit on memory, including numeric magnitude. 3. A hard limit on state size per contract and per call. 4. A hard limit on the number of token table entries. 5. A wall clock timeout independent of the step limit. 6. Rejection rather than truncation when any limit is hit. 7. Deterministic behavior at every limit, so all evaluators agree on the failure. ## What would have to exist before a network is supported 1. A pinned interpreter revision deployed on a named network. 2. Activation conditions, if any. 3. Deterministic conformance vectors executed against that exact revision in CI. 4. A published statement of what those vectors prove and what they do not. 5. A Universe service revision that exposes it, or an explicit statement that none does. 6. A resource limit policy, published. Testnet4 has items 1, 2, and 5 and is still in validation. Mainnet has none in production. A network is supported only when all six exist. --- # DMINT URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/containers/dmint/ Page ID: protocol/containers/dmint Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-js-cli Verified: 2026-08-31 Limitations: - Manifest structure and rule evaluation are implementation specific. Build manifests with the reference tooling rather than by hand. DMINT lets anyone mint an item into a Container, while the Container owner keeps control of what a valid item is. The control comes from a manifest that is sealed before minting starts. ## The manifest The manifest declares, per item, what a valid claim looks like. It is built from a folder of item files with `prepare-dmint`, attached with `enable-dmint`, and then sealed. What a manifest typically constrains: | Constraint | Effect | | --- | --- | | The set of item identifiers | Only listed items can be claimed | | A digest per item | The claimed content must match exactly | | A mint height | Claims before it are invalid | | A Bitwork requirement | Claimants must grind | | Rules per item | Additional conditions, including payment | ## Why sealing comes first An unsealed manifest can be edited. If items are minted against an editable manifest, the owner can change what counts as valid after the fact. Verification then proves nothing. Seal, publish the sealed manifest, then open minting. In that order. ## Claiming an item ```text yarn cli mint-item ``` The claimant supplies the item identifier and the manifest entry. A validator checks the claim against the sealed manifest. Verification with `validate-container-item` checks an item without minting. See the [CLI reference](/reference/cli/). ## Payments An item rule can require a payment. The payment is made in the same transaction, to the output the rule specifies, and is checked as part of validity. A payment marker output identifies which claim the payment belongs to. A claim that meets every other condition but misses the payment is invalid, and the Bitcoin transaction still confirmed and cost a fee. ## Failure states | State | Cause | What a claimant sees | | --- | --- | --- | | Item not in the manifest | Wrong identifier | Confirmed transaction, invalid claim | | Digest mismatch | Content differs from the manifest entry | Confirmed transaction, invalid claim | | Before mint height | Claimed too early | Confirmed transaction, invalid claim | | Bitwork not satisfied | Grinding incomplete or wrong target | Confirmed transaction, invalid claim | | Payment missing or wrong | Rule not satisfied | Confirmed transaction, invalid claim | | Already claimed | Someone else won the race | Confirmed transaction, invalid claim | | Manifest not sealed | The collection is not trustworthy | Claim may succeed but proves little | Every row costs a Bitcoin fee. Check before broadcasting, not after. ## For consumers Do not display an item as a member of a collection unless it was verified against the sealed manifest. Show the Container Atomical ID, the sealed state, and the verification result per item. --- # Item verification URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/containers/item-verification/ Page ID: protocol/containers/item-verification Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-js-cli Verified: 2026-08-31 ## The verification chain Each step depends on the one before it. A break anywhere means the item is unverified. 1. **Resolve the Container.** By Atomical ID, not by name. 2. **Confirm the manifest is sealed.** An unsealed manifest proves nothing. 3. **Read the manifest entry** for the claimed item identifier. 4. **Compare the item content digest** to the manifest entry. 5. **Check the claim satisfied its rules**, including mint height, Bitwork, and payment. 6. **Check the claim was the winning one** for that identifier, if the identifier is unique. 7. **Confirm the item Atomical exists** and its current location. The reference CLI exposes `validate-container-item` for this. See the [CLI reference](/reference/cli/). ## What each check establishes | Check | Establishes | | --- | --- | | Container resolved by ID | You are looking at the right collection | | Manifest sealed | The rules could not be changed after minting began | | Manifest entry exists | The item was allowed | | Digest matches | The content is exactly what was allowed | | Rules satisfied | The claim was valid | | Winning claim | No one else holds that identifier | | Item exists | The object is real and locatable | ## What a product must show - Verified, with the checks that passed. - Unverified, with the first check that failed. - Never a green tick based on a metadata field. An interface that shows collection membership from metadata alone is misleading, because anyone can mint an object asserting membership in anything. ## Consumer expectations for an indexer An index that serves Container items should expose: - the Container Atomical ID and sealed state; - the manifest total and the verified item count; - per item, the verification result and the reason when it failed; - the generation and source revision the answer came from. No Universe read projection exposes Containers today. See [status and known limitations](/start/status-and-limitations/). --- # Containers URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/containers/overview/ Page ID: protocol/containers/overview Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-js-cli Verified: 2026-08-31 Limitations: - No Universe read projection exposes Containers or DMINT items today. This section documents protocol behavior only. A Container is an Atomical that represents a collection. It has a globally allocated name, and it is the anchor that items prove membership against. ## The lifecycle | Stage | Operation | What exists afterwards | | --- | --- | --- | | Mint the Container | `nft` with a container request | A named collection identity, as a candidate | | Resolve the name | Rules | A verified Container name | | Prepare the manifest | Off chain, then `mod` | The item rules, still editable | | Seal the manifest | `sl` | Rules that can never change | | Claim items | `dmt` item claims | Verified items, bounded by the manifest | Sealing before item minting is what makes the collection meaningful. An unsealed manifest can be rewritten while people mint against it. ## Reference commands | Command | Use | | --- | --- | | `mint-container ` | Mint the Container | | `prepare-dmint ` | Build a manifest from a folder of items | | `prepare-dmint-items` | Prepare the item files | | `enable-dmint ` | Attach the manifest to the Container | | `mint-item ` | Claim one item | | `validate-container-item` | Check an item against the manifest | | `set-container-data` | Write Container data | | `seal` | Seal, permanently | | `get-container`, `get-container-item`, `get-container-items` | Read | | `find-containers`, `summary-containers` | Discover | Exact signatures are in the generated [CLI reference](/reference/cli/). ## Name allocation A Container name is a globally allocated name and follows the same candidate model as tickers and Realms. A request is not a name until the rules resolve it. See [candidates and winners](/protocol/core/candidates-and-winners/). ## What a consumer should check 1. The Container's Atomical ID, not its name. 2. Whether the manifest is sealed, and at what height. 3. Whether each item was verified against the manifest or merely claims membership in metadata. 4. The verified item count against the manifest total. ## Universe status Containers and DMINT items are excluded from the Universe NFT and Realm read projection by declaration. Asking that index about a Container is out of scope, not a failure. See [status and known limitations](/start/status-and-limitations/). --- # Sealing and rules URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/containers/sealing-and-rules/ Page ID: protocol/containers/sealing-and-rules Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-js-cli Verified: 2026-08-31 ## What sealing does Sealing applies the `sl` operation. After it: - state can no longer change; - a Container manifest can no longer be edited; - the object can still be transferred. There is no unseal. Sealing the wrong manifest is permanent. ## The order that makes a collection trustworthy 1. Mint the Container and wait for its name to resolve. 2. Build the manifest from the final item set. 3. Verify the manifest locally against every item you intend to allow. 4. Attach it with `enable-dmint`. 5. Read it back from the chain and compare it to what you built. 6. Seal. 7. Publish the sealed manifest and the Container Atomical ID. 8. Open minting. Step five is the one people skip. Read back what is actually on chain before making it permanent. ## Rule evaluation must be deterministic Two implementations reading the same sealed manifest and the same claim must reach the same answer. That means: - no dependence on wall clock time; - no dependence on the order results happen to arrive in; - no dependence on a service that may be unavailable; - bounded work per evaluation. A rule that cannot be evaluated deterministically cannot be verified by an independent party, which defeats the purpose of sealing it. ## Rules that involve payment A payment rule names an output the claim must include. Evaluation checks the output exists, pays the required amount, and carries the correct payment marker. Because payment is part of validity, a claimant who pays the wrong amount or to the wrong script has made an invalid claim and lost the fee. ## For Subrealms The same rule machinery governs Subrealm claims under a parent Realm. See [claims and rules](/protocol/realms/claims-and-rules/). --- # Activation boundaries URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/core/activation-boundaries/ Page ID: protocol/core/activation-boundaries Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet, testnet, signet, regtest Sources: atomicals-electrumx-1.5.2.0 Verified: 2026-08-31 Limitations: - Activation heights are defined per network in the reference implementation. A behavior proven on one network says nothing about another. Atomicals validation rules are not all active from genesis. The reference implementation defines activation conditions per network, and a transaction is judged by the rules active at its own height. ## The consequences 1. A historical transaction must be re-evaluated under historical rules, not today's rules. 2. A behavior you tested on regtest, where rules may be always-on, can differ on mainnet. 3. Two indexers at different revisions can disagree about an old transaction and both be internally consistent. 4. A feature that exists in code is not usable until its activation condition is met. ## Rules that are commonly activation sensitive - Custom coloring with the `z` operation. - Perpetual decentralised mint parameters. - Mint count limits for fixed deployments, which have legacy and later variants. - Payload and operation validation refinements. This documentation marks activation-sensitive statements in the source panel under **Activation boundary**. ## How to reason about it | Question | Where the answer lives | | --- | --- | | Is this rule active on my network? | The coin definition in the validator revision | | Was it active at this height? | The activation condition compared to the block height | | Does my indexer implement it? | The indexer revision, not the protocol | | Does my counterparty agree? | Their indexer revision, which you must ask for | ## What to record in your system For every stored Atomicals result, keep: - the validator revision that produced it; - the network; - the block height it was computed at; - the generation identifier if your source publishes one. Without those four, a disagreement later is unexplainable. See [source of truth](/develop/source-of-truth/). --- # Bitwork URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/core/bitwork/ Page ID: protocol/core/bitwork Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-guide Verified: 2026-08-31 Limitations: - Estimates are probabilistic. No amount of work guarantees a result in any particular time, and nothing here is a profitability statement. Bitwork requires a transaction id to begin with a chosen prefix. Because a transaction id is a hash, the only way to satisfy it is to change the transaction and hash again until the prefix appears. ## Where it applies | Requirement | Applies to | | --- | --- | | `bitworkc` | The commit transaction id | | `bitworkr` | The reveal transaction id | | `mint_bitworkc` | The commit transaction id of every claim against a deployment | | `mint_bitworkr` | The reveal transaction id of every claim against a deployment | A deployment can require Bitwork from its claimants even when the deployment itself required little. Read the deployment, not the deployer's transaction. ## What it costs Each additional hexadecimal character of prefix multiplies the expected attempts by sixteen. | Prefix length | Expected attempts | | --- | --- | | 2 | about 256 | | 3 | about 4 096 | | 4 | about 65 536 | | 5 | about 1 048 576 | | 6 | about 16 777 216 | | 7 | about 268 435 456 | These are expectations, not schedules. Attempts are independent, so a run can finish far under or far over the expected count. It does not make a mint fair, does not prove identity, does not reserve a name, and does not guarantee inclusion. It raises the cost of spam. That is all it claims to do. ## Extensions Some configurations allow a partial next character, which sits between two whole-character levels in difficulty. Perpetual deployments progress their requirement over time. Read the exact deployment parameters rather than assuming a fixed level. See [perpetual DFT](/protocol/arc20/perpetual-dft/). ## Practical notes - Grinding changes the transaction, so any fee estimate must be recomputed after a successful grind. - Grinding the commit and the reveal are two separate searches. - The reference CLI exposes `--bitworkc`, `--bitworkr`, `--mintbitworkr`, and `--disablechalk` on the relevant commands. See the [CLI reference](/reference/cli/). --- # Candidates and winners URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/core/candidates-and-winners/ Page ID: protocol/core/candidates-and-winners Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-guide Verified: 2026-08-31 Limitations: - Confirmation depth requirements and tie-breaking are version sensitive. Read the deployment and the active revision rather than assuming a fixed number of blocks. Globally allocated names in Atomicals are tickers, Realms, Subrealms, and Container names. They are requested, not assigned. A request is a candidate. Only the rules decide a winner. ## The lifecycle | Stage | What exists | What a product should show | | --- | --- | --- | | Requested | A confirmed mint carrying a name request | "Candidate, not yet resolved" | | Candidate | One or more competing requests for the same name | The full candidate set, with heights | | Verified winner | The rules resolved one Atomical as holding the name | The name plus the resolved Atomical ID | | Losing candidate | A request that did not win | Explicitly marked as losing, never as pending | The ARC-20 guide states that a ticker is claimed after three confirmations. That figure comes from the guide, not from a constant this documentation independently verified against every network configuration. Read the active revision before depending on a specific depth. ## Why this matters more than it looks A user interface that shows a requested name as if it were owned invites two failures: 1. Someone pays for something they do not have yet. 2. Someone trusts a name that later resolves to a different Atomical. Both are avoidable by displaying the resolved Atomical ID alongside every name and by labelling unresolved requests plainly. ## Resolution is not permanent until it is confirmed and indexed A resolution computed from a chain position that later reorgs can change. See [confirmation and reorgs](/protocol/core/confirmation-and-reorgs/) and [consistency and reorgs](/develop/consistency-and-reorgs/). ## Where each name type resolves - Tickers: [tickers and candidates](/protocol/arc20/tickers-and-candidates/) - Realms and Subrealms: [claims and rules](/protocol/realms/claims-and-rules/) - Containers: [Containers](/protocol/containers/overview/) ## Integrator checklist 1. Store the request and the resolution as separate fields. 2. Never key a database row on a name. 3. Expose the candidate set, not just the current best guess. 4. Show the height at which resolution was computed. 5. Re-resolve after a reorg rather than trusting a cached winner. --- # Commit and reveal URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/core/commit-and-reveal/ Page ID: protocol/core/commit-and-reveal Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-guide, atomicals-electrumx-1.5.2.0 Verified: 2026-08-31 Limitations: - Bitwork applies to the commit transaction id, the reveal transaction id, or both, depending on the operation and the deployment configuration. ## Why two transactions Bitcoin script cannot carry arbitrary data cheaply in a way that stays hidden until spend time. Taproot script path spending can. The commit transaction pays into an output that commits to a script without revealing it. The reveal transaction spends that output and publishes the script in the witness, where the envelope becomes visible. ## The steps 1. Build the envelope: the `atom` marker, the operation code, and the CBOR payload. 2. Derive a Taproot output that commits to a script containing that envelope. 3. If the operation requires commit Bitwork, grind the commit transaction until its transaction id satisfies the requirement. 4. Broadcast the commit transaction, funded well enough to cover the reveal. 5. Build the reveal transaction spending that output, with the envelope in the witness. 6. If the operation requires reveal Bitwork, grind the reveal transaction the same way. 7. Broadcast the reveal transaction. 8. Wait for confirmation, then for a validator to index that height. ## What can go wrong between the steps | Problem | Symptom | What to do | | --- | --- | --- | | Commit funded, reveal never broadcast | Value sits in a Taproot output only your key material can spend | Rebuild and broadcast the reveal with the same key material | | Reveal underfunded | Reveal rejected by mempool policy | Increase the commit amount and start again | | Bitwork requirement misread | Reveal rejected by the validator, not by Bitcoin | Re-read the deployment and grind again | | Race for a limited mint | Reveal confirms but the quota is already full | The mint is invalid. The Bitcoin transaction still cost a fee | | Name already resolved | Reveal confirms as a losing candidate | See [candidates and winners](/protocol/core/candidates-and-winners/) | Every row above except the first produces a confirmed Bitcoin transaction. Confirmation costs money and proves nothing about validity. Check the validator result, not a block explorer. ## Fees You pay two fees. The commit fee is ordinary. The reveal fee depends on witness size, which grows with your payload, so embedding a large file makes the reveal expensive. Estimate before you grind, not after. The reference CLI accepts `--satsbyte` on the commands that build these transactions. See the [CLI reference](/reference/cli/). --- # Confirmation and reorgs URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/core/confirmation-and-reorgs/ Page ID: protocol/core/confirmation-and-reorgs Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, universe-index-atomicals-nfts-and-realms Verified: 2026-08-31 Two questions, two answers, never the same answer. **Did Bitcoin confirm the transaction?** A block contains it. Depth grows over time. **Did the Atomicals operation succeed?** A validator applied the rules and produced a result. That result is only as final as the chain position it was computed at. ## What a reorg changes A reorg replaces blocks. Everything computed from the replaced blocks is suspect: | Result | Effect of a reorg | | --- | --- | | A mint in a replaced block | May not exist in the new chain | | A name resolution | May resolve to a different candidate | | A transfer | May never have happened | | A burn | May not have occurred | | A mint quota position | May shift, invalidating later claims | A well-built index does not patch these results in place. It invalidates the affected generation and rebuilds from a checkpoint. See [consistency and reorgs](/develop/consistency-and-reorgs/). ## What a caller should do 1. Read the generation identifier and indexed height from every response. 2. Do not treat a result computed within the reorg window as settled. 3. For value decisions, wait for depth appropriate to the value at risk, then re-read. 4. Re-read after any reported generation change, not only after an obvious reorg. 5. Never cache an Atomicals result without also caching the generation it came from. ## Why "confirmed" in a product is not a protocol statement A product can call an action `confirmed` when it has broadcast and seen one confirmation. That is a product state. It is not a statement about confirmation depth, reorg safety, or indexer finality. Read the field definition before mapping it into your own model. --- # Atomicals digital objects URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/core/digital-objects/ Page ID: protocol/core/digital-objects Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0 Verified: 2026-08-31 An Atomical is the record a validator builds after reading a valid operation envelope in a Bitcoin transaction. Three things exist from that moment. ## Identity Assigned once, at mint, in the form `i`. It never changes and is never reassigned. A separate sequential number is also assigned, useful for display and ordering but not a durable key. Store the Atomical ID. Display the number if you like. Never key on the number alone. ## Type and subtype The mint operation decides the type. `nft` produces a non-fungible object. `ft` and `dft` produce fungible issuance. Subtypes narrow this further: a Realm, a Subrealm, a Container, and a DMINT item are all non-fungible objects with a request payload that makes them a name or a collection. An integration that only expects a plain NFT must reject the subtypes it does not handle, rather than treating them as generic. ## Payload The CBOR payload in the envelope. It can contain: - arbitrary metadata such as `name`, `desc`, `image`, `links`, `legal`; - one or more embedded files with declared content types; - request fields such as a ticker, realm, or container name; - rule structures for Subrealm and DMINT claims. All of it is supplied by the minter. None of it is verified by anyone. See [metadata trust boundaries](/protocol/core/metadata-trust/). ## What a validator stores | Field | Meaning | | --- | --- | | Atomical ID | Durable identity | | Number | Mint order | | Type and subtype | What kind of object it is | | Mint transaction and height | Where it came from | | Current location | The outpoint that carries it now | | Owner script | The script controlling that outpoint | | State | The result of applied `mod` operations | | History | Every operation applied, in order | | Sealed flag | Whether further changes are refused | ## What none of this proves - Not who created it. Anyone can mint anything with any metadata. - Not that the media is original, licensed, or safe to render. - Not that a name in the payload matches the name the rules actually awarded. - Not that another validator revision agrees with this record. Read [indexer dependency](/protocol/core/indexer-dependency/) next. --- # Envelope and operations URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/core/envelope-and-operations/ Page ID: protocol/core/envelope-and-operations Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-guide, universe-index-atomicals Verified: 2026-09-01 Limitations: - Operation availability and payload validation are activation sensitive. Build against the exact revision you target. The reveal witness carries a non-executed script structure of this shape: ```text OP_FALSE OP_IF "atom" OP_ENDIF ``` `OP_FALSE OP_IF` means Bitcoin skips the block entirely. The bytes are inert to consensus and meaningful only to an Atomicals validator. ## Operation codes | Code | Branch | Purpose | | --- | --- | --- | | `nft` | Non-fungible | Mint a non-fungible object, including Realms, Subrealms, and Containers | | `ft` | Fungible | Direct issuance of a complete supply | | `dft` | Fungible | Deploy a decentralised mint | | `dmt` | Fungible | Claim one mint against a deployment | | `y` | Fungible | Split behavior at the pinned revision | | `z` | Fungible | Custom coloring, activation gated | | `x` | Non-fungible | Splat, separating Atomicals held at one output | | `mod` | Any | Update mutable state | | `evt` | Any | Record an event | | `sl` | Any | Seal, refusing further changes | | `dat` | Any | Store permanent data | ## The payload is CBOR, not JSON A user interface may show you JSON. The wire format is CBOR. The differences that matter: - CBOR has real binary strings, so embedded files are raw bytes rather than base64. - CBOR map key ordering affects the encoded bytes and therefore the transaction id you grind. - A JSON round trip can silently change number types and lose byte exactness. Build the CBOR with the library your target validator uses. Do not hand-assemble an envelope from a formatted JSON blob. ## Embedded files A payload can carry named files. Each file declares a content type and its bytes. A validator records a digest so a consumer can check integrity later. See [permanent storage](/protocol/core/permanent-storage/) and [metadata and media](/protocol/nft/metadata-and-media/). ## Validation is contextual The same envelope can be valid in one block and invalid in another. Height, network, active rule set, deployment state, quota, and Bitwork all participate. A parser that only checks structure will pass envelopes a validator rejects. The only reliable check is running the exact validator revision you target against the exact transaction blueprint you intend to broadcast. ## What the parser actually scans for Reading the indexer rather than the prose changes what you should build against. A witness script is considered only if it is at least 39 bytes long and its first byte is `0x20`, the push of a 32 byte key. The parser then scans forward for the first `OP_IF` and checks the five marker bytes that follow it. It does not require an `OP_FALSE` before the `OP_IF`. That tolerance is worth knowing in both directions. An envelope built in either of the two common script shapes is accepted, so a wallet that omits the leading `OP_FALSE` still produces something this indexer reads. It is implementation behavior rather than a relaxation of the format, so do not depend on every implementation being equally tolerant: build the shape your target validator documents, and check it against [the transaction inspector](/tools/transaction-inspector/) before broadcasting. A script that fails either precondition is skipped rather than rejected. A transaction with no readable envelope yields no operation at all, which is a different outcome from an operation that was found and refused. --- # Identifiers and numbers URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/core/identifiers/ Page ID: protocol/core/identifiers Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-js-cli Verified: 2026-08-31 Four different identifiers appear in Atomicals tooling. They are not interchangeable. | Identifier | Shape | Stable? | Use it for | | --- | --- | --- | --- | | Atomical ID | `i` | Yes, forever | The primary key in your database | | Compact Atomical ID | `i` in the compact form used by CLI and payloads | Yes | Wire formats and operation payloads | | Location | `:` | No, changes on every move | Current custody, never as a key | | Number | An integer assigned in mint order | Yes, but not a key | Display and ordering | ## Converting between forms The reference CLI exposes both directions: - `yarn cli compact-outpoint ` turns a location into the compact form. - `yarn cli outpoint-compact ` turns a compact identifier back into an outpoint. See the [CLI reference](/reference/cli/) for the exact generated signatures. ## Rules for integrators 1. Key on the Atomical ID. Nothing else. 2. Store the location separately and expect it to change. 3. Never derive identity from a ticker, realm name, or container name. Those are allocations that resolve to an Atomical ID, and the resolution can change while a candidate is pending. 4. Show both the human name and the resolved Atomical ID wherever a user makes a decision. 5. When you display a number, label it as a number. Users read it as a rank. ## Common failure A product stores the ticker as its key, then a different Atomical wins the name after a candidate resolves, or a lookalike ticker is minted. Every downstream row now points at the wrong asset. Keying on the Atomical ID makes that failure impossible. --- # Indexer and validator dependency URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/core/indexer-dependency/ Page ID: protocol/core/indexer-dependency Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, universe-index-atomicals-nfts-and-realms Verified: 2026-08-31 Limitations: - Two sources agreeing does not prove either is right. It proves they share an interpretation. Bitcoin does not know what an Atomical is. Every Atomicals answer comes from software that reads blocks and applies rules. That software has a version, a network, a chain position, and a set of active rules. ## What every answer is scoped to | Scope | Why it matters | | --- | --- | | Validator revision | Decides how the transaction is interpreted | | Network | Decides which activation conditions apply | | Block height | Decides which rules were active for that transaction | | Generation | Decides which consistent snapshot you are reading | | Projection | Decides which asset kinds are even included | A source that does not tell you all five is not usable for a value decision. ## Projections exclude things on purpose An index can deliberately cover a subset. The Universe NFT and Realm read model projects plain NFTs, Realms, and Subrealms, and excludes fungible tokens, Containers, and DMINT items. Asking it about a Container is not a bug when it returns nothing. It is out of scope by declaration. Always read the projection declaration before concluding that an asset does not exist. ## When two sources disagree Do not vote. Investigate in this order: 1. Are they on the same network? 2. Are they at the same chain position, or is one behind? 3. Are they at the same validator revision? 4. Is the behavior in question activation sensitive at the height involved? 5. Do they cover the same projection? Only after all five match does a disagreement mean one of them is wrong. ## Practical rule For anything with value at stake, compare more than one compatible source, and treat any disagreement as a hold, not a tie-break. Record the revision and generation of each answer so the difference can be explained afterwards. --- # Metadata trust boundaries URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/core/metadata-trust/ Page ID: protocol/core/metadata-trust Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, universe-index-atomicals-nfts-and-realms Verified: 2026-08-31 Anyone can mint an Atomical containing any bytes with any declared type and any claimed name. Nothing in a payload is checked by anyone before it reaches your screen. ## What a payload can claim, and what it proves | The payload says | It proves | | --- | --- | | `name` is a well known brand | Nothing | | `image` is a famous artwork | Nothing | | `legal` grants you rights | Nothing | | `links` point to an official site | Nothing | | The content type is an image | Nothing. Verify the bytes | | The ticker matches a project | Only that a name was allocated to some Atomical | ## Rules for a renderer 1. Choose the content type yourself from the bytes. Do not trust the declared type. 2. Restrict the set of types you will render at all. 3. Enforce a size limit before decoding. 4. Serve media from an isolated origin with a restrictive content security policy. 5. Never inline payload content into your own document. 6. Sanitise any text before display, including names, descriptions, and link labels. 7. Verify the digest before serving. ## Rules for a user interface 1. Show the resolved Atomical ID next to every name. 2. Mark unresolved name requests as candidates. 3. Never present metadata as verification. 4. Warn when a displayed name is visually confusable with another. See [Unicode and IDNA](/protocol/realms/unicode-and-idna/). 5. Show the data source, its revision, and its freshness. ## Rules for an indexer 1. Bound payload size and nesting depth before parsing. 2. Reject or quarantine payloads that fail to parse rather than partially applying them. 3. Record the digest of every stored file. 4. Keep the raw bytes exactly as revealed. Optimised derivatives are separate artefacts. 5. Never let payload content influence routing, authentication, or storage paths. --- # Permanent file storage URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/core/permanent-storage/ Page ID: protocol/core/permanent-storage Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-js-cli Verified: 2026-08-31 Limitations: - Permanence describes the bytes in a block. It does not promise that any particular service will serve, decode, or render them. Atomicals can carry files directly in the reveal witness. The bytes live in a Bitcoin block, so they persist for as long as the chain does. ## What is stored - One or more named files. - A declared content type per file. - The raw bytes, as a CBOR binary string. - A digest recorded by the validator. Relevant CLI commands from the generated inventory: `store-file`, `dat`, and `download`. ## What a digest proves and does not prove A digest proves the bytes you received match the bytes that were revealed. That is integrity. It does not prove: - that the content is original, licensed, or authorised; - that the declared content type is honest; - that the file is safe to render; - that a service currently serving it has not substituted a derivative. Treat every stored file as hostile input. See [metadata trust](/protocol/core/metadata-trust/). ## Cost Reveal fees scale with witness size. A large file makes the reveal transaction large, and the fee follows. Three ways to reduce it: 1. Reference shared bytes instead of duplicating them. See [references and recursion](/protocol/core/references-and-recursion/). 2. Store a compact source such as optimised SVG rather than a raster image. 3. Store the minimum that must be permanent, and derive the rest. ## Serving stored files A read service that exposes stored media should: - restrict the content types it will serve; - enforce a size limit; - verify the digest before serving; - serve with a content type it chose, not one the payload asserted; - send immutable cache headers for content-addressed responses; - never execute or inline the content into its own origin. The Universe NFT and Realm read model applies these rules. See [NFT and Realm API](/reference/api/atomicals-nfts-realms/). --- # References and recursion URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/core/references-and-recursion/ Page ID: protocol/core/references-and-recursion Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0 Verified: 2026-08-31 Limitations: - Recursive rendering depends on the renderer resolving every dependency. A renderer that cannot reach a dependency produces a different result from one that can, without either being wrong about the chain data. An Atomical payload can reference another Atomical instead of embedding the same bytes again. A collection of a thousand items can share one script, one font, and one palette, and each item can carry only what makes it different. ## Why references exist | Without references | With references | | --- | --- | | Every item embeds every byte | Shared bytes are stored once | | Reveal fees scale with total content | Reveal fees scale with what is unique | | Updating shared logic is impossible | The shared object has its own history | ## How a reference resolves 1. The payload names a target, usually by compact Atomical ID. 2. A renderer resolves that identifier to the target's stored payload. 3. The target may itself reference further Atomicals, so resolution is recursive. 4. The renderer composes the final output from the resolved set. The `set-relation` command records a relation between Atomicals. See the [CLI reference](/reference/cli/). ## Failure modes **Unresolvable dependency.** The renderer cannot reach the target. The item renders differently or not at all. The chain data did not change. **Depth or cycle.** A reference chain that is too deep, or that loops, must be bounded by the renderer. Treat a cycle as a rendering failure, never as an infinite loop. **Mutable target.** If the referenced object is not sealed, its owner can change what every referring item renders. Check the sealed flag before treating a reference as stable. **Silent substitution.** A renderer that falls back to a placeholder without saying so produces a wrong picture that looks fine. Fail visibly instead. ## Practical guidance - Seal shared dependencies before minting items against them. - Archive the complete resolved dependency set so an item can be re-rendered later without a live index. - Cache deterministically by content hash so unchanged content is never fetched or rendered twice. - Record which revision resolved each dependency, so a difference later can be explained. --- # State, history, and updates URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/core/state-and-history/ Page ID: protocol/core/state-and-history Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-js-cli Verified: 2026-08-31 An Atomical is not frozen at mint. The owner can apply operations that change recorded state, and every one of those is kept in an ordered history. ## State State is the accumulated result of `mod` operations applied by the owner. It is a structured document, not a single value. Readers should treat it the way they treat mint metadata: supplied by whoever controlled the object at that moment, and unverified. Relevant commands from the generated CLI inventory: | Command | Purpose | | --- | --- | | `set` | Write state | | `state` | Read current state | | `state-history` | Read ordered state changes | | `delete` | Remove a state path | | `set-relation` | Write a relation between Atomicals | | `emit` | Record an event | | `seal` | Refuse further changes, permanently | See the [CLI reference](/reference/cli/) for exact signatures at the pinned revision. ## History History is every operation applied to the object, in order, with the transaction and height that carried it. It is the audit trail a consumer should read before trusting current state, because current state alone does not show who changed what or when. ## Sealing Sealing makes an Atomical refuse further updates. After a seal: - state can no longer change; - a Container manifest can no longer be edited; - the object can still be transferred. Sealing is permanent. There is no unseal. For collections, sealing the DMINT manifest is what makes item verification meaningful, because the rules cannot be rewritten after items start minting. See [sealing and rules](/protocol/containers/sealing-and-rules/). ## Reading state safely 1. Read the Atomical ID, not the display name. 2. Read history, not only current state. 3. Check the sealed flag before deciding whether state is stable. 4. Record the generation and source revision your answer came from. 5. Re-read after a reorg. See [confirmation and reorgs](/protocol/core/confirmation-and-reorgs/). --- # UTXO ownership and location URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/core/utxo-ownership/ Page ID: protocol/core/utxo-ownership Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0 Verified: 2026-08-31 Limitations: - Address level views are conveniences built on top of outpoint level truth. They can lag or aggregate incorrectly without being wrong about any single outpoint. You do not own an Atomical at an address. You own it because you control the private key for the script of one specific unspent output, and that output currently carries the object. ## Why the distinction matters | Statement | True? | | --- | --- | | This address holds 5000 units | A convenience sum, not a stored fact | | This outpoint carries 5000 units | The actual fact a validator records | | Moving BTC from this address is safe | Only if the spent outputs are cardinal | | Consolidating my UTXOs is harmless | No. Consolidation is an allocation event | An ordinary wallet sees satoshis. It will happily select a coloured output to pay a fee, split it into change, or sweep it into one consolidated output. Every one of those is an Atomicals operation whether you meant it or not. ## The three states of an output **Coloured.** A validator recognises Atomicals value at this outpoint. Spending it moves or destroys that value. **Cardinal.** Ordinary bitcoin. Safe to spend for fees. **Unknown.** Your data source has not caught up, is unavailable, or does not index the relevant asset type. Treat unknown as coloured until proven otherwise. ## Multiple Atomicals at one output An output can carry more than one Atomical. That happens after a consolidation, or when a mint places several objects together. Separating them is a deliberate operation, not a side effect of an ordinary spend. For non-fungible objects that separation is the `x` splat operation. See [splat and mixed outputs](/protocol/nft/splat-and-mixed-outputs/). ## What to do about it 1. Ask your data source for outpoints, not address totals. 2. Keep coloured outputs in a wallet that can freeze or exclude them. 3. Keep a dedicated pool of cardinal outputs for fees. See [protect coloured outputs](/guides/protect-colored-outputs/). 4. Before signing, confirm each input's state individually. --- # Collections and Containers URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/nft/collections-and-containers/ Page ID: protocol/nft/collections-and-containers Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0 Verified: 2026-08-31 A collection in Atomicals is not a label. It is a relationship a validator can check. ## The weak form: a metadata claim An NFT payload can say it belongs to a collection. Nothing checks that. Anyone can mint an object claiming membership in anything. A product that groups by a metadata field is grouping by an unverified string. ## The strong form: a Container A Container is a named Atomical that represents the collection identity. Items prove membership against it, and with a sealed DMINT manifest that proof is checkable. | Property | Metadata claim | Container membership | | --- | --- | --- | | Anyone can assert it | Yes | No | | A validator can check it | No | Yes, against the manifest | | Rules can be changed later | Not applicable | No, once sealed | | Item count is bounded | No | Yes, by the manifest | See [Containers](/protocol/containers/overview/) and [DMINT](/protocol/containers/dmint/). ## Parent linkage Mint commands accept `--parent` and `--parentowner`, which link the new object to a parent Atomical at mint time. That linkage is set once and is part of the mint. ## What to display 1. The collection's Container Atomical ID, not just its name. 2. Whether the manifest is sealed. 3. Whether this item's membership was verified against the manifest, or merely asserted in metadata. 4. The number of verified items against the manifest total. A user interface that shows a collection name without those four is showing a claim. --- # NFT marketplace behavior URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/nft/marketplace/ Page ID: protocol/nft/marketplace Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals, universe-index-atomicals Verified: 2026-08-31 Limitations: - Every marketplace action gate defaults to off. A capability being documented does not mean it is enabled on any deployment. The Universe Marketplace v1 exposes four isolated protocol authorities: `arc20`, `atomicals_nft`, `realms`, and `subrealms`. They share one durable transaction engine, and every route, cursor, idempotency scope, listing, offer, order, reservation, browse query, and status count is scoped to one protocol. ## What the generic NFT lane accepts An authoritative compact Atomical ID, with `quantityAtomic` always exposed as `1`. It **rejects** realm, subrealm, FT, container, and item subtypes. Those either belong to another lane or are not supported. ## What must agree before collateral is accepted For a non-fungible asset the authority requires independent views to agree: - Bitcoin Core reports a confirmed, live output with the exact value and owner script, and a mature coinbase where applicable. - The Atomicals provider reports exactly that location, script, and value. - The height and hash on both the Bitcoin side and the Atomicals side stay unchanged across the verification bracket. If any view disagrees, or the chain position moves mid-check, the request fails closed. ## What is always rejected - Mixed collateral, meaning an output carrying more than the selected asset. - Spent outputs. - Checkpoint drift between verification and execution. - Ambiguous balances. - Atomicals operations inside the settlement transaction. - Burns. - Output assignments that do not move the exact selected Atomical. ## Ownership proof Owner actions require a short lived owner session, issued only after a BIP-322 simple proof for P2WPKH or key-path P2TR. Proof is separate from signing the settlement transaction. ## Lifecycle Listing, reservation, purchase preparation, signed validation, broadcast, and settlement are distinct steps with their own routes and idempotency scope. See [Marketplace v1](/reference/api/marketplace-v1/) for the complete contract. --- # Metadata and media URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/nft/metadata-and-media/ Page ID: protocol/nft/metadata-and-media Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, universe-index-atomicals-nfts-and-realms Verified: 2026-08-31 Limitations: - A digest proves byte integrity only. It says nothing about rights, originality, or whether the content is safe to render. ## What is stored An NFT payload can contain named files. Each declares a content type and carries raw bytes. A validator records a digest per file so a consumer can verify what it received. Metadata fields such as `name`, `desc`, `image`, `links`, and `legal` sit alongside. All of it is supplied by the minter and none of it is checked. ## Media selection When several files exist, a renderer must choose one to display. Choose deterministically: 1. Prefer an explicitly named primary field if the payload declares one. 2. Otherwise prefer the first file whose sniffed type is in your render allowlist. 3. Otherwise render nothing and say so. Never choose based on the declared content type alone, and never fall back silently to a placeholder that looks like real content. ## Content type safety | Rule | Reason | | --- | --- | | Sniff the type from the bytes | The declared type is attacker controlled | | Serve only an allowlist of types | An unknown type is an unbounded risk | | Enforce a size limit before decoding | Decompression and decoding are attack surfaces | | Serve from an isolated origin | So content cannot reach your session | | Send a restrictive content security policy | So embedded script cannot execute | | Never inline payload bytes into your document | Same reason | | Verify the digest before serving | So a substitution is detected | The Universe NFT and Realm read model applies MIME restrictions, size limits, and digest validation on its media route. See [NFT and Realm API](/reference/api/atomicals-nfts-realms/). ## Integrity and derivatives Preserve exact original bytes permanently. Optimised files, thumbnails, and responsive sizes are derivatives, stored separately and content addressed by hash so identical bytes are stored once. A derivative must never be served as if it were the original when a caller asked for the original. ## Displaying text safely Escape everything. Names, descriptions, and link labels are arbitrary strings and can contain markup, control characters, bidirectional overrides, and confusable glyphs. See [Unicode and IDNA](/protocol/realms/unicode-and-idna/). --- # Minting an NFT URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/nft/minting/ Page ID: protocol/nft/minting Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-js-cli Verified: 2026-08-31 Minting an NFT is a commit and reveal pair carrying an `nft` operation. The resulting object is assigned to output zero of the reveal transaction. ## Reference commands | Command | Use | | --- | --- | | `mint-nft ` | Mint from a file payload | | `mint-nft-json ` | Mint from a JSON payload | | `mint-realm ` | Mint a top-level Realm | | `mint-subrealm ` | Mint a Subrealm | | `mint-container ` | Mint a Container | | `mint-item ` | Mint a DMINT item | Exact signatures and options are in the generated [CLI reference](/reference/cli/). ## What output zero receives The new Atomical, at the satoshi value you chose. Most commands accept `--satsoutput` to set it. Choose deliberately: - Too small and the output may be below the relay dust threshold for its script type. - Too large and you have locked more bitcoin than you needed to. - The value is not the asset. It is just the output that carries it. ## Decisions that cannot be changed later | Decision | Why it is permanent | | --- | --- | | The Atomical ID | Assigned at mint, never reassigned | | Embedded file bytes | They are in a block | | The name requested | A different name means a different mint | | Parent linkage | Set at mint through `--parent` and `--parentowner` | | Sealing, once applied | There is no unseal | Everything else is state, and state can change until sealed. See [state and history](/protocol/core/state-and-history/). ## Cost The reveal fee scales with the witness, which scales with your payload. Before grinding any Bitwork, estimate the reveal size with the real payload bytes. A collection that embeds the same shared asset in every item pays for it every time. See [references and recursion](/protocol/core/references-and-recursion/). ## After the mint 1. Confirm on Bitcoin. 2. Wait for the index to reach that height. 3. Read the Atomical ID and confirm the subtype is what you expected. 4. For a name request, confirm it resolved rather than remaining a candidate. 5. Record the ID in your own records before doing anything else with it. --- # Atomicals NFTs URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/nft/overview/ Page ID: protocol/nft/overview Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, universe-index-atomicals-nfts-and-realms Verified: 2026-08-31 Limitations: - The Universe read model projects plain NFTs, Realms, and Subrealms. Containers and DMINT items are excluded from that projection by declaration. An Atomicals NFT is a single non-fungible object created with the `nft` operation. It carries metadata and optionally embedded files, it lives in a Bitcoin output, and it has an ordered history. ## Subtypes matter The same `nft` operation produces several different things depending on the request in the payload: | Request | Result | | --- | --- | | none | A plain NFT | | `request_realm` | A top-level Realm | | `request_subrealm` | A Subrealm under a parent | | `request_container` | A Container collection identity | | item claim against a sealed manifest | A DMINT item | An integration that expects a plain NFT must reject the subtypes it does not handle rather than treating them as generic. The Universe Marketplace generic NFT lane does exactly that: it rejects realm, subrealm, FT, container, and item subtypes. ## What an NFT carries - Metadata, arbitrary and unverified. - Zero or more named files with declared content types and recorded digests. - Mutable state, until sealed. - A complete operation history. See [metadata and media](/protocol/nft/metadata-and-media/) and [permanent storage](/protocol/core/permanent-storage/). ## How an NFT moves Spending the output that carries it moves it, subject to the non-fungible allocation branch. Unlike the fungible branch, an NFT is a whole object: it lands somewhere or it does not. The hazards are different too. An output can carry several Atomicals at once, and separating them requires a deliberate operation. See [splat and mixed outputs](/protocol/nft/splat-and-mixed-outputs/). ## Reading pages | Topic | Page | | --- | --- | | Minting an NFT and what the payload contains | [Minting](/protocol/nft/minting/) | | Files, content types, digests, and safe rendering | [Metadata and media](/protocol/nft/metadata-and-media/) | | Normal transfers and swap transfers | [Transfers](/protocol/nft/transfers/) | | Splat and shared outputs | [Splat and mixed outputs](/protocol/nft/splat-and-mixed-outputs/) | | Collections and Container membership | [Collections and Containers](/protocol/nft/collections-and-containers/) | | Listing, buying, and settling | [Marketplace](/protocol/nft/marketplace/) | --- # Splat and mixed outputs URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/nft/splat-and-mixed-outputs/ Page ID: protocol/nft/splat-and-mixed-outputs Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-js-cli Verified: 2026-08-31 One Bitcoin output can carry several Atomicals at once. That happens after a consolidation, after some mints, or when a transfer places several objects in the same slot. ## Why it is dangerous A mixed output cannot be moved selectively. Spending it moves everything it carries, and the allocation branch decides where each object lands. You cannot send one and keep the others by adjusting an amount, because there is no amount. Consequences: - Selling one object from a mixed output means moving all of them. - A marketplace that accepts a mixed output as collateral cannot guarantee what settles. - A wallet that shows a mixed output as one asset is hiding the others. The Universe Marketplace rejects mixed collateral across all four protocol lanes for exactly this reason. ## Splat Splat is the `x` operation on the non-fungible branch. It extracts Atomicals from an output that holds several, placing them into separate outputs. The reference CLI exposes: ```text yarn cli splat ``` Options include `--satsoutput`, `--owner`, `--funding`, `--satsbyte`, `--bitworkc`, `--rbf`. See the [CLI reference](/reference/cli/#splat). Splat is not a fungible operation. It is not a substitute for [split](/protocol/arc20/split-and-combine/). ## Procedure 1. Identify the outpoint and list every Atomical it carries. 2. Decide the destination output for each. 3. Build the splat, choosing an output value for each destination that is above the relay dust threshold. 4. Fund the fee from a cardinal input. 5. Confirm, index, then verify each object landed where you intended. ## Prevention - Never consolidate outputs that carry Atomicals. - Keep one asset per output as a working rule. - Ask your data source for the full Atomicals list per outpoint, not a single asset. - Refuse to list a mixed output for sale until it is separated. --- # NFT transfers URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/nft/transfers/ Page ID: protocol/nft/transfers Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-js-cli Verified: 2026-08-31 ## Normal transfer Spend the output carrying the NFT and arrange outputs so the non-fungible allocation branch places the object where you intend. The reference CLI exposes `transfer-nft` and `transfer-utxos`. See the [CLI reference](/reference/cli/#transfer-nft). The shape that works: | Position | Contents | | --- | --- | | Input 0 | The output carrying the NFT | | Input 1 and later | Cardinal inputs for the fee | | Output 0 | The recipient | | Output 1 and later | Cardinal change | ## Swap transfer A swap moves the NFT and its payment in one transaction, with both parties signing. The safety requirements are the same as for fungible swaps: exact output binding, ownership proof separate from signing, and pre-broadcast validation of the whole blueprint. See [transfers and swaps](/protocol/arc20/transfers-and-swaps/). For the non-fungible lanes, the Universe Marketplace always exposes `quantityAtomic` as `1`, because the object is indivisible. ## What can go wrong | Problem | Cause | Prevention | | --- | --- | --- | | The NFT went somewhere unexpected | The output arrangement placed it differently than you assumed | Model the transfer before signing | | Several Atomicals moved together | The input carried more than one | Splat first. See [splat and mixed outputs](/protocol/nft/splat-and-mixed-outputs/) | | The object was spent as ordinary bitcoin | An ordinary wallet chose the output for a fee | Use an Atomicals aware wallet | | The swap payment was redirected | The seller signature did not bind the payment output | Refuse to sign an unbound swap | ## Verifying afterwards Read the asset by Atomical ID and confirm its location matches the output you intended, at a generation past the confirming height. Confirmation alone is not the answer. See [verify a transaction](/guides/verify-a-transaction/). --- # Atomicals protocol URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/overview/ Page ID: protocol/overview Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-guide Verified: 2026-08-31 Limitations: - The Atomicals specification is defined in code. This page summarises one pinned revision and is not an independent consensus specification. The Atomicals specification is defined in code. The official guide says so directly. Everything below describes what the pinned reference revision does, not what a standard document declares. Concepts are stable. Exact validation is version sensitive. Pin a revision, record the network, and re-test on every upgrade. See [networks and versions](/start/networks-and-versions/). ## The pipeline every operation follows 1. A builder constructs a commit transaction paying to a Taproot output that commits to a script containing the envelope. 2. A reveal transaction spends that output and exposes the envelope in its witness. 3. A validator reads `atom`, the operation code, and the CBOR payload. 4. The validator checks the operation against the rules active at that block height on that network. 5. On success it assigns the result, usually to output zero for a mint. 6. Transfers of existing Atomicals are decided by allocation over the transaction's inputs and outputs. ## Where each rule lives | Question | Decided by | Read | | --- | --- | --- | | Is this envelope well formed? | Mint parser | [Envelope and operations](/protocol/core/envelope-and-operations/) | | Is this ticker name legal? | Ticker rule at the active revision | [Tickers and candidates](/protocol/arc20/tickers-and-candidates/) | | Does this claim satisfy Bitwork? | Bitwork check | [Bitwork](/protocol/core/bitwork/) | | Which output gets the value? | Blueprint builder allocation | [Allocation](/protocol/arc20/allocation/) | | Did anything burn? | Allocation remainder handling | [Burns](/protocol/arc20/burns/) | | Can this create value from nothing? | No-inflation validation | [Allocation](/protocol/arc20/allocation/) | | Is this rule active yet? | Per-network activation table | [Activation boundaries](/protocol/core/activation-boundaries/) | ## Read next --- # Claims and rules URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/realms/claims-and-rules/ Page ID: protocol/realms/claims-and-rules Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-electrumx-1.5.2.0 Verified: 2026-08-31 Name claims for Subrealms and Container items share the same shape: a parent publishes rules, a claimant submits a claim, a validator evaluates the claim against the rules. ## The evaluation 1. Is the name available, or is there a competing candidate? 2. Does the claim satisfy every published rule? 3. Where a rule requires payment, is the payment present, correct, and correctly marked? 4. Where Bitwork is required, is it satisfied? 5. Was this claim the first valid one for the name? A claim that fails any step is invalid. The Bitcoin transaction still confirmed. ## Payment markers A payment output alone is not enough. A marker identifies which claim the payment belongs to, so a validator can match payment to claim without guessing. The reference implementation recognises markers for both Subrealm and DMINT item payments. Consequences for a builder: - The marker must be present and well formed. - The payment must go to the exact output the rule specifies. - The amount must be exact. - All of it must be in the same transaction as the claim. ## Deterministic evaluation Rules must evaluate the same way for every independent implementation. That rules out anything that depends on wall clock time, arrival order, an external service, or unbounded work. A rule that cannot be evaluated independently cannot be checked by a buyer, which removes the reason to trust the name in the first place. ## Competing claims When several valid claims arrive for the same name, the rules decide. A product must show the full candidate set with heights rather than presenting one as settled. See [candidates and winners](/protocol/core/candidates-and-winners/). ## After a reorg Resolution is computed at a chain position. A reorg can change which claim was first, which changes the winner. Re-resolve rather than trusting a cached result. See [consistency and reorgs](/develop/consistency-and-reorgs/). --- # Realm marketplace behavior URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/realms/marketplace/ Page ID: protocol/realms/marketplace Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals Verified: 2026-08-31 Limitations: - Every marketplace action gate defaults to off. Documentation of a capability is not a statement that it is enabled. Realms and Subrealms have their own Marketplace lanes, separate from the generic NFT lane. They carry one extra check that the other lanes do not. ## The extra step Before every mutation, the Realm and Subrealm lanes resolve the verified name winner. That is not the same as confirming the seller controls an Atomical. It confirms the Atomical they control is the one that currently holds the name. Why it matters: a name can move between Atomicals through candidate resolution. Selling an Atomical that used to hold a name is not selling the name. ## What must agree before collateral is accepted - The name resolves to a verified winner, and that winner is the offered Atomical. - Bitcoin Core reports a confirmed, live output with the exact value and owner script. - The Atomicals provider reports exactly that location, script, and value. - Heights and hashes on both sides stay unchanged across the verification bracket. Any disagreement, or any movement mid-check, fails the request closed. ## Always rejected Mixed collateral, spent outputs, checkpoint drift, ambiguous balances, Atomicals operations inside the settlement transaction, burns, and output assignments that do not move the exact selected Atomical. ## `quantityAtomic` Always `1` for Realm and Subrealm lanes. A name is indivisible. ## What a buyer should verify 1. The name, in exact bytes, and its normalised form. 2. Whether it is confusable with a name they already know. 3. The Atomical ID that currently holds it. 4. That the listing references that same Atomical ID. 5. After settlement, that the name still resolves to the Atomical they now control. Step five matters because resolution is computed at a chain position and can change. See [Marketplace v1](/reference/api/marketplace-v1/). --- # Realms URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/realms/overview/ Page ID: protocol/realms/overview Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, universe-index-atomicals-nfts-and-realms Verified: 2026-08-31 Limitations: - A name proves allocation, never identity. Two names that look identical to a reader can be different strings. A Realm is a top-level Atomicals name, owned as a non-fungible Atomical. Whoever controls the output carrying that Atomical controls the name. ## Claiming A Realm is requested inside an `nft` mint payload as `request_realm`. The request is a candidate until the rules resolve it into a verified winner. See [candidates and winners](/protocol/core/candidates-and-winners/). Reference commands: `mint-realm `, `get-realm`, `realm-info`, `find-realms`, `summary-realms`, `resolve`. See the [CLI reference](/reference/cli/). ## What a Realm gives you | It gives you | It does not give you | | --- | --- | | A globally allocated name | Any claim to a trademark or identity | | The right to define Subrealm rules | Control over what people do with similar names | | A resolvable destination for Paynames | Any guarantee that a lookalike is not deceiving someone | | A transferable Atomical | Any protection against confusable characters | ## Ownership and transfer Ownership is control of the output carrying the Realm Atomical. Transferring it is an ordinary non-fungible transfer. Losing the output loses the name. Practical consequences: - Never hold a valuable Realm in a wallet that can spend its output for fees. - Never leave a Realm on an output shared with other Atomicals. Splat first. See [splat and mixed outputs](/protocol/nft/splat-and-mixed-outputs/). ## Resolution and search Resolution turns a name into the Atomical that holds it. It is computed at a chain position, so it can change after a reorg. Always record the height and generation a resolution came from. The Universe read model exposes realm resolution, hierarchy, and Subrealm listing. See [NFT and Realm API](/reference/api/atomicals-nfts-realms/). ## Read next | Topic | Page | | --- | --- | | Child names under a Realm | [Subrealms](/protocol/realms/subrealms/) | | Using a Realm as a payment destination | [Paynames](/protocol/realms/paynames/) | | How claims and payments are evaluated | [Claims and rules](/protocol/realms/claims-and-rules/) | | Unicode, normalisation, and confusable names | [Unicode and IDNA](/protocol/realms/unicode-and-idna/) | | Listing and buying names | [Marketplace](/protocol/realms/marketplace/) | --- # Paynames URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/realms/paynames/ Page ID: protocol/realms/paynames Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0 Verified: 2026-08-31 Limitations: - Resolution is computed at a chain position and by one implementation. A payer who resolves once and caches the answer can pay the wrong destination later. A Payname is a Realm used as a payment destination. Instead of a raw address, a payer uses a name that resolves to one. ## What resolution guarantees That, at the height and generation the answer was computed, this name resolved to this Atomical, whose current location is this output, whose owner script is this. That is a chain of four facts. Every one of them can change. The output that carries a Realm can move at any time, and the owner script changes with it. Resolve immediately before paying, at a current generation, and show the payer the resolved address before they confirm. ## Checks a payer must run 1. Resolve the name to an Atomical ID. 2. Read the Atomical's current location and owner script. 3. Confirm the resolution generation is current, not cached. 4. Display the resolved address to the payer for confirmation. 5. Check the name for confusable characters against names the payer has used before. 6. For a significant amount, resolve through a second compatible source and compare. Step four is not optional. A payer who never sees the address cannot detect a wrong resolution. ## Confusable names Two names can render identically and be different strings. A payer who copies a name from a message may be copying a lookalike. See [Unicode and IDNA](/protocol/realms/unicode-and-idna/) for the normalisation rules and the warnings a product must show. ## What a product must never do - Never resolve once at page load and pay later from the cached answer. - Never hide the resolved address behind the name. - Never treat a name as proof of who the recipient is. - Never auto-fill a payment from a name found in untrusted content. --- # Subrealms URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/realms/subrealms/ Page ID: protocol/realms/subrealms Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-js-cli, universe-index-atomicals Verified: 2026-09-01 A Subrealm is a name under a parent Realm. The parent defines the rules; anyone who satisfies them can claim a Subrealm. ## The parent controls the rules Reference commands: `enable-subrealms`, `disable-subrealms`, `pending-subrealms`, `mint-subrealm `, `summary-subrealms`. See the [CLI reference](/reference/cli/). A parent can: - enable or disable Subrealm claiming; - define rules that a claim must satisfy; - require a payment to a specified output; - leave claiming open, subject only to name availability. ## Claiming 1. Read the parent's current rules, at a specific height. 2. Build a claim that satisfies them, including any payment. 3. Mint with `mint-subrealm`. 4. Wait for confirmation, then for resolution. 5. Confirm you are the verified winner, not a losing candidate. A claim that misses a rule still produces a confirmed Bitcoin transaction and costs a fee. ## Payments Where a rule requires payment, the payment output and its marker are part of validity. A payment marker output identifies which claim the payment belongs to, so a validator can match them. Paying the right amount to the wrong script, or omitting the marker, makes the claim invalid. ### A payment is never satisfied in a split transaction A payment carried in a transaction that also carries a split (`y`) operation is refused, even when the amount and the marker are both correct. The reason is that a split can reassign ARC-20 value inside the very transaction that is meant to pay, so the payment cannot be judged in isolation. This is the indexer being conservative rather than a rule stated in the format, and it may refuse a payment another implementation would accept. Send the payment as its own transaction. Combining it with a token movement to save a fee costs the claim. ## Pending claims A parent can inspect outstanding claims with `pending-subrealms`. A product showing Subrealms should distinguish: | State | Meaning | | --- | --- | | Pending | A claim exists and has not resolved | | Verified winner | The rules awarded the name | | Losing candidate | Another claim won | | Rejected | A rule was not satisfied | Showing a pending claim as owned is the failure to avoid. ## Hierarchy Subrealms can nest. A hierarchy read should return the root, the path, and the direct children, and should say when the child list was truncated rather than silently cutting it. The Universe read model exposes hierarchy and direct Subrealm listing with an explicit truncation flag. See [NFT and Realm API](/reference/api/atomicals-nfts-realms/). --- # Unicode, IDNA, and confusable names URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/protocol/realms/unicode-and-idna/ Page ID: protocol/realms/unicode-and-idna Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, universe-index-atomicals-nfts-and-realms Verified: 2026-08-31 Limitations: - Confusable detection reduces risk. It cannot eliminate it, because what looks alike depends on the font and the reader. Names can contain characters beyond ASCII. That is useful and it is dangerous, because two different strings can render identically. Someone registers a name that renders exactly like one you trust, using a different code point. You read it, recognise it, and pay. The bytes were never the same. ## Three different strings A reader sees one word. A comparison sees three: | Appearance | What differs | | --- | --- | | A Latin lowercase a | The ordinary code point | | A Cyrillic lowercase a | A different code point that renders the same in most fonts | | A Latin a with a combining mark | Two code points that compose to one glyph | ## Normalisation Normalisation maps different byte sequences that mean the same thing to one form, so comparison works. Two rules follow: 1. **Normalise before comparing.** Two names are the same only after both are normalised the same way. 2. **Keep the exact original bytes.** The authoritative name is what was minted. The normalised form is for comparison, not for display or for identity. Never store only the normalised form, and never display it as if it were the name. ## Authoritative against display | Form | Use | | --- | --- | | Exact minted bytes | Identity, storage, and what a validator saw | | Normalised form | Comparison, deduplication, confusable detection | | Display form | What a reader sees, escaped and marked when risky | ## What a product must do 1. Reject names that fail validation for the target rule set, with a clear reason. 2. Normalise before comparing, never before storing. 3. Detect mixed scripts within one name and warn. 4. Detect confusability against names the user already uses and warn prominently. 5. Escape names everywhere they are displayed, including in link text and error messages. 6. Neutralise bidirectional control characters so a name cannot reorder surrounding text. 7. Show the Atomical ID next to any name the user is about to act on. ## Error reporting A rejected name deserves a specific reason: which character, which rule. A generic failure teaches the user nothing and pushes them to guess. The Universe read model surfaces Unicode and IDNA errors explicitly rather than returning a generic validation failure. See [NFT and Realm API](/reference/api/atomicals-nfts-realms/). --- # AI and agent access URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/reference/ai-access/ Page ID: reference/ai-access Applicability: editorial Authority: none Networks: none Sources: none Verified: 2026-08-31 This documentation is built to be read by software as well as by people. Nothing here requires scraping rendered HTML. ## The outputs | Artefact | Path | Use | | --- | --- | --- | | Compact LLM index | `/llms.txt` | An orientation file: scope, core model, and where to look | | Full LLM bundle | `/llms-full.txt` | The complete normative content in one file | | Rendered LLM page | `/llms.html` | The same content, readable in a browser | | Page manifest | `/manifest.json` | Every page with its stable ID, area, status, sources, and content hash | | Raw Markdown | `/raw/.md` | The exact source of any page | | Specification | `/specification.md` | The compatibility specification as a standalone file | | Source ledger | `/sources.md` | Every source, revision, and why it is used | | OpenAPI documents | `/contracts/openapi/*.json` | Validated 3.1 contracts | | JSON Schemas | `/contracts/schemas/*.json` | The shared component library | | Conformance vectors | `/conformance/vectors/*.json` | Executed deterministic cases | | Changelog feed | `/changelog.xml` | A subscribable feed of documentation changes | | Sitemap | `/sitemap.xml` | Every route | ## What the LLM files guarantee 1. **Normative sources come first.** The pinned validator revision and the executed vectors lead; explanatory prose follows. 2. **Proposals and experiments are labelled.** Nothing that is proposed or beta is presented as live behavior. 3. **Protocol and product are never collapsed.** Every claim says whether it describes the protocol or a Universe service. 4. **Every claim is dated and pinned.** The source revision and verification date travel with the content. ## Page identity Every page has a stable `pageId` recorded in its frontmatter and exposed in the manifest, in a `bu:page-id` meta tag, and in the raw Markdown path. Page IDs are never reused and never renamed without a redirect. Use the page ID as the key, not the URL. URLs can move between locales and versions; a page ID cannot. ## Content hashes The manifest records a hash of each page's content. An agent can detect a change without diffing text, and a translation records the hash of the English source it was made from, which is how the site marks a translation as stale. ## Fetching politely `robots.txt` allows crawling. Two requests: 1. Read `manifest.json` once and fetch only the pages whose hash changed. 2. Prefer `/raw/.md` over the rendered page. It is smaller and it is the source. --- # Universe ARC-20 API URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/reference/api/arc20/ Page ID: reference/api/arc20 Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals, universe-index-atomicals Verified: 2026-08-31 Limitations: - Declared coverage is partial. The limitation applies to pending activity only, not to the confirmed scan or the holder proof requirements. ## What this service guarantees **Verified winners only.** Every ticker candidate is discovered without an upstream verified-only filter, then resolved through the provider. Only the verified winning Atomical ID is published. The reference exposed to products is the lower-case ticker, and the winning compact Atomical ID is retained in protocol details. **All or nothing scans.** Holder rows are aggregated by address and must sum exactly to circulating supply. A mismatch, a null address, a truncated page sequence, a changing declared total, or a changing chain tip aborts the entire poll. No partial authoritative snapshot is committed. **No double application.** Supply and holder snapshots are the authoritative state, so activity events publish empty wallet and supply deltas. A consumer that also applied event deltas would count everything twice. Confirmed authoritative history and complete proven holder snapshots are indexed, but the shipped adapter has no exhaustive mempool feed with stable pending lifecycle and disappearance handling. That limitation applies to **pending activity only**. ## Routes ## Cursors Cursors are opaque and signed with a secret separate from the feed bearer token. They refer to a position inside an immutable generation and preserve the page and holder chunk sizes they were created with. A cursor-free request may need to build a generation first. In that case the service copies a bounded number of rows and returns a retryable unavailable response until the generation is ready. Retries resume and reuse the same source fingerprint, and source movement abandons an unfinished generation. Treat that retryable response as normal during cold bootstrap, with backoff. At most 64 unexpired generations are retained. See [pagination and cursors](/develop/pagination-and-cursors/). ## Reorg handling Each changed tip is rescanned under identical before and after Bitcoin and Atomicals tips. Missing unfinalised events produce explicit invalidations. Changes to finalised blocks, events, or ticker identity fail closed. Historical headers outside the configured reorg window are reused from a durable journal. See [consistency and reorgs](/develop/consistency-and-reorgs/). ## Amount encoding Every satoshi and protocol quantity is a decimal string. JSON numbers are rejected, so no precision is lost in transit. Never parse one into a floating point number. ## Reading the figures correctly | Figure | What it is | | --- | --- | | Maximum issuance | `mint_amount * max_mints`. A ceiling, not a supply | | Claims made | Valid claims counted from records | | Circulating supply | Coloured value actually held after burns | | Global maximum | Null for a perpetual deployment with no configured maximum. Do not compute one | --- # Universe NFT and Realm API URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/reference/api/atomicals-nfts-realms/ Page ID: reference/api/atomicals-nfts-realms Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals-nfts-and-realms, universe-index-atomicals-nfts-and-realms Verified: 2026-08-31 Limitations: - The projection excludes fungible tokens, Containers, and DMINT items by declaration. An empty answer for one of those is correct, not a failure. ## The projection **Included:** plain NFT, Realm, Subrealm. **Excluded:** FT, DFT, Container, DMItem. **Write capabilities:** none. Asking this service about a Container returns nothing, correctly. Fungible tokens are served by the [ARC-20 API](/reference/api/arc20/). ## What this service guarantees - NFT, Realm, and Subrealm rows share one provider scan, one generation, one checkpoint, and one active pointer. - Publication requires exact final declared source-row coverage and rejects a count shrink or an incomplete page. - A generation spanning more than one provider tip is published explicitly as mixed and stale, without a single indexed height. - Realm name, parent, claim, candidate, and payment evidence is retained in asset-specific indexes. - The upstream provider commit is provenance, not a self-attested observed revision unless the provider reports it. ## Routes ## Readiness Ready requires all of the following: a generation identifier exists, the indexed height is a safe integer, the view is not stale, the tip is not mixed, and the integrity check has not failed. When any fails, the response is 503 carrying the reason, the state, the source, the network, the generation identifier, the indexed height, the source revision, and the counts. That response is designed to be actionable. See [readiness and freshness](/develop/readiness-and-freshness/). ## Media The media route serves stored bytes with MIME restrictions, a size limit, and digest validation. The service chooses the content type; it does not trust the one the payload declared. Treat everything it returns as hostile input. See [metadata and media](/protocol/nft/metadata-and-media/). ## Names `resolve` returns a status, and only `verified` means the rules awarded the name. A `candidate` status is not ownership. `hierarchy` and `subrealms` return a truncation flag. Honour it: it means there was more and the response stopped. Unicode and IDNA errors are surfaced explicitly rather than flattened into a generic validation failure. See [Unicode and IDNA](/protocol/realms/unicode-and-idna/). ## Holders A non-fungible object has exactly one holder, so `holderScope` is always `current-owner` and the total is one when an owner is known. ## Chain lookups Transaction, block, and outpoint lookups return projected assets scoped to the active generation. The outpoint lookup is the one to use before spending an output, because it tells you whether the output carries more than one Atomical. See [splat and mixed outputs](/protocol/nft/splat-and-mixed-outputs/). --- # Marketplace v1 URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/reference/api/marketplace-v1/ Page ID: reference/api/marketplace-v1 Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals, universe-index-atomicals, universe-index-atomicals Verified: 2026-08-31 Limitations: - Every marketplace and action gate defaults to false. Documentation of a capability is not a statement that it is enabled on any deployment. - Internal bridge routes are documented so integrators understand the boundary. They are not publicly reachable and no credential value appears here. The Marketplace v1 service is a durable protocol authority backed by Atomicals ElectrumX, Bitcoin Core, and the token-explorer database. It does not infer ownership from an address string or from indexer metadata alone. ## Four isolated lanes One router exposes four protocol authorities: `arc20`, `atomicals_nft`, `realms`, and `subrealms`. They share the durable transaction engine and operational credentials, but every route, cursor, idempotency scope, listing, offer, order, reservation, browse query, and status count is protocol scoped. Non-ARC-20 storage keys are prefixed internally, and the prefix is never returned as a public asset ID. | Lane | Collateral | Extra check | | --- | --- | --- | | `arc20` | The verified ticker winner, trading the complete FT value | None beyond the shared set | | `atomicals_nft` | An authoritative compact Atomical ID | Rejects realm, subrealm, FT, container, and item subtypes | | `realms` | A Realm | Resolves the verified name winner before every mutation | | `subrealms` | A Subrealm | Resolves the verified name winner before every mutation | The three non-fungible lanes always expose `quantityAtomic` as `1`. ## Safety model All marketplace and action gates default to false. Enabling an action gate while the marketplace gate is false is a configuration error. Enabling also requires separate request-HMAC, internal execution-bearer, internal execution-HMAC, and Bitcoin Core credentials, and the two HMAC secrets must be distinct. Buy or offer execution additionally requires an exact fee script. Enabling requires a release SHA identifying the exact deployed indexer commit. Every internal readiness response binds that revision and the exact `index-atomicals-{protocolId}-settlement-v1` authority identity, so a stale binary or a confused settlement authority is rejected before wallet preparation. ## What must agree before collateral is accepted For ARC-20, all of these independent views must agree: 1. The ticker resolves to its verified authoritative FT winner. 2. Bitcoin Core reports a confirmed, live UTXO with the exact value and owner script, and a mature coinbase where applicable. 3. `blockchain.atomicals.at_location` reports exactly that location, script, value, and one authoritative FT. 4. `blockchain.atomicals.listscripthash` reports exactly one active row whose coloured balance is the full UTXO value. 5. Bitcoin height and hash, and the Atomicals Bitcoin and Atomicals tips, remain unchanged across the verification bracket. Buyer funding inputs must be confirmed P2WPKH or key-path P2TR outputs, uncoloured in both the active script hash view and location history. The Atomicals transaction blueprint must assign the selected inputs cleanly to output zero, with no operation, no NFT, no mixed Atomical ID, and no burn. ## Always rejected Mixed collateral, spent outputs, checkpoint drift, ambiguous balances, Atomicals operations inside the settlement transaction, burns, output assignments that do not move the exact selected Atomical, wallet supplied mutations to a stored reservation projection, and unsupported adapter filters. ## Routes ### Public ### Adapter Direct, envelope free pages at `/v1/marketplace/protocols/{protocolId}`. Pages have exactly `{items, nextCursor?}` and accept the `cursor`, `limit`, `assetId`, `collectionId`, `owner`, `status`, `sort`, and `direction` query fields. Unsupported filters fail closed, and ARC-20 collection pages are empty by design. Listing and offer IDs exposed by this bridge are stable lowercase UUIDs reversibly mapped to the authority's prefixed storage keys. ### Operator ### Internal bridge Not publicly reachable. Documented so integrators understand where the boundary sits. ## Authentication and signing Reads use a bearer token. Public mutations add a replay-resistant signature: ```text v1\n{timestamp}\n{nonce}\n{method}\n{path}\n{sha256(exact_body_bytes)} ``` Headers: `X-Marketplace-Key-Id: universe-marketplace-v1`, `X-Marketplace-Timestamp`, `X-Marketplace-Nonce`, `X-Marketplace-Signature`. Mutations require `Idempotency-Key`. Owner actions use a short lived `X-Marketplace-Owner-Authorization` session, issued only after a BIP-322 simple proof with message type `smp`, for P2WPKH or key-path P2TR. The internal bridge requires three independent credentials and its own signature over `{timestamp}\n{method}\n{path}\n{sha256(exact_body_bytes)}`, with a sixty second acceptance window. The signed path is the exact protocol-specific request path, so a signature for another protocol path is rejected. No credential value appears anywhere in this documentation. See [authentication](/develop/authentication/). ## The PSBT and signing contract **Seller preparation.** PSBT v0, one collateral input, one payout output, sequence `0xfffffffd`, witness UTXO, and sighash type `0x83`, which is `SIGHASH_SINGLE` with `ANYONECANPAY`. The authority verifies the signature before persisting a live listing. **Purchase preparation is deterministic:** | Position | Contents | | --- | --- | | Input 0 | The first buyer funding input | | Inputs 1 to N | Seller inputs in request order | | Remaining inputs | The remaining buyer funding inputs | | Output 0 | The complete asset amount | | Outputs 1 to N | The corresponding seller payouts | | Next output | The marketplace fee output, when non-zero | | Last output | Buyer change, when it is not dust | Every seller input retains sighash `0x83` after combination. Buyer P2WPKH inputs require `SIGHASH_ALL`; key-path P2TR inputs allow default or ALL. The signed PSBT must preserve the prepared unsigned digest, the exact previous outputs, the output ordering, the miner fee, the fee-rate ceiling, and the Atomicals transfer blueprint. The authority performs Atomicals dry validation and Bitcoin Core `testmempoolaccept` before writing a durable broadcast intent. A transport failure after a durable broadcast intent is an ambiguous outcome and never triggers a blind rebroadcast. Reconciliation resolves it against chain evidence. ## Reservations A reservation request carries 1 through 63 buyer inputs, leaving one of the maximum 64 ordered spend claims for collateral. The reservation response is the complete projection: authoritative UUID reservation, subject, action-intent, claim, and spend-fence identifiers; exactly one non-null `listingId` or `offerId`; trusted actor and request context; ordered fees and spend claims; and every fee, payout, protocol-data, spend-claim, and economic commitment hash. The economic hash uses the exact `bitcoin-universe:marketplace-v1:purchase-reservation-economics:v1` schema and commits an absent optional `requestId` as JSON `null`. Reload and purchase preparation both recompute and compare the entire stored projection. Wallet supplied mutations are rejected. ## Exact protocol data | Action | Accepted shape | | --- | --- | | Listing validation | `{location, payoutAddress?}` | | Update | `{payoutAddress?}` | | Delist and offer cancellation | `{}` | | Offer creation | `{listingId, expectedListingRevision}` | | Purchase reservation | `{buyerInputs, receiveAddress, changeAddress?, feeRateAtomicVb}` | Anything else is rejected. These shapes are exact, not minimums. ## Amounts Every amount is a decimal string. JSON numbers are rejected for satoshi and protocol quantities. ARC-20 listings and offers cover the complete coloured UTXO. Non-fungible listings have quantity one and their price is the exact total Bitcoin consideration. ## Order lifecycle Orders move through `prepared`, `finalized`, `broadcasting`, `submitted` or `mempool`, and `confirmed`, or an explicit failure or recovery state. Reconciliation compares Bitcoin Core transaction, mempool, block-header, spending-prevout, and UTXO evidence. Listings settle only after the configured confirmation depth. Replacement, drop, conflict, and reorganisation evidence is recorded rather than guessed. Partial unique indexes enforce one live listing per collateral location, one open buyer offer per listing, and one active reservation per listing. Every mutation uses an expected revision inside a single immediate transaction. ## Composite position source `position-source` routes join Bitcoin Core's current UTXO, the Atomicals location inventory, active script hash balances, the ticker winner, and Realm and Subrealm winners between stable checkpoint probes. Responses use `universe-marketplace-protocol-position-v1` and contain only positions from that protocol. ARC-20 returns the exact coloured atomic quantity; non-fungible positions are singletons. Spent and unrelated outputs return a complete empty set. Mixed, unknown, non-standard, or internally inconsistent Atomicals fail closed rather than disappearing from composite evidence. ## Deprecated aliases | Deprecated | Replacement | | --- | --- | | `POST /buys` | `POST /reservations` then `POST /purchases/prepare` | | `POST /orders/{orderId}/reconcile` | `POST /settlements/{orderId}/reconcile` | See [versioning and deprecation](/develop/versioning-and-deprecation/). --- # Ordex contract URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/reference/api/ordex/ Page ID: reference/api/ordex Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-ordex, universe-ordex Verified: 2026-08-31 Limitations: - This page links the Ordex contract rather than restating it. A restated copy would drift, and a drifted copy of a settlement contract is dangerous. ## Why this page is short Ordex publishes its own OpenAPI document, SDK, conformance vectors, and purchase verifier. Copying them here would create a second version that can drift from the first. A drifted copy of a settlement contract is worse than no copy. So this page points at the source and documents only the boundary. ## Where the contract lives | Artefact | Path in the Ordex repository | | --- | --- | | OpenAPI document | `spec/openapi.json` | | Lifecycle specification | `spec/lifecycle.md` | | Purchase specification | `spec/purchase.md` | | API reference | `spec/api.md` | | Interoperability notes | `spec/interoperability.md` | | Conformance vectors | `conformance/purchase-vectors.json` | | Burn vectors | `conformance/rune-burn-vectors.json` | | SDK | `sdk/` | | Purchase verifier | `verifier/` | Repository: [bitcoinuniverseio/ordex](https://github.com/bitcoinuniverseio/ordex), pinned in this documentation at the revision shown in the source panel above. ## The boundary | Concern | Owned by | | --- | --- | | The Ordex marketplace contract, its lifecycle, and its vectors | Ordex | | Atomicals collateral verification for the four protocol lanes | [Marketplace v1](/reference/api/marketplace-v1/) | | Atomicals allocation and burn semantics | [The protocol](/protocol/arc20/allocation/) | | Which Universe surface exposes which flow | [Status and limitations](/start/status-and-limitations/) | Where a Universe surface wraps Ordex, the wrapper is documented on the Universe side and the contract stays where it is defined. ## What to do as an integrator 1. Take the OpenAPI document from the Ordex repository at a pinned revision. 2. Generate your client from that document rather than hand writing calls. 3. Run the Ordex conformance vectors against your build. 4. Use the Ordex verifier for purchase validation rather than reimplementing it. 5. For anything touching Atomicals collateral, read [Marketplace v1](/reference/api/marketplace-v1/) as well, because the collateral rules are enforced there. ## Do not - Do not assume an Ordex route behaves the same as a Marketplace v1 route with a similar name. - Do not mix vectors from the two contracts. - Do not treat an Ordex listing as evidence of Atomicals ownership. Ownership is verified at settlement, against the chain. --- # Atomicals CLI reference URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/reference/cli/ Page ID: reference/cli Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet, testnet, regtest Sources: atomicals-js-cli Verified: 2026-08-31 Limitations: - Command availability and behavior depend on the CLI revision you run and the validator it talks to. This inventory describes one pinned revision. - Options that change wallet or signing behavior are noted per command below, but the CLI itself is the authority on what it does. Any command that builds a transaction can spend outputs. Commands with `--funding` draw from a funding wallet, and commands with `--owner` spend the owner's outputs. Before running anything that moves an asset, model the allocation first with the [allocation visualizer](/tools/allocation-visualizer/). ## How to read this page - **Usage** shows the argument shape parsed from the source, not from a written example. - **Options** are the flags declared on that command. A flag absent here is not accepted. - **Defaults** are recorded only where the source declares one. Common options and what they affect: | Option | Effect | | --- | --- | | `--satsbyte` | Fee rate. Recompute after any Bitwork grind, which changes the transaction | | `--funding` | The wallet that pays. Keep it cardinal | | `--owner` | The wallet whose outputs are spent. This is where an asset moves from | | `--initialowner` | Where a newly minted object lands | | `--satsoutput` | The satoshi value of the output carrying the result. Keep it above the dust threshold | | `--bitworkc`, `--bitworkr` | Work required on your own commit and reveal transaction ids | | `--mintbitworkr` | Work a deployment requires of its claimants | | `--parent`, `--parentowner` | Parent linkage, set once at mint | | `--rbf` | Signals replaceability. A replacement is a different transaction with a different allocation | | `--disablechalk` | Turns off the progress display during grinding | ## Safety notes that apply to every command 1. No command needs a seed phrase typed into a prompt from a web page. Manage wallets locally. 2. A confirmed Bitcoin transaction is not a successful Atomicals operation. See [commit and reveal](/protocol/core/commit-and-reveal/). 3. Grinding changes the transaction, so any fee estimate taken before the grind is stale. 4. Read commands are safe. Build commands are not. ## Commands --- # TypeScript client URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/reference/client-sdk/ Page ID: reference/client-sdk Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals-nfts-and-realms, universe-index-atomicals Verified: 2026-08-31 Limitations: - The client covers the public read surfaces and the safe Marketplace contract types. It does not sign, broadcast, or hold key material. The client is generated from the OpenAPI documents and lives in `packages/client`. It is regenerated by `npm run generate`, and CI fails if the committed output differs. It does not sign, broadcast, request key material, or embed a credential. Those belong in a wallet and in your own server, not in a generated read client. ## Install and configure The base URL is required. There is no default, because a default would be a production host baked into a package. ```ts const client = new AtomicalsClient({ baseUrl: process.env.ATOMICALS_API_URL!, // Optional. Only for surfaces that require it. Never ship this in a browser. bearerToken: process.env.ATOMICALS_API_TOKEN, }) const asset = await client.getAsset({ atomicalId: '4d0b1f1c9c53a5b1e0b1b2c3d4e5f60718293a4b5c6d7e8f9a0b1c2d3e4f5061i0', }) console.log(asset.data.atomicalId, asset.generationId, asset.requestId) ``` ```js const client = new AtomicalsClient({ baseUrl: process.env.ATOMICALS_API_URL }) const ready = await client.getReady() if (!ready.data.ready) { console.error('not ready:', ready.data.reason) process.exit(1) } ``` ## Typed errors Failures throw a typed error carrying the status, the machine readable code, and the request identifier. Branch on the code, never on the message. ```ts try { await client.getNft({ atomicalId }) } catch (error) { if (error instanceof AtomicalsApiError) { if (error.code === 'NFT_NOT_FOUND') { // Not in the active generation. Check readiness before concluding it is gone. } console.error(error.status, error.code, error.requestId) } throw error } ``` ## Pagination The helper restarts the listing when the generation changes, rather than continuing with a cursor that is no longer valid. ```ts for await (const page of client.paginate.listNfts({ limit: 100 })) { for (const asset of page.items) { // page.generationId is stable across this loop. } } ``` ## Freshness Every response exposes the generation identifier, the indexed height, and the request identifier alongside the parsed body. Store them with anything you cache. ```ts const page = await client.listRealms({ limit: 50 }) console.log(page.generationId, page.indexedHeight, page.requestId) ``` ## What is included | Included | Not included | | --- | --- | | Public read operations for both indexes | Anything that signs or broadcasts | | Marketplace read operations and contract types | Marketplace mutation request signing | | Typed errors and pagination helpers | Credential storage or management | | Freshness metadata on every response | A default base URL | Marketplace mutations require an HMAC over exact body bytes and an owner session. Those belong in your server, where the secret lives. The client exposes the types so you can build the request, and deliberately does not sign it for you. ## Source [OpenAPI and downloads](/reference/openapi/) and [migration](/develop/migration/). --- # Conformance vectors URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/reference/conformance/ Page ID: reference/conformance Applicability: protocol-behavior Authority: executed-source Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-electrumx-1.5.2.0, atomicals-electrumx-1.5.2.0 Verified: 2026-08-31 Limitations: - The allocation engine models normal allocation and the activation gated custom coloring path. It is explanatory and never a substitute for validating a concrete transaction against your target validator revision. - Vectors for lifecycle behavior that depends on a live chain or a live service are described here as expectations rather than published as executed vectors, because executing them would require infrastructure this documentation deliberately does not carry. ## One engine, three consumers The prose, the [allocation visualizer](/tools/allocation-visualizer/), and the test suite all call the same function. They cannot disagree, because there is only one implementation. | Artefact | Path | | --- | --- | | Engine | `conformance/allocation.mjs` | | Vectors | `conformance/vectors/arc20-allocation.json` | | Tests | `tests/conformance-allocation.test.mjs` | The engine is implemented directly from `assign_expected_outputs_basic`, `calculate_outputs_to_color_for_ft_atomical_ids`, and `AtomicalsTransferBlueprintBuilder.color_ft_atomicals_regular` at the pinned revision. ## Executed allocation vectors Every row below is computed at build time by that engine. ## What each vector proves | Case | Proves | | --- | --- | | `clean-split` | An exactly covered output set places everything with no burn | | `oversized-next-output` | An output larger than the remaining value stops the walk and burns the remainder | | `exact-single-output` | A single output equal to the value takes everything | | `first-output-too-large` | Nothing can be placed at all, so the whole lot burns | | `too-few-outputs` | Running out of outputs burns what is left | | `unspendable-output-skipped` | An unspendable output is passed over and consumes nothing | | `combine-two-lots` | Two inputs of the same token are summed before allocation | | `two-tokens-sequential-slots` | A second token starts after the last slot the first used | | `two-tokens-non-clean-fallback` | A non-clean plan restarts every token from output zero | | `dust-remainder-burns` | A correctly sized change output places the remainder cleanly | | `change-output-too-large` | The same intent with a larger change output destroys the remainder | | `custom-coloring-partial-fill` | Activation gated custom coloring fills the last output partially instead of burning | ## The no-inflation property A separate test asserts, across every vector, that coloured output totals never exceed coloured input totals. That is the one rule no output arrangement can work around. ## Coverage the vectors do not claim This documentation does not publish unexecuted vectors as evidence. The following behaviors are documented as expectations, with their source, rather than presented as executed conformance material: | Behavior | Where it is documented | Why it is not an executed vector here | | --- | --- | --- | | Direct FT issuance, DFT deployment, DMT claim validity | [ARC-20](/protocol/arc20/overview/) | Validity depends on chain height, quota state, and Bitwork at execution time | | NFT normal transfer, swap, splat | [NFT transfers](/protocol/nft/transfers/) | Requires the non-fungible allocation branch against a live provider | | Container and DMINT verification | [Item verification](/protocol/containers/item-verification/) | Requires a sealed manifest and a live provider | | Realm candidate and winner resolution | [Candidates and winners](/protocol/core/candidates-and-winners/) | Resolution is computed at a chain position | | Unicode and IDNA behavior | [Unicode and IDNA](/protocol/realms/unicode-and-idna/) | Enforced by the runtime, surfaced through its explicit errors | | Marketplace listing, reservation, purchase, settlement, replay, stale ownership, mixed collateral | [Marketplace v1](/reference/api/marketplace-v1/) | Enforced by the authority against Bitcoin Core and the Atomicals provider, and covered by that repository's own suite | | Media digest validation, reorg generation behavior, signed cursor validation | [NFT and Realm API](/reference/api/atomicals-nfts-realms/) | Enforced by the runtime and covered by that repository's own suite | | Ordex purchase and burn vectors | [Ordex](/reference/api/ordex/) | Published and executed in the Ordex repository. Copying them here would create a second version that can drift | Stating this plainly is the point. A vector that was never executed is not evidence. ## Adding a vector See [conformance vectors](/contribute/conformance-vectors/). A new case must name the source lines it derives from, and it must pass before it is committed. --- # ElectrumX reference URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/reference/electrumx/ Page ID: reference/electrumx Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, universe-index-atomicals-nfts-and-realms Verified: 2026-08-31 Limitations: - Method availability and response shapes are version sensitive. Confirm against the exact release you connect to. - A Universe proxy or gateway is not the same as official ElectrumX. Do not attribute proxy behavior to the protocol. ## What ElectrumX is here Atomicals ElectrumX reads Bitcoin blocks and applies the Atomicals protocol rules. It is where protocol interpretation happens. Everything downstream is a projection of what it reports. The pinned baseline for this documentation is release **v1.5.2.0**, commit [`8df23747`](https://github.com/atomicals/atomicals-electrumx/commit/8df23747835c20230fc8b8097d469e7a1d97c3e0), released on 2025-03-27. That baseline is preserved as a historical reference and is not rewritten when a Universe service upgrades. ## The version handshake A consumer must check compatibility before trusting anything a provider reports. The Universe NFT and Realm index does exactly that, and refuses a provider that does not match: | Field | Checked against | | --- | --- | | Version | The pinned provider version | | Tag | The pinned provider tag | | Commit | The pinned provider commit | | Implemented AIPs | The exact required set, `[1, 3]` | | Network | The configured network | An exact AIP set is required. A provider reporting a different set, in a different order, or a different length is rejected rather than accepted with a warning. See [Atomicals Improvement Proposals](/protocol/aips/). ## Methods the Universe projection relies on | Method | Used for | | --- | --- | | `server.info` | The version and AIP handshake above | | `blockchain.atomicals.get_global` | The provider's current tip and global state | | `blockchain.atomicals.list` | Enumerating Atomicals for the scan | | `blockchain.atomicals.get_location` | Resolving where an Atomical currently sits | The Marketplace authority additionally reads: | Method | Used for | | --- | --- | | `blockchain.atomicals.at_location` | Confirming exactly one authoritative asset at an outpoint | | `blockchain.atomicals.listscripthash` | Confirming exactly one active row whose coloured balance is the full output value | | `blockchain.atomicals.get_by_ticker` | Resolving a ticker to its verified winner | Those two lists are the write capability boundary as well: the projection declares **no write capabilities**. ## Caching and consistency Three rules: 1. **Never cache a result without its chain position.** A response is only true at the tip it was computed at. 2. **Never mix positions.** Two calls at different tips produce an inconsistent picture. Bracket related calls and abort if the tip moved. 3. **A generation spanning more than one provider tip is mixed.** The Universe index publishes such a generation explicitly as mixed and stale rather than presenting it as consistent. ## Activation sensitive behavior Some responses depend on rules that activate at a height, per network. A method that returns one answer today can return a different one for the same historical transaction under a different revision. Record the provider version, the network, and the height with every stored answer. See [activation boundaries](/protocol/core/activation-boundaries/). ## Official against proxy behavior | Layer | What it is | | --- | --- | | Official Atomicals ElectrumX | The protocol authority. Its behavior is protocol behavior | | A Universe proxy or gateway | Transport, authentication, and shaping in front of it | | A Universe index | A materialised projection with its own generation model | Only the first is protocol behavior. Anything added by the second or third is Universe implementation and is labelled as such throughout this documentation. ## Source [Indexer and validator dependency](/protocol/core/indexer-dependency/) and [source of truth](/develop/source-of-truth/). --- # Documentation MCP server URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/reference/mcp/ Page ID: reference/mcp Applicability: universe-implementation Authority: universe-implementation Networks: none Sources: none Verified: 2026-08-31 Limitations: - The server is read only by construction. It exposes no mutation, signing, broadcast, wallet, or operator capability, and it requires no credential. The package in `packages/mcp` runs a local Model Context Protocol server over the built documentation artefacts. An agent can then query pages, contracts, and vectors directly instead of scraping rendered HTML. It reads the generated page manifest, raw Markdown, contracts, and vectors from disk. It requires no network access, no credential, and it cannot mutate anything. ## Install ```bash npm install npm run generate npm --workspace packages/mcp run build ``` ```bash node packages/mcp/dist/server.js --artifacts ./dist ``` The `--artifacts` path points at a built site directory containing `manifest.json` and the `raw/` tree. After installing those artefacts once, the server works offline. ## Tools it exposes | Tool | Returns | | --- | --- | | `search_documentation` | Pages matching a query, with page IDs and scores | | `get_page` | One page by its stable page ID, as raw Markdown | | `get_protocol_status` | The applicability and authority of a capability, with its limitations | | `get_api_operation` | One OpenAPI operation by operation identifier | | `get_json_schema` | One schema definition from the shared library | | `get_source_provenance` | The source manifest entry for a source identifier | | `get_version_matrix` | Every pinned source revision and its networks | | `get_conformance_vector` | One executed vector by case identifier | | `list_glossary_entries` | Every glossary term and its definition | | `list_known_limitations` | Every declared limitation across the documentation | ## What it will never expose - No mutation of any kind. - No signing or broadcasting. - No wallet interaction. - No credential, secret, or operator-only material. - No network calls to a Universe service. Those are structural, not configuration. The server has no code paths for them. ## Configuring an agent Point your MCP client at the built server with the artefacts path. The exact configuration format depends on the client, and the server itself takes only the one argument. ## Determinism The server answers from the committed artefacts. Given the same artefacts, the same query returns the same answer, which makes it usable in tests. ## Source [AI and agent access](/reference/ai-access/). --- # OpenAPI and downloads URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/reference/openapi/ Page ID: reference/openapi Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals, universe-index-atomicals-nfts-and-realms Verified: 2026-08-31 Limitations: - No production host is published in any document. Set the server variable to the origin your deployment exposes. Every document here is validated in CI. A route present in a document but absent from its source inventory fails the build, and so does the reverse. ## Documents ## What CI checks | Check | Effect when it fails | | --- | --- | | OpenAPI 3.1 structure | Build fails | | Operation identifier uniqueness within and across documents | Build fails | | Every operation has a summary, a declared tag, and responses | Build fails | | Route inventory equals the documented paths, in both directions | Build fails | | Every response example validates against its own schema | Build fails | | Every deprecated route names a replacement | Build fails | | No production host or routable address appears | Build fails | Publishing an origin in a contract invites people to point production traffic at it from a browser with a credential in the page. The server is a variable. Set it to the origin your deployment exposes. ## Amount encoding Every satoshi and protocol quantity is a decimal string in these contracts. JSON numbers are rejected, so no precision is lost in transit and no client silently converts a large integer into a float. ## Using the documents 1. Download the document for the surface you integrate with. 2. Generate a client rather than hand writing calls. See [TypeScript client](/reference/client-sdk/). 3. Run the [conformance vectors](/reference/conformance/) against your build. 4. Pin the document version alongside your service revision. 5. Regenerate on every upgrade and diff the generated types. --- # JSON Schemas URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/reference/schemas/ Page ID: reference/schemas Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals-nfts-and-realms, universe-index-atomicals Verified: 2026-08-31 One component library is shared by every OpenAPI document and by the generated client. Every example in it is validated in CI. ## The rules the schemas encode **Atomic amounts are strings.** `AtomicAmount` is a decimal string with a pattern, not a number. That is deliberate: a satoshi quantity above the safe integer range would lose precision as a JSON number, and a client that parses one into a float produces silently wrong arithmetic. **Atomical IDs have a shape.** `AtomicalId` is `i`, matched by pattern. A location is `:`. They are different things and the schemas keep them apart. **Names have three forms.** `AssetProjection` carries `name` as the exact minted bytes and `normalizedName` for comparison. Neither is a display form. See [Unicode and IDNA](/protocol/realms/unicode-and-idna/). **Freshness travels with answers.** `Freshness` carries the generation identifier, indexed height, stale flag, mixed tip flag, source revision, and network. A caller that stores an answer without these cannot explain a later disagreement. **Errors have a code.** Branch on `error.code`, never on `error.message`. Messages are for humans and can change without a version bump. `MediaDescriptor` carries a declared content type and a digest. The digest proves the bytes. The content type is attacker controlled. Sniff the bytes. ## Versioning Schemas carry a version. When it changes: 1. Validate your stored records against the new schema. 2. Fix what fails before switching. 3. Keep the old schema available until nothing reads the old records. See [migration](/develop/migration/). ## Adding a schema Contributor instructions are in [adding an API](/contribute/adding-an-api/). In short: add the definition with at least one example, reference it from the documents that use it, and let CI validate the example. --- # Wallet integration URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/reference/wallet-integration/ Page ID: reference/wallet-integration Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals, universe-inscribe Verified: 2026-08-31 Limitations: - Provider methods and payload shapes vary between wallets and versions. Only build against capabilities the current provider contract actually proves. ## Discover before you build The single most common integration failure is building a transaction for a capability the wallet does not have, then discovering it at signing time. Discover first: 1. Is a provider present? 2. Which networks does it support, and which is it on? 3. Which address and script types can it sign? 4. Which PSBT encodings does it accept? 5. Which signature hash flags will it produce? 6. Does it sign only, or sign and broadcast? 7. Can it prove address control without moving anything? Then build for what it answered. Do not code against a provider method because another integration uses it. Verify it exists in the current provider contract for the version your users run. ## Provider detection A provider is injected into the page. Detection must: - wait for injection rather than assuming it happened before your code ran; - handle a provider that appears after a user installs it; - handle more than one provider being present; - never assume a specific provider is the only one. ## Connection states | State | What it means | What to show | | --- | --- | --- | | Absent | No provider injected | An install path, not an error | | Present, not connected | Injected, no permission granted | A connect action | | Locked | Connected previously, wallet locked | An unlock prompt, and retry | | Wrong network | Connected, different network | The network you need, and how to switch | | Wrong account | Connected, a different account owns the input | Which account is required | | Ready | Connected and on the right network | The action | Handle reconnection: a provider can disconnect at any time, and a stale connection produces confusing failures. ## PSBT requirements Every input must carry the previous output script and value, derivation information for the signing key, and for Taproot inputs the internal key and merkle root. Every output must carry its exact script and value. Never reorder inputs or outputs. Order is meaning in Atomicals, and a library that canonicalises ordering changes the allocation result. See [PSBT requirements](/protocol/arc20/psbt-requirements/). ## Signature hash scopes | Scope | Use | | --- | --- | | `SIGHASH_ALL` | An ordinary transfer, and buyer P2WPKH inputs in a settlement | | Default or ALL for key-path P2TR | Buyer Taproot inputs in a settlement | | `SIGHASH_SINGLE` with `ANYONECANPAY`, `0x83` | Seller collateral in a Marketplace v1 listing | A builder must state the expected scope per input. A wallet must show which scope it is about to use. A signer must refuse a scope they did not expect. ## BIP-322 ownership proof Proving control of an address without moving anything. Marketplace v1 issues an owner session only after a BIP-322 simple proof for P2WPKH or key-path P2TR. A proof is not a signature on a settlement transaction. Keep the two steps distinct in your user interface, so a user is never led to believe proving ownership sold something. ## Protected outputs The wallet must exclude coloured outputs from automatic coin selection unless the user explicitly chose to spend that asset. An integration should also: - request the coloured state per input before building; - surface the asset name and Atomical ID for every coloured input; - show the expected allocation per output; - show the burn figure, and require a deliberate confirmation when it is not zero. ## Normalised errors Map provider errors into categories a user can act on, rather than surfacing raw strings: | Category | Examples | What to show | | --- | --- | --- | | Capability | Unsupported script type, unsupported flag | What the wallet cannot do, and an alternative | | Encoding | Unreadable PSBT, missing input data | A rebuild, not a retry | | Scope | Refused signature hash flag | The scope required, and why | | State | Locked, disconnected, wrong network or account | The exact state to fix | | User | Rejected in the wallet | Nothing happened. Offer to try again | ## Browser and mobile Injection timing, deep links, and app switching all differ on mobile. Two rules: 1. Never lose transaction state when the browser backgrounds during an app switch. 2. Never re-prompt for a signature you already have. ## Source [Wallet safety](/protocol/arc20/wallet-safety/) and [wallet signing failures](/guides/wallet-signing-failures/). --- # Releases URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/releases/ Page ID: releases/index Applicability: editorial Authority: none Networks: mainnet Sources: none Verified: 2026-08-31 Documentation version **2026.08**. The machine readable form of this page is the [changelog feed](/changelog.xml). ## What is versioned separately | Axis | Where it appears | Current | | --- | --- | --- | | Protocol reference baseline | The pinned validator revision | Atomicals ElectrumX v1.5.2.0 | | Universe API surface | The `/v1/` segment and the service revision | v1 | | Marketplace contract | The Marketplace v1 route and signing contract | v1 | | Generated schemas | A version field in each schema | 1.0.0 | | Documentation | The version on every page | 2026.08 | Never assume two of them move together. See [versioning and deprecation](/develop/versioning-and-deprecation/). ## Related | Page | Contains | | --- | --- | | [Versions and compatibility](/releases/versions/) | Every pinned source revision and what it applies to | | [Deprecations](/releases/deprecations/) | What is scheduled for removal, and what replaces it | | [Migrations](/releases/migrations/) | Step by step moves between versions | --- # Deprecations URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/releases/deprecations/ Page ID: releases/deprecations Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals Verified: 2026-08-31 ## The policy A deprecated capability still works. It is scheduled for removal, and every deprecation records six things: 1. The old behavior. 2. The new behavior. 3. The effective version. 4. Migration instructions. 5. The compatibility impact. 6. The source evidence. A deprecation does not promise the old and new behaviors are identical. Read the migration note rather than assuming a rename. ## Current deprecations ### Marketplace legacy purchase alias | Field | Value | | --- | --- | | Old | `POST /api/marketplace/v1/protocols/{protocolId}/buys` | | New | `POST /reservations` followed by `POST /purchases/prepare` | | Effective | Marketplace v1 | | Impact | The merged step is separated into reservation and preparation, which is why the replacement is two calls | | Migration | [Migration](/develop/migration/) | | Evidence | Recorded in the Marketplace v1 contract in `index-atomicals` | The alias remains available. New integrations use the replacement. ### Marketplace legacy reconcile alias | Field | Value | | --- | --- | | Old | `POST /api/marketplace/v1/protocols/{protocolId}/orders/{orderId}/reconcile` | | New | `POST /api/marketplace/v1/protocols/{protocolId}/settlements/{orderId}/reconcile` | | Effective | Marketplace v1 | | Impact | Route move only, under the settlement resource | | Migration | [Migration](/develop/migration/) | | Evidence | Recorded in the Marketplace v1 contract in `index-atomicals` | ## The sunset policy 1. A deprecation is announced here and in the changelog feed before removal. 2. A deprecated route is marked in its OpenAPI document, and CI requires it to name a replacement. 3. Removal happens in a version, never silently. 4. Nothing is removed without a documented replacement or an explicit statement that the capability is gone. ## Documentation route compatibility The earlier standalone documentation files are not deprecated. They are preserved as compatibility artefacts and regenerated from the current content on every build, so they cannot drift from it. | Route | Status | | --- | --- | | `/index.html` | Generated, current | | `/about.html` | Generated, current | | `/guide.html` | Generated, current | | `/reference.html` | Generated, current | | `/specification.md` and `/specification.html` | Generated, current | | `/sources.md` and `/sources.html` | Generated, current | | `/llms.txt` and `/llms.html` | Generated, current | ## What has never been deprecated Page IDs. A page ID is never reused and never renamed without a redirect, which is why an agent should key on the page ID rather than the URL. See [AI and agent access](/reference/ai-access/). --- # Migrations URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/releases/migrations/ Page ID: releases/migrations Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals Verified: 2026-08-31 ## The general procedure 1. Record your current pins: validator revision, network, service revisions, schema versions, and documentation version. 2. Read the [changelog](/releases/) between your pins and the target. 3. Read every applicable migration below. 4. Re-run the [conformance vectors](/reference/conformance/) against the target combination. 5. Regenerate your client from the target OpenAPI document. 6. Diff the generated types. Anything that changed shape is work. 7. Test against the target outside production. 8. Move, then verify with real reads before switching traffic. Step four catches interpretation changes that a type diff cannot show. ## Migration: legacy buy to reservation and purchase **Old behavior.** One call created a purchase intent and prepared the transaction together. **New behavior.** Two calls. `POST /reservations` holds the listing and returns the complete reservation projection. `POST /purchases/prepare` builds the settlement transaction from that reservation. **Why.** Separating them makes the reservation projection inspectable before anything is prepared, and lets a client reload it without mutation. **Steps.** 1. Replace the single call with `POST /reservations`. 2. Store the returned `reservationId` and the complete projection. 3. Call `POST /purchases/prepare` with that `reservationId`. 4. Continue with validate-signed and broadcast as before. 5. Use one idempotency key per logical action, reused across retries of that action. **Compatibility impact.** The legacy alias remains available. Reservation expiry is now visible, so handle an expired reservation by reserving again. ## Migration: legacy reconcile to settlement reconcile **Old behavior.** `POST /orders/{orderId}/reconcile`. **New behavior.** `POST /settlements/{orderId}/reconcile`. **Steps.** Change the path. The request and response shapes are unchanged. **Compatibility impact.** None beyond the path. Both remain available. ## Migration: to the documentation platform Anything linking to the earlier standalone files keeps working. Those routes are generated from the current content on every build. | If you linked to | It still resolves | The current page is | | --- | --- | --- | | `/specification.html` | Yes | [ARC-20](/protocol/arc20/overview/) | | `/sources.html` | Yes | [Versions and compatibility](/releases/versions/) | | `/reference.html` | Yes | [Reference](/reference/cli/) | | `/guide.html` | Yes | [Guides](/guides/) | | `/llms.txt` | Yes | Unchanged in purpose, expanded in content | New links should use the page routes. Agents should key on page IDs from [the manifest](/reference/ai-access/). ## Migrating a validator revision Move one thing at a time. 1. Move the validator revision. Re-run the vectors. Verify with real reads. 2. Only then move the API revision. Re-run the vectors again. Moving both at once makes an unexpected difference impossible to attribute. --- # Versions and compatibility URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/releases/versions/ Page ID: releases/versions Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, universe-index-atomicals, universe-index-atomicals-nfts-and-realms Verified: 2026-08-31 ## The verified source set ## Every pinned source ## The two baselines The protocol baseline is preserved as history. The Universe revisions move. Rewriting the historical baseline whenever a service upgrades would erase the record of what a transaction meant when it was made. **Protocol reference baseline.** Atomicals ElectrumX v1.5.2.0, commit `8df23747`, released 2025-03-27. Every version-sensitive protocol statement on this site is pinned to it. It is not silently updated. **Universe implementation revisions.** Listed separately, per page, in each source panel. They move with deployments. A page that describes both says which is which. ## Documentation versions | Version | Status | Covers | | --- | --- | --- | | 2026.08 | Current | The full platform: protocol, guides, contracts, tools, and machine readable outputs | Earlier documentation existed as a small set of standalone files. Those routes are preserved as compatibility artefacts and are regenerated from this content, so they cannot drift. See [deprecations](/releases/deprecations/). ## Compatibility matrix | Consumer | Requires | Notes | | --- | --- | --- | | Universe NFT and Realm index | Provider version, tag, commit, and the exact AIP set `[1, 3]` | Refuses a provider that does not match | | Universe ARC-20 index | The pinned Atomicals proxy contract | Declares partial coverage with an explicit reason | | Marketplace v1 | A release SHA identifying the exact deployed indexer commit | Binds the settlement authority identity per protocol lane | | Generated TypeScript client | An OpenAPI document version | Regenerate rather than hand editing | | Documentation MCP server | Built site artefacts | Works offline once installed | ## Pinning your own integration 1. Choose a validator revision or release, and record it. 2. Record the network and its active rule set. 3. Record the Universe service revision from `GET /version`. 4. Re-run the [conformance vectors](/reference/conformance/) against that combination. 5. Re-check before every upgrade, not after. --- # SDKs URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/sdks/ Page ID: sdks Applicability: universe-implementation Authority: universe-implementation Networks: mainnet, regtest Sources: universe-index-atomicals, universe-index-atomicals-nfts-and-realms Verified: 2026-09-02 Limitations: - Every client is read-only with an explicit base URL, typed errors, timeouts, and cancellation in the language idiom. No client signs, broadcasts, or stores keys. - The Go and Python toolchains are exercised in CI; the Rust client is compiled and checked locally with cargo. The TypeScript client under packages/client and the Python, Go, and Rust clients under clients/ all derive from the same OpenAPI documents the site validates. A contract change regenerates every client, and the coverage test fails CI if any operation goes missing. | Language | Location | Transport | Notes | | --- | --- | --- | --- | | TypeScript | `packages/client` | fetch | Generated types for every operation and response | | Python | `clients/python` | urllib, no runtime dependencies | Type hints, Ruff and mypy clean in CI | | Go | `clients/go` | net/http with contexts | `gofmt` and `go vet` clean in CI | | Rust | `clients/rust` | reqwest with rustls | `cargo check` and Clippy clean in CI | Each client requires an explicit base URL: none of them hides a default production origin. Retries are absent by default; a caller who wants retries for safe idempotent reads adds them explicitly. ## Coverage The generated [coverage manifest](../../site/src/generated/sdk-coverage.json) lists every read-only operation each client exposes. Regenerating is one command and must leave the working tree clean: ``` npm run sdk:generate ``` ## Quick start (Python) ```python from atomicals_client.client import Client client = Client("http://127.0.0.1:3043") status = client.arc20_get_status() print(status["coverage"], status["chainTip"]) ``` ## Quick start (Rust) ```rust let client = atomicals_client::Client::new("http://127.0.0.1:3043")?; let status = client.arc20_get_status().await?; println!("{} at {}", status["coverage"], status["chainTip"]); ``` ## Release artifacts Versioned archives and checksums for every SDK ship with each release so the packages stay installable without any external registry credential. See [releases](/releases/). --- # Choose your path URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/start/choose-your-path/ Page ID: start/choose-your-path Applicability: editorial Authority: none Networks: mainnet Sources: none Verified: 2026-08-31 Pick the row that matches what you are doing today. Every route is short on purpose. ## Holder You own units, an NFT, or a Realm, and you want to keep them. 1. Learn the model: [what is ARC-20](/start/what-is-arc-20/) and [what are Atomicals](/start/what-are-atomicals/). 2. Run the checks in [safety fundamentals](/start/safety-fundamentals/). 3. Pick a wallet that understands coloured outputs: [choose a wallet](/guides/choose-a-wallet/). 4. Separate fee money from coloured money: [protect coloured outputs](/guides/protect-colored-outputs/). 5. Before any move, model it: [allocation visualizer](/tools/allocation-visualizer/). 6. After broadcast, confirm the result: [verify a transaction](/guides/verify-a-transaction/). ## Creator You are launching a token, a collection, or a name. 1. Decide the issuance shape: [direct](/protocol/arc20/direct-issuance/), [fixed DFT](/protocol/arc20/fixed-dft/), or [perpetual DFT](/protocol/arc20/perpetual-dft/). 2. Understand what a ticker actually reserves: [tickers and candidates](/protocol/arc20/tickers-and-candidates/). 3. Budget the work: [Bitwork](/protocol/core/bitwork/) and the [Bitwork estimator](/tools/bitwork-estimator/). 4. Build the command: [CLI reference](/reference/cli/) and the [command builder](/tools/cli-builder/). 5. For collections: [Containers](/protocol/containers/overview/) then [DMINT](/protocol/containers/dmint/). 6. For names: [claim a Realm](/guides/claim-a-realm/) and [Unicode and IDNA](/protocol/realms/unicode-and-idna/). ## Developer You are integrating an API, a wallet, or an indexer. 1. Read the [source of truth model](/develop/source-of-truth/) first. It decides how much you can trust any response. 2. Take the contracts: [OpenAPI and schemas](/reference/openapi/). 3. Generate a client: [TypeScript client](/reference/client-sdk/). 4. Handle the hard parts: [cursors](/develop/pagination-and-cursors/), [reorgs](/develop/consistency-and-reorgs/), [readiness](/develop/readiness-and-freshness/). 5. Prove your builder: [conformance vectors](/reference/conformance/). 6. Wire the wallet: [wallet integration](/reference/wallet-integration/). ## Operator You run or depend on the indexes. 1. [Generations, checkpoints, and rollback](/develop/consistency-and-reorgs/). 2. [Readiness against configured](/develop/readiness-and-freshness/) and what each state means to a caller. 3. [Unavailable index against empty balance](/guides/unavailable-indexer-vs-empty-balance/), the difference that causes support tickets. 4. [Versioning and deprecation](/develop/versioning-and-deprecation/) so consumers are warned before behavior changes. Deployment, credentials, capacity, topology, monitoring, and recovery procedures are not published here. They belong in the private developer documentation repositories `docs-dev-atomicals` and `docs-dev-atomicals-nfts-and-realms`. --- # Glossary URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/start/glossary/ Page ID: start/glossary Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-guide Verified: 2026-08-31 Terms in this glossary are the ones used across the site and in every translation. Code identifiers, schema property names, operation names, and hashes are never translated. ## Core **Atomical** : A digital object created by a Bitcoin transaction and carried by a Bitcoin output. **Atomical ID** : The durable identity of an Atomical, written `i`. Assigned once, never changes. **Atomical number** : A sequential number assigned in mint order. Useful for display. Not the identity to store. **Location** : The unspent output that currently carries an Atomical. Changes on every move. **Envelope** : The witness script structure carrying `atom`, an operation, and a CBOR payload in the reveal transaction. **Operation** : The short code inside the envelope that tells a validator what to do. Examples: `ft`, `dft`, `dmt`, `nft`, `mod`, `sl`. **Commit and reveal** : The two-transaction pattern. The commit pays to a Taproot output; the reveal spends it and exposes the envelope. **Bitwork** : A proof-of-work style prefix requirement on a transaction id, used to gate mints and claims. **Candidate** : A pending claim for a globally allocated name or ticker, before rules resolve a winner. **Verified winner** : The Atomical that the rules resolved as holding a name or ticker. **Generation** : An immutable snapshot of an index at one consistent chain position. **Reorg** : A Bitcoin chain reorganisation that can invalidate previously indexed results. ## ARC-20 **ARC-20** : The Atomicals fungible token model. One unit is one coloured satoshi. **Ticker** : A globally allocated ARC-20 name. Not proof of creator identity. **Coloured UTXO** : A Bitcoin output that a validator recognises as carrying ARC-20 value. **Cardinal UTXO** : An ordinary Bitcoin output with no Atomicals value. Used for fees and change. **Direct FT** : A one-step `ft` mint that places the whole supply in output zero. **DFT** : A decentralised fungible token deployment created with `dft`. **DMT claim** : A single mint against a DFT deployment, using the `dmt` operation. **Perpetual DFT** : An activation-gated decentralised mode with progressing Bitwork and an optional global cap. **Mint amount** : The exact satoshi value each valid DMT claim places in output zero. **Max mints** : The number of valid fixed-mode claims a deployment allows. **Allocation** : The validator's decision about which output receives how much coloured value. **Normal allocation** : The default coloring behavior when no operation payload changes it. **Burn** : Coloured value that could not be placed in any eligible output and is therefore destroyed. **Split** : The `y` operation, which separates fungible value at one output. **Custom coloring** : The `z` operation, activation gated, which assigns coloured value explicitly. **Splat** : The `x` operation on the non-fungible branch, separating multiple Atomicals held at one output. **No-inflation validation** : The rule that coloured output totals cannot exceed coloured input totals. ## Names and collections **Container** : A named collection identity that items can prove membership in. **DMINT** : Decentralised minting of Container items against a sealed manifest. **Sealing** : Making an Atomical or a Container manifest permanently unchangeable. **Realm** : A top-level Atomicals name owned as an NFT. **Subrealm** : A child name claimed under a parent Realm's rules. **Payname** : A Realm used as a payment destination. **IDNA** : The internationalised domain name rules used when comparing and normalising names. **Confusable** : Two distinct names that render similarly enough to deceive a reader. ## Integration **Cursor** : An opaque, signed pagination token that refers to a stable position in a generation. **Readiness** : Whether a service can currently answer correctly, distinct from whether it is configured or running. **Freshness** : How far behind the chain tip an index currently is. **Idempotency key** : A client-supplied key that makes a repeated mutation safe to retry. **Request ID** : A per-request identifier returned in responses and logs, used to trace one call. **PSBT** : A partially signed Bitcoin transaction, the exchange format between a service and a wallet. **BIP-322** : A message signing scheme used here to prove control of an address without moving funds. **SIGHASH** : The flag that decides which parts of a transaction a signature commits to. ## Terms we avoid These words appear in third-party material and are not used as claims on this site: guaranteed, risk-free, backed, collateralised, price floor, redemption. Where a source uses them, the page quotes the source and says what evidence exists. --- # Networks and versions URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/start/networks-and-versions/ Page ID: start/networks-and-versions Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet, testnet, signet, regtest Sources: atomicals-electrumx-1.5.2.0, universe-index-atomicals-nfts-and-realms Verified: 2026-08-31 Limitations: - Activation heights differ per network. A behavior proven on one network does not prove the same behavior on another. Three separate version axes affect every source-sensitive statement on this site. Mixing them up is the single most common cause of wrong integrations. ## 1. The network Atomicals activation conditions are network specific. The pinned reference implementation carries different activation heights per coin definition. A rule that is active on mainnet may be inactive, active at a different height, or always-on in a regtest configuration. Every page lists the networks it applies to in its source panel. When a page says `mainnet` only, do not assume the same behavior elsewhere. ## 2. The validator revision The Atomicals specification is defined in code. The reference revision this documentation is pinned to is Atomicals ElectrumX [`8df23747`](https://github.com/atomicals/atomicals-electrumx/commit/8df23747835c20230fc8b8097d469e7a1d97c3e0), released as v1.5.2.0 on 2025-03-27. That revision is preserved as a stable historical baseline. It is not silently rewritten when a Universe service upgrades. Universe implementation revisions are listed separately, per page, in the source panel. If two implementations at different revisions read the same transaction differently, that is a version difference, not a bug in one of them. Investigate the revision and activation state before deciding which answer to trust. Never resolve a disagreement by majority vote. ## 3. The documentation version This site publishes documentation version **2026.08**. Each page states the version it describes in its source panel. See [versions and compatibility](/releases/versions/) for the full matrix, and [releases](/releases/) for what changed. ## How to pin your own integration 1. Choose an Atomicals validator revision or release, and record it. 2. Record the network and its active rule set. 3. Record the Universe service revision if you consume our APIs. Every service exposes it on `GET /version`. 4. Re-run the [conformance vectors](/reference/conformance/) against that exact combination. 5. Re-check before every upgrade, not after. ## What "activation" means here An activation boundary is a block height or configuration flag that turns a validation rule on. Before the boundary the old interpretation applies. After it the new one does. A transaction is judged by the rules active at its own height, not by today's rules. Pages that describe activation-sensitive behavior show the boundary in the source panel under **Activation boundary**. See [activation boundaries](/protocol/core/activation-boundaries/). --- # Protocol family map URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/start/protocol-family-map/ Page ID: start/protocol-family-map Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-js-cli, universe-inscribe Verified: 2026-09-26 Limitations: - Support columns describe Universe product exposure at the verified date, not protocol capability. ## Primitives | Primitive | Creating operation | Result | Read | | --- | --- | --- | --- | | Atomicals NFT | `nft` | One non-fungible object with optional payload files | [NFT overview](/protocol/nft/overview/) | | Direct FT | `ft` | Complete fungible supply in output zero | [Direct issuance](/protocol/arc20/direct-issuance/) | | Fixed DFT | `dft` | A deployment that others mint against | [Fixed DFT](/protocol/arc20/fixed-dft/) | | DFT claim | `dmt` | One mint of the deployment's exact amount | [Decentralised mint](/protocol/arc20/decentralized-mint/) | | Perpetual DFT | `dft` with perpetual parameters | Activation gated progressive minting | [Perpetual DFT](/protocol/arc20/perpetual-dft/) | | Container | `nft` with a container request | A named collection identity | [Containers](/protocol/containers/overview/) | | DMINT item | `dmt` item claim against a sealed manifest | A verified collection item | [DMINT](/protocol/containers/dmint/) | | Realm | `nft` with a realm request | A top-level name | [Realms](/protocol/realms/overview/) | | Subrealm | `nft` with a subrealm request | A child name under a Realm | [Subrealms](/protocol/realms/subrealms/) | | Payname | A Realm used as a payment destination | A resolvable name | [Paynames](/protocol/realms/paynames/) | ## Transfer and maintenance operations | Operation | Applies to | What it does | | --- | --- | --- | | normal allocation | FT and NFT | Default coloring when no operation payload is present | | `y` | FT | Split behavior at the pinned revision | | `z` | FT | Custom coloring, activation gated | | `x` | NFT | Splat, separating multiple Atomicals held at one output | | `mod` | Any | State update recorded in history | | `evt` | Any | Event record | | `sl` | Container, NFT | Seal, making further changes impossible | | `dat` | Any | Permanent data storage | Exact payload shapes and activation conditions are version sensitive. See [envelope and operations](/protocol/core/envelope-and-operations/). ## Universe product exposure This column answers a different question from the one above. It is about what our services do, not what the protocol allows. | Capability | Universe status | Where | | --- | --- | --- | | ARC-20 token discovery, details, holders, activity | Available | [ARC-20 API](/reference/api/arc20/) | | ARC-20 portfolio balances and UTXOs | Available | [ARC-20 API](/reference/api/arc20/) | | NFT, Realm, and Subrealm read model | Available | [NFT and Realm API](/reference/api/atomicals-nfts-realms/) | | Marketplace v1 for ARC-20, NFTs, Realms, Subrealms | Available, gated per action | [Marketplace v1](/reference/api/marketplace-v1/) | | Direct `mint-ft` issuance from a Universe product | Not exposed | [Direct issuance](/protocol/arc20/direct-issuance/) | | Container and DMINT read model | Not in the NFT and Realm projection | [Containers](/protocol/containers/overview/) | | AVM execution | Testnet4 only. No mainnet writes | [AVM status](/protocol/avm/status-and-limitations/) | The Universe NFT and Realm index deliberately projects plain NFTs, Realms, and Subrealms only. Fungible tokens, Containers, and DMINT items are excluded from that projection and served by the ARC-20 side. That exclusion is declared in the index's own provenance manifest. --- # Safety fundamentals URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/start/safety-fundamentals/ Page ID: start/safety-fundamentals Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-electrumx-1.5.2.0 Verified: 2026-08-31 Limitations: - These checks reduce avoidable loss. They do not replace validating a concrete transaction against the validator revision your counterparties run. Most Atomicals losses are not exploits. They are ordinary Bitcoin transactions that spent a coloured output the way an ordinary wallet would. ## Never do these - Never give a seed phrase, private key, or wallet export file to anything, including us. No legitimate verification needs them. - Never let a general purpose Bitcoin wallet choose fee inputs from a set that includes your coloured outputs. - Never treat a ticker, image, name, or marketplace listing as proof of who made something. - Never treat one indexer response as final truth. It is one version's opinion at one moment. ## The eight checks before you sign 1. **Which outputs are coloured?** Identify the exact outpoints carrying the asset. If your wallet cannot tell you, stop. 2. **What is the input order?** Allocation walks inputs and outputs in order. Order changes the result. 3. **What is each output worth in satoshis?** Not in token units. In satoshis. 4. **What is the output order?** Output zero is special for mints and for most transfer shapes. 5. **How much lands where?** Every output should have an expected unit figure before you sign. 6. **What burns?** If any value cannot be placed, it is destroyed. It should be zero unless you intended otherwise. 7. **Where does the fee come from?** A separate cardinal input, never the coloured one. 8. **What does the wallet prompt actually say?** Compare it to your expectation, line by line. Sending a coloured output to an exchange deposit address, a plain Bitcoin wallet, or any service that does not understand Atomicals means the value is spent as ordinary bitcoin. The units are gone. There is no recovery path. ## What a burn looks like A burn is not an error. The Bitcoin transaction is valid, mined, and confirmed. The units simply have nowhere to go, so the validator records them as destroyed. Read [burns](/protocol/arc20/burns/) for the exact rule and [avoid burns](/guides/avoid-burns/) for the working procedure. ## Four claims that prove nothing | Claim | What it actually proves | | --- | --- | | The ticker matches | A name was allocated to some Atomical. Nothing about who. | | The metadata says so | Someone wrote arbitrary data into a payload. | | It is listed on a marketplace | Someone submitted a listing. Ownership is checked separately, at settlement. | | The indexer shows a balance | One implementation, at one generation, believes that. Check the version and freshness. | ## After you broadcast 1. Wait for confirmation on Bitcoin. 2. Wait for the index to reach that height and report a stable generation. 3. Re-read the asset's location and confirm it matches the output you intended. 4. Check the transaction for recorded burns. Confirmation and indexing are two separate answers. See [confirmations and reorgs](/guides/confirmations-and-reorgs/). ## If something already went wrong - A transaction that was rejected before broadcast is recoverable: [recover from a rejection](/guides/recover-from-a-rejection/). - A wallet that will not sign is usually a capability or encoding problem: [wallet signing failures](/guides/wallet-signing-failures/). - A balance that reads zero is often an unavailable index, not a loss: [unavailable index against empty balance](/guides/unavailable-indexer-vs-empty-balance/). - A confirmed burn cannot be reversed. Nothing on this site can change that. --- # Status and known limitations URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/start/status-and-limitations/ Page ID: start/status-and-limitations Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals, universe-index-atomicals-nfts-and-realms, atomicals-avm-interpreter, universe-inscribe Verified: 2026-09-26 Limitations: - This page reflects the verified date above. Check the source panel before relying on any row. ## ARC-20 | Capability | Status | Notes | | --- | --- | --- | | Verified ticker resolution and token details | Universe implementation | Winning Atomical ID is published, not just the name | | Holder snapshots | Universe implementation | Holder rows must sum exactly to circulating supply or the scan aborts | | Confirmed activity history | Universe implementation | Deployment, direct and decentralised mint, transfer, burn, protocol operations | | Pending activity coverage | Limited | No exhaustive mempool feed with stable pending lifecycle handling | | Portfolio balances and coloured UTXOs | Universe implementation | Read views, not proof of settlement | | Direct `mint-ft` issuance from a Universe product | Not exposed | The protocol supports it. No Universe surface offers it | | Substantiation Factor material | Preliminary | See [Substantiation Factor](/protocol/arc20/substantiation-factor/) | The ARC-20 source reports `partial` coverage with an explicit reason: confirmed authoritative history and complete proven holder snapshots are indexed, but the shipped adapter has no exhaustive mempool feed with stable pending lifecycle and disappearance handling. That limitation applies to pending activity only. It does not weaken the confirmed scan or the holder proof requirements. ## Atomicals NFTs, Realms, and Subrealms | Capability | Status | Notes | | --- | --- | --- | | Plain NFT, Realm, and Subrealm read model | Universe implementation | One shared provider scan, generation, and checkpoint | | Realm resolution, hierarchy, and Subrealm listing | Universe implementation | Candidate and payment evidence retained per asset | | Transaction, block, and UTXO lookup | Universe implementation | Scoped to the active generation | | Media delivery with integrity checks | Universe implementation | MIME restrictions and size limits apply | | Fungible tokens in this projection | Excluded by design | Served by the ARC-20 side instead | | Containers and DMINT items in this projection | Excluded by design | Declared in the index provenance manifest | | Write operations | None | The projection is read only | ## Marketplace | Capability | Status | Notes | | --- | --- | --- | | Four isolated protocol authorities | Universe implementation | `arc20`, `atomicals_nft`, `realms`, `subrealms` | | Listing, reservation, purchase, offer, settlement | Universe implementation | Every action gate defaults to off | | Ownership proof | Universe implementation | BIP-322 simple proof for P2WPKH and key-path P2TR | | Mixed collateral, burns, spent outputs, checkpoint drift | Rejected | All four lanes fail closed | | Legacy `/buys` and `/orders/{orderId}/reconcile` aliases | Deprecated | Use `/reservations`, `/purchases`, `/settlements` | ## AVM | Layer | Status | | --- | --- | | Architectural whitepaper concepts | Proposed | | Official beta interpreter | Experimental or beta | | Universe runtime integration | Testnet4 only | | Universe runtime attestation | Readiness only | AVM Studio (`/avm-studio`), the `/avm/*` API, and the indexer `blockchain.atomicals.avm.*` RPCs are validated on Bitcoin Testnet4 only, from height 27000. Signet cannot carry AVM with the pinned indexer. Mainnet AVM writes are not enabled in production. Nothing about the AVM on this site should be read as production mainnet support. See [AVM status and limitations](/protocol/avm/status-and-limitations/). ## Limitations we know about 1. Pending ARC-20 activity is not exhaustively covered. Confirmed history is. 2. Containers and DMINT are documented as protocol behavior. No Universe read projection exposes them today. 3. Direct FT issuance is protocol behavior with no Universe product surface. 4. AVM is beta upstream and validated here on Bitcoin Testnet4 only. Mainnet AVM writes are not enabled in production, and the indexer readiness report is not a published conformance statement. 5. Some Atomicals ecosystem services listed in the [registry](/ecosystem/) could not be verified from a reachable source. Those rows say `unknown` rather than guessing. 6. Rate limiting is documented only where it is actually implemented. Where a service has none, the page says so instead of inventing a policy. ## How to report something wrong Open an issue in the [documentation repository](https://github.com/bitcoinuniverseio/atomicals-and-arc-20/issues). Use the **incorrect protocol claim** or **API mismatch** template and include the page ID from the source panel. --- # What are Atomicals? URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/start/what-are-atomicals/ Page ID: start/what-are-atomicals Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-guide Verified: 2026-08-31 Limitations: - The pinned reference revision is one implementation. Another validator version can interpret the same transaction differently. An **Atomical** is a digital object created by a Bitcoin transaction and carried by a Bitcoin output. There is no side chain, no separate token ledger, and no smart contract account. The object exists because a validator reads your transaction and applies the Atomicals rules to it. ## The three parts of an Atomical **Identity** is the Atomical ID, written `i`. It is assigned once and never changes. A number is also assigned in mint order, but the ID is the durable identity to store. **Location** is the UTXO that currently carries the object. Spending that UTXO moves the object, or destroys it, depending on how the outputs are arranged. **History** is the ordered set of operations applied to the object: the mint, any state updates, and every move. ## How an operation is written The envelope is not executed by Bitcoin. It is data inside a Taproot script path. Bitcoin does not know what `atom` means. An Atomicals validator does. A confirmed Bitcoin transaction only tells you the bytes are in a block. Whether the operation was valid, which output received the object, and whether anything burned are all answers a validator gives you. Always check both. ## The protocol family | Kind | What it is | Read | | --- | --- | --- | | Atomicals NFT | A single non-fungible object with metadata and media | [NFT overview](/protocol/nft/overview/) | | ARC-20 | Fungible tokens where one unit is one coloured satoshi | [ARC-20 overview](/protocol/arc20/overview/) | | Container | A named collection that items can prove membership in | [Containers](/protocol/containers/overview/) | | DMINT | Decentralised minting of Container items against a sealed manifest | [DMINT](/protocol/containers/dmint/) | | Realm | A top-level name owned as an Atomical | [Realms](/protocol/realms/overview/) | | Subrealm | A child name claimed under a Realm's rules | [Subrealms](/protocol/realms/subrealms/) | | Payname | A Realm used as a payment destination | [Paynames](/protocol/realms/paynames/) | | AVM | A sandboxed script interpreter, beta and separately scoped | [AVM](/protocol/avm/overview/) | ## What an Atomical is not - It is not proof of who made something. A ticker or a Realm name is an allocation, not an identity check. - It is not a contract account. There is no balance row to debit. - It is not safe to infer from metadata. Metadata is arbitrary data supplied by the minter. - It is not final because Bitcoin confirmed it. See [confirmation and reorgs](/protocol/core/confirmation-and-reorgs/). --- # What is ARC-20? URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/start/what-is-arc-20/ Page ID: start/what-is-arc-20 Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-guide Verified: 2026-08-31 Limitations: - Allocation behavior is version sensitive. The numbers on this page follow the pinned reference revision only. ARC-20 is the fungible token model inside Atomicals. Its rule is short: > **One ARC-20 unit is one satoshi in a Bitcoin output that a validator recognises as coloured.** That single sentence decides everything else. Supply is measured in satoshis. A transfer is a question about which outputs receive how much value. Value that cannot be placed is destroyed. ## Why this is not an account balance In an account model a transfer subtracts from one row and adds to another, and the transaction either succeeds or fails. In ARC-20 the transaction succeeds on Bitcoin either way. What changes is where the coloured value lands. | Question | Account model | ARC-20 | | --- | --- | --- | | Where is the balance? | A row in a ledger | Spread across your unspent outputs | | What is a transfer? | Debit and credit | Assigning input value to outputs in order | | Can value vanish? | No | Yes. Unplaceable value is burned | | Who decides the result? | The contract | The validator revision your indexer runs | | Does confirmation mean success? | Yes | No. Confirmation and allocation are separate answers | If the next eligible output is larger than the coloured value still to place, that value is not carried forward. It is burned. This is not an error state on Bitcoin: the transaction confirms normally. Read [burns](/protocol/arc20/burns/) before moving anything. ## The three ways units come into existence | Mode | Operation | Shape | | --- | --- | --- | | Direct issuance | `ft` | The entire supply lands in output zero of one transaction | | Fixed decentralised | `dft` then `dmt` | A deployment sets the rules, then claimants mint a fixed amount each | | Perpetual decentralised | `dft` with perpetual parameters | Activation gated, with progressing Bitwork and an optional global cap | See [direct issuance](/protocol/arc20/direct-issuance/), [fixed DFT](/protocol/arc20/fixed-dft/), and [perpetual DFT](/protocol/arc20/perpetual-dft/). ## What a ticker does and does not mean A ticker is a globally allocated name. Winning it means the Atomicals rules resolved a candidate into a verified winner. It does not mean: - the project is who it says it is; - the metadata is accurate; - the image belongs to the minter; - anyone stands behind the supply. Always store and display the resolved **Atomical ID** next to any ticker. See [tickers and candidates](/protocol/arc20/tickers-and-candidates/). ## Decimals do not create fractions `decimals` is presentation metadata. It changes how a wallet formats a number on screen. It never creates sub-satoshi units. Native ARC-20 quantities are integers, always. See [metadata and decimals](/protocol/arc20/metadata-and-decimals/). --- # Tools URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/tools/ Page ID: tools/index Applicability: editorial Authority: none Networks: mainnet Sources: none Verified: 2026-08-31 It runs in your browser. It never signs, never broadcasts, never asks for key material, and never sends what you paste to any service. Where a tool cannot determine something, it says unknown rather than guessing. ## Why they are local Anything you paste into a transaction tool is sensitive. An outpoint list reveals what you hold. A PSBT reveals what you are about to do. Sending either to a service to be analysed creates a record you did not need to create. So these tools parse in the page. There is no upload, no analytics on the content, and no request made on your behalf. ## What they are not They are explanatory. They are not the active validator, and they do not replace validating a concrete transaction against the validator revision your counterparties run. The allocation visualizer is the closest to authoritative, because it runs the same engine as the [conformance vectors](/reference/conformance/) and the test suite. Even so, it models normal allocation from one pinned revision, not the live network you are about to broadcast to. --- # ARC-20 allocation visualizer URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/tools/allocation-visualizer/ Page ID: tools/allocation-visualizer Applicability: protocol-behavior Authority: executed-source Networks: mainnet Sources: atomicals-electrumx-1.5.2.0 Activation: Custom coloring is activation gated. Normal allocation is not. Verified: 2026-08-31 Limitations: - Models normal allocation and the activation gated custom coloring path only. - Explanatory. Never a substitute for validating a concrete transaction against your target validator revision. - It never signs, broadcasts, or sends anything anywhere. ## How to use it 1. Start from a preset, or enter your own coloured inputs. 2. Enter the outputs in the exact order your transaction will have them, in satoshis. 3. Read the burn figure. It should be zero. 4. Add the fee inputs and the cardinal change output, then read it again. 5. Only build the transaction once the figure is still zero. Step four is where wallet-added change silently changes the result. The presets are the executed [conformance vectors](/reference/conformance/), and the computation is `conformance/allocation.mjs`, the same module `tests/conformance-allocation.test.mjs` calls. The tool and the tests cannot disagree. ## What it models | Modelled | Not modelled | | --- | --- | | Normal allocation, exactly as the pinned builder performs it | Live chain state | | The output zero fallback when a plan is not clean | Whether an output is actually coloured today | | Unspendable outputs, skipped without consuming value | Whether your wallet will reorder outputs | | Activation gated custom coloring | Whether custom coloring is active on your network | | The no-inflation rule | Anything on the non-fungible branch | ## Copy as a vector The copy control produces a JSON object in the same shape as the committed vector set. If you find a case this documentation should cover, that object is what to attach to an issue. See [conformance vectors](/contribute/conformance-vectors/). --- # API Conformance Workbench URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/tools/api-conformance/ Page ID: tools/api-conformance Applicability: universe-implementation Authority: universe-implementation Networks: mainnet, regtest Sources: universe-index-atomicals Verified: 2026-09-02 Limitations: - The bench sends only read-only GET operations from the canonical contract, one explicit press at a time. - A network failure is reported as unreachable. It is never described as deprecation or closure. - The hosted site never operates as a proxy. For CORS-blocked endpoints, run the repository's local proxy. The workbench refuses every method except GET and HEAD, and only operations the contract marks read-only. Endpoint URLs and headers live in memory: never in a URL, never in local storage, never in a service-worker cache, and redacted from every exported report. ## What is checked Status against the contract, media type, JSON parsing, schema validation through build-time standalone validators, error shape, pagination behaviour, and contract-required headers. Each check reports individually. The verdict distinguishes compatible, compatible-with-warnings, schema divergence, wrong network, stale, unreachable, and unknown, and never infers identity fields from unrelated responses. ## Local proxy for CORS-blocked endpoints Run `npm run lab:proxy`. The proxy binds `127.0.0.1`, requires an explicit target allowlist, refuses wildcards, blocks private, loopback, link-local, and metadata destinations (except the local Regtest Lab), re-resolves destinations per request against DNS rebinding, enforces method, timeout, rate, and size limits, strips hop-by-hop headers, persists nothing, and redacts its logs. The hosted documentation site never operates as a proxy. ## Relation to the offline explorer The [offline API explorer](/tools/api-explorer/) remains the default reading surface. The live bench is an addition for validating an implementation, not a replacement. --- # API explorer URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/tools/api-explorer/ Page ID: tools/api-explorer Applicability: universe-implementation Authority: universe-implementation Networks: mainnet Sources: universe-index-atomicals-nfts-and-realms, universe-index-atomicals Verified: 2026-08-31 Limitations: - The explorer never sends a request. It renders the contract and produces a command you run yourself. - No credential is embedded, offered, or stored. An explorer that sends requests needs a credential in the page and an origin to point at. Both are mistakes: the credential ends up in browser history and logs, and the origin becomes a default someone points production traffic at. So this explorer renders the contract and hands you a command. You choose the origin and supply the credential in your own environment. ## Reading a mutation Mutations are marked. Before building one, read: - [Authentication](/develop/authentication/) for the signature material and headers. - [Idempotency and request IDs](/develop/idempotency-and-request-ids/) for safe retries. - [Marketplace v1](/reference/api/marketplace-v1/) for the exact protocol data shapes. The copied command carries placeholders for the idempotency key and the body, because the signature covers the exact body bytes. Re-serialising the body invalidates it. ## Downloads The full documents are on [OpenAPI and downloads](/reference/openapi/). --- # AVM Workbench URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/tools/avm-workbench/ Page ID: tools/avm-workbench Applicability: experimental Authority: executed-source Networks: none Sources: atomicals-avm-interpreter Verified: 2026-09-02 Limitations: - AVM is beta and experimental. Nothing here is evidence of deployment by anyone. - Results describe the pinned interpreter revision only; resource behavior can differ across hosts. - The workbench executes only the release-pipeline WASM build. It never reimplements interpreter semantics in JavaScript. The banner in the workbench is permanent for a reason: the AVM interpreter at the pinned revision is beta. Running a sample locally proves what that revision does, nothing more. ## Resource limits Every run is bounded: 64 MiB memory, a five second wall-clock budget with worker termination, a 256 KB program cap, a 1 MB output cap, and a ten million instruction budget metered by the interpreter build itself. Exceeding any limit terminates the run and says so; the host never truncates silently. ## Native and WASM parity The same pinned source builds twice through deterministic container toolchains: a native binary for the Regtest Lab and CI, and the WASM module for this workbench. The CI gate executes the golden fixtures on both and requires byte-identical outcomes before either ships. ## Runtime package The host interface lives in `packages/avm-runtime`: pinned source acquisition with checksum verification, the narrow host interface, resource limits, and refusal semantics. There is no JavaScript reimplementation of AVM semantics anywhere in this repository. --- # Bitwork estimator URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/tools/bitwork-estimator/ Page ID: tools/bitwork-estimator Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet Sources: atomicals-electrumx-1.5.2.0, atomicals-guide Verified: 2026-08-31 Limitations: - Probabilistic. Attempts are independent, so a run can finish far under or far over the expectation. - No amount of work guarantees a result in any particular time. - Nothing here estimates cost, revenue, or profitability. ## How the numbers are derived Each hexadecimal character of prefix fixes four bits of the transaction id, so the expected number of attempts is two to the power of the fixed bits. A partial next character fixes whole bits between two character levels. The probability of having finished after a given number of attempts assumes independent attempts, each succeeding with probability two to the negative power of the fixed bits. There is a real chance of finishing in a fraction of the expected time, and a real chance of taking several times longer. Plan for the range, not the average. ## What this does not tell you - Your actual attempt rate. Measure it; the tool takes your figure. - Electricity, hardware, or opportunity cost. - Whether the mint will still have quota left when you finish. - Whether a perpetual deployment's requirement will have progressed by then. ## For deployers Setting a mint Bitwork requirement raises the cost of automated claiming, and it raises the cost for every ordinary participant equally. Model the level you are considering before publishing it, because it cannot be changed afterwards for a fixed deployment. See [ARC-20 Bitwork requirements](/protocol/arc20/bitwork-requirements/). --- # CLI command builder URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/tools/cli-builder/ Page ID: tools/cli-builder Applicability: protocol-behavior Authority: reference-implementation Networks: mainnet, testnet, regtest Sources: atomicals-js-cli Verified: 2026-08-31 Limitations: - The builder offers only the arguments and options the pinned source declares. A flag absent here is not accepted by that revision. - It builds a string. It never runs anything. ## Why the combinations are constrained The builder is generated from the same inventory as the [CLI reference](/reference/cli/). It cannot offer a flag the pinned revision does not declare, which removes a whole category of mistake: building a command against a flag you read somewhere that the revision you run does not have. The builder produces a string. Running it is your decision, and a build command spends outputs. Model the allocation first with the [allocation visualizer](/tools/allocation-visualizer/). ## The flags marked with a star Options that change what is spent or where a result lands are marked. Check each one twice: | Flag | What it changes | | --- | --- | | `--funding` | Which wallet pays. Keep it cardinal | | `--owner` | Whose outputs are spent. This is where an asset moves from | | `--initialowner` | Where a newly minted object lands | | `--satsoutput` | The satoshi value of the output carrying the result | | `--satsbyte` | The fee rate. Recompute after any grind | | `--rbf` | Signals replaceability. A replacement is a different transaction with a different allocation | ## Before you run anything 1. Confirm you are on the network you think you are. 2. Confirm the funding input is cardinal. 3. Confirm the output value is above the relay dust threshold. 4. For a mint, confirm the deployment reads back the way you expect. 5. For a transfer, model the allocation and confirm the burn figure is zero. --- # Protocol comparison has moved URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/tools/protocol-comparison/ Page ID: tools/protocol-comparison Applicability: editorial Authority: none Networks: mainnet Sources: none Verified: 2026-09-02 --- # Protocol Lab URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/tools/protocol-lab/ Page ID: tools/protocol-lab Applicability: protocol-behavior Authority: executed-source Networks: regtest, testnet, signet, mainnet Sources: atomicals-electrumx-1.5.2.0 Verified: 2026-09-02 Limitations: - Scenarios are deterministic models. Identifiers are synthetic and derived from the scenario seed; they are not real Bitcoin hashes. - The lab models normal ARC-20 allocation, commit and reveal, confirmations, and reorganizations. It does not simulate semantics the pinned reference does not support. - Nothing here substitutes for validating a concrete transaction against the validator revision you target. The lab replays protocol rules deterministically so you can see why units land where they land. It never asks for keys, never signs, and never broadcasts. Every identifier it generates is synthetic, derived from the scenario seed, and starts with "sim". Pick a guided scenario, watch each step apply the shared rules, and click a rule to open the exact page that explains it. The same allocation module executes the conformance vectors, powers the [allocation visualizer](/tools/allocation-visualizer/), so the lab cannot disagree with them. ## What the scenarios cover - Commit and reveal for NFTs, Realms, and ARC-20 deployments and mints. - ARC-20 transfer, split, and merge through the reference allocation engine. - Intentional burns to unspendable outputs, and the accidental burn pattern that destroys units. - Confirmation progression and a one-block reorganization that unsettles confirmed state. - An invalid operation the engine refuses instead of inventing money. ## Share and export Every scenario is data. Copy a shareable link for a small scenario, or export the scenario JSON and the execution trace as files. Large scenarios stay local by design: nothing is ever uploaded anywhere. ## Where the rules come from The engine lives in `packages/protocol-lab` and calls the allocation engine in `packages/protocol-core`, which is the exact module the conformance vectors execute at the pinned reference revision. Each trace entry names the rule it evaluated and the outcome. --- # Transaction safety inspector URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/tools/transaction-inspector/ Page ID: tools/transaction-inspector Applicability: protocol-behavior Authority: executed-source Networks: mainnet Sources: atomicals-electrumx-1.5.2.0 Verified: 2026-08-31 Limitations: - Parses locally and queries nothing. It cannot know which inputs are coloured unless you supply that. - Explanatory. It is not the active validator and never a substitute for one. - It never signs, broadcasts, or asks for key material. This tool takes a transaction or a PSBT. It never needs a private key, a seed phrase, or a wallet export file, and neither does anything else on this site. Nothing you paste leaves your browser. ## What it tells you | Reads | From | | --- | --- | | Version, and whether the transaction is segwit | The serialisation | | Every input outpoint and sequence | The serialisation | | Every output value, in order | The serialisation | | The script kind per output | Script shape recognition | | Declared signature hash types | The PSBT input maps | | Expected allocation and burns | The allocation engine, if you supply the coloured inputs | ## What it cannot tell you - Whether an input is actually coloured. It queries nothing, so you must supply that. - Whether the counterparty's validator agrees. - Whether the transaction will be accepted by a mempool. - Whether an unrecognised script is safe. Unrecognised means unknown, not fine. It fails closed: anything it cannot determine is reported as unknown rather than assumed. ## The checks to run with it 1. Confirm every input outpoint is one you meant to spend. 2. Confirm every output script and value matches your intent. 3. Confirm the output order matches what you modelled. 4. Confirm the signature hash type is the one you expected. 5. Supply the coloured inputs and confirm the burn figure is zero. See [verify a transaction](/guides/verify-a-transaction/) for the full procedure, including what to do after broadcast. --- # UTXO Safety Planner URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/tools/utxo-safety/ Page ID: tools/utxo-safety Applicability: protocol-behavior Authority: executed-source Networks: mainnet, testnet, signet, regtest Sources: atomicals-electrumx-1.5.2.0 Verified: 2026-09-02 Limitations: - Classification is only as good as the assignment data you import. Without indexer data the planner says unknown and never claims safety. - Plans are unsigned intents. The planner never signs, never broadcasts, and never performs an address lookup without an explicit action at a chosen endpoint. Most permanent ARC-20 losses happen when an ordinary wallet sweeps coloured satoshis into fees or change. This planner exists so you can see exactly which outputs carry assets, which moves burn them, and which candidate plans preserve them, before anything is ever signed. ## What the planner checks Every candidate plan is examined for the classic loss patterns: accidental asset burns, mixed token inputs, unknown assignment state, insufficient asset change, unsafe output ordering, dust, fees that cannot cover the virtual size, unconfirmed input chains, and reused change addresses. Each warning links to the rule page and the pinned source revision behind it. Unknown stays unknown: an output with no assignment data is classified as unknown with no confidence, and the planner refuses to call it safe. ## Comparing plans Plans are compared on asset safety, fee, input count, and privacy impact side by side. There is no single score, because collapsing those axes into a number hides exactly the trade-offs you need to see. ## Exports Export the plan as JSON, as a Protocol Lab scenario to replay its effects, or as a CLI command sequence to run against your own setup. When fields for a structurally valid unsigned PSBT are missing, the planner exports an explicit transaction intent and names what is missing instead of fabricating values. --- # Workflows URL: https://bitcoinuniverseio.github.io/atomicals-and-arc-20/workflows/ Page ID: workflows Applicability: universe-implementation Authority: universe-implementation Networks: mainnet, regtest Sources: universe-index-atomicals, atomicals-electrumx-1.5.2.0 Verified: 2026-09-02 Limitations: - Every workflow here is read-only or explicitly local. No hosted mainnet signing or broadcast workflow exists. - Steps that execute against the Regtest Lab require the lab to be running locally. The workflow layer is a single Arazzo 1.1.0 document under `contracts/workflows/`, validated against the specification schema in CI with every referenced OpenAPI operation ID resolved. The page below, the curl examples, the TypeScript and JavaScript snippets, the MCP tool metadata, and the conformance tests all generate from that one document. The machine-readable sources are the [Arazzo document](../../contracts/workflows/atomicals-read-only.arazzo.yaml) and the [generated summary](../../site/src/generated/workflows.json). ## Running the local workflows The Regtest Lab workflows need the lab running: ``` npm run lab:up npm run lab:seed npm run lab:test ``` Everything else runs against any endpoint you choose in the [Conformance Workbench](/tools/api-conformance/), which never sends a mutation.