@artblocks/abx-cli 0.1.0-alpha.32 → 0.1.0-alpha.34

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.
Files changed (55) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/dist/capabilities.d.ts +94 -0
  3. package/dist/capabilities.d.ts.map +1 -0
  4. package/dist/capabilities.js +135 -0
  5. package/dist/capabilities.js.map +1 -0
  6. package/dist/commands/deploy.d.ts.map +1 -1
  7. package/dist/commands/deploy.js +13 -17
  8. package/dist/commands/deploy.js.map +1 -1
  9. package/dist/commands/feedback.d.ts +7 -0
  10. package/dist/commands/feedback.d.ts.map +1 -0
  11. package/dist/commands/feedback.js +147 -0
  12. package/dist/commands/feedback.js.map +1 -0
  13. package/dist/commands/reads.js +1 -1
  14. package/dist/commands/reads.js.map +1 -1
  15. package/dist/commands/scaffold.d.ts +9 -1
  16. package/dist/commands/scaffold.d.ts.map +1 -1
  17. package/dist/commands/scaffold.js +60 -13
  18. package/dist/commands/scaffold.js.map +1 -1
  19. package/dist/commands/service.d.ts.map +1 -1
  20. package/dist/commands/service.js +5 -4
  21. package/dist/commands/service.js.map +1 -1
  22. package/dist/flag-allowlists.d.ts.map +1 -1
  23. package/dist/flag-allowlists.js +19 -0
  24. package/dist/flag-allowlists.js.map +1 -1
  25. package/dist/main.js +45 -11
  26. package/dist/main.js.map +1 -1
  27. package/dist/ownerops.d.ts +3 -3
  28. package/dist/ownerops.js +5 -5
  29. package/dist/ownerops.js.map +1 -1
  30. package/dist/remote.d.ts +5 -1
  31. package/dist/remote.d.ts.map +1 -1
  32. package/dist/remote.js +31 -2
  33. package/dist/remote.js.map +1 -1
  34. package/dist/scaffold.js +1 -1
  35. package/dist/scaffold.js.map +1 -1
  36. package/dist/update-check.d.ts +6 -1
  37. package/dist/update-check.d.ts.map +1 -1
  38. package/dist/update-check.js +40 -17
  39. package/dist/update-check.js.map +1 -1
  40. package/package.json +6 -6
  41. package/skill/SKILL.md +174 -526
  42. package/skill/agents/openai.yaml +4 -0
  43. package/skill/reference/capabilities.md +171 -285
  44. package/skill/reference/code.md +210 -0
  45. package/skill/reference/creator-token.md +90 -95
  46. package/skill/reference/deploy.md +167 -0
  47. package/skill/reference/diagnose.md +165 -0
  48. package/skill/reference/hosting.md +148 -126
  49. package/skill/reference/operate.md +181 -0
  50. package/skill/reference/services.md +76 -0
  51. package/skill/reference/setup.md +108 -62
  52. package/skill/reference/code-projects.md +0 -368
  53. package/skill/reference/decisions.md +0 -182
  54. package/skill/reference/operating.md +0 -220
  55. package/skill/reference/troubleshooting.md +0 -65
