@artblocks/abx-sdk 0.1.0-alpha.30 → 0.1.0-alpha.31
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 +68 -0
- package/dist/chunks.d.ts +55 -0
- package/dist/chunks.d.ts.map +1 -1
- package/dist/chunks.js +42 -0
- package/dist/chunks.js.map +1 -1
- package/dist/deployments.d.ts +15 -0
- package/dist/deployments.d.ts.map +1 -1
- package/dist/deployments.js +20 -0
- package/dist/deployments.js.map +1 -1
- package/dist/errors.d.ts +15 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +22 -0
- package/dist/errors.js.map +1 -1
- package/dist/node.d.ts +59 -0
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +68 -0
- package/dist/node.js.map +1 -1
- package/dist/reconstruct.d.ts +27 -1
- package/dist/reconstruct.d.ts.map +1 -1
- package/dist/reconstruct.js +37 -3
- package/dist/reconstruct.js.map +1 -1
- package/dist/resume.d.ts +49 -5
- package/dist/resume.d.ts.map +1 -1
- package/dist/resume.js +54 -3
- package/dist/resume.js.map +1 -1
- package/dist/script-chunks.d.ts +81 -0
- package/dist/script-chunks.d.ts.map +1 -1
- package/dist/script-chunks.js +95 -0
- package/dist/script-chunks.js.map +1 -1
- package/dist/token.d.ts +10 -0
- package/dist/token.d.ts.map +1 -1
- package/dist/token.js +31 -0
- package/dist/token.js.map +1 -1
- package/package.json +1 -1
package/dist/script-chunks.js
CHANGED
|
@@ -7,7 +7,18 @@
|
|
|
7
7
|
* never parses the reassembled program. Splitting AT an existing newline (and dropping it, because
|
|
8
8
|
* the join puts it back) makes `chunks.join('\n') === source`. A 22 kB+ span with no newline is
|
|
9
9
|
* refused: there is no honest split that matches the on-chain join.
|
|
10
|
+
*
|
|
11
|
+
* This module also carries the write-side counterpart to that split (`prepareSetScriptChunk` /
|
|
12
|
+
* `prepareRemoveLastScriptChunk`, wrapping `OnChainScript.sol`'s `setScriptChunk`/
|
|
13
|
+
* `removeLastScriptChunk` — contracts/src/extensions/onchain-script/OnChainScript.sol) and the
|
|
14
|
+
* SAFE-REPLACEMENT planning + verification pair (`planScriptReplace` / `verifyScriptReplace`) that
|
|
15
|
+
* `abx replace-script` is built on (packages/cli/src/ownerops.ts). Both take a small reader
|
|
16
|
+
* interface rather than a viem client — the same shape `resume.ts` uses — so the diff and the
|
|
17
|
+
* post-write verification are testable with a fake chain, no RPC, no signer.
|
|
10
18
|
*/
|
|
19
|
+
import { encodeFunctionData, hexToBytes } from 'viem';
|
|
20
|
+
import { seriesCodeAbi } from './abi/index.js';
|
|
21
|
+
const ZERO_VALUE = '0x0';
|
|
11
22
|
/** SSTORE2 data-contract code limit is 24576 bytes (EIP-170) minus STOP; stay conservative. */
|
|
12
23
|
export const DEFAULT_SCRIPT_CHUNK_SIZE = 22_000;
|
|
13
24
|
/** The byte the on-chain generator inserts between script chunks. Must stay in lockstep with
|
|
@@ -60,4 +71,88 @@ export function joinScriptChunks(chunks) {
|
|
|
60
71
|
const dec = new TextDecoder();
|
|
61
72
|
return chunks.map((c) => dec.decode(c)).join(SCRIPT_CHUNK_JOIN);
|
|
62
73
|
}
|
|
74
|
+
// ── writes: OnChainScript.sol's setScriptChunk / removeLastScriptChunk ────────
|
|
75
|
+
// No `prepare*` wrapper existed for either before this — every caller (deploy-code's setup
|
|
76
|
+
// multicall, its --resume leg) hand-encoded `encodeFunctionData` inline. These mirror
|
|
77
|
+
// `prepareSetDependency`/`prepareRemoveLastDependency` (ops.ts) exactly: same `PreparedTx` shape,
|
|
78
|
+
// same "one index-addressed setter + one pop-the-tail remover" split.
|
|
79
|
+
/** Owner writes/replaces the on-chain program chunk at `index` (`index === count` appends) —
|
|
80
|
+
* `OnChainScript.setScriptChunk`. Content should come from {@link splitScriptChunks} so the
|
|
81
|
+
* generator's newline-join reassembles the exact source. Signer must be the owner. */
|
|
82
|
+
export function prepareSetScriptChunk(args) {
|
|
83
|
+
const index = BigInt(args.index);
|
|
84
|
+
const bytes = (args.chunk.length - 2) / 2;
|
|
85
|
+
// EVM code deposit is 200 gas/byte — the same physics-backed floor the code-setup multicall
|
|
86
|
+
// computes for its script-chunk legs (ops.ts). Restated per-chunk here so a caller that assembles
|
|
87
|
+
// its own multicall (`replace-script`) can sum an honest `gasFloor` instead of trusting
|
|
88
|
+
// `eth_estimateGas` against a target too fresh for the estimator to see (see PreparedTx.gasFloor's
|
|
89
|
+
// own doc for why a wrong estimate must be DETECTED, not silently replaced).
|
|
90
|
+
const gasFloor = bytes > 0 ? `0x${(bytes * 200).toString(16)}` : undefined;
|
|
91
|
+
return {
|
|
92
|
+
op: 'set-script-chunk',
|
|
93
|
+
to: args.contract,
|
|
94
|
+
data: encodeFunctionData({ abi: seriesCodeAbi, functionName: 'setScriptChunk', args: [index, args.chunk] }),
|
|
95
|
+
value: ZERO_VALUE,
|
|
96
|
+
chainId: args.chainId,
|
|
97
|
+
summary: `Set script chunk [${index}] (${bytes} byte${bytes === 1 ? '' : 's'})`,
|
|
98
|
+
fields: { contract: args.contract, index: index.toString(), bytes: String(bytes) },
|
|
99
|
+
...(gasFloor === undefined ? {} : { gasFloor }),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/** Remove the LAST on-chain program chunk (the list stays dense; order is load-bearing) —
|
|
103
|
+
* `OnChainScript.removeLastScriptChunk`. There is no "remove N": shrinking by more than one chunk
|
|
104
|
+
* is this call, repeated. Signer must be the owner. */
|
|
105
|
+
export function prepareRemoveLastScriptChunk(args) {
|
|
106
|
+
return {
|
|
107
|
+
op: 'remove-last-script-chunk',
|
|
108
|
+
to: args.contract,
|
|
109
|
+
data: encodeFunctionData({ abi: seriesCodeAbi, functionName: 'removeLastScriptChunk', args: [] }),
|
|
110
|
+
value: ZERO_VALUE,
|
|
111
|
+
chainId: args.chainId,
|
|
112
|
+
summary: 'Remove the last script chunk (the list stays dense)',
|
|
113
|
+
fields: { contract: args.contract },
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Diff a replacement program's chunks against what a contract holds NOW, so `replace-script` sends
|
|
118
|
+
* only what actually changed. Mirrors `resume.ts`'s script-chunk leg (`planCoreLegs`) exactly —
|
|
119
|
+
* content, not count, decides "present" — the difference being that a resume leg is checked
|
|
120
|
+
* present/absent as a GROUP (the setup multicall is atomic, so partial-content-mismatch never
|
|
121
|
+
* legitimately happens), while a replacement is expected to change SOME indices and not others, so
|
|
122
|
+
* each index is diffed and reported independently.
|
|
123
|
+
*/
|
|
124
|
+
export async function planScriptReplace(read, next) {
|
|
125
|
+
const currentCount = await read.scriptChunkCount();
|
|
126
|
+
const toWrite = [];
|
|
127
|
+
for (let i = 0; i < next.length; i++) {
|
|
128
|
+
const stored = i < currentCount ? await read.scriptChunk(i) : null;
|
|
129
|
+
if (stored !== null && stored.toLowerCase() === next[i].toLowerCase())
|
|
130
|
+
continue;
|
|
131
|
+
toWrite.push({ index: i, hex: next[i] });
|
|
132
|
+
}
|
|
133
|
+
const toRemove = Math.max(0, currentCount - next.length);
|
|
134
|
+
return { toWrite, toRemove, currentCount, targetCount: next.length, noop: toWrite.length === 0 && toRemove === 0 };
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Read the completed script back from chain and confirm it reassembles EXACTLY to `expectedSource`
|
|
138
|
+
* — the safety property that justifies `replace-script` existing at all. A transaction not
|
|
139
|
+
* reverting is proof the EVM accepted each call; it is NOT proof the final program is what was
|
|
140
|
+
* intended (a stale RPC view, a concurrent write racing the same contract, or a bug in the ordering
|
|
141
|
+
* of writes-vs-removes could all leave a script that "sent fine" and reassembles to garbage). This
|
|
142
|
+
* is the check that turns "the multicall didn't revert" into "the program is provably correct" —
|
|
143
|
+
* run it BEFORE reporting success, never after.
|
|
144
|
+
*/
|
|
145
|
+
export async function verifyScriptReplace(read, expectedSource) {
|
|
146
|
+
const chunkCount = await read.scriptChunkCount();
|
|
147
|
+
const chunks = [];
|
|
148
|
+
for (let i = 0; i < chunkCount; i++) {
|
|
149
|
+
const hex = await read.scriptChunk(i);
|
|
150
|
+
// `scriptChunkCount()` and `scriptChunk(i)` are two separate reads against (hopefully) the same
|
|
151
|
+
// block; a `null` here means they disagree, which is itself the failure this function exists to
|
|
152
|
+
// catch — report it as a verification miss rather than silently reassembling a gap.
|
|
153
|
+
chunks.push(hex === null ? new Uint8Array(0) : hexToBytes(hex));
|
|
154
|
+
}
|
|
155
|
+
const reassembled = joinScriptChunks(chunks);
|
|
156
|
+
return { ok: reassembled === expectedSource, reassembled, chunkCount };
|
|
157
|
+
}
|
|
63
158
|
//# sourceMappingURL=script-chunks.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"script-chunks.js","sourceRoot":"","sources":["../src/script-chunks.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"script-chunks.js","sourceRoot":"","sources":["../src/script-chunks.ts"],"names":[],"mappings":"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"}
|
package/dist/token.d.ts
CHANGED
|
@@ -15,6 +15,16 @@ export declare function verifyAgainstHash(bytes: Uint8Array | string, field: Met
|
|
|
15
15
|
* Decode a `reader` field value → `(reader, pointer)` addresses. Content is then
|
|
16
16
|
* obtained on-chain by `IAbxOnChainReader(reader).read(pointer)` (an `eth_call`). The
|
|
17
17
|
* reader encapsulates storage + on-chain decoding; this just unpacks the two addresses.
|
|
18
|
+
*
|
|
19
|
+
* Requires the CANONICAL `abi.encode(address reader, address pointer)` shape: exactly two
|
|
20
|
+
* 32-byte words, each zero-padded in its leading 12 bytes. `decodeAbiParameters` alone is
|
|
21
|
+
* too permissive to use as the only gate here — it happily reads an `address` out of a word
|
|
22
|
+
* with non-zero padding, and it ignores any bytes beyond the words a type list needs, so a
|
|
23
|
+
* truncated-then-repadded, trailing-garbage, or double-encoded (e.g. `abi.encode(bytes)`
|
|
24
|
+
* wrapping a reader pair) value can decode into a plausible but wrong address pair instead
|
|
25
|
+
* of failing. Because the decoded `reader` address is then `eth_call`'d directly (see
|
|
26
|
+
* `resolveFieldBytes` in token-api), a silent mis-decode here is a wrong-contract call, not
|
|
27
|
+
* a cosmetic bug — so this checks shape and padding itself before trusting the ABI decode.
|
|
18
28
|
*/
|
|
19
29
|
export declare function decodeReader(value: Hex): {
|
|
20
30
|
reader: Address;
|
package/dist/token.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,OAAO,EACZ,KAAK,GAAG,EACT,MAAM,MAAM,CAAC;AAEd,OAAO,KAAK,EAAC,aAAa,EAAE,YAAY,EAAE,UAAU,EAAC,MAAM,YAAY,CAAC;AAExE,qDAAqD;AACrD,wBAAgB,SAAS,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,IAAI,CAG1F;AAED,mGAAmG;AACnG,wBAAgB,OAAO,CAAC,MAAM,EAAE,aAAa,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAExF;AAED,wBAAgB,SAAS,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAEzD;AAID,oDAAoD;AACpD,wBAAgB,UAAU,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAMvD;AAED,mDAAmD;AACnD,wBAAgB,WAAW,CAAC,KAAK,EAAE,aAAa,GAAG,UAAU,CAE5D;AAED,8GAA8G;AAC9G,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,GAAG,IAAI,CAKlG;AAED
|
|
1
|
+
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,OAAO,EACZ,KAAK,GAAG,EACT,MAAM,MAAM,CAAC;AAEd,OAAO,KAAK,EAAC,aAAa,EAAE,YAAY,EAAE,UAAU,EAAC,MAAM,YAAY,CAAC;AAExE,qDAAqD;AACrD,wBAAgB,SAAS,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,IAAI,CAG1F;AAED,mGAAmG;AACnG,wBAAgB,OAAO,CAAC,MAAM,EAAE,aAAa,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAExF;AAED,wBAAgB,SAAS,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAEzD;AAID,oDAAoD;AACpD,wBAAgB,UAAU,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAMvD;AAED,mDAAmD;AACnD,wBAAgB,WAAW,CAAC,KAAK,EAAE,aAAa,GAAG,UAAU,CAE5D;AAED,8GAA8G;AAC9G,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,GAAG,IAAI,CAKlG;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,GAAG,GAAG;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAC,CA4B5E;AAED,2FAA2F;AAC3F,wBAAgB,YAAY,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,GAAG,CAInE;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,OAAO,GAAG,GAAG,CAE/D;AAED,+FAA+F;AAC/F,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CAGvD"}
|
package/dist/token.js
CHANGED
|
@@ -39,8 +39,39 @@ export function verifyAgainstHash(bytes, field) {
|
|
|
39
39
|
* Decode a `reader` field value → `(reader, pointer)` addresses. Content is then
|
|
40
40
|
* obtained on-chain by `IAbxOnChainReader(reader).read(pointer)` (an `eth_call`). The
|
|
41
41
|
* reader encapsulates storage + on-chain decoding; this just unpacks the two addresses.
|
|
42
|
+
*
|
|
43
|
+
* Requires the CANONICAL `abi.encode(address reader, address pointer)` shape: exactly two
|
|
44
|
+
* 32-byte words, each zero-padded in its leading 12 bytes. `decodeAbiParameters` alone is
|
|
45
|
+
* too permissive to use as the only gate here — it happily reads an `address` out of a word
|
|
46
|
+
* with non-zero padding, and it ignores any bytes beyond the words a type list needs, so a
|
|
47
|
+
* truncated-then-repadded, trailing-garbage, or double-encoded (e.g. `abi.encode(bytes)`
|
|
48
|
+
* wrapping a reader pair) value can decode into a plausible but wrong address pair instead
|
|
49
|
+
* of failing. Because the decoded `reader` address is then `eth_call`'d directly (see
|
|
50
|
+
* `resolveFieldBytes` in token-api), a silent mis-decode here is a wrong-contract call, not
|
|
51
|
+
* a cosmetic bug — so this checks shape and padding itself before trusting the ABI decode.
|
|
42
52
|
*/
|
|
43
53
|
export function decodeReader(value) {
|
|
54
|
+
const hex = value.slice(2);
|
|
55
|
+
const WORD_HEX_LEN = 64; // one 32-byte ABI word, as hex chars
|
|
56
|
+
const EXPECTED_HEX_LEN = WORD_HEX_LEN * 2; // exactly two words: (address reader, address pointer)
|
|
57
|
+
if (hex.length !== EXPECTED_HEX_LEN) {
|
|
58
|
+
throw new Error(`decodeReader: expected exactly two 32-byte ABI words (abi.encode(address reader, address ` +
|
|
59
|
+
`pointer) — ${EXPECTED_HEX_LEN / 2} bytes), received ${hex.length / 2} bytes (${value}). This ` +
|
|
60
|
+
`looks like a truncated, trailing-byte, or double-encoded value; only output from ` +
|
|
61
|
+
`encodeReader() is accepted.`);
|
|
62
|
+
}
|
|
63
|
+
const ZERO_PAD = '0'.repeat(24); // the 12 zero bytes a canonical address word pads with
|
|
64
|
+
const words = [
|
|
65
|
+
['reader', hex.slice(0, WORD_HEX_LEN)],
|
|
66
|
+
['pointer', hex.slice(WORD_HEX_LEN, WORD_HEX_LEN * 2)],
|
|
67
|
+
];
|
|
68
|
+
for (const [name, word] of words) {
|
|
69
|
+
if (!word.startsWith(ZERO_PAD)) {
|
|
70
|
+
throw new Error(`decodeReader: ${name} word is not canonically zero-padded — expected its leading 12 bytes ` +
|
|
71
|
+
`to be zero, received 0x${word}. A non-zero-padded address word is not produced by ` +
|
|
72
|
+
`encodeReader() and is rejected as a non-canonical encoding.`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
44
75
|
const [reader, pointer] = decodeAbiParameters([{ type: 'address' }, { type: 'address' }], value);
|
|
45
76
|
return { reader, pointer };
|
|
46
77
|
}
|
package/dist/token.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token.js","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,MAAM,EACN,WAAW,EACX,UAAU,EACV,mBAAmB,GAGpB,MAAM,MAAM,CAAC;AACd,OAAO,EAAC,uBAAuB,IAAI,CAAC,EAAC,MAAM,YAAY,CAAC;AAGxD,qDAAqD;AACrD,MAAM,UAAU,SAAS,CAAC,KAAmB,EAAE,OAAwB;IACrE,MAAM,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAC3B,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,EAAE,CAAC,IAAI,IAAI,CAAC;AAC5D,CAAC;AAED,mGAAmG;AACnG,MAAM,UAAU,OAAO,CAAC,MAAuB,EAAE,SAAiB;IAChE,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,IAAI,IAAI,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,cAAsB;IAC9C,OAAO,cAAc,KAAK,CAAC,CAAC,MAAM,IAAI,cAAc,KAAK,CAAC,CAAC,MAAM,CAAC;AACpE,CAAC;AAED,gFAAgF;AAEhF,oDAAoD;AACpD,MAAM,UAAU,UAAU,CAAC,KAAoB;IAC7C,IAAI,CAAC;QACH,OAAO,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,WAAW,CAAC,KAAoB;IAC9C,OAAO,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AACjC,CAAC;AAED,8GAA8G;AAC9G,MAAM,UAAU,iBAAiB,CAAC,KAA0B,EAAE,KAAoB;IAChF,MAAM,KAAK,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAClF,IAAI,KAAK,CAAC,cAAc,KAAK,CAAC,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC;IAClF,IAAI,KAAK,CAAC,cAAc,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC;IAC5E,OAAO,IAAI,CAAC;AACd,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"token.js","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED