# 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](params.md) 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](effects.md) 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.
