@artblocks/abx-token-api 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.
- package/CHANGELOG.md +31 -1244
- package/dist/code.js +3 -5
- package/dist/code.js.map +1 -1
- package/dist/control-plane.d.ts +2 -2
- package/dist/control-plane.d.ts.map +1 -1
- package/dist/control-plane.js +6 -7
- package/dist/control-plane.js.map +1 -1
- package/dist/deps.d.ts +2 -2
- package/dist/deps.js +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/metadata.d.ts +60 -3
- package/dist/metadata.d.ts.map +1 -1
- package/dist/metadata.js +47 -3
- package/dist/metadata.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +31 -7
- package/dist/server.js.map +1 -1
- package/dist/watcher.d.ts +1 -1
- package/dist/watcher.js +1 -1
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,1258 +1,45 @@
|
|
|
1
1
|
# @artblocks/abx-token-api
|
|
2
2
|
|
|
3
|
-
## 0.1.0-alpha.
|
|
4
|
-
|
|
5
|
-
### Patch Changes
|
|
6
|
-
|
|
7
|
-
- Updated dependencies [c198237]
|
|
8
|
-
- @artblocks/abx-sdk@0.1.0-alpha.29
|
|
9
|
-
- @artblocks/abx-indexer@0.1.0-alpha.30
|
|
10
|
-
- @artblocks/abx-storage@0.1.0-alpha.29
|
|
11
|
-
|
|
12
|
-
## 0.1.0-alpha.31
|
|
13
|
-
|
|
14
|
-
### Patch Changes
|
|
15
|
-
|
|
16
|
-
- c5e0d84: Published package `homepage` and `bugs` fields now point at docs.abx.io instead of a private GitHub
|
|
17
|
-
repo that 404s. File reports with `abx feedback`; `npm bugs` no longer names a repository the public
|
|
18
|
-
cannot open.
|
|
19
|
-
|
|
20
|
-
Reported in the 2026-08-27 tester batch (feedback 40142396).
|
|
21
|
-
|
|
22
|
-
- Updated dependencies [c5e0d84]
|
|
23
|
-
- Updated dependencies [c5e0d84]
|
|
24
|
-
- @artblocks/abx-sdk@0.1.0-alpha.28
|
|
25
|
-
- @artblocks/abx-indexer@0.1.0-alpha.29
|
|
26
|
-
- @artblocks/abx-storage@0.1.0-alpha.28
|
|
27
|
-
|
|
28
|
-
## 0.1.0-alpha.30
|
|
29
|
-
|
|
30
|
-
### Patch Changes
|
|
31
|
-
|
|
32
|
-
- Updated dependencies [4072f0c]
|
|
33
|
-
- @artblocks/abx-sdk@0.1.0-alpha.27
|
|
34
|
-
- @artblocks/abx-indexer@0.1.0-alpha.28
|
|
35
|
-
- @artblocks/abx-storage@0.1.0-alpha.27
|
|
36
|
-
|
|
37
|
-
## 0.1.0-alpha.29
|
|
38
|
-
|
|
39
|
-
### Patch Changes
|
|
40
|
-
|
|
41
|
-
- Updated dependencies [b182f23]
|
|
42
|
-
- @artblocks/abx-sdk@0.1.0-alpha.26
|
|
43
|
-
- @artblocks/abx-indexer@0.1.0-alpha.27
|
|
44
|
-
- @artblocks/abx-storage@0.1.0-alpha.26
|
|
45
|
-
|
|
46
|
-
## 0.1.0-alpha.28
|
|
47
|
-
|
|
48
|
-
### Patch Changes
|
|
49
|
-
|
|
50
|
-
- Updated dependencies [8f2f78a]
|
|
51
|
-
- @artblocks/abx-sdk@0.1.0-alpha.25
|
|
52
|
-
- @artblocks/abx-indexer@0.1.0-alpha.26
|
|
53
|
-
- @artblocks/abx-storage@0.1.0-alpha.25
|
|
54
|
-
|
|
55
|
-
## 0.1.0-alpha.27
|
|
56
|
-
|
|
57
|
-
### Patch Changes
|
|
58
|
-
|
|
59
|
-
- Updated dependencies [61503c3]
|
|
60
|
-
- @artblocks/abx-sdk@0.1.0-alpha.24
|
|
61
|
-
- @artblocks/abx-indexer@0.1.0-alpha.25
|
|
62
|
-
- @artblocks/abx-storage@0.1.0-alpha.24
|
|
63
|
-
|
|
64
|
-
## 0.1.0-alpha.26
|
|
65
|
-
|
|
66
|
-
### Patch Changes
|
|
67
|
-
|
|
68
|
-
- bd77ba2: Correct the Node floor to 22.13, and refuse to start with a remedy instead of a stack trace.
|
|
69
|
-
|
|
70
|
-
Every package declared `engines.node: ">=22.5.0"` — the version `node:sqlite` was **added**, not the
|
|
71
|
-
version it became usable. It shipped in v22.5.0 behind `--experimental-sqlite` and lost the flag in
|
|
72
|
-
v22.13.0 / v23.4.0. So `npm i -g @artblocks/abx-cli` on Node 22.5 installed silently (the engine
|
|
73
|
-
range was satisfied) and then `abx doctor` — the first command we tell everyone to run — died with a
|
|
74
|
-
raw `ERR_UNKNOWN_BUILTIN_MODULE: No such built-in module: node:sqlite` stack trace naming neither
|
|
75
|
-
abx nor a fix. Reported 2026-08-24; the floor is now `>=22.13.0` everywhere, so npm warns at install
|
|
76
|
-
time.
|
|
77
|
-
|
|
78
|
-
The crash happened while ESM _linked_ `main.ts`'s import graph (`output.ts` →
|
|
79
|
-
`@artblocks/abx-indexer` → `node:sqlite`), before any of our code ran, so no guard inside the CLI
|
|
80
|
-
could have caught it. The published binary is now a deliberately import-free shim (`dist/bin.js`)
|
|
81
|
-
that probes for `node:sqlite` and hands off to `main.js` — it prints the running version, the real
|
|
82
|
-
floor, and the upgrade command. It probes the **capability**, not the version number: an old Node
|
|
83
|
-
launched with `NODE_OPTIONS=--experimental-sqlite` genuinely works, and refusing that would be a
|
|
84
|
-
false negative. `engines` states what we support; the guard blocks only what is actually broken.
|
|
85
|
-
|
|
86
|
-
`abx doctor`'s header now also reports the running Node, since its output is what people paste when
|
|
87
|
-
something is wrong.
|
|
88
|
-
|
|
89
|
-
- Updated dependencies [bd77ba2]
|
|
90
|
-
- @artblocks/abx-indexer@0.1.0-alpha.24
|
|
91
|
-
- @artblocks/abx-storage@0.1.0-alpha.23
|
|
92
|
-
- @artblocks/abx-sdk@0.1.0-alpha.23
|
|
93
|
-
|
|
94
|
-
## 0.1.0-alpha.25
|
|
95
|
-
|
|
96
|
-
### Patch Changes
|
|
97
|
-
|
|
98
|
-
- 549a32d: The live-view route (`/a/:chainId/:address/:id`) tells the truth for renderer-only projects and for
|
|
99
|
-
ERC-1155 editions. Two inverse bugs in one branch:
|
|
100
|
-
|
|
101
|
-
- **A renderer-only code project answered `503 + Retry-After` forever.** `deploy-code --image-renderer
|
|
102
|
-
… --onchain-uri` with no `--script` has no program and never will — image and traits are computed in
|
|
103
|
-
Solidity. The route told callers to keep retrying for content that does not exist. It is now the
|
|
104
|
-
terminal 404, which is the honest answer: there is no live view here, by design.
|
|
105
|
-
- **`edition-code` was missing from the code-contract check**, so an EditionCode whose chunks had not
|
|
106
|
-
been folded in yet answered the _terminal_ 404 instead of the retryable 503 — the exact inverse
|
|
107
|
-
failure the mid-index case was written to prevent, on the ERC-1155 lane.
|
|
108
|
-
|
|
109
|
-
The two are separated by `script.chunkCount`, which is a head read: a number is what the chain says
|
|
110
|
-
right now, so `0` means there is nothing to wait for, while `null` means nobody has asked yet and the
|
|
111
|
-
honest answer to unknown stays the retryable one.
|
|
112
|
-
|
|
113
|
-
Newly relevant because `deploy-code --copies --image-renderer` now makes a fully on-chain ERC-1155 a
|
|
114
|
-
supported lane, and every project on it is renderer-only.
|
|
115
|
-
|
|
116
|
-
- Updated dependencies [993e095]
|
|
117
|
-
- @artblocks/abx-sdk@0.1.0-alpha.22
|
|
118
|
-
- @artblocks/abx-indexer@0.1.0-alpha.23
|
|
119
|
-
- @artblocks/abx-storage@0.1.0-alpha.22
|
|
120
|
-
|
|
121
|
-
## 0.1.0-alpha.24
|
|
122
|
-
|
|
123
|
-
### Patch Changes
|
|
124
|
-
|
|
125
|
-
- Updated dependencies [c9f7aeb]
|
|
126
|
-
- @artblocks/abx-sdk@0.1.0-alpha.21
|
|
127
|
-
- @artblocks/abx-storage@0.1.0-alpha.21
|
|
128
|
-
- @artblocks/abx-indexer@0.1.0-alpha.22
|
|
129
|
-
|
|
130
|
-
## 0.1.0-alpha.23
|
|
131
|
-
|
|
132
|
-
### Patch Changes
|
|
133
|
-
|
|
134
|
-
- Updated dependencies [84ca9dd]
|
|
135
|
-
- Updated dependencies [84ca9dd]
|
|
136
|
-
- @artblocks/abx-sdk@0.1.0-alpha.20
|
|
137
|
-
- @artblocks/abx-indexer@0.1.0-alpha.21
|
|
138
|
-
- @artblocks/abx-storage@0.1.0-alpha.20
|
|
139
|
-
|
|
140
|
-
## 0.1.0-alpha.22
|
|
141
|
-
|
|
142
|
-
### Patch Changes
|
|
143
|
-
|
|
144
|
-
- Updated dependencies [b1c333d]
|
|
145
|
-
- Updated dependencies [b1c333d]
|
|
146
|
-
- @artblocks/abx-sdk@0.1.0-alpha.19
|
|
147
|
-
- @artblocks/abx-indexer@0.1.0-alpha.20
|
|
148
|
-
- @artblocks/abx-storage@0.1.0-alpha.19
|
|
149
|
-
|
|
150
|
-
## 0.1.0-alpha.21
|
|
151
|
-
|
|
152
|
-
### Patch Changes
|
|
153
|
-
|
|
154
|
-
- Updated dependencies [77a6248]
|
|
155
|
-
- Updated dependencies [77a6248]
|
|
156
|
-
- @artblocks/abx-sdk@0.1.0-alpha.18
|
|
157
|
-
- @artblocks/abx-indexer@0.1.0-alpha.19
|
|
158
|
-
- @artblocks/abx-storage@0.1.0-alpha.18
|
|
159
|
-
|
|
160
|
-
## 0.1.0-alpha.20
|
|
161
|
-
|
|
162
|
-
### Minor Changes
|
|
163
|
-
|
|
164
|
-
- c5b8ec3: `ipfs` and `arweave` metadata fields now resolve on both planes, through a gateway the collection
|
|
165
|
-
chooses — renderer **spec v11**.
|
|
166
|
-
|
|
167
|
-
These are the two representations that are content-addressed, the two where the locator IS the
|
|
168
|
-
integrity hash, and the two this protocol tells creators to prefer. They were also the two the
|
|
169
|
-
on-chain renderer could not serve. So `abx deploy --onchain-uri --backend ipfs|arweave` worked around
|
|
170
|
-
it by baking a gateway HOST into a `url` field, which welded a hostname the creator could never
|
|
171
|
-
migrate and made `abx_provenance` report `source: url` for bytes that live on IPFS.
|
|
172
|
-
|
|
173
|
-
The fix separates the two facts that the baked URL had fused. The CID/txid stays in the field, as
|
|
174
|
-
identity, under that field's own lock. The HTTPS prefix becomes a project-wide preference in two
|
|
175
|
-
reserved collection-scope fields, `abx_gateway_ipfs` / `abx_gateway_arweave`, with `https://ipfs.io/ipfs/`
|
|
176
|
-
and `https://arweave.net/` as floors. The renderer, the canonical generator, and the off-chain
|
|
177
|
-
resolver all read those two fields and apply the same wrap, so a token served from the chain and from
|
|
178
|
-
a resolver produces the same URL.
|
|
179
|
-
|
|
180
|
-
A dead or slow gateway is now a **repoint**, not a rewrite:
|
|
181
|
-
|
|
182
|
-
```bash
|
|
183
|
-
abx set-gateway 0xYourContract --ipfs https://your-dedicated.mypinata.cloud/ipfs/
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
One transaction, every token, no re-upload — and it works on fields you have already locked, because
|
|
187
|
-
the locked value is the CID and the gateway was never in it.
|
|
188
|
-
|
|
189
|
-
**What changes for you**
|
|
190
|
-
|
|
191
|
-
- `--onchain-uri --backend ipfs|arweave` writes the bare CID (or `cid/{id}.ext` for the O(1) directory)
|
|
192
|
-
as an `ipfs`/`arweave` field instead of a gateway URL as `url`/`url-template`. `--backend cloud` is
|
|
193
|
-
unchanged — an HTTPS CDN locator _is_ the address.
|
|
194
|
-
- New `abx set-gateway <addr> [--ipfs <prefix>] [--arweave <prefix>]` (`none` clears to the public
|
|
195
|
-
default). Two flags, so a project can pay for a dedicated IPFS gateway and leave Arweave public.
|
|
196
|
-
- New `--ipfs-gateway` / `--arweave-gateway` on every deploy command. Plain `--gateway` (the
|
|
197
|
-
storage/upload gateway) seeds the preference for the backend in use, so passing it still does what
|
|
198
|
-
you meant. Nothing is written when no gateway is named — silence keeps the floor live.
|
|
199
|
-
- `abx set-field` refuses the two gateway keys and points at `set-gateway`, which validates the
|
|
200
|
-
prefix, the scope and the representation. Every way to set them by hand fails silently.
|
|
201
|
-
- The `display.gateway` contract param is **superseded and no longer read**. It could name only one
|
|
202
|
-
prefix for both schemes and existed only on code projects.
|
|
203
|
-
- SDK: `projectGatewayPrefix`, `projectGatewayUrl`, `gatewayPrefixFrom`, `contentIdFromLocator`,
|
|
204
|
-
`GATEWAY_FIELD`, `GATEWAY_FLOOR`. For a host running its own resolver, `ABX_IPFS_GATEWAY` /
|
|
205
|
-
`ABX_ARWEAVE_GATEWAY` are now a **floor**: a project that stated a preference on chain gets that
|
|
206
|
-
preference from every conforming resolver, and host config only fills a silence.
|
|
207
|
-
|
|
208
|
-
**New canonical addresses** (both testnets; nothing else moved — no token implementation, factory, or
|
|
209
|
-
`initialize` ABI changed):
|
|
210
|
-
|
|
211
|
-
| Contract | Address |
|
|
212
|
-
| -------------------------------- | -------------------------------------------- |
|
|
213
|
-
| `AbxMetadataRenderer` (spec v11) | `0x85C1aE1F076d808fF7c1729F21B85038Fa16105E` |
|
|
214
|
-
| `AbxGenerator` (Sepolia) | `0xb7104AdFa6Fb5615e46E2a681A2Ff043B08fADB5` |
|
|
215
|
-
| `AbxGenerator` (Base Sepolia) | `0x2c1b7Cf6C54E4acBcB54FCc395f7Af88eB4fC8Ce` |
|
|
216
|
-
|
|
217
|
-
Also fixes a crash on `abx deploy-code --copies`: an undefined `bytes` reference threw a
|
|
218
|
-
`ReferenceError` at the end of the dry-run plan and, worse, at the confirmation prompt of a real
|
|
219
|
-
deploy.
|
|
220
|
-
|
|
221
|
-
### Patch Changes
|
|
222
|
-
|
|
223
|
-
- 5b29f53: Drop-in for every reconstruct caller; new exports for hosted/self-host watch loops so they stop
|
|
224
|
-
reimplementing `eth_getLogs` chunking and a second per-project fetch.
|
|
225
|
-
|
|
226
|
-
**`getLogsAdaptive` is public and accepts `Address | Address[]`.** Address-list chunking defaults to
|
|
227
|
-
1000 (ordinary RPC tier cap) via `addressBatch` — an RPC opinion, not a protocol constant; `0`
|
|
228
|
-
disables splitting. Per-tick block windows stay with the watcher (the reference one still uses 5000).
|
|
229
|
-
|
|
230
|
-
**`reconstructFromLogs(client, prior, logs, {toBlock})`** is the fold / head-read half of
|
|
231
|
-
`reconstructIncremental` given logs the caller already holds. `toBlock` is the inclusive scan head
|
|
232
|
-
those logs cover, so a capped window cannot stamp past the last block actually scanned.
|
|
233
|
-
`reconstructIncremental` is now a getLogs + that function.
|
|
234
|
-
|
|
235
|
-
**A Transfer no longer re-downloads every on-chain script chunk.** Chunk content has no log;
|
|
236
|
-
`ScriptUpdated` is the ping. `applyHeadReads` keeps the prior digest unless that ping is in `fresh`
|
|
237
|
-
(or the prior digest is missing). Same change helps the single-address path.
|
|
238
|
-
|
|
239
|
-
The reference token-api watcher now calls `getLogsAdaptive` for the registered set and hands each
|
|
240
|
-
touched project's logs to `reindex({logs, toBlock})`, so the watch tick is the only getLogs.
|
|
241
|
-
|
|
242
|
-
- Updated dependencies [c5b8ec3]
|
|
243
|
-
- Updated dependencies [5b29f53]
|
|
244
|
-
- @artblocks/abx-sdk@0.1.0-alpha.17
|
|
245
|
-
- @artblocks/abx-indexer@0.1.0-alpha.18
|
|
246
|
-
- @artblocks/abx-storage@0.1.0-alpha.17
|
|
247
|
-
|
|
248
|
-
## 0.1.0-alpha.19
|
|
249
|
-
|
|
250
|
-
### Patch Changes
|
|
251
|
-
|
|
252
|
-
- Updated dependencies [9c287c0]
|
|
253
|
-
- Updated dependencies [b5744a1]
|
|
254
|
-
- Updated dependencies [9c287c0]
|
|
255
|
-
- @artblocks/abx-sdk@0.1.0-alpha.16
|
|
256
|
-
- @artblocks/abx-indexer@0.1.0-alpha.17
|
|
257
|
-
- @artblocks/abx-storage@0.1.0-alpha.16
|
|
258
|
-
|
|
259
|
-
## 0.1.0-alpha.18
|
|
260
|
-
|
|
261
|
-
### Minor Changes
|
|
262
|
-
|
|
263
|
-
- 7fec2d7: Off chain, `animation_url` is now a link to this node's route instead of an inlined `data:` URI
|
|
264
|
-
|
|
265
|
-
The two URI-valued keys disagreed about the same thing. For on-chain **content**, `image` has always
|
|
266
|
-
been served as a link to the resolver's route — bytes should not ride inside a JSON document that
|
|
267
|
-
marketplaces re-fetch on every view — while `animation_url` was inlined as
|
|
268
|
-
`data:text/html;base64,…`. That is backwards on the rule's own logic: `animation_url` is usually the
|
|
269
|
-
_larger_ asset.
|
|
270
|
-
|
|
271
|
-
Worse, a reserved key's resolved value is repeated verbatim into the `artifacts` listing, so an
|
|
272
|
-
inlined document shipped **twice** in one response. A 3 MB on-chain HTML artwork meant roughly 8 MB of
|
|
273
|
-
JSON per metadata fetch, of which the sibling `image` — the small one — contributed a single line.
|
|
274
|
-
|
|
275
|
-
And the inline form was already the exception rather than the rule: a code project's `animation_url`
|
|
276
|
-
has always been the live-view route. Only a project with an explicit `animation` field holding
|
|
277
|
-
on-chain content took the `data:` path.
|
|
278
|
-
|
|
279
|
-
```jsonc
|
|
280
|
-
// before // after
|
|
281
|
-
"image": "http://node/…/7/image", "image": "http://node/…/7/image",
|
|
282
|
-
"animation_url": "data:text/html;base64,PGh0…", "animation_url": "http://node/…/7/data/animation_url",
|
|
283
|
-
"artifacts": [ "artifacts": [
|
|
284
|
-
{"key":"image", "uri":"http://…"}, {"key":"image", "uri":"http://…"},
|
|
285
|
-
{"key":"animation_url", "uri":"data:text/…"} {"key":"animation_url", "uri":"http://…/data/animation_url"}
|
|
286
|
-
] ]
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
- **The bytes are unchanged and still on chain.** `abx_provenance` still reports
|
|
290
|
-
`source: inline`/`reader`/`renderer` with `status: 'on-chain'` — the route changes where the bytes
|
|
291
|
-
ride, not where they live. The route (`/…/data/{field}`, the data plane's own serving route) returns
|
|
292
|
-
them with the declared Content-Type, and 302s to a durable locator when one exists.
|
|
293
|
-
- **Locators are untouched.** `url`, `url-template`, and a computed `text/uri-list` still land verbatim
|
|
294
|
-
on both planes: they are already URIs, and re-hosting one would hide it.
|
|
295
|
-
- **The on-chain renderer is unchanged** — a contract has no URL space, so `tokenURI` still inlines the
|
|
296
|
-
document, and that self-contained form is the durability floor. **No contract changed and no address
|
|
297
|
-
moved.**
|
|
298
|
-
- **`abx inspect`'s on-chain readout is unaffected**; it reads the contract's `tokenURI`, not this
|
|
299
|
-
document.
|
|
300
|
-
|
|
301
|
-
Adopts the position the abx-services team argued while upgrading their resolver — theirs already served
|
|
302
|
-
the route form, so this closes the divergence in their favor and the reference is what changed. The
|
|
303
|
-
class was invisible to the cross-implementation parity audit, whose fixtures are client-free while the
|
|
304
|
-
`renderer` representation needs a live `eth_call`; a new `animation-route.test.ts` boots a real server
|
|
305
|
-
on a real socket and follows the link, because a value promising bytes at a URL is a dead link if
|
|
306
|
-
nothing serves that URL.
|
|
307
|
-
|
|
308
|
-
- 7fec2d7: An edition's per-id cap now folds from the log, so a capped edition stops reporting itself as open
|
|
309
|
-
|
|
310
|
-
`DefaultMaxSupplySet` — added in the contract-audit release precisely so the log could tell an open
|
|
311
|
-
edition from a capped one — reached the ABI and stopped there. `reconstruct.ts` had no fold case, so
|
|
312
|
-
the collection-wide default never landed in `ProjectState`, and **the common shape was the broken
|
|
313
|
-
one**: `--copies N` sets the cap at `initialize` and never calls `setMaxSupply`, so no id has a
|
|
314
|
-
`MaxSupplyUpdated` of its own and every capped edition ever deployed folded as _uncapped_. The
|
|
315
|
-
head-read lane (`listTokens`, which calls `maxSupply(id)`) said `N` the whole time — one field name,
|
|
316
|
-
two answers, on the value that decides whether a buy button renders. Found by the abx-services team
|
|
317
|
-
while upgrading their resolver/indexer to this release.
|
|
318
|
-
|
|
319
|
-
- **`ProjectState.defaultMaxSupply`** — the collection-wide per-id default (`'0'` = open; `null` ⇒ not
|
|
320
|
-
an edition). The 1155 analogue of `maxInvocations`.
|
|
321
|
-
- **`TokenState.maxSupply` is now the _effective_ cap** — an id's own override, else that default —
|
|
322
|
-
and so equals `maxSupply(id)` on chain and its head-read twin `TokenRow.maxSupply`. Previously it
|
|
323
|
-
was the override alone, and absent otherwise.
|
|
324
|
-
- **`TokenState.maxSupplyOverridden`** — whether this id has ever been explicitly overridden. The
|
|
325
|
-
distinction the on-chain getter cannot express (`maxSupply(id)` returns `0` for both "never capped"
|
|
326
|
-
and "deliberately closed") and the log now can, plus a signal that the monotonic never-increase rule
|
|
327
|
-
is in force for that id.
|
|
328
|
-
- **`editionCapOf(token)`** — new SDK export returning `{kind:'open'} | {kind:'capped', cap} |
|
|
329
|
-
{kind:'closed'}`, so nothing re-derives the rule. Used by the dashboard and `abx tokens`; pass a
|
|
330
|
-
head-read row and a `'0'` cap reads `open`, which is all a state read can honestly say.
|
|
331
|
-
- **The dashboard stops lying twice.** It tested `maxSupply` for truthiness: a `--copies 10` id read
|
|
332
|
-
"(open)", and — because `'0'` is a non-empty string — an id deliberately closed would have read
|
|
333
|
-
"12 / 0". It now reads "12 / 10" and "12 (closed — no more can be minted)".
|
|
334
|
-
- **Projection columns**: `projects.default_max_supply`, `tokens.max_supply_overridden` (migration-added,
|
|
335
|
-
so an existing store keeps working; NULL stays NULL rather than becoming a fabricated `0`).
|
|
336
|
-
|
|
337
|
-
Also in this pass, from the same review:
|
|
338
|
-
|
|
339
|
-
- **`SPINE_EVENT_DOC` had drifted to 41 of 52 events**, so eleven folded events carried an empty
|
|
340
|
-
human description and defaulted to Register 2 — including `TransferValidatorUpdated`, which belongs
|
|
341
|
-
to Register 1, and the factory's `Deployed`. All eleven are described, and a new
|
|
342
|
-
`spine-doc-coverage.test.ts` fails the build if the table and the spine ABI drift apart again in
|
|
343
|
-
either direction.
|
|
344
|
-
- **One provenance body in the resolver's `renderer` branch.** The `text/uri-list` arm hand-built an
|
|
345
|
-
object byte-identical to `onChainProv(field, 'renderer', …)` — same keys, same order, the note string
|
|
346
|
-
typed a second time — so the only thing that branch could do was drift from `sourceNote`.
|
|
347
|
-
- **Dead `abx_params`-era test scaffolding deleted** (a `paramsOf(json) => json.abx_params` reader, an
|
|
348
|
-
RPC stub, a schema factory), including an import of a `ParamMember` type that no longer exists —
|
|
349
|
-
which nothing caught, because `tsconfig` includes only `src`, so test files are never typechecked.
|
|
350
|
-
|
|
351
|
-
### Patch Changes
|
|
352
|
-
|
|
353
|
-
- Updated dependencies [7fec2d7]
|
|
354
|
-
- @artblocks/abx-sdk@0.1.0-alpha.15
|
|
355
|
-
- @artblocks/abx-indexer@0.1.0-alpha.16
|
|
356
|
-
- @artblocks/abx-storage@0.1.0-alpha.15
|
|
357
|
-
|
|
358
|
-
## 0.1.0-alpha.17
|
|
359
|
-
|
|
360
|
-
### Minor Changes
|
|
361
|
-
|
|
362
|
-
- 1b6b741: Rename "artist" to "creator" throughout, including the protocol vocabulary
|
|
363
|
-
|
|
364
|
-
ABX is a tool for creators generally. Art remains a first-class use case, but it should not be baked
|
|
365
|
-
into the product's framing — and it was, down to the on-chain identifiers.
|
|
366
|
-
|
|
367
|
-
**Breaking, and deliberately a clean break** (pre-launch, folded into the one redeploy that four
|
|
368
|
-
rounds of security remediation already required — deferring would have meant either living with the
|
|
369
|
-
old vocabulary permanently or spending a second deployment on a word):
|
|
370
|
-
|
|
371
|
-
- `AuthOption` is now `Creator`, `TokenOwner`, `Address`, `CreatorOrTokenOwner`, `CreatorOrAddress`,
|
|
372
|
-
`TokenOwnerOrAddress`, `CreatorOrTokenOwnerOrAddress`. Order is unchanged, so the `uint8` values
|
|
373
|
-
are identical — only the names moved. Users type these: `--schema key:Type:Creator`.
|
|
374
|
-
- The on-chain collection metadata field keys `artist` / `artist_links` are now `creator` /
|
|
375
|
-
`creator_links`. These are `bytes32` keys written on-chain and emitted verbatim into every
|
|
376
|
-
collection's `contractURI` JSON.
|
|
377
|
-
- CLI flags `--artist` / `--artist-links` are now `--creator` / `--creator-links`. No aliases.
|
|
378
|
-
- `@artblocks/abx-token-api` renames its `art` module to `content`: `generateArt` →
|
|
379
|
-
`generateContent`, `artContentHash` → `contentHash`.
|
|
380
|
-
- `AbxMetadataRenderer.SPEC_VERSION` is **7**, and `isCurrentRenderer` gates on it. A v6 renderer
|
|
381
|
-
emits a different member key, so it is genuinely behind, not cosmetically so.
|
|
382
|
-
|
|
383
|
-
Package CHANGELOGs are left alone on purpose: they record what past alpha versions actually shipped,
|
|
384
|
-
and rewriting them would make the release history lie about flag names that really were `--artist`.
|
|
385
|
-
|
|
386
|
-
- 1b6b741: Renderer spec v10 projects four long-reserved keys; edition trust anchors move
|
|
387
|
-
|
|
388
|
-
**Renderer spec v10.** Four keys the spec reserved from the start were projected on chain by nothing:
|
|
389
|
-
`background_color` and `youtube_url` (token), `banner_image` and `featured_image` (collection). A
|
|
390
|
-
documented reserved key that no surface emits is a hole rather than a saved byte — a creator sets it,
|
|
391
|
-
observes nothing, and cannot tell whether the tool or the marketplace is at fault. All four now project
|
|
392
|
-
when their representation is chain-reachable, and are omitted when unset. `isCurrentRenderer` gates on
|
|
393
|
-
10; a v9 renderer silently drops them.
|
|
394
|
-
|
|
395
|
-
**`collaborators` is no longer a reserved key.** It was in the registry, projected by neither plane, and
|
|
396
|
-
because reserved keys are excluded from the resolver's `artifacts` listing, setting it on chain did
|
|
397
|
-
nothing observable anywhere. It is now an ordinary creator key — which means it **does** list in
|
|
398
|
-
`artifacts`. Put a collaborator list in a named artifact (`abx attach`) or in `description`.
|
|
399
|
-
|
|
400
|
-
**The resolver's two collection image keys are now symmetric with the renderer.** `featured_image` is a
|
|
401
|
-
top-level `contractURI` key instead of artifacts-only, and `banner_image` projects for every
|
|
402
|
-
chain-reachable representation instead of only `url` (an `inline` or `reader` banner used to vanish).
|
|
403
|
-
|
|
404
|
-
**Docs now carry the three-list split** — which keys both planes project, which are the off-chain
|
|
405
|
-
resolver's alone by design (`abx_provenance.status`, operator overlay, effects/live-view, the
|
|
406
|
-
`artifacts` listing, collection `image` courtesy, `image_data`, off-chain-decode values), and which are
|
|
407
|
-
not reserved at all. That split is the thing to read before adding a key to either surface: drift on a
|
|
408
|
-
key both planes _can_ emit is what produced three earlier remediations.
|
|
409
|
-
|
|
410
|
-
**Addresses.** The three edition factories move (trust anchors) along with their implementations, and
|
|
411
|
-
the renderer moves. `AbxEditionLib`, `AbxMetadataLib`, `AbxCodeLib`, `AbxParamsLib`, all three ERC-721
|
|
412
|
-
factories, the chunk store, the seed source, both minters and both generators keep their addresses.
|
|
413
|
-
Existing clones keep running their frozen implementations; re-point a live collection at the new
|
|
414
|
-
renderer with `abx set-renderer` rather than redeploying it.
|
|
415
|
-
|
|
416
|
-
- 1b6b741: Independent-audit remediation: `abx_provenance` reshaped, `abx_params` removed, hook ABI widened
|
|
417
|
-
|
|
418
|
-
An independent adversarial audit of the contracts found no Critical or High issue, no theft path and
|
|
419
|
-
no cross-project reach — but four Mediums, eight Lows and five architectural notes. Everything is
|
|
420
|
-
addressed. Consumer-visible changes:
|
|
421
|
-
|
|
422
|
-
**`abx_provenance` entries are now `{field, source, note}`.** They lost `onChain`, which was wrong in
|
|
423
|
-
both directions — a `url` reported `false` although the URL string is stored on chain, while an
|
|
424
|
-
`inline` value of `"https://…"` reported `true` for a pure pointer — and `verifiedAgainstChain`,
|
|
425
|
-
which was hardcoded `null` on every entry. `source` says where the bytes came from; whether a value
|
|
426
|
-
resolves on chain is visible in the value, and that judgment belongs to the reader. The off-chain
|
|
427
|
-
resolver drops `onChain` for the same reason (it was exactly `status === 'on-chain'`) and keeps
|
|
428
|
-
`status`, which it can genuinely compute.
|
|
429
|
-
|
|
430
|
-
**`abx_params` no longer appears in `tokenURI`.** It was emitted by the on-chain renderer AND the
|
|
431
|
-
resolver and parsed back by nobody. Params enumerate directly from the contract — `tokenParamKeys`,
|
|
432
|
-
`tokenParam`, `paramSchemaKeys` — which is canonical, needs no indexer, and is what a chain-only
|
|
433
|
-
reader should use; a code project's script still receives them through `tokenData`. Traits for
|
|
434
|
-
marketplaces belong in `attributes`, unchanged.
|
|
435
|
-
|
|
436
|
-
**A computed `image` locator now lands verbatim.** A field renderer returning
|
|
437
|
-
`("text/uri-list", "ipfs://…")` was being data-wrapped into `data:text/uri-list;base64,…`, which no
|
|
438
|
-
marketplace dereferences. `image` and `animation_url` now share one implementation of the rule.
|
|
439
|
-
|
|
440
|
-
**`IAbxTransferHook.onTokenTransfer` gains `operator` and `amount`.** Without them a hook on a
|
|
441
|
-
shared-supply ERC-1155 cannot tell a real transfer from a zero-amount no-op — which let any address
|
|
442
|
-
fire the param lifecycle for an id it held no copy of. The token also refuses to notify on
|
|
443
|
-
zero-amount and self-transfers.
|
|
444
|
-
|
|
445
|
-
**`pingURI` is owner-only**, and `paramSchemaHead` / `selectOption` are new: resolving one selected
|
|
446
|
-
option no longer copies the whole option table on every render.
|
|
447
|
-
|
|
448
|
-
`AbxMetadataRenderer.SPEC_VERSION` is 8. Every canonical address moves — every token type is now
|
|
449
|
-
library-linked, including the two ERC-721 image factories, because the metadata field store was
|
|
450
|
-
externalized into the new `AbxMetadataLib` to restore EIP-170 headroom before any fix was stacked on
|
|
451
|
-
top of 187 bytes of margin.
|
|
452
|
-
|
|
453
|
-
The CLI now warns when `--copies` meets a holder-writable `--schema`: on an edition, params belong to
|
|
454
|
-
the id, so every holder shares one value and the last writer wins.
|
|
455
|
-
|
|
456
|
-
- 1b6b741: Upgrading from alpha.12/alpha.13 — what breaks, in one place
|
|
457
|
-
|
|
458
|
-
This release lands the contract-audit branch. It is a **compatibility break with earlier alphas**, which
|
|
459
|
-
is fine at this stage (greenfield alpha, no backwards-compatibility promise) but is worth having in one
|
|
460
|
-
list rather than spread across a dozen changesets. Nothing here is a deprecation with a migration
|
|
461
|
-
window; the old shapes are gone.
|
|
462
|
-
|
|
463
|
-
**Every canonical address moved**, and four manifest fields are new (`metadataLib`, `paramsLib`,
|
|
464
|
-
`codeLib`, `editionLib` — the delegatecalled write-path libraries). Resolve through `getDeployment` and
|
|
465
|
-
the upgrade is transparent; anything you have _stored_ keyed by a factory address is not. A project
|
|
466
|
-
indexed from a superseded anchor reads `isCanonical: false` against the new manifest — correct, since it
|
|
467
|
-
is what a creator sees if they don't redeploy, but it is a data question, not a version bump.
|
|
468
|
-
|
|
469
|
-
**The metadata document changed: renderer spec v4 → v9.** If you assemble or assert on it:
|
|
470
|
-
|
|
471
|
-
- `abx_provenance` entries lost `onChain` (it was exactly `status === 'on-chain'`, and wrong in both
|
|
472
|
-
directions) and `verifiedAgainstChain` (hardcoded `null` on every entry). `source` and `status` stay.
|
|
473
|
-
- The `abx_params` block is gone from **both** lanes. Params enumerate from the contract —
|
|
474
|
-
`tokenParamKeys` / `tokenParam` / `paramSchemaKeys` — which is canonical and needs no indexer; a code
|
|
475
|
-
project's script still receives them through `tokenData`.
|
|
476
|
-
- `artist` / `artist_links` are now `creator` / `creator_links` (reserved on-chain collection field
|
|
477
|
-
keys), and `AuthOption.Artist*` is `AuthOption.Creator*` (numeric values unchanged).
|
|
478
|
-
- A computed `image` locator (`text/uri-list`) lands **verbatim** instead of being wrapped into a
|
|
479
|
-
`data:` URI no marketplace dereferences.
|
|
480
|
-
- The on-chain renderer no longer duplicates a computed image into `artifacts`. The off-chain resolver
|
|
481
|
-
still emits the complete listing — that asymmetry is specified, not a bug.
|
|
482
|
-
- Four long-reserved keys now project on chain: `background_color`, `youtube_url` (token) and
|
|
483
|
-
`banner_image`, `featured_image` (collection). `featured_image` also becomes a top-level resolver key
|
|
484
|
-
instead of artifacts-only, and `banner_image` projects for every chain-reachable representation
|
|
485
|
-
rather than `url` alone.
|
|
486
|
-
- `collaborators` is **no longer reserved** — projected by neither plane and excluded from `artifacts`
|
|
487
|
-
by its own reserved-ness, so it did nothing. It is now an ordinary creator key that does list.
|
|
488
|
-
|
|
489
|
-
**`tokenData` divergences fixed, so rendered output can change:** a contract-scope `seed` no longer
|
|
490
|
-
leaks into a token's `tokenData` (the on-chain generator never read one), `seed`'s wire format is always
|
|
491
|
-
raw 32-byte hex regardless of schema, and `</script` escaping is case-insensitive to match the on-chain
|
|
492
|
-
generator. Cached renders for affected code projects should be re-derived.
|
|
493
|
-
|
|
494
|
-
**Removed:** `paramKeysOf`, `paramSchemaOf`, `paramDataOf` on `AbxMetadataRenderer` — orphaned when
|
|
495
|
-
params left `tokenURI`. Read the token directly instead.
|
|
496
|
-
|
|
497
|
-
**Two hook interfaces widened** (`ConfigurableParams` is extension **v3**; a hook built for the old
|
|
498
|
-
signature reverts against a v3 token): `IAbxTransferHook.onTokenTransfer` gained `operator` + `amount`;
|
|
499
|
-
`IAbxConfigureHook.onParamConfigured` gained `dataLength` + `dataBlobAddress`.
|
|
500
|
-
|
|
501
|
-
**Additive:** `ParamHooksFrozen` folds into `ParamHooks.locked`; `paramSchemaHead` + `selectOption`
|
|
502
|
-
replace pulling a whole option table to resolve one index; `readParamHooks`; `abxJs()` / `gunzipScript()`
|
|
503
|
-
on the generator for piecewise document assembly; and the three ERC-1155 ABIs now carry
|
|
504
|
-
`MetadataUpdate` / `BatchMetadataUpdate` / `DefaultMaxSupplySet`, which were emitted but not decodable.
|
|
505
|
-
|
|
506
|
-
### Patch Changes
|
|
507
|
-
|
|
508
|
-
- Updated dependencies [1b6b741]
|
|
509
|
-
- Updated dependencies [1b6b741]
|
|
510
|
-
- Updated dependencies [1b6b741]
|
|
511
|
-
- Updated dependencies [1b6b741]
|
|
512
|
-
- Updated dependencies [1b6b741]
|
|
513
|
-
- Updated dependencies [1b6b741]
|
|
514
|
-
- Updated dependencies [f64a31f]
|
|
515
|
-
- Updated dependencies [1b6b741]
|
|
516
|
-
- Updated dependencies [1b6b741]
|
|
517
|
-
- Updated dependencies [1b6b741]
|
|
518
|
-
- Updated dependencies [1b6b741]
|
|
519
|
-
- Updated dependencies [1b6b741]
|
|
520
|
-
- Updated dependencies [1b6b741]
|
|
521
|
-
- Updated dependencies [1b6b741]
|
|
522
|
-
- Updated dependencies [1b6b741]
|
|
523
|
-
- Updated dependencies [1b6b741]
|
|
524
|
-
- Updated dependencies [1b6b741]
|
|
525
|
-
- @artblocks/abx-sdk@0.1.0-alpha.14
|
|
526
|
-
- @artblocks/abx-indexer@0.1.0-alpha.15
|
|
527
|
-
- @artblocks/abx-storage@0.1.0-alpha.14
|
|
528
|
-
|
|
529
|
-
## 0.1.0-alpha.16
|
|
530
|
-
|
|
531
|
-
### Patch Changes
|
|
532
|
-
|
|
533
|
-
- Updated dependencies [528c6c6]
|
|
534
|
-
- @artblocks/abx-sdk@0.1.0-alpha.13
|
|
535
|
-
- @artblocks/abx-indexer@0.1.0-alpha.14
|
|
536
|
-
- @artblocks/abx-storage@0.1.0-alpha.13
|
|
537
|
-
|
|
538
|
-
## 0.1.0-alpha.15
|
|
3
|
+
## 0.1.0-alpha.34
|
|
539
4
|
|
|
540
5
|
### Minor Changes
|
|
541
6
|
|
|
542
|
-
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
`transfer --amount`, `set-max-supply` (per-id cap, only ever decreases), `ping-uri` (re-emit the
|
|
552
|
-
native `URI` event after a re-point). ERC-1155C creator-token enforcement is the same `--721c`
|
|
553
|
-
opt-in (same validator registry and ERC-165 ids as 721C). Editions announce one new extension
|
|
554
|
-
(`abx.extension.edition-supply`, per-id supply/cap); everything else — metadata fields, params,
|
|
555
|
-
royalties, renderer, storage, effects — is the same protocol surface on both standards.
|
|
556
|
-
|
|
557
|
-
**Integrator surface (audience line):** additive only. `ProjectState.contractType` gains
|
|
558
|
-
`'1of1-edition' | 'edition' | 'edition-code'`; `TokenState` gains `supply`/`maxSupply`/`holders`
|
|
559
|
-
(editions only; `minted` means supply > 0 there); the spine ABI now decodes
|
|
560
|
-
`TransferSingle`/`TransferBatch`/`URI`/`MaxSupplyUpdated`; `ChainDeployment` gains the four
|
|
561
|
-
edition anchors (recorded for Sepolia + Base Sepolia, CREATE2-identical); token-api summaries gain
|
|
562
|
-
an optional `copies` field. No existing export, route, column, or event shape changed.
|
|
7
|
+
- c068a0f: `abx artifacts <address> [--token <id>]` reads a token's `artifacts` manifest directly, instead of
|
|
8
|
+
fetching and parsing the whole served tokenURI document. Reports every entry plus every
|
|
9
|
+
producer-registered effect row — current AND stale — each labeled against the token's active
|
|
10
|
+
`inputsHash`, so a param change that re-addressed a render is diagnosable rather than silently
|
|
11
|
+
absent. `--remote <name|url>` reads what a hosted resolver actually reports (the surface that owns a
|
|
12
|
+
hosted project's real artifact set), mirroring the existing `abx verify` / `abx verify --remote`
|
|
13
|
+
split. Neither "not registered here" nor "not registered on that remote" fails the command — both
|
|
14
|
+
return a stable `{surface, registered, available, reason, entries, effects}` JSON shape.
|
|
15
|
+
`@artblocks/abx-token-api` exports the underlying `tokenArtifacts()` read for direct SDK/server use.
|
|
563
16
|
|
|
564
17
|
### Patch Changes
|
|
565
18
|
|
|
566
|
-
- Updated dependencies [
|
|
567
|
-
- Updated dependencies [
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
19
|
+
- Updated dependencies [c068a0f]
|
|
20
|
+
- Updated dependencies [c068a0f]
|
|
21
|
+
- Updated dependencies [c068a0f]
|
|
22
|
+
- Updated dependencies [c068a0f]
|
|
23
|
+
- Updated dependencies [c068a0f]
|
|
24
|
+
- Updated dependencies [c068a0f]
|
|
25
|
+
- Updated dependencies [c068a0f]
|
|
26
|
+
- Updated dependencies [c068a0f]
|
|
27
|
+
- Updated dependencies [c068a0f]
|
|
28
|
+
- Updated dependencies [c068a0f]
|
|
29
|
+
- @artblocks/abx-sdk@0.1.0-alpha.31
|
|
30
|
+
- @artblocks/abx-indexer@0.1.0-alpha.32
|
|
31
|
+
- @artblocks/abx-storage@0.1.0-alpha.31
|
|
571
32
|
|
|
572
|
-
## 0.1.0-alpha.
|
|
33
|
+
## 0.1.0-alpha.33
|
|
573
34
|
|
|
574
35
|
### Patch Changes
|
|
575
36
|
|
|
576
|
-
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
-
|
|
581
|
-
`buildGeneratorDocument`, `injectTokenDataIntoHtml` — new `src/generator-document.ts`): pure
|
|
582
|
-
string operations with no resolver-specific behavior, so the SDK, `abx preview`, and any
|
|
583
|
-
third-party provider now share one definition instead of the CLI importing token-api just for
|
|
584
|
-
this.
|
|
585
|
-
- **The registry-dependency family** (`DEPENDENCY_REGISTRY_ABI`, `activeRegistry`,
|
|
586
|
-
`resolveRegistryDep`, `registryDepUrl`, `dependencyScriptTags`, `URL_BUDGET_BYTES`), merged into
|
|
587
|
-
the SDK's existing `deps.ts` alongside its registry-pointer logic. `node:zlib` can't come along
|
|
588
|
-
— SDK core has to stay reachable from a browser bundle — so decompression is now an INJECTED
|
|
589
|
-
`inflate?: (bytes: Uint8Array) => Uint8Array` threaded through `resolveRegistryDep`/
|
|
590
|
-
`dependencyScriptTags`; omitting it when a resolved dep actually needs decompressing throws a
|
|
591
|
-
new typed `InflateRequiredError` naming the fix, rather than crashing opaquely or silently
|
|
592
|
-
degrading. `@artblocks/abx-sdk/node` gains `nodeInflate` (a one-line `gunzipSync` wrapper) so a
|
|
593
|
-
Node host wires it in one line; a browser host passes a `DecompressionStream`-based
|
|
594
|
-
implementation instead. (Merge note: the prior `dependencyRegistryReadAbi` and token-api's
|
|
595
|
-
`DEPENDENCY_REGISTRY_ABI` declared the identical `getDependencyDetails` entry twice — deduped
|
|
596
|
-
into one array that also carries `getDependencyScript`.)
|
|
597
|
-
- **`contentTypeFromPath`** (new `src/mime.ts`): the MIME extension-map lookup, verbatim.
|
|
598
|
-
- **Gateway resolution, split pure/env** (new `src/gateways.ts`): `resolveGatewayBase` is now PURE
|
|
599
|
-
(no env read — takes resolved `{ipfs?, arweave?}` overrides) and `gatewayUrlFor` moves alongside
|
|
600
|
-
it; `gatewayConfigFromEnv()` is the one place that reads `ABX_IPFS_GATEWAY`/
|
|
601
|
-
`ABX_ARWEAVE_GATEWAY`, kept separate so a host with its own gateway config never has to touch
|
|
602
|
-
`process.env` through this module at all.
|
|
603
|
-
- **`exponentialBackoffDelay(attempt, baseMs, capMs)`** (`util.ts`): `min(baseMs * 2^(attempt-1),
|
|
604
|
-
capMs)`, 1-indexed like the existing `linearBackoffDelay`. Prefer it for a sustained rate limit
|
|
605
|
-
or an overloaded upstream; `linearBackoffDelay` stays right for a one-off transient failure.
|
|
606
|
-
`service.ts`'s own retry ladder is unchanged (still linear — its rationale comment stands).
|
|
607
|
-
|
|
608
|
-
Token-api and storage keep every existing export working, re-exported from the SDK where the
|
|
609
|
-
implementation moved — no removals, and token-api's own `nodeInflate`-pre-wired wrappers mean its
|
|
610
|
-
internal call sites (`code.ts`'s document assembly, `deps.ts`'s `depStatusReport`) needed no
|
|
611
|
-
signature changes at all. The browser-bundle test (`packages/sdk/test/browser-bundle.test.ts`)
|
|
612
|
-
stays green with all of this now exported from the core index — proof that the injected-`inflate`
|
|
613
|
-
design actually keeps `node:zlib` out of the bundle.
|
|
614
|
-
|
|
615
|
-
- d40caf4: Two first-party consumers adopt the backoff/gateway/data-URI helpers hoisted into `@artblocks/abx-sdk`
|
|
616
|
-
last round, and `mint-page` refuses a 1/1 target instead of scaffolding a page that hangs. Drop-in for
|
|
617
|
-
everyone — no behavior change in the adoption itself, and the mint-page refusal only fires for a
|
|
618
|
-
contract type the page never worked against.
|
|
619
|
-
|
|
620
|
-
**`token-api`'s chain watcher now calls `exponentialBackoffDelay`/`linearBackoffDelay` instead of
|
|
621
|
-
re-deriving them inline.** `dueForRetry`'s failed-project retry and the tick loop's repeated-failure
|
|
622
|
-
delay were the sdk helpers reimplemented by hand; both now call the shared functions, with the exact
|
|
623
|
-
index mapping (`min(attempts, 8) + 1` into the 1-indexed exponential helper) that reproduces identical
|
|
624
|
-
delays for every `attempts`/`failures` value — proved by an old-formula-vs-sdk-helper equality table
|
|
625
|
-
in `packages/token-api/test/watcher-backoff.test.ts` (attempts/failures 0..12, several `baseMs`
|
|
626
|
-
values, and the cap boundary explicitly).
|
|
627
|
-
|
|
628
|
-
**The `mint-page` template's generated app now reads gateway URLs and `data:` URIs through the sdk**
|
|
629
|
-
(`gatewayUrlFor`/`resolveGatewayBase`/`parseDataUri`) instead of a hand-rolled `ipfs://`-slicing
|
|
630
|
-
`toGateway` and a hand-parsed comma-split in `fetchJson`. Same output for every input (plain
|
|
631
|
-
`https://`, empty string, `ipfs://`, `ar://`, base64 and percent-encoded `data:` bodies) — verified
|
|
632
|
-
byte-for-byte before the swap, and pinned by a new mintpage.test.ts assertion that the emitted
|
|
633
|
-
`lib/meta.ts` imports the sdk helpers and no longer contains the old hand-rolled body.
|
|
634
|
-
|
|
635
|
-
**`mint-page` now refuses a non-Series target.** The generated page reads `maxInvocations`/`paused`
|
|
636
|
-
and mints through the shared fixed-price minter — a 1/1 (`OneOfOneImage`) has none of that, so pointing
|
|
637
|
-
`mint-page` at one silently wrote a page that sat on "Loading…" forever with no diagnostic. `cmdMintPage`
|
|
638
|
-
now probes the same ERC-165 `supportsInterface(IAbxSequentialMint)` `sdk/anchors.ts`'s
|
|
639
|
-
`isCurrentSeriesFactory` uses, and refuses with a `CliError` pointing at `abx deploy-series --dir
|
|
640
|
-
<folder> --count 1` (matching the existing guidance in `sales.mdx`). A probe that can't run at all (RPC
|
|
641
|
-
unreachable) is left undecided and does NOT refuse — scaffolding stays usable offline, same tolerance
|
|
642
|
-
the existing best-effort `name()` read already has.
|
|
643
|
-
|
|
644
|
-
Also folded in: `PUBLIC_RPC` (the mint-page template's keyless-RPC table) gains `base` and
|
|
645
|
-
`base-sepolia` — the toolkit's own default chain was missing from it, so every default-chain deploy
|
|
646
|
-
needed a manual `--rpc` just to scaffold its own mint page.
|
|
647
|
-
|
|
648
|
-
- Updated dependencies [d40caf4]
|
|
649
|
-
- Updated dependencies [d40caf4]
|
|
650
|
-
- @artblocks/abx-sdk@0.1.0-alpha.11
|
|
651
|
-
- @artblocks/abx-storage@0.1.0-alpha.11
|
|
652
|
-
- @artblocks/abx-indexer@0.1.0-alpha.12
|
|
653
|
-
|
|
654
|
-
## 0.1.0-alpha.13
|
|
655
|
-
|
|
656
|
-
### Patch Changes
|
|
657
|
-
|
|
658
|
-
- 11fa933: The remaining phases of the simplification refactor that hadn't yet gotten a changeset: the CLI's
|
|
659
|
-
internal module split, the token-api/effects/mint-page convergence on the SDK, the shipped skill's
|
|
660
|
-
rewrite for the simplified surface, and a new SDK README.
|
|
661
|
-
|
|
662
|
-
- **`abx`'s `main.ts` split into domain command modules** (`commands/{deploy,project,reads,service,
|
|
663
|
-
scaffold,storage}.ts`, shared `output.ts`/`errors.ts`), with one exit-discipline rule
|
|
664
|
-
(`process.exitCode` + return, or a typed `CliError`, everywhere — bare `process.exit` only at the
|
|
665
|
-
entry guard, the top-level catch, and the keep-alive SIGINT handler). Purely internal: a 207-fixture
|
|
666
|
-
byte-diff matrix (every help text, dry-run, error path, and exit code) confirmed identical output
|
|
667
|
-
before and after.
|
|
668
|
-
- **token-api / effects / mint-page converge on the SDK**: `@artblocks/abx-storage` gains one
|
|
669
|
-
`resolveGatewayBase` (`readiness.ts`), replacing three near-identical copies (two in token-api, one
|
|
670
|
-
inline in storage itself); token-api exports `buildGeneratorDocument` so the CLI's `abx preview`
|
|
671
|
-
consumes the real generator-document assembler instead of a hand-kept duplicate; the effects runner
|
|
672
|
-
now resolves its config via the SDK's `readEnv` and gets a `makePublicClient` fallback transport, so
|
|
673
|
-
`ABX_RPC_URL` accepts a comma-separated failover list like every other RPC var; the scaffolded
|
|
674
|
-
mint-page app now imports ABIs from `@artblocks/abx-sdk/abi` and a browser-safe `makePublicClient` +
|
|
675
|
-
typed `readSaleConfig` instead of hand-rolled fetch/decode, and pins its generated `package.json` to
|
|
676
|
-
the SDK's _resolved_ version via a new `@artblocks/abx-sdk/package.json` export (alpha version
|
|
677
|
-
counters diverge per package under changesets, so pinning the CLI's own number could produce an
|
|
678
|
-
unsatisfiable range).
|
|
679
|
-
- **The shipped skill (`.claude/skills/abx-self-host/`) is rewritten for the surface phases 0–5
|
|
680
|
-
actually shipped**: every warning made obsolete by an enforcement is deleted rather than softened —
|
|
681
|
-
predict-only deploy-preview addresses, the `approvals N` line, the single `ABX_REMOTE_SELF_*`
|
|
682
|
-
credential grammar, `doctor`'s version/provenance ladder, `storage show --check`, the render/storage
|
|
683
|
-
combo validator's dry-run row, and `ABX_DEPLOYER_PK` as the only key name. Retired names swept from
|
|
684
|
-
`dev-loop-test`, the agent-eval scenarios, and spec prose. The skill ships bundled inside this CLI
|
|
685
|
-
package (co-versioned via `SKILL.md` frontmatter), so it rides this same patch.
|
|
686
|
-
- **New `packages/sdk/README.md`**: what the SDK is, the send-injection model (`PreparedTx` +
|
|
687
|
-
`SendTx`, `makeHotSender` for a hot key, bring-your-own for a wallet/multisig), a complete
|
|
688
|
-
deploy → upload → mint → read walkthrough against real exports, and browser-use notes (explicit
|
|
689
|
-
`rpcUrls`, no env, the `/node` subpath is Node-only). Included in the npm tarball automatically
|
|
690
|
-
(README is one of the files npm always packs, regardless of the `files` allowlist).
|
|
691
|
-
|
|
692
|
-
- Updated dependencies [11fa933]
|
|
693
|
-
- Updated dependencies [11fa933]
|
|
694
|
-
- Updated dependencies [11fa933]
|
|
695
|
-
- Updated dependencies [11fa933]
|
|
696
|
-
- @artblocks/abx-sdk@0.1.0-alpha.10
|
|
697
|
-
- @artblocks/abx-storage@0.1.0-alpha.10
|
|
698
|
-
- @artblocks/abx-indexer@0.1.0-alpha.11
|
|
699
|
-
|
|
700
|
-
## 0.1.0-alpha.12
|
|
701
|
-
|
|
702
|
-
### Patch Changes
|
|
703
|
-
|
|
704
|
-
- df298d8: Fix three ways the reference resolver misreported on-chain state — and the head-read bug underneath one of them
|
|
705
|
-
|
|
706
|
-
From an engineering audit by the abx-services team (2026-08-04), who run the same protocol on a
|
|
707
|
-
hosted node against real testers and so reach long-tail states a single-node run rarely does. All
|
|
708
|
-
three findings reproduced. Verifying the second one turned up a fourth defect that was its actual
|
|
709
|
-
cause, and that one is the most consequential of the set.
|
|
710
|
-
|
|
711
|
-
**1 · A renderer-computed TEXT field was dropped entirely.** `resolveImage` had an `R.renderer`
|
|
712
|
-
branch; `resolveText` did not. So a `renderer`-represented `description`, `external_url`,
|
|
713
|
-
`animation_url`, `background_color`, `youtube_url`, or `name` matched no branch and resolved **as if
|
|
714
|
-
unset** — silently replaced by the operator's off-chain value with provenance reporting `off-chain`,
|
|
715
|
-
or omitted from the metadata altogether. A creator who committed a computed field on-chain got the
|
|
716
|
-
operator's version served instead, and nothing errored anywhere.
|
|
717
|
-
|
|
718
|
-
`resolveText` now mirrors `AbxMetadataRenderer._appendText`'s `R_RENDERER` arm exactly, because the
|
|
719
|
-
two must agree: with `tokenURIRenderer` set the chain assembles this JSON and the resolver merely
|
|
720
|
-
re-serves it, so any difference is a resolver contradicting the token's own `tokenURI`. That means
|
|
721
|
-
the **declared** contentType is used verbatim (`renderer` is the one representation that types itself
|
|
722
|
-
on-chain) rather than an assumed `text/html`, and a `text/uri-list` result (RFC 2483 — the canonical
|
|
723
|
-
generator's directory branch) lands as the locator it is, never data-wrapped. This is a deliberate
|
|
724
|
-
divergence from the shape the audit recommended (pointing at the node's own `/data/{field}` route):
|
|
725
|
-
parity with the on-chain renderer is the stronger constraint here. A field renderer that reverts now
|
|
726
|
-
degrades that one field — with provenance saying the on-chain attempt failed, not a clean
|
|
727
|
-
`off-chain` — instead of being indistinguishable from an unset field.
|
|
728
|
-
|
|
729
|
-
**2 · The `name` fallback asserted an ERC-721 `name()` read it had not performed.** When
|
|
730
|
-
`state.name` is null the served value is the raw contract address, and the note still said
|
|
731
|
-
`on-chain (ERC-721 name() + #id)`. A hosted node served `"name": "0xb844…c35e56 #0"` beside that note
|
|
732
|
-
while the contract's `name()` was `"ABXdoku"`. The wrong name is cosmetic; provenance is the surface
|
|
733
|
-
you would point an artist at to audit their own metadata, so a false positive there costs more. The
|
|
734
|
-
note is now conditional, and deliberately does not adjudicate _why_ the value was empty — the
|
|
735
|
-
projection cannot tell an unnamed contract from a failed read, and guessing is how the original note
|
|
736
|
-
came to lie.
|
|
737
|
-
|
|
738
|
-
**3 · The live view answered "not a code project" for a code project that was merely mid-index.**
|
|
739
|
-
`/a/` collapsed every `resolveLiveView` null into one confident verdict about the **contract**, when
|
|
740
|
-
at least one is a statement about the **index**: `chunkCount` is a head read, so a template-mode
|
|
741
|
-
project whose chunks have not been folded in yet reads as zero. A tester got
|
|
742
|
-
`live · caught up · 127 events · 32 tokens` from the node and this 404, concluded the resolver did
|
|
743
|
-
not recognise the SeriesCode factory, and a `--full` re-index did not clear it — the confident
|
|
744
|
-
wording sent them looking in the wrong place. The route now consults `contractType` (folded from the
|
|
745
|
-
deployed extensions, so it knows before any code lands) and answers **503 + Retry-After** for "not
|
|
746
|
-
yet" versus 404 for "not ever". Both verdicts are answered before the chain client is touched, since
|
|
747
|
-
neither needs an RPC. The three-way decision is extracted as `liveViewAvailability(state)` so it has
|
|
748
|
-
a test seam at all.
|
|
749
|
-
|
|
750
|
-
**4 · The head-read multicall failed _whole_ on the flagship lane, and took identity, trust, and the
|
|
751
|
-
URI lane with it.** This was not in the audit — it is why finding 2 fires, found by reproducing it
|
|
752
|
-
instead of accepting "an RPC hiccup". `applyHeadReads` batched `name`, `symbol`, `owner`,
|
|
753
|
-
`contractURI`, `isAbxClone`, `implementation`, the four URI-config getters, and **one `tokenURI` per
|
|
754
|
-
token** into a single multicall. A multicall is one `eth_call`: on a fully-on-chain project
|
|
755
|
-
`tokenURI(id)` assembles the entire metadata document on-chain, so a handful of those legs exceeds a
|
|
756
|
-
public node's budget and _every_ leg in the aggregate reports failure — including legs that answer
|
|
757
|
-
fine alone.
|
|
758
|
-
|
|
759
|
-
Measured on Base Sepolia `0xB844F4D2137a8Ce785Cbc80D281A36DBD1c35E56` (32 tokens, chain-complete):
|
|
760
|
-
1 tokenURI leg → 5/5 succeeded; **4 legs → 0/8 succeeded**, while `name()` on its own returned
|
|
761
|
-
`"ABXdoku"`. Every resolver indexing that collection therefore believed it had no name, no symbol,
|
|
762
|
-
no `contractURI`, no canonical proof — and **no `tokenURIRenderer`, i.e. that it was not in the
|
|
763
|
-
on-chain-URI lane at all.** Deterministic for any sizable on-chain collection, not a hiccup.
|
|
764
|
-
|
|
765
|
-
Reads are now split by cost class: the cheap fixed-size ones that decide a project's identity and
|
|
766
|
-
lane go in a batch of their own and can never be collateral damage, while the unbounded ones
|
|
767
|
-
(`contractURI`, per-token `tokenURI`, script chunks) read in small chunks through a helper that
|
|
768
|
-
re-asks a failed chunk one leg at a time before believing it. After the fix, that same contract
|
|
769
|
-
reconstructs with its name, symbol, both URI renderers, and all 32 token URIs intact.
|
|
770
|
-
|
|
771
|
-
12 regression tests across the four, including the null-name case both surfaces missed because every
|
|
772
|
-
parity fixture on both sides hardcoded a non-null name.
|
|
773
|
-
|
|
774
|
-
- Updated dependencies [df298d8]
|
|
775
|
-
- Updated dependencies [df298d8]
|
|
776
|
-
- Updated dependencies [df298d8]
|
|
777
|
-
- @artblocks/abx-sdk@0.1.0-alpha.9
|
|
778
|
-
- @artblocks/abx-storage@0.1.0-alpha.9
|
|
779
|
-
- @artblocks/abx-indexer@0.1.0-alpha.10
|
|
780
|
-
|
|
781
|
-
## 0.1.0-alpha.11
|
|
782
|
-
|
|
783
|
-
### Patch Changes
|
|
784
|
-
|
|
785
|
-
- Updated dependencies [e325b46]
|
|
786
|
-
- @artblocks/abx-sdk@0.1.0-alpha.8
|
|
787
|
-
- @artblocks/abx-indexer@0.1.0-alpha.9
|
|
788
|
-
- @artblocks/abx-storage@0.1.0-alpha.8
|
|
789
|
-
|
|
790
|
-
## 0.1.0-alpha.10
|
|
791
|
-
|
|
792
|
-
### Patch Changes
|
|
793
|
-
|
|
794
|
-
- Updated dependencies [1b50f9d]
|
|
795
|
-
- Updated dependencies [1b50f9d]
|
|
796
|
-
- @artblocks/abx-sdk@0.1.0-alpha.7
|
|
797
|
-
- @artblocks/abx-storage@0.1.0-alpha.7
|
|
798
|
-
- @artblocks/abx-indexer@0.1.0-alpha.8
|
|
799
|
-
|
|
800
|
-
## 0.1.0-alpha.9
|
|
801
|
-
|
|
802
|
-
### Patch Changes
|
|
803
|
-
|
|
804
|
-
- 1158420: Fixes from a parallel cold-agent sweep: a chain typo no longer crashes every command, and `inspect` stops over-promising on hand-written PRNGs.
|
|
805
|
-
|
|
806
|
-
**An unknown `ABX_CHAIN` printed a raw Node stack trace — from every command.** Chain-derived values
|
|
807
|
-
were resolved at module scope, in `token-api` (which the CLI imports) and in the CLI itself, so the
|
|
808
|
-
throw happened during module evaluation, before `main()` existed to catch it. `ABX_CHAIN=mainnet abx
|
|
809
|
-
doctor` dumped an internal source path and exited 1 — including from the one command whose job is to
|
|
810
|
-
tell you what is wrong with your environment. Those resolutions are lazy now, and the CLI validates
|
|
811
|
-
the variable up front with an answer rather than a crash: unknown values list the shipped chains, and
|
|
812
|
-
a mainnet-shaped value says plainly that ABX is testnet-only today.
|
|
813
|
-
|
|
814
|
-
**`abx inspect` reported "(no PRNG)" for a hand-written seeded generator — with the _stronger_
|
|
815
|
-
reproducibility verdict attached.** The `seeded` check only recognized p5's `randomSeed(`, so a
|
|
816
|
-
vanilla LCG or xorshift matched no branch and fell through to "traits look derived from the
|
|
817
|
-
seed/params directly". That is the common case, not an edge one — the skill's own canonical
|
|
818
|
-
dependency-free example hand-rolls an LCG, and all three sketches written by agents in the sweep hit
|
|
819
|
-
it. A hand-rolled generator now gets the `careful` verdict and is told the truth: deterministic and
|
|
820
|
-
reproducible on-chain, but only by porting that exact generator and call order into Solidity.
|
|
821
|
-
|
|
822
|
-
Also: `--yes` is now documented in `deploy-code --help` (its own placeholder-identity refusal already
|
|
823
|
-
told you to pass it), and the `--onchain-uri` raster warning now names the two routes that actually
|
|
824
|
-
deliver a no-server image instead of only one.
|
|
825
|
-
|
|
826
|
-
Found by the 2026-08-03 parallel sweep (8 cold Sonnet/Haiku agents, isolated sandboxes).
|
|
827
|
-
|
|
828
|
-
- Updated dependencies [1158420]
|
|
829
|
-
- Updated dependencies [1158420]
|
|
830
|
-
- Updated dependencies [1158420]
|
|
831
|
-
- @artblocks/abx-sdk@0.1.0-alpha.6
|
|
832
|
-
- @artblocks/abx-indexer@0.1.0-alpha.7
|
|
833
|
-
- @artblocks/abx-storage@0.1.0-alpha.6
|
|
834
|
-
|
|
835
|
-
## 0.1.0-alpha.8
|
|
836
|
-
|
|
837
|
-
### Minor Changes
|
|
838
|
-
|
|
839
|
-
- feba8c2: A resolver is no longer an object store: effect outputs split into **bound** and **referenced**
|
|
840
|
-
(`specs/protocol/effects.md → Bound vs referenced`), and the artifact registry enforces the split.
|
|
841
|
-
|
|
842
|
-
An output is **bound** iff a binding stitches its _content_ into the metadata JSON (today exactly
|
|
843
|
-
`render/traits` → `attributes`); everything else is **referenced** — the projection carries its URL,
|
|
844
|
-
or it only appears in the `artifacts` manifest. That one distinction decides who holds the bytes, and
|
|
845
|
-
it is now the wire rule rather than a runner constant.
|
|
846
|
-
|
|
847
|
-
- **`POST /v1/effect-artifacts` derives the mode from the binding, and refuses both mismatches.**
|
|
848
|
-
Bytes for a referenced output → `400` (the resolver redirects either way, so the bytes buy no
|
|
849
|
-
capability and cost it storage, retention and egress). A locator for a bound output → `400` (its
|
|
850
|
-
content is assembled into `tokenURI`; a pointer there used to be recorded and then silently never
|
|
851
|
-
stitch — a wrong answer served confidently). Bound content is capped at **64 KB**, and a locator
|
|
852
|
-
that only the producer could resolve (loopback/private host, presigned expiring URL) is rejected.
|
|
853
|
-
The resolver never fetches a locator while handling the write, and serves registered locators by
|
|
854
|
-
`302` — never by proxying.
|
|
855
|
-
- **Bound content moved out of byte custody** into the artifact row (`effect_artifacts.bytes`). Two
|
|
856
|
-
distinct rules, deliberately not one: a node **MUST** serve and stitch bound content only at the
|
|
857
|
-
token's current settled `inputsHash`, and it **MAY** drop superseded content whenever it likes
|
|
858
|
-
(nothing may read it, and it is re-creatable). The reference drops eagerly, on each bound
|
|
859
|
-
registration, so it holds at most `64 KB × minted × bound outputs` — but retention is a service
|
|
860
|
-
policy, not an obligation. Either way "conforming means holding a bounded amount of JSON in the
|
|
861
|
-
database you already run" is now literally true: a resolver in the publish topology needs no object
|
|
862
|
-
storage at all.
|
|
863
|
-
- **`abx-effects-publish/v1` is gone** (not deprecated): the two routes ride `abx-control-plane/v1`.
|
|
864
|
-
Once referenced output is locator-only, accepting a registration is a database insert, so the
|
|
865
|
-
capability flag described a distinction that no longer exists. A service that won't take a caller's
|
|
866
|
-
artifacts refuses on the credential (`403`) — interfaces describe wire grammar, tokens describe
|
|
867
|
-
permission. The interface ids are also explicitly **all-or-nothing**, and the conformance fixture
|
|
868
|
-
now checks that every route a declared interface names actually answers.
|
|
869
|
-
- **The runner declares bound outputs** (`EffectOutputDecl.bound`), refuses to start when it has a
|
|
870
|
-
publish token but a backend that can't name a locator, preflights the descriptor + credential
|
|
871
|
-
before spending a render, and **latches** on a permanent (4xx) publish failure instead of
|
|
872
|
-
re-rendering every sweep forever. Skips now re-register rows, so a transient publish failure heals
|
|
873
|
-
without a re-render.
|
|
874
|
-
- **The CLI refuses the impossible combination up front**: `abx render --remote`, `abx effects`
|
|
875
|
-
against a remote resolver, and `abx deploy-effects` all require a backend that can name a reachable
|
|
876
|
-
URL — `cloud` (S3/R2 + public base), `ipfs`, or `arweave`, named as **peers**. Derived output is
|
|
877
|
-
re-creatable, so the protocol has no preference among schemes: a chosen `https://` gateway or
|
|
878
|
-
bucket URL is exactly as legitimate as `ipfs://`/`ar://`, and reachability — not durability — is
|
|
879
|
-
the requirement. Rendering **co-located** with the resolver remains fully supported on any backend,
|
|
880
|
-
including `fs`.
|
|
881
|
-
|
|
882
|
-
Breaking for producers that relied on pushing media bytes to a resolver: publish a locator instead,
|
|
883
|
-
or co-locate. Breaking for clients that read `abx-effects-publish/v1` from a descriptor.
|
|
884
|
-
|
|
885
|
-
### Patch Changes
|
|
886
|
-
|
|
887
|
-
- Updated dependencies [feba8c2]
|
|
888
|
-
- @artblocks/abx-sdk@0.1.0-alpha.5
|
|
889
|
-
- @artblocks/abx-indexer@0.1.0-alpha.6
|
|
890
|
-
- @artblocks/abx-storage@0.1.0-alpha.5
|
|
891
|
-
|
|
892
|
-
## 0.1.0-alpha.7
|
|
893
|
-
|
|
894
|
-
### Minor Changes
|
|
895
|
-
|
|
896
|
-
- 67b686b: `abx contracturi`, and the read plane stops answering a bare 404 to three different problems.
|
|
897
|
-
|
|
898
|
-
Both halves come from one real failure: an agent driving a hosted resolver wanted collection
|
|
899
|
-
metadata, pattern-matched off `/t/{chainId}/{address}/{id}`, dropped the token id, got a bare `404`,
|
|
900
|
-
and reported the service as broken. The documented route (`/c/{chainId}/{address}`) was right there —
|
|
901
|
-
but there was also no command to just _ask_, and the 404 gave it nothing to correct.
|
|
902
|
-
|
|
903
|
-
- **New `abx contracturi <address>`** — the collection-level counterpart of `tokenuri`. Reads
|
|
904
|
-
`contractURI()` (ERC-7572) from the contract, **follows it**, and decodes: a `data:` URI inline
|
|
905
|
-
(the on-chain lane), an `https://` URL by fetching it (the off-chain lane). A contract commits its
|
|
906
|
-
own metadata base on-chain (`contractURIBase`), so the chain — not a doc, not a service
|
|
907
|
-
descriptor — is the authoritative answer to where a project's metadata lives. Nobody needs to
|
|
908
|
-
hand-build a resolver URL. When the fetch fails, the message says so plainly: the URL came from
|
|
909
|
-
the chain, so a bad status is about the _service_ (unregistered project · wrong chain · down),
|
|
910
|
-
never a mistyped path.
|
|
911
|
-
- **Read-plane responses now carry a machine `code`**, so the three causes of "no metadata came
|
|
912
|
-
back" are distinguishable — they were one indistinguishable `{"error": "…"}` `404`:
|
|
913
|
-
- `400 invalid_request` — a real route, wrong shape. Names the correct template, and carries
|
|
914
|
-
`didYouMean` when the fix is obvious (a `/t/…` missing its token id → `/c/{chainId}/{address}`).
|
|
915
|
-
- `404 unknown_route` — this node serves nothing at that path; the body lists what it does serve.
|
|
916
|
-
- `404 not_registered` — the path and chain were fine; this node doesn't index that contract.
|
|
917
|
-
- `400 unsupported_chain` — wrong chain, plus the `chains` this node does serve. Was a bare `404`;
|
|
918
|
-
now matches what the control plane already answered for the same condition.
|
|
919
|
-
- `ServiceErrorCode` gains `unknown_route`. The spec's Errors section now covers the read plane too,
|
|
920
|
-
with a **MUST** on distinguishing the three misses — and an explicit **MUST NOT** on treating
|
|
921
|
-
route templates as per-node discoverable configuration. The route grammar is fixed by the
|
|
922
|
-
`abx-token-api/v1` interface; these responses are diagnostics, not a discovery mechanism.
|
|
923
|
-
- **The conformance fixture checks all of it** (`pnpm conformance <base-url>`), so any provider can
|
|
924
|
-
self-verify in one command. Also fixed: the documented `pnpm conformance -- <base-url>` form
|
|
925
|
-
parsed `--` as a flag and swallowed the base URL, printing usage instead of running.
|
|
926
|
-
|
|
927
|
-
### Patch Changes
|
|
928
|
-
|
|
929
|
-
- Updated dependencies [67b686b]
|
|
930
|
-
- @artblocks/abx-sdk@0.1.0-alpha.4
|
|
931
|
-
- @artblocks/abx-indexer@0.1.0-alpha.5
|
|
932
|
-
- @artblocks/abx-storage@0.1.0-alpha.4
|
|
933
|
-
|
|
934
|
-
## 0.1.0-alpha.6
|
|
935
|
-
|
|
936
|
-
### Minor Changes
|
|
937
|
-
|
|
938
|
-
- a72723d: A standard indexing lifecycle, and registration that no longer blocks on a slow chain RPC
|
|
939
|
-
(specs/self-host-toolkit/remote-services.md → The indexing lifecycle).
|
|
940
|
-
|
|
941
|
-
- **Fixed: a slow register triggered a retry storm.** The SDK's per-attempt timeout (30s) plus its
|
|
942
|
-
retry ladder meant a cold reconstruct that outran one request was **re-POSTed up to four times**,
|
|
943
|
-
each starting another full replay against the RPC that was already too slow to answer — and the
|
|
944
|
-
caller then saw "nothing responded" even though the registration was durable and indexing was
|
|
945
|
-
underway. A timed-out register now asks whether it landed (a status read) instead of re-POSTing, and
|
|
946
|
-
the resolver coalesces concurrent catch-ups for one project into a single run.
|
|
947
|
-
- **`POST /v1/projects` answers in two conformant shapes, discriminated by HTTP status:** `200` with
|
|
948
|
-
the completed summary, or `202` + `{accepted, project: {status}}` when catch-up is deferred. The
|
|
949
|
-
registration is normatively **durable before catch-up** and visible on the list immediately, so a
|
|
950
|
-
flaky RPC makes for a slower backfill rather than a lost add. No `?wait=`/`Prefer:` negotiation — the
|
|
951
|
-
status code is the discriminator, and clients handle both. The reference resolver answers _by
|
|
952
|
-
deadline_ (`ABX_REGISTER_DEADLINE_MS`, default 8s): the common case (a fresh deploy) stays
|
|
953
|
-
synchronous with real counts; only the pathological case defers.
|
|
954
|
-
- **Closed lifecycle enum + error classes, on the status and list routes:**
|
|
955
|
-
`queued | backfilling | live | stale | failed`, plus credential-free
|
|
956
|
-
`error.class ∈ {rpc_unavailable, rpc_rate_limited, not_abx_contract, internal}` (fixed per-class
|
|
957
|
-
messages, never a scrubbed upstream string). Status gains top-level `headBlock` (so lag / % complete
|
|
958
|
-
is computable without knowing a service has a watcher) and `attempts`; the list carries `status` +
|
|
959
|
-
the error class, so a client renders "3 live, 1 backfilling, 1 failed (rpc_rate_limited)" in one
|
|
960
|
-
request. SDK: `IndexStatus`, `IndexErrorClass`, `isAccepted()`, `indexProgress()`,
|
|
961
|
-
`classifyIndexError()`, and `AbxServiceClient.awaitIndexed()` — one wait loop for the CLI, the
|
|
962
|
-
effects runner, and any hosted agent.
|
|
963
|
-
- **The same five words on your own node.** `abx status [address] [--remote [name|url]] [--watch]`:
|
|
964
|
-
bare is the node summary (now with each project's state), an address gives lifecycle + scan floor +
|
|
965
|
-
blocks-indexed-vs-head + cause, and `--remote` asks a service. (`status` = who is serving it and how
|
|
966
|
-
fresh; `state` = what the chain says. Both `--help` texts now say so.)
|
|
967
|
-
- **New observability the self-hosted node never had:** the chain watcher marks projects `stale` when
|
|
968
|
-
it falls far behind head or its ticks keep failing (previously visible only in the node's log),
|
|
969
|
-
re-queues a backfill interrupted by a restart (previously left registered-but-empty until a manual
|
|
970
|
-
`abx index`), and retries a `failed` catch-up on exponential backoff instead of hammering a
|
|
971
|
-
rate-limited RPC every tick. Lifecycle rows live in their own table: they survive a projection wipe
|
|
972
|
-
and are never clobbered by a re-add.
|
|
973
|
-
- **CLI:** `abx add|index --remote` prints `registered — backfilling…`, polls to `live`, then prints
|
|
974
|
-
the same summary a synchronous service would have given; `--no-wait` returns at the 202 and names
|
|
975
|
-
the command to check later. A post-op nudge (`ownerops`) never blocks on someone else's backfill.
|
|
976
|
-
A caught-up project with **0 events** now warns instead of printing ✓ (a real ABX clone always emits
|
|
977
|
-
a spine, so zero means wrong chain/floor or an RPC that didn't serve the logs).
|
|
978
|
-
- **Conformance fixture** accepts either register shape, asserts durable-before-catch-up, lifecycle
|
|
979
|
-
membership, `headBlock`, that a deferred catch-up actually reaches `live`, and that no error message
|
|
980
|
-
carries a URL.
|
|
981
|
-
- Fixed `scripts/mock-remote-service.mts`, which imported the token API by a path that resolved
|
|
982
|
-
against `scripts/` and could silently fall back to a _published_ build outside the repo — the
|
|
983
|
-
fixture was testing the last release instead of the working tree. The fixture also re-points
|
|
984
|
-
scenarios by their fixture header now, so a new one can't keep a dead contract address.
|
|
985
|
-
|
|
986
|
-
Found by a cold-agent sweep over the above (10 parallel clean rooms, haiku + sonnet) and fixed here:
|
|
987
|
-
|
|
988
|
-
- **`abx status --remote <name>` with no address** parsed the flag itself as the address and sent it
|
|
989
|
-
as a URL path segment.
|
|
990
|
-
- **A register whose catch-up already failed** was announced as "registered — failed (…is catching
|
|
991
|
-
up…)", and with `--no-wait` it exited 0 and then claimed the provider "now serves" the project. A
|
|
992
|
-
known failure is now an error in both lanes — there is nothing left to wait for.
|
|
993
|
-
- **A `failed` status said what broke but not whose problem it was.** Both the failure error and
|
|
994
|
-
`abx status` now carry a per-class action line ("the SERVICE can't reach its chain RPC — not your
|
|
995
|
-
key, address, or chain…"), plus a `follow` line naming `--watch`, so a red word isn't a dead end.
|
|
996
|
-
- **A `live` project showed a misleading completion percentage.** `toBlock` only advances when a
|
|
997
|
-
project has _events_, so a fully current project on a busy chain read as `2/202 (0%)`.
|
|
998
|
-
`indexProgress()` now returns a ratio only while `backfilling`; `live` reads "caught up", `stale`
|
|
999
|
-
reads "not tracking head right now".
|
|
1000
|
-
- **`--remote-token` was misattributed on a 401** — the error blamed `ABX_REMOTE_<NAME>_TOKEN` even
|
|
1001
|
-
when the caller passed an override, making the override look ignored at exactly the moment someone
|
|
1002
|
-
is testing a replacement key.
|
|
1003
|
-
- **`not_registered` on a read** (status/reindex) now names the register command instead of echoing a
|
|
1004
|
-
404, and a 5xx carrying a failure `class` becomes a wait-vs-broken error.
|
|
1005
|
-
- **`abx verify`'s summary** read `✓ 0/1 up to date` for a project with no off-chain renders at all —
|
|
1006
|
-
"zero of one succeeded" to two independent reviewers. It now says "nothing to render for this
|
|
1007
|
-
project", and otherwise leads with polarity ("N of M token(s) current").
|
|
1008
|
-
- **`abx doctor` now reports named remotes** and flags a credential stored under a name the CLI does
|
|
1009
|
-
not read (`ABX_REMOTE_<NAME>_KEY`). That fault presents as "it acts like I never gave it a key" and
|
|
1010
|
-
previously only surfaced from `abx remote <name>` — which a creator reaches _after_ doctor.
|
|
1011
|
-
- **Skill: the `npx --no-install abx version` probe was documented as failing cleanly.** It doesn't —
|
|
1012
|
-
npm will run any `abx` binary already in the npx cache, which in a real sweep reported a months-old
|
|
1013
|
-
build as the project's CLI (and if a plain `npx abx` ever ran on that machine, the bare name is a
|
|
1014
|
-
squatted package). The skill now probes `./node_modules/.bin/abx` directly.
|
|
1015
|
-
- Also documented: how a multi-word provider name folds into `ABX_REMOTE_<NAME>_*`, and what
|
|
1016
|
-
`watching: no` means on a status readout.
|
|
1017
|
-
|
|
1018
|
-
A second sweep round over those fixes caught three more, including one the first round's fix created:
|
|
1019
|
-
|
|
1020
|
-
- **`abx verify --remote` never checked byte integrity at all** — both of its lanes only ask "is there
|
|
1021
|
-
a current render / is this a placeholder", and a green ✓ from that was standing in for "the served
|
|
1022
|
-
bytes match the on-chain commitment". A reviewer hit the worst version of this: `--remote` (the form
|
|
1023
|
-
the skill tells you to use for a hosted project) reported ✓ on a token whose bytes genuinely did NOT
|
|
1024
|
-
hash-match, while bare `abx verify` on the same project reported `✗ keccak256 MISMATCH`. It now calls
|
|
1025
|
-
the service's own purpose-built `GET /api/project/:addr/verify` (which holds both the bytes and the
|
|
1026
|
-
chain) and reports that verdict separately from the render summary — and when it _can't_ run that
|
|
1027
|
-
check (no credential, older node) it says "byte integrity NOT checked" instead of leaving a ✓ to
|
|
1028
|
-
imply it passed. The remedy names both real causes (an unbridged durable locator vs. bytes that only
|
|
1029
|
-
exist on the creator's machine, which a hosted resolver can never serve).
|
|
1030
|
-
- **`abx verify` exited 0 while printing a byte MISMATCH**, in both lanes — nothing could gate on it.
|
|
1031
|
-
An integrity mismatch now fails the command; a missing render or placeholder is a normal state and
|
|
1032
|
-
still exits 0.
|
|
1033
|
-
- **`abx add --dry-run` silently ignored the flag and performed the registration**, local or remote.
|
|
1034
|
-
It now refuses and names the read-only commands (`abx state`, `abx status`) instead. Silently doing
|
|
1035
|
-
the thing when the caller asked to preview is the one outcome that must never happen.
|
|
1036
|
-
- **`PRAGMA busy_timeout` was set third in the store schema**, after the WAL switch it needs to
|
|
1037
|
-
protect — so two processes opening the same store at once (parallel CLI runs, or a co-located
|
|
1038
|
-
effects runner starting alongside the resolver) could fail outright with `database is locked`
|
|
1039
|
-
instead of waiting the moment out. It is now the first statement.
|
|
1040
|
-
|
|
1041
|
-
A third round, re-running the scenario that found the verify bug (it now catches it) turned up:
|
|
1042
|
-
|
|
1043
|
-
- **`abx add --remote` ended on "it now serves <url>"** — true about indexing, silent about whether
|
|
1044
|
-
the bytes are right, and two reviewers stopped there and reported a blank page as fixed. It now names
|
|
1045
|
-
the byte check (`abx verify <addr> --remote <name>`) in the same breath.
|
|
1046
|
-
- **`canonical:` collapsed a tri-state.** `isCanonical` is `true | false | null`, and both readouts
|
|
1047
|
-
printed "unverified" for the last two — so "the chain says this is NOT a clone of the configured
|
|
1048
|
-
factory" (a trust finding) looked identical to "the check never ran" (no factory on this chain, normal
|
|
1049
|
-
on a dev chain). Two reviewers read the collapsed word as a second failure sitting next to a real one.
|
|
1050
|
-
- **`abx verify --remote` gave a bare `fetch failed`** for an endpoint that was down, where
|
|
1051
|
-
`abx status --remote` names the host and asks whether it's running. Two commands, one condition, two
|
|
1052
|
-
error qualities — now consistent.
|
|
1053
|
-
- `abx status <addr>` printed the address twice when the project has no name.
|
|
1054
|
-
- Skill: registering with a provider on **their** hostname vs. a domain you control decides whether
|
|
1055
|
-
leaving later costs a transaction — now stated in the managed-provider section, before you bake it.
|
|
1056
|
-
|
|
1057
|
-
### Patch Changes
|
|
1058
|
-
|
|
1059
|
-
- Updated dependencies [a72723d]
|
|
1060
|
-
- @artblocks/abx-sdk@0.1.0-alpha.3
|
|
1061
|
-
- @artblocks/abx-indexer@0.1.0-alpha.4
|
|
1062
|
-
- @artblocks/abx-storage@0.1.0-alpha.3
|
|
1063
|
-
|
|
1064
|
-
## 0.1.0-alpha.5
|
|
1065
|
-
|
|
1066
|
-
### Minor Changes
|
|
1067
|
-
|
|
1068
|
-
- 3745bd3: Remote services are first-class: a provider-neutral control plane, named remotes, and a service
|
|
1069
|
-
descriptor (specs/self-host-toolkit/remote-services.md).
|
|
1070
|
-
|
|
1071
|
-
- **Control plane moves to `/v1`** (hard cutover; `/admin/*` is gone — redeploy self-hosted nodes):
|
|
1072
|
-
`POST/GET /v1/projects`, `DELETE|reindex|status /v1/projects/{chainId}/{address}`,
|
|
1073
|
-
`POST /v1/effect-artifacts|effect-status`. `chainId` is explicit and validated everywhere; every
|
|
1074
|
-
error carries a machine `code` (`unauthorized` 401 · `forbidden` 403 · `unsupported_chain` ·
|
|
1075
|
-
`not_registered` · `disabled`) replacing the old prose-sniffed 404. One bearer guard replaces the
|
|
1076
|
-
four inline copies; OPTIONS preflight now answers so browser clients can send `Authorization`.
|
|
1077
|
-
- **`GET /.well-known/abx-service`** — the public service descriptor: `interfaces` (present iff
|
|
1078
|
-
actually enabled), `chains`, `auth` (with optional provider-set `signupUrl`/`docsUrl` via
|
|
1079
|
-
`ABX_SERVICE_*` env), and `render.attached` (managed rendering, probed from the runner's
|
|
1080
|
-
`/health`) — so an agent can match a project to a provider before registering.
|
|
1081
|
-
- **Named remotes in the CLI**: `--remote <name>` reads `ABX_REMOTE_<NAME>_URL`/`_TOKEN`
|
|
1082
|
-
(a managed provider's per-account key — never falls back to `ABX_RESOLVER_ADMIN_TOKEN`);
|
|
1083
|
-
`--remote <url> [--remote-token <t>]` for ad-hoc targets; bare `--remote` stays the self-host
|
|
1084
|
-
default. New `abx remote [name|url]` inspects a service's descriptor and the projects a token
|
|
1085
|
-
sees. `migrate --from/--to` accept names; only the destination needs a credential.
|
|
1086
|
-
- **The SDK gains its first HTTP surface**: `AbxServiceClient` (endpoint + injected bearer, retry
|
|
1087
|
-
on 5xx/network, immediate typed `AbxServiceError` on 4xx) — shared by the CLI and the effects
|
|
1088
|
-
runner's publish lane. `envSuffix()` is the shared env-name normalization.
|
|
1089
|
-
- **Conformance fixture**: `pnpm conformance -- <base-url> [--token …]` self-verifies any
|
|
1090
|
-
implementation; the e2e suite runs it against the reference container.
|
|
1091
|
-
|
|
1092
|
-
### Patch Changes
|
|
1093
|
-
|
|
1094
|
-
- 3745bd3: Membrane fixes found by a 20-run cold-agent regression sweep (sonnet + haiku, black-box clean rooms).
|
|
1095
|
-
|
|
1096
|
-
- **A 500 no longer leaks the node's own credentials.** An upstream RPC failure surfaced viem's
|
|
1097
|
-
message, which embeds the endpoint URL — and a keyed RPC URL _is_ a credential, so on a
|
|
1098
|
-
multi-tenant provider any tenant who could provoke a 500 got the operator's RPC key. The cause now
|
|
1099
|
-
goes to the node's log; the wire gets a generic message, an `internal_error` code, and a
|
|
1100
|
-
credential-free hint about the failure class. Normative in the remote-services spec.
|
|
1101
|
-
- **The service client no longer discards a 5xx body.** The service's own words survive the retry
|
|
1102
|
-
ladder, and an exhausted ladder says "failed — last response …" rather than mislabelling a
|
|
1103
|
-
server that answered as "unreachable". The descriptor probe drops to 2 attempts, so a typo'd
|
|
1104
|
-
provider URL fails in ~1s instead of grinding 5s, with distinct "nothing responded" vs
|
|
1105
|
-
"answered, but serves no descriptor" messages.
|
|
1106
|
-
- **Conflicting duplicate `.env` keys are reported.** First-wins is unchanged, but a stale second
|
|
1107
|
-
`ABX_RPC_URLS_<CHAIN>` line silently pointed the CLI at another network while every check read
|
|
1108
|
-
green — the symptom surfaced far away as "no contract at that address". Only genuinely
|
|
1109
|
-
_conflicting_ duplicates warn (identical repeats stay quiet).
|
|
1110
|
-
- **"No contract at …" errors now name the endpoint they asked** (redacted), because a chain key
|
|
1111
|
-
can't distinguish two RPCs that both claim it.
|
|
1112
|
-
- **A misnamed remote credential is called out.** `ABX_REMOTE_<NAME>_KEY` (or `_API_KEY`, `_SECRET`)
|
|
1113
|
-
is not read, so it previously reported as "no token" while the value sat in `.env`; both
|
|
1114
|
-
`abx remote` and the register path now name the near-miss and the correct `_TOKEN` name.
|
|
1115
|
-
- **`--dry-run` explains a missing trust anchor instead of crashing.** On a chain where the
|
|
1116
|
-
configured factory has no code, `deploy`/`deploy-series` previews died inside
|
|
1117
|
-
`predictDeterministicAddress` with a raw `returned no data ("0x")`; they now report it the way
|
|
1118
|
-
`abx predict` and a real deploy already did, and name the two ways forward. The keyless
|
|
1119
|
-
`--for` requirement also fails fast instead of after several steps of output.
|
|
1120
|
-
- **The placeholder-identity guard is one shared predicate** across all three deploy commands
|
|
1121
|
-
(it was copy-pasted, and one copy's comment claimed coverage it didn't have), pinned by a new
|
|
1122
|
-
regression test: a real send refuses tool defaults, a preview only warns.
|
|
1123
|
-
- **The served dashboard's empty state no longer prints `pnpm abx demo`** — a contributor-only
|
|
1124
|
-
invocation on a page a published user sees.
|
|
1125
|
-
|
|
1126
|
-
- Updated dependencies [3745bd3]
|
|
1127
|
-
- Updated dependencies [3745bd3]
|
|
1128
|
-
- @artblocks/abx-sdk@0.1.0-alpha.2
|
|
1129
|
-
- @artblocks/abx-indexer@0.1.0-alpha.3
|
|
1130
|
-
- @artblocks/abx-storage@0.1.0-alpha.2
|
|
1131
|
-
|
|
1132
|
-
## 0.1.0-alpha.4
|
|
1133
|
-
|
|
1134
|
-
### Patch Changes
|
|
1135
|
-
|
|
1136
|
-
- 4074766: Fix the dashboard's block-explorer links, which were hardcoded to `https://sepolia.etherscan.io`. Every
|
|
1137
|
-
link on the page — contract, owner, implementation, each event's tx — pointed at Ethereum Sepolia no
|
|
1138
|
-
matter which chain was being served, so a dashboard for a normal `abx demo` (Base Sepolia by default)
|
|
1139
|
-
sent you to an explorer where the contract does not exist. The SDK now derives the explorer from viem's
|
|
1140
|
-
own chain metadata (`explorerUrl`/`chainById`), so adding a chain brings its explorer along and no
|
|
1141
|
-
hand-maintained table can drift. The CLI's separate copy of that table is collapsed into the same
|
|
1142
|
-
helper; `signer.ts` was already doing it correctly.
|
|
1143
|
-
|
|
1144
|
-
Drop the demo's opening "trust anchor" step. It asserted that only the canonical factory can make a
|
|
1145
|
-
token that _is_ an ABX token, which is false — anything following the protocol's event spine is an ABX
|
|
1146
|
-
token, and the factory is one route to that, not the definition. The same overclaim in the index step
|
|
1147
|
-
("verified real") now reports the fact instead: made by the canonical factory, or not. The demo opens
|
|
1148
|
-
on the renderer step, and resolving the factory no longer prints a line of its own there.
|
|
1149
|
-
|
|
1150
|
-
- Updated dependencies [4074766]
|
|
1151
|
-
- @artblocks/abx-sdk@0.1.0-alpha.1
|
|
1152
|
-
- @artblocks/abx-indexer@0.1.0-alpha.2
|
|
1153
|
-
- @artblocks/abx-storage@0.1.0-alpha.1
|
|
1154
|
-
|
|
1155
|
-
## 0.1.0-alpha.3
|
|
1156
|
-
|
|
1157
|
-
### Patch Changes
|
|
1158
|
-
|
|
1159
|
-
- Updated dependencies [c21ea30]
|
|
1160
|
-
- @artblocks/abx-indexer@0.1.0-alpha.1
|
|
1161
|
-
|
|
1162
|
-
## 0.1.0-alpha.2
|
|
1163
|
-
|
|
1164
|
-
### Patch Changes
|
|
1165
|
-
|
|
1166
|
-
- afb36a3: Fix three bugs that made the documented first run (`abx demo`) look broken.
|
|
1167
|
-
|
|
1168
|
-
**A 0-event index was reported as success, and served.** `eth_getLogs` is
|
|
1169
|
-
read-after-write inconsistent on load-balanced RPCs: `waitForTransactionReceipt`
|
|
1170
|
-
resolves against a node that has the block, then the log query lands on one that
|
|
1171
|
-
doesn't yet and returns nothing for a block we _know_ contains our deploy. The CLI
|
|
1172
|
-
took that single read at face value, printed `✓ reconstructed 0 events`, stored the
|
|
1173
|
-
empty projection and served an empty dashboard — no events, no token, nothing to
|
|
1174
|
-
look at. This reproduced 100% of the time against `https://sepolia.base.org`, which
|
|
1175
|
-
is the **default endpoint when there is no `.env`** — so the documented first run
|
|
1176
|
-
was the path that broke. Every post-deploy index (`deploy`, `demo`, `deploy-series`,
|
|
1177
|
-
`deploy-code`, `add`) now re-scans with backoff instead of trusting one read, since
|
|
1178
|
-
having just minted means the spine cannot legitimately be empty. If it still comes
|
|
1179
|
-
back empty, that is now reported as a failure naming `abx index <addr> --full` as
|
|
1180
|
-
the recovery, rather than dressed up as a ✓.
|
|
1181
|
-
|
|
1182
|
-
**The demo told you to press a button that does not exist.** It ended with _"Open
|
|
1183
|
-
the dashboard, then hit 'Re-index from chain'"_. The dashboard is read-only —
|
|
1184
|
-
re-index and verify are admin actions that 404 unless the node has an
|
|
1185
|
-
`ABX_RESOLVER_ADMIN_TOKEN` — so that control isn't there to find. It now points at
|
|
1186
|
-
the spine table (which _is_ the reconstruction) and at `abx index <addr> --full` to
|
|
1187
|
-
replay it. The dashboard's own note also stopped printing a **shortened** address
|
|
1188
|
-
inside a copy-pasteable command, and no longer suggests `--remote` for a local node.
|
|
1189
|
-
|
|
1190
|
-
**Re-running the demo crashed after spending a transaction.** With port 8787 already
|
|
1191
|
-
busy — an `abx demo` or `abx serve` in another terminal, i.e. exactly what happens
|
|
1192
|
-
when you run the demo twice — the deploy went through, was paid for, and _then_ the
|
|
1193
|
-
serve step died with an unhandled Node `EADDRINUSE` stack trace. The port is now
|
|
1194
|
-
preflighted before anything irreversible, so it refuses with "Nothing was deployed"
|
|
1195
|
-
and suggests `--port <n+1>`.
|
|
1196
|
-
|
|
1197
|
-
**`abx demo` is now a walkthrough rather than a smoke test.** The docs point a
|
|
1198
|
-
first-time reader here, but it asserted its interesting claims without ever showing
|
|
1199
|
-
them — "reconstructed 9 events — no provider involved" with the events invisible.
|
|
1200
|
-
It now teaches, continuously and without pauses (so agents and CI behave
|
|
1201
|
-
identically): it explains why the trust anchor is the factory and not a spoofable
|
|
1202
|
-
event, names what goes on chain versus what stays a keccak256 commitment, prints
|
|
1203
|
-
the reconstructed event spine with what each event told us (tagged ABX vs plain
|
|
1204
|
-
ERC-721/7572), then **deletes its own local projection and replays it from the
|
|
1205
|
-
deploy block**, comparing a sha256 fingerprint of every chain-derived field to prove
|
|
1206
|
-
it lands on identical state. Finally it reads the token back the way a marketplace
|
|
1207
|
-
would. `abx deploy` is unchanged — it stays terse.
|
|
1208
|
-
|
|
1209
|
-
Adds `Store.dropProjection(address)` / `SelfHostIndexer.dropProjection()`: discard a
|
|
1210
|
-
project's reconstructed projection while keeping its registration, so the next index
|
|
1211
|
-
rebuilds from the deploy block. That's the primitive the rebuild proof needs, and it
|
|
1212
|
-
makes "the projection is a disposable cache" a checkable claim rather than a comment.
|
|
1213
|
-
|
|
1214
|
-
## 0.1.0-alpha.1
|
|
1215
|
-
|
|
1216
|
-
### Patch Changes
|
|
1217
|
-
|
|
1218
|
-
- 48d96c5: Add **`abx preview`** — the studio lane for code projects: run the program on
|
|
1219
|
-
localhost, live, while it's still being made. No chain, no key, no deploy.
|
|
1220
|
-
|
|
1221
|
-
`abx preview --script art.js --schema "palette:HexColor:TokenOwner"` serves a
|
|
1222
|
-
studio on `localhost:8788` — shuffle seeds, drive every declared PostParam from a
|
|
1223
|
-
real typed input (a color picker for `HexColor`, a dropdown for `Select`), read the
|
|
1224
|
-
traits the program actually reported, and `/grid` to see N seeds at once. `/view`
|
|
1225
|
-
is the bare document. The program is re-read from disk on every render, so the loop
|
|
1226
|
-
is edit-and-refresh with no watcher and no restart.
|
|
1227
|
-
|
|
1228
|
-
It serves the **same template-mode document the generator serves** — the real
|
|
1229
|
-
`abx.js`, the real canonical `tokenData` shape, the real dependency script tags —
|
|
1230
|
-
with a synthetic bytes32 seed in place of a minted one, so what you approve is what
|
|
1231
|
-
deploys. There is no second copy of the runtime to drift from. (`@artblocks/abx-token-api`
|
|
1232
|
-
now exports `ABX_JS` and the inline-safety escapes so the CLI can build that exact
|
|
1233
|
-
document rather than reimplement it.)
|
|
1234
|
-
|
|
1235
|
-
`--shoot <dir>` drives the same server headlessly to PNGs plus a `traits.json` and
|
|
1236
|
-
exits — that's how an agent, which can't open a browser, sees what the creator sees.
|
|
1237
|
-
It also flags the two silent killers: no frame reporting traits (⇒ no marketplace
|
|
1238
|
-
`attributes` on any lane) and identical traits across every seed (⇒ the program
|
|
1239
|
-
isn't reading `abx.tokenData.seed`, so the drop mints N identical tokens).
|
|
1240
|
-
|
|
1241
|
-
Why a live server rather than a screenshot sweep: a still flattens every time-based
|
|
1242
|
-
piece, and `abx.done()` exists precisely because stills need a settle point — so a
|
|
1243
|
-
proof sheet of an animated piece is a set of arbitrary frozen frames presented as
|
|
1244
|
-
the work. Frames render into a fixed 1000×1000 viewport and are scaled to fit their
|
|
1245
|
-
slot, so a program that hardcodes its canvas size is never clipped to its own corner.
|
|
37
|
+
- 64248d9: Establish the public source baseline and refresh dependency constraints.
|
|
38
|
+
- Updated dependencies [64248d9]
|
|
39
|
+
- @artblocks/abx-indexer@0.1.0-alpha.31
|
|
40
|
+
- @artblocks/abx-sdk@0.1.0-alpha.30
|
|
41
|
+
- @artblocks/abx-storage@0.1.0-alpha.30
|
|
1246
42
|
|
|
1247
|
-
|
|
1248
|
-
(hosting, thumbnail, traits, storage, wallet, supply, royalties, name/symbol) off
|
|
1249
|
-
the table until the creator says ship, and points at `abx preview` for the loop. The
|
|
1250
|
-
skill previously went straight from "the creator brought an idea" to "pick a deploy
|
|
1251
|
-
lane", so an agent helping someone _design_ a piece front-loaded infrastructure
|
|
1252
|
-
questions while there was still nothing to look at.
|
|
43
|
+
## Unreleased
|
|
1253
44
|
|
|
1254
|
-
|
|
1255
|
-
before global, install `@artblocks/abx-cli` (not `@artblocks/abx-sdk`, which ships
|
|
1256
|
-
no binary), and default to a per-project install. The skill previously assumed `abx`
|
|
1257
|
-
was already on PATH and gave no bootstrap path at all, so agents improvised — one
|
|
1258
|
-
installed the SDK, then went global unprompted.
|
|
45
|
+
Public release history begins here.
|