@artblocks/abx-sdk 0.1.0-alpha.0 → 0.1.0-alpha.10

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.
Files changed (103) hide show
  1. package/README.md +131 -0
  2. package/dist/abi/generated.d.ts +585 -12
  3. package/dist/abi/generated.d.ts.map +1 -1
  4. package/dist/abi/generated.js +16 -16
  5. package/dist/abi/generated.js.map +1 -1
  6. package/dist/abi/index.d.ts +209 -12
  7. package/dist/abi/index.d.ts.map +1 -1
  8. package/dist/anchors.d.ts +150 -0
  9. package/dist/anchors.d.ts.map +1 -0
  10. package/dist/anchors.js +290 -0
  11. package/dist/anchors.js.map +1 -0
  12. package/dist/chains.d.ts +34 -9
  13. package/dist/chains.d.ts.map +1 -1
  14. package/dist/chains.js +45 -18
  15. package/dist/chains.js.map +1 -1
  16. package/dist/chunks.d.ts +53 -23
  17. package/dist/chunks.d.ts.map +1 -1
  18. package/dist/chunks.js +68 -6
  19. package/dist/chunks.js.map +1 -1
  20. package/dist/clients.d.ts +23 -11
  21. package/dist/clients.d.ts.map +1 -1
  22. package/dist/clients.js +17 -18
  23. package/dist/clients.js.map +1 -1
  24. package/dist/creator-token.d.ts +65 -0
  25. package/dist/creator-token.d.ts.map +1 -0
  26. package/dist/creator-token.js +93 -0
  27. package/dist/creator-token.js.map +1 -0
  28. package/dist/deploy.d.ts +24 -10
  29. package/dist/deploy.d.ts.map +1 -1
  30. package/dist/deploy.js +62 -87
  31. package/dist/deploy.js.map +1 -1
  32. package/dist/deployments.d.ts.map +1 -1
  33. package/dist/deployments.js +38 -22
  34. package/dist/deployments.js.map +1 -1
  35. package/dist/deps.d.ts +38 -0
  36. package/dist/deps.d.ts.map +1 -1
  37. package/dist/deps.js +70 -1
  38. package/dist/deps.js.map +1 -1
  39. package/dist/env.d.ts +11 -0
  40. package/dist/env.d.ts.map +1 -1
  41. package/dist/env.js +42 -2
  42. package/dist/env.js.map +1 -1
  43. package/dist/errors.d.ts +63 -0
  44. package/dist/errors.d.ts.map +1 -0
  45. package/dist/errors.js +85 -0
  46. package/dist/errors.js.map +1 -0
  47. package/dist/execute.d.ts +115 -0
  48. package/dist/execute.d.ts.map +1 -0
  49. package/dist/execute.js +142 -0
  50. package/dist/execute.js.map +1 -0
  51. package/dist/index.d.ts +13 -2
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js +13 -2
  54. package/dist/index.js.map +1 -1
  55. package/dist/inspect.d.ts +48 -0
  56. package/dist/inspect.d.ts.map +1 -0
  57. package/dist/inspect.js +290 -0
  58. package/dist/inspect.js.map +1 -0
  59. package/dist/migrate.d.ts +41 -0
  60. package/dist/migrate.d.ts.map +1 -0
  61. package/dist/migrate.js +140 -0
  62. package/dist/migrate.js.map +1 -0
  63. package/dist/node.d.ts +13 -0
  64. package/dist/node.d.ts.map +1 -0
  65. package/dist/node.js +13 -0
  66. package/dist/node.js.map +1 -0
  67. package/dist/onchain-uri.d.ts +96 -0
  68. package/dist/onchain-uri.d.ts.map +1 -0
  69. package/dist/onchain-uri.js +231 -0
  70. package/dist/onchain-uri.js.map +1 -0
  71. package/dist/ops.d.ts +113 -5
  72. package/dist/ops.d.ts.map +1 -1
  73. package/dist/ops.js +172 -13
  74. package/dist/ops.js.map +1 -1
  75. package/dist/reconstruct.d.ts +20 -1
  76. package/dist/reconstruct.d.ts.map +1 -1
  77. package/dist/reconstruct.js +124 -50
  78. package/dist/reconstruct.js.map +1 -1
  79. package/dist/resume.d.ts +96 -0
  80. package/dist/resume.d.ts.map +1 -0
  81. package/dist/resume.js +95 -0
  82. package/dist/resume.js.map +1 -0
  83. package/dist/service.d.ts +369 -0
  84. package/dist/service.d.ts.map +1 -0
  85. package/dist/service.js +376 -0
  86. package/dist/service.js.map +1 -0
  87. package/dist/staging.d.ts +95 -0
  88. package/dist/staging.d.ts.map +1 -0
  89. package/dist/staging.js +57 -0
  90. package/dist/staging.js.map +1 -0
  91. package/dist/tokendata.d.ts +62 -2
  92. package/dist/tokendata.d.ts.map +1 -1
  93. package/dist/tokendata.js +60 -16
  94. package/dist/tokendata.js.map +1 -1
  95. package/dist/tokens.d.ts +55 -0
  96. package/dist/tokens.d.ts.map +1 -0
  97. package/dist/tokens.js +152 -0
  98. package/dist/tokens.js.map +1 -0
  99. package/dist/util.d.ts +59 -0
  100. package/dist/util.d.ts.map +1 -0
  101. package/dist/util.js +89 -0
  102. package/dist/util.js.map +1 -0
  103. package/package.json +10 -2
