@artblocks/abx-sdk 0.1.0-alpha.0

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 (86) hide show
  1. package/LICENSE +21 -0
  2. package/dist/abi/generated.d.ts +6185 -0
  3. package/dist/abi/generated.d.ts.map +1 -0
  4. package/dist/abi/generated.js +28 -0
  5. package/dist/abi/generated.js.map +1 -0
  6. package/dist/abi/index.d.ts +3227 -0
  7. package/dist/abi/index.d.ts.map +1 -0
  8. package/dist/abi/index.js +38 -0
  9. package/dist/abi/index.js.map +1 -0
  10. package/dist/chains.d.ts +27 -0
  11. package/dist/chains.d.ts.map +1 -0
  12. package/dist/chains.js +71 -0
  13. package/dist/chains.js.map +1 -0
  14. package/dist/chunks.d.ts +168 -0
  15. package/dist/chunks.d.ts.map +1 -0
  16. package/dist/chunks.js +232 -0
  17. package/dist/chunks.js.map +1 -0
  18. package/dist/clients.d.ts +42 -0
  19. package/dist/clients.d.ts.map +1 -0
  20. package/dist/clients.js +90 -0
  21. package/dist/clients.js.map +1 -0
  22. package/dist/create2.d.ts +42 -0
  23. package/dist/create2.d.ts.map +1 -0
  24. package/dist/create2.js +47 -0
  25. package/dist/create2.js.map +1 -0
  26. package/dist/deploy.d.ts +192 -0
  27. package/dist/deploy.d.ts.map +1 -0
  28. package/dist/deploy.js +231 -0
  29. package/dist/deploy.js.map +1 -0
  30. package/dist/deployments.d.ts +60 -0
  31. package/dist/deployments.d.ts.map +1 -0
  32. package/dist/deployments.js +81 -0
  33. package/dist/deployments.js.map +1 -0
  34. package/dist/deps.d.ts +109 -0
  35. package/dist/deps.d.ts.map +1 -0
  36. package/dist/deps.js +103 -0
  37. package/dist/deps.js.map +1 -0
  38. package/dist/env.d.ts +2 -0
  39. package/dist/env.d.ts.map +1 -0
  40. package/dist/env.js +45 -0
  41. package/dist/env.js.map +1 -0
  42. package/dist/fastlz.d.ts +20 -0
  43. package/dist/fastlz.d.ts.map +1 -0
  44. package/dist/fastlz.js +123 -0
  45. package/dist/fastlz.js.map +1 -0
  46. package/dist/generator.d.ts +129 -0
  47. package/dist/generator.d.ts.map +1 -0
  48. package/dist/generator.js +81 -0
  49. package/dist/generator.js.map +1 -0
  50. package/dist/index.d.ts +31 -0
  51. package/dist/index.d.ts.map +1 -0
  52. package/dist/index.js +20 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/ops.d.ts +379 -0
  55. package/dist/ops.d.ts.map +1 -0
  56. package/dist/ops.js +811 -0
  57. package/dist/ops.js.map +1 -0
  58. package/dist/probe.d.ts +30 -0
  59. package/dist/probe.d.ts.map +1 -0
  60. package/dist/probe.js +74 -0
  61. package/dist/probe.js.map +1 -0
  62. package/dist/reconstruct.d.ts +97 -0
  63. package/dist/reconstruct.d.ts.map +1 -0
  64. package/dist/reconstruct.js +597 -0
  65. package/dist/reconstruct.js.map +1 -0
  66. package/dist/spine.d.ts +110 -0
  67. package/dist/spine.d.ts.map +1 -0
  68. package/dist/spine.js +0 -0
  69. package/dist/spine.js.map +1 -0
  70. package/dist/token.d.ts +33 -0
  71. package/dist/token.d.ts.map +1 -0
  72. package/dist/token.js +66 -0
  73. package/dist/token.js.map +1 -0
  74. package/dist/tokendata.d.ts +50 -0
  75. package/dist/tokendata.d.ts.map +1 -0
  76. package/dist/tokendata.js +178 -0
  77. package/dist/tokendata.js.map +1 -0
  78. package/dist/traits.d.ts +38 -0
  79. package/dist/traits.d.ts.map +1 -0
  80. package/dist/traits.js +92 -0
  81. package/dist/traits.js.map +1 -0
  82. package/dist/types.d.ts +145 -0
  83. package/dist/types.d.ts.map +1 -0
  84. package/dist/types.js +2 -0
  85. package/dist/types.js.map +1 -0
  86. package/package.json +53 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/abi/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,uBAAuB,EACvB,4BAA4B,EAC5B,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,EACrB,0BAA0B,EAC1B,cAAc,EACd,mBAAmB,EACnB,oBAAoB,EACpB,yBAAyB,EACzB,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,qBAAqB,EACrB,eAAe,EACf,oBAAoB,EACpB,aAAa,EACb,kBAAkB,EAClB,sBAAsB,EACtB,2BAA2B,EAC3B,gBAAgB,EAChB,qBAAqB,EACrB,sBAAsB,EACtB,2BAA2B,GAC5B,MAAM,gBAAgB,CAAC;AAiBxB;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAmBtB,CAAC"}
