# Build an NFT Collection Frontend

ChainRender delivers the **entire frontend** for an NFT collection — mint, gallery, my-collection, and the on-chain
art itself — driven by *your* ERC-721 backend. This guide shows the pattern. It's the same architecture as the
flagship swap app (read live on-chain state + declared write actions), applied to a collection.

## The division of labour (honest)

ChainRender is a fully-on-chain **UI/rendering** framework, not an NFT protocol. So:

- **You bring the ERC-721** — mint, ownership, trading, and an **on-chain `tokenURI`** (the art as `data:` SVG/JSON).
  Use OpenZeppelin, ERC-721A, or your own contract.
- **ChainRender builds the frontend** — it *reads* your contract's state live, *renders* the UI and the on-chain
  art, and turns each user action (mint, reveal, transfer) into a declared, gate-checked transaction to sign.

Nothing here is minted or owned by ChainRender. It's the trustless frontend, exactly like the flagship is the
frontend for a DEX.

## What you get, Grade A

A multi-view app — **Mint / Gallery / My NFTs** — where:

- **Live reads** (`totalSupply`, `mintPrice`, `saleActive`, `balanceOf`) come from *your* contract via the
  `staticread` **CallResolver** — any `view` function, rendered live on-chain.
- **The Mint button** is a **declared action** → your `mint(uint256)`, carrying the mint price
  (the `TRANSFER_VALUE` capability). The runtime constructs the exact calldata; the user sees the decoded action
  before signing; the button can only ever call what it declares.
- **Each token's art** renders through *your* `tokenURI` via the **`NftImageResolver`**, which decodes the on-chain
  JSON/SVG and verifies provenance per token — off-chain pointers are refused, never laundered as on-chain.
- **Grade A**: every read is on-chain, the art is on-chain, no off-chain fetch.

## The shape

```ts
import { buildNftCollectionApp } from "@chainrender/examples/nft-collection-app";

const app = buildNftCollectionApp({
  collection:       "0x…",         // your deployed ERC-721
  callResolver:     "0x…",         // a deployed CallResolver (reads any view fn)
  nftImageResolver: "0x…",         // a deployed NftImageResolver (renders your tokenURI)
  name:    "Cryptic Organisms",
  tagline: "100 fully on-chain generative creatures",
  maxSupply: 100,
  mintPriceWei:  "0x…",            // price in wei, 32-byte hex, for the payable action
  mintPriceLabel: "0.01 ETH",
  user: "0x…",                     // the connected wallet (for My NFTs), or undefined
  galleryTokenIds: [0,1,2,3,4,5,6,7],
});
// app.views = [Mint, Gallery, My NFTs] — compile each, combine with buildTabs([hashes], { shell }), deploy.
```

## The three views

**Mint** — collection name + tagline, a live stat row (minted / max / price / sale status, all read from your
contract), a quantity input, and the payable Mint button.

**Gallery** — a responsive grid; each card renders a token's on-chain art from your `tokenURI`.

**My NFTs** — the connected user's `balanceOf` and their owned tokens (or a "connect wallet" prompt).

## Wiring it to your contract

1. Deploy your **ERC-721** with an **on-chain `tokenURI`** (the art as a `data:` payload).
2. Deploy (or reuse) a **`CallResolver`** and an **`NftImageResolver`**.
3. Plug their addresses into the config. If your view getters differ from the standard names
   (`totalSupply()`, `mintPrice()`, `saleActive()`), adjust the selectors — the builder documents which it assumes.
4. Compile each view to a component hash, combine with `buildTabs`, and deploy. Register a subname if you want a
   `yourcollection.chainrender.eth` address.

## Trading, and the OpenSea question

- **On-chain trade functions** on *your* contract (list, buy, transfer) are just more declared actions — add a
  button for each.
- **Secondary marketplace**: once your ERC-721 + on-chain `tokenURI` exist, **OpenSea and other sites display the
  collection automatically** (the on-chain SVG shows everywhere). Link out to OpenSea for the open market.
- **Interactive art**: the p5/three interactive version lives in *your ChainRender app* (the premium experience).
  On OpenSea, the fully-on-chain **SVG poster** displays; a self-contained interactive `animation_url` is optional
  extra work on your side. See **[Rich Media: p5.js & three.js](../concepts/rich-media-p5-three.md)**.

## Try it in the builder

The **[Visual Builder](https://chainrender.org/builder)** ships an **"NFT Collection (mint + gallery)"** template —
load it to see the multi-view app, adapt the addresses, grade it, and deploy.

## Related
- **[Declare an Action](./declare-action.md)** · **[Bind Live On-Chain Data](./bind-data.md)** ·
  **[Multi-View App](./multi-view-app.md)** · **[On-Chain NFT Media](../concepts/visual-media.md)**