@@ -0,0 +1,290 @@
1
+ import { oneOfOneImageAbi, oneOfOneImageFactoryAbi, seriesImageAbi, seriesImageFactoryAbi, abxMetadataRendererAbi } from './abi/index.js';
2
+ import { resolveFactory, resolveSeriesFactory, resolveRenderer, resolveSeriesCodeFactory, resolveSeedSource } from './deployments.js';
3
+ import { predictRenderer, predictSeedSource } from './create2.js';
4
+ import { deployFactory, deploySeriesFactory, deployRenderer, deploySeriesCodeFactory, deploySeedSource } from './deploy.js';
5
+ import { discoverDeployBlock } from './reconstruct.js';
6
+ import { AnchorUnavailableError } from './errors.js';
7
+ // ── the canonical 1/1 clone factory ───────────────────────────────────────────
8
+ /** Is the deployed factory this build's version? Reads its implementation and probes the
9
+ * NEWEST capability the current implementation exposes — `totalSupply()` (the live-count
10
+ * read) — so an older factory whose impl predates it is detected and a fresh, source-current
11
+ * (and thus Etherscan-verifiable) one deployed. A stale impl reverts the probe. (Bump this to
12
+ * the newest capability with each impl change.) */
13
+ export async function isCurrentFactory(publicClient, factory) {
14
+ try {
15
+ const impl = (await publicClient.readContract({
16
+ address: factory,
17
+ abi: oneOfOneImageFactoryAbi,
18
+ functionName: 'implementation',
19
+ }));
20
+ // `totalSupply()` is a view → readContract; it reverts on an impl that predates it.
21
+ await publicClient.readContract({ address: impl, abi: oneOfOneImageAbi, functionName: 'totalSupply' });
22
+ return true;
23
+ }
24
+ catch {
25
+ return false;
26
+ }
27
+ }
28
+ /**
29
+ * Get (or deploy) the chain's canonical 1/1 clone factory — the trust anchor: a factory is THE
30
+ * address platforms allowlist by. Resolves the manifest (override → env → manifest); on a chain
31
+ * with no current entry, deploys a fresh one when `allowBootstrap` is set (else throws
32
+ * {@link AnchorUnavailableError} so the caller can refuse with guidance instead of silently
33
+ * fragmenting trust across duplicate "canonical" factories).
34
+ */
35
+ export async function ensureFactory(publicClient, send, opts) {
36
+ const notify = opts.onEvent ?? (() => { });
37
+ // Resolve the canonical factory from the shipped manifest (flag → env → manifest); on a chain
38
+ // with no entry, deploy a fresh trust anchor and tell the operator how to reuse it.
39
+ const known = resolveFactory(opts.chainId, opts.override);
40
+ if (known) {
41
+ // sanity: is there code there, and is it *this* version of the factory?
42
+ const code = await publicClient.getCode({ address: known });
43
+ if (code && code !== '0x') {
44
+ if (await isCurrentFactory(publicClient, known)) {
45
+ notify({ anchor: 'factory', kind: 'resolved', address: known });
46
+ return known;
47
+ }
48
+ if (!opts.allowBootstrap)
49
+ throw new AnchorUnavailableError('factory', 'stale-version', known);
50
+ notify({ anchor: 'factory', kind: 'stale', address: known, reason: 'stale-version' });
51
+ }
52
+ else {
53
+ if (!opts.allowBootstrap)
54
+ throw new AnchorUnavailableError('factory', 'no-code', known);
55
+ notify({ anchor: 'factory', kind: 'stale', address: known, reason: 'no-code' });
56
+ }
57
+ }
58
+ if (!known && !opts.allowBootstrap)
59
+ throw new AnchorUnavailableError('factory', 'not-configured');
60
+ notify({ anchor: 'factory', kind: 'deploying' });
61
+ const { factory, implementation, txHash } = await deployFactory(send, publicClient);
62
+ notify({ anchor: 'factory', kind: 'deployed', address: factory, implementation, txHash, inManifest: false });
63
+ return factory;
64
+ }
65
+ // ── the canonical Series trust anchor ─────────────────────────────────────────
66
+ /** Is the deployed Series factory this build's version? Probes the impl for `nextTokenId()`
67
+ * (the Series-specific issuance cursor), which a stale/incompatible impl won't expose. */
68
+ export async function isCurrentSeriesFactory(publicClient, factory) {
69
+ try {
70
+ const impl = (await publicClient.readContract({
71
+ address: factory,
72
+ abi: seriesImageFactoryAbi,
73
+ functionName: 'implementation',
74
+ }));
75
+ // Probe the NEWEST capability the current implementation exposes — ERC-165 support for the
76
+ // IAbxSequentialMint primitive (mint(address) → uint256, the fixed-price-minter target).
77
+ // A pre-minter-spine impl (mint returns void, id not advertised) returns false → a fresh,
78
+ // source-current factory is deployed. (Bump this to the newest capability with each impl change.)
79
+ return (await publicClient.readContract({
80
+ address: impl,
81
+ abi: seriesImageAbi,
82
+ functionName: 'supportsInterface',
83
+ args: ['0x6a627842'], // type(IAbxSequentialMint).interfaceId = bytes4(keccak256("mint(address)"))
84
+ }));
85
+ }
86
+ catch {
87
+ return false;
88
+ }
89
+ }
90
+ /** Get (or deploy) the chain's `SeriesImageFactory` — the multi-token trust anchor, the sibling
91
+ * of {@link ensureFactory}. Ownerless + immutable; one deployment serves every Series. */
92
+ export async function ensureSeriesFactory(publicClient, send, opts) {
93
+ const notify = opts.onEvent ?? (() => { });
94
+ const known = resolveSeriesFactory(opts.chainId, opts.override);
95
+ if (known) {
96
+ const code = await publicClient.getCode({ address: known });
97
+ if (code && code !== '0x' && (await isCurrentSeriesFactory(publicClient, known))) {
98
+ notify({ anchor: 'series-factory', kind: 'resolved', address: known });
99
+ return known;
100
+ }
101
+ if (!opts.allowBootstrap)
102
+ throw new AnchorUnavailableError('series-factory', 'stale-version', known);
103
+ notify({ anchor: 'series-factory', kind: 'stale', address: known, reason: 'stale-version' });
104
+ }
105
+ if (!known && !opts.allowBootstrap)
106
+ throw new AnchorUnavailableError('series-factory', 'not-configured');
107
+ notify({ anchor: 'series-factory', kind: 'deploying' });
108
+ const { factory, implementation, txHash } = await deploySeriesFactory(send, publicClient);
109
+ notify({ anchor: 'series-factory', kind: 'deployed', address: factory, implementation, txHash, inManifest: false });
110
+ return factory;
111
+ }
112
+ // ── the canonical on-chain renderer ────────────────────────────────────────────
113
+ /** Is the configured renderer the spec version this build expects (v4 — the computed `abx_params`
114
+ * object, enumerated from chain, plus `animation_url` wrapped as `data:text/html;base64` for the
115
+ * inline/reader representations)? A behind-spec renderer is treated as stale so {@link ensureRenderer}
116
+ * deploys a fresh one (greenfield redeploy-freely: this number is what tells the CLI a deployed
117
+ * renderer predates a projection the current build emits). A v4 renderer is safe on ANY token —
118
+ * pointed at a legacy implementation it simply emits no params block. Bump in lockstep with
119
+ * `AbxMetadataRenderer.SPEC_VERSION`. */
120
+ export async function isCurrentRenderer(publicClient, renderer) {
121
+ try {
122
+ const v = (await publicClient.readContract({
123
+ address: renderer,
124
+ abi: abxMetadataRendererAbi,
125
+ functionName: 'specVersion',
126
+ }));
127
+ return v === 4n;
128
+ }
129
+ catch {
130
+ return false;
131
+ }
132
+ }
133
+ /** Get (or deploy) the chain's shared `AbxMetadataRenderer` — the on-chain metadata
134
+ * renderer that fully-on-chain tokens point at. Stateless + shared, so one deployment
135
+ * serves every project; redeployed only if missing or a stale spec version. */
136
+ export async function ensureRenderer(publicClient, send, opts) {
137
+ const notify = opts.onEvent ?? (() => { });
138
+ const known = resolveRenderer(opts.chainId, opts.override);
139
+ if (known) {
140
+ const code = await publicClient.getCode({ address: known });
141
+ if (code && code !== '0x' && (await isCurrentRenderer(publicClient, known))) {
142
+ notify({ anchor: 'renderer', kind: 'resolved', address: known });
143
+ return known;
144
+ }
145
+ notify({ anchor: 'renderer', kind: 'stale', address: known, reason: 'stale-version' });
146
+ }
147
+ // The current renderer is CREATE2-deterministic, so it may already exist at its predicted address
148
+ // (deployed by the forge script, or a prior lazy deploy, with the manifest not yet updated). Check
149
+ // there before deploying — self-healing, and never a duplicate. `deployRenderer` lands here too.
150
+ const predicted = predictRenderer();
151
+ if (!known || known.toLowerCase() !== predicted.toLowerCase()) {
152
+ const pcode = await publicClient.getCode({ address: predicted });
153
+ if (pcode && pcode !== '0x' && (await isCurrentRenderer(publicClient, predicted))) {
154
+ notify({ anchor: 'renderer', kind: 'canonical', address: predicted });
155
+ return predicted;
156
+ }
157
+ }
158
+ notify({ anchor: 'renderer', kind: 'deploying' });
159
+ const { renderer, specVersion, txHash } = await deployRenderer(send, publicClient);
160
+ notify({ anchor: 'renderer', kind: 'deployed', address: renderer, specVersion, txHash, inManifest: false });
161
+ return renderer;
162
+ }
163
+ // ── the code-project (SeriesCode) trust anchor ────────────────────────────────
164
+ /** The code-project trust anchor: use the canonical factory, else deploy one (a sandbox /
165
+ * fresh chain — libraries linked in-flight; see {@link deploySeriesCodeFactory}). Unlike the
166
+ * 1/1 and Series factories there is no version probe (no `isCurrentSeriesCodeFactory` — a
167
+ * configured factory with code is always accepted) and no CREATE2 self-heal (its bytecode is
168
+ * link-time-linked against two libraries deployed by plain CREATE, so nothing about its address
169
+ * is predictable — see {@link deploySeriesCodeFactory}'s own doc comment). */
170
+ export async function ensureSeriesCodeFactory(publicClient, send, opts) {
171
+ const notify = opts.onEvent ?? (() => { });
172
+ const known = resolveSeriesCodeFactory(opts.chainId, opts.override);
173
+ if (known) {
174
+ const code = await publicClient.getCode({ address: known });
175
+ if (code && code !== '0x') {
176
+ notify({ anchor: 'series-code-factory', kind: 'resolved', address: known });
177
+ return known;
178
+ }
179
+ if (!opts.allowBootstrap)
180
+ throw new AnchorUnavailableError('series-code-factory', 'no-code', known);
181
+ notify({ anchor: 'series-code-factory', kind: 'stale', address: known, reason: 'no-code' });
182
+ }
183
+ if (!known && !opts.allowBootstrap)
184
+ throw new AnchorUnavailableError('series-code-factory', 'not-configured');
185
+ notify({ anchor: 'series-code-factory', kind: 'deploying' });
186
+ const r = await deploySeriesCodeFactory(send, publicClient);
187
+ notify({
188
+ anchor: 'series-code-factory',
189
+ kind: 'deployed',
190
+ address: r.factory,
191
+ implementation: r.implementation,
192
+ paramsLib: r.paramsLib,
193
+ codeLib: r.codeLib,
194
+ txHash: r.txHash,
195
+ inManifest: false,
196
+ });
197
+ return r.factory;
198
+ }
199
+ // ── the canonical seed source ─────────────────────────────────────────────────
200
+ /** The canonical seed source — a clean keyless singleton (like the renderer / chunk store / minter):
201
+ * single-profile, so CREATE2 lands at THE canonical address on any chain. Resolves from the manifest,
202
+ * self-heals to the predicted address (deployed but not yet repointed), else auto-deploys via CREATE2. */
203
+ export async function ensureSeedSource(publicClient, send, opts) {
204
+ const notify = opts.onEvent ?? (() => { });
205
+ const known = resolveSeedSource(opts.chainId);
206
+ if (known) {
207
+ const code = await publicClient.getCode({ address: known });
208
+ if (code && code !== '0x') {
209
+ notify({ anchor: 'seed-source', kind: 'resolved', address: known });
210
+ return known;
211
+ }
212
+ }
213
+ const predicted = predictSeedSource();
214
+ if (!known || known.toLowerCase() !== predicted.toLowerCase()) {
215
+ const pcode = await publicClient.getCode({ address: predicted });
216
+ if (pcode && pcode !== '0x') {
217
+ notify({ anchor: 'seed-source', kind: 'canonical', address: predicted });
218
+ return predicted;
219
+ }
220
+ }
221
+ const { seedSource, txHash } = await deploySeedSource(send, publicClient);
222
+ notify({ anchor: 'seed-source', kind: 'deployed', address: seedSource, txHash, inManifest: false });
223
+ return seedSource;
224
+ }
225
+ // ── protocol reads: which factory, and from when ──────────────────────────────
226
+ /**
227
+ * Pick the canonical factory for a clone being added. An explicit override or a stored value
228
+ * wins; otherwise probe the chain's known factories (SeriesCode, Series, 1/1) for the ONE whose
229
+ * `isAbxClone` confirms this address, so `abx add` of a code / Series project records the RIGHT
230
+ * factory and canonicity actually verifies. Without this, `add` defaulted to the 1/1 factory, so a
231
+ * code/Series clone read `canonical: unverified` (the check ran against the wrong factory). One
232
+ * multicall, only when the factory isn't already known; falls back to the 1/1 default on any miss/RPC
233
+ * error (`isAbxClone` shares a selector across all factory ABIs, so one ABI probes them all).
234
+ */
235
+ export async function detectCanonicalFactory(publicClient, address, opts) {
236
+ if (opts.override)
237
+ return opts.override;
238
+ if (opts.stored)
239
+ return opts.stored;
240
+ const known = [resolveSeriesCodeFactory(opts.chainId), resolveSeriesFactory(opts.chainId), resolveFactory(opts.chainId)].filter((f) => !!f);
241
+ const candidates = [...new Set(known)];
242
+ if (candidates.length <= 1)
243
+ return candidates[0]; // nothing to disambiguate
244
+ try {
245
+ const results = (await publicClient.multicall({
246
+ contracts: candidates.map((f) => ({
247
+ address: f,
248
+ abi: oneOfOneImageFactoryAbi,
249
+ functionName: 'isAbxClone',
250
+ args: [address],
251
+ })),
252
+ allowFailure: true,
253
+ }));
254
+ const hit = candidates.find((_, i) => results[i]?.status === 'success' && results[i].result === true);
255
+ if (hit)
256
+ return hit;
257
+ }
258
+ catch {
259
+ /* RPC hiccup — fall back to the default; canonicity just shows unverified, never wrong */
260
+ }
261
+ return resolveFactory(opts.chainId) ?? undefined;
262
+ }
263
+ /**
264
+ * Resolve the scan floor (fromBlock) for an add/index: an explicit override wins, else the deploy
265
+ * block the local deploy already stored, else discover it from chain (getCode binary search). It
266
+ * NEVER silently defaults to genesis — a from-0 full scan of a live chain must be an explicit
267
+ * opt-in, because on a range-capped RPC it's the difference between an instant index and grinding
268
+ * millions of blocks (the #1 reason a hosted resolver appears "not to index"). Returns a decimal
269
+ * block string. Only touches RPC in the discovery fallback (rare — a foreign contract we didn't
270
+ * deploy here), so the common post-deploy path makes no extra call.
271
+ */
272
+ export async function resolveScanFloor(publicClient, address, opts = {}) {
273
+ const notify = opts.onEvent ?? (() => { });
274
+ if (opts.explicit !== undefined) {
275
+ if (/^0+$/.test(opts.explicit.trim()))
276
+ notify({ kind: 'genesis-warning' });
277
+ return opts.explicit;
278
+ }
279
+ if (opts.localFromBlock !== undefined)
280
+ return opts.localFromBlock; // the deploy stored the exact block
281
+ const discovered = await discoverDeployBlock(publicClient, address);
282
+ if (discovered !== null) {
283
+ notify({ kind: 'discovered', block: discovered });
284
+ return discovered.toString();
285
+ }
286
+ throw new Error(`couldn't determine ${address}'s deploy block (no local record, and on-chain discovery failed — a non-archive RPC?). ` +
287
+ `Pass --from-block <deployBlock> so indexing starts there instead of sweeping from genesis. ` +
288
+ `(--from-block 0 forces a full-chain scan if you really want it.)`);
289
+ }
290
+ //# sourceMappingURL=anchors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anchors.js","sourceRoot":"","sources":["../src/anchors.ts"],"names":[],"mappings":"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"}
package/dist/chains.d.ts CHANGED
@@ -5,23 +5,48 @@ import type { Chain } from 'viem';
5
5
  * The protocol is per-EVM-chain (one project = one contract, per chain).
