Code projects

A code project is an ABX contract whose content is a program. Its output follows the determinism contract, (content, params, environment) -> output.

Two custody modes

  • Directory. The code is an off-chain build directory with an index.html entry, on IPFS, Arweave, or a URL. The on-chain surface is the code collection field, which holds a locator only, never inline bytes.
  • Template. The code is stored on-chain in chunks, through the On-Chain Script and Dependencies extensions. Dependency index 0 is the runtime, by convention. A generator assembles the dependencies in order, injects the token data, and concatenates the script chunks.

tokenData

The program receives one flat object, tokenData. It is the contract-scope and token-scope parameters merged, with token scope winning, and read-time hook entries applied last. Each value is decoded to its canonical string form.

jsonc
{
  "chainId": 1,
  "contractAddress": "0x1a2b...",
  "tokenId": "42",
  "seed": "0x9f31...",
  "palette": "#0e1a40",
  "density": "0.85"
}

chainId, contractAddress, tokenId, and seed are reserved keys. seed is present only when a seed source assigned it. The serialization is canonical: JSON, keys sorted, no insignificant whitespace, UTF-8, because it is hashed as part of an effect's inputs.

tokenData reaches the program three ways: injected as a window.abxTokenData global (template, or a resolver-served directory), carried in the URL as a base64 abx query parameter (directory, budgeted at about 8 KB), or passed to a render node as input. A runtime companion, abx.js, resolves the token data from the injected global, then the query parameter, then RPC. It also exposes abx.traits({...}) to report traits and abx.done() to signal that output is complete. abx.js is a convention, not protocol.

Seeds

Mint-time randomness is configuration, through the Seed Source extension. A contract stores a seed-source address; at mint it calls IAbxSeedSource.seed(tokenId, to) and stores the result as the token's seed parameter. The canonical source is AbxSeedSource, one shared pseudorandom source per chain. A project can point at any contract that satisfies the interface, such as a commit-reveal or an artist-curated source. A seed is settled once assigned, and immutable unless a parameter schema authorizes reconfiguration.

On-chain rendering

The canonical field renderer, AbxGenerator, produces the animation field for both custody modes:

  • Template branch. With script chunks present, it emits a full HTML document: the token data, abx.js, the dependencies in order, and the script chunks. It is chain-complete when every dependency resolves to on-chain bytes.
  • Directory branch. With a code field present, it emits a locator with the token data in the query string, served through a gateway.

onChainStatus(token) reports which branch was taken, whether the project is chain-complete, and any unresolved dependency references. A static image cannot be produced on-chain, because rendering a program to a PNG needs a browser.

Traits

Traits have two homes. By default they are computed at render time: the script reports them with abx.traits(...), and the render effect captures and stores them off-chain. A project can instead put traits on-chain by setting the attributes field to a renderer representation, so a field renderer computes them. When both exist, they are unioned, and the on-chain value wins on a trait_type conflict.

How metadata is derived

  • animation_url: an explicit animation field wins; otherwise, if code is present and not suppressed, the resolver's live-view route; otherwise it is omitted.
  • image: an explicit image field wins; otherwise the latest bound render.image effect output; otherwise a deterministic placeholder.

Until an effect produces render.image, the token shows the deterministic placeholder. When a project renders is the artist's choice.