# Immutables.art documentation Source review: 2026-09-10 # Art to collect, create and preserve Source: https://immutables.art/docs/ Immutables.art brings together an artist's program, an edition's identity on Ethereum and a viewer that runs the work. Start with the guide that fits what you want to do. - [Collectors](/docs/collectors): Understand editions, find a work and make it part of your collection. - [Artists & Coders](/docs/artists): Build, test and publish generative artwork with the project wizard. - [Galleries & Museums](/docs/galleries-museums): Acquire, exhibit and care for works that run as software. ## Find an answer - **How do I mint or check an edition?** Read [minting and ownership](/docs/collecting). - **How do I use the artwork on my phone?** Read [viewing your collection](/docs/viewing). - **How do I make and test a project?** Start in [Artists & Coders](/docs/artists). - **How do we display a particular work?** Follow [exhibition setup](/docs/exhibiting). - **What should an archive contain?** Use [conservation and archives](/docs/preservation). - **Where do code, images and metadata live?** Read [storage and metadata](/docs/storage). ## Three things to keep distinct **The code page NFT** identifies an owned page on Immutables Code, currently branded Immutables.co. Code posts belong to that page's history; an individual post is not automatically a separate NFT. **The art project** references one code-post transaction. It has its own settings, artist address and royalty manager. **An edition NFT** belongs to the art project. Its mint transaction and edition number are inputs the viewer can use to recreate the artwork. The [Technical Reference](/docs/technical-reference) connects these concepts. Read [contracts and identity](/docs/contracts) when comparing project numbers, edition numbers, global token IDs or transaction hashes. ## Bring an assistant The copy button provides instructions suited to the section you are reading. The [LLM index](/llms.txt) organizes the same guides for assistants, and the [complete reference](/llms-full.txt) includes every chapter. Artists also have a detailed [authoring brief](/docs/llm-guide). ## Scope Contract behavior is checked against the deployed platform sources. Settings such as fees, active projects and royalty rates can change; read the current values before signing. The [current/proposed feature guide](/docs/future) identifies work that is not part of the deployed artist workflow. # Section: Collectors Assistant brief: https://immutables.art/docs/collectors-brief.txt Help me understand or care for an Immutables.art edition using https://immutables.art/docs/collectors and https://immutables.art/docs/technical-reference. Identify the project and edition, global token ID, chain and contract before making specific claims. Distinguish the code-post transaction from the edition's mint transaction. Check current ownership from current chain data when needed; do not treat a cached viewer as live ownership evidence. Explain the work and its artist positively and accurately. Distinguish traits from the complete visual experience, and a captured image or GIF from the running artwork. EoD previews show an excerpt of continuous evolution. Strongly recommend live rendering for viewing and exhibitions. Treat compressed images and clips as previews or fallbacks. A museum can render an edition while its NFT remains in the owner's wallet; no token transfer, loan or museum custody is required to render it. Presentation and attribution terms should be agreed with the artist. Use the project's actual mint eligibility and controls, not invented universal behavior. Keep the original mint identity separate from transfers. Do not imply an art edition grants project administration or owns the artist's code page. For downloads, follow /docs/preservation and /docs/storage, including matching build hashes and testing dependencies. Do not call untested playback fully offline. Do not connect a wallet, send transactions or make purchases without an explicit instruction. Explain observations and unresolved details clearly. # Collect the work, understand the edition Source: https://immutables.art/docs/collectors An edition is more than its marketplace thumbnail. Its program runs in your browser, using the edition's inputs to create an image, an animation or an interactive experience. ## Start with the work **Prefer live rendering when viewing or exhibiting the work.** Open a project in the [art viewer](/), choose an edition and let its program run. Read the artist's description and try the available controls. Live rendering preserves the work's movement, interaction and detail as its program produces them on your display. Compressed images and GIFs are useful for browsing and sharing previews, or as a fallback when a device cannot run the work. For example, EoD is intended to evolve continuously. A looping preview repeats the captured clip, not the full progression of the running work. Other projects have their own relationships to time and interaction. ## A collector's route 1. [Understand minting and ownership](/docs/collecting): project eligibility, edition identity and checking a transfer. 2. [View and interact with your collection](/docs/viewing): live artwork, mobile controls and saved outputs. 3. [Keep a copy](/docs/preservation): preserve source, edition inputs and a tested viewer alongside your collection records. ## What identifies an edition? Keep its chain, contract address and global token ID. The project ID and edition number make it recognizable within Immutables.art; the global token ID identifies it within the art contract. These numbers are not interchangeable. Transferring an edition changes ownership, while its original mint transaction remains part of its history. See [contracts and identity](/docs/contracts) for the distinction between the artist's code-page NFT and the edition you collect. ## Read beyond the thumbnail Traits describe choices in the program, rather than the full visual experience. Consider composition, movement and the artist's intent alongside trait data. The [seed guide](/docs/randomness) explains reproducible variation and why a transaction hash alone does not guarantee unpredictable mint outcomes. For an exhibition, share the edition URL and [institution guide](/docs/galleries-museums). The NFT can remain in your wallet while a museum or gallery renders it: display requires no token transfer or custody. Keep credit, source license and agreed presentation terms with the work's records. --- # Minting and ownership Source: https://immutables.art/docs/collecting Begin on the artwork's project page. Viewing is available without connecting a wallet; minting or transferring ownership requires an on-chain transaction. ## Before a mint Read the description, artist credit and current mint information. Some projects have eligibility conditions or a particular mint route. Follow that project's instructions rather than assuming every project is minted in the same way. For a standard public mint, the deployed art contract checks active and paused states, available supply and configured price. Artists and team members have different permissions. [Project management](/docs/project-admin) explains those rules; [current and proposed features](/docs/future) identifies prospective extensions. Confirm the wallet's network and contract. The [contracts reference](/docs/contracts) links to the deployed art and code contracts. Mint price and transaction fee are separate amounts; use the wallet's current transaction details when reviewing a mint. ## After a mint Wait for the transaction result and inspect its receipt. A slow page or missing thumbnail is not proof that minting failed. Check the transaction before submitting another mint. Record Ethereum mainnet, the art contract address, global token ID, project ID, edition number, mint transaction hash and edition URL. Keep the artist's credit and project description as documented at acquisition. The viewer uses `/#//`. Marketplace token URLs and the contract's `ownerOf` call use the global token ID. Preserve both identifiers so another person can find the same work. ## Ownership and transfers Read `ownerOf(globalTokenId)` on the art contract to verify the current owner. Transfer events provide movement history; a cached page or downloaded viewer can show an earlier owner. A transfer does not create a new mint transaction. The recipient receives the existing edition with its original identity. Source access, the code-page NFT and the artist's stated license remain separate parts of the record. Collecting an edition does not grant project administration controls. After receiving an edition, check the confirmed transaction and current owner, then reopen the work in the [viewer](/docs/viewing). Keep an [archive copy](/docs/preservation) of the materials needed to recreate it. --- # Spend time with the artwork Source: https://immutables.art/docs/viewing **Live rendering is the recommended way to experience the artwork.** It runs the actual program, including its detail, movement, response to time and available interactions. Use compressed images and animated clips for quick previews or as a fallback when live rendering is impractical. ## Open the edition Select a project and edition, or use its `/#//` link. Choose **live render** for viewing and display. The viewer also offers **still image** where the project has a hosted asset; this is a captured output of the work. Viewing does not require a wallet. A museum can render an edition while its owner keeps the NFT in their own wallet. The viewer's status identifies cached or chain data. An archive's ownership and edition list reflect its snapshot. ## Find the controls Open **Artwork controls** from the bottom bar or use the small lower-right handle. On a touch device, available controls initially open, then collapse after idle time. Typing and active interactions keep the panel available. Controls depend on the artwork. A project without supported actions does not receive an invented panel. For PILLARS, **Consult (C)** and **Chronicle (T)** provide the corresponding interactions; letters also indicate keyboard shortcuts. Other works expose actions supported by their own code. ## Save an output Where the artwork exposes exports, open **Save** and choose an available format. An image or clip is a rendering of the work; exporting it does not transfer the edition NFT. For a longer-lived copy, download the [art bundle](/immutablesArt.html) or [whole interface](/immutablesArtApp.html) and check the [verification page](/verify). These packages contain a build snapshot, without future mints or transfers automatically added. ## Let time be part of the work Some pieces evolve while running; others consult the clock or change on a schedule. Reloading may restart a progression or recompute a time-dependent state. Follow the artist's description and record playback conditions when comparing captures. Keep an edition selected to display that particular work. **start museum mode** immediately starts the current project’s familiar cycle: a random live edition, a return to its grid, then another random edition. Controls fade when idle. The separate **⚙ Museum settings** button optionally customizes projects, edition subsets, collection wallets, timing and presentation, or opens projection mapping. See [exhibition setup](/docs/exhibiting). --- # Section: Artists & Coders Assistant brief: https://immutables.art/docs/llm-brief.txt Build a NEW Immutables.art artwork using the current artist handbook at https://immutables.art/docs/ and https://immutables.art/llms-full.txt. Ask me for the artistic direction, renderer, intended interactions and whether time changes the work when those choices are missing. Preserve my aesthetic intent and artist credit. Do not silently repurpose an existing release. Deliver the complete posted JavaScript function body, a separate project CSS stylesheet, an information post, and a short testing report. Include all helper functions in the script. No HTML wrapper, ES module imports or top-level export. Do not perform wallet transactions or publish without my explicit instruction. Runtime: - p5js receives p; threejs receives t and THREE; vanillajs receives v; glsl receives g and must create WebGL with JavaScript. - Implement context.myCustomRedrawAccordingToNewPropsHandler(props). - Props: transactionHash (mint transaction), projectId, editionId, tokenId, square; non-p5 renderers also get container. IDs can be decimal strings. - No generic blockHash, timestamp, prevrandao, VRF result or seed prop exists. - Keep state local per instance. Guard missing inputs. Handle setup, resize and cleanup. Distinguish trait identity from layout and animation progression. Seeds: - Include the full helper from /docs/examples/edition-seed.js for the current deterministic convention, or explain and validate an intentional alternative. - Mix the full mint transaction hash, full project ID and full edition ID with a fixed domain/version. Do not use editionId modulo a small number as the only edition input. Preserve the original transactionHash for metadata. - Use local seeded streams. No Math.random or fresh browser entropy for fixed edition traits. Separate named streams can isolate palette, geometry and noise. - Seed mixing improves differentiation and adds mint-order dependence. It does not prevent seed shopping or bots. Do not claim new entropy from extra hashing. - Stronger allocation requires an actual reviewed contract/reveal integration; do not invent one in the art script or describe prospective features as live. Controls: - Declare context.immutablesControls with version 1 and supported actions. - Use descriptive labels; toggle state comes from getState().values[id]. - Text/navigation require onAction; use busy and optional activeControl. - Non-p5 buttons/toggles use callbacks without key, with native keys implemented separately. Exports require an explicit action. Do not auto-download on load. - Style existing .btn, .form-control, .font-display and .modal-content classes, plus the documented .artwork-controls selectors inside #root. - Preserve idle behavior, focus, reduced motion and 44px touch targets. Metadata: - Log console.log('metadata: ', { transactionHash: props.transactionHash, ...traits }). - Use stable flat string/number traits. Never substitute the derived seed for the real transaction hash. Document the current hash-grouping limitation for multiple editions minted in one transaction. Acceptance checks: - Same hash and IDs reproduce traits and initial composition. - Same hash with edition IDs 1, 2, 9, 51 and 257 changes the seed. - Last bytes of the hash affect seed output; normalize IDs consistently. - Resize, reload and grid/detail mode preserve identity. - Test native text, keys, toggles, idle handle, exports and CSS in Preview in UI. - Validate JavaScript and actual rendering; report what was not tested. - Run the wizard's Hash & mint checks on the final draft; review the copied report against its source SHA-256. Resolve defects and explain intentional time-dependent or repeating traits. Never turn an inconclusive test into a pass just to clear the report, or claim the suite certifies bot resistance. - Preserve attribution and license. Save exact source and renderer dependencies. - Use Statistics across rolls to inspect trait frequencies and numerical distributions. Report sample mode, count and exclusions. Do not assume equal artistic weights, infer missing outcomes are impossible, treat repeated trait profiles as identical art, or present synthetic roll statistics as mint odds. Contract facts: - Code posts are calldata plus emitted logs on an owned/public code page. Reserving a page creates its NFT; every post is not a new NFT. - The art project references a code-post transaction. Mint events identify editions; the viewer recovers the mint transaction hash from those events. - Projects start inactive and paused. Team controls active; artist/team controls pause. Privileged mints still need the configured price and available supply. - A project lock freezes only fields protected by onlyUnlocked; the contract owner can unlock. Do not call it irrevocable or a freeze of every setting. - Each project's manager receives mint ETH and distributes it on release. Anyone may trigger release to configured recipients. ERC-2981 signals royalties but does not enforce every marketplace's payment. - Metadata mode is a platform-owner setting. Contract-generated JSON may still reference hosted images. Historical-data access and external dependencies must be preserved separately. # Make art that can be recreated Source: https://immutables.art/docs/artists Write a program. Give each edition its own starting conditions. Let anyone recreate the work in their browser. This artist guide covers the current Immutables.art viewer and deployed Ethereum platform. You can start in the [project wizard](/project-wizard.html) without a wallet, then connect when you are ready to publish. ## A first route through the platform 1. **Prepare your artwork.** Learn the [script inputs and lifecycle](/docs/script-api), or open a [working starter](/docs/examples). 2. **Give editions their identity.** Read [seeds and fair minting](/docs/randomness) before choosing how variation works. 3. **Make it usable.** Add [touch controls](/docs/controls) and [project styling](/docs/project-style). 4. **Preview and publish.** Follow the [wizard walkthrough](/docs/getting-started), including the checks before any paid transaction. 5. **Look after the release.** Understand [project permissions](/docs/project-admin), [royalties](/docs/royalties), and [preservation](/docs/storage). ## Three things to keep distinct **The code page NFT** identifies an owned page on Immutables Code, currently branded Immutables.co. Code posts belong to that page's history; an individual post is not automatically a separate NFT. **The art project** references one code-post transaction. It has its own settings, artist address and royalty manager. **An edition NFT** belongs to the art project. Its mint transaction and edition number are inputs the viewer can use to recreate the artwork. ## Bring your coding assistant Use the [LLM instructions](/docs/llm-guide) for a concise authoring brief. The [machine-readable index](/llms.txt) links to every Markdown chapter, and the [complete text](/llms-full.txt) provides the entire handbook in one file. ## Scope Contract behavior is checked against the deployed platform sources. Settings such as fees, active projects and royalty rates can change; read the current values before signing. The [current/proposed feature guide](/docs/future) identifies work that is not part of the deployed artist workflow. --- # From sketch to project Source: https://immutables.art/docs/getting-started Use the [project wizard](/project-wizard.html) to develop locally in your browser. Previewing a sketch does not create a project on Ethereum. ## Prepare the project Choose a project name, artist credit, description, initial mint price and maximum editions. Choose a code license that matches your intentions and any material you are building on. Publicly readable source does not by itself grant permission to reuse it. The wizard supports `p5js`, `threejs`, `vanillajs` and `glsl`. Start with p5.js if it already fits your practice; use the renderer your work needs. The [script reference](/docs/script-api) explains the supplied context for each. Keep the artwork self-contained where practical. A texture fetched from a server, an unpinned library, or a changing API response becomes another dependency someone must preserve to recreate the work. ## Work through the five steps 1. **Project Details:** enter the identity, edition limit, price, renderer and license. Save or export your draft before major edits. 2. **Art Script:** load a starter or paste a complete script body. Built-in examples use the [edition seed convention](/docs/randomness); their adapted seeds are intended for new projects. The Project seed ID and Edition seed ID fields let you keep the preview hash while varying its identity. Test multiple mint hashes and edition numbers, including repeated hashes with different edition IDs. 3. **Info Post:** explain the work, its controls, intentional time dependence, attribution and license. This becomes a page post tagged `info.immutables.art`. 4. **CSS Style:** preview the interface around the art. The wizard posts the style under `style.immutables.art`. Test phone widths and readable controls. 5. **Review & Deploy:** check the exact script, page, account, network and current fees. Gas estimates are estimates. Large source posts must still fit the network's transaction limits; extra gas is not unlimited storage capacity. **Preview in UI** opens your draft inside the full viewer. Its mint button creates local preview editions. These have synthetic hashes and are not blockchain tokens. Project ID and edition context in previews may differ from the eventual live project, so preview outputs are studies rather than promises of particular editions. ## What publishing sends The workflow can reserve an unclaimed code page, post optional information and CSS, post your script, and create the art project referencing the successful script-post transaction. These are separate transactions; each can complete independently. The wizard wraps the script in a fenced `javascript` block and posts it with the `code` tag. Paste JavaScript into the editor, not an entire HTML document or an already fenced Markdown block. Reserving a page mints the **page NFT** to the reserving account. A public-page post is not equivalent to reserving an owned page. If using an existing page, verify that the publishing account has the required posting rights. For a partial deployment, inspect the recorded transaction receipts before retrying. The resume field accepts an existing script transaction hash. Reuse it only when its decoded content is the exact script you intend to publish. ## After creation A newly created project begins **inactive and paused**. A team member controls activation; the artist or team can control pause. Artist/team mints still require the configured price even when they bypass those publication restrictions. See [project management](/docs/project-admin). Before announcing a release, test an actual edition's rendering and metadata, configure marketplace images if needed, confirm recipients, and decide when to lock the project. A lock is not a declaration that every setting can never change. Source basis: `project-wizard.html` publishing functions, `WizardProvider`, and `anyoneCreateProject` / `anyoneMintProjectEdition` in the [art contract](https://etherscan.io/address/0xA8A6CB3978e2c4EdcF5A3d0cB3400E1E5D031479#code). --- # Seeds and fair minting Source: https://immutables.art/docs/randomness An edition needs a repeatable identity. A mint also needs a fair allocation policy. A deterministic seed helps with the first; it does not, by itself, guarantee the second. ## What the current platform gives you The deployed contract increments the project's edition counter and emits the project, edition and token IDs when an edition is minted. The viewer obtains that event's transaction hash and passes it to the script. The contract does not generate a VRF seed or store a delayed random reveal. A signed Ethereum transaction has a hash **before** it is included in a block. A determined minter can evaluate candidate transactions and their resulting art before submitting a preferred one. This follows from the transaction lifecycle described in [Ethereum's transaction documentation](https://ethereum.org/en/developers/docs/transactions/). ## The default for a new artwork Mix the **full mint hash, full edition ID and project ID**, with a fixed version/domain, before deriving your drawing stream. Include all 64 hex digits of the transaction hash, not just its first few bytes. Normalize decimal IDs and keep the original mint hash separately for provenance. The [standalone helper](/docs/examples/edition-seed.js) implements this deterministic convention. It is synchronous, self-contained and compatible with the wizard examples. It uses non-cryptographic mixing for art variation; neither its 32-byte-shaped output nor its name implies cryptographic security. p5's random stream is initialized with a 32-bit value. ```javascript // Include the complete helper in your posted script first. const seed = immutablesSeed(props); p.randomSeed(parseInt(seed.slice(2, 10), 16)); p.noiseSeed(parseInt(immutablesSeed(props, 'noise').slice(2, 10), 16)); // Metadata still uses props.transactionHash, never seed. ``` Use separate named streams such as `composition`, `palette` and `noise` when adding a new random choice should not rearrange unrelated parts of the work. Keep their names and the seed version fixed after release. The wizard's adapted built-in studies apply this full-ID convention. Loading a new example changes the editor after confirmation; it does not rewrite saved drafts or existing on-chain artwork. ## What edition mixing improves Different editions from the same transaction can produce different art. The final result also depends on the edition number assigned in mint order, so a hash-only shopping strategy cannot ignore ordering. Using the full ID avoids deliberately repeating an eight- or fifty-edition seed-selection cycle. **That is a limited mitigation.** The next edition number may be predictable when minting is quiet. A bot can search against likely IDs; transaction ordering, private inclusion and builder influence can preserve an advantage. Hashing repeatedly, choosing a different substring, discarding random draws, obfuscating the script, or using a longer-looking seed does not create an unpredictable input. ## When stronger allocation is required A stronger design commits the purchase or allocation before its decisive entropy is available, then binds one later random result to it under rules the minter cannot selectively retry. Candidate mechanisms include a reviewed VRF integration or a carefully designed future-randomness/reveal protocol. That design needs more than an artist-script edit: exact commitment and fulfillment rules, immutable association with each edition, no favorable rerolls, handling for failed reveals or unavailable entropy, a finality policy, preserved historical data, and viewer support. A commit/reveal scheme also needs to address participants withholding an unfavorable reveal. Using the current timestamp, a recent block hash, or current `prevrandao` as a magic replacement is insufficient. Block producers can influence timing and randomness selection; [EIP-4399 describes predictability and bias considerations](https://eips.ethereum.org/EIPS/eip-4399#security-considerations). The generic viewer does not currently pass those values to scripts. ## Bot participation is a different problem A fair seed does not stop a bot buying many editions. Allowlists, allocation limits and gated eligibility may reduce unwanted participation when enforced by the actual mint path. A browser-only check is bypassable, and a per-address limit is not a per-person limit. The deployed open mint method has no general wallet-limit, allowlist, commit/reveal or VRF parameter. Do not advertise those protections unless a verified contract integration actually enforces them. Coordinate a different launch mechanism before publishing a project that depends on one; see [current and proposed features](/docs/future). ## Test before you publish The wizard's **Hash & mint checks** run automatically after you pause editing the script. **Run checks now** repeats them on demand; **Stop** cancels the current run. Results also appear as a status in Review & Deploy. **Copy report** includes the exact source's SHA-256, test inputs and findings so you can share it with a collaborator or LLM without including the unpublished source. The suite uses 13 fresh isolated previews: a repeat of the baseline, edition IDs 2, 9, 51 and 257 against edition 1, changes at five byte positions across the hash, a different project ID, and a one-day clock shift. The global token ID stays fixed during the edition comparisons, so a token-ID dependency cannot masquerade as edition mixing. It compares observed p5 seed calls, logged traits and sampled canvas pixels. Provenance fields are excluded from the variation comparison, and the original transaction hash is checked separately in metadata. Source checks point to calls such as `Math.random()`, fresh browser entropy, clock reads and short edition-modulo expressions. These are review prompts: a time-dependent animation or an intentionally repeating trait may be exactly what you want. Merely pasting the recommended helper into a script does not make an unused seed pass. Visual repeatability is reported separately from seed calls and traits. If baseline pixels differ, the suite excludes pixels from the edition and hash comparisons so renderer variation cannot create a false pass. You will still see the visual review finding. **Interpret the evidence, not just the label.** Changed seed calls do not prove that every trait uses that seed. Matching coarse traits do not prove two whole editions are identical. The suite samples an early animation moment at a fixed 360px size with a controlled clock; it does not exhaustively test animation, every hash bit, resizing, GPU behavior or external dependencies. Network requests are blocked in the isolated test frames. Missing output, failed initialization and unsupported dependencies remain inconclusive rather than receiving a pass. An edit invalidates the old report. The allocation review remains even when the sampled checks pass: these are synthetic hashes, not signed mint transactions or an estimate of a bot's search cost. No browser-only artwork test can establish fair transaction ordering or enforce mint limits. - Same mint hash and same IDs: identical traits and initial composition. - Same hash, edition IDs 1, 2, 9, 51 and 257: distinct seed inputs, without modulo-only cycles. - A change in the last bytes of the hash: reaches the derived seed. - Resize and reload: preserve the edition's identity. - Metadata: still carries the original transaction hash. - Describe allocation protections precisely; never label a seed alone “bot-proof.” ## Statistics across rolls Use **Analyze 100 rolls** beside the preview, or choose 100, 250 or 1,000 under **Statistics across rolls**. The wizard automatically analyzes the batch when it finishes. Larger batches are deliberate runs, not something repeated after every keystroke. The current art preview and its hash stay in place, and quick seed checks pause while the batch uses isolated previews. Two modes answer different questions: - **Random hashes, one fixed edition** holds the preview project, edition and token IDs constant. Each roll uses a fresh uniformly sampled synthetic 32-byte hash. This explores variation over hash inputs for that edition. - **New hash for each sequential edition** advances both the edition ID and the preview token ID from the chosen starting values. This describes a hypothetical sequence of editions; the preview token ID is not a prediction of the global token counter on chain. The report shows counts, percentages, numerical histograms and summaries, missing metadata, repeated trait combinations, and repeated sampled-frame fingerprints. Percentages use all captured metadata records with a correct original mint hash. A trait's missing or invalid values are reported separately. Numeric summaries use finite number values that are present; numeric-looking text stays categorical. Raw hashes and IDs are excluded from trait profiles so provenance alone cannot make each roll seem unique. Repeated profiles mean repeated **reported traits**, not identical art. The frame fingerprint is a coarse early-frame comparison, not a comparison of whole animations. Uneven frequencies can be intentional artistic weights. Without a declared target distribution, the report does not call them biased or defective. For complete fixed-ID batches with no excluded records and no missing values for that trait, the report adds approximate 95% Wilson intervals for individual value frequencies. These intervals assume independent uniform hash sampling; they are not simultaneous bounds for every value, a probability that an interval contains the true rate, or guaranteed mint odds. Partial batches, failed renders, missing metadata and sequential-ID runs retain descriptive counts but have intervals withheld. The [NIST handbook explains Wilson proportion intervals](https://www.itl.nist.gov/div898/handbook/prc/section2/prc241.htm). Small samples can miss uncommon outcomes. For a predefined outcome with probability `p` under independent rolls, the chance of seeing it at least once in `n` rolls is `1 - (1 - p)^n`. The report illustrates this with a hypothetical 1% outcome; it does not assign that probability to an unseen trait or infer all possible trait values from the code. **Stop** keeps a clearly labeled partial analysis. Three consecutive render failures stop the batch automatically. Changing the draft, renderer or preview seed IDs invalidates the previous report. **Copy report** includes every attempted roll, actual input IDs and hash, exclusions, sample mode and source fingerprint. Results stay in the current wizard session until replaced or the page is reloaded; copy anything you want to retain. These are synthetic-input statistics, not signed transaction simulations. A seed-shopping minter need not sample hashes uniformly, so attractive distribution charts cannot establish resistance to adversarial selection. Use the quick checks, inspect the code and review the mint mechanism as separate evidence. Source basis: `anyoneMintProjectEdition` in the [deployed art contract](https://etherscan.io/address/0xA8A6CB3978e2c4EdcF5A3d0cB3400E1E5D031479#code), viewer mint-event decoding, and the primary references above. --- # Artwork controls Source: https://immutables.art/docs/controls Declare your artwork's interactions in the posted script. The viewer creates touch buttons and native text fields, while your artwork remains responsible for its own keyboard behavior. ## A declaration ```javascript let motion = true; function toggleMotion() { motion = !motion; motion ? p.loop() : p.noLoop(); } p.keyTyped = () => { if (p.key === 'A') toggleMotion(); }; p.immutablesControls = { version: 1, actions: [ { id: 'motion', label: 'Animate', type: 'toggle', key: 'A' }, { id: 'png', label: 'Save PNG', type: 'export' } ], getState: () => ({ values: { motion }, busy: false }), onAction: id => { if (id === 'png') p.saveCanvas('my-edition', 'png'); } }; ``` For other renderers use `t.immutablesControls`, `v.immutablesControls` or `g.immutablesControls`. Use callbacks without a `key` for their buttons and toggles; implement physical keyboard input in your own script. ## Actions and state Declare at most 12 actions. Each needs a unique lowercase ID beginning with a letter and containing only letters, digits or hyphens, up to 40 characters. Labels are plain text, up to 48 characters. - `button`: one action. With a key, p5's keyboard handler runs; without one, `onAction(id)` runs. - `toggle`: also needs `getState().values[id]` as a Boolean. Without a key, `onAction(id, proposedBoolean)` receives the proposed value; update your own state. - `text`: a native field and Send button. `maxLength` is optional, 1–500, default 120. Always provide `onAction`. - `navigation`: Up, Down, Open and Back buttons. Always provide `onAction`. - `export`: appears under Save. It runs only after the visitor chooses it; use it for explicit captures rather than automatic downloads. Keys preserve case. Supported keys are single letters/digits, a space, arrows, Enter and Escape. A text/navigation `key` is a shortcut label; those controls always use callbacks, so implement the corresponding physical shortcut yourself. ## Text and navigation ```javascript p.immutablesControls = { version: 1, actions: [{ id: 'message', label: 'Message', type: 'text', maxLength: 60 }], getState: () => ({ busy: thinking, activeControl: mode }), onAction: (id, event) => { if (event.action === 'open') mode = id; if (event.action === 'change') draft = event.text; if (event.action === 'submit') respond(event.text); if (event.action === 'close') mode = ''; } }; ``` `thinking`, `mode`, `draft` and `respond` above stand for your own state and functions. Text events are `open`, `change`, `submit`, `close`; change and submit include `text`. Navigation events are `open`, `up`, `down`, `back`, `close`. Keep `getState()` cheap and free of side effects. Return `busy: true` during work. Optional `activeControl` follows modes opened by the artwork's own keys or pointer handlers; return an action ID while open and an empty string when closed. If omitted, the viewer manages its own panel selection. Navigation Back stays available during busy work. ## Visibility and styling On mobile the panel opens automatically. On desktop it starts collapsed, with an icon and the bottom-bar **Artwork controls** entry. After four idle seconds it fades to a faint lower-right icon. Typing, navigation, an open Save menu, busy work and keyboard focus keep it open. It does not resize the canvas. The controls live inside `#root` and use existing `.btn`, `.btn-secondary`, `.btn-outline-secondary`, `.form-control`, `.modal-content` and `.font-display` classes. Your [project CSS](/docs/project-style) can style them. There is no shadow DOM. Stable selectors include `.artwork-controls`, `.artwork-controls-panel`, `.artwork-control`, `.artwork-controls-handle`, `.artwork-controls-form`, `.artwork-controls-navigation`, `.artwork-controls-exports` and `.artwork-controls-status`. Individual actions have `data-action`; the outer element has `data-project-id`, `.is-touch` or `.is-desktop`, and `.is-open` or `.is-idle`. ## Existing projects and automatic discovery Reviewed profiles match the exact script SHA-256 and project ID. They provide known controls for Syncret, Firmament and PILLARS; those editions open live even when their grids use cached images. Reviewed profiles take priority over declarations. Otherwise an explicit declaration takes priority. With no declaration, the viewer conservatively detects literal comparisons inside `p.keyTyped` / `p.keyPressed` and offers simple Key buttons. It does not infer semantic labels or toggle state. Unannotated S/P exports and contextual Enter/Escape are omitted. Unsupported syntax may yield no automatic controls. An invalid declaration produces no panel. `{ version: 1, actions: [] }` opts out for an unreviewed script. Grids and still-image views do not execute interactive controls. Test your own declaration in **Preview in UI**, not only the wizard's isolated canvas. Source basis: `artworkControlConventions`, `artworkControlProfile`, `artworkInput`, `ArtworkControls` and `config/artwork-controls.json` in `clients/art/src/`. --- # Give the interface your style Source: https://immutables.art/docs/project-style Your project can theme the artwork's surrounding interface. Use ordinary CSS selectors so the same visual language reaches navigation, information and artwork controls. ## Where styles come from The wizard posts its CSS to the code page with the `style.immutables.art` tag. The current client also serves mirrored `style.css` and `style.mobile.css` files per project for reliable loading. A live reader can fall back to page posts; an archive reader uses its cached styles. Coordinate publication of a separate mobile stylesheet with the platform rather than assuming a second wizard field exists. Project styles are scoped to `#root`. Root selectors such as `body`, `html` and `:root` are mapped into that scope. Some platform or administration panels intentionally live outside it; do not assume project CSS should recolor every wallet or administrative flow. ## Start with the existing classes ```css body { background: #000; color: #fff; } .navbar { background: #000 !important; } .btn, .form-control { border-radius: 0; } .font-display { font-family: 'Major Mono Display', monospace; } .artwork-controls .modal-content { background: #000; color: #fff; } .artwork-controls .btn { color: #fff; border-color: #777; } .artwork-control[aria-pressed="true"] { background: #333; } .artwork-controls { --artwork-controls-gap: 8px; } ``` This is an example, not a required palette. Test selected, unselected, focused and disabled buttons. A theme can override the UI font too; keep body copy and small controls readable even if the artwork uses a distinctive display face. ## Layout and phones Style `.cell` and `.selected` carefully. A mask or transform intended for the artwork should not hide its owner caption or interfere with taps. The control panel is a portal inside `#root`, outside the transformed artwork cell; use its documented classes instead of assuming it is nested inside a canvas wrapper. Preserve 44-pixel touch targets and a visible focus indicator. Keep native input text at least 16 pixels on mobile, allow the on-screen keyboard room, and avoid fixed widths that overflow a narrow screen. The default controls already handle keyboard viewport changes and safe areas. Do not override `.is-idle` in a way that leaves invisible buttons intercepting touches. The faint icon should become clear on hover or keyboard focus. Respect `prefers-reduced-motion` for interface effects. ## Preserve the visual dependencies A remote font or CSS import is a dependency, even when the art source is on Ethereum. Choose a usable fallback and include external assets in your preservation plan. Use the full UI preview, a phone-sized viewport, a reload and a downloaded copy to test your styling. Source basis: `scopeCss`, `projectAssets`, `ArtworkControls.css` and the wizard's CSS posting flow. --- # Manage your project Source: https://immutables.art/docs/project-admin Project settings have different permissions. The artist address, team membership and contract ownership are separate roles; owning an edition does not grant project administration rights. ## Publication and minting A project starts inactive and paused. A team member controls **active** status. The artist or a team member can toggle **paused**. Public minting requires active, unpaused status, an available edition and payment of at least the project price. The artist and team bypass active/paused restrictions, but not the price or edition cap. The deployed entry point is `anyoneMintProjectEdition(projectId)`, one edition per call. It does not include built-in batch, allowlist, per-wallet allocation, or randomness-reveal arguments. Do not confuse a future gate design with a feature of that entry point. Send the intended mint price. The full `msg.value` is forwarded to the royalty manager; this method does not refund an overpayment. ## Artist or team settings The artist or a team member can change price, grid size, pause state and image URL configuration. While the project is unlocked they can also change its name, artist display name, description, maximum editions, script transaction reference and script type. The edition cap cannot be lower than editions already minted and cannot exceed the contract limit of 1,000,000. The display grid size is a separate setting and does not change the edition supply. Changing a script reference can change how already-minted editions render. Review and preserve the old reference, and communicate changes rather than treating a reference update as a harmless text edit. ## Artist-only settings The current artist can update the artist address and the additional payee information. Use the platform's project settings so the parent project and its royalty manager stay coordinated. Changing only the manager directly can leave the parent project's artist mapping out of sync. Check a new recipient address carefully. Changing the artist address transfers the platform's artist authority; changing the additional payee changes payment distribution. See [sales and royalties](/docs/royalties) for how existing balances are treated. ## What locking means `artistTeamLockProject` blocks the contract's `onlyUnlocked` fields: project name, artist name, description, max editions, script transaction reference and script type. It does **not** freeze price, pause, image URLs, grid size, artist address or additional-payee settings. The contract owner can unlock a project with `contractOwnerUnlockProject`. Describe this precisely to collectors; it is not an irreversible renunciation of every permission. The deployed Solidity itself remains immutable reference code in this repository. Changing settings through its functions and changing the contract implementation are different things. ## A release check Confirm the project ID, exact script-post transaction, renderer, price, supply limit, active/paused state, artist wallet and payout recipients. Test a live edition, then confirm the intended lock state. Inspect transaction receipts before retrying a failed-looking action: a slow interface is not proof that a transaction failed. Source basis: `ImmutablesAdminProject` and `ImmutablesArt` in the [deployed art contract source](https://etherscan.io/address/0xA8A6CB3978e2c4EdcF5A3d0cB3400E1E5D031479#code), and the frontend's `ProjectAdminModal` / `BlockchainWriteProvider`. --- # Your sales and royalty manager Source: https://immutables.art/docs/royalties Each new art project receives its own royalty-manager clone. The artist can control the artist recipient and an additional payee through the deployed functions, without waiting for a platform employee to perform those updates. ## Follow an ETH mint 1. A collector calls the art contract's mint function and supplies ETH. 2. The art contract mints the edition and forwards the **entire payment** to that project's royalty manager. 3. A call to `releaseRoyaltiesForProject(projectId)` invokes the manager's `release()`. 4. The manager distributes its current ETH balance to the configured artist, additional payee if any, and parent art contract. Anyone can trigger release; that caller does not choose the recipients or receive their funds. Minting deposits the ETH into the manager. It does not automatically send the artist's share straight into their wallet in the same step. ## Percentages Percentages use basis points: 10,000 is 100%. The project's manager captures the platform's artist percentage when it is created. Do not assume today's global artist percentage retroactively changes every existing manager. An additional payee's percentage is deducted from the artist allocation, not added on top. For illustration only: with a 9,000-basis-point artist allocation and a 1,000-basis-point additional payee, a 1 ETH balance pays 0.8 ETH to the artist, 0.1 ETH to the additional payee and 0.1 ETH to the parent contract. Read the actual manager values for your project before using this example as an expectation. ## Updating recipients Use the project administration interface or the corresponding parent-contract artist function. The manager also permits its current artist to call its update functions directly, but that does not update every parent-project mapping. Changing the additional payee first releases existing **ETH** using the previous split. It cannot automatically find and release every ERC-20 balance before changing that split. Release relevant token balances first if they should use the old recipients. Changing the artist address does not first empty the manager. Remaining balances follow the configured recipients at release time. Check both the authority transfer and any undistributed funds before making that change. ## Exhibition collaborators An artist can use the additional-payee setting to share project revenue with a gallery or museum during an exhibition. Updating it settles the existing ETH under the outgoing split before applying the new one, making confirmed artist updates the opening and closing boundaries. The manager does not automatically expire the arrangement, attribute referrals, or distinguish mint ETH from other ETH it receives. See [exhibition collaborations](/docs/exhibition-collaborations) for the full workflow and ERC-20 treatment. ## Secondary royalties and ERC-20s `royaltyInfo(tokenId, salePrice)` identifies the project's manager and computes an amount using the platform's global secondary royalty percentage. This is a royalty signal for supporting marketplaces; it does not force every transfer or marketplace to pay royalties. The manager can distribute a specified ERC-20 balance with `releaseERC20(token)`. This capability does not create a project token or an art reserve. Different marketplace or token behavior can affect whether funds arrive and whether a release succeeds. Release sends payments in one transaction. If a required recipient or token transfer reverts, the whole release can fail. Check receipts and recipient compatibility instead of assuming a displayed balance is already withdrawn. ## What to verify Read `projectIdToRoyaltyAddress(projectId)` from the parent contract, then inspect the manager's artist address, artist percentage, additional payee and balance. The project administration panel provides a release action and contract links. Keep roles and fee assumptions visible when arranging collaborations. Source basis: `setupImmutablesArtRoyaltyManagerForProjectId`, `anyoneMintProjectEdition`, `royaltyInfo`, and `ImmutablesArtRoyaltyManager.initialize/release/releaseERC20/artistUpdateAddress/artistUpdateAdditionalPayeeInfo` in the [deployed source](https://etherscan.io/address/0xA8A6CB3978e2c4EdcF5A3d0cB3400E1E5D031479#code). --- # Start with a working sketch Source: https://immutables.art/docs/examples Use these for a **new project**. Changing an existing artwork's seed recipe changes its rendered editions, so this is not an instruction to patch released artwork. ## A complete p5 starter [Download the complete script](/docs/examples/p5-starter.js), paste it into the wizard's script editor, choose `p5js`, and use Preview in UI. The file includes the seed helper; it has no package imports or remote asset requirements. It demonstrates a stable composition, a separate noise seed, fixed logical coordinates, resize handling, flat metadata, an Animate toggle and an explicit PNG export. The complete script is also included in the [LLM reference](/llms-full.txt). ```javascript // Immutables.art edition seed convention v1 — for NEW projects. // Deterministic mixing, not cryptographic randomness or bot prevention. // Keep props.transactionHash unchanged for metadata and provenance. function immutablesSeed(props, stream = 'art') { const hash = String(props.transactionHash || '').toLowerCase(); if (!/^0x[0-9a-f]{64}$/.test(hash)) throw new Error('A full mint transaction hash is required'); const decimal = (value, name, allowZero) => { if (typeof value === 'number' && !Number.isSafeInteger(value)) throw new Error(name + ' must be a safe integer or decimal string'); const text = String(value); if (!/^\d+$/.test(text)) throw new Error(name + ' is required'); const normalized = text.replace(/^0+(?=\d)/, ''); if (!allowZero && normalized === '0') throw new Error(name + ' must be positive'); return normalized; }; const input = ['immutables.art/edition-seed/v1', hash, decimal(props.projectId, 'projectId', true), decimal(props.editionId, 'editionId', false), stream].join('|'); let hex = '0x'; for (let word = 0; word < 8; word++) { let state = (2166136261 ^ Math.imul(word + 1, 0x9e3779b9)) >>> 0; for (let i = 0; i < input.length; i++) state = Math.imul(state ^ input.charCodeAt(i), 16777619) >>> 0; state = Math.imul(state ^ (state >>> 16), 0x85ebca6b); state = Math.imul(state ^ (state >>> 13), 0xc2b2ae35); hex += ((state ^ (state >>> 16)) >>> 0).toString(16).padStart(8, '0'); } return hex; } // A local drawing stream. Do not replace Math.random globally. function immutablesRandom(props, stream = 'art') { let state = parseInt(immutablesSeed(props, stream).slice(2, 10), 16) >>> 0; return () => { state = (state + 0x6d2b79f5) >>> 0; let value = Math.imul(state ^ (state >>> 15), state | 1); value ^= value + Math.imul(value ^ (value >>> 7), value | 61); return ((value ^ (value >>> 14)) >>> 0) / 4294967296; }; } // Include edition-seed.js above this body. MIT; see examples/LICENSE.txt. let edition = null; let composition = []; let motion = true; let frame = 0; p.setup = () => { p.createCanvas(1, 1); p.noLoop(); }; function fitCanvas() { if (!edition) return; const size = Math.max(1, Math.floor(Math.min(window.innerWidth, window.innerHeight) * 0.8 / Number(edition.square))); p.resizeCanvas(size, size); } p.myCustomRedrawAccordingToNewPropsHandler = props => { if (!props || !props.transactionHash || !props.editionId || !props.square) return; const identity = immutablesSeed(props); if (!edition || edition.identity !== identity) { p.randomSeed(parseInt(identity.slice(2, 10), 16)); p.noiseSeed(parseInt(immutablesSeed(props, 'noise').slice(2, 10), 16)); composition = Array.from({ length: 18 }, () => ({ x: p.random(40, 360), y: p.random(40, 360), radius: p.random(8, 35) })); frame = 0; console.log('metadata: ', { transactionHash: props.transactionHash, Structure: 'Orbits', Circles: composition.length }); } edition = { ...props, identity }; fitCanvas(); motion ? p.loop() : p.redraw(); }; p.draw = () => { if (!edition) return; p.background(0); p.push(); p.scale(p.width / 400); p.noFill(); p.stroke(255); p.strokeWeight(1.5); for (const circle of composition) { p.circle(circle.x, circle.y, circle.radius * 2 + Math.sin(frame / 45 + circle.x) * 6); } p.pop(); if (motion) frame++; }; p.windowResized = () => { fitCanvas(); if (!motion) p.redraw(); }; function toggleMotion() { motion = !motion; motion ? p.loop() : p.noLoop(); } p.keyTyped = () => { if (p.key === 'A' || p.key === 'a') toggleMotion(); }; p.immutablesControls = { version: 1, actions: [ { id: 'motion', label: 'Animate', type: 'toggle', key: 'A' }, { id: 'png', label: 'Save PNG', type: 'export' } ], getState: () => ({ values: { motion } }), onAction: id => { if (id === 'png' && edition) p.saveCanvas('orbits-' + edition.editionId, 'png'); } }; ``` ## Seed helper by itself [Download edition-seed.js](/docs/examples/edition-seed.js) if you already have a drawing. Copy its functions into the posted source; do not add a runtime fetch dependency on the documentation website. Use `immutablesRandom(props, 'composition')` for a local `random()` function in vanilla or three.js artwork. For p5, initialize `p.randomSeed` from `immutablesSeed(props)` and use a separate domain for noise. See [seed limitations](/docs/randomness). ## Built-in wizard studies The wizard contains four renderer boilerplates and 16 studies across p5.js, three.js, vanilla canvas and GLSL. Their current seed paths mix the full transaction hash and full project/edition IDs. The particle example uses a local seeded stream rather than `Math.random()` for its persistent structure. Examples based on existing projects are **adapted studies**. Their seed behavior is intentionally different from the historical releases. Preserve credits and check the applicable license before reusing artwork code. The generic starter is available under the [MIT license](/docs/examples/LICENSE.txt). The wizard only replaces the current editor after the example-load confirmation. Saved drafts and already-posted scripts are not automatically migrated. To adopt a new recipe in your own unreleased draft, explicitly replace its seed initialization and retest the work. ## What a good preview demonstrates Compare different hashes, then reuse one hash with different edition IDs. Reload a fixed input, resize the viewport, and compare both traits and a fixed animation moment. Preview in a grid and as a selected edition. Test native mobile typing, exports and control styling in the full UI. --- # Check the work before publishing Source: https://immutables.art/docs/troubleshooting Check the actual renderer, the actual inputs and the exact posted source. A working canvas in an editor is the beginning of validation, not the last step. ## Blank or tiny canvas Confirm the script type and its context name. A p5 body receives `p`; a vanilla body receives `v`. Guard missing props and initialize the edition only after the required inputs arrive. Handle the grid `square` divisor and create or resize a real canvas. For WebGL, check shader compile/link logs and attach the canvas to `props.container`. The current viewer catches some drawing errors to keep the page usable. Inspect the browser console during development rather than treating a blank image as proof that the script is merely slow. ## Different art after reload or resize Look for unseeded `Math.random`, fresh browser entropy, changing external data, mutable globals shared between instances, or random draws consumed in a different order. Separate persistent traits from layout and animation. Reinitialize a local stream from the same full edition identity; do not pick new traits just because the canvas changed size. Start with the wizard's automatic **Hash & mint checks** below the script editor. The report compares fresh renders, tests several edition IDs and hash positions, and flags source locations worth reviewing. Copy its report when asking an LLM to help. See [how to interpret the sampled checks](/docs/randomness#test-before-you-publish); an inconclusive render or a repeated trait needs context, and the suite does not certify bot resistance. ## Missing controls Open an individual edition in **live render** mode. Grids and static images have no interactive script instance. On desktop, use the faint lower-right icon or **Artwork controls** in the bottom bar. On mobile, tap the icon if the panel has faded. For your own project, validate `version: 1`, supported action types, IDs and callbacks. A toggle needs `getState`. Text/navigation need `onAction`, including when you also supply a key label. An invalid explicit declaration suppresses automatic discovery. Reviewed known-project behavior only applies to its exact source hash. ## Native typing triggers artwork shortcuts Use the declared text control and the p5 handler convention. Avoid document-wide capture listeners that swallow every key, including keystrokes in input fields. The current adapter protects supported handlers and its scoped window listeners; custom listeners installed elsewhere remain your responsibility. ## Traits do not appear Log `console.log('metadata: ', object)` after the traits exist. Keep the original `transactionHash` in the object. Prefer simple named values, and do not emit a new trait distribution every frame. For multiple mints in one transaction, review the current transaction-hash grouping limitation in the [script reference](/docs/script-api). ## Marketplace image differs from the live edition Verify that the image file is named by global `tokenId`, that the source and seed recipe are the released ones, and that the captured moment matches your intent. Check the project image base, file extension, hosted JSON and marketplace cache. An endlessly changing artwork's GIF is only an excerpt. ## A transaction appears stuck or failed Check its hash and receipt before retrying. The wizard's deploy steps are separate transactions, and an interrupted browser does not undo successful earlier steps. Verify network, account, posting rights, current fees, project active/paused state and available supply. Do not send another transaction simply because a progress label is stale. ## Before release - Test several hashes and full edition IDs, including the same hash at 1 and 9. - Reproduce a fixed edition after reload and resize. - Test a crowded grid and a selected edition on desktop and phone-sized screens. - Check metadata, text entry, keyboard shortcuts, idle controls and explicit exports. - Preserve exact source, dependencies, license and project settings. - Review recipients, price, edition cap, script transaction and lock semantics. - Describe the seed and mint mechanism accurately; do not promise bot prevention from deterministic mixing alone. Use physical devices for memory-intensive captures and mobile keyboard behavior before making those features part of the release promise. --- # Work with an LLM Source: https://immutables.art/docs/llm-guide Give your coding assistant this page and the [complete handbook](/llms-full.txt). The [llms.txt index](/llms.txt) links to individual Markdown chapters for assistants that read incrementally. ## Copyable authoring brief ```text Build a NEW Immutables.art artwork using the current artist handbook at https://immutables.art/docs/ and https://immutables.art/llms-full.txt. Ask me for the artistic direction, renderer, intended interactions and whether time changes the work when those choices are missing. Preserve my aesthetic intent and artist credit. Do not silently repurpose an existing release. Deliver the complete posted JavaScript function body, a separate project CSS stylesheet, an information post, and a short testing report. Include all helper functions in the script. No HTML wrapper, ES module imports or top-level export. Do not perform wallet transactions or publish without my explicit instruction. Runtime: - p5js receives p; threejs receives t and THREE; vanillajs receives v; glsl receives g and must create WebGL with JavaScript. - Implement context.myCustomRedrawAccordingToNewPropsHandler(props). - Props: transactionHash (mint transaction), projectId, editionId, tokenId, square; non-p5 renderers also get container. IDs can be decimal strings. - No generic blockHash, timestamp, prevrandao, VRF result or seed prop exists. - Keep state local per instance. Guard missing inputs. Handle setup, resize and cleanup. Distinguish trait identity from layout and animation progression. Seeds: - Include the full helper from /docs/examples/edition-seed.js for the current deterministic convention, or explain and validate an intentional alternative. - Mix the full mint transaction hash, full project ID and full edition ID with a fixed domain/version. Do not use editionId modulo a small number as the only edition input. Preserve the original transactionHash for metadata. - Use local seeded streams. No Math.random or fresh browser entropy for fixed edition traits. Separate named streams can isolate palette, geometry and noise. - Seed mixing improves differentiation and adds mint-order dependence. It does not prevent seed shopping or bots. Do not claim new entropy from extra hashing. - Stronger allocation requires an actual reviewed contract/reveal integration; do not invent one in the art script or describe prospective features as live. Controls: - Declare context.immutablesControls with version 1 and supported actions. - Use descriptive labels; toggle state comes from getState().values[id]. - Text/navigation require onAction; use busy and optional activeControl. - Non-p5 buttons/toggles use callbacks without key, with native keys implemented separately. Exports require an explicit action. Do not auto-download on load. - Style existing .btn, .form-control, .font-display and .modal-content classes, plus the documented .artwork-controls selectors inside #root. - Preserve idle behavior, focus, reduced motion and 44px touch targets. Metadata: - Log console.log('metadata: ', { transactionHash: props.transactionHash, ...traits }). - Use stable flat string/number traits. Never substitute the derived seed for the real transaction hash. Document the current hash-grouping limitation for multiple editions minted in one transaction. Acceptance checks: - Same hash and IDs reproduce traits and initial composition. - Same hash with edition IDs 1, 2, 9, 51 and 257 changes the seed. - Last bytes of the hash affect seed output; normalize IDs consistently. - Resize, reload and grid/detail mode preserve identity. - Test native text, keys, toggles, idle handle, exports and CSS in Preview in UI. - Validate JavaScript and actual rendering; report what was not tested. - Run the wizard's Hash & mint checks on the final draft; review the copied report against its source SHA-256. Resolve defects and explain intentional time-dependent or repeating traits. Never turn an inconclusive test into a pass just to clear the report, or claim the suite certifies bot resistance. - Preserve attribution and license. Save exact source and renderer dependencies. - Use Statistics across rolls to inspect trait frequencies and numerical distributions. Report sample mode, count and exclusions. Do not assume equal artistic weights, infer missing outcomes are impossible, treat repeated trait profiles as identical art, or present synthetic roll statistics as mint odds. Contract facts: - Code posts are calldata plus emitted logs on an owned/public code page. Reserving a page creates its NFT; every post is not a new NFT. - The art project references a code-post transaction. Mint events identify editions; the viewer recovers the mint transaction hash from those events. - Projects start inactive and paused. Team controls active; artist/team controls pause. Privileged mints still need the configured price and available supply. - A project lock freezes only fields protected by onlyUnlocked; the contract owner can unlock. Do not call it irrevocable or a freeze of every setting. - Each project's manager receives mint ETH and distributes it on release. Anyone may trigger release to configured recipients. ERC-2981 signals royalties but does not enforce every marketplace's payment. - Metadata mode is a platform-owner setting. Contract-generated JSON may still reference hosted images. Historical-data access and external dependencies must be preserved separately. ``` ## Useful source locations for repository-aware assistants - `clients/art/src/components/P5Cell/P5Wrapper.js` and `ThreeCell/ThreeWrapper.js`: current runtime inputs and lifecycle. - `clients/art/src/utils/artworkControlConventions.js` and `artworkInput.js`: the declaration validator and callbacks. - `clients/art/src/services/BlockchainProvider.js`: code-post decoding and mint events. - `clients/art/public/project-wizard.html`: authoring and publishing flow, adapted built-in examples. - `contracts/legacy-art/contracts/ImmutablesArt.sol` and `ImmutablesArtRoyaltyManager.sol`: deployed art behavior. - `contracts/legacy-code/contracts/Immutables.sol`: page NFTs and code posts. Treat the deployed Solidity, checked-in deployment artifacts and posted artwork as reference material. Make new work in the artist's draft or active client code as instructed. Do not change released seed behavior to make a documentation example pass. When the docs and source disagree, quote the exact behavior, identify the mismatch and propose a correction. Do not invent a field, method or permission to fit an example. --- # Section: Galleries & Museums Assistant brief: https://immutables.art/docs/institutions-brief.txt Help plan an Immutables.art exhibition or conservation record using https://immutables.art/docs/galleries-museums, /docs/exhibiting and /docs/preservation. Establish the exact work and edition, artist credit, intended presentation, target hardware, interaction and any artist-approved installation conditions. Strongly prefer live rendering for exhibitions. Compressed images and clips are previews, records or fallbacks, not the preferred presentation. Museums do not need to acquire, borrow or hold NFTs to render them; owners can retain tokens in their wallets. Agree presentation rights with the artist. Viewing and artist-authorized payee updates need no platform employee's approval; institutions cannot assign themselves a share, and project mint eligibility still applies. For exhibition revenue sharing, read /docs/exhibition-collaborations. The artist can assign a gallery or museum as the project's single additional payee. Its share comes from the artist allocation; payment happens on release. Confirmed payee updates define the period and settle existing ETH using the outgoing split. There is no automatic expiry, referral attribution or mint-only ETH accounting. Release relevant ERC-20 balances under the intended recipients before changing the payee. Payee status grants no project administration or NFT ownership. Start museum mode immediately runs the current project's original cycle: random live edition, return to grid, another random edition, on a 30-second cycle with roughly 20 seconds per edition. Controls fade when idle. The separate settings gear optionally selects whole projects, edition subsets, multiple projects and collection wallets, with duration, order, grid intervals, presentation CSS, labels, interaction and saved/exported settings. The reviewed list stays fixed during playback; review again for ownership changes. A single-edition show runs continuously when the grid interval is disabled; holding an edition pauses the cycle, not the artwork. The main Start button uses the current project and original defaults; reopen settings to use a saved custom configuration. Use Stop to end playback; a browser may consume Escape to exit fullscreen first. Projection mapping uses the separate gallery runtime for p5 projects, live mapped surfaces, multiple projector windows, calibration and a scene timeline. A reviewed Museum selection becomes a new scene while preserving existing scenes and calibration. Single-screen CSS and labels do not carry over. Output coordination is within one browser/computer, not a networked controller. Save space/show files and test the build's exact supported editions and offline dependencies. Label recorded images or clips as captures. Do not describe a looping excerpt as the full behavior of a continuously evolving work such as EoD. Document clock conditions and restart behavior for time-dependent projects. Preserve source bytes, code-post transaction and logs, mint inputs, identifiers, project settings, runtime dependencies, license and agreed presentation terms, installation records and reference captures. Keep original materials separate from adaptations. Test actual playback and offline dependencies on the target hardware. Do not guarantee pixel-identical output across browsers or GPUs. Use /docs/storage and /docs/contracts for shared facts, and distinguish proposed archives from deployed functionality. Do not change artwork, source, project settings or ownership without explicit instructions. State what was tested and what needs the artist's input. # Exhibit and care for living software Source: https://immutables.art/docs/galleries-museums **Present the live artwork whenever possible.** Generative artworks are running software: their movement, interaction and response to time belong in the exhibition. Compressed images and clips serve as previews, reference captures or fallbacks when live rendering is impractical. The institution does not need to acquire or take custody of an NFT to display it. Owners can keep their editions in their own wallets throughout the exhibition. Agree presentation and attribution with the artist; no platform account or wallet connection is needed to run the display. A gallery or museum can also be an **exhibition collaborator**, receiving an artist-agreed share of project mint revenue while an exhibition arrangement is active. The artist configures this through the project's existing Additional Payee setting. Read [exhibition collaborations](/docs/exhibition-collaborations) for the revenue flow and how to open and close the period. ## For galleries Build the presentation around the artist and selected works. Agree on edition selection, credit, permitted captures and visitor interaction. Keep the edition link beside the display so visitors can find the work and its project. Use [exhibition setup](/docs/exhibiting) to curate a single-screen sequence or configure projection mapping across multiple outputs and surfaces. Select exact editions, whole projects or works held by particular collection wallets. If visitors are directed to mint or collect, provide that route on their phones or another device. The display can run without a connected wallet. ## For museums and collections Record each exhibited edition's chain, contract and token ID alongside its project, edition number, artist and provenance. A code-page NFT and art-edition NFT identify different objects; [contracts and identity](/docs/contracts) explains their roles. Ask the artist to document significant behaviors: how the edition starts, how time affects it, which interactions matter, and which display changes are acceptable. Use [conservation and archives](/docs/preservation) to keep source, historical inputs, dependencies and installation records together. ## Plan the handover An exhibition record should identify the editions, contacts, intended presentation and files supplied. Preserve the artist's stated license and agreed exhibition terms alongside technical materials. An acquisition can be documented separately when one is involved; neither a purchase nor a transfer to the museum is required for rendering. Test on the actual display hardware. Record a reference capture, then check that a fresh copy reproduces the relevant behavior. A repeatable installation procedure makes the next exhibition easier. ## Shared references - [Exhibition collaborations](/docs/exhibition-collaborations): artist-controlled revenue sharing for galleries and museums during a show. - [Exhibition setup](/docs/exhibiting): Museum settings, projection mapping, live rendering and daily operation. - [Conservation and archives](/docs/preservation): archive inventory and reconstruction checks. - [Storage and metadata](/docs/storage): source transactions, previews and metadata modes. - [Project management](/docs/project-admin): which settings can change and who controls them. --- # Prepare an exhibition Source: https://immutables.art/docs/exhibiting **Prefer live rendering for an exhibition.** Let the artwork's program produce its images, movement and interactions on the display. Compressed images and clips are useful previews and reference captures; reserve them for situations where running the work is impractical. The museum does not need to acquire, borrow or hold the NFTs to render them. Owners can keep their editions in their wallets throughout the exhibition. Agree the presentation and attribution with the artist, then run the viewer without a wallet connection or platform approval. The institution can also participate as a revenue-sharing collaborator. An artist can configure a gallery or museum to receive an agreed share of project proceeds during the exhibition through **Additional Payee**. [Exhibition collaborations](/docs/exhibition-collaborations) explains the arrangement, including confirmed start/end updates and project-wide participation. ## Start museum mode Open a project in the [art viewer](/) and choose **start museum mode** in the bottom bar. On a narrow screen, expand the bar's menu first. It starts immediately from the loaded project, with no configuration required. The original cycle fades into a random live edition, returns to that project’s grid after roughly 20 seconds, then chooses another edition on a 30-second cycle. The grid uses the project’s normal preview settings and preloads its images while the live edition plays. A bounded cache retains decoded previews between cycles. Controls align below the artwork’s left edge and the project caption below its right edge. Controls fade when idle; move the pointer or tap **•••** on the left to reveal them. Use **dark** or **light** to change the surrounding field. ## Optionally customize the exhibition The separate **⚙ Museum settings** button opens optional configuration. Keep **Museum mode** selected and name the exhibition. Starting from these settings uses the same edition-and-grid mechanics with your choices; the main **start museum mode** button always starts the current project with the original defaults. 1. **Select projects.** Include a whole project by leaving its edition field empty. Enter numbers such as `1, 3, 7-12` for a subset. Combine whole projects and selected editions from other projects in the same exhibition. 2. **Filter by collection wallets, if useful.** Enter full Ethereum addresses to include only works held by any of those wallets within your selection. The display never takes custody. Archive mode identifies the ownership snapshot it uses; a snapshot is not a current ownership check. 3. **Set duration and order.** Keep random selection each cycle, choose project-selection order then edition number, or shuffle once and repeat that order. Adjust time per edition and time on the grid. The grid shows only the selected editions of the current project. Turn off **Return to the project grid between editions** for continuous edition-to-edition playback; with just one selected edition, it runs continuously. 4. **Choose presentation.** Use black or white surroundings, each project's artist CSS, or custom exhibition CSS. Custom CSS applies to the artwork stage through the existing classes; staff controls stay separate. Labels can show the title, artist, edition and readable URL. Visitor interaction can be enabled or disabled. 5. **Review selection.** Check the exact resulting list, then choose **Start museum mode**. Missing editions or unresolved ownership prevent a filtered show from quietly proceeding with an incomplete selection. The reviewed list remains fixed during playback. Review it again to include new mints or changed ownership. For a fixed display outside Museum mode, open the edition's `/#//` URL directly. ## Operate the display Edition views render the work live. The default returns to the grid between editions; optional settings can turn that off. Open **•••** for additional controls: **Hold this edition** pauses the cycle while the artwork continues running, and **Previous** or **Next** chooses another work. **Blackout** temporarily covers the display while the artwork keeps running. The gear returns to optional settings. **stop museum mode** ends playback; Escape also stops it when the browser delivers that key to the page. Browsers may consume the first Escape to leave fullscreen, so use Stop to be certain playback has ended. Fullscreen availability and screen wake-lock support depend on the device; rehearse the actual installation. Use **Save settings** to keep the configuration in this browser. **Export settings** saves a portable JSON file; **Import settings** restores it on another viewer using the same network. Settings contain the selection and presentation choices, not the artwork source or a permanent ownership record. After a restart, reopen museum settings, review the selection and start the show. ## Projection mapping mode Choose **Projection mapping** in museum settings to send the reviewed editions into the [gallery projection tool](/immutablesArtGallery.html?mode=program). The current mapping runtime supports **p5 projects**. Use Museum mode for the other supported artwork renderers. The selection becomes a new scene, preserving existing scenes and calibrated surfaces. Each surface initially receives the selected sequence; arrange different sequences on different surfaces in the timeline as needed. The scene repeats until you change the programming. A missing edition in the gallery bundle must be resolved before importing the selection. 1. **Set up projector outputs.** Add an output for each projector or display and create its surfaces. A surface is an area where an artwork will appear. 2. **Calibrate the room.** Open **calibrate** on the projector display and press **F** (or **fullscreen ⛶**) before aligning to the room. Each surface shows a white grid on black, with an outline and centre cross to check perspective. Drag the corners onto the physical wall, panel or object; **grid: on/off** toggles the pattern. The artwork and corner handles update together when the viewport changes. 3. **Program the show.** Use the timeline to choose editions, set block durations and transitions, and arrange scenes. It also supports project pools and trait-based selections. Scrubbing chooses the scheduled work; it does not seek through a recording of the generative program. **Run here** is fixed at the top right of both programming and calibration, above the floating panels. From the timeline it starts fullscreen playback at the current playhead, keeping the live artwork running. 4. **Open outputs.** Use the Projectors panel to open each output window, move it to its projector and click **Enter fullscreen ⛶** or press **F**. This uses browser fullscreen, hiding tabs and the address bar. Match the display and fullscreen size used for calibration: a smaller window scales the mapping to its viewport. **H** hides or restores the tools without restarting the artwork or leaving fullscreen; from a clean output it restores the timeline at the current point. **C** returns the same output to calibration; **Run here** returns to clean playback. These mode switches keep the page open so the browser stays fullscreen. **B** toggles blackout during clean playback. Calibration grids are removed from the live artwork layer, and the fullscreen button disappears in fullscreen. Keyboard shortcuts also work when the artwork has focus, but leave text-entry fields alone. Allow the browser to open the output windows. 5. **Save and rehearse.** Export the space, show or both from calibration. Retain those files alongside the exact gallery build and the room's installation notes. The mapping runtime renders the programs live on a black field. It embeds the supported source, p5 runtime and edition mint inputs from its build snapshot. Museum mode’s grid intervals, CSS and labels do not carry into the projection timeline. Coordinate the output windows in the same browser on the same computer; this is not a networked multi-computer control system. For offline use, retain the downloaded gallery file and test the whole installation disconnected. Any external dependency used by an artwork still needs to be available. Do not assume a fresh online mint is included in an older gallery build. ## Time and interaction For continuously evolving work such as EoD, a recorded loop shows a finite excerpt. Prefer a long live presentation or a single selected edition. Changing editions restarts the next program; agree appropriate duration and restart behavior with the artist. Record the edition, live/capture choice, viewport, orientation, browser and renderer versions, and relevant start time. For clock-dependent works, preserve the installation's time and timezone settings. Agree with the artist how restarts should be handled. ## Interaction and attribution Test actual touch and keyboard controls, including idle collapse and how visitors reopen them. Document intentionally limited interaction with the artist. A photograph cannot capture the full behavior of an interactive work. A useful label includes title, artist, edition, project, medium, playback mode and a readable edition URL or QR code. Identify a collection where agreed. Verify attribution from the project records rather than guessing from a wallet address. Visitors can open the project and mint on their own devices under its existing mint conditions. ## Installation rehearsal 1. Open the exact edition on the target hardware and confirm rendering at the intended resolution. 2. Run for the intended session length; check performance, sleep settings and restart recovery. 3. Test the visitor input device, readability, motion and any artwork-specific audio behavior. 4. Rehearse with the intended network conditions. For offline display, disconnect and test every dependency required by the work. 5. Keep installation notes and reference captures with the [archive](/docs/preservation). The display does not need a wallet connection. Use the [verification page](/verify) for downloaded viewers and retain the exact tested build. Source basis: `MuseumExhibition`, `MuseumPlayer`, `museumSettings`, `ArtworkControls`, `tools/gallery-shell.html` and `tools/build-gallery.js`. --- # An exhibition can be a collaboration Source: https://immutables.art/docs/exhibition-collaborations A gallery or museum can participate in an exhibition as a revenue-sharing collaborator. The artist can allocate part of a project's proceeds to the institution while the exhibition is running, connecting its presentation and programming to new collecting activity. ## A collaboration around the work For a gallery, this can support the work of presenting the artist and introducing collectors to the project. For a museum, it can be part of an agreed arrangement supporting an exhibition, interpretation or public programming. Visitors encounter the live artwork and can mint from the project using their own devices. The artist chooses the institution's receiving address and share through the project's **Additional Payee** settings. The contract calls this recipient an `additionalPayee`; “exhibition collaborator” describes the institution's role in the arrangement. Being a payee does not grant ownership of the artist's code-page NFT, an edition, or project administration authority. The artist retains control of the setting. Agree the collaboration, credit and presentation terms separately. ## Work directly with the artist For an existing project, the artist and institution can arrange this directly. The artist sets the additional payee through the deployed contract without needing a platform employee's approval or signature. Anyone can trigger payment release under those settings. This is the permissionless part of the arrangement: the institution cannot assign itself a share or change the artist's settings. The display itself needs no wallet connection, token transfer or custody. Editions can remain in their owners' wallets. Agree the presentation, attribution and any required display rights with the artist; public access to the program is not a new copyright license. Visitors mint under the project's existing availability, price and eligibility rules. ## How the share reaches the institution A mint sends its ETH payment into that project's royalty manager. When funds are released, the manager distributes the configured shares to the artist, additional payee and platform. Anyone can trigger that release; the caller cannot choose different recipients. The collaborator's share comes from the artist allocation. The platform allocation is not increased by adding a collaborator. Percentages are expressed in basis points of the total received: 1,000 basis points means 10% of the total, not 10% of the artist's remaining share. See [sales and royalties](/docs/royalties) for a worked example. Each project has one additional-payee slot. If it already represents another collaborator, include that existing arrangement when deciding how the exhibition will be supported. ## Open and close the exhibition period 1. **Agree the arrangement.** Identify the project, institution's receiving address, share, intended start and end, and how other revenue will be treated. Record the current payee settings so they can be restored. 2. **Open the period.** The artist updates the project's Additional Payee setting. That transaction first releases existing ETH under the previous split, then installs the exhibition split. Subsequent mint payments use the new arrangement. 3. **During the show.** Share the project link with visitors and release funds as needed. Retain mint, payee-change and payment receipts with the exhibition records. 4. **Close the period.** The artist restores the previous settings or removes the exhibition allocation. This update first releases the remaining ETH under the exhibition split, then applies the next settings. The confirmed setting changes define the on-chain period. The deployed manager has no exhibition calendar or automatic expiry: an agreed closing date does not change the payee by itself. If precise boundaries matter, record the update transactions and their block positions as well as the intended dates. ## Project-wide participation The setting applies to the project's manager, so it includes mints made elsewhere while the exhibition arrangement is active. A gallery link or QR code does not make the current contract attribute a mint to a particular visitor, venue or referral. The manager also receives supporting marketplaces' secondary royalties and can receive other funds. It does not separate mint ETH from other ETH when releasing its balance. Agree how those receipts fit the collaboration; this mechanism is not an automatically enforced mint-only commission. If the manager holds ERC-20 tokens, release the relevant balances before changing the payee when they should use the outgoing split. Payee updates settle ETH automatically, but cannot discover and settle every ERC-20 balance. Confirm successful receipts: a failed update has not opened or closed the period. ## Pair the arrangement with the installation Use [exhibition setup](/docs/exhibiting) for curated single-screen Museum mode or projection mapping, and [conservation and archives](/docs/preservation) for the installation records. The museum's financial participation and its presentation mode are independent: either display format can be used in an agreed collaboration. Source basis: `ImmutablesArt.artistUpdateProjectAdditionalPayeeInfo`, `anyoneMintProjectEdition`, and `ImmutablesArtRoyaltyManager.artistUpdateAdditionalPayeeInfo/release/releaseERC20` in the unchanged deployed sources. [Sales and royalties](/docs/royalties) links to those sources and explains recipient updates. --- # Preserve a work you can run again Source: https://immutables.art/docs/preservation Preserve the materials needed to run the work, together with an account of how it should behave. This applies to personal collections and institutional archives. ## An archive inventory - **Identity and provenance:** chain, contract, global token ID, project, edition number, mint transaction hash, acquisition records and relevant transfer receipts. - **Artist and project records:** title, credit, description, license, agreed presentation terms and instructions about behavior or acceptable display changes. - **Exact source:** referenced code-post transaction, original content bytes, receipt/logs and extracted JavaScript. Keep the code-page identifier too. - **Edition inputs:** mint receipt and event data used to recover its original mint hash and identifiers. Save project configuration with a date and block reference where available. - **Runtime and dependencies:** tested viewer build, library versions, styling, fonts, images and other required assets. Record dependency URLs alongside preserved files. - **Playback record:** operating system, browser, graphics hardware, viewport, clock conditions, interactions and reference captures explaining what they demonstrate. [Storage and metadata](/docs/storage) explains why calldata, logs, project state and preview images are distinct archival materials. An immutable deployed contract does not guarantee that future data providers will serve all historical transactions. ## Download and verify Keep the [art bundle](/immutablesArt.html) and, where useful, the [whole-interface bundle](/immutablesArtApp.html). Save the matching [hash file](/hashes.txt) and acquisition date, then compare the downloaded bytes using the [verification page](/verify). A matching hash checks agreement with that published build. It does not replace provenance records or prove every external dependency is present. Downloads contain snapshots; ownership information can become historical. ## Reconstruct from a fresh copy Use a fresh browser profile without relying on an existing site's cache. Confirm identifiers and initial composition, then test significant behaviors: animation, text, controls, clock changes and exports where applicable. For offline display, test separately with the network disconnected. Record what works and what requests external data. Keep missing dependencies visible in the record rather than calling an untested package self-contained. ## Preserve identity and behavior Reproducible inputs do not imply pixel-identical output on every browser or GPU. Font rasterization, shaders and device capabilities can affect rendering. Use artist instructions and the reference installation to identify meaningful differences. Keep an untouched original when adapting a viewer or preparing an emulation. Document the reason, changes, runtime versions and comparison results in a separate working copy. Evolving work may need starting conditions and elapsed runtime; clock-dependent work may need its reference time. The proposed on-chain archive is [future work](/docs/future). You can begin this practical archive now; do not describe the proposed extension as an already-deployed service. --- # Section: Technical Reference Assistant brief: https://immutables.art/docs/reference-brief.txt Use https://immutables.art/docs/technical-reference and https://immutables.art/llms.txt to explain Immutables.art platform behavior. Trace claims to the relevant deployed contract or current viewer source. Separate code-page NFTs, art projects and edition NFTs; code-post and mint hashes; project/edition numbers and global token IDs. JavaScript executes in the browser. Metadata can be hosted or contract-generated; neither mode guarantees every image, dependency or historical transaction is available forever. Distinguish fixed deployed Solidity from configurable project fields and permissions. Read current values for live ownership, pricing and configuration. State the chain, contract and observation date where relevant. Preserve source bytes and edition inputs for reconstruction. Treat /docs/future as a boundary between available behavior and proposals, not proof of a live integration. For authoring, also read /docs/llm-guide. For exhibition or collecting, adapt the explanation to those guides. Do not execute wallet transactions or modify deployed reference material. # Follow the work from code to screen Source: https://immutables.art/docs/technical-reference The same source material supports the collector, artist and institution guides. Use these chapters to check an identifier, renderer input or platform behavior. ## From code to screen 1. **Code post:** a transaction and its event history identify content posted to a code page. 2. **Art project:** the project references that code-post transaction and records its settings. 3. **Edition mint:** a mint transaction creates an edition with project, edition and token identifiers. 4. **Browser rendering:** the viewer retrieves the program and supplies edition inputs. The program creates the visual or interactive work. The browser runs the JavaScript. Metadata and preview images help other services describe an edition; they do not replace its program and inputs. ## Reference chapters - [Contracts and identity](/docs/contracts): addresses, code-page ownership, edition IDs and royalty managers. - [Script reference](/docs/script-api): renderer contexts, inputs, lifecycle and metadata conventions. - [Storage and metadata](/docs/storage): historical source, metadata modes, downloads and verification. - [Current and proposed features](/docs/future): current functionality and prospective extensions. Authors can also consult [seeds](/docs/randomness), [controls](/docs/controls), [project management](/docs/project-admin) and [royalties](/docs/royalties). Reconstruction guidance lives in [conservation and archives](/docs/preservation). ## Check a claim against its source Identify chain, contract, project and block or observation date before treating ownership, price or configuration as current. Use deployed source and project settings to establish permissions. A future feature description is not evidence of a deployed integration. The [LLM index](/llms.txt) exposes this same chapter structure. Preserve artist credit, distinguish observed behavior from proposed changes, and state the scope of reconstruction tests. --- # The contracts behind an edition Source: https://immutables.art/docs/contracts The code and art platforms have different responsibilities. Use the contract address together with the token ID when identifying an NFT. ## Immutables Code The Ethereum mainnet [code contract, 0x499f4943fB86717adcE584927E6AB5a172f03001](https://etherscan.io/address/0x499f4943fB86717adcE584927E6AB5a172f03001#code) manages code-page NFTs and posted content history. Reserving a page creates its NFT. An artist can hold that page NFT while publishing associated code posts. Each post is not automatically another NFT, and a code-page NFT is not an art edition. The prospective name `code.immutables.art` would be a frontend branding change; it does not by itself change this contract or its token identities. ## Immutables Art The Ethereum mainnet [art contract, 0xA8A6CB3978e2c4EdcF5A3d0cB3400E1E5D031479](https://etherscan.io/address/0xA8A6CB3978e2c4EdcF5A3d0cB3400E1E5D031479#code) records projects and issues edition NFTs. A project references a particular code-post transaction. Each edition has a project, a number within that project and a global ERC-721 token ID. The viewer's `/#//` URL uses project and edition numbers. `ownerOf` and `tokenURI` use the global token ID. Keep the **code-post transaction hash** and **mint transaction hash** separate. The former identifies the referenced program; the latter reaches that edition's renderer as `transactionHash`. See [script inputs](/docs/script-api). ## Artist royalty managers Each new art project receives a royalty-manager clone. Read `projectIdToRoyaltyAddress(projectId)` to identify the project's manager rather than assuming all projects share one address. The manager holds incoming mint funds and releases them to configured recipients. Anyone can trigger release, but the caller does not choose new recipients. [Sales and royalties](/docs/royalties) explains artist administration and payee updates. ## Immutable code and project settings The deployed Solidity is fixed reference material, while the contract exposes project-management functions. A lock covers specified fields and the contract owner can unlock it. Price, pause and other settings have their own rules. Read [project management](/docs/project-admin) for precisely what is fixed or changeable. Source basis: the linked deployed sources, unchanged frontend deployment artifacts and `BlockchainProvider` in the art client. Read current chain state for live ownership or configuration. --- # Writing the artwork Source: https://immutables.art/docs/script-api The viewer executes a JavaScript **function body** for each artwork instance. Do not include HTML, an import statement, a top-level module export, or your own `new p5(...)` wrapper in a p5 script. ## Contexts and renderers - `p5js`: the supplied `p` is the p5 instance. Use `p.setup`, `p.draw`, `p.keyTyped` and other instance methods. - `threejs`: the supplied `t` is your instance context; the current viewer supplies `THREE`. Create the scene and renderer and attach its canvas to `props.container`. - `vanillajs`: the supplied `v` is your instance context. Create your own canvas and attach it to `props.container`. - `glsl`: the supplied `g` is your instance context. Provide JavaScript that creates WebGL and compiles shaders; raw GLSL alone is not a complete posted script. Do not assume the same runtime version will exist forever. Preserve the library versions used to validate your release and test the downloadable viewer. GPU output and font rasterization can differ between devices even when the inputs and trait choices agree. ## Edition inputs Implement `context.myCustomRedrawAccordingToNewPropsHandler = props => { ... }`, substituting `p`, `t`, `v` or `g` for `context`. The callback receives: - `transactionHash`: the full `0x`-prefixed hash of the **edition's mint transaction**, not the code-post transaction. - `projectId`: the art project ID. - `editionId`: the edition's number within that project, starting at 1 for a real mint. - `tokenId`: the ERC-721 token number across the art platform. This differs from `editionId`. - `square`: the layout divisor; a single selected edition uses 1. Numeric fields may arrive as strings. - `container`: supplied to the three.js, vanilla and GLSL wrapper for your renderer's DOM output. p5's wrapper manages its own container. The current generic callback does **not** supply a block hash, `prevrandao`, mint timestamp, VRF result, or an authenticated `seed` field. Do not invent those inputs. Extra project-specific data requires an explicitly supported integration. ## Initialization and redraw For p5, create a small canvas in `setup` and use the props callback to configure the edition. Guard against missing props. Create edition-specific state when its identity changes, and handle size changes separately. Avoid registering a new keyboard listener or starting another animation loop every time props arrive. `p.updateWithProps` is bridged to the older props callback in the current viewer, but the callback above is the portable authoring convention for this client. For a non-p5 renderer, put cleanup work on `context.cleanup`; keep requestAnimationFrame IDs in `context._animationId` and dispose GPU resources. A useful sizing pattern is `Math.min(window.innerWidth, window.innerHeight) * 0.8 / Number(props.square)`. Use fixed logical coordinates for the composition and scale to the canvas. Changing phone orientation should not choose new traits. Each grid cell is a separate artwork. Keep state local to the posted function body or its supplied context. Avoid assignments to `window`, replacing browser globals, or mounting unrelated elements into the surrounding app. ## Traits and metadata Report a flat object after the edition's traits are ready: ```javascript console.log('metadata: ', { transactionHash: props.transactionHash, Palette: 'Midnight', Structure: 'Orbit' }); ``` Keep `transactionHash` as the original mint transaction. Do not replace it with your derived seed. Prefer stable strings or finite numbers for traits; do not put a canvas, a cyclic object, current frame, or fluctuating performance measurements in metadata. The current viewer groups reported traits by transaction hash. Multiple editions minted in one transaction can have distinct art when the seed includes edition ID, but that grouping can conflate their statistics. This is a viewer limitation to account for before designing a batch release. ## Deterministic identity and time Use a local seeded stream for persistent composition and traits. `Math.random()` and `crypto.getRandomValues()` are suitable for generating preview inputs, not the permanent identity of a rendered edition. Animation may evolve over frames or time if that is the artwork's design; document its clock, initial state and replay expectations. See the [working starter](/docs/examples), [controls](/docs/controls) and [seed guidance](/docs/randomness). Source basis: `P5Wrapper`, `ThreeWrapper`, `Grid`, `WizardProvider` and `BlockchainProvider` in `clients/art/src/`. --- # Code, ownership and preservation Source: https://immutables.art/docs/storage The work is recreated from its program and edition inputs. Images and hosted metadata make that work convenient to browse; preserving the source and the inputs is what lets another viewer reconstruct it. ## The code page is an NFT Reserving an eligible unclaimed page on **Immutables Code**, currently Immutables.co, mints an ERC-721 page NFT to the reserving account. The page name maps to that token, and the page has its own royalty manager. Artists can hold their project's code-page NFT separately from the art editions they issue. Code posts are immutable entries in the page's history. Posting another revision does not erase an earlier post, and posting content does not mint a separate NFT for every revision. Ownership of the page and copyright or reuse rights in its content are distinct; choose and state the license. The possible future name `code.immutables.art` is a branding direction, not a change to these deployed contract addresses or token identities. ## Where source and edition identity live The code contract's `anyonePostPageTagContent(page, tag, content)` receives the text in **transaction calldata** and emits it in `AddressPostedPageTagContent`. It does not save the full text into a Solidity string mapping for arbitrary later contract reads. The art project's `scriptTransactionHash` points to a particular code-post transaction. The current live client requests that transaction, decodes its three string arguments and extracts the fenced JavaScript. It then reads art mint events and provides each mint transaction hash plus project, edition and token IDs to the renderer. The mint hash is recovered from chain history by the viewer; it is not a random seed variable stored by the mint contract. The project and token mappings remain separate from the historical transactions and logs needed for a full reconstruction. ## Two metadata modes The platform's `useMetadataServer` setting controls `tokenURI`: - **Hosted mode:** return the configured base URI plus the global art token ID. This URL can serve pre-generated JSON from static object storage; it does not require a continuously running application server. - **Contract-generated mode:** return a `data:application/json;base64,...` URI assembled by the contract. It includes project metadata and an image reference. If the project has an image base and extension, the image still points there; otherwise the contract supplies a basic SVG. “Serverless metadata” describes how the JSON is produced, not a claim that every rich preview image or generative renderer is embedded in Solidity. Neither metadata mode executes the JavaScript artwork inside the EVM. The metadata-mode switch is a **platform owner** setting. Artists can manage their own project's image base and extension through the artist/team function. Hosted JSON generation and marketplace caching may need a refresh after a change. ## Current image hosting This repository's `services/metadata-art/` generates static metadata and uploads assets to R2. There is no Cloudflare Worker metadata server in this checkout. Image URLs are formed from a project base URL, the **global token ID**, and an extension such as `.png` or `.gif`—not the project's edition number. Use the [image generator](/image-generator.html) and test the output against live rendering. For an endlessly evolving artwork, an animated thumbnail is a sample of its progression, not the complete work or a claim that its animation repeats. ## Preserve more than a link Historical transaction data must remain obtainable from some source. A deployed immutable contract does not guarantee that every future RPC provider will serve its full historical calldata and logs. Keep the exact posted bytes, transaction receipts/logs, edition inputs, renderer dependencies, styling and external assets. Preserve the chain/network and project identifiers alongside them. The [art download](/immutablesArt.html) packages the available scripts and edition snapshot with a viewer. The [whole-interface download](/immutablesArtApp.html) packages the broader app. They reflect the build's snapshot, not future editions or transfers. Connected writes require a wallet and network; an offline copy is not a way to transact offline. Use the [verification page](/verify) and [hash file](/hashes.txt) to check the exact downloaded bytes. A future on-chain archive extension is [proposed work](/docs/future), not something the current mint method silently provides. Source basis: [code contract](https://etherscan.io/address/0x499f4943fB86717adcE584927E6AB5a172f03001#code), [art contract](https://etherscan.io/address/0xA8A6CB3978e2c4EdcF5A3d0cB3400E1E5D031479#code), `BlockchainProvider.getProjectScript`, and `services/metadata-art/`. --- # What is available today Source: https://immutables.art/docs/future This handbook describes the existing art platform and current client. It does not turn a design proposal into a deployed contract feature. ## Available in the deployed platform Code-page NFTs and historical posts, art projects referencing code transactions, sequential edition mints, project artist/team administration, royalty-manager clones, optional hosted or contract-generated metadata, and the artist-script runtime described here. The touch-control declaration is a **viewer convention**. It adds interface support without changing the deployed art contracts or editing posted artwork. ## Active development and design work The repository has a separate Hardhat mint-gate project under `contracts/new-art/`. Its existence and local tests are not proof that a gate is deployed or configured for a particular release. Verify an actual deployment, permissions and routing before relying on one. The proposed retrofit includes an archive for preserved source and project reserve/token mechanisms. Batch minting, minting into a reserve, token redemption and related sale flows require their own implemented, reviewed and configured contracts. They are not parameters of the deployed `anyoneMintProjectEdition` method. A VRF or delayed randomness/reveal integration is likewise not supplied by the current generic viewer or mint method. An artist needing stronger allocation guarantees should settle that protocol before making release promises. Immutables.co may eventually be presented as `code.immutables.art`. The branding change has not been assumed by these contract instructions. ## Before documenting a new capability as live Verify the deployed address and chain, source and ABI, project configuration, who can bypass or change it, how collectors interact with it, how the viewer reconstructs the result, and what happens when a dependency fails. Update the human chapters and LLM reference together. Repository references: `contracts/new-art/README.md` and `docs/RETROFIT_CONTRACT_SPEC.md`. These are development/design references, not a deployment registry.