6
6
  */
7
7
  export declare const CHAINS: Record<string, Chain>;
8
+ /** Every chain key this toolkit ships, for validating an `ABX_CHAIN` before anything tries to use it. */
9
+ export declare const KNOWN_CHAIN_KEYS: string[];
8
10
  export declare const DEFAULT_CHAIN_KEY = "base-sepolia";
9
11
  export declare function resolveChain(key?: string): Chain;
12
+ /** A supported chain by its EIP-155 id, or undefined. Callers that only carry a chainId (the
13
+ * token-api's routes are `/t/<chainId>/…`) need this to reach the chain's metadata. */
14
+ export declare function chainById(chainId: number): Chain | undefined;
15
+ /**
16
+ * Block-explorer base URL for a chain id, taken from viem's own chain metadata rather than a
17
+ * hand-maintained table — so adding a chain to {@link CHAINS} brings its explorer along and no
18
+ * separate list can fall out of sync. Falls back to Etherscan's Sepolia only for an unknown id.
19
+ *
20
+ * There was a hardcoded `https://sepolia.etherscan.io` in the token-api dashboard, so every link on
21
+ * it — contract, tx, address — pointed at Ethereum Sepolia regardless of the chain being served.
22
+ * Since the default chain is Base Sepolia, that meant the dashboard for a normal `abx demo` sent you
23
+ * to an explorer where the contract does not exist.
24
+ */
25
+ export declare function explorerUrl(chainId: number): string;
26
+ /** Env-name suffix for a user-facing key: uppercased, any run of non-alphanumerics collapsed to
27
+ * one `_` (`base-sepolia` → `BASE_SEPOLIA`, `my.provider` → `MY_PROVIDER`). Shared by every
28
+ * `ABX_<FAMILY>_<NAME>_*` convention (`ABX_RPC_URLS_<CHAIN>`, `ABX_REMOTE_<NAME>_URL/_TOKEN`) so
29
+ * the conventions can't drift. Lossy — the normalized form is the canonical name. */
30
+ export declare function envSuffix(name: string): string;
10
31
  /** The env var holding RPC endpoints for a chain: per-chain `ABX_RPC_URLS_<CHAIN>` (e.g.
11
32
  * `ABX_RPC_URLS_SEPOLIA`) when set, else the bare `ABX_RPC_URLS` (the active `ABX_CHAIN`). */