@@ -0,0 +1,38 @@
1
+ // The ABI surface the SDK speaks. Generated artifacts come from the contracts
2
+ // package (Layer 1) via `pnpm sync-abis`; never hand-edit `generated.ts`.
3
+ export { oneOfOneImageFactoryAbi, oneOfOneImageFactoryBytecode, oneOfOneImageAbi, oneOfOneImageBytecode, seriesImageFactoryAbi, seriesImageFactoryBytecode, seriesImageAbi, seriesImageBytecode, seriesCodeFactoryAbi, seriesCodeFactoryBytecode, seriesCodeAbi, seriesCodeBytecode, abxSeedSourceAbi, abxSeedSourceBytecode, abxParamsLibAbi, abxParamsLibBytecode, abxCodeLibAbi, abxCodeLibBytecode, abxMetadataRendererAbi, abxMetadataRendererBytecode, abxChunkStoreAbi, abxChunkStoreBytecode, abxFixedPriceMinterAbi, abxFixedPriceMinterBytecode, } from './generated.js';
4
+ import { oneOfOneImageAbi, oneOfOneImageFactoryAbi, seriesImageAbi, seriesImageFactoryAbi, seriesCodeAbi, seriesCodeFactoryAbi, abxFixedPriceMinterAbi, } from './generated.js';
5
+ /** A stable signature key for an ABI event fragment (name + input types), for de-duping. */
6
+ function eventKey(f) {
7
+ return `${f.name ?? ''}(${(f.inputs ?? []).map((i) => i.type).join(',')})`;
8
+ }
9
+ /**
10
+ * The event-spine ABI: every event any ABX token type + its factory can emit — the set
11
+ * the reference indexer decodes. Both concrete tokens (1/1 and Series) declare the full
12
+ * spine they participate in (Register 1 standards + Register 2 native events); we union
13
+ * them plus the factories' `Deployed` and the fixed-price minter's sibling Minter-spine
14
+ * events (`SaleConfigured`/`Purchase`), de-duping shared fragments (e.g. `Transfer`) so a
15
+ * single ABI decodes any ABX contract's logs unambiguously.
16
+ */
17
+ export const spineEventAbi = (() => {
18
+ const all = [
19
+ ...oneOfOneImageAbi,
20
+ ...seriesImageAbi,
21
+ ...seriesCodeAbi,
22
+ ...oneOfOneImageFactoryAbi,
23
+ ...seriesImageFactoryAbi,
24
+ ...seriesCodeFactoryAbi,
25
+ ...abxFixedPriceMinterAbi,
26
+ ].filter((f) => f.type === 'event');
27
+ const seen = new Set();
28
+ const out = [];
29
+ for (const f of all) {
30
+ const key = eventKey(f);
31
+ if (seen.has(key))
32
+ continue;
33
+ seen.add(key);
34
+ out.push(f);
35
+ }
36
+ return out;
37
+ })();
38
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/abi/index.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,0EAA0E;AAC1E,OAAO,EACL,uBAAuB,EACvB,4BAA4B,EAC5B,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,EACrB,0BAA0B,EAC1B,cAAc,EACd,mBAAmB,EACnB,oBAAoB,EACpB,yBAAyB,EACzB,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,qBAAqB,EACrB,eAAe,EACf,oBAAoB,EACpB,aAAa,EACb,kBAAkB,EAClB,sBAAsB,EACtB,2BAA2B,EAC3B,gBAAgB,EAChB,qBAAqB,EACrB,sBAAsB,EACtB,2BAA2B,GAC5B,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,cAAc,EACd,qBAAqB,EACrB,aAAa,EACb,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AAExB,4FAA4F;AAC5F,SAAS,QAAQ,CAAC,CAAwE;IACxF,OAAO,GAAG,CAAC,CAAC,IAAI,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;AAC7E,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE;IACjC,MAAM,GAAG,GAAG;QACV,GAAG,gBAAgB;QACnB,GAAG,cAAc;QACjB,GAAG,aAAa;QAChB,GAAG,uBAAuB;QAC1B,GAAG,qBAAqB;QACxB,GAAG,oBAAoB;QACvB,GAAG,sBAAsB;KAC1B,CAAC,MAAM,CAAC,CAAC,CAAiB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,GAAG,GAAe,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;QACpB,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAU,CAAC,CAAC;QACjC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACd,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC,EAAE,CAAC"}
@@ -0,0 +1,27 @@
1
+ import type { Chain } from 'viem';
2
+ /**
3
+ * Chain targets. The SDK is neutral about *which* chain — it takes a target as
4
+ * input — but the toolkit's demo runs on a testnet, so that's the default here.
5
+ * The protocol is per-EVM-chain (one project = one contract, per chain).
6
+ */
7
+ export declare const CHAINS: Record<string, Chain>;
8
+ export declare const DEFAULT_CHAIN_KEY = "base-sepolia";
9
+ export declare function resolveChain(key?: string): Chain;
10
+ /** The env var holding RPC endpoints for a chain: per-chain `ABX_RPC_URLS_<CHAIN>` (e.g.
11
+ * `ABX_RPC_URLS_SEPOLIA`) when set, else the bare `ABX_RPC_URLS` (the active `ABX_CHAIN`). */
12
+ export declare function rpcEnvVar(chainKey: string): string;
13
+ /**
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`.
21
+ */
22
+ export declare function resolveRpcUrls(chainKey?: string): string[];
23
+ /** The primary RPC endpoint (the first of {@link resolveRpcUrls}). */
24
+ export declare function resolveRpcUrl(chainKey?: string): string;
25
+ /** A display-safe form of an RPC URL — host + a redacted key tail (URLs can embed keys). */
26
+ export declare function redactRpcUrl(url: string): string;
27
+ //# sourceMappingURL=chains.d.ts.map
@@ -0,0 +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"}
package/dist/chains.js ADDED
@@ -0,0 +1,71 @@
1
+ import { sepolia, baseSepolia } from 'viem/chains';
2
+ import { loadDotEnv } from './env.js';
3
+ /**
4
+ * Chain targets. The SDK is neutral about *which* chain — it takes a target as
5
+ * input — but the toolkit's demo runs on a testnet, so that's the default here.
6
+ * The protocol is per-EVM-chain (one project = one contract, per chain).
7
+ */
8
+ export const CHAINS = {
9
+ 'base-sepolia': baseSepolia,
10
+ sepolia,
11
+ };
12
+ export const DEFAULT_CHAIN_KEY = 'base-sepolia';
13
+ // Public, keyless endpoints per chain — overridable. A self-hoster points these at
14
+ // their own node; nothing about resolution depends on a particular provider.
15
+ const DEFAULT_RPC_URLS = {
16
+ 'base-sepolia': 'https://sepolia.base.org',
17
+ sepolia: 'https://ethereum-sepolia-rpc.publicnode.com',
18
+ };
19
+ export function resolveChain(key = DEFAULT_CHAIN_KEY) {
20
+ const chain = CHAINS[key];
21
+ if (!chain)
22
+ throw new Error(`Unknown chain "${key}". Known: ${Object.keys(CHAINS).join(', ')}`);
23
+ return chain;
24
+ }
25
+ /** The env var holding RPC endpoints for a chain: per-chain `ABX_RPC_URLS_<CHAIN>` (e.g.
26
+ * `ABX_RPC_URLS_SEPOLIA`) when set, else the bare `ABX_RPC_URLS` (the active `ABX_CHAIN`). */
27
+ 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, '_')}`;
31
+ }
32
+ /**
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`.
40
+ */
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 ?? '';
46
+ const seen = new Set();
47
+ const urls = list
48
+ .split(/[\s,]+/)
49
+ .map((u) => u.trim())
50
+ .filter((u) => u && !seen.has(u) && seen.add(u));
51
+ if (urls.length === 0 && DEFAULT_RPC_URLS[chainKey])
52
+ urls.push(DEFAULT_RPC_URLS[chainKey]);
53
+ return urls;
54
+ }
55
+ /** The primary RPC endpoint (the first of {@link resolveRpcUrls}). */
56
+ export function resolveRpcUrl(chainKey = DEFAULT_CHAIN_KEY) {
57
+ return resolveRpcUrls(chainKey)[0] ?? '';
58
+ }
59
+ /** A display-safe form of an RPC URL — host + a redacted key tail (URLs can embed keys). */
60
+ export function redactRpcUrl(url) {
61
+ try {
62
+ const u = new URL(url);
63
+ const last = u.pathname.split('/').filter(Boolean).pop() ?? '';
64
+ const tail = last.length > 6 ? `…${last.slice(-4)}` : last;
65
+ return tail ? `${u.host}/…/${tail}` : u.host;
66
+ }
67
+ catch {
68
+ return url.length > 24 ? `${url.slice(0, 20)}…` : url;
69
+ }
70
+ }
71
+ //# sourceMappingURL=chains.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chains.js","sourceRoot":"","sources":["../src/chains.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,168 @@
1
+ import { type Address, type Hex, type PublicClient, type TransactionReceipt } from 'viem';
2
+ /**
3
+ * Multi-chunk on-chain content — the off-chain side of {@link AbxChunkStore}.
4
+ *
5
+ * Large content (a 30 kB image, a long description) is split into SSTORE2-sized chunks,
6
+ * optionally FastLZ-compressed **per chunk** off-chain (the chunk store decompresses on
7
+ * read, so it stays on-chain-renderable), written as immutable data contracts, and tied
8
+ * together by a manifest. The field then carries the `reader` representation with
9
+ * `value = abi.encode(chunkStore, manifest)`. gzip is *not* handled here — it's an
10
+ * off-chain decode signaled by the `-gzip` representation, applied to the assembled bytes.
11
+ */
12
+ /** SSTORE2 data-contract code limit is 24576 bytes (EIP-170) minus the STOP byte; chunk
13
+ * conservatively so even an incompressible FastLZ chunk (slight expansion) still fits. */
14
+ export declare const DEFAULT_CHUNK_SIZE = 22000;
15
+ /** One planned chunk: the bytes to store + whether they're FastLZ-compressed. */
16
+ export interface PlannedChunk {
17
+ data: Uint8Array;
18
+ compressed: boolean;
19
+ }
20
+ /**
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).
29
+ */
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
+ /**
39
+ * Split content into chunks, FastLZ-compressing each when `fastlz` is set (per-chunk — the
40
+ * convention the store + reader expect). Pure: no chain, no I/O. A chunk is only stored
41
+ * compressed when that actually shrinks it (so the reader never wastes a decompress).
42
+ */
43
+ export declare function planChunks(content: Uint8Array, opts?: {
44
+ fastlz?: boolean;
45
+ chunkSize?: number;
46
+ }): PlannedChunk[];
47
+ /**
48
+ * A per-transaction gas ceiling for packing chunk writes. Comfortably under mainnet's
49
+ * ~30M block limit so a batch always fits with room for the base + calldata cost; the
50
+ * planner splits content across multiple transactions to stay beneath it.
51
+ */
52
+ export declare const DEFAULT_TX_GAS_BUDGET = 8000000;
53
+ /**
54
+ * Rough gas for writing one chunk as an SSTORE2 data contract: a fixed CREATE + base
55
+ * overhead plus the code-deposit cost (~200 gas/byte) and calldata. Deliberately an
56
+ * over-estimate so packed batches land safely inside {@link DEFAULT_TX_GAS_BUDGET};
57
+ * the wallet still does the real `eth_estimateGas` before sending.
58
+ */
59
+ export declare function estimateChunkGas(chunk: PlannedChunk): number;
60
+ /** How content will be written on-chain — one atomic tx, or several batched ones. */
61
+ export type ContentTxPlan = {
62
+ mode: 'single';
63
+ chunks: PlannedChunk[];
64
+ txCount: 1;
65
+ } | {
66
+ mode: 'split';
67
+ batches: PlannedChunk[][];
68
+ txCount: number;
69
+ };
70
+ /**
71
+ * Decide the transaction shape for a piece of content. When the whole thing fits one
72
+ * tx's gas budget it's a single atomic {@link writeContent} (no address prediction, no
73
+ * follow-up). Otherwise it's split into gas-bounded batches of {@link writeChunk} calls
74
+ * (each batch one `multicall`), followed by a single {@link writeManifest} — so
75
+ * `txCount` is `batches.length + 1`. Pure: no chain, no I/O.
76
+ */
77
+ export declare function planContentTxs(chunks: PlannedChunk[], opts?: {
78
+ gasBudget?: number;
79
+ }): ContentTxPlan;
80
+ /**
81
+ * Deploy `AbxChunkStore` — the shared, stateless multi-chunk store + reader. Deploy once
82
+ * per chain (like the renderer); every chunked field references it as its `reader`.
83
+ */
84
+ export declare function deployChunkStore(send: SendStagingTx): Promise<{
85
+ chunkStore: Address;
86
+ txHash: Hex;
87
+ blockNumber: bigint;
88
+ }>;
89
+ /**
90
+ * Does `store` expose the current `writeContent(bytes[],bool[])` ABI? A chunk store deployed
91
+ * before `writeContent` existed (an older `AbxChunkStore`) still *has code*, so a bare
92
+ * `getCode` check passes — but the call reverts, silently breaking the `--onchain-image`
93
+ * path. We probe with an empty `writeContent([],[])`: the current store returns a manifest
94
+ * address, a stale/incompatible one reverts. This is a pure `eth_call` (no tx, no state
95
+ * change, no gas spent), so it's safe to run on every staging path as a guard.
96
+ */
97
+ export declare function storeSupportsWriteContent(publicClient: PublicClient, store: Address): Promise<boolean>;
98
+ /** Write one chunk as an SSTORE2 data contract; returns its address (from `ChunkWritten`). */
99
+ export declare function writeChunk(send: SendStagingTx, args: {
100
+ store: Address;
101
+ data: Uint8Array;
102
+ }): Promise<{
103
+ pointer: Address;
104
+ txHash: Hex;
105
+ }>;
106
+ /**
107
+ * Write a whole piece of content — every chunk plus the manifest — in ONE transaction
108
+ * via `AbxChunkStore.writeContent`. The atomic, prediction-free path for content that
109
+ * fits a single tx's gas (see {@link planContentTxs}); returns the manifest address (the
110
+ * `reader` pointer) from the `ManifestWritten` event.
111
+ */
112
+ export declare function writeContent(send: SendStagingTx, args: {
113
+ store: Address;
114
+ chunks: ReadonlyArray<PlannedChunk>;
115
+ }): Promise<{
116
+ manifest: Address;
117
+ txHash: Hex;
118
+ }>;
119
+ /**
120
+ * Write a batch of chunks in ONE transaction via the store's `multicall`, returning their
121
+ * pointer addresses **in order** (parsed from the `ChunkWritten` events). Used by the
122
+ * split path for content too large for a single tx: the caller writes one or more such
123
+ * batches, concatenates the returned pointers, then calls {@link writeManifest}. Pairs
124
+ * each pointer with its planned `compressed` flag for manifest assembly.
125
+ */
126
+ export declare function writeChunkBatch(send: SendStagingTx, args: {
127
+ store: Address;
128
+ chunks: ReadonlyArray<PlannedChunk>;
129
+ }): Promise<{
130
+ written: Array<{
131
+ pointer: Address;
132
+ compressed: boolean;
133
+ }>;
134
+ txHash: Hex;
135
+ }>;
136
+ /**
137
+ * Stage a whole piece of content on the chunk store and return its manifest — the
138
+ * `pointer` half of a `reader` field's value. Plans the chunks, then executes the
139
+ * minimal transaction set ({@link planContentTxs}): one atomic {@link writeContent} when
140
+ * it fits, else gas-bounded {@link writeChunkBatch} multicalls plus a final
141
+ * {@link writeManifest}. Returns every tx hash so a UX can report the count honestly.
142
+ *
143
+ * This is the same path whether the manifest is later baked into a deploy's `InitParams`
144
+ * or set on a live token — staging always precedes the contract that references it.
145
+ */
146
+ export declare function stageContent(send: SendStagingTx, args: {
147
+ store: Address;
148
+ content: Uint8Array;
149
+ fastlz?: boolean;
150
+ chunkSize?: number;
151
+ gasBudget?: number;
152
+ }): Promise<{
153
+ manifest: Address;
154
+ txHashes: Hex[];
155
+ chunkCount: number;
156
+ }>;
157
+ /** Write the manifest (ordered chunk list); returns its address (the `reader` pointer). */
158
+ export declare function writeManifest(send: SendStagingTx, args: {
159
+ store: Address;
160
+ chunks: ReadonlyArray<{
161
+ pointer: Address;
162
+ compressed: boolean;
163
+ }>;
164
+ }): Promise<{
165
+ manifest: Address;
166
+ txHash: Hex;
167
+ }>;
168
+ //# sourceMappingURL=chunks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunks.d.ts","sourceRoot":"","sources":["../src/chunks.ts"],"names":[],"mappings":"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"}
package/dist/chunks.js ADDED
@@ -0,0 +1,232 @@
1
+ import { encodeFunctionData, parseEventLogs, } from 'viem';
2
+ import { abxChunkStoreAbi, abxChunkStoreBytecode } from './abi/index.js';
3
+ import { flzCompress } from './fastlz.js';
4
+ import { ABX_SALT, CREATE2_PROXY, create2Calldata, predictCreate2Address } from './create2.js';
5
+ /**
6
+ * Multi-chunk on-chain content — the off-chain side of {@link AbxChunkStore}.
7
+ *
8
+ * Large content (a 30 kB image, a long description) is split into SSTORE2-sized chunks,
9
+ * optionally FastLZ-compressed **per chunk** off-chain (the chunk store decompresses on
10
+ * read, so it stays on-chain-renderable), written as immutable data contracts, and tied
11
+ * together by a manifest. The field then carries the `reader` representation with
12
+ * `value = abi.encode(chunkStore, manifest)`. gzip is *not* handled here — it's an
13
+ * off-chain decode signaled by the `-gzip` representation, applied to the assembled bytes.
14
+ */
15
+ /** SSTORE2 data-contract code limit is 24576 bytes (EIP-170) minus the STOP byte; chunk
16
+ * conservatively so even an incompressible FastLZ chunk (slight expansion) still fits. */
17
+ export const DEFAULT_CHUNK_SIZE = 22_000;
18
+ /**
19
+ * Split content into chunks, FastLZ-compressing each when `fastlz` is set (per-chunk — the
20
+ * convention the store + reader expect). Pure: no chain, no I/O. A chunk is only stored
21
+ * compressed when that actually shrinks it (so the reader never wastes a decompress).
22
+ */
23
+ export function planChunks(content, opts = {}) {
24
+ const size = opts.chunkSize ?? DEFAULT_CHUNK_SIZE;
25
+ const chunks = [];
26
+ for (let i = 0; i < content.length; i += size) {
27
+ const raw = content.subarray(i, i + size);
28
+ if (opts.fastlz) {
29
+ const packed = flzCompress(raw);
30
+ if (packed.length < raw.length) {
31
+ chunks.push({ data: packed, compressed: true });
32
+ continue;
33
+ }
34
+ }
35
+ chunks.push({ data: raw, compressed: false });
36
+ }
37
+ return chunks;
38
+ }
39
+ const toHex = (b) => `0x${Buffer.from(b).toString('hex')}`;
40
+ /**
41
+ * A per-transaction gas ceiling for packing chunk writes. Comfortably under mainnet's
42
+ * ~30M block limit so a batch always fits with room for the base + calldata cost; the
43
+ * planner splits content across multiple transactions to stay beneath it.
44
+ */
45
+ export const DEFAULT_TX_GAS_BUDGET = 8_000_000;
46
+ /**
47
+ * Rough gas for writing one chunk as an SSTORE2 data contract: a fixed CREATE + base
48
+ * overhead plus the code-deposit cost (~200 gas/byte) and calldata. Deliberately an
49
+ * over-estimate so packed batches land safely inside {@link DEFAULT_TX_GAS_BUDGET};
50
+ * the wallet still does the real `eth_estimateGas` before sending.
51
+ */
52
+ export function estimateChunkGas(chunk) {
53
+ return 40_000 + chunk.data.length * 240;
54
+ }
55
+ /**
56
+ * Decide the transaction shape for a piece of content. When the whole thing fits one
57
+ * tx's gas budget it's a single atomic {@link writeContent} (no address prediction, no
58
+ * follow-up). Otherwise it's split into gas-bounded batches of {@link writeChunk} calls
59
+ * (each batch one `multicall`), followed by a single {@link writeManifest} — so
60
+ * `txCount` is `batches.length + 1`. Pure: no chain, no I/O.
61
+ */
62
+ export function planContentTxs(chunks, opts = {}) {
63
+ const budget = opts.gasBudget ?? DEFAULT_TX_GAS_BUDGET;
64
+ const total = chunks.reduce((g, c) => g + estimateChunkGas(c), 0);
65
+ // writeContent also pays for the manifest write; approximate it as one more chunk.
66
+ if (total + 60_000 <= budget)
67
+ return { mode: 'single', chunks, txCount: 1 };
68
+ const batches = [];
69
+ let cur = [];
70
+ let curGas = 0;
71
+ for (const c of chunks) {
72
+ const g = estimateChunkGas(c);
73
+ if (cur.length > 0 && curGas + g > budget) {
74
+ batches.push(cur);
75
+ cur = [];
76
+ curGas = 0;
77
+ }
78
+ cur.push(c);
79
+ curGas += g;
80
+ }
81
+ if (cur.length > 0)
82
+ batches.push(cur);
83
+ return { mode: 'split', batches, txCount: batches.length + 1 };
84
+ }
85
+ /**
86
+ * Deploy `AbxChunkStore` — the shared, stateless multi-chunk store + reader. Deploy once
87
+ * per chain (like the renderer); every chunked field references it as its `reader`.
88
+ */
89
+ export async function deployChunkStore(send) {
90
+ // CREATE2 via the keyless proxy + canonical salt → the SAME address on every chain (matches the
91
+ // forge `DeployChunkStore` script and the manifest). The address is deterministic, so we compute
92
+ // it rather than read `receipt.contractAddress` (which is null — the tx targets the proxy, not a
93
+ // contract creation). Deploy only when the store isn't already there (the caller checks first).
94
+ const chunkStore = predictCreate2Address(ABX_SALT.chunkStore, abxChunkStoreBytecode);
95
+ const receipt = await send({
96
+ to: CREATE2_PROXY,
97
+ data: create2Calldata(ABX_SALT.chunkStore, abxChunkStoreBytecode),
98
+ summary: 'Deploy the shared on-chain chunk store (AbxChunkStore) — CREATE2, deterministic address',
99
+ fields: { contract: 'AbxChunkStore', address: chunkStore, note: 'one-time, ownerless, shared by every chunked field' },
100
+ });
101
+ return { chunkStore, txHash: receipt.transactionHash, blockNumber: receipt.blockNumber };
102
+ }
103
+ /**
104
+ * Does `store` expose the current `writeContent(bytes[],bool[])` ABI? A chunk store deployed
105
+ * before `writeContent` existed (an older `AbxChunkStore`) still *has code*, so a bare
106
+ * `getCode` check passes — but the call reverts, silently breaking the `--onchain-image`
107
+ * path. We probe with an empty `writeContent([],[])`: the current store returns a manifest
108
+ * address, a stale/incompatible one reverts. This is a pure `eth_call` (no tx, no state
109
+ * change, no gas spent), so it's safe to run on every staging path as a guard.
110
+ */
111
+ export async function storeSupportsWriteContent(publicClient, store) {
112
+ try {
113
+ await publicClient.call({
114
+ to: store,
115
+ data: encodeFunctionData({ abi: abxChunkStoreAbi, functionName: 'writeContent', args: [[], []] }),
116
+ });
117
+ return true;
118
+ }
119
+ catch {
120
+ return false;
121
+ }
122
+ }
123
+ /** Write one chunk as an SSTORE2 data contract; returns its address (from `ChunkWritten`). */
124
+ export async function writeChunk(send, args) {
125
+ const receipt = await send({
126
+ to: args.store,
127
+ data: encodeFunctionData({ abi: abxChunkStoreAbi, functionName: 'writeChunk', args: [toHex(args.data)] }),
128
+ summary: 'Stage one on-chain content chunk',
129
+ fields: { store: args.store, bytes: String(args.data.length) },
130
+ });
131
+ const ev = parseEventLogs({ abi: abxChunkStoreAbi, eventName: 'ChunkWritten', logs: receipt.logs });
132
+ const pointer = ev[0]?.args.pointer;
133
+ if (!pointer)
134
+ throw new Error('writeChunk emitted no ChunkWritten event');
135
+ return { pointer, txHash: receipt.transactionHash };
136
+ }
137
+ /**
138
+ * Write a whole piece of content — every chunk plus the manifest — in ONE transaction
139
+ * via `AbxChunkStore.writeContent`. The atomic, prediction-free path for content that
140
+ * fits a single tx's gas (see {@link planContentTxs}); returns the manifest address (the
141
+ * `reader` pointer) from the `ManifestWritten` event.
142
+ */
143
+ export async function writeContent(send, args) {
144
+ const receipt = await send({
145
+ to: args.store,
146
+ data: encodeFunctionData({
147
+ abi: abxChunkStoreAbi,
148
+ functionName: 'writeContent',
149
+ args: [args.chunks.map((c) => toHex(c.data)), args.chunks.map((c) => c.compressed)],
150
+ }),
151
+ summary: `Stage on-chain content (${args.chunks.length} chunk${args.chunks.length === 1 ? '' : 's'}, atomic)`,
152
+ fields: { store: args.store, chunks: String(args.chunks.length) },
153
+ });
154
+ const ev = parseEventLogs({ abi: abxChunkStoreAbi, eventName: 'ManifestWritten', logs: receipt.logs });
155
+ const manifest = ev[0]?.args.manifest;
156
+ if (!manifest)
157
+ throw new Error('writeContent emitted no ManifestWritten event');
158
+ return { manifest, txHash: receipt.transactionHash };
159
+ }
160
+ /**
161
+ * Write a batch of chunks in ONE transaction via the store's `multicall`, returning their
162
+ * pointer addresses **in order** (parsed from the `ChunkWritten` events). Used by the
163
+ * split path for content too large for a single tx: the caller writes one or more such
164
+ * batches, concatenates the returned pointers, then calls {@link writeManifest}. Pairs
165
+ * each pointer with its planned `compressed` flag for manifest assembly.
166
+ */
167
+ export async function writeChunkBatch(send, args) {
168
+ const calls = args.chunks.map((c) => encodeFunctionData({ abi: abxChunkStoreAbi, functionName: 'writeChunk', args: [toHex(c.data)] }));
169
+ const receipt = await send({
170
+ to: args.store,
171
+ data: encodeFunctionData({ abi: abxChunkStoreAbi, functionName: 'multicall', args: [calls] }),
172
+ summary: `Stage ${args.chunks.length} on-chain content chunk${args.chunks.length === 1 ? '' : 's'} (batch)`,
173
+ fields: { store: args.store, chunks: String(args.chunks.length) },
174
+ });
175
+ const txHash = receipt.transactionHash;
176
+ const evs = parseEventLogs({ abi: abxChunkStoreAbi, eventName: 'ChunkWritten', logs: receipt.logs });
177
+ if (evs.length !== args.chunks.length) {
178
+ throw new Error(`writeChunkBatch: expected ${args.chunks.length} ChunkWritten events, got ${evs.length}`);
179
+ }
180
+ const written = evs.map((e, i) => ({
181
+ pointer: e.args.pointer,
182
+ compressed: args.chunks[i].compressed,
183
+ }));
184
+ return { written, txHash };
185
+ }
186
+ /**
187
+ * Stage a whole piece of content on the chunk store and return its manifest — the
188
+ * `pointer` half of a `reader` field's value. Plans the chunks, then executes the
189
+ * minimal transaction set ({@link planContentTxs}): one atomic {@link writeContent} when
190
+ * it fits, else gas-bounded {@link writeChunkBatch} multicalls plus a final
191
+ * {@link writeManifest}. Returns every tx hash so a UX can report the count honestly.
192
+ *
193
+ * This is the same path whether the manifest is later baked into a deploy's `InitParams`
194
+ * or set on a live token — staging always precedes the contract that references it.
195
+ */
196
+ export async function stageContent(send, args) {
197
+ const chunks = planChunks(args.content, { fastlz: args.fastlz, chunkSize: args.chunkSize });
198
+ const plan = planContentTxs(chunks, { gasBudget: args.gasBudget });
199
+ const txHashes = [];
200
+ if (plan.mode === 'single') {
201
+ const { manifest, txHash } = await writeContent(send, { store: args.store, chunks });
202
+ return { manifest, txHashes: [txHash], chunkCount: chunks.length };
203
+ }
204
+ const written = [];
205
+ for (const batch of plan.batches) {
206
+ const res = await writeChunkBatch(send, { store: args.store, chunks: batch });
207
+ written.push(...res.written);
208
+ txHashes.push(res.txHash);
209
+ }
210
+ const { manifest, txHash } = await writeManifest(send, { store: args.store, chunks: written });
211
+ txHashes.push(txHash);
212
+ return { manifest, txHashes, chunkCount: chunks.length };
213
+ }
214
+ /** Write the manifest (ordered chunk list); returns its address (the `reader` pointer). */
215
+ export async function writeManifest(send, args) {
216
+ const receipt = await send({
217
+ to: args.store,
218
+ data: encodeFunctionData({
219
+ abi: abxChunkStoreAbi,
220
+ functionName: 'writeManifest',
221
+ args: [args.chunks.map((c) => ({ pointer: c.pointer, compressed: c.compressed }))],
222
+ }),
223
+ summary: `Write the on-chain content manifest (${args.chunks.length} chunk${args.chunks.length === 1 ? '' : 's'})`,
224
+ fields: { store: args.store, chunks: String(args.chunks.length) },
225
+ });
226
+ const ev = parseEventLogs({ abi: abxChunkStoreAbi, eventName: 'ManifestWritten', logs: receipt.logs });
227
+ const manifest = ev[0]?.args.manifest;
228
+ if (!manifest)
229
+ throw new Error('writeManifest emitted no ManifestWritten event');
230
+ return { manifest, txHash: receipt.transactionHash };
231
+ }
232
+ //# sourceMappingURL=chunks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunks.js","sourceRoot":"","sources":["../src/chunks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import { type PublicClient, type WalletClient, type Account } from 'viem';
2
+ export interface ClientOptions {
3
+ chainKey?: string;
4
+ rpcUrl?: string;
5
+ }
6
+ /** A read-only client — all the indexer and token API ever need. */
7
+ export declare function makePublicClient(opts?: ClientOptions): PublicClient;
8
+ /**
9
+ * Verify the configured RPC actually IS the chain we think it is, before any write.
10
+ * The env var names a network ("sepolia") but the URL behind it could point anywhere;
11
+ * this calls `eth_chainId` and hard-fails on a mismatch so an irreversible tx can't go
12
+ * to the wrong chain. Memoized per chainKey — one round-trip per process, so callers can
13
+ * invoke it liberally at write preflights. Reads never call it (they stay zero-overhead).
14
+ *
15
+ * `allowUnreachable` (used by `--dry-run` preflights): a *wrong-network* RPC still hard-fails
16
+ * with the clear mismatch message — a dry run makes RPC reads (predict address, resolve the
17
+ * factory/renderer) that otherwise fail deep inside viem as an opaque "returned no data" — but
18
+ * an *unreachable* RPC is tolerated (returns silently), so a genuinely offline `--dry-run` can
19
+ * still preview what it can. Only a reachable-but-wrong endpoint is a preview-blocking error.
20
+ */
21
+ export declare function assertChainId(chainKey?: string, opts?: {
22
+ allowUnreachable?: boolean;
23
+ }): Promise<void>;
24
+ /**
25
+ * A signing client, backed by a private key from the environment. The SDK never
26
+ * takes custody of keys beyond reading them from the operator's own env — there
27
+ * is no key storage, no prompt, no remote signer here.
28
+ *
29
+ * Key precedence: `ABX_DEPLOYER_PK` → `SEPOLIA_FUNDED_PK` → `SEPOLIA_WALLET_PK`.
30
+ */
31
+ export declare function makeWalletClient(opts?: ClientOptions): {
32
+ wallet: WalletClient;
33
+ account: Account;
34
+ };
35
+ /**
36
+ * The env signing key (0x-normalized), same precedence as {@link makeWalletClient}
37
+ * (`ABX_DEPLOYER_PK` → `SEPOLIA_FUNDED_PK` → `SEPOLIA_WALLET_PK`), or `undefined` if none is set.
38
+ * For reusing the hot key as a *storage* signing identity (an Ethereum Turbo identity) without
39
+ * constructing a wallet client. Never throws.
40
+ */
41
+ export declare function envSigningKey(): `0x${string}` | undefined;
42
+ //# sourceMappingURL=clients.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clients.d.ts","sourceRoot":"","sources":["../src/clients.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,YAAY,EAEjB,KAAK,YAAY,EACjB,KAAK,OAAO,EACb,MAAM,MAAM,CAAC;AAKd,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAeD,oEAAoE;AACpE,wBAAgB,gBAAgB,CAAC,IAAI,GAAE,aAAkB,GAAG,YAAY,CAEvE;AAID;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CACjC,QAAQ,GAAE,MAA0B,EACpC,IAAI,GAAE;IAAC,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAAM,GACtC,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,GAAE,aAAkB,GAAG;IAC1D,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;CAClB,CAYA;AAOD;;;;;GAKG;AACH,wBAAgB,aAAa,IAAI,KAAK,MAAM,EAAE,GAAG,SAAS,CAIzD"}