@artblocks/abx-cli 0.1.0-alpha.3 → 0.1.0-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.js +332 -14
- package/dist/main.js.map +1 -1
- package/dist/preview.d.ts +63 -0
- package/dist/preview.d.ts.map +1 -0
- package/dist/preview.js +483 -0
- package/dist/preview.js.map +1 -0
- package/package.json +6 -3
- package/skill/SKILL.md +49 -5
- package/skill/reference/code-projects.md +35 -0
package/skill/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: abx-self-host
|
|
|
3
3
|
description: Launch and operate a self-hosted ABX NFT end to end with the ABX CLI (`abx`) on testnet — a 1/1 (`abx deploy`), a multi-token Series from a folder of media (`abx deploy-series`), or a generative/code drop (`abx deploy-code`). Covers on-chain vs off-chain metadata, storage custody (local disk, S3/R2, IPFS, Arweave), deploy + mint (now or pre-warmed at a predicted address), rendered thumbnails and on-chain traits for code art, primary sales via the shared fixed-price minter, and owner ops (transfer, refresh, re-point URIs, royalties, lock fields, pause/unpause, supply cap, delegate minting). Use when the user wants to self-host an ABX project, take an image to an NFT on testnet, deploy a collection from a folder of images, launch generative/code art, mint or run a primary sale, refresh a listing, operate a project they launched, choose a storage backend, or stand up hosting they own.
|
|
4
4
|
compatibility: Drives the abx CLI (@artblocks/abx-cli). Co-versioned with it — install/refresh with `abx skill install` so this skill matches the CLI's `abx version`. Requires Node 22.5+.
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.1.0-alpha.
|
|
6
|
+
version: "0.1.0-alpha.5"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# ABX Self-Host Toolkit (`abx`)
|
|
@@ -14,16 +14,18 @@ L3 agentic surface: image → live self-hosted NFT the creator owns — a **1/1*
|
|
|
14
14
|
|
|
15
15
|
## Read first (every session)
|
|
16
16
|
|
|
17
|
-
- **YOU run the `abx` commands — never tell the creator to run one.** You have a shell; use it. Run `doctor`, `ls`, `--dry-run`, `tokenuri`, `state`, `refresh`, `balance`, etc. yourself and read the output — don't paste a command and wait for them to run it or copy back results. The creator's
|
|
17
|
+
- **YOU run the `abx` commands — never tell the creator to run one.** You have a shell; use it. Run `doctor`, `ls`, `--dry-run`, `tokenuri`, `state`, `refresh`, `balance`, etc. yourself and read the output — don't paste a command and wait for them to run it or copy back results. The creator's hands-on steps are approving in their **browser wallet** (`--sign`), giving you a value you asked for (their address, a name), and **looking at the art in `abx preview`** — you run that command, but the URL it prints is theirs to open and play with ([Phase 0](#phase-0--make-the-work-first-skip-every-gate-below-until-its-good)). Even "next steps" after a deploy: **run the read-only ones** (`tokenuri` to prove it resolves) and **offer to run** the actions (`refresh`, `unpause`, `mint`) — don't hand over a list of commands to run. Exceptions: a genuinely interactive/again-in-their-env command (an OS login, `gcloud auth`), and the **in-chain Solidity lane's Foundry step** (`forge build/test/deploy` a renderer — `abx` never compiles/deploys Solidity; see [Code projects](#code-projects-generative--code-based-drops)) — then run it if you have the tool, else hand it over.
|
|
18
18
|
- **Skill ⇄ CLI version must match.** This skill is co-versioned with the `abx` CLI. Run `abx version` and compare it to this file's frontmatter `metadata.version` (top of SKILL.md). If they differ, this skill is stale for the installed CLI — run `abx skill install` to resync, then reload the skill before continuing. (`abx` also prints a drift nudge on its own when it notices.)
|
|
19
|
+
- **Resolve the CLI before you install anything — local beats global.** Probe `npx --no-install abx version` (project-local), then `abx version` (global); only install if both miss, and default to the **project-local** `npm install --save-dev @artblocks/abx-cli`. The package is `@artblocks/abx-cli`; `@artblocks/abx-sdk` is the library and ships no binary. Full ladder + why `--no-install` matters → [Setup](#setup--environment).
|
|
19
20
|
- **`abx doctor` first, always** — full preflight (Node, pnpm, RPC, signing key, storage). Fix any ✗ before deploying ([Setup](#setup--environment)). A missing public-base-url is not a "set up IPFS" signal: for tiny art go on-chain, for larger art pick an off-chain backend — see [Quick start](#quick-start).
|
|
20
21
|
- **Never collect secrets in chat.** Keys, `PINATA_JWT`, S3 secrets → the project's `.env`. The Arweave/Turbo key is a CLI-managed file (`.abx-self-host/arweave-key.json`) — never paste it. Name the var/file; never take the value.
|
|
21
22
|
- **Testnet only today** — every launch is on a testnet: **Base Sepolia by default** (`ABX_CHAIN` unset), with **Sepolia** also shipped (`ABX_CHAIN=sepolia`). Say "testnet"; don't imply mainnet. **Testnet IS the preview + e2e environment**: it runs the *real* wiring (renderers, generator, on-chain tokenURI assembly), so a creator should deploy there, inspect the actual result (`abx tokenuri` / the live view / `abx verify`), confirm it looks right, and only *then* go to mainnet — no separate local "preview" is as faithful as the real testnet drop, and a testnet deploy is ~free + ~minutes. **One cross-chain gotcha: on-chain library deps (`--dep p5@…`) resolve to on-chain bytes only where an Art Blocks dependency registry exists — that's Sepolia, NOT Base Sepolia.** A no-dependency script (vanilla JS/GLSL) goes fully on-chain on either; a drop that needs a registry-hosted library on-chain must target `ABX_CHAIN=sepolia` (or run the resolver lane).
|
|
22
23
|
- **Scope today = ERC-721 on testnet.** The shipped token standard is **ERC-721** (a 1/1, or a **Series** for many tokens), on Base Sepolia (default) or Sepolia via `ABX_CHAIN`. There is **no `--chain` flag (pick the chain with `ABX_CHAIN`) and no `--erc1155`/`--standard` flag** — don't invent one; mainnet + ERC-1155 are roadmap, not something you flip here. Map the ask to what ships: **"an edition of N" / "N copies"** → an ERC-721 **Series** (`abx deploy-series`, N tokens; for a priced sale of one piece, a 1-token Series). If a creator needs a true ERC-1155 shared-supply edition or an unsupported chain, say plainly it's not in the toolkit today rather than fabricating a recipe.
|
|
23
|
-
- **
|
|
24
|
+
- **Is the work finished yet?** If the creator is still *making* the piece, you're in **[Phase 0](#phase-0--make-the-work-first-skip-every-gate-below-until-its-good)** — iterate on the art and keep every deploy question off the table until they say ship. The gates below apply to launching something that already exists.
|
|
25
|
+
- **Two gates decide everything: (1) demo or real? (2) who signs?** Settle both first — *once there's something to launch*.
|
|
24
26
|
- **Confirm the full config before any on-chain write** ([readout](#confirm-before-sending)); wait for go-ahead. Never invent a field silently (name/symbol from filename, an auto description) — show it, flag it `inferred`.
|
|
25
27
|
- **Safe to explore:** `abx <cmd> --help` and `abx deploy --dry-run` never send. You never run a real write just to learn flags.
|
|
26
|
-
- **`deploy` returns; `demo`/`serve` block** (they serve) — background them or warn.
|
|
28
|
+
- **`deploy` returns; `demo`/`serve`/`preview` block** (they serve) — background them or warn. Background `abx preview` and relay its URL, then keep working while the creator looks; `--shoot` is the one preview mode that exits on its own.
|
|
27
29
|
|
|
28
30
|
## Which command — what are you launching?
|
|
29
31
|
|
|
@@ -39,6 +41,25 @@ Route by the **content** first, then apply the gates below. The three paths diff
|
|
|
39
41
|
|
|
40
42
|
**Planning a priced primary sale? Decide 1/1 vs Series BEFORE deploying — it's irreversible.** The shared fixed-price minter sells a **Series** (mint-on-purchase); a plain `abx deploy` **1/1 has no minter/pause/payee**, so its only post-mint move is `abx transfer` (settle an off-chain sale). To run a native fixed-price sale of even a *single* piece, deploy it as a **1-token Series** (`abx deploy-series --count 1`), not a 1/1. abx has **no secondary-listing feature** — reselling a held token means an external marketplace or a manual `transfer`. Full detail: [operating.md → Selling](reference/operating.md#selling--the-shared-fixed-price-minter).
|
|
41
43
|
|
|
44
|
+
## Phase 0 — make the work first (skip every gate below until it's good)
|
|
45
|
+
|
|
46
|
+
**If the creator is still making the piece, you are in the studio, not in a deploy. Stay there until they say ship.** The gates and decisions below are for *launching* something that already exists — reaching for them while someone is still designing is the single most common way this skill feels wrong to use. A real session: the creator said *"I want to work on one with you"* and got asked about metadata resolution, hosting, and wallet ownership before a single pixel existed. They had to push back with *"let's work on actually designing the piece together first."* Don't make them.
|
|
47
|
+
|
|
48
|
+
**Which mode are you in?**
|
|
49
|
+
- **They handed you a finished file** (`sketch.js`, a build dir, an image folder) → skip this section, go to [Gate 1](#gate-1--demo-or-real-launch).
|
|
50
|
+
- **They brought an idea, a reference, a vibe, or "let's make one together"** → Phase 0. The deploy is a footnote at the end of an afternoon of work; treat it that way.
|
|
51
|
+
|
|
52
|
+
**During Phase 0, these are OFF the table** — do not ask, do not "just quickly confirm," do not pre-emptively lay out the tradeoffs: hosting/lane, thumbnails, traits-on-chain, storage permanence, wallet address, supply cap, royalties, mint count, name/symbol. Every one of them is answerable in five minutes *after* the art is right, and asking early reads as pressure to ship something half-made. The **one** exception is a constraint that changes what you'd *write*: if they want an on-chain library (`p5`), say early that on-chain deps mean `ABX_CHAIN=sepolia` — that's an authoring constraint, not a deploy decision.
|
|
53
|
+
|
|
54
|
+
**The loop** — depth + the `--shoot` details → [reference/code-projects.md → Studio loop](reference/code-projects.md#studio-loop--iterate-on-the-art-before-you-deploy-anything):
|
|
55
|
+
|
|
56
|
+
1. **Write against the real runtime contract from the first draft** — `abx.tokenData.seed` for randomness, `abx.traits({…})` for features. Not `Math.random()` "for now": a piece prototyped on `Math.random()` looks finished and then deploys as N identical tokens, and retrofitting the seed late means re-tuning every visual you just approved.
|
|
57
|
+
2. **Run `abx preview --script art.js` and give the creator the URL.** It serves the *same document the generator serves* (real `abx.js`, real tokenData) on `localhost:8788`, so they get a seed shuffle, real inputs for every `--schema` PostParam, a live traits readout, and `/grid` for N seeds at once. **This is the one place you hand over a link instead of running it for them** — the art is theirs to judge, and an animated piece cannot be judged from a screenshot. Don't hand-roll a preview page; a stub you write yourself will run a sketch that reads its seed wrong.
|
|
58
|
+
3. **Edit and tell them to refresh.** The program is re-read from disk per render — no restart, no watcher. To check your own work between rounds (you have no browser), `abx preview --script art.js --shoot ./frames` renders the same document headlessly and flags the two silent killers: no traits reported, or identical traits across every seed.
|
|
59
|
+
4. **Take feedback and go again.** Expect several rounds. Rounds are the point — "add faces to the shapes" is a normal Phase 0 request, not scope creep.
|
|
60
|
+
|
|
61
|
+
**Exit only on an explicit ship signal** ("let's deploy this", "I'm happy with it"). Then run `abx inspect <script>` and open the deploy decisions — and say plainly that some are irreversible, so it's worth a few minutes ([Code projects](#code-projects-generative--code-based-drops)). If *you* feel the pull to start the deploy conversation while they're still iterating: don't. Ask what they want to try next.
|
|
62
|
+
|
|
42
63
|
## Gate 1 — demo or real launch?
|
|
43
64
|
|
|
44
65
|
| | **Demo** (`abx demo`) | **Real launch** (`abx deploy` → operate) |
|
|
@@ -279,7 +300,30 @@ Once it's live, cover these in plain language; don't wait to be asked.
|
|
|
279
300
|
|
|
280
301
|
## Setup + environment
|
|
281
302
|
|
|
282
|
-
`abx`
|
|
303
|
+
`abx` needs **Node ≥ 22.5** at runtime (the projection store uses built-in SQLite).
|
|
304
|
+
|
|
305
|
+
### Find `abx` before you install it — local first, then global
|
|
306
|
+
|
|
307
|
+
**Resolve in this order and use the first hit.** Don't jump to a global install; a project-local CLI is pinned in the creator's `package.json` (reproducible, and what `abx skill install` version-locks against), so it wins whenever it exists:
|
|
308
|
+
|
|
309
|
+
```bash
|
|
310
|
+
npx --no-install abx version # 1. project-local (./node_modules/.bin/abx) — PREFER this
|
|
311
|
+
abx version # 2. a global install already on PATH
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
- **`--no-install` is mandatory on that probe.** The bare `abx` name on npm is an **unrelated squatted package** — a plain `npx abx` with nothing local would *download that*, not this CLI. `--no-install` makes the probe fail cleanly instead.
|
|
315
|
+
- In the **abx source repo** (contributor), neither applies: use `pnpm abx <cmd>`, which runs the live `tsx` source.
|
|
316
|
+
|
|
317
|
+
**Nothing found → install.** The package is **`@artblocks/abx-cli`** (not `@artblocks/abx-sdk` — that's the library, and installing it gets you no `abx` binary; a real session lost a cycle to exactly that mistake):
|
|
318
|
+
|
|
319
|
+
| Situation | Install | Then invoke as |
|
|
320
|
+
|---|---|---|
|
|
321
|
+
| The creator has a project dir (a `package.json`) — **default** | `npm install --save-dev @artblocks/abx-cli` | `npx abx …` |
|
|
322
|
+
| No project, or they asked for a machine-wide tool | `npm install -g @artblocks/abx-cli` | `abx …` |
|
|
323
|
+
|
|
324
|
+
Ask before installing **globally** — it's a machine-wide change to their PATH, and the per-project install is the reversible one. A project install needs no permission beyond the usual.
|
|
325
|
+
|
|
326
|
+
Whichever you land on, **keep using that same invocation for every command in the session** (`npx abx …` vs `abx …`) — don't mix them, or you'll silently drive two different CLI versions. Then run `abx doctor` (preflight: signing key/wallet, RPC, canonical factory, storage).
|
|
283
327
|
|
|
284
328
|
`.env` (in the creator's project dir) = **secrets only**:
|
|
285
329
|
- **Signing:** a key (`SEPOLIA_FUNDED_PK` / `ABX_DEPLOYER_PK` / `SEPOLIA_WALLET_PK`) is needed ONLY for hot/unattended signing. If the creator owns a wallet, prefer **`--sign`** — no key in `.env`. `doctor`'s missing-key ✗ is **not fatal** on the `--sign` path.
|
|
@@ -45,6 +45,41 @@ When a creator arrives with an *idea* and you write the program, it must read it
|
|
|
45
45
|
|
|
46
46
|
**`abx inspect <script>` is your author-time check** — iterate the script against it before picking a lane: its **PostParams** list must show every collector key you intend (if it says "none detected" but you meant `palette` to be collector-set, you're reading it the wrong way), and its **Traits** line must not say "no traits reported" if you want filterable traits. (A Solidity in-chain renderer is a *different* contract — see [In-chain Solidity SVG](#in-chain-solidity-svg--the-zero-dependency-lane); the `abx.js` contract above is for a JS `--script`/`--code-dir` program.)
|
|
47
47
|
|
|
48
|
+
## Studio loop — iterate on the art before you deploy anything
|
|
49
|
+
|
|
50
|
+
[← Phase 0 in SKILL.md](../SKILL.md#phase-0--make-the-work-first-skip-every-gate-below-until-its-good). When the creator is still designing, your job is to make the work **visible, interactive, and fast to change**. One command does it:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
abx preview --script art.js --schema "palette:HexColor:TokenOwner" # → http://localhost:8788
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Give the creator the URL and let them drive.** This is the one place in the toolkit where handing over a link is right — the art is theirs to judge, and a browser they control is the only honest way to judge it. The studio gives them a seed shuffle, real inputs for every PostParam they declared, a live traits readout, and `/grid` for N seeds at once. `/view` is the bare document.
|
|
57
|
+
|
|
58
|
+
**Why a server and not a screenshot sweep:** a still flattens every time-based piece. Plenty of generative work animates, and `abx.done()` exists *because* stills need a settle point — so a proof sheet of an animated piece is a set of arbitrary frozen frames presented as the work. The server also makes PostParams tangible (a color picker that re-renders beats any explanation of governed params), and it costs no Chromium download.
|
|
59
|
+
|
|
60
|
+
**It serves the same document the generator serves** — the real `abx.js`, the real canonical tokenData shape, the real dependency tags — with a synthetic seed in place of a minted one. So what they approve is what deploys. (This is why you should not hand-roll a preview page: a stub you write yourself defines its own `abx` surface, and will happily run a sketch that reads its seed the wrong way.)
|
|
61
|
+
|
|
62
|
+
**The program is re-read from disk on every render**, so the loop is: edit `art.js` → tell them to refresh → take feedback → edit again. No restart, no watcher, no rebuild.
|
|
63
|
+
|
|
64
|
+
**When you need to see it yourself** — you have no browser, and "how does it look?" every round is a bad experience for them:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
abx preview --script art.js --shoot ./frames --count 9 # PNGs + traits.json, then exits
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Same server, same document, headless. Needs Playwright + Chromium (`npm i -D playwright && npx playwright install chromium`); the interactive lane needs neither. **Read the PNGs** — don't report on art you haven't looked at. `--shoot` also flags the two silent killers for you: no frame reporting traits (⇒ no marketplace `attributes` on any lane), and identical traits across every seed (⇒ the sketch isn't reading `abx.tokenData.seed`, so the drop mints N identical tokens).
|
|
71
|
+
|
|
72
|
+
Use both: `--shoot` to check your own work between rounds, the live URL as what the creator actually looks at.
|
|
73
|
+
|
|
74
|
+
**What preview is NOT.** It injects the token data itself, so it will run a sketch that reads its seed the wrong way — and a piece that only ever renders one seed correctly still looks fine here. Neither check that follows is optional:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
abx inspect art.js # the wiring check: are traits + PostParams actually read/reported?
|
|
78
|
+
abx deploy-code --script art.js --onchain-uri --dry-run # the lane + surfaces check
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
And a **testnet deploy remains the faithful end-to-end** (the real generator, the real assembled document, the real seed from the chain). Both come after the art is settled.
|
|
82
|
+
|
|
48
83
|
## What a code project requires you to run — and keep running (say this up front)
|
|
49
84
|
|
|
50
85
|
A code project's art depends on live on-chain state (the per-token `seed`, mutable PostParams), and *something* must read that state and inject it at view time. That something is a **resolver you run** — **unless** you take the fully-on-chain lanes (`--onchain-uri` for the tokenURI+animation, `--image-base` for a deterministic off-chain thumbnail, `--attributes-renderer` for on-chain traits), which can eliminate the metadata resolver entirely. When a resolver *is* in play, it's three pieces of ongoing infrastructure — lay them out plainly before they commit:
|