12
33
  export declare function rpcEnvVar(chainKey: string): string;
13
34
  /**
14
- * The ordered, de-duplicated RPC endpoints for `chainKey`. **Network-scoped**: a
15
- * per-chain `ABX_RPC_URLS_<CHAIN>` wins when set; otherwise the bare `ABX_RPC_URLS`
16
- * (understood as "for the active `ABX_CHAIN`"). Both are comma/whitespace-separated
17
- * lists in preference order — the client fails over across them and `abx doctor`
18
- * probes + ranks each (e.g. widest `eth_getLogs` range). The bare and per-chain vars
19
- * are never mixed, so a list for one network can't leak into another; a chainId guard
20
- * (see `assertChainId`) then verifies the endpoints actually ARE `chainKey`.
35
+ * The ordered, de-duplicated RPC endpoints for `chainKey`. Precedence is **override → env →
36
+ * manifest default**, the same `pick()` shape `deployments.ts` uses for every other address:
37
+ * - `override` (a `ClientOptions.rpcUrls`, or a single `rpcUrl` the caller already joined) —
38
+ * explicit config wins outright, no env involved.
39
+ * - env: a per-chain `ABX_RPC_URLS_<CHAIN>` wins when set; otherwise the bare `ABX_RPC_URLS`
40
+ * (understood as "for the active `ABX_CHAIN`"). Both are comma/whitespace-separated lists in
41
+ * preference order — the client fails over across them and `abx doctor` probes + ranks each
42
+ * (e.g. widest `eth_getLogs` range). The bare and per-chain vars are never mixed, so a list for
43
+ * one network can't leak into another; a chainId guard (see `assertChainId`) then verifies the
44
+ * endpoints actually ARE `chainKey`.
45
+ * - manifest: the built-in keyless default for `chainKey`.
21
46
  */
