@artblocks/abx-sdk 0.1.0-alpha.4 → 0.1.0-alpha.41
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 +72 -0
- package/README.md +130 -0
- package/dist/abi/generated.d.ts +8502 -129
- package/dist/abi/generated.d.ts.map +1 -1
- package/dist/abi/generated.js +40 -22
- package/dist/abi/generated.js.map +1 -1
- package/dist/abi/index.d.ts +2645 -168
- package/dist/abi/index.d.ts.map +1 -1
- package/dist/abi/index.js +34 -7
- package/dist/abi/index.js.map +1 -1
- package/dist/anchors.d.ts +325 -0
- package/dist/anchors.d.ts.map +1 -0
- package/dist/anchors.js +740 -0
- package/dist/anchors.js.map +1 -0
- package/dist/chain-support.d.ts +28 -0
- package/dist/chain-support.d.ts.map +1 -0
- package/dist/chain-support.js +65 -0
- package/dist/chain-support.js.map +1 -0
- package/dist/chain-support.json +60 -0
- package/dist/chains.d.ts +24 -10
- package/dist/chains.d.ts.map +1 -1
- package/dist/chains.js +51 -17
- package/dist/chains.js.map +1 -1
- package/dist/chunks.d.ts +162 -31
- package/dist/chunks.d.ts.map +1 -1
- package/dist/chunks.js +179 -14
- package/dist/chunks.js.map +1 -1
- package/dist/clients.d.ts +23 -11
- package/dist/clients.d.ts.map +1 -1
- package/dist/clients.js +17 -18
- package/dist/clients.js.map +1 -1
- package/dist/contract-generations.d.ts +58 -0
- package/dist/contract-generations.d.ts.map +1 -0
- package/dist/contract-generations.js +109 -0
- package/dist/contract-generations.js.map +1 -0
- package/dist/contract-generations.json +48 -0
- package/dist/create2.d.ts +84 -1
- package/dist/create2.d.ts.map +1 -1
- package/dist/create2.js +158 -2
- package/dist/create2.js.map +1 -1
- package/dist/creator-token.d.ts +132 -0
- package/dist/creator-token.d.ts.map +1 -0
- package/dist/creator-token.js +183 -0
- package/dist/creator-token.js.map +1 -0
- package/dist/deploy.d.ts +234 -14
- package/dist/deploy.d.ts.map +1 -1
- package/dist/deploy.js +289 -111
- package/dist/deploy.js.map +1 -1
- package/dist/deployments.d.ts +38 -5
- package/dist/deployments.d.ts.map +1 -1
- package/dist/deployments.js +157 -30
- package/dist/deployments.js.map +1 -1
- package/dist/deps.d.ts +123 -6
- package/dist/deps.d.ts.map +1 -1
- package/dist/deps.js +249 -7
- package/dist/deps.js.map +1 -1
- package/dist/env.d.ts +5 -4
- package/dist/env.d.ts.map +1 -1
- package/dist/env.js +20 -5
- package/dist/env.js.map +1 -1
- package/dist/errors.d.ts +109 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +148 -0
- package/dist/errors.js.map +1 -0
- package/dist/execute.d.ts +118 -0
- package/dist/execute.d.ts.map +1 -0
- package/dist/execute.js +159 -0
- package/dist/execute.js.map +1 -0
- package/dist/gateways.d.ts +79 -0
- package/dist/gateways.d.ts.map +1 -0
- package/dist/gateways.js +156 -0
- package/dist/gateways.js.map +1 -0
- package/dist/generator-document.d.ts +57 -0
- package/dist/generator-document.d.ts.map +1 -0
- package/dist/generator-document.js +123 -0
- package/dist/generator-document.js.map +1 -0
- package/dist/generator.d.ts +44 -2
- package/dist/generator.d.ts.map +1 -1
- package/dist/generator.js +29 -0
- package/dist/generator.js.map +1 -1
- package/dist/index.d.ts +19 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -3
- package/dist/index.js.map +1 -1
- package/dist/inspect.d.ts +48 -0
- package/dist/inspect.d.ts.map +1 -0
- package/dist/inspect.js +295 -0
- package/dist/inspect.js.map +1 -0
- package/dist/migrate.d.ts +41 -0
- package/dist/migrate.d.ts.map +1 -0
- package/dist/migrate.js +142 -0
- package/dist/migrate.js.map +1 -0
- package/dist/mime.d.ts +11 -0
- package/dist/mime.d.ts.map +1 -0
- package/dist/mime.js +40 -0
- package/dist/mime.js.map +1 -0
- package/dist/node.d.ts +69 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +92 -0
- package/dist/node.js.map +1 -0
- package/dist/onchain-uri.d.ts +110 -0
- package/dist/onchain-uri.d.ts.map +1 -0
- package/dist/onchain-uri.js +276 -0
- package/dist/onchain-uri.js.map +1 -0
- package/dist/ops.d.ts +507 -14
- package/dist/ops.d.ts.map +1 -1
- package/dist/ops.js +850 -34
- package/dist/ops.js.map +1 -1
- package/dist/policy.d.ts +57 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +35 -0
- package/dist/policy.js.map +1 -0
- package/dist/probe.d.ts +58 -0
- package/dist/probe.d.ts.map +1 -1
- package/dist/probe.js +190 -9
- package/dist/probe.js.map +1 -1
- package/dist/reconstruct.d.ts +141 -3
- package/dist/reconstruct.d.ts.map +1 -1
- package/dist/reconstruct.js +479 -100
- package/dist/reconstruct.js.map +1 -1
- package/dist/resume.d.ts +147 -0
- package/dist/resume.d.ts.map +1 -0
- package/dist/resume.js +146 -0
- package/dist/resume.js.map +1 -0
- package/dist/script-chunks.d.ts +105 -0
- package/dist/script-chunks.d.ts.map +1 -0
- package/dist/script-chunks.js +158 -0
- package/dist/script-chunks.js.map +1 -0
- package/dist/service.d.ts +155 -9
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +103 -11
- package/dist/service.js.map +1 -1
- package/dist/spine.d.ts +47 -4
- package/dist/spine.d.ts.map +1 -1
- package/dist/spine.js +0 -0
- package/dist/spine.js.map +1 -1
- package/dist/staging.d.ts +139 -0
- package/dist/staging.d.ts.map +1 -0
- package/dist/staging.js +139 -0
- package/dist/staging.js.map +1 -0
- package/dist/token.d.ts +11 -1
- package/dist/token.d.ts.map +1 -1
- package/dist/token.js +32 -1
- package/dist/token.js.map +1 -1
- package/dist/tokendata.d.ts +63 -3
- package/dist/tokendata.d.ts.map +1 -1
- package/dist/tokendata.js +81 -19
- package/dist/tokendata.js.map +1 -1
- package/dist/tokens.d.ts +119 -0
- package/dist/tokens.d.ts.map +1 -0
- package/dist/tokens.js +317 -0
- package/dist/tokens.js.map +1 -0
- package/dist/types.d.ts +107 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/util.d.ts +74 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +106 -0
- package/dist/util.js.map +1 -0
- package/package.json +15 -6
package/dist/node.d.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export { loadDotEnv, parseEnvContent } from './env.js';
|
|
2
|
+
/** The directory name every self-hosted node's local state (SQLite projection, managed Arweave
|
|
3
|
+
* key, content index) lives under. One literal, everywhere — see {@link resolveDataDir}. */
|
|
4
|
+
export declare const ABX_DATA_DIR_NAME = ".abx-self-host";
|
|
5
|
+
export interface DataDirResolution {
|
|
6
|
+
/** Absolute path to use as this invocation's data directory. */
|
|
7
|
+
dir: string;
|
|
8
|
+
/**
|
|
9
|
+
* Where `dir` came from:
|
|
10
|
+
* - `'env'` — `ABX_DATA_DIR` was set; it always wins and discovery never ran.
|
|
11
|
+
* - `'cwd'` — the ordinary default, `<cwd>/${ABX_DATA_DIR_NAME}` (whether or not it
|
|
12
|
+
* exists yet — a write command creates it there on first use, same as always).
|
|
13
|
+
* - `'discovered'` — an EXISTING `${ABX_DATA_DIR_NAME}` found by walking up from cwd. Never
|
|
14
|
+
* the write-path outcome — see {@link ResolveDataDirOptions.allowUpwardDiscovery}.
|
|
15
|
+
*/
|
|
16
|
+
source: 'env' | 'cwd' | 'discovered';
|
|
17
|
+
}
|
|
18
|
+
export interface ResolveDataDirOptions {
|
|
19
|
+
/** Defaults to `process.cwd()`. Exposed so callers (and tests) don't have to `chdir`. */
|
|
20
|
+
cwd?: string;
|
|
21
|
+
/** Defaults to `process.env`. Exposed for tests — never mutate the real environment to test this. */
|
|
22
|
+
env?: Record<string, string | undefined>;
|
|
23
|
+
/** Defaults to `os.homedir()`. Exposed so a test can exercise the home-directory boundary
|
|
24
|
+
* without depending on (or touching) the real account running the test. */
|
|
25
|
+
home?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Walk up from `cwd`, git-style, for an ALREADY-EXISTING `${ABX_DATA_DIR_NAME}` before falling
|
|
28
|
+
* back to `<cwd>/${ABX_DATA_DIR_NAME}`. Opt in per-invocation for READ paths ONLY — see
|
|
29
|
+
* {@link resolveDataDir}'s doc comment for the full rationale and the bound on how far it looks.
|
|
30
|
+
*/
|
|
31
|
+
allowUpwardDiscovery?: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The ONE place a self-hosted node's data directory gets located. Every consumer — the CLI, the
|
|
35
|
+
* indexer's SQLite store, the storage package's local-disk backend, content index, and managed
|
|
36
|
+
* Arweave key — used to carry an INDEPENDENT copy of `ABX_DATA_DIR ?? cwd/.abx-self-host`, which is
|
|
37
|
+
* exactly the setup that silently splits one project's SQLite projection from its managed Arweave
|
|
38
|
+
* key into two different directories the moment any single copy drifts from the others. To keep
|
|
39
|
+
* managed Arweave key and projection locations coherent, every one of those call sites now
|
|
40
|
+
* resolves through here instead.
|
|
41
|
+
*
|
|
42
|
+
* `ABX_DATA_DIR` always wins outright — set it and discovery never runs, full stop. That isolation
|
|
43
|
+
* is load-bearing (tests rely on it to run concurrently against disposable temp dirs; an operator
|
|
44
|
+
* relies on it to pin a specific node) and this function must never weaken it.
|
|
45
|
+
*
|
|
46
|
+
* Without it, the default is `<cwd>/.abx-self-host` — unchanged from before this existed. With
|
|
47
|
+
* {@link ResolveDataDirOptions.allowUpwardDiscovery} (a READ-only opt-in; see the CLI's
|
|
48
|
+
* per-command allowlist in `config.ts`), and only when nothing already exists at cwd, this walks
|
|
49
|
+
* UP the directory tree looking for an EXISTING `.abx-self-host`, so (say) `abx status` run from a
|
|
50
|
+
* project subdirectory finds the same node a run from the project root would — instead of quietly
|
|
51
|
+
* opening a second, empty one.
|
|
52
|
+
*
|
|
53
|
+
* The search is BOUNDED, git-style — it stops at (but still checks) the user's home directory, a
|
|
54
|
+
* directory containing `.git` (a repository root), or the filesystem root, so it can never wander
|
|
55
|
+
* into an unrelated ancestor tree. And it never merges two directories: the first EXISTING
|
|
56
|
+
* `.abx-self-host` found wins outright, and `source: 'discovered'` tells the caller to say so — a
|
|
57
|
+
* discovered node is not the one a human just `cd`-ed into; that distinction must stay visible
|
|
58
|
+
* rather than silently answering from the wrong place.
|
|
59
|
+
*/
|
|
60
|
+
export declare function resolveDataDir(options?: ResolveDataDirOptions): DataDirResolution;
|
|
61
|
+
/**
|
|
62
|
+
* The registry-dependency family's injected `inflate` (deps.ts: `resolveRegistryDep` /
|
|
63
|
+
* `dependencyScriptTags`), pre-wired for a Node host: `node:zlib`'s `gunzipSync`, one line. SDK
|
|
64
|
+
* core takes `inflate` as a parameter rather than importing `node:zlib` directly so it stays
|
|
65
|
+
* reachable from a browser bundle — a Node host (the token-api resolver, the CLI) passes this;
|
|
66
|
+
* a browser host passes a `DecompressionStream`-based implementation instead.
|
|
67
|
+
*/
|
|
68
|
+
export declare function nodeInflate(bytes: Uint8Array): Uint8Array;
|
|
69
|
+
//# sourceMappingURL=node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAC,UAAU,EAAE,eAAe,EAAC,MAAM,UAAU,CAAC;AAErD;6FAC6F;AAC7F,eAAO,MAAM,iBAAiB,mBAAmB,CAAC;AAElD,MAAM,WAAW,iBAAiB;IAChC,gEAAgE;IAChE,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;;OAOG;IACH,MAAM,EAAE,KAAK,GAAG,KAAK,GAAG,YAAY,CAAC;CACtC;AAED,MAAM,WAAW,qBAAqB;IACpC,yFAAyF;IACzF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qGAAqG;IACrG,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC;gFAC4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAUD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,qBAA0B,GAAG,iBAAiB,CAwBrF;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAEzD"}
|
package/dist/node.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@artblocks/abx-sdk/node` — the ONE Node-only subpath. Everything reachable from the
|
|
3
|
+
* package's main entry (`.`) has to run in a browser bundle (see `test/browser-bundle.test.ts`),
|
|
4
|
+
* so `.env` loading — which needs `node:fs` + `node:path` — lives here instead, behind an
|
|
5
|
+
* explicit import a host opts into.
|
|
6
|
+
*
|
|
7
|
+
* A host calls `loadDotEnv()` exactly ONCE, at startup, before anything reads `process.env`
|
|
8
|
+
* (the CLI's `main()`, the effects runner's `main()`). The SDK core never calls it itself —
|
|
9
|
+
* see `clients.ts` / `chains.ts` / `deployments.ts`'s `readEnv`, which just reads whatever is
|
|
10
|
+
* already in `process.env` (or nothing, in a browser) and leaves loading it to the host.
|
|
11
|
+
*/
|
|
12
|
+
import { existsSync, statSync } from 'node:fs';
|
|
13
|
+
import { homedir } from 'node:os';
|
|
14
|
+
import { dirname, join, resolve } from 'node:path';
|
|
15
|
+
import { gunzipSync } from 'node:zlib';
|
|
16
|
+
export { loadDotEnv, parseEnvContent } from './env.js';
|
|
17
|
+
/** The directory name every self-hosted node's local state (SQLite projection, managed Arweave
|
|
18
|
+
* key, content index) lives under. One literal, everywhere — see {@link resolveDataDir}. */
|
|
19
|
+
export const ABX_DATA_DIR_NAME = '.abx-self-host';
|
|
20
|
+
function isDirectory(path) {
|
|
21
|
+
try {
|
|
22
|
+
return statSync(path).isDirectory();
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return false; // missing, or a file where a directory is expected — either way, not a hit
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The ONE place a self-hosted node's data directory gets located. Every consumer — the CLI, the
|
|
30
|
+
* indexer's SQLite store, the storage package's local-disk backend, content index, and managed
|
|
31
|
+
* Arweave key — used to carry an INDEPENDENT copy of `ABX_DATA_DIR ?? cwd/.abx-self-host`, which is
|
|
32
|
+
* exactly the setup that silently splits one project's SQLite projection from its managed Arweave
|
|
33
|
+
* key into two different directories the moment any single copy drifts from the others. To keep
|
|
34
|
+
* managed Arweave key and projection locations coherent, every one of those call sites now
|
|
35
|
+
* resolves through here instead.
|
|
36
|
+
*
|
|
37
|
+
* `ABX_DATA_DIR` always wins outright — set it and discovery never runs, full stop. That isolation
|
|
38
|
+
* is load-bearing (tests rely on it to run concurrently against disposable temp dirs; an operator
|
|
39
|
+
* relies on it to pin a specific node) and this function must never weaken it.
|
|
40
|
+
*
|
|
41
|
+
* Without it, the default is `<cwd>/.abx-self-host` — unchanged from before this existed. With
|
|
42
|
+
* {@link ResolveDataDirOptions.allowUpwardDiscovery} (a READ-only opt-in; see the CLI's
|
|
43
|
+
* per-command allowlist in `config.ts`), and only when nothing already exists at cwd, this walks
|
|
44
|
+
* UP the directory tree looking for an EXISTING `.abx-self-host`, so (say) `abx status` run from a
|
|
45
|
+
* project subdirectory finds the same node a run from the project root would — instead of quietly
|
|
46
|
+
* opening a second, empty one.
|
|
47
|
+
*
|
|
48
|
+
* The search is BOUNDED, git-style — it stops at (but still checks) the user's home directory, a
|
|
49
|
+
* directory containing `.git` (a repository root), or the filesystem root, so it can never wander
|
|
50
|
+
* into an unrelated ancestor tree. And it never merges two directories: the first EXISTING
|
|
51
|
+
* `.abx-self-host` found wins outright, and `source: 'discovered'` tells the caller to say so — a
|
|
52
|
+
* discovered node is not the one a human just `cd`-ed into; that distinction must stay visible
|
|
53
|
+
* rather than silently answering from the wrong place.
|
|
54
|
+
*/
|
|
55
|
+
export function resolveDataDir(options = {}) {
|
|
56
|
+
const env = options.env ?? process.env;
|
|
57
|
+
const explicit = env.ABX_DATA_DIR;
|
|
58
|
+
if (explicit)
|
|
59
|
+
return { dir: resolve(explicit), source: 'env' };
|
|
60
|
+
const startCwd = resolve(options.cwd ?? process.cwd());
|
|
61
|
+
const cwdDir = resolve(startCwd, ABX_DATA_DIR_NAME);
|
|
62
|
+
if (!options.allowUpwardDiscovery || isDirectory(cwdDir)) {
|
|
63
|
+
return { dir: cwdDir, source: 'cwd' };
|
|
64
|
+
}
|
|
65
|
+
const home = resolve(options.home ?? homedir());
|
|
66
|
+
let dir = startCwd;
|
|
67
|
+
for (;;) {
|
|
68
|
+
if (dir !== startCwd) {
|
|
69
|
+
const candidate = resolve(dir, ABX_DATA_DIR_NAME);
|
|
70
|
+
if (isDirectory(candidate))
|
|
71
|
+
return { dir: candidate, source: 'discovered' };
|
|
72
|
+
}
|
|
73
|
+
if (dir === home || existsSync(join(dir, '.git')))
|
|
74
|
+
break; // boundary: checked, never crossed
|
|
75
|
+
const parent = dirname(dir);
|
|
76
|
+
if (parent === dir)
|
|
77
|
+
break; // filesystem root
|
|
78
|
+
dir = parent;
|
|
79
|
+
}
|
|
80
|
+
return { dir: cwdDir, source: 'cwd' };
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* The registry-dependency family's injected `inflate` (deps.ts: `resolveRegistryDep` /
|
|
84
|
+
* `dependencyScriptTags`), pre-wired for a Node host: `node:zlib`'s `gunzipSync`, one line. SDK
|
|
85
|
+
* core takes `inflate` as a parameter rather than importing `node:zlib` directly so it stays
|
|
86
|
+
* reachable from a browser bundle — a Node host (the token-api resolver, the CLI) passes this;
|
|
87
|
+
* a browser host passes a `DecompressionStream`-based implementation instead.
|
|
88
|
+
*/
|
|
89
|
+
export function nodeInflate(bytes) {
|
|
90
|
+
return new Uint8Array(gunzipSync(bytes));
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=node.js.map
|
package/dist/node.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.js","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAC,UAAU,EAAE,QAAQ,EAAC,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAC,OAAO,EAAC,MAAM,SAAS,CAAC;AAChC,OAAO,EAAC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAC,MAAM,WAAW,CAAC;AACjD,OAAO,EAAC,UAAU,EAAC,MAAM,WAAW,CAAC;AAErC,OAAO,EAAC,UAAU,EAAE,eAAe,EAAC,MAAM,UAAU,CAAC;AAErD;6FAC6F;AAC7F,MAAM,CAAC,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;AAgClD,SAAS,WAAW,CAAC,IAAY;IAC/B,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC,CAAC,2EAA2E;IAC3F,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,cAAc,CAAC,UAAiC,EAAE;IAChE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACvC,MAAM,QAAQ,GAAG,GAAG,CAAC,YAAY,CAAC;IAClC,IAAI,QAAQ;QAAE,OAAO,EAAC,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,EAAC,CAAC;IAE7D,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;IACpD,IAAI,CAAC,OAAO,CAAC,oBAAoB,IAAI,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;QACzD,OAAO,EAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAC,CAAC;IACtC,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI,OAAO,EAAE,CAAC,CAAC;IAChD,IAAI,GAAG,GAAG,QAAQ,CAAC;IACnB,SAAS,CAAC;QACR,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;YACrB,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;YAClD,IAAI,WAAW,CAAC,SAAS,CAAC;gBAAE,OAAO,EAAC,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAC,CAAC;QAC5E,CAAC;QACD,IAAI,GAAG,KAAK,IAAI,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAAE,MAAM,CAAC,mCAAmC;QAC7F,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM,CAAC,kBAAkB;QAC7C,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IACD,OAAO,EAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAC,CAAC;AACtC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,KAAiB;IAC3C,OAAO,IAAI,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;AAC3C,CAAC"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The on-chain tokenURI lane for code projects (`abx deploy-code --onchain-uri`) — pure leg
|
|
3
|
+
* composition + the verify-time honesty reads, all unit-testable with a mocked client.
|
|
4
|
+
*
|
|
5
|
+
* The lane (site/content/docs/protocol/code-projects.mdx → "The canonical generator — AbxGenerator" +
|
|
6
|
+
* site/content/docs/protocol/metadata.mdx → "URI resolution"): the collection-scope `animation_url`
|
|
7
|
+
* field points at the canonical generator via the `renderer` representation
|
|
8
|
+
* (`abi.encode(address)`), and the token's `tokenURIRenderer` toggles tokenURI to the canonical
|
|
9
|
+
* on-chain metadata renderer (`setContractURIRenderer` does the same for contractURI). Both ride
|
|
10
|
+
* the EXISTING setup multicall, before the mints.
|
|
11
|
+
*
|
|
12
|
+
* The param surface is NOT part of that wiring: params enumerate ON-CHAIN (`contractParamKeys` /
|
|
13
|
+
* `tokenParamKeys`, maintained by the write paths themselves), so the generator reads the key set
|
|
14
|
+
* straight from the token. The old `params.keys` CSV convention is retired — nothing writes it any
|
|
15
|
+
* more.
|
|
16
|
+
*/
|
|
17
|
+
import { type Address, type Hex } from 'viem';
|
|
18
|
+
import { type GeneratorReadClient, type GeneratorStatus } from './generator.js';
|
|
19
|
+
import { type DepCheck, type ParsedDependencyRef } from './deps.js';
|
|
20
|
+
import type { ProjectState } from './types.js';
|
|
21
|
+
/**
|
|
22
|
+
* The `--onchain-uri` legs of the setup multicall, in order:
|
|
23
|
+
* 1. collection-scope `animation_url` field → representation `renderer`,
|
|
24
|
+
* value `abi.encode(generator)` (the canonical generator computes the live view on-chain);
|
|
25
|
+
* 2. `setTokenURIRenderer(metadataRenderer)` — tokenURI resolves ON-CHAIN from here on;
|
|
26
|
+
* 3. `setContractURIRenderer(metadataRenderer)` — contractURI too (parity with the 1/1 lane).
|
|
27
|
+
* Placed BEFORE the mint legs so every token is born with the on-chain lane fully configured.
|
|
28
|
+
*
|
|
29
|
+
* There is no param leg: the generator enumerates the param surface from the token itself
|
|
30
|
+
* (`contractParamKeys` / `tokenParamKeys`), so there is nothing for a deploy to declare.
|
|
31
|
+
*/
|
|
32
|
+
export declare function onchainUriSetupCalls(args: {
|
|
33
|
+
generator: Address;
|
|
34
|
+
metadataRenderer: Address;
|
|
35
|
+
}): Hex[];
|
|
36
|
+
/** The SET param keys: `contractParamKeys()`, plus `tokenParamKeys(tokenId)` when a token is named.
|
|
37
|
+
* Null when the getters are absent — a LEGACY project deployed before enumeration shipped (or a
|
|
38
|
+
* token type with no Params extension at all). */
|
|
39
|
+
export declare function readSetParamKeys(client: GeneratorReadClient, contract: Address, tokenId?: bigint): Promise<{
|
|
40
|
+
contract: string[];
|
|
41
|
+
token: string[];
|
|
42
|
+
} | null>;
|
|
43
|
+
/** The DECLARED (governed) keys: `paramSchemaKeys()`, append-only — including keys declared but
|
|
44
|
+
* never yet written, which are otherwise undiscoverable. Null on a legacy project. */
|
|
45
|
+
export declare function readParamSchemaKeys(client: GeneratorReadClient, contract: Address): Promise<string[] | null>;
|
|
46
|
+
/** The project's three param-lifecycle hook addresses (`paramHooks()`), zeroes included — null on a
|
|
47
|
+
* project with no ConfigurableParams surface (a 1/1, a plain Series, an image edition).
|
|
48
|
+
*
|
|
49
|
+
* The `transferHook` in this trio is a **veto**: its revert fails the transfer, and a mint is a
|
|
50
|
+
* transfer from `0x0`, so a reverting hook stops minting too. Whether the trio can still change is
|
|
51
|
+
* a separate read — `readParamHooksLocked` (ops.ts), or the `ParamHooksFrozen` fold. */
|
|
52
|
+
export declare function readParamHooks(client: GeneratorReadClient, contract: Address): Promise<{
|
|
53
|
+
configureHook: Address;
|
|
54
|
+
augmentHook: Address;
|
|
55
|
+
transferHook: Address;
|
|
56
|
+
} | null>;
|
|
57
|
+
/** Does this token expose the enumeration surface at all? The one-call probe behind the repoint
|
|
58
|
+
* guard: the canonical generator reads params from chain, so pointing a token that lacks these
|
|
59
|
+
* getters at it makes every param silently invisible. */
|
|
60
|
+
export declare function hasParamEnumeration(client: GeneratorReadClient, contract: Address): Promise<boolean>;
|
|
61
|
+
/** What the deploy can honestly promise about the generator's template branch, derived from
|
|
62
|
+
* the selection-time dependency report (never a new RPC): chain-complete iff every registry
|
|
63
|
+
* dep has proven ON-CHAIN bytes (OnChain refs read their data contract directly, so they
|
|
64
|
+
* count as on-chain; `abx verify` is the from-chain confirmation either way). */
|
|
65
|
+
export declare function expectedChainComplete(deps: ParsedDependencyRef[], checks: DepCheck[]): {
|
|
66
|
+
expected: boolean | null;
|
|
67
|
+
detail: string;
|
|
68
|
+
};
|
|
69
|
+
/** The generator this project's on-chain lane actually uses: the collection `animation_url`
|
|
70
|
+
* field's `renderer` value when set (that address is what the metadata renderer staticcalls),
|
|
71
|
+
* else the chain's canonical generator. Null when neither exists. */
|
|
72
|
+
export declare function generatorFor(state: ProjectState, override?: string): Address | null;
|
|
73
|
+
/** Whether verify should run the on-chain-URI report: the tokenURIRenderer toggle is on, or
|
|
74
|
+
* the collection `animation` field points at a field renderer (the generator). */
|
|
75
|
+
export declare function hasOnChainUriLane(state: ProjectState): boolean;
|
|
76
|
+
export interface TokenUriProbe {
|
|
77
|
+
tokenId: string;
|
|
78
|
+
/** Which accessor was actually read — `tokenURI` on a 721, `uri` on an ERC-1155 edition. Readouts
|
|
79
|
+
* quote this so an edition is never described in 721 terms. */
|
|
80
|
+
accessor: 'tokenURI' | 'uri';
|
|
81
|
+
/** tokenURI(id)/uri(id) is a `data:application/json;base64,` URI (resolves on-chain, any RPC). */
|
|
82
|
+
onChainJson: boolean;
|
|
83
|
+
uriPrefix: string;
|
|
84
|
+
animation: {
|
|
85
|
+
form: 'data-html';
|
|
86
|
+
bytes: number;
|
|
87
|
+
marker: string | null;
|
|
88
|
+
} | {
|
|
89
|
+
form: 'url';
|
|
90
|
+
url: string;
|
|
91
|
+
} | {
|
|
92
|
+
form: 'data-other';
|
|
93
|
+
prefix: string;
|
|
94
|
+
} | {
|
|
95
|
+
form: 'missing';
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
export interface OnChainUriReport {
|
|
99
|
+
generator: Address;
|
|
100
|
+
status: GeneratorStatus;
|
|
101
|
+
/** Null when no token is minted yet (tokenURI would revert). */
|
|
102
|
+
probe: TokenUriProbe | null;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* The verify-time on-chain-URI report: `generator.onChainStatus(token)` (branch ·
|
|
106
|
+
* chain-completeness · unresolved refs · URL budget) plus a `tokenURI` probe of the lowest
|
|
107
|
+
* minted token — decoded, with the `animation_url` form checked against the branch.
|
|
108
|
+
*/
|
|
109
|
+
export declare function onChainUriReport(client: GeneratorReadClient, state: ProjectState, generatorOverride?: string): Promise<OnChainUriReport>;
|
|
110
|
+
//# sourceMappingURL=onchain-uri.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onchain-uri.d.ts","sourceRoot":"","sources":["../src/onchain-uri.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The on-chain tokenURI lane for code projects (`abx deploy-code --onchain-uri`) — pure leg
|
|
3
|
+
* composition + the verify-time honesty reads, all unit-testable with a mocked client.
|
|
4
|
+
*
|
|
5
|
+
* The lane (site/content/docs/protocol/code-projects.mdx → "The canonical generator — AbxGenerator" +
|
|
6
|
+
* site/content/docs/protocol/metadata.mdx → "URI resolution"): the collection-scope `animation_url`
|
|
7
|
+
* field points at the canonical generator via the `renderer` representation
|
|
8
|
+
* (`abi.encode(address)`), and the token's `tokenURIRenderer` toggles tokenURI to the canonical
|
|
9
|
+
* on-chain metadata renderer (`setContractURIRenderer` does the same for contractURI). Both ride
|
|
10
|
+
* the EXISTING setup multicall, before the mints.
|
|
11
|
+
*
|
|
12
|
+
* The param surface is NOT part of that wiring: params enumerate ON-CHAIN (`contractParamKeys` /
|
|
13
|
+
* `tokenParamKeys`, maintained by the write paths themselves), so the generator reads the key set
|
|
14
|
+
* straight from the token. The old `params.keys` CSV convention is retired — nothing writes it any
|
|
15
|
+
* more.
|
|
16
|
+
*/
|
|
17
|
+
import { encodeFunctionData, zeroAddress } from 'viem';
|
|
18
|
+
import { decodeTag, encodeTag, METADATA_FIELD as F, METADATA_REPRESENTATION as R } from './spine.js';
|
|
19
|
+
import { seriesCodeAbi } from './abi/index.js';
|
|
20
|
+
import { readGeneratorStatus } from './generator.js';
|
|
21
|
+
import { resolveGenerator } from './deployments.js';
|
|
22
|
+
import { decodeFieldRenderer, encodeFieldRenderer } from './token.js';
|
|
23
|
+
import { DEP_RESOLUTION } from './deps.js';
|
|
24
|
+
import { parseDataUri, base64ToBytes } from './util.js';
|
|
25
|
+
/**
|
|
26
|
+
* The `--onchain-uri` legs of the setup multicall, in order:
|
|
27
|
+
* 1. collection-scope `animation_url` field → representation `renderer`,
|
|
28
|
+
* value `abi.encode(generator)` (the canonical generator computes the live view on-chain);
|
|
29
|
+
* 2. `setTokenURIRenderer(metadataRenderer)` — tokenURI resolves ON-CHAIN from here on;
|
|
30
|
+
* 3. `setContractURIRenderer(metadataRenderer)` — contractURI too (parity with the 1/1 lane).
|
|
31
|
+
* Placed BEFORE the mint legs so every token is born with the on-chain lane fully configured.
|
|
32
|
+
*
|
|
33
|
+
* There is no param leg: the generator enumerates the param surface from the token itself
|
|
34
|
+
* (`contractParamKeys` / `tokenParamKeys`), so there is nothing for a deploy to declare.
|
|
35
|
+
*/
|
|
36
|
+
export function onchainUriSetupCalls(args) {
|
|
37
|
+
const calls = [];
|
|
38
|
+
// The `animation_url` leg points at the generator (which computes the doc from a PROGRAM). A
|
|
39
|
+
// renderer-only drop (in-chain SVG, no program) has no generator — and baking this leg at a ZERO
|
|
40
|
+
// generator would make the metadata renderer staticcall a codeless address and REVERT every
|
|
41
|
+
// tokenURI. So emit it only when there's a real generator; otherwise there's simply no animation_url
|
|
42
|
+
// (optional by spec — the metadata renderer omits an unset field).
|
|
43
|
+
if (args.generator !== zeroAddress) {
|
|
44
|
+
calls.push(encodeFunctionData({
|
|
45
|
+
abi: seriesCodeAbi,
|
|
46
|
+
functionName: 'setContractField',
|
|
47
|
+
args: [encodeTag(F.animationUrl), encodeTag(R.renderer), encodeFieldRenderer(args.generator)],
|
|
48
|
+
}));
|
|
49
|
+
}
|
|
50
|
+
calls.push(encodeFunctionData({ abi: seriesCodeAbi, functionName: 'setTokenURIRenderer', args: [args.metadataRenderer] }), encodeFunctionData({ abi: seriesCodeAbi, functionName: 'setContractURIRenderer', args: [args.metadataRenderer] }));
|
|
51
|
+
return calls;
|
|
52
|
+
}
|
|
53
|
+
// ── the param surface, enumerated FROM CHAIN ──────────────────────────────────
|
|
54
|
+
// `key ∈ list ⟺ the param isSet` — the contract maintains both key lists inside the write paths
|
|
55
|
+
// themselves, so nothing off-chain has to be kept in step. `seed` is deliberately never listed
|
|
56
|
+
// (every consumer reads it as a tokenData coordinate). Enumeration order is unspecified; the
|
|
57
|
+
// canonical serialization sorts.
|
|
58
|
+
/** The SET param keys: `contractParamKeys()`, plus `tokenParamKeys(tokenId)` when a token is named.
|
|
59
|
+
* Null when the getters are absent — a LEGACY project deployed before enumeration shipped (or a
|
|
60
|
+
* token type with no Params extension at all). */
|
|
61
|
+
export async function readSetParamKeys(client, contract, tokenId) {
|
|
62
|
+
try {
|
|
63
|
+
const contractKeys = (await client.readContract({
|
|
64
|
+
address: contract,
|
|
65
|
+
abi: seriesCodeAbi,
|
|
66
|
+
functionName: 'contractParamKeys',
|
|
67
|
+
args: [],
|
|
68
|
+
}));
|
|
69
|
+
const tokenKeys = tokenId === undefined
|
|
70
|
+
? []
|
|
71
|
+
: (await client.readContract({
|
|
72
|
+
address: contract,
|
|
73
|
+
abi: seriesCodeAbi,
|
|
74
|
+
functionName: 'tokenParamKeys',
|
|
75
|
+
args: [tokenId],
|
|
76
|
+
}));
|
|
77
|
+
return { contract: contractKeys.map(decodeTag), token: tokenKeys.map(decodeTag) };
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/** The DECLARED (governed) keys: `paramSchemaKeys()`, append-only — including keys declared but
|
|
84
|
+
* never yet written, which are otherwise undiscoverable. Null on a legacy project. */
|
|
85
|
+
export async function readParamSchemaKeys(client, contract) {
|
|
86
|
+
try {
|
|
87
|
+
const keys = (await client.readContract({
|
|
88
|
+
address: contract,
|
|
89
|
+
abi: seriesCodeAbi,
|
|
90
|
+
functionName: 'paramSchemaKeys',
|
|
91
|
+
args: [],
|
|
92
|
+
}));
|
|
93
|
+
return keys.map(decodeTag);
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/** The project's three param-lifecycle hook addresses (`paramHooks()`), zeroes included — null on a
|
|
100
|
+
* project with no ConfigurableParams surface (a 1/1, a plain Series, an image edition).
|
|
101
|
+
*
|
|
102
|
+
* The `transferHook` in this trio is a **veto**: its revert fails the transfer, and a mint is a
|
|
103
|
+
* transfer from `0x0`, so a reverting hook stops minting too. Whether the trio can still change is
|
|
104
|
+
* a separate read — `readParamHooksLocked` (ops.ts), or the `ParamHooksFrozen` fold. */
|
|
105
|
+
export async function readParamHooks(client, contract) {
|
|
106
|
+
try {
|
|
107
|
+
const [configureHook, augmentHook, transferHook] = (await client.readContract({
|
|
108
|
+
address: contract,
|
|
109
|
+
abi: seriesCodeAbi,
|
|
110
|
+
functionName: 'paramHooks',
|
|
111
|
+
args: [],
|
|
112
|
+
}));
|
|
113
|
+
return { configureHook, augmentHook, transferHook };
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/** Does this token expose the enumeration surface at all? The one-call probe behind the repoint
|
|
120
|
+
* guard: the canonical generator reads params from chain, so pointing a token that lacks these
|
|
121
|
+
* getters at it makes every param silently invisible. */
|
|
122
|
+
export async function hasParamEnumeration(client, contract) {
|
|
123
|
+
try {
|
|
124
|
+
await client.readContract({ address: contract, abi: seriesCodeAbi, functionName: 'tokenParamKeys', args: [0n] });
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// ── the chain-complete expectation (deploy-time, from the P1 dependency report) ──
|
|
132
|
+
/** What the deploy can honestly promise about the generator's template branch, derived from
|
|
133
|
+
* the selection-time dependency report (never a new RPC): chain-complete iff every registry
|
|
134
|
+
* dep has proven ON-CHAIN bytes (OnChain refs read their data contract directly, so they
|
|
135
|
+
* count as on-chain; `abx verify` is the from-chain confirmation either way). */
|
|
136
|
+
export function expectedChainComplete(deps, checks) {
|
|
137
|
+
if (deps.length === 0)
|
|
138
|
+
return { expected: true, detail: 'no dependencies — the document assembles from the script chunks alone' };
|
|
139
|
+
const registryDeps = deps.filter((d) => d.resolution === DEP_RESOLUTION.registry);
|
|
140
|
+
if (registryDeps.length === 0) {
|
|
141
|
+
return { expected: true, detail: 'all dependencies are on-chain data contracts (read directly)' };
|
|
142
|
+
}
|
|
143
|
+
const byDep = new Map(checks.map((c) => [c.dep, c]));
|
|
144
|
+
const cdnOnly = [];
|
|
145
|
+
const missing = [];
|
|
146
|
+
let unknown = false;
|
|
147
|
+
for (const d of registryDeps) {
|
|
148
|
+
const chk = byDep.get(d.display);
|
|
149
|
+
if (!chk || chk.status === 'skipped')
|
|
150
|
+
unknown = true;
|
|
151
|
+
else if (chk.status === 'not-found')
|
|
152
|
+
missing.push(d.display);
|
|
153
|
+
else if (!chk.details.availableOnChain)
|
|
154
|
+
cdnOnly.push(d.display);
|
|
155
|
+
}
|
|
156
|
+
if (missing.length)
|
|
157
|
+
return { expected: false, detail: `${missing.join(', ')} not on the registry — the generator will emit an unresolved marker` };
|
|
158
|
+
if (cdnOnly.length)
|
|
159
|
+
return { expected: false, detail: `${cdnOnly.join(', ')} CDN-served (the normal production path) — serves fine, NOT chain-complete` };
|
|
160
|
+
if (unknown)
|
|
161
|
+
return { expected: null, detail: 'registry check was skipped (RPC unreachable) — `abx verify` reads the truth from chain' };
|
|
162
|
+
return { expected: true, detail: 'every dependency has ON-CHAIN bytes — no server, gateway, or CDN in the graph' };
|
|
163
|
+
}
|
|
164
|
+
// ── verify: the honesty reads (`onChainStatus` + a tokenURI probe) ─────────────
|
|
165
|
+
/** The generator this project's on-chain lane actually uses: the collection `animation_url`
|
|
166
|
+
* field's `renderer` value when set (that address is what the metadata renderer staticcalls),
|
|
167
|
+
* else the chain's canonical generator. Null when neither exists. */
|
|
168
|
+
export function generatorFor(state, override) {
|
|
169
|
+
const field = state.collectionFields.find((f) => f.field === F.animationUrl && f.representation === R.renderer);
|
|
170
|
+
if (field) {
|
|
171
|
+
try {
|
|
172
|
+
return decodeFieldRenderer(field.value);
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
/* malformed value — fall through to the manifest */
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return resolveGenerator(state.chainId, override) ?? null;
|
|
179
|
+
}
|
|
180
|
+
/** Whether verify should run the on-chain-URI report: the tokenURIRenderer toggle is on, or
|
|
181
|
+
* the collection `animation` field points at a field renderer (the generator). */
|
|
182
|
+
export function hasOnChainUriLane(state) {
|
|
183
|
+
const rendererSet = !!state.tokenURIRenderer && state.tokenURIRenderer !== zeroAddress;
|
|
184
|
+
const animationRenderer = state.collectionFields.some((f) => f.field === F.animationUrl && f.representation === R.renderer);
|
|
185
|
+
return rendererSet || animationRenderer;
|
|
186
|
+
}
|
|
187
|
+
const erc721TokenUriAbi = [
|
|
188
|
+
{
|
|
189
|
+
type: 'function',
|
|
190
|
+
name: 'tokenURI',
|
|
191
|
+
stateMutability: 'view',
|
|
192
|
+
inputs: [{ name: 'id', type: 'uint256' }],
|
|
193
|
+
outputs: [{ name: '', type: 'string' }],
|
|
194
|
+
},
|
|
195
|
+
];
|
|
196
|
+
/** The three ERC-1155 members of the `contractType` ladder — the ones that expose `uri(id)` instead
|
|
197
|
+
* of `tokenURI(id)`. Kept as a set so adding a token family is one edit, not a string-shape guess. */
|
|
198
|
+
const EDITION_CONTRACT_TYPES = new Set(['1of1-edition', 'edition', 'edition-code']);
|
|
199
|
+
/** The 1155 twin of the probe above. An edition exposes `uri(id)`, NOT `tokenURI(id)` — probing a
|
|
200
|
+
* 721 selector on an edition reverts, which surfaced as `verify` reporting "on-chain URI check
|
|
201
|
+
* unavailable" (plus a raw viem dump) for EVERY edition. Mirrors `reconstruct.ts`'s uriAbi/uriFn. */
|
|
202
|
+
const erc1155UriAbi = [
|
|
203
|
+
{
|
|
204
|
+
type: 'function',
|
|
205
|
+
name: 'uri',
|
|
206
|
+
stateMutability: 'view',
|
|
207
|
+
inputs: [{ name: 'id', type: 'uint256' }],
|
|
208
|
+
outputs: [{ name: '', type: 'string' }],
|
|
209
|
+
},
|
|
210
|
+
];
|
|
211
|
+
/** An HTML comment marker the generator emits on degradation (`<!-- abx:… -->`), or null. */
|
|
212
|
+
function degradationMarker(html) {
|
|
213
|
+
const m = /<!--\s*abx:[^>]*-->/.exec(html);
|
|
214
|
+
return m ? m[0] : null;
|
|
215
|
+
}
|
|
216
|
+
function probeAnimation(animationUrl) {
|
|
217
|
+
if (!animationUrl)
|
|
218
|
+
return { form: 'missing' };
|
|
219
|
+
const parsed = parseDataUri(animationUrl);
|
|
220
|
+
if (parsed && parsed.mime === 'text/html' && parsed.base64) {
|
|
221
|
+
const bytes = base64ToBytes(parsed.body);
|
|
222
|
+
const html = new TextDecoder().decode(bytes);
|
|
223
|
+
return { form: 'data-html', bytes: bytes.length, marker: degradationMarker(html) };
|
|
224
|
+
}
|
|
225
|
+
if (animationUrl.startsWith('data:'))
|
|
226
|
+
return { form: 'data-other', prefix: animationUrl.slice(0, 40) };
|
|
227
|
+
return { form: 'url', url: animationUrl };
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* The verify-time on-chain-URI report: `generator.onChainStatus(token)` (branch ·
|
|
231
|
+
* chain-completeness · unresolved refs · URL budget) plus a `tokenURI` probe of the lowest
|
|
232
|
+
* minted token — decoded, with the `animation_url` form checked against the branch.
|
|
233
|
+
*/
|
|
234
|
+
export async function onChainUriReport(client, state, generatorOverride) {
|
|
235
|
+
const generator = generatorFor(state, generatorOverride);
|
|
236
|
+
if (!generator) {
|
|
237
|
+
throw new Error(`no AbxGenerator known for chain ${state.chainId} — set ABX_GENERATOR=0x… (or update @artblocks/abx-sdk's deployments manifest)`);
|
|
238
|
+
}
|
|
239
|
+
const status = await readGeneratorStatus(client, generator, state.address);
|
|
240
|
+
// LIVE tokens only, and the reason is sharper than tidiness: this probe reads the LOWEST id it
|
|
241
|
+
// finds, and `tokenURI` reverts `NonexistentToken` for a burned one. Burned ids must not make the
|
|
242
|
+
// collection's on-chain-URI lane report as broken.
|
|
243
|
+
const minted = state.tokens.filter((t) => t.lifecycle === 'live').map((t) => BigInt(t.tokenId));
|
|
244
|
+
let probe = null;
|
|
245
|
+
if (minted.length) {
|
|
246
|
+
const tokenId = minted.reduce((a, b) => (b < a ? b : a));
|
|
247
|
+
const isEdition = EDITION_CONTRACT_TYPES.has(state.contractType ?? '');
|
|
248
|
+
const uri = (await client.readContract({
|
|
249
|
+
address: state.address,
|
|
250
|
+
abi: isEdition ? erc1155UriAbi : erc721TokenUriAbi,
|
|
251
|
+
functionName: isEdition ? 'uri' : 'tokenURI',
|
|
252
|
+
args: [tokenId],
|
|
253
|
+
}));
|
|
254
|
+
const parsed = parseDataUri(uri);
|
|
255
|
+
const isOnChainJson = !!parsed && parsed.mime === 'application/json' && parsed.base64;
|
|
256
|
+
let animation = { form: 'missing' };
|
|
257
|
+
if (parsed && isOnChainJson) {
|
|
258
|
+
try {
|
|
259
|
+
const json = JSON.parse(new TextDecoder().decode(base64ToBytes(parsed.body)));
|
|
260
|
+
animation = probeAnimation(typeof json.animation_url === 'string' ? json.animation_url : undefined);
|
|
261
|
+
}
|
|
262
|
+
catch {
|
|
263
|
+
/* undecodable JSON — reported as onChainJson with a missing animation */
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
probe = {
|
|
267
|
+
tokenId: tokenId.toString(),
|
|
268
|
+
accessor: isEdition ? 'uri' : 'tokenURI',
|
|
269
|
+
onChainJson: isOnChainJson,
|
|
270
|
+
uriPrefix: uri.slice(0, 48),
|
|
271
|
+
animation,
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
return { generator, status, probe };
|
|
275
|
+
}
|
|
276
|
+
//# sourceMappingURL=onchain-uri.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onchain-uri.js","sourceRoot":"","sources":["../src/onchain-uri.ts"],"names":[],"mappings":"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"}
|