@artblocks/abx-cli 0.1.0-alpha.4 → 0.1.0-alpha.40
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/CHANGELOG.md +16 -0
- package/assets/renderer-scaffold/README.md +29 -11
- package/assets/renderer-scaffold/foundry.toml +1 -0
- package/assets/renderer-scaffold/remappings.txt +1 -1
- package/assets/renderer-scaffold/script/DeployHooks.s.sol +24 -0
- package/assets/renderer-scaffold/src/MyHooks.sol +20 -0
- package/assets/renderer-scaffold/src/MyRenderer.sol +4 -4
- package/assets/renderer-scaffold/src/MyTraits.sol +2 -2
- package/assets/renderer-scaffold/test/MyRenderer.t.sol +60 -3
- package/dist/bin.d.ts +26 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +63 -0
- package/dist/bin.js.map +1 -0
- package/dist/capabilities.d.ts +94 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +135 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/commands/auth.d.ts +54 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +447 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/deploy.d.ts +242 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +4763 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/feedback.d.ts +7 -0
- package/dist/commands/feedback.d.ts.map +1 -0
- package/dist/commands/feedback.js +147 -0
- package/dist/commands/feedback.js.map +1 -0
- package/dist/commands/project.d.ts +257 -0
- package/dist/commands/project.d.ts.map +1 -0
- package/dist/commands/project.js +1414 -0
- package/dist/commands/project.js.map +1 -0
- package/dist/commands/reads.d.ts +64 -0
- package/dist/commands/reads.d.ts.map +1 -0
- package/dist/commands/reads.js +701 -0
- package/dist/commands/reads.js.map +1 -0
- package/dist/commands/scaffold.d.ts +89 -0
- package/dist/commands/scaffold.d.ts.map +1 -0
- package/dist/commands/scaffold.js +733 -0
- package/dist/commands/scaffold.js.map +1 -0
- package/dist/commands/service.d.ts +67 -0
- package/dist/commands/service.d.ts.map +1 -0
- package/dist/commands/service.js +741 -0
- package/dist/commands/service.js.map +1 -0
- package/dist/commands/storage.d.ts +51 -0
- package/dist/commands/storage.d.ts.map +1 -0
- package/dist/commands/storage.js +370 -0
- package/dist/commands/storage.js.map +1 -0
- package/dist/commands/submit-app.d.ts +59 -0
- package/dist/commands/submit-app.d.ts.map +1 -0
- package/dist/commands/submit-app.js +513 -0
- package/dist/commands/submit-app.js.map +1 -0
- package/dist/config.d.ts +90 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +284 -11
- package/dist/config.js.map +1 -1
- package/dist/conformance.d.ts +31 -0
- package/dist/conformance.d.ts.map +1 -0
- package/dist/conformance.js +390 -0
- package/dist/conformance.js.map +1 -0
- package/dist/contract-read-error.d.ts +5 -0
- package/dist/contract-read-error.d.ts.map +1 -0
- package/dist/contract-read-error.js +37 -0
- package/dist/contract-read-error.js.map +1 -0
- package/dist/deps.d.ts +6 -39
- package/dist/deps.d.ts.map +1 -1
- package/dist/deps.js +4 -68
- package/dist/deps.js.map +1 -1
- package/dist/errors.d.ts +20 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +25 -0
- package/dist/errors.js.map +1 -0
- package/dist/flag-allowlists.d.ts +53 -0
- package/dist/flag-allowlists.d.ts.map +1 -0
- package/dist/flag-allowlists.js +180 -0
- package/dist/flag-allowlists.js.map +1 -0
- package/dist/flags.d.ts +41 -0
- package/dist/flags.d.ts.map +1 -1
- package/dist/flags.js +111 -1
- package/dist/flags.js.map +1 -1
- package/dist/jsonout.d.ts +37 -0
- package/dist/jsonout.d.ts.map +1 -0
- package/dist/jsonout.js +68 -0
- package/dist/jsonout.js.map +1 -0
- package/dist/kind.d.ts +57 -0
- package/dist/kind.d.ts.map +1 -0
- package/dist/kind.js +122 -0
- package/dist/kind.js.map +1 -0
- package/dist/main.js +747 -4838
- package/dist/main.js.map +1 -1
- package/dist/mintpage.d.ts +17 -2
- package/dist/mintpage.d.ts.map +1 -1
- package/dist/mintpage.js +241 -54
- package/dist/mintpage.js.map +1 -1
- package/dist/output.d.ts +179 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +780 -0
- package/dist/output.js.map +1 -0
- package/dist/ownerops.d.ts +312 -57
- package/dist/ownerops.d.ts.map +1 -1
- package/dist/ownerops.js +1808 -357
- package/dist/ownerops.js.map +1 -1
- package/dist/preview.d.ts +23 -5
- package/dist/preview.d.ts.map +1 -1
- package/dist/preview.js +95 -43
- package/dist/preview.js.map +1 -1
- package/dist/prompt.d.ts +17 -0
- package/dist/prompt.d.ts.map +1 -0
- package/dist/prompt.js +19 -0
- package/dist/prompt.js.map +1 -0
- package/dist/provision.d.ts +3 -13
- package/dist/provision.d.ts.map +1 -1
- package/dist/provision.js +19 -21
- package/dist/provision.js.map +1 -1
- package/dist/remote.d.ts +157 -52
- package/dist/remote.d.ts.map +1 -1
- package/dist/remote.js +435 -46
- package/dist/remote.js.map +1 -1
- package/dist/riskgate.d.ts +62 -0
- package/dist/riskgate.d.ts.map +1 -0
- package/dist/riskgate.js +234 -0
- package/dist/riskgate.js.map +1 -0
- package/dist/scaffold.d.ts +12 -0
- package/dist/scaffold.d.ts.map +1 -0
- package/dist/scaffold.js +56 -0
- package/dist/scaffold.js.map +1 -0
- package/dist/schema.d.ts +36 -1
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +121 -26
- package/dist/schema.js.map +1 -1
- package/dist/script-chunks.d.ts +8 -0
- package/dist/script-chunks.d.ts.map +1 -0
- package/dist/script-chunks.js +35 -0
- package/dist/script-chunks.js.map +1 -0
- package/dist/served.d.ts +30 -0
- package/dist/served.d.ts.map +1 -0
- package/dist/served.js +112 -0
- package/dist/served.js.map +1 -0
- package/dist/signer.d.ts +13 -0
- package/dist/signer.d.ts.map +1 -1
- package/dist/signer.js +84 -15
- package/dist/signer.js.map +1 -1
- package/dist/update-check.d.ts +86 -5
- package/dist/update-check.d.ts.map +1 -1
- package/dist/update-check.js +161 -20
- package/dist/update-check.js.map +1 -1
- package/package.json +13 -12
- package/skill/SKILL.md +179 -347
- package/skill/agents/openai.yaml +4 -0
- package/skill/reference/capabilities.md +188 -0
- package/skill/reference/code.md +211 -0
- package/skill/reference/creator-token.md +94 -0
- package/skill/reference/deploy.md +167 -0
- package/skill/reference/diagnose.md +165 -0
- package/skill/reference/hosting.md +161 -94
- package/skill/reference/operate.md +181 -0
- package/skill/reference/services.md +121 -0
- package/skill/reference/setup.md +140 -36
- package/assets/renderer-scaffold/src/interfaces/IAbxFieldRenderer.sol +0 -32
- package/assets/renderer-scaffold/src/interfaces/IAbxParams.sol +0 -26
- package/dist/inspect.d.ts +0 -48
- package/dist/inspect.d.ts.map +0 -1
- package/dist/inspect.js +0 -184
- package/dist/inspect.js.map +0 -1
- package/dist/migrate.d.ts +0 -65
- package/dist/migrate.d.ts.map +0 -1
- package/dist/migrate.js +0 -180
- package/dist/migrate.js.map +0 -1
- package/dist/onchain-uri.d.ts +0 -97
- package/dist/onchain-uri.d.ts.map +0 -1
- package/dist/onchain-uri.js +0 -243
- package/dist/onchain-uri.js.map +0 -1
- package/dist/upload.d.ts +0 -28
- package/dist/upload.d.ts.map +0 -1
- package/dist/upload.js +0 -41
- package/dist/upload.js.map +0 -1
- package/skill/reference/code-projects.md +0 -246
- package/skill/reference/operating.md +0 -116
- package/skill/reference/troubleshooting.md +0 -28
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# Diagnosis and recovery
|
|
2
|
+
|
|
3
|
+
Use this reference when a command fails, a project is incomplete, metadata is wrong, a render is
|
|
4
|
+
missing, storage is propagating, a remote rejects a request, or an agent is tempted to add retries.
|
|
5
|
+
|
|
6
|
+
## Contents
|
|
7
|
+
|
|
8
|
+
- [Diagnose one state transition at a time](#diagnose-one-state-transition-at-a-time)
|
|
9
|
+
- [State-to-action table](#state-to-action-table)
|
|
10
|
+
- [Nonces and serialized writes](#nonces-and-serialized-writes)
|
|
11
|
+
- [Incomplete deployments](#incomplete-deployments)
|
|
12
|
+
- [RPC and chain failures](#rpc-and-chain-failures)
|
|
13
|
+
- [Metadata and resolution failures](#metadata-and-resolution-failures)
|
|
14
|
+
- [Storage failures](#storage-failures)
|
|
15
|
+
- [Render and effects failures](#render-and-effects-failures)
|
|
16
|
+
- [Secret-safe reporting](#secret-safe-reporting)
|
|
17
|
+
|
|
18
|
+
## Diagnose one state transition at a time
|
|
19
|
+
|
|
20
|
+
1. Capture the command, exit code, typed error/status, active chain, target address, and signer lane.
|
|
21
|
+
Never capture secret values or complete credential-bearing URLs.
|
|
22
|
+
2. Run `abx version` and `abx doctor`; correct binary/skill drift before interpreting behavior.
|
|
23
|
+
3. Run the relevant read command (`state`, `tokens`, `tokenuri`, `contracturi`, `status`, `verify`,
|
|
24
|
+
`remote`, or `storage status`) to establish current state.
|
|
25
|
+
4. Classify the result as nonterminal, terminal/configuration, terminal/on-chain, or integrity fault.
|
|
26
|
+
5. Choose one documented transition. Re-read state after it. Stop when the state changes or a human
|
|
27
|
+
decision is required.
|
|
28
|
+
|
|
29
|
+
Do not run the same failed write with random flags, switch representations silently, rotate providers
|
|
30
|
+
without evidence, or wrap the CLI in an unbounded retry loop.
|
|
31
|
+
|
|
32
|
+
## State-to-action table
|
|
33
|
+
|
|
34
|
+
| Observation | Meaning | Next action |
|
|
35
|
+
|---|---|---|
|
|
36
|
+
| `indexing`, `queued`, `running`, `propagating` | nonterminal work | use the command's `--watch`/status and wait |
|
|
37
|
+
| `401` from a remote | token absent/invalid | replace the configured credential, then probe once |
|
|
38
|
+
| `403` from a remote | credential lacks scope | fix provider authorization; do not rotate blindly |
|
|
39
|
+
| wrong chain id | endpoint/config mismatch | correct `ABX_CHAIN`/RPC; do not deploy another contract |
|
|
40
|
+
| no code at address | wrong chain/address or incomplete deploy | verify explorer/chain and deploy state before retrying |
|
|
41
|
+
| transaction reverted | on-chain rule rejected the exact call | inspect typed reason/tx; change intent or inputs, not nonce |
|
|
42
|
+
| integrity/hash mismatch | served bytes differ from commitment | stop publication; restore committed bytes or explicitly repoint |
|
|
43
|
+
| placeholder image | image surface not published/wired | choose renderer, public image base, or resolver/effects path |
|
|
44
|
+
| storage accepted but gateway 404 | propagation may be pending | `storage status`; wait if propagating |
|
|
45
|
+
| empty historical reconstruction | pruning/range-capped RPC may have answered `[]` | put a full-history endpoint first, then re-index |
|
|
46
|
+
| skill version/name warning | agent membrane is stale or duplicated | run the exact project/global `abx skill install` commands shown |
|
|
47
|
+
|
|
48
|
+
## Nonces and serialized writes
|
|
49
|
+
|
|
50
|
+
ABX already owns nonce handling. A hot sender reads pending and latest counts once, uses the safe
|
|
51
|
+
maximum, increments locally for the sequence, waits for newly deployed code before dependent calls,
|
|
52
|
+
pins gas with bounded estimation, and reports a reverted receipt as an error.
|
|
53
|
+
|
|
54
|
+
The operational rule is therefore simple: **one EOA, one write process at a time**. Two processes can
|
|
55
|
+
start from the same nonce before either sees the other's pending transaction. If contention occurred:
|
|
56
|
+
|
|
57
|
+
1. Stop additional writers.
|
|
58
|
+
2. Read nonce coherence with `abx doctor` and check pending/mined transactions on the active chain.
|
|
59
|
+
3. Wait for the pending transaction or resolve it using the wallet's standard replacement flow.
|
|
60
|
+
4. Re-read project state; resume only the missing documented step.
|
|
61
|
+
|
|
62
|
+
Do not add “nonce too low” retries, increment a guessed nonce, or send concurrent replacement
|
|
63
|
+
transactions from the agent. Those layers fight the CLI's serializer and can duplicate value-bearing
|
|
64
|
+
operations.
|
|
65
|
+
|
|
66
|
+
## Incomplete deployments
|
|
67
|
+
|
|
68
|
+
A failed multi-transaction code-project setup can leave a valid clone with missing setup legs. Use
|
|
69
|
+
`deploy-code --resume <address>` only where the capability output says resume is supported. It reads
|
|
70
|
+
the contract and sends only missing work; it is not a general “try deploy again” switch.
|
|
71
|
+
|
|
72
|
+
Before resume:
|
|
73
|
+
|
|
74
|
+
- verify the address, chain, contract family, owner, and original artifacts;
|
|
75
|
+
- use the same normalized script/dependencies/schema/renderer plan;
|
|
76
|
+
- read the resume dry run and confirm every proposed transaction;
|
|
77
|
+
- ensure no second writer is operating the same EOA.
|
|
78
|
+
|
|
79
|
+
EditionCode resume is not currently supported. Inspect state and stop for an explicit recovery or new
|
|
80
|
+
deployment decision rather than applying the 721 recipe.
|
|
81
|
+
|
|
82
|
+
## RPC and chain failures
|
|
83
|
+
|
|
84
|
+
Use `abx doctor` rather than probing secret endpoints manually. Distinguish:
|
|
85
|
+
|
|
86
|
+
- connectivity/rate limit: endpoint did not provide a usable response;
|
|
87
|
+
- wrong network: endpoint chain id differs from `ABX_CHAIN`;
|
|
88
|
+
- shallow history: recent reads work but old logs are unavailable;
|
|
89
|
+
- range cap: large `eth_getLogs` queries fail or return misleading empty ranges;
|
|
90
|
+
- read-gas cap: a large on-chain `tokenURI` call exceeds that endpoint's allowance;
|
|
91
|
+
- stale distributed view: pending nonce or newly deployed code lags the endpoint's own head.
|
|
92
|
+
|
|
93
|
+
Put the best archive endpoint first. Fallback transports can accept an empty successful answer from a
|
|
94
|
+
pruned endpoint and never reach a healthy second endpoint. For large on-chain content, state whose RPC
|
|
95
|
+
was measured; do not generalize creator reach to marketplace reach.
|
|
96
|
+
|
|
97
|
+
If a write simulation or estimate reverts, preserve the exact representation the creator chose. Use a
|
|
98
|
+
read-only call/CLI diagnostic to surface the contract reason. Never silently replace an on-chain reader
|
|
99
|
+
with an off-chain URL merely to make the command pass.
|
|
100
|
+
|
|
101
|
+
## Metadata and resolution failures
|
|
102
|
+
|
|
103
|
+
Start from the contract, not a constructed URL:
|
|
104
|
+
|
|
105
|
+
1. `abx state <addr>` — contract family, renderer, owner powers, schemas/locks.
|
|
106
|
+
2. `abx tokenuri <addr> --token <id>` — actual on-chain URI and decoded metadata.
|
|
107
|
+
3. `abx contracturi <addr>` — actual collection URI.
|
|
108
|
+
4. `abx verify <addr> --json` — commitments, chain-completeness, placeholders, public bytes.
|
|
109
|
+
|
|
110
|
+
Then follow the failing surface:
|
|
111
|
+
|
|
112
|
+
- URI absent/wrong: inspect URI pointer/renderer and deploy configuration.
|
|
113
|
+
- Metadata resolves but image fails: inspect image representation and public locator/gateway.
|
|
114
|
+
- Animation fails: inspect generated document, dependencies, target token data, and hosting.
|
|
115
|
+
- Traits missing: inspect decoded `attributes`, renderer/effects output, and publication—not only
|
|
116
|
+
program console traits.
|
|
117
|
+
- Attachments absent: verify resolver artifacts enumeration; bare on-chain metadata cannot enumerate
|
|
118
|
+
arbitrary keys.
|
|
119
|
+
|
|
120
|
+
Use `refresh` only after the current path is correct. Refreshing a broken URI makes a marketplace fetch
|
|
121
|
+
the same broken document again.
|
|
122
|
+
|
|
123
|
+
## Storage failures
|
|
124
|
+
|
|
125
|
+
Run `abx storage show --check` with the intended backend overrides. For cloud, inspect both the private
|
|
126
|
+
put endpoint and public read base by hostname only; never print credentials. For IPFS, separate pinning
|
|
127
|
+
from gateway retrieval. For Arweave, use structured status to distinguish propagation from failure.
|
|
128
|
+
|
|
129
|
+
Retry policy:
|
|
130
|
+
|
|
131
|
+
- accepted/deduplicated upload: success; do not upload again;
|
|
132
|
+
- propagating locator: wait using status backoff;
|
|
133
|
+
- terminal authentication/configuration error: fix configuration before one new attempt;
|
|
134
|
+
- integrity mismatch: stop and restore/republish the committed bytes;
|
|
135
|
+
- transient provider failure: use the client's bounded retry or retry once after status evidence;
|
|
136
|
+
- repeated unknown failure: stop and report the smallest redacted reproduction.
|
|
137
|
+
|
|
138
|
+
Do not switch backend or public locator without telling the creator; that changes the custody plan.
|
|
139
|
+
|
|
140
|
+
## Render and effects failures
|
|
141
|
+
|
|
142
|
+
A still is derived state keyed by current inputs. Diagnose the graph in order:
|
|
143
|
+
|
|
144
|
+
1. Token/id is minted and indexed.
|
|
145
|
+
2. Live document loads for that real id.
|
|
146
|
+
3. Dependencies and PostParams resolve.
|
|
147
|
+
4. Effects runner is authenticated and receives the job.
|
|
148
|
+
5. Render bytes are non-placeholder and uploaded to public storage.
|
|
149
|
+
6. Resolver receives/publishes the locator and traits.
|
|
150
|
+
7. Token metadata exposes them.
|
|
151
|
+
|
|
152
|
+
Use `abx render --force` only when an existing render is known bad or stale; a plain render should
|
|
153
|
+
idempotently skip an existing current artifact. A PostParam change produces a new inputs hash; verify
|
|
154
|
+
the watcher or run the explicit one-shot path. Solidity image renderers have no effects job—diagnose
|
|
155
|
+
their on-chain call instead.
|
|
156
|
+
|
|
157
|
+
## Secret-safe reporting
|
|
158
|
+
|
|
159
|
+
Include command name, CLI version, chain key, redacted host labels, contract address, transaction hash,
|
|
160
|
+
exit code, typed status/error, and expected versus observed state. Exclude `.env`, keys, tokens, JWKs,
|
|
161
|
+
wallet-session URLs, query strings, and raw provider responses containing request headers.
|
|
162
|
+
|
|
163
|
+
If the same blocking state survives three evidence-based transitions, stop. Report what was proven,
|
|
164
|
+
what was ruled out, and the exact external decision or state change required. Repetition is not
|
|
165
|
+
progress.
|
|
@@ -1,138 +1,205 @@
|
|
|
1
|
-
# Hosting
|
|
1
|
+
# Hosting, storage, and remote operation
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use this reference when a project needs public resolution, managed remote service, creator-operated
|
|
4
|
+
resolver/effects, storage configuration, render publication, lifecycle monitoring, or migration.
|
|
4
5
|
|
|
5
|
-
##
|
|
6
|
+
## Contents
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
- [First decide whether a host exists](#first-decide-whether-a-host-exists)
|
|
9
|
+
- [Choose managed or creator-operated resolution](#choose-managed-or-creator-operated-resolution)
|
|
10
|
+
- [Choose storage independently](#choose-storage-independently)
|
|
11
|
+
- [Operate resolver and effects services](#operate-resolver-and-effects-services)
|
|
12
|
+
- [Use lifecycle states](#use-lifecycle-states)
|
|
13
|
+
- [Migrate without losing canonicity](#migrate-without-losing-canonicity)
|
|
8
14
|
|
|
9
|
-
|
|
10
|
-
|---|---|---|---|
|
|
11
|
-
| **`fs`** (default) | Operator-held, local disk | — | — |
|
|
12
|
-
| **`cloud`** | S3-compatible: AWS S3 / R2 / B2 / MinIO | `--backend cloud --endpoint <url> --bucket <b> --region <r>` (or `ABX_S3_ENDPOINT`/`ABX_S3_BUCKET`/`ABX_S3_REGION`) | `ABX_S3_ACCESS_KEY_ID`, `ABX_S3_SECRET_ACCESS_KEY` |
|
|
13
|
-
| **`ipfs`** | Decentralized (CID) | kubo: `--backend ipfs --mode kubo --api-url http://127.0.0.1:5001 --gateway http://127.0.0.1:8080` · pinata: `--backend ipfs --mode pinata --gateway https://<you>.mypinata.cloud` | `PINATA_JWT` (pinata mode) |
|
|
14
|
-
| **`arweave`** | Pay-once permanent | `--backend arweave` (Turbo default; or `ABX_STORAGE_BACKEND=arweave`) | the Turbo key (auto-managed) |
|
|
15
|
+
## First decide whether a host exists
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
Do not ask “where should we host?” until the public surfaces require a host.
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
No ABX resolver is required when:
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
- **`cloud`/`fs`** — durable only while the creator maintains the bucket/disk; centralized, mutable.
|
|
24
|
-
- **Backends are swappable** — the on-chain keccak is the anchor, so bytes are portable: re-upload to the new backend and re-point the `image` field (`abx set-field <addr> --field image …`), then `abx verify` confirms the served bytes still match the on-chain hash. For a hosted-resolver project, `abx migrate` re-pins node-custody images to a durable backend as part of the move (see [operating.md](operating.md)). Re-pointing is an owner-signed tx, so keep the owner wallet secure. Starting on `fs`/`ipfs` and moving to `arweave` later is fine; just don't let an interim backend lapse before the move.
|
|
21
|
+
- static bytes and metadata resolve on-chain;
|
|
22
|
+
- on-chain JSON points at public Arweave/IPFS/cloud media;
|
|
23
|
+
- Solidity field renderers compute every required metadata surface on-chain.
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
A resolver is useful or required when:
|
|
27
26
|
|
|
28
|
-
|
|
27
|
+
- metadata must remain operationally editable;
|
|
28
|
+
- a JavaScript/build project needs a hosted live document;
|
|
29
|
+
- marketplace stills/traits are produced by an effects runner;
|
|
30
|
+
- attached artifacts must be enumerated and fetched;
|
|
31
|
+
- large on-chain content needs an HTTP reader in front of endpoint-dependent `eth_call` execution;
|
|
32
|
+
- a project needs indexed status/dashboard/API surfaces.
|
|
29
33
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
- **`--storage-signer eth`** — reuse the **`.env` EVM signing key** as the Turbo identity (`ABX_DEPLOYER_PK`/`SEPOLIA_FUNDED_PK`/`SEPOLIA_WALLET_PK`). Its ETH address holds the credits, so credits funded on that wallet's Turbo balance are spendable. Hot lane (key in `.env`).
|
|
33
|
-
- **`--storage-signer eth` + `--sign`** — the **browser wallet** signs each upload data-item via `personal_sign` (no gas, no funds move; the upload is paid from the wallet's Turbo credits), in the same sign session as the deploy tx. The key never leaves the wallet. *(New; the mechanism matches arbundles' `InjectedEthereumSigner` and is unit-tested at the CLI↔page contract, but the live MetaMask↔Turbo path wants a manual smoke test. If a live upload misbehaves, fall back to `--storage-signer eth` with a key, or fund the managed key.)*
|
|
34
|
-
- **Under 100 KB → free**, permanent, zero setup. The CLI prints this from the file size (in `--dry-run` too).
|
|
35
|
-
- **Over 100 KB → prepaid credits, one-time.** `abx storage balance` shows the funded address + credits; `abx storage topup --usd <n>` returns a Stripe checkout link. A **pre-upload balance guard** stops *before* the deploy if credits are short — printing the address + fund options — so a shortfall never fails mid-deploy after txs already landed. One-time payment, no recurring fee, nothing to re-pin (contrast `cloud`/`ipfs`). Credits are non-refundable.
|
|
36
|
-
- **Credits attach to the IDENTITY, not "you".** With the default `arweave` lane, a top-up funds the CLI-managed Arweave address (derived from the key file) — a *different* identity from the ETH wallet used to sign deploys. So a fresh managed key shows **0 credits even if the creator "funded Turbo before"**: those old credits sit on whatever identity they funded. If they funded their **ETH wallet's** Turbo balance, reach it with `--storage-signer eth` (key) or `--storage-signer eth --sign` (browser). If they hold a funded **Arweave** key, import it via `ARWEAVE_JWK`/`ABX_ARWEAVE_KEY_FILE`.
|
|
37
|
-
- **If the Stripe link fails**, fall back to Turbo's hosted top-up (`https://turbo-topup.com`) and fund the **exact address `abx storage topup` prints** (it accepts a recipient address, so credits still land on the intended identity). Not ideal, but it beats abandoning Arweave for IPFS on a link glitch.
|
|
34
|
+
Storage can be on-chain while resolution is hosted, or external while metadata resolution is
|
|
35
|
+
on-chain. Keep those axes separate.
|
|
38
36
|
|
|
39
|
-
|
|
37
|
+
## Choose managed or creator-operated resolution
|
|
40
38
|
|
|
41
|
-
|
|
39
|
+
Both routes implement the same public resolver contract. The token holds a base URI; the operator
|
|
40
|
+
reconstructs canonical state from chain and serves metadata/live/data surfaces.
|
|
42
41
|
|
|
43
|
-
|
|
44
|
-
- **"…has already been uploaded to this service!" is SUCCESS, not failure.** Turbo deduplicates identical bytes (same signer + bytes → same data-item id), so re-uploads (a retry, a redeploy, two identical images) return that sentence instead of JSON. The CLI treats it as the existing txid and continues. If you ever see it surface as an error, the toolkit is stale — don't work around it.
|
|
45
|
-
- **Check BOTH balances before concluding "needs funding."** `abx storage balance --backend arweave` prints the managed key's balance **and** the deployer wallet's Turbo balance (Turbo exposes balance-by-address publicly — no key needed). The managed key showing 0 does NOT mean "top up": if the **wallet** has credits, use them (`--storage-signer eth`, or `+ --sign` for a browser wallet). The pre-upload funds guard does this check for you and recommends the wallet lane when it applies — checking only the managed key's 0 and pushing a top-up is the classic wrong turn.
|
|
46
|
-
- **Don't reflexively push a $5 top-up or "switch to IPFS."** Both throw away what the creator chose (their funded wallet credits; permanence). Only top up if *neither* the managed key nor the wallet can cover the bytes — and **back up the managed key first** (`abx storage backup-key --out <path>`), since it will hold the credits you buy. Only suggest IPFS if they ask or Arweave is truly unavailable.
|
|
47
|
-
- **A blind retry re-signs the same bytes → same dedup reply.** Retry only after you've identified and fixed the actual cause.
|
|
48
|
-
- **Gateway swappable, integrity independent.** The on-chain keccak256 is the anchor; `arweave.net` is the default gateway (`--gateway` to override). A gateway issue is a re-point, never a lost asset.
|
|
49
|
-
- **Provider swappable.** `--provider http-bundler --upload-url <bundler>` uses a dep-free token-authed endpoint you run (secret `ARWEAVE_UPLOAD_TOKEN`); funding then means "fund the wallet directly" (only Turbo tracks credits). Default to Turbo unless asked.
|
|
42
|
+
### Managed remote
|
|
50
43
|
|
|
51
|
-
|
|
44
|
+
Use a named remote already configured in the environment rather than standing up duplicate
|
|
45
|
+
infrastructure. Start with:
|
|
52
46
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
- **Mixed extensions → per-token `url`** fields (O(N)) — still no server. A uniform extension unlocks the single-template path; flag it if a folder is mixed.
|
|
57
|
-
- **`cloud` (S3/R2/CDN)** works the same but needs a **public read base** (`--public-base` / `ABX_S3_PUBLIC_BASE`, also what `deploy-code --image-base` takes), **distinct from the signed-API `--endpoint`/`ABX_S3_ENDPOINT`** — they are different hosts. ⚠ **R2:** `https://<acct>.r2.cloudflarestorage.com` is the *API endpoint* (auth-only, never public → 403 for marketplaces); the public read URL is a `https://pub-<hash>.r2.dev` you ENABLE in the dashboard, or a custom domain. AWS: a public-read bucket or a CloudFront domain. The full set: `ABX_S3_ENDPOINT`/`BUCKET`/`REGION`/`ACCESS_KEY_ID`/`SECRET_ACCESS_KEY` + `ABX_S3_PUBLIC_BASE` (`abx storage show` prints them). Files upload under a content-derived prefix → `<publicBase>/<prefix>/{id}.png`. **Caveat:** S3 is centralized, mutable, not content-addressed (no CID/txid root). Bake a domain/CDN you control. Good if the creator already runs a bucket/CDN; IPFS/Arweave are the trustless/permanent options.
|
|
58
|
-
- **Integrity** (IPFS/Arweave) comes from the content-addressed root (CID / manifest txid), not a per-token keccak. The gateway host is baked on-chain → moving gateways is a `set-field` (bytes stay put). Prefer a **dedicated** gateway.
|
|
59
|
-
- **`url-template`** is a first-class representation ([spec](../../../../specs/protocol/onchain-metadata.md)); set by hand with `abx set-field <addr> --collection --field image --representation url-template --text "<gateway>/ipfs/<cid>/{id}.png"` then `abx set-renderer <addr>`.
|
|
47
|
+
```bash
|
|
48
|
+
abx remote <name>
|
|
49
|
+
```
|
|
60
50
|
|
|
61
|
-
|
|
51
|
+
`abx` is the built-in name for the first-party service at `services.abx.io`; it needs only
|
|
52
|
+
`ABX_SERVICES_API_KEY`, not a remote URL variable. Read [services.md](services.md) for its verified
|
|
53
|
+
OAuth login, manual recovery path, current access model, and provider-feedback path. Other providers
|
|
54
|
+
use their configured name.
|
|
62
55
|
|
|
63
|
-
|
|
56
|
+
This reports the service descriptor, supported chains, rendering policy, and authentication status.
|
|
57
|
+
Do not infer provider capability from its hostname or marketing page.
|
|
64
58
|
|
|
65
|
-
|
|
59
|
+
Interpret control-plane failures precisely:
|
|
66
60
|
|
|
67
|
-
|
|
61
|
+
- `401` means the supplied token is missing, stale, or invalid; replace the credential.
|
|
62
|
+
- `403` means the credential is recognized but lacks permission for this chain/project; fix provider
|
|
63
|
+
scope rather than rotating keys blindly.
|
|
64
|
+
- a conformance failure means the service contract is incomplete or incompatible; do not register a
|
|
65
|
+
production launch until the failing assertion is understood.
|
|
68
66
|
|
|
69
|
-
|
|
67
|
+
Register or operate a project using `--remote <name>` and monitor with `abx status --remote <name>`.
|
|
68
|
+
If the provider advertises managed rendering, confirm it for the active chain/project. Otherwise the
|
|
69
|
+
creator still owns the effects and storage path.
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
Never invent a provider, auth flow, price, quota, or key source. If no configured provider exists,
|
|
72
|
+
offer the fully supported creator-operated route.
|
|
72
73
|
|
|
73
|
-
|
|
74
|
+
### Creator-operated resolver
|
|
74
75
|
|
|
75
|
-
|
|
76
|
+
Use `abx deploy-resolver --provider …` to generate hosting artifacts for the selected platform. The
|
|
77
|
+
creator owns the cloud account, domain, secrets, monitoring, and upgrades. Review the generated
|
|
78
|
+
configuration before deploying it; do not copy repository `.env` wholesale.
|
|
76
79
|
|
|
77
|
-
|
|
80
|
+
The host needs read-only RPC access, storage access where applicable, and a stable public URL. Keep
|
|
81
|
+
signing keys off the resolver. Use the project/state API and on-chain reconstruction instead of a
|
|
82
|
+
private source-of-truth database.
|
|
78
83
|
|
|
79
|
-
|
|
80
|
-
|
|
84
|
+
Prefer a creator-controlled domain in the on-chain base URI. Provider-specific hostnames work, but a
|
|
85
|
+
custom domain makes migration a DNS operation rather than a contract operation. Tunnels and localhost
|
|
86
|
+
are preview-only and must never be baked into a launch.
|
|
81
87
|
|
|
82
|
-
|
|
88
|
+
After provisioning:
|
|
83
89
|
|
|
84
|
-
|
|
90
|
+
1. Run health/conformance checks.
|
|
91
|
+
2. Register the contract with its deploy block when known.
|
|
92
|
+
3. Wait for indexing readiness.
|
|
93
|
+
4. Fetch contract and token metadata through the public URL.
|
|
94
|
+
5. Verify byte commitments with `abx verify`.
|
|
95
|
+
6. Mint only after required token-specific surfaces can become ready.
|
|
85
96
|
|
|
86
|
-
|
|
87
|
-
- **Local resolver** (`abx serve` here): a local `deploy`/`add` already indexed it — done.
|
|
88
|
-
- **Remote resolver** (baked URL is hosted): after deploy run **`abx add <clone> --remote [url]`** to register + index it on the node (url defaults to `ABX_PUBLIC_BASE_URL`; needs `ABX_RESOLVER_ADMIN_TOKEN` matching the resolver). Also **bridges** what the node can't derive: the durable `ipfs://`/`ar://` locator and off-chain traits. Post-deploy nudge (after a deferred mint) is **`abx index <clone> --remote`** (idempotent). Remove with **`abx forget <clone> --remote`**. Every remote command prints `REMOTE → <url>`.
|
|
97
|
+
## Choose storage independently
|
|
89
98
|
|
|
90
|
-
|
|
99
|
+
Storage is stateless configuration selected per command or through environment defaults. Inspect the
|
|
100
|
+
resolved choice with:
|
|
91
101
|
|
|
92
|
-
The deploy address is deterministic (`predict` = a pure function of factory + salt), so have the resolver watch the address *before* the token mints — metadata is live the instant a marketplace sees it, no cached blank:
|
|
93
102
|
```bash
|
|
94
|
-
abx
|
|
95
|
-
abx add <predicted> --remote --from-block <now> # 2. resolver starts WATCHING that address (nothing there yet)
|
|
96
|
-
ABX_PUBLIC_BASE_URL=https://meta.you.xyz abx deploy --image ./art.png --name "Aurora" --salt <salt> # 3. deploy + MINT in one tx (same salt!)
|
|
97
|
-
abx add <predicted> --remote # 4. one nudge → pulls the deploy events + bridges the image locator
|
|
98
|
-
abx refresh <predicted> # 5. marketplaces (already resolvable → they cache the real thing)
|
|
103
|
+
abx storage show --check
|
|
99
104
|
```
|
|
100
|
-
Use the **exact `--salt` that `predict` printed** in step 3 (a plain `deploy` reserves a *different* salt → a different address than the resolver is watching). `--from-block <now>` = current block (`cast block-number`, or just `0` on a quiet testnet).
|
|
101
105
|
|
|
102
|
-
|
|
106
|
+
| Backend | Good for | Operator responsibility |
|
|
107
|
+
|---|---|---|
|
|
108
|
+
| `fs` | local development | disk durability and no public reach by default |
|
|
109
|
+
| `cloud` | mutable/fast public assets | bucket, auth endpoint, public read base/CDN, retention |
|
|
110
|
+
| `ipfs` | content-addressed distribution | pinning and public gateway availability |
|
|
111
|
+
| `arweave` | permanent external custody | upload identity/credits and propagation |
|
|
103
112
|
|
|
104
|
-
|
|
113
|
+
Never silently fall back to `fs` when a selected backend is incomplete. Fix the missing configuration
|
|
114
|
+
or change the plan explicitly.
|
|
105
115
|
|
|
106
|
-
###
|
|
116
|
+
### Cloud
|
|
107
117
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
118
|
+
Separate the authenticated S3/R2 API endpoint used for writes from the public HTTP base used by
|
|
119
|
+
collectors. An R2 S3 endpoint is not a marketplace image URL. `--check` performs a real write/read
|
|
120
|
+
round trip through the public base; require it to pass.
|
|
121
|
+
|
|
122
|
+
### IPFS
|
|
123
|
+
|
|
124
|
+
Pinning success and gateway retrieval are distinct. Use a durable pinning service and public gateway
|
|
125
|
+
for launches. A local kubo node is suitable for development only. The on-chain field may hold the
|
|
126
|
+
bare CID while a collection gateway preference chooses the serving prefix; `abx set-gateway` can
|
|
127
|
+
change that prefix without changing the content.
|
|
128
|
+
|
|
129
|
+
### Arweave
|
|
130
|
+
|
|
131
|
+
The accepted upload and a retrievable gateway object are separate lifecycle states. Use
|
|
132
|
+
`abx storage status <locator> --json`; wait for `ready` instead of uploading duplicates during
|
|
133
|
+
propagation. Upload deduplication is success, not an instruction to top up or switch backends.
|
|
134
|
+
|
|
135
|
+
Turbo credits attach to the signing identity. `abx storage balance` reports the managed identity and
|
|
136
|
+
wallet-related lanes; choose the intended payer before funding. Back up the managed key using the
|
|
137
|
+
dedicated command and never expose the JWK.
|
|
138
|
+
|
|
139
|
+
### Publication bridge
|
|
117
140
|
|
|
118
|
-
|
|
141
|
+
An effects runner stores rendered bytes, then publishes their locator to the resolver. The resolver
|
|
142
|
+
usually redirects to that public object rather than proxying it. Therefore the storage backend must be
|
|
143
|
+
reachable from both the runner and collectors. A local `fs` output from one machine is orphaned when
|
|
144
|
+
the public resolver runs elsewhere.
|
|
119
145
|
|
|
120
|
-
|
|
121
|
-
- `GET /` — read-only index of served contracts · `GET /t/<chainId>/<address>/0` — ERC-721 metadata · `…/0/image` — the image
|
|
122
|
-
- `GET /c/<chainId>/<address>` — ERC-7572 collection metadata · `GET /api/project/<address>` — full reconstructed state · `GET /d/<chainId>/<address>` — per-contract read-only dashboard (namespaced so one host serves many contracts). No public action buttons anywhere.
|
|
123
|
-
- For IPFS/Arweave the served `image` is the **gateway HTTPS URL** (`https://<gateway>/ipfs/<cid>` / `<gateway>/<txid>`), the form wallets/marketplaces render (raw `ipfs://` doesn't). The on-chain commitment is the **keccak256** (backend-neutral anchor, survives a gateway migration); the CID/txid is just the locator. The locator lives in the **deployer's** local index, so a **remote** resolver emits the gateway URL only once it's bridged (`abx add <clone> --remote`), else `image` falls back to the resolver's own `/…/image` route.
|
|
124
|
-
- `POST /api/project/<address>/reindex` (full replay) · `GET /api/project/<address>/verify` — both **admin-only** (bearer `ABX_RESOLVER_ADMIN_TOKEN`), never exposed as public actions. Run from the CLI: `abx index <addr> --remote` / `abx verify <addr>`.
|
|
125
|
-
- `POST /admin/projects` `{address, fromBlock?, factory?, description?, externalUrl?, attributes?, contentLocators?}` + `DELETE /admin/projects/<address>` — the **admin control plane** (register/forget which contracts the node indexes, bridge off-chain traits + locators; a remote `add`/`forget`). Bearer-gated, disabled when the var is unset. Indexing control only — never signing.
|
|
146
|
+
## Operate resolver and effects services
|
|
126
147
|
|
|
127
|
-
|
|
148
|
+
The resolver handles indexed state and public metadata/live/data routes. The effects service executes
|
|
149
|
+
programs and publishes stills/traits. Deploy them separately so heavy browser work does not destabilize
|
|
150
|
+
metadata reads.
|
|
128
151
|
|
|
129
|
-
|
|
152
|
+
For an active JavaScript sale, run continuous effects. For a fixed supply or repair, a one-shot render
|
|
153
|
+
may be sufficient. With an on-chain Solidity image renderer, no effects service is needed for the
|
|
154
|
+
image; do not deploy infrastructure merely because the collection is a code contract.
|
|
130
155
|
|
|
131
|
-
|
|
156
|
+
Protect public effects endpoints with the generated token. An unauthenticated force-render endpoint
|
|
157
|
+
can burn compute and storage. Keep resolver admin/effects credentials separate from wallet signing.
|
|
158
|
+
|
|
159
|
+
Verify the operational graph:
|
|
160
|
+
|
|
161
|
+
1. Resolver can reconstruct chain state from its configured RPC.
|
|
162
|
+
2. Effects can load the exact live document for a minted id.
|
|
163
|
+
3. Effects storage produces a publicly retrievable locator.
|
|
164
|
+
4. Resolver publishes or redirects to that locator.
|
|
165
|
+
5. Token metadata exposes the resulting image/attributes.
|
|
166
|
+
6. A PostParam change reaches the watcher and creates the next inputs-hash render.
|
|
167
|
+
|
|
168
|
+
## Use lifecycle states
|
|
169
|
+
|
|
170
|
+
Prefer status over retries. Typical nonterminal states include deployment accepted, indexing,
|
|
171
|
+
storage propagating, render queued/running, and remote registration pending. Typical terminal faults
|
|
172
|
+
include authentication/authorization failure, invalid contract/chain, interface mismatch, failed
|
|
173
|
+
transaction, integrity mismatch, and unsupported configuration.
|
|
174
|
+
|
|
175
|
+
Use:
|
|
132
176
|
|
|
133
|
-
The container is **emitted by `deploy-resolver --provider vps`** — it writes `deploy/vps/` with a `Dockerfile` + `docker-compose.yml` + `Caddyfile` + `setup.sh`, self-contained. Don't hand-write a Dockerfile or compose file. Run compose **from that dir**:
|
|
134
177
|
```bash
|
|
135
|
-
|
|
136
|
-
|
|
178
|
+
abx status [address] --watch
|
|
179
|
+
abx status <address> --remote <name> --watch
|
|
180
|
+
abx storage status <locator> --json
|
|
181
|
+
abx verify <address> --json
|
|
137
182
|
```
|
|
138
|
-
|
|
183
|
+
|
|
184
|
+
Wait on nonterminal states using the command's watcher/backoff. Do not wrap the CLI in a second tight
|
|
185
|
+
poller. Do not retry terminal 4xx responses or reverted transactions unchanged. Read
|
|
186
|
+
[diagnose.md](diagnose.md) for the one-transition recovery model.
|
|
187
|
+
|
|
188
|
+
## Migrate without losing canonicity
|
|
189
|
+
|
|
190
|
+
Migration changes a public projection, not canonical on-chain history. Use `abx migrate` to copy and
|
|
191
|
+
compare resolver state without cutting over prematurely.
|
|
192
|
+
|
|
193
|
+
1. Resolve the source and destination descriptors and credentials.
|
|
194
|
+
2. Confirm both support the active chain and contract type.
|
|
195
|
+
3. Reconstruct/register the destination from chain using the deploy block.
|
|
196
|
+
4. Copy only off-chain operator state and published artifact locators that are not derivable from chain.
|
|
197
|
+
5. Verify contract metadata, representative token metadata, fields, attachments, renders, and byte
|
|
198
|
+
commitments on both sides.
|
|
199
|
+
6. Cut over via DNS when using a stable creator domain, or change the on-chain URI pointer only after
|
|
200
|
+
parity is proven.
|
|
201
|
+
7. Re-emit URI/refresh signals as required, then monitor the destination.
|
|
202
|
+
8. Keep the old service until marketplace and collector paths have converged.
|
|
203
|
+
|
|
204
|
+
Never describe resolver migration as moving the NFT. Ownership, parameters, commitments, and canonical
|
|
205
|
+
events remain on-chain; only the serving/indexing projection changes.
|