@@ -0,0 +1,181 @@
1
+ # Operating an existing ABX project
2
+
3
+ Use this reference for inspection, minting and sales, transfers, fields, gateways, URI pointers,
4
+ royalties, supply, attachments, refreshes, ownership transfer, and locks.
5
+
6
+ ## Contents
7
+
8
+ - [Read before writing](#read-before-writing)
9
+ - [Mint and run primary sales](#mint-and-run-primary-sales)
10
+ - [Transfer tokens and authority](#transfer-tokens-and-authority)
11
+ - [Operate metadata and data](#operate-metadata-and-data)
12
+ - [Manage economics and supply](#manage-economics-and-supply)
13
+ - [Lock precisely](#lock-precisely)
14
+
15
+ ## Read before writing
16
+
17
+ Never infer contract type or current authority from the original launch notes. Read the contract:
18
+
19
+ ```bash
20
+ abx state <address>
21
+ abx tokens <address> --json
22
+ abx contracturi <address>
23
+ abx tokenuri <address> --token <id>
24
+ abx verify <address> --json
25
+ ```
26
+
27
+ Use `abx status` or its remote form for projection/render lifecycle. Record active chain, detected
28
+ family, owner/admin, supply and pause state, minter/payee, royalty/cap, URI renderer/pointers, code
29
+ dependencies, schemas/hooks, and lock state.
30
+
31
+ Before every write, run its help and dry-run form when available. Confirm sender, target, value,
32
+ token/id/amount, and permanence. Let the CLI validate contract type; do not send raw ABI calls to make
33
+ an operation fit the wrong family.
34
+
35
+ ## Mint and run primary sales
36
+
37
+ `abx mint` follows the detected family:
38
+
39
+ - A 1/1 issues its single token.
40
+ - A Series mints the next id in order; `--count` can mint multiple sequential ids.
41
+ - An edition requires `--token-id` except where the contract has only the single 1/1-edition id, and
42
+ uses `--amount` for copies. `--count` is not an edition synonym.
43
+
44
+ Confirm the recipient. Minting may trigger a transfer hook; a hook that vetoes mint will revert the
45
+ whole transaction.
46
+
47
+ ### Shared fixed-price minter
48
+
49
+ Use the shared minter commands for ordinary ETH primary sales:
50
+
51
+ 1. `abx minter configure <token> …` sets price and allocation. Editions require a token id and use a
52
+ per-id sale configuration.
53
+ 2. `abx set-minter <token> --minter <address>` authorizes the minter.
54
+ 3. `abx set-primary-payee <token> --payee <address>` declares payout.
55
+ 4. `abx unpause <token>` opens minting when the family supports the pause gate.
56
+ 5. `abx minter show <token> …` verifies the public sale state.
57
+ 6. `abx minter buy <token> …` is the public purchase path; editions use quantity and token id.
58
+
59
+ Do not call a sale live until price units, allocation, payee, minter address, pause state, and a
60
+ representative purchase are verified. `abx mint-page` scaffolds a client for the shared minter; it does
61
+ not configure the on-chain sale for you.
62
+
63
+ Use a custom minter for auctions, allowlists, raffles, free claims, ERC-20 pricing, or other issuance
64
+ rules. The custom contract calls the canonical token's mint authority; the token itself remains a
65
+ factory clone. Read [capabilities.md](capabilities.md).
66
+
67
+ ## Transfer tokens and authority
68
+
69
+ `abx transfer` moves token ownership/copies, not contract administration.
70
+
71
+ - A 721 transfer names token id and destination.
72
+ - An edition transfer names token id, amount, destination, and source holder because an id can have
73
+ multiple holders.
74
+ - Creator-token validation or a transfer hook may reject the move. Diagnose the actual revert; do not
75
+ bypass or clear an enforcement mechanism without the owner's explicit intent.
76
+
77
+ `abx set-admin --to <address>` transfers contract authority. Treat it as a high-risk, potentially
78
+ irrecoverable handoff:
79
+
80
+ 1. Verify the recipient is correct for the active chain.
81
+ 2. Inventory unfinished operations and unlocked surfaces.
82
+ 3. State which powers move and which external controllers remain separate.
83
+ 4. Receive exact human confirmation.
84
+ 5. Execute once, then read state from chain to prove the new owner.
85
+
86
+ Never interpret a token transfer as a sale listing. ABX has no secondary order book; a marketplace or
87
+ manual transfer handles secondary exchange.
88
+
89
+ ## Operate metadata and data
90
+
91
+ ### URI pointers and renderers
92
+
93
+ Use `set-token-uri`, `set-contract-uri`, and `set-renderer` only after reading the current configuration
94
+ and verifying the destination. Switching `set-renderer --off` can place an HTTP resolver in front of
95
+ content that remains stored on-chain. Switching to the canonical renderer makes configured on-chain
96
+ fields self-resolving when the contract supports them.
97
+
98
+ Never hand-build a resolver path. Read `tokenURI`/`contractURI`, decode it, and follow what the
99
+ contract actually returns. A correct-looking URL constructed from memory is not evidence.
100
+
101
+ ### Fields
102
+
103
+ `abx set-field` writes one metadata field representation at token or collection scope. Representations
104
+ include inline data, reader/chunk pointers, hashes, public locators, and renderer pointers as supported
105
+ by the contract. Collection-scope values act as shared defaults; token-scope values override them.
106
+
107
+ Use reserved fields such as description, attributes, creator, license, display notes, and links
108
+ according to command help. Verify the resulting provenance in decoded metadata. On-chain-wins means a
109
+ new on-chain value can intentionally supersede a resolver projection.
110
+
111
+ ### Gateways
112
+
113
+ `abx set-gateway` changes the serving prefix for IPFS/Arweave locator representations without moving
114
+ the content. Verify a representative locator through the new gateway before changing it. A gateway
115
+ repoint is not a re-upload and does not change the committed CID/transaction id.
116
+
117
+ ### Attachments versus parameters
118
+
119
+ `abx attach <addr> <key> <locator>` records a named artifact. The resolver exposes the complete
120
+ artifacts list and `/data/<key>` retrieval. Bare on-chain metadata cannot enumerate arbitrary field
121
+ keys, so consumers need a resolver to discover all attachments even when each locator is durable and
122
+ hash-anchored.
123
+
124
+ PostParams are different: the parameter store enumerates schemas and values on-chain. Read schemas
125
+ with `state` and values with `tokens --json`. Parameters do not require a resolver merely to be
126
+ canonical or enumerable.
127
+
128
+ ### Refresh and URI events
129
+
130
+ `abx refresh` asks external marketplaces to fetch metadata again; it does not fix the metadata or
131
+ mutate canonical state. First prove that the current URI resolves and returns the intended document.
132
+ For editions, `ping-uri` re-emits native URI events for selected ids after a repoint. Use the smallest
133
+ id set needed and verify the new path before signalling indexers.
134
+
135
+ ## Manage economics and supply
136
+
137
+ Use `set-royalty` to change receiver/rate within the collection's permanent royalty ceiling. Use
138
+ `set-royalty-cap` only to lower that ceiling. State the old and new values and confirm the irreversible
139
+ loss of future headroom.
140
+
141
+ Series supply caps and edition per-id caps are monotonic downward. Read current minted supply before
142
+ lowering a cap; never propose a value below already minted supply. For editions, name the id and
143
+ distinguish its per-id cap from aggregate collection supply.
144
+
145
+ Pause/unpause controls the supported mint gate, not transfers or every external minter behavior.
146
+ Read state after changing it.
147
+
148
+ Primary payee declares sale proceeds; royalty receiver handles secondary royalty reporting. Keep them
149
+ separate. Changing one does not update the other.
150
+
151
+ ## Lock precisely
152
+
153
+ Lock last, after production-path verification. Every lock freezes a different surface:
154
+
155
+ | Lock | Freezes | Does not necessarily freeze |
156
+ |---|---|---|
157
+ | `lock-field` | one token/collection field representation | other fields, URI pointer, program, params |
158
+ | `lock-uri` | URI configuration/pointer at selected scope | program/dependencies/params/hooks |
159
+ | `lock-script` | code-project script chunks | dependencies, metadata, params, external renderer code |
160
+ | `lock-dependencies` | dependency list and registry pointer | bytes returned later by a live registry entry |
161
+ | `lock-param-hooks` | configure/transfer/augment addresses | behavior behind an upgradeable address |
162
+ | governed schema/value lock | writes governed by that schema/key | unrelated or ungoverned params; some inherited defaults |
163
+ | ownership transfer | future owner-only authority at this contract | powers held by external minters/hooks/providers |
164
+
165
+ For a code project, metadata locks alone do not freeze the program. A strong freeze normally requires
166
+ script, dependency, relevant field/URI, hook, and governed-parameter decisions, plus immutable external
167
+ renderer/hook/dependency deployments.
168
+
169
+ Important qualifications:
170
+
171
+ - An ungoverned parameter remains writable despite metadata locks.
172
+ - A schema-welded token value is stronger than a collection default inherited by many tokens; the
173
+ recovery path may still allow a poisoned collection default to be cleared.
174
+ - A registry dependency may return different bytes behind a frozen reference.
175
+ - A locked pointer to an upgradeable proxy fixes the address, not its behavior.
176
+ - A transfer-hook address represents a standing ability to veto mints/transfers. Freezing an empty
177
+ hook set is the proof that this power cannot later be added.
178
+
179
+ Use `abx verify` and direct state reads to enumerate what remains mutable. Describe the guarantee as
180
+ specific stored values and addresses that can no longer change; do not promise immutable output unless
181
+ every live input and external implementation has actually been bounded.
@@ -0,0 +1,76 @@
1
+ # First-party services and feedback
2
+
3
+ Use this reference for the public ABX service, API-key signup, hosted resolver/rendering, or feedback.
4
+ For provider-independent hosting and migration, also read [hosting.md](hosting.md).
5
+
6
+ ## First-party service
7
+
8
+ The documented endpoints are:
9
+
10
+ - documentation: `https://docs.abx.io`
11
+ - service: `https://services.abx.io`
12
+ - verified signup: `https://services.abx.io/signup`
13
+
14
+ The first-party provider has the built-in remote name `abx`:
15
+
16
+ ```bash
17
+ abx remote abx
18
+ ```
19
+
20
+ It needs `ABX_SERVICES_API_KEY` in the project's ignored `.env`; it does not need
21
+ `ABX_REMOTE_ABX_URL`. Signup asks for a name and email, sends a short-lived verification code, then
22
+ returns an API key after the email is verified. Never request an access code, paste the key into a
23
+ command or agent instruction file, or expose it in feedback. An already verified email reuses its
24
+ account and may receive another key, subject to the service's active-key limit.
25
+
26
+ The service currently provides hosted resolution and managed rendering to any verified free API key.
27
+ That entitlement may later become paid to cover infrastructure. Say so when it affects a durable
28
+ hosting choice, and keep the exit route explicit: the same remote-service contract supports another
29
+ provider or a creator-operated resolver/effects deployment. Do not promise future pricing, quotas, or
30
+ continued free hosting.
31
+
32
+ Before depending on hosted behavior, inspect the live descriptor with `abx remote abx`; do not infer
33
+ capabilities from this file. Use `--remote abx` on commands that accept a managed remote and verify
34
+ the resulting public surfaces as described in [hosting.md](hosting.md).
35
+
36
+ ## Feedback targets
37
+
38
+ `abx feedback` has two deliberately separate targets:
39
+
40
+ | Intent | Command | Recipient |
41
+ |---|---|---|
42
+ | ABX protocol, contracts, CLI, SDK, skill, or docs | `abx feedback` | core ABX team |
43
+ | A remote provider's resolver, rendering, auth, or operations | `abx feedback --remote <name>` | that provider |
44
+
45
+ For first-party hosted-service feedback use `--remote abx`. A third-party remote can advertise the
46
+ optional `abx-service-feedback/v1` interface and operate its own feedback store. Never send
47
+ provider-specific incidents through core feedback merely because both first-party targets currently
48
+ share infrastructure.
49
+
50
+ Run the command without report flags to inspect its live schema and instructions. To report, provide
51
+ the required structured flags; use `--detail-file` or `--context-file` rather than fragile shell
52
+ quoting for longer content. The CLI shows the exact destination and payload first. Review and redact
53
+ the preview with the human, then repeat with `--yes` only after explicit approval.
54
+
55
+ ```bash
56
+ # Preview core feedback; nothing is sent.
57
+ abx feedback --area cli --kind bug --summary "Concise summary" --detail-file report.md
58
+
59
+ # After the human approves this exact preview.
60
+ abx feedback --area cli --kind bug --summary "Concise summary" --detail-file report.md --yes
61
+
62
+ # Provider-specific preview.
63
+ abx feedback --remote abx --component rendering --kind bug --summary "Concise summary"
64
+
65
+ # Review reports previously submitted with the current key.
66
+ abx feedback --mine
67
+ abx feedback --remote abx --mine
68
+ ```
69
+
70
+ Do not attach `.env`, credentials, wallet/session URLs, full transcripts, or unrelated source files.
71
+ Prefer the smallest reproduction and relevant version/chain/address context. The API key authenticates
72
+ the reporter and hosted entitlement; it never grants transaction-signing authority.
73
+
74
+ Use the CLI instead of hand-written HTTP or retry loops. Treat `401` as missing/invalid credentials,
75
+ `403` as recognized credentials without the required entitlement, and schema/interface errors as a
76
+ request or provider-contract mismatch. Read [diagnose.md](diagnose.md) and make one state transition.
@@ -1,87 +1,133 @@
1
- # Setup install `abx`, configure `.env`, then RPC & troubleshooting
1
+ # Setup and safety
2
2
 
3
- [← back to SKILL.md](../SKILL.md)
3
+ Use this reference when installing ABX, selecting a binary or signer, configuring a new environment,
4
+ or preparing a real transaction.
4
5
 
5
- **First time? Start at [Finding, installing and configuring `abx`](#finding-installing-and-configuring-abx)** —
6
- that section is the required setup. The RPC and troubleshooting material below it is reference you reach
7
- for when indexing is slow or a resolver will not serve, not something a first launch needs.
6
+ ## Contents
8
7
 
9
- ## Finding, installing and configuring `abx`
8
+ - [Resolve the tool before the project](#resolve-the-tool-before-the-project)
9
+ - [Never expose secrets](#never-expose-secrets)
10
+ - [Select the chain explicitly through the environment](#select-the-chain-explicitly-through-the-environment)
11
+ - [Choose one signing lane](#choose-one-signing-lane)
12
+ - [Prepare without mutating](#prepare-without-mutating)
13
+ - [New environment checklist](#new-environment-checklist)
10
14
 
11
- `abx` needs **Node 22.13** at runtime (the projection store uses built-in SQLite, unflagged only from
12
- v22.13.0 / v23.4.0). On anything older the CLI refuses to start and names the fix — do not work around it
13
- with `NODE_OPTIONS=--experimental-sqlite`, that combination is untested.
15
+ ## Resolve the tool before the project
14
16
 
15
- ### Find `abx` before you install it local first, then global
16
-
17
- **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:
17
+ Inside the ABX source repository run `pnpm abx …`; elsewhere run the installed `abx`. A bare global
18
+ binary inside the repository may be older than the source. Start with:
18
19
 
19
20
  ```bash
20
- ./node_modules/.bin/abx version # 1. project-local — PREFER this (invoke as `npx abx <cmd>` once you know it's there)
21
- abx version # 2. a global install already on PATH
21
+ abx version
22
+ abx doctor
23
+ abx capabilities --json
24
+ abx skill install
22
25
  ```
23
26
 
24
- - **Probe the local binary by PATH, never with `npx abx`.** The bare `abx` name on npm is an **unrelated squatted package**, so a plain `npx abx` with nothing local *downloads that*. And `--no-install` does **not** make the probe safe or trustworthy: it only skips a *fresh download*, and npm will still happily run any `abx` binary sitting in the npx cache from an earlier run — which can be a stale version (a real sweep saw `--no-install` report a months-old build as the project's CLI) or, if a plain `npx abx` was ever run on that machine, the squatted package itself. `./node_modules/.bin/abx` is unambiguous: it exists in THIS project or it doesn't.
25
- - In the **abx source repo** (contributor), neither applies: use `pnpm abx <cmd>`, which runs the live `tsx` source.
27
+ `abx doctor` reports binary provenance, CLI/skill drift, active chain, RPC health and history reach,
28
+ wallet readiness, canonical factories, storage, and configured remotes without exposing credentials.
29
+ Treat a red check as an actionable setup state, not as permission to improvise a workaround.
26
30
 
27
- **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):
31
+ The shipped skill is named `abx`. `abx skill install` installs it to `.claude/skills/abx` and
32
+ `.agents/skills/abx` by default; `--agent`, `--global`, and `--target` narrow the destination. During
33
+ the rename transition the installer moves a recognized `abx-self-host` folder to
34
+ `.abx-skill-backups/` before installing the new name. It preserves custom bytes rather than deleting
35
+ them. For a custom skills parent, run `abx skill install --target <that-parent>`; do not move or merge
36
+ the old folder manually. Restart the agent after installation.
28
37
 
29
- | Situation | Install | Then invoke as |
30
- |---|---|---|
31
- | The creator has a project dir (a `package.json`) — **default** | `npm install --save-dev @artblocks/abx-cli` | `npx abx …` |
32
- | No project, or they asked for a machine-wide tool | `npm install -g @artblocks/abx-cli` | `abx …` |
38
+ ABX requires Node 22.13 or newer. Prefer a project-local npm dependency for reproducible automation;
39
+ use a global install for interactive machine-wide use. Avoid repeated `npx` execution when version
40
+ provenance matters because caches can outlive an upgrade.
41
+
42
+ ## Never expose secrets
43
+
44
+ Do not open, search, quote, or print `.env`. Do not echo variables to test whether they exist. Do not
45
+ paste a private key into a command line, generated file, wallet page, bug report, or transcript.
46
+
47
+ Sensitive values include:
33
48
 
34
- 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.
49
+ - `ABX_DEPLOYER_PK` and any wallet key;
50
+ - credential-bearing `ABX_RPC_URLS*` values;
51
+ - `PINATA_JWT`, S3/R2 keys, `ABX_SERVICES_API_KEY`, other remote-provider tokens, effects/admin
52
+ tokens;
53
+ - Arweave JWK contents and browser signing-session URLs.
35
54
 
36
- 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).
55
+ Use `abx doctor`, `abx remote <name>`, `abx storage show --check`, and redacted CLI errors. If a tool
56
+ ever emits an unredacted credential-bearing endpoint, stop, rotate the credential, and report the
57
+ output bug without repeating the secret.
37
58
 
38
- `.env` (in the creator's project dir) = **secrets only**:
39
- - **Signing:** `ABX_DEPLOYER_PK` (the only name read — older `SEPOLIA_FUNDED_PK`/`SEPOLIA_WALLET_PK` are retired, and the CLI's error names them if it finds neither) 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.
40
- - `ABX_RPC_URLS`, `ABX_PUBLIC_BASE_URL` (remote-resolver custody only), optional `OPENSEA_API_KEY`, plus any backend secret.
41
- - **One client-side credential grammar: `ABX_REMOTE_<NAME>_URL` + `ABX_REMOTE_<NAME>_TOKEN`** (same normalization as `ABX_RPC_URLS_<CHAIN>`) — a node you run is just the name **`self`** (`deploy-resolver` generates `ABX_REMOTE_SELF_TOKEN` locally; bare `--remote` defaults to it), a managed provider is its own name. `ABX_RESOLVER_ADMIN_TOKEN` is the **resolver's own server-side config** (never read client-side) — a stale copy of it in `.env` with no `ABX_REMOTE_SELF_TOKEN` gets a pointed error naming both vars, and `abx doctor` flags it too. Only `_URL`/`_TOKEN` are read — `ABX_REMOTE_<NAME>_KEY` is ignored (the CLI flags a near-miss name).
59
+ ## Select the chain explicitly through the environment
42
60
 
43
- <sub>Working from the abx **source repo** (contributor)? `pnpm install`, then `pnpm abx <cmd>` or `pnpm sandbox`. Every command below is identical.</sub>
61
+ The toolkit supports the chains printed by `abx capabilities`; today those are Base Sepolia by
62
+ default and Ethereum Sepolia via `ABX_CHAIN=sepolia`. There is deliberately no `--chain` flag. The
63
+ CLI refuses it because silently ignoring a wrong-chain request could spend on the wrong network.
44
64
 
45
- **Indexing reads the event log via `eth_getLogs` from the contract's deploy block**, which the CLI records at deploy and forwards to a resolver on `add` — so a normal deploy→index scans a small recent window, is fast on any RPC, and re-indexes incrementally. **If indexing is slow, or a hosted resolver won't serve, ASK IT: `abx status <addr> [--remote <name>]`** reports the lifecycle (`queued`→`backfilling`→`live`, plus `stale`/`failed` with a machine-readable cause), so "still catching up" and "broken" stop looking alike. Then **check the scan floor (is it scanning from block 0?) before blaming the RPC tier** — that mis-diagnosis is a known trap. Range caps, pruned log history, and which endpoint to give a resolver under load are covered below.
65
+ Use per-chain RPC variables when operating more than one chain. `abx doctor` checks chain identity,
66
+ wide-range `eth_getLogs`, archival reach, and nonce coherence. Put a healthy archive endpoint first:
67
+ fallback transports rotate on errors, not on a successful but pruned empty log response.
46
68
 
69
+ The local projection and managed Arweave identity remain in `.abx-self-host/` unless
70
+ `ABX_DATA_DIR` overrides it. That runtime directory is separate from the renamed `abx` skill and is
71
+ not being renamed. Back up the managed Arweave key with `abx storage backup-key`; never print it.
47
72
 
48
- ## Choosing an RPC (drives re-index speed)
73
+ ## Choose one signing lane
49
74
 
50
- Reconstruction reads the event log via `eth_getLogs` **from the contract's deploy block** — the CLI records it at deploy and forwards it to a resolver on `add`, and discovers it on-chain (a getCode binary search) for a contract it didn't deploy here. So a normal deploy→index scans a *small, recent* window and is fast on **any** RPC. Providers cap the getLogs block range very differently **and these caps change** — treat any number as illustrative, re-verify before you quote it. *(Illustrative, Jun 2026: Alchemy free ≈10 blocks/call, Infura/Chainstack free ≈2000, PublicNode/dRPC vary; no-key public endpoints are the lowest-friction to try.)* The toolkit **auto-chunks**, so any RPC yields correct state — but a range cap is **not** cost-free to shrug off: a **from-genesis** or long-span reconstruction, or a resolver serving many code projects under load, is slow and rate-limit-prone on a capped endpoint. `abx doctor` rates each endpoint and flags a capped one; treat that flag as a real infra signal, not noise. **First diagnosis when indexing is slow or a hosted resolver won't serve: is it scanning from block 0? Check the scan floor before the RPC tier.**
75
+ Every write uses one of three lanes:
51
76
 
52
- When `abx doctor` flags a tight range, or a reconstruction would be large/slow — **a decision point: research and present, don't power through:**
53
- 1. **Do your own current research** (the limits rot) — find a free, range-generous, archive-capable endpoint for this chain *right now*.
54
- 2. **Present clear choices with current specifics** — (a) point `ABX_RPC_URLS` at a higher-range endpoint *(recommended for anything large)*, with the exact signup/URL steps you found; or (b) stay on the current RPC and accept the wait.
55
- 3. The CLI **stops a large job with an estimate** instead of grinding through thousands of requests; a better RPC is the real fix. To chunk through anyway, re-run with `--yes` (or raise `ABX_GETLOGS_MAX_CHUNKS`); `ABX_GETLOGS_RANGE` tunes the window.
77
+ | Lane | Select | Use when |
78
+ |---|---|---|
79
+ | Hot | `--send` or default | An environment key may sign unattended |
80
+ | Wallet | `--sign --for 0x…` | A human approves in their browser wallet |
81
+ | Cold | `--unsigned --for 0x…` | A multisig/offline signer needs prepared transactions |
82
+
83
+ Run `abx doctor --for <address>` before a wallet or cold operation. On the wallet lane, give the
84
+ human the locally generated signing page; never request or handle their key. On the cold lane, verify
85
+ chain, sender, target, calldata, value, and ordering before handing transactions over.
86
+
87
+ `--onchain-image` staging cannot use the cold lane because each chunk transaction depends on the
88
+ receipt of the preceding transaction. Use hot or wallet signing. Do not split staging into a homemade
89
+ offline sequence.
56
90
 
57
- **One RPC var, network-scoped.** `ABX_RPC_URLS` is a comma/space-separated list of endpoints **for the active `ABX_CHAIN`** (there is no singular `ABX_RPC_URL`). The client **fails over** across them at request time — a request one endpoint **rejects** (a too-wide `eth_getLogs`) is retried on the next. Note the limit of that: failover triggers on an *error*, and an endpoint that has **pruned its log history** does not error — it answers `eth_getLogs` with `[]` and HTTP 200, which is a success, so the pool keeps asking it. That is why `abx doctor` **probes every endpoint** and reports a per-endpoint verdict (✓ wide range + archive · ⚠ usable but range-capped · ✗ unusable, with the reason, e.g. *history pruned ~500000 blocks back* / *archive refused* / *wrong network*), then names the best for reconstruction — and why it warns when a **reachable** endpoint can't serve history, since ordering is what decides who answers first. So list a couple, let `doctor` pick, and order the list best-first. For **multiple chains**, set `ABX_RPC_URLS_<CHAIN>` (e.g. `ABX_RPC_URLS_BASE_SEPOLIA`, `ABX_RPC_URLS_SEPOLIA` — the default `ABX_CHAIN` is `base-sepolia`) — a per-chain list that overrides the bare var, never mixed, so one network's endpoints can't leak into another. The var *names* a network but the URL could point anywhere, so before any write the toolkit **verifies `eth_chainId` matches `ABX_CHAIN`** and hard-fails on a mismatch (reads stay unguarded/fast) — that's what makes "which network is this?" a checked fact, not a guess.
91
+ For any one EOA, run one write command at a time. ABX obtains pending and latest nonces once, takes the
92
+ safe maximum, increments locally, waits for newly deployed code when a following transaction targets
93
+ it, and throws typed reversion errors. Starting concurrent processes bypasses that serialization.
58
94
 
59
- **Named remotes follow the same env-name normalization**: `--remote my-provider` reads `ABX_REMOTE_MY_PROVIDER_URL` / `ABX_REMOTE_MY_PROVIDER_TOKEN` (uppercase, non-alphanumerics collapse to `_`). Inspect what's configured with `abx remote` ([hosting.md → Managed providers](hosting.md#managed-providers--a-resolver-someone-else-runs---remote-name)).
95
+ ## Prepare without mutating
60
96
 
61
- **Re-index is incremental by default** — it resumes from the last-indexed block and only fetches new blocks, so routine re-indexing (after an owner op, or just refreshing) stays instant *regardless* of the range cap. Even the **first** reconstruction scans only from the **deploy block** (not genesis), so range/archive capability bites only on a genuinely long span — a forced full replay (`abx index --full`, a fresh projection, or the dashboard's "Re-index from chain" — the durability proof) of a contract deployed long ago. A "why is this scanning millions of blocks?" moment almost always means the scan floor is wrong (block 0), not that the RPC is inadequate.
97
+ Use command help and dry runs, not guessed syntax:
62
98
 
63
- ## Troubleshooting
99
+ ```bash
100
+ abx help deploy-code
101
+ abx deploy-code … --dry-run --json
102
+ ```
64
103
 
65
- - **doctor: signing key** **not fatal — a missing key is a fork, not a blocker.** A key in `.env` is only needed to sign *unattended* (hot lane). To sign in a browser wallet instead, run the write with `--sign` and no env key is needed. Offer both: add `ABX_DEPLOYER_PK` for autonomous signing, **or** use `--sign`. **deployer unfunded** → fund the printed address from a faucet for the active chain (Base Sepolia by default, else Sepolia).
66
- - **a write reverts with no clear reason (`--onchain-image` / staging)** → don't thrash by retrying variations. Get the actual reason: re-run the same call read-only with `cast call <addr> "<sig>" <args> --rpc-url <one of your ABX_RPC_URLS>`, which surfaces the revert string. The classic culprit is a stale chunk store (deployed before a contract upgrade) — the toolkit now detects this and auto-deploys a current store with a yellow notice, so you shouldn't hit the silent revert, but verify the resolved chunk-store/factory addresses are live (`cast code <addr>`; `abx doctor` / `abx status` print the factory) if anything looks off. **Never silently switch the representation you told the user you'd use** (e.g. fall back from `reader` to `inline`) — if the path changes, say so and why.
67
- - **storage 'cloud' missing accessKeyId/…** set `ABX_S3_*` in `.env`. **'ipfs' unreachable** Kubo not running or `PINATA_JWT` missing.
68
- - **re-index slow, or a "scan too large" stop** → **first check the scan floor: is it indexing from block 0 instead of the deploy block?** That's the usual cause of a "huge" scan (an `add` that lost the deploy block). The floor is `flags['from-block'] → the stored deploy block → on-chain discovery`; if none resolve, the CLI refuses rather than sweeping genesis. Only once the floor is correct does the RPC's `eth_getLogs` range matter: the toolkit chunks automatically, but a genuinely large job stops with an estimate rather than grinding. Real fix then: research a current higher-range free endpoint and set `ABX_RPC_URLS` (`abx doctor` reports your range); or re-run with `--yes` to chunk through. **archive-range getLogs refused** → use an archive-capable provider.
69
- - **the scan finished but reconstructed 0 events** (`registered …, but with NO reconstructed state`) → for a project you JUST deployed this is transient (the logs haven't propagated; `abx index <addr> --full` in a minute). For a project that is **not new**, suspect **log retention**: several free endpoints keep only days of history and return an empty success past it, which is indistinguishable from "this contract emitted nothing". The CLI now re-runs the scan against **each configured endpoint on its own** before giving up, and names the one that served the logs — put that one FIRST in `ABX_RPC_URLS_<CHAIN>`. `abx doctor` flags a pruned endpoint up front.
70
- - **`serve`/resolver returns `{"error":"unknown project"}`** → the resolver you hit doesn't have that contract in *its own* projection store **yet**. Two distinct situations — diagnose which, and NEVER default to "RPC limit":
71
- - **A remote resolver you just registered** (`abx add … --remote`): it may still be **backfilling** — hit `GET /` (or `abx remote <name|url>`, which lists the projects the token sees) to see if it's appearing. If it's slow or stuck, the cause is almost always a **from-genesis scan (from-block=0)**, not the RPC tier — a fixed `abx add` forwards the deploy block, so re-run it and confirm the floor. (Fixed in-toolkit: a first remote add now forwards/derives the deploy block and refuses a genesis default.)
72
- - **A local `abx serve`**: a **store/port** problem. Usual causes, in order: (1) a **stale/duplicate `abx serve` from an old session** holds the port and serves a *different* store — hit `GET /` and see what it lists; (2) you're serving a different store directory than the deploy indexed into; (3) the contract was never registered there. Fix the server/port/registration.
73
- - **`/a/…` returns `503` with "its on-chain code has not been folded into the projection yet"** → exactly what it says: the resolver knows this is a code project (from the deployed extensions) but hasn't read its code yet. **Retry** — this is normal right after a register. It only means trouble if it persists, and then it's the scan-floor bug below.
74
- - **`/a/…` returns `404 {"error":"no live view — not a code project"}` on a project that IS a code drop** → the resolver indexed *above* the deploy block, so it never saw the deploy at all — a scan-floor bug, **not** a resolver version/compat gap (do NOT redeploy as a static NFT). The 404-vs-503 split is the diagnosis: 404 on a real code drop means the fold never saw this contract's deploy, which is the scan-floor signature. This is the *opposite* of the genesis bug: the floor is too **high**, not too low. It happened when a `--sign` code deploy spanned blocks (deploy at N, mint at N+2) and the mint block was recorded as the floor. Confirm: `GET /api/project/<addr>` → `collectionFields` is `[]` and `fromBlock` sits above the deploy block. Fix: `abx add <addr> --remote <url> --from-block <deployBlock>` — a *changed* floor forces a full replay that picks up the `code` field. Find the true deploy block with `abx add <addr>` locally (it prints "deploy block N (discovered on-chain)"). (Fixed in-toolkit: `deploy-code` now records the clone-CREATION block, and discovers it on-chain rather than trusting the last-tx receipt.)
75
- - **directory-mode live view 302s to a doubled URL** (`https://arweave.net/https://arweave.net/<txid>/index.html`) → the `code` locator was stored as a full gateway URL and the gateway got prefixed again. Fixed in-toolkit (deploy stores the bare txid/CID; the resolver serves an already-absolute locator verbatim). A resolver image built before the fix still doubles — redeploy it to pick up the resolver-side tolerance.
76
- - **the thumbnail stays a placeholder on a HOSTED resolver even after `abx render` reports `ran=1`** → the render bytes landed in a store the hosted resolver can't read. A local `abx render` with the default `fs` backend writes to your laptop; `ipfs`/`arweave` write a LOCAL key→CID index the resolver doesn't have. Fix: render **to** the resolver — `abx render <addr> --remote <resolver>` (uploads to your `ABX_STORAGE_BACKEND` home and **publishes** a locator/bytes the resolver serves), or stand up the runner beside it (`abx deploy-effects --resolver-url <resolver>`). Only a SHARED `s3`/`cloud` bucket makes a bare local render visible to a hosted resolver. Confirm with `abx verify <addr>`.
77
- - **resolver won't start / errors about `ABX_PUBLIC_BASE_URL`** → it refuses a placeholder `.example` base (a scaffold leftover) or a `localhost` base in a hosted image (`ABX_HOSTED=1`), because it bakes that base into every image/animation URL it serves — a bad one serves dead links, so a loud fail beats silent breakage. Set `ABX_PUBLIC_BASE_URL` to the resolver's real public URL (`fly secrets set ABX_PUBLIC_BASE_URL=https://<app>.fly.dev`, or your custom domain). The current scaffold bakes the real platform hostname by default, so this only bites a hand-edited/old artifact or a stripped env.
78
- - **a hosted resolver LOST its index (or its render thumbnails) after a redeploy** → the SQLite projection wasn't on a persistent volume. The scaffold creates `fly volumes create abx_data` **before** the first deploy so the store lives on `/data` (the mount); if you deployed WITHOUT the volume, the store sat on ephemeral disk and a redeploy wiped it. Fix: ensure the volume exists (`fly volumes list`), then re-index (`abx add <addr> --remote --from-block <deployBlock>`). Note published **render locators + traits live on that same volume** (producer-published, not chain-derived), so restoring them after a volume loss needs a runner re-sweep, not just a chain replay — re-run `abx render <addr> --remote <resolver>` (idempotent; it re-publishes from the storage home without re-rendering) or let the effects service sweep.
79
- - **the project's on-chain `tokenURI` points at a HOSTED resolver but it isn't serving** → **do NOT "fix" it by running `abx serve` locally and handing over a `localhost` link.** The baked URL is the hosted one; a local serve resolves for no one but you. Fix the HOSTED resolver instead: re-run `abx add <addr> --remote` (now forwards the deploy block), check `GET /` on the host, and vet its RPC with `abx doctor`. A local serve is only ever the answer when the baked base is that same local machine.
80
- - **port hygiene before `serve`** → check the port is free first (`lsof -i:8787`). If an old session holds it, kill that process or serve this project on a distinct `--port <n>` (and point its `--public-base-url`/tokenURI accordingly) — a stale server silently answering on the port is the #1 cause of "works for me, `unknown project` for everyone."
81
- - **serving code projects is RPC-heavier than static content** → the live view rebuilds `tokenData` per request, and template-mode script chunks + data-backed (`String`/`Bytes`) params are read **live per view** (scalar PostParams come from the indexed projection, so they don't hit RPC each view). A resolver serving many code projects under marketplace traffic wants a range-generous, reliable RPC — this is a genuine scaling consideration, distinct from the getLogs range cap above.
82
- - **a remote command returns 401 unauthorized** → the token the CLI resolved is missing/wrong for that target — the error names the var it used (`ABX_REMOTE_<NAME>_TOKEN` for a named remote, else `ABX_REMOTE_SELF_TOKEN`, else `--remote-token`). Check that var, or rotate the key at the provider if it may have leaked. Named remotes deliberately never fall back to `ABX_REMOTE_SELF_TOKEN` (or the resolver's own server-side `ABX_RESOLVER_ADMIN_TOKEN`).
83
- - **a remote command returns 403 forbidden** → the key is **valid but not authorized** for this contract/chain — provider-side scoping, not a typo. Don't retry-loop and don't swap tokens blindly: check the provider dashboard, and the descriptor's `chains` (`abx remote <name>`).
84
- - **register refused with `unsupported_chain`** → the service doesn't serve the project's chain — its descriptor `chains` says which it does. Pick a provider that covers the chain, or self-host.
85
- - **`/.well-known/abx-service` 404s** → an older self-hosted node (fine if it's yours — the remote commands still work against it once redeployed to the current image) or **not an ABX service at all** — verify the URL with `abx remote <url>` before registering anything; don't register blind.
86
- - **wallet lane: "no injected wallet"** → the human has no extension wallet; fall back to the hot lane (`--send`) if they're comfortable, or the cold lane for a Safe.
87
- - **owner op reverts** → the signer isn't the owner/holder. Check `abx status` / the `/api/project` state for the current owner; sign as that wallet.
104
+ A dry run may read contracts, probe endpoints, analyze files, or verify an address, but it does not
105
+ send or store. Address prediction is meaningful only when the salt and deployer are pinned. Use
106
+ `abx predict` when another contract or resolver must know the collection address before deployment.
107
+
108
+ Before any real send, confirm:
109
+
110
+ - active chain and deploying/owning address;
111
+ - contract family and edition arithmetic;
112
+ - name, symbol, royalties and royalty ceiling;
113
+ - deploy-time options such as burnability and creator-token enrollment;
114
+ - custody, public resolution, image/animation/trait surfaces;
115
+ - mint amount, value, transaction count, and expected gas;
116
+ - every irreversible lock or authority transfer.
117
+
118
+ Do not make a real send merely because a dry run exited successfully. The dry run is the plan; the
119
+ human confirmation authorizes execution.
120
+
121
+ ## New environment checklist
122
+
123
+ 1. Install Node 22.13+ and the desired CLI version.
124
+ 2. Install the co-versioned skill with `abx skill install`, then restart the agent.
125
+ 3. Select the testnet using `ABX_CHAIN` if not using Base Sepolia.
126
+ 4. Add RPC, signer, storage, and remote configuration outside the transcript. For the first-party
127
+ service, keep `ABX_SERVICES_API_KEY` in the project's ignored `.env`; do not add it or standing
128
+ signup instructions to `AGENTS.md` or `CLAUDE.md`.
129
+ 5. Run `abx doctor` and resolve every red check relevant to the chosen lane.
130
+ 6. Run `abx storage show --check` when bytes will leave the local disk.
131
+ 7. Run `abx remote <name>` before relying on a configured managed service.
132
+ 8. Run command help, then a JSON dry run.
133
+ 9. Confirm the plan and only then execute.