@artblocks/abx-cli 0.1.0-alpha.53 → 0.1.0-alpha.54
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 +15 -0
- package/dist/commands/deploy.js +1 -1
- package/dist/commands/project.d.ts +27 -0
- package/dist/commands/project.d.ts.map +1 -1
- package/dist/commands/project.js +134 -98
- package/dist/commands/project.js.map +1 -1
- package/dist/commands/reads.d.ts +1 -1
- package/dist/commands/reads.d.ts.map +1 -1
- package/dist/commands/reads.js +56 -44
- package/dist/commands/reads.js.map +1 -1
- package/dist/flag-allowlists.js +2 -2
- package/dist/flag-allowlists.js.map +1 -1
- package/dist/main.js +5 -1
- package/dist/main.js.map +1 -1
- package/dist/output.d.ts +6 -1
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +1 -7
- package/dist/output.js.map +1 -1
- package/dist/remote.d.ts +9 -1
- package/dist/remote.d.ts.map +1 -1
- package/dist/remote.js +27 -3
- package/dist/remote.js.map +1 -1
- package/package.json +6 -6
- package/skill/SKILL.md +1 -1
- package/skill/reference/operate.md +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @artblocks/abx-cli
|
|
2
2
|
|
|
3
|
+
## 0.1.0-alpha.54
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- f9d7a44: Clarify fully on-chain image deployment tradeoffs and make static-project verification report
|
|
8
|
+
`onChainUri.chainComplete` as not applicable instead of false.
|
|
9
|
+
- ee24497: Add machine-readable `--json` output to `contracturi` and `add`. Collection metadata reads now emit
|
|
10
|
+
the resolved document alone, while registration reports identify the target surface, chain and
|
|
11
|
+
address, scan floor, lifecycle status, and whether remote catch-up is complete or still backfilling.
|
|
12
|
+
- Updated dependencies [b9197bc]
|
|
13
|
+
- @artblocks/abx-sdk@0.1.0-alpha.40
|
|
14
|
+
- @artblocks/abx-indexer@0.1.0-alpha.41
|
|
15
|
+
- @artblocks/abx-storage@0.1.0-alpha.40
|
|
16
|
+
- @artblocks/abx-token-api@0.1.0-alpha.43
|
|
17
|
+
|
|
3
18
|
## 0.1.0-alpha.53
|
|
4
19
|
|
|
5
20
|
### Patch Changes
|
package/dist/commands/deploy.js
CHANGED
|
@@ -947,7 +947,7 @@ export async function cmdDeployBody(flags, serveAfter, emit) {
|
|
|
947
947
|
})()
|
|
948
948
|
: 1;
|
|
949
949
|
if (dryRun && onchainImage && imageEndsUpOnChain(flags, false)) {
|
|
950
|
-
|
|
950
|
+
warn(`${bold('one-transaction alternative:')} this SVG can be inlined with bare ${bold('--onchain-uri')} instead of staged with ` +
|
|
951
951
|
`${bold('--onchain-image')} (${approvals} transactions here). Dry-run that form before changing lanes.`);
|
|
952
952
|
}
|
|
953
953
|
// Mint-on-deploy is the default; --no-mint defers it so you can stand up + warm
|
|
@@ -2,6 +2,29 @@ import { type Address, type PublicClient, type MetadataField } from '@artblocks/
|
|
|
2
2
|
import { type Flags } from '../flags.js';
|
|
3
3
|
import { type RemoteTarget } from '../remote.js';
|
|
4
4
|
export declare function cmdPredict(flags: Flags): Promise<void>;
|
|
5
|
+
export interface AddJsonResult extends Record<string, unknown> {
|
|
6
|
+
target: {
|
|
7
|
+
surface: 'local' | 'remote';
|
|
8
|
+
name: string | null;
|
|
9
|
+
url: string | null;
|
|
10
|
+
};
|
|
11
|
+
chainId: number;
|
|
12
|
+
address: Address;
|
|
13
|
+
status: string;
|
|
14
|
+
scanFloor: string;
|
|
15
|
+
completed: boolean;
|
|
16
|
+
backfilling: boolean;
|
|
17
|
+
eventCount?: number;
|
|
18
|
+
tokenCount?: number;
|
|
19
|
+
}
|
|
20
|
+
/** Keep the local lane's machine contract independent of the indexer's larger state object. */
|
|
21
|
+
export declare function localAddJsonResult(input: {
|
|
22
|
+
chainId: number;
|
|
23
|
+
address: Address;
|
|
24
|
+
scanFloor: string;
|
|
25
|
+
eventCount: number;
|
|
26
|
+
tokenCount: number;
|
|
27
|
+
}): AddJsonResult;
|
|
5
28
|
export declare function cmdAdd(address: Address | undefined, flags: Flags): Promise<void>;
|
|
6
29
|
export declare function cmdIndex(address: Address | undefined, flags: Flags): Promise<void>;
|
|
7
30
|
export declare function cmdVerify(address: Address | undefined, flags: Flags): Promise<void>;
|
|
@@ -42,6 +65,10 @@ export declare function onChainImageSource(fields: MetadataField[]): string | nu
|
|
|
42
65
|
* "no commitment", a different fact from "an unrecomputable one".
|
|
43
66
|
*/
|
|
44
67
|
export declare function pointerOnlyImageCheck(fields: MetadataField[]): string | null;
|
|
68
|
+
/** `chainComplete` describes a code template's dependency graph. Static projects have no code
|
|
69
|
+
* graph to classify, so their structured verification result must say "not applicable" instead
|
|
70
|
+
* of reporting a confident `false` that reads like a failed durability check. */
|
|
71
|
+
export declare function verifyChainComplete(isCodeProject: boolean, chainComplete: boolean): boolean | null;
|
|
45
72
|
export declare function cmdVerifyBody(address: Address, flags: Flags, emit: (p: Record<string, unknown>) => void): Promise<void>;
|
|
46
73
|
export declare function cmdVerifyRemote(address: Address, remote: RemoteTarget, emit: (p: Record<string, unknown>) => void): Promise<void>;
|
|
47
74
|
/** What {@link reportRemoteByteIntegrity} found, structured for the JSON payload as well as its own
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../src/commands/project.ts"],"names":[],"mappings":"AAQA,OAAO,EAGL,KAAK,OAAO,EAGZ,KAAK,YAAY,EAkCjB,KAAK,aAAa,EACnB,MAAM,oBAAoB,CAAC;AAgB5B,OAAO,EAAC,KAAK,KAAK,EAA6C,MAAM,aAAa,CAAC;AAOnF,OAAO,EACL,KAAK,YAAY,EAalB,MAAM,cAAc,CAAC;AAQtB,wBAAsB,UAAU,CAAC,KAAK,EAAE,KAAK,iBA+E5C;AAMD,wBAAsB,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../src/commands/project.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/project.js
CHANGED
|
@@ -99,10 +99,20 @@ export async function cmdPredict(flags) {
|
|
|
99
99
|
info(dim('(this is the 1/1 lane; a Series/code drop uses a different factory → a different address — pass --dir / --script to predict those, or use that command\'s --dry-run)'));
|
|
100
100
|
console.log('');
|
|
101
101
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
102
|
+
/** Keep the local lane's machine contract independent of the indexer's larger state object. */
|
|
103
|
+
export function localAddJsonResult(input) {
|
|
104
|
+
return {
|
|
105
|
+
target: { surface: 'local', name: null, url: null },
|
|
106
|
+
chainId: input.chainId,
|
|
107
|
+
address: input.address,
|
|
108
|
+
status: input.eventCount > 0 ? 'live' : 'empty',
|
|
109
|
+
scanFloor: input.scanFloor,
|
|
110
|
+
completed: true,
|
|
111
|
+
backfilling: false,
|
|
112
|
+
eventCount: input.eventCount,
|
|
113
|
+
tokenCount: input.tokenCount,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
106
116
|
export async function cmdAdd(address, flags) {
|
|
107
117
|
if (!address || address.startsWith('--')) {
|
|
108
118
|
console.error('usage: abx add <address> [--from-block N] [--factory 0x..] [--label "..."] [--remote [name|url]]\n');
|
|
@@ -118,103 +128,123 @@ export async function cmdAdd(address, flags) {
|
|
|
118
128
|
'Nothing here touches the chain, but it does write. To look before acting: `abx state <address>` (on-chain snapshot) ' +
|
|
119
129
|
'or `abx status <address> [--remote <name>]` (what a node already has). Re-run without --dry-run when you mean it.');
|
|
120
130
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
131
|
+
return withJson(flags, async (emit) => {
|
|
132
|
+
// `--attributes` is lane-aware here exactly as at deploy: a PER-TOKEN payload edits a Series'
|
|
133
|
+
// per-token off-chain traits; a flat payload (+ `--traits`) edits the collection/1-of-1 `attributes`.
|
|
134
|
+
// Ambiguity defaults to flat (see looksPerTokenAttributes), so a 1/1 add is never mis-read.
|
|
135
|
+
const attrRaw = flags.attributes ? readFileSync(resolvePath(process.cwd(), String(flags.attributes)), 'utf8') : undefined;
|
|
136
|
+
const perTokenEdit = attrRaw != null && looksPerTokenAttributes(attrRaw);
|
|
137
|
+
const flagTraits = [];
|
|
138
|
+
if (attrRaw != null && !perTokenEdit)
|
|
139
|
+
flagTraits.push(...normalizeAttributes(JSON.parse(attrRaw)));
|
|
140
|
+
if (flags.traits)
|
|
141
|
+
flagTraits.push(...parseTraitPairs(flags.traits));
|
|
142
|
+
const editedTokenAttributes = perTokenEdit ? parseSeriesTraitsById(attrRaw) : undefined;
|
|
143
|
+
const remote = remoteFlag(flags);
|
|
144
|
+
if (remote) {
|
|
145
|
+
requireRemoteToken(remote);
|
|
146
|
+
// Bridge what a remote resolver can't derive itself: the off-chain traits and the durable
|
|
147
|
+
// content locators (ipfs://…). Prefer flags; otherwise forward what the LOCAL deploy stored
|
|
148
|
+
// (the local registration), and compute locators from this machine's content index if needed.
|
|
149
|
+
const localReg = localIndexer().store.getRegistration(address);
|
|
150
|
+
const attributes = flagTraits.length
|
|
151
|
+
? flagTraits
|
|
152
|
+
: localReg?.attributes
|
|
153
|
+
? normalizeAttributes(JSON.parse(localReg.attributes))
|
|
154
|
+
: undefined;
|
|
155
|
+
// Bridge a Series' per-token off-chain traits to the remote resolver (the resolver has no other
|
|
156
|
+
// way to derive them — they're operator metadata, not chain state). A fresh per-token `--attributes`
|
|
157
|
+
// EDITS them; otherwise forward what the LOCAL deploy stored. Best-effort parse.
|
|
158
|
+
let tokenAttributes;
|
|
159
|
+
if (editedTokenAttributes && Object.keys(editedTokenAttributes).length) {
|
|
160
|
+
tokenAttributes = editedTokenAttributes;
|
|
161
|
+
}
|
|
162
|
+
else if (localReg?.tokenAttributes) {
|
|
163
|
+
try {
|
|
164
|
+
const obj = JSON.parse(localReg.tokenAttributes);
|
|
165
|
+
const norm = {};
|
|
166
|
+
for (const [id, v] of Object.entries(obj)) {
|
|
167
|
+
const a = normalizeAttributes(v);
|
|
168
|
+
if (a.length)
|
|
169
|
+
norm[id] = a;
|
|
170
|
+
}
|
|
171
|
+
if (Object.keys(norm).length)
|
|
172
|
+
tokenAttributes = norm;
|
|
159
173
|
}
|
|
160
|
-
|
|
161
|
-
tokenAttributes = norm;
|
|
174
|
+
catch { /* skip a malformed local column */ }
|
|
162
175
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
176
|
+
const contentLocators = await remoteLocators(address, localReg?.contentLocators, flags);
|
|
177
|
+
// Forward the deploy block, like every other field falls back to the local registration.
|
|
178
|
+
// (Its ABSENCE here was the bug: a hosted resolver defaulted to genesis and scanned the whole
|
|
179
|
+
// chain.) Re-sending the same floor stays incremental server-side, so a nudge ≠ a re-scan.
|
|
180
|
+
const body = {
|
|
181
|
+
chainId: resolveChain(CHAIN).id,
|
|
182
|
+
address,
|
|
183
|
+
fromBlock: await resolveScanFloor(address, localReg?.fromBlock, flags),
|
|
184
|
+
factory: await detectCanonicalFactory(address, flags.factory, localReg?.factory),
|
|
185
|
+
label: flags.label,
|
|
186
|
+
description: flags.description ?? localReg?.description,
|
|
187
|
+
externalUrl: flags['external-url'] ?? localReg?.externalUrl,
|
|
188
|
+
attributes,
|
|
189
|
+
tokenAttributes,
|
|
190
|
+
contentLocators: Object.keys(contentLocators).length ? contentLocators : undefined,
|
|
191
|
+
full: flags.full ? true : undefined,
|
|
192
|
+
};
|
|
193
|
+
info(`${bold('REMOTE')} → ${remote.url} ${dim('(registering with the remote resolver — NOT this machine)')}`);
|
|
194
|
+
if (body.contentLocators)
|
|
195
|
+
info(`bridging image locator → ${Object.values(body.contentLocators)[0]} ${dim('(so the resolver points at IPFS, not its own localhost)')}`);
|
|
196
|
+
let r;
|
|
197
|
+
try {
|
|
198
|
+
r = await serviceClient(remote).registerProject(body);
|
|
199
|
+
}
|
|
200
|
+
catch (err) {
|
|
201
|
+
throw describeRemoteError(err, remote, 'remote add');
|
|
202
|
+
}
|
|
203
|
+
const outcome = await reportRemoteIndexing(remote, body.chainId, address, r, flags, 'indexed');
|
|
204
|
+
info(`it now serves ${remote.url}/t/${body.chainId}/${address.toLowerCase()}/0`);
|
|
205
|
+
// "Indexed" is not "correct". This line proves the service replayed the chain and will answer at
|
|
206
|
+
// that URL; it says nothing about whether the bytes it serves match the on-chain commitment.
|
|
207
|
+
// Name the step that checks.
|
|
208
|
+
info(`confirm what it actually serves (bytes vs. the on-chain hash): ${bold(`abx verify ${address} --remote ${remote.name?.toLowerCase() ?? remote.url}`)}`);
|
|
209
|
+
// Say what this registration did NOT buy. A project whose `tokenURIRenderer` is set answers
|
|
210
|
+
// `tokenURI` from the chain, so marketplaces and wallets read THAT document and never touch this
|
|
211
|
+
// service — the register is still useful (indexing, the live view, managed rendering for a code
|
|
212
|
+
// drop) but it changes nothing a collector sees. Without this line the readout is a list of
|
|
213
|
+
// successes that reads like a win, and a creator who was told "put it on a hosted service so it
|
|
214
|
+
// shows up properly" concludes their problem is solved when nothing about it moved.
|
|
215
|
+
const onChainRenderer = await tryReadContract(makePublicClient({ chainKey: CHAIN }), {
|
|
216
|
+
address,
|
|
217
|
+
abi: STATE_ABI,
|
|
218
|
+
functionName: 'tokenURIRenderer',
|
|
219
|
+
});
|
|
220
|
+
if (onChainRenderer && onChainRenderer !== zeroAddress) {
|
|
221
|
+
info(`${dim('note:')} this project resolves ${bold('tokenURI from the chain')} (renderer ${onChainRenderer}) — marketplaces read that, not this service. ` +
|
|
222
|
+
`Registering still gives you indexing, the live view and managed rendering, but it does not change the metadata a collector sees.`);
|
|
223
|
+
}
|
|
224
|
+
emit({
|
|
225
|
+
target: { surface: 'remote', name: remote.name ?? null, url: remote.url },
|
|
226
|
+
chainId: body.chainId,
|
|
227
|
+
address,
|
|
228
|
+
status: outcome.status,
|
|
229
|
+
scanFloor: body.fromBlock ?? '0',
|
|
230
|
+
completed: outcome.completed,
|
|
231
|
+
backfilling: outcome.backfilling,
|
|
232
|
+
...(outcome.eventCount === undefined ? {} : { eventCount: outcome.eventCount }),
|
|
233
|
+
...(outcome.tokenCount === undefined ? {} : { tokenCount: outcome.tokenCount }),
|
|
234
|
+
});
|
|
235
|
+
return;
|
|
191
236
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
info(`confirm what it actually serves (bytes vs. the on-chain hash): ${bold(`abx verify ${address} --remote ${remote.name?.toLowerCase() ?? remote.url}`)}`);
|
|
198
|
-
// Say what this registration did NOT buy. A project whose `tokenURIRenderer` is set answers
|
|
199
|
-
// `tokenURI` from the chain, so marketplaces and wallets read THAT document and never touch this
|
|
200
|
-
// service — the register is still useful (indexing, the live view, managed rendering for a code
|
|
201
|
-
// drop) but it changes nothing a collector sees. Without this line the readout is a list of
|
|
202
|
-
// successes that reads like a win, and a creator who was told "put it on a hosted service so it
|
|
203
|
-
// shows up properly" concludes their problem is solved when nothing about it moved.
|
|
204
|
-
const onChainRenderer = await tryReadContract(makePublicClient({ chainKey: CHAIN }), {
|
|
237
|
+
// The local (non-`--remote`) path is shared with the deploy family's post-setup registration —
|
|
238
|
+
// see registerAndIndexLocally's doc comment (output.ts).
|
|
239
|
+
const outcome = await registerAndIndexLocally(address, flags);
|
|
240
|
+
emit(localAddJsonResult({
|
|
241
|
+
chainId: outcome.state.chainId,
|
|
205
242
|
address,
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
`Registering still gives you indexing, the live view and managed rendering, but it does not change the metadata a collector sees.`);
|
|
212
|
-
}
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
// The local (non-`--remote`) path is shared with the deploy family's post-setup registration —
|
|
216
|
-
// see registerAndIndexLocally's doc comment (output.ts).
|
|
217
|
-
return registerAndIndexLocally(address, flags);
|
|
243
|
+
scanFloor: outcome.scanFloor,
|
|
244
|
+
eventCount: outcome.state.eventCount,
|
|
245
|
+
tokenCount: outcome.state.tokens.length,
|
|
246
|
+
}));
|
|
247
|
+
});
|
|
218
248
|
}
|
|
219
249
|
export async function cmdIndex(address, flags) {
|
|
220
250
|
const remote = remoteFlag(flags);
|
|
@@ -366,6 +396,12 @@ export function pointerOnlyImageCheck(fields) {
|
|
|
366
396
|
return image.representation;
|
|
367
397
|
return null;
|
|
368
398
|
}
|
|
399
|
+
/** `chainComplete` describes a code template's dependency graph. Static projects have no code
|
|
400
|
+
* graph to classify, so their structured verification result must say "not applicable" instead
|
|
401
|
+
* of reporting a confident `false` that reads like a failed durability check. */
|
|
402
|
+
export function verifyChainComplete(isCodeProject, chainComplete) {
|
|
403
|
+
return isCodeProject ? chainComplete : null;
|
|
404
|
+
}
|
|
369
405
|
export async function cmdVerifyBody(address, flags, emit) {
|
|
370
406
|
const indexer = localIndexer();
|
|
371
407
|
let state = indexer.getProject(address);
|
|
@@ -641,7 +677,7 @@ export async function cmdVerifyBody(address, flags, emit) {
|
|
|
641
677
|
// renderer — the underlying probe cannot tell those apart, so neither can this field.
|
|
642
678
|
tokenURIRendererCurrent: rendererCurrent,
|
|
643
679
|
branch: status.branchName,
|
|
644
|
-
chainComplete: !!status.chainComplete,
|
|
680
|
+
chainComplete: verifyChainComplete(isCodeProject, !!status.chainComplete),
|
|
645
681
|
unresolvedRefs: [...status.unresolvedRefs],
|
|
646
682
|
urlOverBudget: !!status.urlOverBudget,
|
|
647
683
|
probe: probe
|