@artblocks/abx-cli 0.1.0-alpha.12 → 0.1.0-alpha.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/gas.d.ts +63 -0
- package/dist/gas.d.ts.map +1 -0
- package/dist/gas.js +76 -0
- package/dist/gas.js.map +1 -0
- package/dist/inspect.d.ts.map +1 -1
- package/dist/inspect.js +121 -15
- package/dist/inspect.js.map +1 -1
- package/dist/main.js +268 -31
- package/dist/main.js.map +1 -1
- package/dist/ownerops.d.ts +22 -1
- package/dist/ownerops.d.ts.map +1 -1
- package/dist/ownerops.js +163 -5
- package/dist/ownerops.js.map +1 -1
- package/dist/preview.d.ts +6 -0
- package/dist/preview.d.ts.map +1 -1
- package/dist/preview.js +59 -23
- package/dist/preview.js.map +1 -1
- package/dist/schema.d.ts +12 -1
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +62 -7
- package/dist/schema.js.map +1 -1
- package/dist/signer.d.ts.map +1 -1
- package/dist/signer.js +38 -2
- package/dist/signer.js.map +1 -1
- package/package.json +6 -6
- package/skill/SKILL.md +27 -38
- package/skill/reference/code-projects.md +37 -2
- package/skill/reference/decisions.md +61 -0
package/dist/gas.d.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gas limits for a sequenced transaction — decided HERE, once, rather than re-read at signing time.
|
|
3
|
+
*
|
|
4
|
+
* The failure this exists to prevent, in full, because it is not obvious and it cost a reporter every
|
|
5
|
+
* `deploy-code` attempt of a session: a project deploys in two transactions, and the second targets
|
|
6
|
+
* the contract the first just created. If the node answering `eth_estimateGas` has not yet seen the
|
|
7
|
+
* deploy block, the target looks like an account with no code — and an estimate for a call to a
|
|
8
|
+
* codeless account is just the calldata cost, around 200k. That number is then sent as the gas limit.
|
|
9
|
+
* Once the contract does exist the same call needs ~941k, because storing a program on-chain is
|
|
10
|
+
* dominated by CREATE code deposit at ~200 gas per byte. The CREATE receives 63/64 of a budget that
|
|
11
|
+
* cannot cover the deposit, returns 0, and Solady's `SSTORE2.write` reverts `DeploymentFailed()` — a
|
|
12
|
+
* revert that reads like a contract bug and is really an out-of-gas.
|
|
13
|
+
*
|
|
14
|
+
* (Measured, from the real transactions: `gasLimit 201,616 / gasUsed 198,870` and
|
|
15
|
+
* `gasLimit 169,301 / gasUsed 166,810` — 98.6% and 98.5% of their limits. Replaying those payloads
|
|
16
|
+
* against a codeless address reproduces both limits to the gas; against the real contract the same
|
|
17
|
+
* calls estimate at 941,331.)
|
|
18
|
+
*
|
|
19
|
+
* The deploy loop already pinned the *nonce* against exactly this read-after-write lag on a
|
|
20
|
+
* distributed RPC. The rule generalizes, and it is the reason this module exists: **anything read at
|
|
21
|
+
* send time on a distributed RPC needs pinning, not just the nonce.**
|
|
22
|
+
*/
|
|
23
|
+
import type { Address, Hex, PublicClient } from 'viem';
|
|
24
|
+
/**
|
|
25
|
+
* Wait until `address` has code from THIS client's point of view. A deploy receipt proves the
|
|
26
|
+
* contract exists on chain; it does not prove the node answering the next request has caught up.
|
|
27
|
+
* Bounded — on timeout we proceed and let the gas floor carry it, since a slow RPC is not a reason
|
|
28
|
+
* to refuse to continue a deploy that already spent money.
|
|
29
|
+
*/
|
|
30
|
+
export declare function waitForCodeAt(client: PublicClient, address: Address, timeoutMs?: number): Promise<boolean>;
|
|
31
|
+
/**
|
|
32
|
+
* Decide a transaction's gas limit once, here.
|
|
33
|
+
*
|
|
34
|
+
* The important design point, because the obvious approach is wrong: when an estimate looks too low
|
|
35
|
+
* we do **not** substitute a computed number. A caller can only compute the *provable* part of a
|
|
36
|
+
* payload's cost (see `PreparedTx.gasFloor` — code deposit is 200 gas/byte and nothing else is
|
|
37
|
+
* physics); the same setup multicall also carries schema writes, dependency legs, URI legs and
|
|
38
|
+
* mints, whose cost we cannot derive without simulating them. A "probably enough" constant is a
|
|
39
|
+
* number tuned to whatever case was in front of its author: it papers over the symptom, then
|
|
40
|
+
* under-funds the next payload that carries a few more legs, producing the identical
|
|
41
|
+
* `DeploymentFailed()` with a fresh mystery attached.
|
|
42
|
+
*
|
|
43
|
+
* So the floor is used as a **detector**. An estimate below a provable minimum is not "low", it is
|
|
44
|
+
* *impossible* — proof that the node answering us is looking at the wrong state (typically it has
|
|
45
|
+
* not seen the deploy block yet, so the target reads as an account with no code and the estimate
|
|
46
|
+
* comes back as the calldata cost alone). The right response to a broken measurement is to take it
|
|
47
|
+
* again, and if it stays broken, to refuse — sending a transaction we can prove is under-funded
|
|
48
|
+
* would burn the gas AND orphan the contract.
|
|
49
|
+
*
|
|
50
|
+
* When the estimate IS plausible it is trusted, plus headroom for state drift between estimate and
|
|
51
|
+
* inclusion.
|
|
52
|
+
*/
|
|
53
|
+
export declare function pinGas(client: PublicClient, tx: {
|
|
54
|
+
from: Address;
|
|
55
|
+
to: Address | null;
|
|
56
|
+
data: Hex;
|
|
57
|
+
value?: Hex;
|
|
58
|
+
gasFloor?: Hex;
|
|
59
|
+
}, opts?: {
|
|
60
|
+
attempts?: number;
|
|
61
|
+
delayMs?: number;
|
|
62
|
+
}): Promise<bigint>;
|
|
63
|
+
//# sourceMappingURL=gas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gas.d.ts","sourceRoot":"","sources":["../src/gas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,EAAC,OAAO,EAAE,GAAG,EAAE,YAAY,EAAC,MAAM,MAAM,CAAC;AAErD;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAQhH;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,MAAM,CAC1B,MAAM,EAAE,YAAY,EACpB,EAAE,EAAE;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CAAC;IAAC,IAAI,EAAE,GAAG,CAAC;IAAC,KAAK,CAAC,EAAE,GAAG,CAAC;IAAC,QAAQ,CAAC,EAAE,GAAG,CAAA;CAAC,EAC/E,IAAI,GAAE;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAM,GAC/C,OAAO,CAAC,MAAM,CAAC,CAmCjB"}
|
package/dist/gas.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wait until `address` has code from THIS client's point of view. A deploy receipt proves the
|
|
3
|
+
* contract exists on chain; it does not prove the node answering the next request has caught up.
|
|
4
|
+
* Bounded — on timeout we proceed and let the gas floor carry it, since a slow RPC is not a reason
|
|
5
|
+
* to refuse to continue a deploy that already spent money.
|
|
6
|
+
*/
|
|
7
|
+
export async function waitForCodeAt(client, address, timeoutMs = 15_000) {
|
|
8
|
+
const deadline = Date.now() + timeoutMs;
|
|
9
|
+
for (;;) {
|
|
10
|
+
const code = await client.getCode({ address }).catch(() => undefined);
|
|
11
|
+
if (code && code !== '0x')
|
|
12
|
+
return true;
|
|
13
|
+
if (Date.now() >= deadline)
|
|
14
|
+
return false;
|
|
15
|
+
await new Promise((r) => setTimeout(r, 750));
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Decide a transaction's gas limit once, here.
|
|
20
|
+
*
|
|
21
|
+
* The important design point, because the obvious approach is wrong: when an estimate looks too low
|
|
22
|
+
* we do **not** substitute a computed number. A caller can only compute the *provable* part of a
|
|
23
|
+
* payload's cost (see `PreparedTx.gasFloor` — code deposit is 200 gas/byte and nothing else is
|
|
24
|
+
* physics); the same setup multicall also carries schema writes, dependency legs, URI legs and
|
|
25
|
+
* mints, whose cost we cannot derive without simulating them. A "probably enough" constant is a
|
|
26
|
+
* number tuned to whatever case was in front of its author: it papers over the symptom, then
|
|
27
|
+
* under-funds the next payload that carries a few more legs, producing the identical
|
|
28
|
+
* `DeploymentFailed()` with a fresh mystery attached.
|
|
29
|
+
*
|
|
30
|
+
* So the floor is used as a **detector**. An estimate below a provable minimum is not "low", it is
|
|
31
|
+
* *impossible* — proof that the node answering us is looking at the wrong state (typically it has
|
|
32
|
+
* not seen the deploy block yet, so the target reads as an account with no code and the estimate
|
|
33
|
+
* comes back as the calldata cost alone). The right response to a broken measurement is to take it
|
|
34
|
+
* again, and if it stays broken, to refuse — sending a transaction we can prove is under-funded
|
|
35
|
+
* would burn the gas AND orphan the contract.
|
|
36
|
+
*
|
|
37
|
+
* When the estimate IS plausible it is trusted, plus headroom for state drift between estimate and
|
|
38
|
+
* inclusion.
|
|
39
|
+
*/
|
|
40
|
+
export async function pinGas(client, tx, opts = {}) {
|
|
41
|
+
const floor = tx.gasFloor ? BigInt(tx.gasFloor) : 0n;
|
|
42
|
+
const attempts = opts.attempts ?? 3;
|
|
43
|
+
let lastEstimate = null;
|
|
44
|
+
let lastError;
|
|
45
|
+
for (let i = 0; i < attempts; i++) {
|
|
46
|
+
try {
|
|
47
|
+
const estimate = await client.estimateGas({
|
|
48
|
+
account: tx.from,
|
|
49
|
+
to: tx.to ?? undefined,
|
|
50
|
+
data: tx.data,
|
|
51
|
+
...(tx.value && tx.value !== '0x0' ? { value: BigInt(tx.value) } : {}),
|
|
52
|
+
});
|
|
53
|
+
// Plausible (or nothing provable to check it against) → trust it.
|
|
54
|
+
if (estimate >= floor)
|
|
55
|
+
return (estimate * 125n) / 100n;
|
|
56
|
+
lastEstimate = estimate;
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
lastError = err;
|
|
60
|
+
// A revert during estimation is a real answer about the transaction, not a lagging node —
|
|
61
|
+
// surface it immediately, since its message ("caller is not the owner") is the useful part.
|
|
62
|
+
if (floor === 0n)
|
|
63
|
+
throw err;
|
|
64
|
+
}
|
|
65
|
+
if (i < attempts - 1)
|
|
66
|
+
await new Promise((r) => setTimeout(r, opts.delayMs ?? 1_500));
|
|
67
|
+
}
|
|
68
|
+
if (lastEstimate !== null) {
|
|
69
|
+
throw new Error(`Refusing to send: the RPC estimated ${lastEstimate} gas for a transaction that provably needs at least ${floor} ` +
|
|
70
|
+
`(storing ${floor / 200n} bytes on-chain costs 200 gas/byte in code deposit alone). An estimate below the floor means the node ` +
|
|
71
|
+
`is answering from stale state — usually it has not seen the contract's deploy block yet, so the call looks like it is going to ` +
|
|
72
|
+
`an empty account. Sending this would revert DeploymentFailed() and burn the gas. Retry in a few seconds, or use a different RPC.`);
|
|
73
|
+
}
|
|
74
|
+
throw lastError instanceof Error ? lastError : new Error('gas estimation failed');
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=gas.js.map
|
package/dist/gas.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gas.js","sourceRoot":"","sources":["../src/gas.ts"],"names":[],"mappings":"AAwBA;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAAoB,EAAE,OAAgB,EAAE,SAAS,GAAG,MAAM;IAC5F,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IACxC,SAAS,CAAC;QACR,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAC,OAAO,EAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACpE,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QACvC,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,QAAQ;YAAE,OAAO,KAAK,CAAC;QACzC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,MAAoB,EACpB,EAA+E,EAC/E,OAA8C,EAAE;IAEhD,MAAM,KAAK,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC;IACpC,IAAI,YAAY,GAAkB,IAAI,CAAC;IACvC,IAAI,SAAkB,CAAC;IAEvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC;gBACxC,OAAO,EAAE,EAAE,CAAC,IAAI;gBAChB,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,SAAS;gBACtB,IAAI,EAAE,EAAE,CAAC,IAAI;gBACb,GAAG,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,EAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC;aACrE,CAAC,CAAC;YACH,kEAAkE;YAClE,IAAI,QAAQ,IAAI,KAAK;gBAAE,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;YACvD,YAAY,GAAG,QAAQ,CAAC;QAC1B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,SAAS,GAAG,GAAG,CAAC;YAChB,0FAA0F;YAC1F,4FAA4F;YAC5F,IAAI,KAAK,KAAK,EAAE;gBAAE,MAAM,GAAG,CAAC;QAC9B,CAAC;QACD,IAAI,CAAC,GAAG,QAAQ,GAAG,CAAC;YAAE,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC;IACvF,CAAC;IAED,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CACb,uCAAuC,YAAY,uDAAuD,KAAK,GAAG;YAChH,YAAY,KAAK,GAAG,IAAI,wGAAwG;YAChI,iIAAiI;YACjI,kIAAkI,CACrI,CAAC;IACJ,CAAC;IACD,MAAM,SAAS,YAAY,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;AACpF,CAAC"}
|
package/dist/inspect.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inspect.d.ts","sourceRoot":"","sources":["../src/inspect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAgBH,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,cAAc,GAAG,SAAS,GAAG,YAAY,GAAG,SAAS,CAAC;AAE9F,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAC,CAAC;IAC3C,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,EAAE;QAAC,MAAM,EAAE,OAAO,CAAC;QAAC,cAAc,EAAE,OAAO,CAAC;QAAC,cAAc,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAC,CAAC;IAC9F,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE;QAAC,OAAO,EAAE,gBAAgB,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAC,CAAC;IACzD,GAAG,EAAE;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAC;QAAC,cAAc,EAAE,OAAO,CAAC;QAAC,eAAe,EAAE,OAAO,CAAA;KAAC,CAAC;IAM3F,OAAO,EAAE;QAAC,cAAc,EAAE,OAAO,CAAC;QAAC,aAAa,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;KAAC,CAAC;CACxF;
|
|
1
|
+
{"version":3,"file":"inspect.d.ts","sourceRoot":"","sources":["../src/inspect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAgBH,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,cAAc,GAAG,SAAS,GAAG,YAAY,GAAG,SAAS,CAAC;AAE9F,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAC,CAAC;IAC3C,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,EAAE;QAAC,MAAM,EAAE,OAAO,CAAC;QAAC,cAAc,EAAE,OAAO,CAAC;QAAC,cAAc,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAC,CAAC;IAC9F,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE;QAAC,OAAO,EAAE,gBAAgB,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAC,CAAC;IACzD,GAAG,EAAE;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAC;QAAC,cAAc,EAAE,OAAO,CAAC;QAAC,eAAe,EAAE,OAAO,CAAA;KAAC,CAAC;IAM3F,OAAO,EAAE;QAAC,cAAc,EAAE,OAAO,CAAC;QAAC,aAAa,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;KAAC,CAAC;CACxF;AAoID,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,GAAE,MAAM,EAAO,GAAG,cAAc,CA0FzF;AAED,2FAA2F;AAC3F,wBAAgB,aAAa,CAAC,CAAC,EAAE,cAAc,GAAG,MAAM,CA0BvD"}
|
package/dist/inspect.js
CHANGED
|
@@ -20,6 +20,84 @@ const RUNTIME_DOC_BYTES = 13_000;
|
|
|
20
20
|
* (geth's 50M gas cap; memory expansion is ~quadratic). Past it, marketplaces that call `tokenURI`
|
|
21
21
|
* once may time out — prefer the generator's piecewise getters, directory mode, or a CDN dep. */
|
|
22
22
|
const SINGLE_CALL_DOC_CEILING = 1_500_000;
|
|
23
|
+
/**
|
|
24
|
+
* Two views of the source, so a regex heuristic can never fire on prose.
|
|
25
|
+
*
|
|
26
|
+
* Every detector here is a regex over the file, and a comment or a string is not code: a
|
|
27
|
+
* dependency-free sketch whose header reads `// vanilla canvas, no p5` was reported as
|
|
28
|
+
* `libraries: p5` and then RECOMMENDED `--dep p5@<version>` — advice the agent adopts verbatim,
|
|
29
|
+
* which bloats the stored document and can drag a drop onto the wrong chain (on-chain deps need a
|
|
30
|
+
* dependency registry ⇒ Sepolia, not Base Sepolia). One tokenizer pass fixes that whole class.
|
|
31
|
+
*
|
|
32
|
+
* - `code`: comments removed, string/template contents blanked (quotes kept, so syntax survives).
|
|
33
|
+
* For flags that must reflect real code — library globals, PRNG use, the runtime data contract.
|
|
34
|
+
* - `noComments`: comments removed, strings INTACT. For extractors that read literal content —
|
|
35
|
+
* trait keys (`'Plant Count':`) and bracket-accessed param keys (`tokenData['collapse.index']`).
|
|
36
|
+
*/
|
|
37
|
+
function sourceViews(source) {
|
|
38
|
+
const code = [];
|
|
39
|
+
const noComments = [];
|
|
40
|
+
const n = source.length;
|
|
41
|
+
let i = 0;
|
|
42
|
+
const push = (ch, inString) => {
|
|
43
|
+
noComments.push(ch);
|
|
44
|
+
code.push(inString ? ' ' : ch);
|
|
45
|
+
};
|
|
46
|
+
while (i < n) {
|
|
47
|
+
const ch = source[i];
|
|
48
|
+
const next = source[i + 1];
|
|
49
|
+
// Comments — dropped from both views (newlines kept so line-anchored regexes still work).
|
|
50
|
+
if (ch === '/' && next === '/') {
|
|
51
|
+
while (i < n && source[i] !== '\n')
|
|
52
|
+
i++;
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if (ch === '/' && next === '*') {
|
|
56
|
+
i += 2;
|
|
57
|
+
while (i < n && !(source[i] === '*' && source[i + 1] === '/')) {
|
|
58
|
+
if (source[i] === '\n')
|
|
59
|
+
push('\n', false);
|
|
60
|
+
i++;
|
|
61
|
+
}
|
|
62
|
+
i += 2;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
// Strings + template literals — kept in `noComments`, blanked in `code`.
|
|
66
|
+
if (ch === '"' || ch === "'" || ch === '`') {
|
|
67
|
+
const quote = ch;
|
|
68
|
+
push(quote, false);
|
|
69
|
+
i++;
|
|
70
|
+
while (i < n && source[i] !== quote) {
|
|
71
|
+
if (source[i] === '\\') {
|
|
72
|
+
push(source[i], true);
|
|
73
|
+
i++;
|
|
74
|
+
if (i < n) {
|
|
75
|
+
push(source[i], true);
|
|
76
|
+
i++;
|
|
77
|
+
}
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
push(source[i] === '\n' ? '\n' : source[i], source[i] !== '\n');
|
|
81
|
+
i++;
|
|
82
|
+
}
|
|
83
|
+
if (i < n) {
|
|
84
|
+
push(quote, false);
|
|
85
|
+
i++;
|
|
86
|
+
}
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
push(ch, false);
|
|
90
|
+
i++;
|
|
91
|
+
}
|
|
92
|
+
return { code: code.join(''), noComments: noComments.join('') };
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Coordinates the runtime injects into `tokenData` on every render. They are NOT PostParams: they
|
|
96
|
+
* arrive automatically, and `--schema tokenId:…` is advice that must never be followed (a reserved
|
|
97
|
+
* key can't be declared). Excluded from {@link paramKeys} so the "declare EACH or it's dropped"
|
|
98
|
+
* warning only ever names keys a creator can actually declare.
|
|
99
|
+
*/
|
|
100
|
+
const RESERVED_TOKEN_DATA_KEYS = new Set(['seed', 'tokenId', 'chainId', 'contractAddress']);
|
|
23
101
|
/** PostParam keys the script READS from tokenData — the palette-style customization inputs. A deploy
|
|
24
102
|
* that omits these from `--schema` silently drops them (the render sees `undefined` → its default),
|
|
25
103
|
* which is exactly how a real session "forgot" the palette it had itself identified. Heuristic (the
|
|
@@ -28,7 +106,7 @@ const SINGLE_CALL_DOC_CEILING = 1_500_000;
|
|
|
28
106
|
* PostParam, so it's excluded. Advisory — over- or under-detection is a hint, never a hard gate. */
|
|
29
107
|
function paramKeys(source) {
|
|
30
108
|
const keys = new Set();
|
|
31
|
-
const add = (k) => { if (k && k
|
|
109
|
+
const add = (k) => { if (k && !RESERVED_TOKEN_DATA_KEYS.has(k))
|
|
32
110
|
keys.add(k); };
|
|
33
111
|
// Identifiers aliased to the token-data object — either `abx.tokenData` (via abx.js) or the raw
|
|
34
112
|
// injected global `window.abxTokenData` (e.g. `var td = (window.abx && abx.tokenData) || {}`).
|
|
@@ -46,6 +124,13 @@ function paramKeys(source) {
|
|
|
46
124
|
let d;
|
|
47
125
|
while ((d = dotRe.exec(source)) !== null)
|
|
48
126
|
add(d[1]);
|
|
127
|
+
// …and bracket reads through the same alias. A DOTTED key (`collapse.index`) is only readable
|
|
128
|
+
// as `d['collapse.index']`, and ABX's own output-naming convention is dotted
|
|
129
|
+
// (`effect.render.image`) — so alias+bracket is the documented idiom, not an edge case. Missing
|
|
130
|
+
// it produced a false "declare EACH or it's dropped at render" warning on a correct program.
|
|
131
|
+
const brkRe = new RegExp(`\\b${a.replace(/[$]/g, '\\$')}\\s*\\??\\s*\\[\\s*['"]([^'"]+)['"]\\s*\\]`, 'g');
|
|
132
|
+
while ((d = brkRe.exec(source)) !== null)
|
|
133
|
+
add(d[1]);
|
|
49
134
|
}
|
|
50
135
|
// Direct `abx.tokenData.key` and `abx.tokenData['key']`.
|
|
51
136
|
const directRe = /abx\s*\??\s*\.\s*tokenData\s*\??\s*(?:\.\s*([A-Za-z_$][\w$]*)|\[\s*['"]([^'"]+)['"]\s*\])/g;
|
|
@@ -79,32 +164,41 @@ function traitKeys(source) {
|
|
|
79
164
|
}
|
|
80
165
|
export function analyzeScript(source, declaredDeps = []) {
|
|
81
166
|
const bytes = new TextEncoder().encode(source).length;
|
|
82
|
-
|
|
83
|
-
|
|
167
|
+
// `code` for flags that must reflect real code, `noComments` for literal-content extraction.
|
|
168
|
+
// Never run a detector against the raw source — a comment mentioning p5 is not a p5 dependency.
|
|
169
|
+
const { code, noComments } = sourceViews(source);
|
|
170
|
+
const keys = traitKeys(noComments);
|
|
171
|
+
const usesMathRandom = /Math\s*\.\s*random\s*\(/.test(code);
|
|
84
172
|
// p5's bare random(...) — a `random(` NOT preceded by `.` or a word char (so not Math.random / obj.random)
|
|
85
|
-
const usesBareRandom = /(^|[^.\w])random\s*\(/.test(
|
|
86
|
-
const seeded = /\brandomSeed\s*\(/.test(
|
|
87
|
-
const usesNoise = /\bnoise\s*\(/.test(
|
|
88
|
-
const looksP5 = /\bcreateCanvas\s*\(|function\s+setup\s*\(|function\s+draw\s*\(|\bp5\b/.test(
|
|
173
|
+
const usesBareRandom = /(^|[^.\w])random\s*\(/.test(code);
|
|
174
|
+
const seeded = /\brandomSeed\s*\(/.test(code);
|
|
175
|
+
const usesNoise = /\bnoise\s*\(/.test(code);
|
|
176
|
+
const looksP5 = /\bcreateCanvas\s*\(|function\s+setup\s*\(|function\s+draw\s*\(|\bp5\b/.test(code);
|
|
177
|
+
// A generator the author wrote themselves — the dominant shape for dependency-free work, and
|
|
178
|
+
// invisible to `seeded` (which only knows p5's `randomSeed(`). Matches the arithmetic fingerprints
|
|
179
|
+
// of the usual suspects: LCG multipliers/moduli, xorshift, and the uint32 coercions they need.
|
|
180
|
+
// Deliberately loose: a false positive costs only the more cautious verdict, a false negative
|
|
181
|
+
// promises on-chain reproducibility that a Solidity port may not actually deliver.
|
|
182
|
+
const handRolledPrng = /\bMath\s*\.\s*imul\s*\(|>>>\s*0\b|\^=\s*[A-Za-z_$][\w$]*\s*<<|\b(?:1664525|1013904223|1103515245|2147483647|4294967296|69069|22695477)\b/.test(code);
|
|
89
183
|
const depHints = [];
|
|
90
184
|
if (looksP5)
|
|
91
185
|
depHints.push('p5');
|
|
92
|
-
if (/\bTHREE\b/.test(
|
|
186
|
+
if (/\bTHREE\b/.test(code))
|
|
93
187
|
depHints.push('three');
|
|
94
|
-
if (/\bTone\b/.test(
|
|
188
|
+
if (/\bTone\b/.test(code))
|
|
95
189
|
depHints.push('tone');
|
|
96
190
|
// The abx.js runtime data contract — does the script read state + report traits the ONE way the
|
|
97
191
|
// toolkit injects/captures them? A near-miss global deploys fine but is silently broken.
|
|
98
192
|
// `\??\s*\.` tolerates optional chaining (`abx?.tokenData`) — a common, correct way to read it.
|
|
99
|
-
const readsTokenData = /abx\s*\??\s*\.\s*tokenData\b/.test(
|
|
100
|
-
const reportsTraits = /abx\s*\??\s*\.\s*traits\s*\(/.test(
|
|
193
|
+
const readsTokenData = /abx\s*\??\s*\.\s*tokenData\b/.test(code) || /window\s*\??\s*\.\s*abxTokenData\b/.test(code);
|
|
194
|
+
const reportsTraits = /abx\s*\??\s*\.\s*traits\s*\(/.test(code);
|
|
101
195
|
let wrongGlobal = null;
|
|
102
196
|
if (!readsTokenData) {
|
|
103
|
-
if (/window\s*\.\s*tokenTraits\b/.test(
|
|
197
|
+
if (/window\s*\.\s*tokenTraits\b/.test(code))
|
|
104
198
|
wrongGlobal = 'window.tokenTraits — traits are reported by CALLING abx.traits({…}), never by writing a global';
|
|
105
|
-
else if (/window\s*\.\s*tokenData\b/.test(
|
|
199
|
+
else if (/window\s*\.\s*tokenData\b/.test(code))
|
|
106
200
|
wrongGlobal = 'window.tokenData — abx injects window.abxTokenData (read it via abx.tokenData), not window.tokenData';
|
|
107
|
-
else if (/\btokenData\b/.test(
|
|
201
|
+
else if (/\btokenData\b/.test(code))
|
|
108
202
|
wrongGlobal = 'a bare `tokenData` — read abx.tokenData (via abx.js) or the raw window.abxTokenData global';
|
|
109
203
|
}
|
|
110
204
|
// Trait-reproducibility rubric (see docs/research/onchain-traits-feasibility.md).
|
|
@@ -130,6 +224,18 @@ export function analyzeScript(source, declaredDeps = []) {
|
|
|
130
224
|
verdict = 'unknown';
|
|
131
225
|
reason = 'traits present and random() is used, but no randomSeed() was found — check the art is deterministic before attempting on-chain traits.';
|
|
132
226
|
}
|
|
227
|
+
else if (handRolledPrng) {
|
|
228
|
+
// `seeded` only recognizes p5's `randomSeed(`, so a hand-written generator used to land in the
|
|
229
|
+
// branch below and be told "no PRNG" — with the STRONGER verdict attached. That is backwards, and
|
|
230
|
+
// it is the common case, not an edge one: the skill's own canonical vanilla example hand-rolls an
|
|
231
|
+
// LCG. Porting a bespoke generator to Solidity means reproducing its arithmetic AND its exact call
|
|
232
|
+
// order, which is the `careful` bar, not the field-renderer-and-done bar.
|
|
233
|
+
verdict = 'careful';
|
|
234
|
+
reason =
|
|
235
|
+
'traits derive from a HAND-WRITTEN PRNG seeded off the token seed — deterministic, so reproducible on-chain, ' +
|
|
236
|
+
'but only if you port that exact generator (same arithmetic, same call order) into Solidity. Verify with identical ' +
|
|
237
|
+
'seeds on both sides before committing to on-chain traits; the off-chain resolver lane needs no port.';
|
|
238
|
+
}
|
|
133
239
|
else {
|
|
134
240
|
verdict = 'exact-likely';
|
|
135
241
|
reason = 'traits look derived from the seed/params directly (no PRNG) — reproducible on-chain via an attributes field-renderer.';
|
|
@@ -148,7 +254,7 @@ export function analyzeScript(source, declaredDeps = []) {
|
|
|
148
254
|
bytes,
|
|
149
255
|
estChunks: Math.max(1, Math.ceil(bytes / 22_000)),
|
|
150
256
|
traits: { present: keys.length > 0, keys },
|
|
151
|
-
paramHints: paramKeys(
|
|
257
|
+
paramHints: paramKeys(noComments),
|
|
152
258
|
prng: { seeded, usesBareRandom, usesMathRandom, usesNoise },
|
|
153
259
|
depHints,
|
|
154
260
|
looksP5,
|
package/dist/inspect.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inspect.js","sourceRoot":"","sources":["../src/inspect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;oGACoG;AACpG,MAAM,mBAAmB,GAA2B;IAClD,UAAU,EAAE,OAAO,EAAE,iEAAiE;CACvF,CAAC;AAEF,mGAAmG;AACnG,MAAM,iBAAiB,GAAG,MAAM,CAAC;AAEjC;;kGAEkG;AAClG,MAAM,uBAAuB,GAAG,SAAS,CAAC;AAsB1C;;;;;qGAKqG;AACrG,SAAS,SAAS,CAAC,MAAc;IAC/B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,GAAG,GAAG,CAAC,CAAqB,EAAE,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"inspect.js","sourceRoot":"","sources":["../src/inspect.ts"],"names":[],"mappings":"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"}
|