22
- export declare function resolveRpcUrls(chainKey?: string): string[];
47
+ export declare function resolveRpcUrls(chainKey?: string, override?: string | string[]): string[];
23
48
  /** The primary RPC endpoint (the first of {@link resolveRpcUrls}). */
24
- export declare function resolveRpcUrl(chainKey?: string): string;
49
+ export declare function resolveRpcUrl(chainKey?: string, override?: string | string[]): string;
25
50
  /** A display-safe form of an RPC URL — host + a redacted key tail (URLs can embed keys). */
26
51
  export declare function redactRpcUrl(url: string): string;
27
52
  //# sourceMappingURL=chains.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chains.d.ts","sourceRoot":"","sources":["../src/chains.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,KAAK,EAAC,MAAM,MAAM,CAAC;AAGhC;;;;GAIG;AACH,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAGxC,CAAC;AAEF,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAShD,wBAAgB,YAAY,CAAC,GAAG,GAAE,MAA0B,GAAG,KAAK,CAInE;AAED;+FAC+F;AAC/F,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAIlD;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,QAAQ,GAAE,MAA0B,GAAG,MAAM,EAAE,CAY7E;AAED,sEAAsE;AACtE,wBAAgB,aAAa,CAAC,QAAQ,GAAE,MAA0B,GAAG,MAAM,CAE1E;AAED,4FAA4F;AAC5F,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAShD"}
1
+ {"version":3,"file":"chains.d.ts","sourceRoot":"","sources":["../src/chains.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,KAAK,EAAC,MAAM,MAAM,CAAC;AAGhC;;;;GAIG;AACH,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAGxC,CAAC;AAEF,yGAAyG;AACzG,eAAO,MAAM,gBAAgB,UAAsB,CAAC;AAGpD,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAShD,wBAAgB,YAAY,CAAC,GAAG,GAAE,MAA0B,GAAG,KAAK,CAInE;AAED;wFACwF;AACxF,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAE5D;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;sFAGsF;AACtF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED;+FAC+F;AAC/F,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAElD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,QAAQ,GAAE,MAA0B,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,CAU3G;AAED,sEAAsE;AACtE,wBAAgB,aAAa,CAAC,QAAQ,GAAE,MAA0B,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,CAExG;AAED,4FAA4F;AAC5F,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAShD"}
package/dist/chains.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { sepolia, baseSepolia } from 'viem/chains';
2
- import { loadDotEnv } from './env.js';
2
+ import { readEnv } from './util.js';
3
3
  /**
4
4
  * Chain targets. The SDK is neutral about *which* chain — it takes a target as
5
5
  * input — but the toolkit's demo runs on a testnet, so that's the default here.
@@ -9,6 +9,8 @@ export const CHAINS = {
9
9
  'base-sepolia': baseSepolia,
10
10
  sepolia,
11
11
  };
12
+ /** Every chain key this toolkit ships, for validating an `ABX_CHAIN` before anything tries to use it. */
13
+ export const KNOWN_CHAIN_KEYS = Object.keys(CHAINS);
12
14
  export const DEFAULT_CHAIN_KEY = 'base-sepolia';
13
15
  // Public, keyless endpoints per chain — overridable. A self-hoster points these at
14
16
  // their own node; nothing about resolution depends on a particular provider.
@@ -22,27 +24,52 @@ export function resolveChain(key = DEFAULT_CHAIN_KEY) {
22
24
  throw new Error(`Unknown chain "${key}". Known: ${Object.keys(CHAINS).join(', ')}`);
23
25
  return chain;
24
26
  }
27
+ /** A supported chain by its EIP-155 id, or undefined. Callers that only carry a chainId (the
28
+ * token-api's routes are `/t/<chainId>/…`) need this to reach the chain's metadata. */
29
+ export function chainById(chainId) {
30
+ return Object.values(CHAINS).find((c) => c.id === chainId);
31
+ }
32
+ /**
33
+ * Block-explorer base URL for a chain id, taken from viem's own chain metadata rather than a
34
+ * hand-maintained table — so adding a chain to {@link CHAINS} brings its explorer along and no
35
+ * separate list can fall out of sync. Falls back to Etherscan's Sepolia only for an unknown id.
36
+ *
37
+ * There was a hardcoded `https://sepolia.etherscan.io` in the token-api dashboard, so every link on
38
+ * it — contract, tx, address — pointed at Ethereum Sepolia regardless of the chain being served.
39
+ * Since the default chain is Base Sepolia, that meant the dashboard for a normal `abx demo` sent you
40
+ * to an explorer where the contract does not exist.
41
+ */
42
+ export function explorerUrl(chainId) {
43
+ return chainById(chainId)?.blockExplorers?.default?.url ?? 'https://sepolia.etherscan.io';
44
+ }
45
+ /** Env-name suffix for a user-facing key: uppercased, any run of non-alphanumerics collapsed to
46
+ * one `_` (`base-sepolia` → `BASE_SEPOLIA`, `my.provider` → `MY_PROVIDER`). Shared by every
47
+ * `ABX_<FAMILY>_<NAME>_*` convention (`ABX_RPC_URLS_<CHAIN>`, `ABX_REMOTE_<NAME>_URL/_TOKEN`) so
48
+ * the conventions can't drift. Lossy — the normalized form is the canonical name. */
49
+ export function envSuffix(name) {
50
+ return name.toUpperCase().replace(/[^A-Z0-9]+/g, '_');
51
+ }
25
52
  /** The env var holding RPC endpoints for a chain: per-chain `ABX_RPC_URLS_<CHAIN>` (e.g.
26
53
  * `ABX_RPC_URLS_SEPOLIA`) when set, else the bare `ABX_RPC_URLS` (the active `ABX_CHAIN`). */
27
54
  export function rpcEnvVar(chainKey) {
28
- // Env var names can't contain hyphens, so a key like `base-sepolia` becomes
29
- // `ABX_RPC_URLS_BASE_SEPOLIA` (any non-alphanumeric collapses to `_`).
30
- return `ABX_RPC_URLS_${chainKey.toUpperCase().replace(/[^A-Z0-9]+/g, '_')}`;
55
+ return `ABX_RPC_URLS_${envSuffix(chainKey)}`;
31
56
  }
32
57
  /**
33
- * The ordered, de-duplicated RPC endpoints for `chainKey`. **Network-scoped**: a
34
- * per-chain `ABX_RPC_URLS_<CHAIN>` wins when set; otherwise the bare `ABX_RPC_URLS`
35
- * (understood as "for the active `ABX_CHAIN`"). Both are comma/whitespace-separated
36
- * lists in preference order — the client fails over across them and `abx doctor`
37
- * probes + ranks each (e.g. widest `eth_getLogs` range). The bare and per-chain vars
38
- * are never mixed, so a list for one network can't leak into another; a chainId guard
39
- * (see `assertChainId`) then verifies the endpoints actually ARE `chainKey`.
58
+ * The ordered, de-duplicated RPC endpoints for `chainKey`. Precedence is **override → env →
59
+ * manifest default**, the same `pick()` shape `deployments.ts` uses for every other address:
60
+ * - `override` (a `ClientOptions.rpcUrls`, or a single `rpcUrl` the caller already joined) —
61
+ * explicit config wins outright, no env involved.
62
+ * - env: a per-chain `ABX_RPC_URLS_<CHAIN>` wins when set; otherwise the bare `ABX_RPC_URLS`
63
+ * (understood as "for the active `ABX_CHAIN`"). Both are comma/whitespace-separated lists in
64
+ * preference order — the client fails over across them and `abx doctor` probes + ranks each
65
+ * (e.g. widest `eth_getLogs` range). The bare and per-chain vars are never mixed, so a list for
66
+ * one network can't leak into another; a chainId guard (see `assertChainId`) then verifies the
67
+ * endpoints actually ARE `chainKey`.
68
+ * - manifest: the built-in keyless default for `chainKey`.
40
69
  */
41
- export function resolveRpcUrls(chainKey = DEFAULT_CHAIN_KEY) {
42
- loadDotEnv();
43
- // Per-chain override is authoritative when present; bare ABX_RPC_URLS is the
44
- // single-/active-chain fallback. They are NOT concatenated — mixing networks is the bug.
45
- const list = process.env[rpcEnvVar(chainKey)] ?? process.env.ABX_RPC_URLS ?? '';
70
+ export function resolveRpcUrls(chainKey = DEFAULT_CHAIN_KEY, override) {
71
+ const overrideList = override === undefined ? undefined : Array.isArray(override) ? override.join(',') : override;
72
+ const list = overrideList ?? readEnv(rpcEnvVar(chainKey)) ?? readEnv('ABX_RPC_URLS') ?? '';
46
73
  const seen = new Set();
47
74
  const urls = list
48
75
  .split(/[\s,]+/)
@@ -53,8 +80,8 @@ export function resolveRpcUrls(chainKey = DEFAULT_CHAIN_KEY) {
53
80
  return urls;
54
81
  }
55
82
  /** The primary RPC endpoint (the first of {@link resolveRpcUrls}). */
56
- export function resolveRpcUrl(chainKey = DEFAULT_CHAIN_KEY) {
57
- return resolveRpcUrls(chainKey)[0] ?? '';
83
+ export function resolveRpcUrl(chainKey = DEFAULT_CHAIN_KEY, override) {
84
+ return resolveRpcUrls(chainKey, override)[0] ?? '';
58
85
  }
59
86
  /** A display-safe form of an RPC URL — host + a redacted key tail (URLs can embed keys). */
60
87
  export function redactRpcUrl(url) {
@@ -1 +1 @@
1
- {"version":3,"file":"chains.js","sourceRoot":"","sources":["../src/chains.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chains.js","sourceRoot":"","sources":["../src/chains.ts"],"names":[],"mappings":"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"}
package/dist/chunks.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { type Address, type Hex, type PublicClient, type TransactionReceipt } from 'viem';
1
+ import { type Address, type Hex, type PublicClient } from 'viem';
2
+ import type { SendTx } from './execute.js';
2
3
  /**
3
4
  * Multi-chunk on-chain content — the off-chain side of {@link AbxChunkStore}.
4
5
  *
@@ -18,23 +19,12 @@ export interface PlannedChunk {
18
19
  compressed: boolean;
19
20
  }
20
21
  /**
21
- * One staging transaction, described in lane-agnostic terms: the SDK builds the calldata,
22
- * the caller decides how it's signed. The chunk-store writes are **ownerless**, so they can
23
- * be signed by any funded signer — the env key (hot lane) *or* a connected browser wallet
24
- * (wallet lane). Keeping the signer out of this module is what lets on-chain staging work
25
- * under every signing lane instead of assuming a hot key.
26
- *
27
- * `summary` + `fields` are surfaced to a human on the wallet sign page; `to: null` means a
28
- * contract creation (deploying the chunk store itself).
22
+ * Chunk-store writes are staged in the SAME lane-agnostic terms as every other write: the SDK
23
+ * builds a {@link PreparedTx}, the caller decides how it's signed via a {@link SendTx}. These writes
24
+ * are **ownerless**, so they can be signed by any funded signer — the env key (hot lane) *or* a
25
+ * connected browser wallet (wallet lane). Keeping the signer out of this module is what lets
26
+ * on-chain staging work under every signing lane instead of assuming a hot key.
29
27
  */
30
- export interface StagingTx {
31
- to: Address | null;
32
- data: Hex;
33
- summary: string;
34
- fields: Record<string, string>;
35
- }
36
- /** Sign + broadcast one {@link StagingTx} and return its mined receipt (for event parsing). */
37
- export type SendStagingTx = (tx: StagingTx) => Promise<TransactionReceipt>;
38
28
  /**
39
29
  * Split content into chunks, FastLZ-compressing each when `fastlz` is set (per-chunk — the
40
30
  * convention the store + reader expect). Pure: no chain, no I/O. A chunk is only stored
@@ -81,7 +71,9 @@ export declare function planContentTxs(chunks: PlannedChunk[], opts?: {
81
71
  * Deploy `AbxChunkStore` — the shared, stateless multi-chunk store + reader. Deploy once
82
72
  * per chain (like the renderer); every chunked field references it as its `reader`.
83
73
  */
84
- export declare function deployChunkStore(send: SendStagingTx): Promise<{
74
+ export declare function deployChunkStore(send: SendTx, opts: {
75
+ chainId: number;
76
+ }): Promise<{
85
77
  chunkStore: Address;
86
78
  txHash: Hex;
87
79
  blockNumber: bigint;
@@ -96,9 +88,10 @@ export declare function deployChunkStore(send: SendStagingTx): Promise<{
96
88
  */
97
89
  export declare function storeSupportsWriteContent(publicClient: PublicClient, store: Address): Promise<boolean>;
98
90
  /** Write one chunk as an SSTORE2 data contract; returns its address (from `ChunkWritten`). */
99
- export declare function writeChunk(send: SendStagingTx, args: {
91
+ export declare function writeChunk(send: SendTx, args: {
100
92
  store: Address;
101
93
  data: Uint8Array;
94
+ chainId: number;
102
95
  }): Promise<{
103
96
  pointer: Address;
104
97
  txHash: Hex;
@@ -109,9 +102,10 @@ export declare function writeChunk(send: SendStagingTx, args: {
109
102
  * fits a single tx's gas (see {@link planContentTxs}); returns the manifest address (the
110
103
  * `reader` pointer) from the `ManifestWritten` event.
111
104
  */
112
- export declare function writeContent(send: SendStagingTx, args: {
105
+ export declare function writeContent(send: SendTx, args: {
113
106
  store: Address;
114
107
  chunks: ReadonlyArray<PlannedChunk>;
108
+ chainId: number;
115
109
  }): Promise<{
116
110
  manifest: Address;
117
111
  txHash: Hex;
@@ -123,9 +117,10 @@ export declare function writeContent(send: SendStagingTx, args: {
123
117
  * batches, concatenates the returned pointers, then calls {@link writeManifest}. Pairs
124
118
  * each pointer with its planned `compressed` flag for manifest assembly.
125
119
  */
126
- export declare function writeChunkBatch(send: SendStagingTx, args: {
120
+ export declare function writeChunkBatch(send: SendTx, args: {
127
121
  store: Address;
128
122
  chunks: ReadonlyArray<PlannedChunk>;
123
+ chainId: number;
129
124
  }): Promise<{
130
125
  written: Array<{
131
126
  pointer: Address;
@@ -143,9 +138,10 @@ export declare function writeChunkBatch(send: SendStagingTx, args: {
143
138
  * This is the same path whether the manifest is later baked into a deploy's `InitParams`
144
139
  * or set on a live token — staging always precedes the contract that references it.
145
140
  */
146
- export declare function stageContent(send: SendStagingTx, args: {
141
+ export declare function stageContent(send: SendTx, args: {
147
142
  store: Address;
148
143
  content: Uint8Array;
144
+ chainId: number;
149
145
  fastlz?: boolean;
150
146
  chunkSize?: number;
151
147
  gasBudget?: number;
@@ -155,14 +151,48 @@ export declare function stageContent(send: SendStagingTx, args: {
155
151
  chunkCount: number;
156
152
  }>;
157
153
  /** Write the manifest (ordered chunk list); returns its address (the `reader` pointer). */
158
- export declare function writeManifest(send: SendStagingTx, args: {
154
+ export declare function writeManifest(send: SendTx, args: {
159
155
  store: Address;
160
156
  chunks: ReadonlyArray<{
161
157
  pointer: Address;
162
158
  compressed: boolean;
163
159
  }>;
160
+ chainId: number;
164
161
  }): Promise<{
165
162
  manifest: Address;
166
163
  txHash: Hex;
167
164
  }>;
165
+ /** Progress from {@link ensureChunkStore}, so a caller can narrate without the SDK printing. */
166
+ export type ChunkStoreEvent = {
167
+ kind: 'stale';
168
+ address: Address;
169
+ } | {
170
+ kind: 'canonical';
171
+ address: Address;
172
+ } | {
173
+ kind: 'deploying';
174
+ } | {
175
+ kind: 'deployed';
176
+ address: Address;
177
+ inManifest: boolean;
178
+ };
179
+ /**
180
+ * Resolve a usable multi-chunk content store for this chain, deploying one if needed.
181
+ *
182
+ * This is the bootstrap every on-chain-content path needs, and it existed only inside the CLI — so an
183
+ * SDK integrator got `resolveChunkStore()` (which may return undefined) plus a separate
184
+ * `storeSupportsWriteContent()` they had to remember to call. Forget the second and an incapable
185
+ * store fails *deep inside a mint, after transactions have already landed*. One team hand-rolled this
186
+ * guard for exactly that reason; exporting it is cheaper than every integrator rediscovering it.
187
+ *
188
+ * Three ways to succeed, in order: the listed store if it exists AND exposes the current ABI; the
189
+ * CREATE2-deterministic address (the store is canonical, so a forge script or an earlier lazy deploy
190
+ * may have put it there before the manifest caught up — self-healing, and never a duplicate at a
191
+ * random CREATE address); otherwise deploy it. Ownerless, so any funded signer may stand it up.
192
+ */
193
+ export declare function ensureChunkStore(publicClient: PublicClient, send: SendTx, opts?: {
194
+ chainId: number;
195
+ override?: string;
196
+ onEvent?: (e: ChunkStoreEvent) => void;
197
+ }): Promise<Address>;
168
198
  //# sourceMappingURL=chunks.d.ts.map