@artblocks/abx-cli 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 +161 -0
- package/assets/renderer-scaffold/README.md +41 -11
- package/assets/renderer-scaffold/foundry.toml +5 -0
- package/assets/renderer-scaffold/remappings.txt +1 -1
- package/assets/renderer-scaffold/script/DeployHooks.s.sol +24 -0
- package/assets/renderer-scaffold/script/Preview.s.sol +99 -0
- package/assets/renderer-scaffold/src/MyHooks.sol +20 -0
- package/assets/renderer-scaffold/src/MyRenderer.sol +4 -4
- package/assets/renderer-scaffold/src/MyTraits.sol +2 -2
- package/assets/renderer-scaffold/test/MyRenderer.t.sol +60 -3
- package/dist/bin.d.ts +26 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +63 -0
- package/dist/bin.js.map +1 -0
- package/dist/capabilities.d.ts +99 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +144 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/commands/auth.d.ts +54 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +447 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/deploy.d.ts +242 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +5429 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/feedback.d.ts +7 -0
- package/dist/commands/feedback.d.ts.map +1 -0
- package/dist/commands/feedback.js +147 -0
- package/dist/commands/feedback.js.map +1 -0
- package/dist/commands/maintenance.d.ts +4 -0
- package/dist/commands/maintenance.d.ts.map +1 -0
- package/dist/commands/maintenance.js +114 -0
- package/dist/commands/maintenance.js.map +1 -0
- package/dist/commands/project.d.ts +429 -0
- package/dist/commands/project.d.ts.map +1 -0
- package/dist/commands/project.js +1720 -0
- package/dist/commands/project.js.map +1 -0
- package/dist/commands/reads.d.ts +85 -0
- package/dist/commands/reads.d.ts.map +1 -0
- package/dist/commands/reads.js +868 -0
- package/dist/commands/reads.js.map +1 -0
- package/dist/commands/scaffold.d.ts +89 -0
- package/dist/commands/scaffold.d.ts.map +1 -0
- package/dist/commands/scaffold.js +738 -0
- package/dist/commands/scaffold.js.map +1 -0
- package/dist/commands/service.d.ts +67 -0
- package/dist/commands/service.d.ts.map +1 -0
- package/dist/commands/service.js +748 -0
- package/dist/commands/service.js.map +1 -0
- package/dist/commands/storage.d.ts +51 -0
- package/dist/commands/storage.d.ts.map +1 -0
- package/dist/commands/storage.js +399 -0
- package/dist/commands/storage.js.map +1 -0
- package/dist/commands/submit-app.d.ts +102 -0
- package/dist/commands/submit-app.d.ts.map +1 -0
- package/dist/commands/submit-app.js +622 -0
- package/dist/commands/submit-app.js.map +1 -0
- package/dist/config.d.ts +105 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +351 -12
- package/dist/config.js.map +1 -1
- package/dist/conformance.d.ts +31 -0
- package/dist/conformance.d.ts.map +1 -0
- package/dist/conformance.js +390 -0
- package/dist/conformance.js.map +1 -0
- package/dist/contract-read-error.d.ts +5 -0
- package/dist/contract-read-error.d.ts.map +1 -0
- package/dist/contract-read-error.js +37 -0
- package/dist/contract-read-error.js.map +1 -0
- package/dist/deploy-plan.d.ts +150 -0
- package/dist/deploy-plan.d.ts.map +1 -0
- package/dist/deploy-plan.js +31 -0
- package/dist/deploy-plan.js.map +1 -0
- package/dist/deps.d.ts +6 -39
- package/dist/deps.d.ts.map +1 -1
- package/dist/deps.js +4 -68
- package/dist/deps.js.map +1 -1
- package/dist/errors.d.ts +20 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +25 -0
- package/dist/errors.js.map +1 -0
- package/dist/flag-allowlists.d.ts +53 -0
- package/dist/flag-allowlists.d.ts.map +1 -0
- package/dist/flag-allowlists.js +184 -0
- package/dist/flag-allowlists.js.map +1 -0
- package/dist/flags.d.ts +47 -0
- package/dist/flags.d.ts.map +1 -1
- package/dist/flags.js +125 -1
- package/dist/flags.js.map +1 -1
- package/dist/jsonout.d.ts +37 -0
- package/dist/jsonout.d.ts.map +1 -0
- package/dist/jsonout.js +79 -0
- package/dist/jsonout.js.map +1 -0
- package/dist/kind.d.ts +57 -0
- package/dist/kind.d.ts.map +1 -0
- package/dist/kind.js +122 -0
- package/dist/kind.js.map +1 -0
- package/dist/main.js +786 -4838
- package/dist/main.js.map +1 -1
- package/dist/mintpage.d.ts +17 -2
- package/dist/mintpage.d.ts.map +1 -1
- package/dist/mintpage.js +241 -54
- package/dist/mintpage.js.map +1 -1
- package/dist/output.d.ts +179 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +780 -0
- package/dist/output.js.map +1 -0
- package/dist/ownerops.d.ts +381 -57
- package/dist/ownerops.d.ts.map +1 -1
- package/dist/ownerops.js +2014 -359
- package/dist/ownerops.js.map +1 -1
- package/dist/preview.d.ts +23 -5
- package/dist/preview.d.ts.map +1 -1
- package/dist/preview.js +95 -43
- package/dist/preview.js.map +1 -1
- package/dist/prompt.d.ts +17 -0
- package/dist/prompt.d.ts.map +1 -0
- package/dist/prompt.js +19 -0
- package/dist/prompt.js.map +1 -0
- package/dist/provision.d.ts +3 -13
- package/dist/provision.d.ts.map +1 -1
- package/dist/provision.js +19 -21
- package/dist/provision.js.map +1 -1
- package/dist/remote.d.ts +157 -52
- package/dist/remote.d.ts.map +1 -1
- package/dist/remote.js +435 -46
- package/dist/remote.js.map +1 -1
- package/dist/riskgate.d.ts +62 -0
- package/dist/riskgate.d.ts.map +1 -0
- package/dist/riskgate.js +234 -0
- package/dist/riskgate.js.map +1 -0
- package/dist/scaffold.d.ts +12 -0
- package/dist/scaffold.d.ts.map +1 -0
- package/dist/scaffold.js +56 -0
- package/dist/scaffold.js.map +1 -0
- package/dist/schema.d.ts +36 -1
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +121 -26
- package/dist/schema.js.map +1 -1
- package/dist/script-chunks.d.ts +8 -0
- package/dist/script-chunks.d.ts.map +1 -0
- package/dist/script-chunks.js +35 -0
- package/dist/script-chunks.js.map +1 -0
- package/dist/served.d.ts +30 -0
- package/dist/served.d.ts.map +1 -0
- package/dist/served.js +112 -0
- package/dist/served.js.map +1 -0
- package/dist/signer.d.ts +13 -0
- package/dist/signer.d.ts.map +1 -1
- package/dist/signer.js +84 -15
- package/dist/signer.js.map +1 -1
- package/dist/update-check.d.ts +86 -5
- package/dist/update-check.d.ts.map +1 -1
- package/dist/update-check.js +161 -20
- package/dist/update-check.js.map +1 -1
- package/package.json +13 -12
- package/skill/SKILL.md +181 -347
- package/skill/agents/openai.yaml +4 -0
- package/skill/reference/capabilities.md +188 -0
- package/skill/reference/code.md +220 -0
- package/skill/reference/creator-token.md +94 -0
- package/skill/reference/deploy.md +174 -0
- package/skill/reference/diagnose.md +178 -0
- package/skill/reference/hosting.md +186 -93
- package/skill/reference/operate.md +220 -0
- package/skill/reference/services.md +121 -0
- package/skill/reference/setup.md +154 -36
- package/assets/renderer-scaffold/src/interfaces/IAbxFieldRenderer.sol +0 -32
- package/assets/renderer-scaffold/src/interfaces/IAbxParams.sol +0 -26
- package/dist/inspect.d.ts +0 -48
- package/dist/inspect.d.ts.map +0 -1
- package/dist/inspect.js +0 -184
- package/dist/inspect.js.map +0 -1
- package/dist/migrate.d.ts +0 -65
- package/dist/migrate.d.ts.map +0 -1
- package/dist/migrate.js +0 -180
- package/dist/migrate.js.map +0 -1
- package/dist/onchain-uri.d.ts +0 -97
- package/dist/onchain-uri.d.ts.map +0 -1
- package/dist/onchain-uri.js +0 -243
- package/dist/onchain-uri.js.map +0 -1
- package/dist/upload.d.ts +0 -28
- package/dist/upload.d.ts.map +0 -1
- package/dist/upload.js +0 -41
- package/dist/upload.js.map +0 -1
- package/skill/reference/code-projects.md +0 -246
- package/skill/reference/operating.md +0 -116
- package/skill/reference/troubleshooting.md +0 -28
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remote-service conformance — the assertion set behind `abx remote <name|url> --conformance`
|
|
3
|
+
* (see `commands/service.ts`'s `cmdRemoteConformance`). A third party can self-certify a hosted
|
|
4
|
+
* resolver against the published CLI with no repository checkout.
|
|
5
|
+
*
|
|
6
|
+
* `scripts/e2e-remote-resolver.sh` runs the CLI command against the reference container and greps
|
|
7
|
+
* stdout for the literal `✓ conformant`. Keep {@link verdictLine} and
|
|
8
|
+
* {@link formatAssertion}'s prefixes stable.
|
|
9
|
+
*
|
|
10
|
+
* Dogfoods the SDK's `AbxServiceClient` — the same client the CLI drives against a remote resolver
|
|
11
|
+
* — so passing here means the real tooling interoperates with the target service, per
|
|
12
|
+
* `site/content/docs/using-abx/remote-services.mdx`.
|
|
13
|
+
*
|
|
14
|
+
* Tiers (each unlocks with the inputs given — a bare URL with no token still runs the always-tier,
|
|
15
|
+
* which is enough to self-certify the public surface with zero setup):
|
|
16
|
+
* always descriptor served + required fields; unauthenticated write refused; the
|
|
17
|
+
* read-plane's error taxonomy; every DECLARED interface's routes exist
|
|
18
|
+
* token authed GET /v1/projects; the artifact registry refuses bound/referenced
|
|
19
|
+
* output mismatches
|
|
20
|
+
* token + address the full write loop: register → (poll to live) → status → reindex →
|
|
21
|
+
* + chainId deregister. Needs a contract the service can actually replay, so point it
|
|
22
|
+
* at one you own — this is the one tier that persists (then removes) state
|
|
23
|
+
* on the target, which is why it stays opt-in behind BOTH flags together (a
|
|
24
|
+
* token alone is not enough to reach it).
|
|
25
|
+
*
|
|
26
|
+
* A 403 anywhere in the loop reports as legitimate provider scoping (the token isn't authorized for
|
|
27
|
+
* that contract), never a conformance failure.
|
|
28
|
+
*/
|
|
29
|
+
import { AbxServiceClient, AbxServiceError, CONTROL_PLANE_INTERFACE, TOKEN_API_INTERFACE } from '@artblocks/abx-sdk';
|
|
30
|
+
const ZERO_ADDRESS = '0x' + '0'.repeat(40);
|
|
31
|
+
// Every lifecycle-bearing status field (register/status responses) must be one of these five words.
|
|
32
|
+
const LIFECYCLE = ['queued', 'backfilling', 'live', 'stale', 'failed'];
|
|
33
|
+
/** One ✓/✗/· line. Nested sub-bullets carry their own leading spaces in `message` (unchanged from
|
|
34
|
+
* the original script), so the indentation is intentional, not a formatting bug. */
|
|
35
|
+
export function formatAssertion(a) {
|
|
36
|
+
const prefix = a.status === 'pass' ? '✓' : a.status === 'fail' ? '✗' : '·';
|
|
37
|
+
return ` ${prefix} ${a.message}`;
|
|
38
|
+
}
|
|
39
|
+
/** The final line — kept byte-stable: `scripts/e2e-remote-resolver.sh` greps for '✓ conformant'. */
|
|
40
|
+
export function verdictLine(report) {
|
|
41
|
+
return report.failures ? `\n✗ ${report.failures} conformance failure(s)\n` : '\n✓ conformant\n';
|
|
42
|
+
}
|
|
43
|
+
export async function runConformance(opts) {
|
|
44
|
+
const base = opts.baseUrl.replace(/\/+$/, '');
|
|
45
|
+
const assertions = [];
|
|
46
|
+
const pass = (message) => assertions.push({ status: 'pass', message });
|
|
47
|
+
const failed = (message) => assertions.push({ status: 'fail', message });
|
|
48
|
+
const note = (message) => assertions.push({ status: 'note', message });
|
|
49
|
+
const scoped = (err) => err instanceof AbxServiceError && err.status === 403;
|
|
50
|
+
const probeAddr = opts.address ?? ZERO_ADDRESS;
|
|
51
|
+
const readJson = async (path) => {
|
|
52
|
+
try {
|
|
53
|
+
const res = await fetch(base + path);
|
|
54
|
+
return { status: res.status, body: (await res.json().catch(() => ({}))) };
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
return { networkError: err };
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
// ── tier 0: the descriptor ────────────────────────────────────────────────────
|
|
61
|
+
const anon = new AbxServiceClient({ baseUrl: base });
|
|
62
|
+
let descriptor = null;
|
|
63
|
+
try {
|
|
64
|
+
descriptor = await anon.descriptor();
|
|
65
|
+
pass('GET /.well-known/abx-service serves JSON');
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
failed(`no service descriptor: ${err.message}`);
|
|
69
|
+
}
|
|
70
|
+
if (descriptor) {
|
|
71
|
+
Array.isArray(descriptor.interfaces) && descriptor.interfaces.length
|
|
72
|
+
? pass(`interfaces declared: ${descriptor.interfaces.join(' · ')}`)
|
|
73
|
+
: failed('descriptor.interfaces missing/empty (required)');
|
|
74
|
+
Array.isArray(descriptor.chains) && descriptor.chains.length
|
|
75
|
+
? pass(`chains declared: ${descriptor.chains.join(', ')}`)
|
|
76
|
+
: failed('descriptor.chains missing/empty (required)');
|
|
77
|
+
if (opts.chainId !== undefined) {
|
|
78
|
+
descriptor.chains?.includes(opts.chainId)
|
|
79
|
+
? pass(`serves chain ${opts.chainId}`)
|
|
80
|
+
: failed(`descriptor.chains does not include ${opts.chainId} — registrations for it should be refused`);
|
|
81
|
+
}
|
|
82
|
+
const controlPlane = descriptor.interfaces?.includes(CONTROL_PLANE_INTERFACE);
|
|
83
|
+
if (controlPlane) {
|
|
84
|
+
descriptor.auth?.scheme === 'bearer'
|
|
85
|
+
? pass('auth.scheme is "bearer"')
|
|
86
|
+
: failed(`control plane declared but auth.scheme is ${JSON.stringify(descriptor.auth?.scheme)} (must be "bearer")`);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
note(`control plane not declared (${CONTROL_PLANE_INTERFACE} absent) — register/list tiers will report accordingly`);
|
|
90
|
+
}
|
|
91
|
+
if (!descriptor.interfaces?.includes(TOKEN_API_INTERFACE))
|
|
92
|
+
note(`descriptor does not declare ${TOKEN_API_INTERFACE} — is this a resolver?`);
|
|
93
|
+
if (descriptor.render?.attached) {
|
|
94
|
+
note(`rendering is managed behind this service (effects: ${descriptor.render.effects ? descriptor.render.effects.map((e) => e.key).join(', ') : 'unverified'})`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// ── tier 0: unauthenticated writes must be refused ────────────────────────────
|
|
98
|
+
const chainForProbe = opts.chainId ?? descriptor?.chains?.[0] ?? 1;
|
|
99
|
+
try {
|
|
100
|
+
await anon.registerProject({ chainId: chainForProbe, address: probeAddr });
|
|
101
|
+
failed('unauthenticated POST /v1/projects was ACCEPTED — the control plane must require a bearer token');
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
if (err instanceof AbxServiceError && err.status === 401)
|
|
105
|
+
pass('unauthenticated register → 401');
|
|
106
|
+
else if (err instanceof AbxServiceError && err.code === 'disabled')
|
|
107
|
+
pass('control plane disabled on this node (404 code "disabled") — honest, conformant');
|
|
108
|
+
else if (err instanceof AbxServiceError)
|
|
109
|
+
failed(`unauthenticated register → ${err.status} ${err.code ?? ''} (expected 401, or 404 code "disabled")`);
|
|
110
|
+
else
|
|
111
|
+
failed(`unauthenticated register probe errored: ${err.message}`);
|
|
112
|
+
}
|
|
113
|
+
// ── tier 0: the read plane's error taxonomy ───────────────────────────────────
|
|
114
|
+
// "No metadata came back" has three distinct causes, and a service that answers a bare 404 to all
|
|
115
|
+
// of them is a trap: a client that hand-built a URL reads its own mistake as a provider outage and
|
|
116
|
+
// files a bug against a working service. Each cause MUST be distinguishable by a machine `code` —
|
|
117
|
+
// remote-services.md → "Three ways a read can miss".
|
|
118
|
+
{
|
|
119
|
+
// (a) a real route with the wrong shape — the observed mistake is dropping the tokenId off
|
|
120
|
+
// /t/{chainId}/{address}/{tokenId} while reaching for collection metadata.
|
|
121
|
+
const shape = await readJson(`/t/${chainForProbe}/${probeAddr}`);
|
|
122
|
+
if (shape.networkError)
|
|
123
|
+
failed(`read-plane probe unreachable: ${shape.networkError.message}`);
|
|
124
|
+
else if (shape.status === 400 && shape.body?.code === 'invalid_request') {
|
|
125
|
+
pass('malformed token path → 400 invalid_request (not a bare 404)');
|
|
126
|
+
/\/c\//.test(shape.body?.error ?? '') || shape.body?.didYouMean
|
|
127
|
+
? pass(' …and it points at /c/{chainId}/{address} for collection metadata')
|
|
128
|
+
: note(' the 400 does not mention /c/{chainId}/{address} — SHOULD name the route that serves what the caller wanted');
|
|
129
|
+
}
|
|
130
|
+
else if (shape.status === 404) {
|
|
131
|
+
failed(`malformed token path /t/${chainForProbe}/${probeAddr} → bare 404 ${JSON.stringify(shape.body?.code ?? null)} — ` +
|
|
132
|
+
'MUST be 400 invalid_request naming the correct template; a 404 here is indistinguishable from "not indexed" and reads as an outage');
|
|
133
|
+
}
|
|
134
|
+
else
|
|
135
|
+
failed(`malformed token path → ${shape.status} ${shape.body?.code ?? ''} (expected 400 invalid_request)`);
|
|
136
|
+
// (b) no such route on this node at all
|
|
137
|
+
const unknown = await readJson('/abx-conformance-no-such-route');
|
|
138
|
+
if (unknown.status === 404 && unknown.body?.code === 'unknown_route')
|
|
139
|
+
pass('unknown path → 404 unknown_route');
|
|
140
|
+
else if (unknown.status === 404)
|
|
141
|
+
failed(`unknown path → 404 with code ${JSON.stringify(unknown.body?.code ?? null)} (expected "unknown_route")`);
|
|
142
|
+
else if (!unknown.networkError)
|
|
143
|
+
note(`unknown path → ${unknown.status} (expected 404 unknown_route)`);
|
|
144
|
+
// (c) well-formed, right chain, contract not indexed here — the ONLY one of the three that is
|
|
145
|
+
// about the project. Skipped when --address names a contract the service may actually serve.
|
|
146
|
+
if (!opts.address) {
|
|
147
|
+
const missing = await readJson(`/c/${chainForProbe}/${probeAddr}`);
|
|
148
|
+
if (missing.status === 404 && missing.body?.code === 'not_registered')
|
|
149
|
+
pass('well-formed path, unindexed contract → 404 not_registered');
|
|
150
|
+
else if (missing.status === 404)
|
|
151
|
+
failed(`unindexed contract → 404 with code ${JSON.stringify(missing.body?.code ?? null)} (expected "not_registered")`);
|
|
152
|
+
else if (!missing.networkError)
|
|
153
|
+
note(`unindexed contract probe → ${missing.status} (expected 404 not_registered)`);
|
|
154
|
+
}
|
|
155
|
+
// (d) a chain this node doesn't serve — a request error, and the body says what IS served.
|
|
156
|
+
const wrongChain = await readJson(`/t/999999999/${probeAddr}/0`);
|
|
157
|
+
if (wrongChain.body?.code === 'unsupported_chain') {
|
|
158
|
+
pass(`wrong chain → ${wrongChain.status} unsupported_chain`);
|
|
159
|
+
Array.isArray(wrongChain.body?.chains)
|
|
160
|
+
? pass(` …and carries the chains it does serve: ${wrongChain.body?.chains?.join(', ')}`)
|
|
161
|
+
: note(' the unsupported_chain body omits `chains` — SHOULD carry the chain ids this node serves');
|
|
162
|
+
}
|
|
163
|
+
else if (!wrongChain.networkError) {
|
|
164
|
+
failed(`wrong chain → ${wrongChain.status} ${JSON.stringify(wrongChain.body?.code ?? null)} (expected code "unsupported_chain")`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// ── tier 0: a declared interface means EVERY route it names answers ────────────
|
|
168
|
+
// The interface ids are all-or-nothing. One provider declared `abx-token-api/v1` while `/verify`
|
|
169
|
+
// had never been implemented, and nothing on either side caught it: the route answered a bare 404,
|
|
170
|
+
// which reads to a client as "this service is broken". Omitting an interface is the honest way to
|
|
171
|
+
// express partial support — declaring one and serving a subset is not.
|
|
172
|
+
//
|
|
173
|
+
// The assertion is deliberately narrow: a declared route may legitimately answer 404 `not_registered`
|
|
174
|
+
// (nothing indexed there) or 400 `invalid_request`. What it must NOT answer is `unknown_route` or a
|
|
175
|
+
// code-less 404 — those say the route itself doesn't exist.
|
|
176
|
+
if (descriptor?.interfaces?.includes(TOKEN_API_INTERFACE)) {
|
|
177
|
+
const routes = [
|
|
178
|
+
[`/t/${chainForProbe}/${probeAddr}/0`, 'token metadata'],
|
|
179
|
+
[`/t/${chainForProbe}/${probeAddr}/0/image`, 'token image'],
|
|
180
|
+
[`/c/${chainForProbe}/${probeAddr}`, 'collection metadata'],
|
|
181
|
+
[`/api/project/${chainForProbe}/${probeAddr}`, 'project state'],
|
|
182
|
+
[`/api/project/${chainForProbe}/${probeAddr}/verify`, 'verify'],
|
|
183
|
+
];
|
|
184
|
+
for (const [path, what] of routes) {
|
|
185
|
+
const r = await readJson(path);
|
|
186
|
+
if (r.networkError) {
|
|
187
|
+
failed(`${what} (${path}) unreachable: ${r.networkError.message}`);
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
// A `410 burned` is conformant, not a miss: the route exists and answered honestly about a
|
|
191
|
+
// destroyed token (`remote-services.md` → the read-miss table). Only a 404 that says the ROUTE
|
|
192
|
+
// is unknown fails here.
|
|
193
|
+
if (r.status === 404 && (r.body?.code === 'unknown_route' || r.body?.code === undefined)) {
|
|
194
|
+
failed(`${what} (${path}) → 404 ${r.body?.code ?? '(no code)'} — but this service declares ${TOKEN_API_INTERFACE}, ` +
|
|
195
|
+
`which names that route. Implement it, or stop declaring the interface.`);
|
|
196
|
+
}
|
|
197
|
+
else
|
|
198
|
+
pass(`${what} route exists (${r.status}${r.body?.code ? ` ${r.body.code}` : ''})`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
// ── tier 1: an authed token ───────────────────────────────────────────────────
|
|
202
|
+
if (!opts.token) {
|
|
203
|
+
note('no token — skipping the authed tiers');
|
|
204
|
+
return { baseUrl: base, assertions, failures: assertions.filter((a) => a.status === 'fail').length };
|
|
205
|
+
}
|
|
206
|
+
const authed = new AbxServiceClient({ baseUrl: base, token: opts.token });
|
|
207
|
+
// A rejected credential makes the authed tiers UNASSESSABLE — it does not make the service
|
|
208
|
+
// non-conformant. Before this was tracked, one stale key produced four confident "this service
|
|
209
|
+
// accepts bytes it must refuse / is becoming an object store" failures, because every probe below
|
|
210
|
+
// 401s and a 401 is not the 400 they assert on. That reads as an indictment of the operator, it is
|
|
211
|
+
// the exact opposite of the guarantee this command exists to give (conformance is checkable from
|
|
212
|
+
// OUTSIDE, before you sign up), and it left an agent choosing between believing five ✗ marks and
|
|
213
|
+
// rationalizing them away. So: record the one true failure, then stop asking questions this
|
|
214
|
+
// credential cannot answer.
|
|
215
|
+
let tokenRejected = false;
|
|
216
|
+
try {
|
|
217
|
+
const projects = await authed.listProjects();
|
|
218
|
+
pass(`GET /v1/projects with the token → ${projects.length} project(s) visible`);
|
|
219
|
+
}
|
|
220
|
+
catch (err) {
|
|
221
|
+
if (err instanceof AbxServiceError && err.status === 401) {
|
|
222
|
+
tokenRejected = true;
|
|
223
|
+
failed('the provided token was rejected (401)');
|
|
224
|
+
}
|
|
225
|
+
else
|
|
226
|
+
failed(`GET /v1/projects failed: ${err.message}`);
|
|
227
|
+
}
|
|
228
|
+
if (tokenRejected) {
|
|
229
|
+
note('skipping the authed tiers — they cannot be assessed with a rejected credential, and a 401 ' +
|
|
230
|
+
'from every probe would look like a conformance failure of the SERVICE rather than of this key. ' +
|
|
231
|
+
`Get a working key${descriptor?.auth?.signupUrl ? ` (provider recovery: ${descriptor.auth.signupUrl})` : ''} and re-run.`);
|
|
232
|
+
return { baseUrl: base, assertions, failures: assertions.filter((a) => a.status === 'fail').length };
|
|
233
|
+
}
|
|
234
|
+
// ── tier 1: the artifact registry is a POINTER registry ─────────────────────
|
|
235
|
+
// `site/content/docs/protocol/effects.mdx → Bound vs referenced`. Which form is legal is fixed by the output's
|
|
236
|
+
// binding, and BOTH mismatches must be refused: silently accepting media bytes makes every
|
|
237
|
+
// conforming resolver an object store, and silently accepting a locator for `traits` records
|
|
238
|
+
// something that can never stitch — a wrong answer served confidently. These probes are all
|
|
239
|
+
// refusals, so a conformant service stores nothing as a result of them.
|
|
240
|
+
if (descriptor?.interfaces?.includes(CONTROL_PLANE_INTERFACE)) {
|
|
241
|
+
const publish = async (body) => {
|
|
242
|
+
try {
|
|
243
|
+
const res = await fetch(base + '/v1/effect-artifacts', {
|
|
244
|
+
method: 'POST',
|
|
245
|
+
headers: { authorization: `Bearer ${opts.token}`, 'content-type': 'application/json' },
|
|
246
|
+
body: JSON.stringify({ chainId: chainForProbe, address: probeAddr, tokenId: '0', inputsHash: '0x' + 'ab'.repeat(32), ...body }),
|
|
247
|
+
});
|
|
248
|
+
return { status: res.status, body: (await res.json().catch(() => ({}))) };
|
|
249
|
+
}
|
|
250
|
+
catch (err) {
|
|
251
|
+
return { networkError: err };
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
const refuses = async (label, body) => {
|
|
255
|
+
const r = await publish(body);
|
|
256
|
+
if (r.networkError)
|
|
257
|
+
return failed(`${label}: unreachable (${r.networkError.message})`);
|
|
258
|
+
if (r.status === 401)
|
|
259
|
+
return note(`${label}: 401 — this token was rejected, so the probe says nothing about the service (fix the key, then re-run)`);
|
|
260
|
+
if (r.status === 403)
|
|
261
|
+
return note(`${label}: 403 — this token isn't authorized to write artifacts (provider scoping, not a failure)`);
|
|
262
|
+
if (r.status === 400)
|
|
263
|
+
return pass(`${label} → 400 ${r.body?.code ?? ''}`);
|
|
264
|
+
if (r.status === 404 && r.body?.code === 'unknown_route') {
|
|
265
|
+
return failed(`${label}: the artifact-registry route is missing, but this service declares ${CONTROL_PLANE_INTERFACE} (the routes ride it — there is no separate publish interface)`);
|
|
266
|
+
}
|
|
267
|
+
failed(`${label} → ${r.status} ${r.body?.code ?? ''} (expected 400; accepting this is how a resolver becomes an object store / serves traits that never stitch)`);
|
|
268
|
+
};
|
|
269
|
+
await refuses('bytes for a REFERENCED output (image)', { output: 'image', contentType: 'image/png', bytes_base64: Buffer.from([1, 2, 3]).toString('base64') });
|
|
270
|
+
await refuses('a locator for a BOUND output (traits)', { output: 'traits', locator: 'ipfs://cid-conformance' });
|
|
271
|
+
await refuses('bound content over the 64KB cap', { output: 'traits', bytes_base64: Buffer.alloc(64 * 1024 + 1, 0x41).toString('base64') });
|
|
272
|
+
await refuses('a locator only the producer could resolve', { output: 'image', locator: 'http://localhost:8080/x.png' });
|
|
273
|
+
}
|
|
274
|
+
// ── tier 2: the full register → status → reindex → deregister loop ──────────
|
|
275
|
+
if (!opts.address) {
|
|
276
|
+
note('no address — skipping the register loop (point it at a contract you own on the served chain)');
|
|
277
|
+
}
|
|
278
|
+
else if (opts.chainId === undefined) {
|
|
279
|
+
note('address given without a chainId — skipping the register loop');
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
const chainId = opts.chainId;
|
|
283
|
+
const address = opts.address;
|
|
284
|
+
try {
|
|
285
|
+
const reg = await authed.registerProject({ chainId, address, ...(opts.fromBlock ? { fromBlock: opts.fromBlock } : {}) });
|
|
286
|
+
// Either register shape is conformant: 200 with the completed summary, or 202 + a lifecycle
|
|
287
|
+
// state with catch-up deferred. The SDK normalizes the HTTP status into `accepted`.
|
|
288
|
+
if (reg.accepted) {
|
|
289
|
+
LIFECYCLE.includes(reg.project?.status)
|
|
290
|
+
? pass(`register → 202 accepted (${reg.project.status}) — catch-up deferred`)
|
|
291
|
+
: failed(`register → 202 but project.status is ${JSON.stringify(reg.project?.status)} (must be one of ${LIFECYCLE.join(' | ')})`);
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
reg.ok && (reg.mode === 'full' || reg.mode === 'incremental')
|
|
295
|
+
? pass(`register → 200 ok (${reg.mode}, ${reg.project?.eventCount ?? '?'} events)`)
|
|
296
|
+
: failed(`register response missing ok/mode: ${JSON.stringify(reg)}`);
|
|
297
|
+
}
|
|
298
|
+
// DURABLE FIRST: whichever shape answered, the registration must be visible IMMEDIATELY — it
|
|
299
|
+
// is persisted before catch-up, so a slow/failing chain RPC can never lose the add.
|
|
300
|
+
const listed = await authed.listProjects();
|
|
301
|
+
listed.some((p) => p.address?.toLowerCase() === address.toLowerCase())
|
|
302
|
+
? pass('registration is visible on the list right after register (durable before catch-up)')
|
|
303
|
+
: failed('the project is NOT on GET /v1/projects right after register — the registration must be persisted before catch-up');
|
|
304
|
+
let status = await authed.projectStatus(chainId, address);
|
|
305
|
+
status.fromBlock !== undefined && 'toBlock' in status
|
|
306
|
+
? pass(`status → fromBlock ${status.fromBlock}, toBlock ${status.toBlock}`)
|
|
307
|
+
: failed(`status response missing fromBlock/toBlock: ${JSON.stringify(status)}`);
|
|
308
|
+
LIFECYCLE.includes(status.status)
|
|
309
|
+
? pass(`status → lifecycle '${status.status}'`)
|
|
310
|
+
: failed(`status.status is ${JSON.stringify(status.status)} (must be one of ${LIFECYCLE.join(' | ')})`);
|
|
311
|
+
if (!('headBlock' in status))
|
|
312
|
+
failed('status is missing headBlock — a client cannot compute lag / % complete without it');
|
|
313
|
+
else if (status.headBlock)
|
|
314
|
+
pass(`status → headBlock ${status.headBlock} (lag is computable)`);
|
|
315
|
+
else
|
|
316
|
+
note('status.headBlock is null — the field is there, but this service is not reporting head, so a client cannot show % complete');
|
|
317
|
+
// Poll to a terminal state, exactly as the CLI does. A service that defers catch-up must
|
|
318
|
+
// eventually reach `live` with nobody prompting it.
|
|
319
|
+
if (status.status !== 'live' && status.status !== 'failed') {
|
|
320
|
+
note(`'${status.status}' — polling to a terminal state…`);
|
|
321
|
+
try {
|
|
322
|
+
status = await authed.awaitIndexed(chainId, address, {
|
|
323
|
+
timeoutMs: opts.awaitTimeoutMs ?? 120_000,
|
|
324
|
+
intervalMs: opts.awaitIntervalMs ?? 2_000,
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
catch (err) {
|
|
328
|
+
failed(`never reached a terminal status: ${err.message}`);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
status.status === 'live'
|
|
332
|
+
? pass(`caught up → live (${status.eventCount} events, ${status.tokenCount} token(s))`)
|
|
333
|
+
: status.status === 'failed'
|
|
334
|
+
? failed(`catch-up reported failed${status.error ? ` (${status.error.class})` : ''} — point address at a contract this service can replay`)
|
|
335
|
+
: note(`still '${status.status}' — not a conformance failure, but slower than this fixture waits`);
|
|
336
|
+
if (status.error && !['rpc_unavailable', 'rpc_rate_limited', 'not_abx_contract', 'internal'].includes(status.error.class)) {
|
|
337
|
+
failed(`error.class is ${JSON.stringify(status.error.class)} — must be one of the closed set`);
|
|
338
|
+
}
|
|
339
|
+
if (status.error?.message && /https?:\/\//.test(status.error.message)) {
|
|
340
|
+
failed('error.message contains a URL — it must be credential-free (a keyed RPC URL is a secret)');
|
|
341
|
+
}
|
|
342
|
+
// The accept path, on a project the service now actually serves: a referenced output's locator
|
|
343
|
+
// is recorded and served by REDIRECT — never proxied, so the producer's egress stays its own.
|
|
344
|
+
try {
|
|
345
|
+
const key = (await authed.publishEffectArtifact({
|
|
346
|
+
chainId,
|
|
347
|
+
address,
|
|
348
|
+
tokenId: '0',
|
|
349
|
+
inputsHash: ('0x' + 'ab'.repeat(32)),
|
|
350
|
+
output: 'image',
|
|
351
|
+
contentType: 'image/png',
|
|
352
|
+
locator: 'https://conformance.invalid/still.png',
|
|
353
|
+
})).key;
|
|
354
|
+
pass(`artifact registry accepted a referenced locator (key ${String(key).slice(0, 10)}…)`);
|
|
355
|
+
try {
|
|
356
|
+
const served = await fetch(`${base}/t/${chainId}/${address}/0/data/render/image`, { redirect: 'manual' });
|
|
357
|
+
if (served.status === 302 || served.status === 301)
|
|
358
|
+
pass(' …and the read plane 302-redirects to it (no proxying)');
|
|
359
|
+
else if (served.status === 404)
|
|
360
|
+
note(" the artifact route 404s — the row addresses a different inputsHash than this token's current one (self-invalidation working as designed)");
|
|
361
|
+
else
|
|
362
|
+
failed(` the artifact route answered ${served.status} — a registered locator MUST be served by redirect, never proxied`);
|
|
363
|
+
}
|
|
364
|
+
catch (err) {
|
|
365
|
+
note(`could not probe the artifact read route: ${err.message}`);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
catch (err) {
|
|
369
|
+
if (scoped(err))
|
|
370
|
+
note("403 on artifact publish — the token isn't authorized to write artifacts (provider scoping)");
|
|
371
|
+
else
|
|
372
|
+
failed(`publishing a referenced locator failed: ${err.message}`);
|
|
373
|
+
}
|
|
374
|
+
const re = await authed.reindexProject(chainId, address);
|
|
375
|
+
re.ok ? pass(`reindex → ok (${re.accepted ? `202 ${re.project.status}` : re.mode})`) : failed(`reindex response missing ok: ${JSON.stringify(re)}`);
|
|
376
|
+
const { removed } = await authed.removeProject(chainId, address);
|
|
377
|
+
removed ? pass('deregister → removed') : failed('deregister reported not_registered for a project just registered');
|
|
378
|
+
const second = await authed.removeProject(chainId, address);
|
|
379
|
+
!second.removed ? pass('second deregister → not_registered (idempotent to retry)') : failed('second deregister claimed to remove again');
|
|
380
|
+
}
|
|
381
|
+
catch (err) {
|
|
382
|
+
if (scoped(err))
|
|
383
|
+
note(`403 during the loop — the token isn't authorized for ${address} (provider scoping; not a conformance failure)`);
|
|
384
|
+
else
|
|
385
|
+
failed(`register loop failed: ${err.message}`);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
return { baseUrl: base, assertions, failures: assertions.filter((a) => a.status === 'fail').length };
|
|
389
|
+
}
|
|
390
|
+
//# sourceMappingURL=conformance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conformance.js","sourceRoot":"","sources":["../src/conformance.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** A revert/no-data/decode failure is evidence that this contract lacks the probed getter. */
|
|
2
|
+
export declare function isMissingContractCapability(error: unknown): boolean;
|
|
3
|
+
/** Is the failed contract read evidence about the node rather than the target contract's shape? */
|
|
4
|
+
export declare function isRpcReadFailure(error: unknown): boolean;
|
|
5
|
+
//# sourceMappingURL=contract-read-error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract-read-error.d.ts","sourceRoot":"","sources":["../src/contract-read-error.ts"],"names":[],"mappings":"AAkBA,8FAA8F;AAC9F,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CASnE;AAED,mGAAmG;AACnG,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CASxD"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Viem wraps a failed `eth_call` in one or more error objects. Walk that chain so callers can
|
|
3
|
+
* distinguish a truthful capability miss (the target does not implement a getter) from an RPC
|
|
4
|
+
* failure (the node did not answer reliably). Collapsing both to `undefined` produces confident,
|
|
5
|
+
* false contract classifications whenever a public endpoint flakes.
|
|
6
|
+
*/
|
|
7
|
+
function errorNames(error) {
|
|
8
|
+
const names = [];
|
|
9
|
+
const seen = new Set();
|
|
10
|
+
let current = error;
|
|
11
|
+
while (current && typeof current === 'object' && !seen.has(current)) {
|
|
12
|
+
seen.add(current);
|
|
13
|
+
if ('name' in current && typeof current.name === 'string')
|
|
14
|
+
names.push(current.name);
|
|
15
|
+
current = 'cause' in current ? current.cause : undefined;
|
|
16
|
+
}
|
|
17
|
+
return names;
|
|
18
|
+
}
|
|
19
|
+
/** A revert/no-data/decode failure is evidence that this contract lacks the probed getter. */
|
|
20
|
+
export function isMissingContractCapability(error) {
|
|
21
|
+
return errorNames(error).some((name) => [
|
|
22
|
+
'ContractFunctionRevertedError',
|
|
23
|
+
'ContractFunctionZeroDataError',
|
|
24
|
+
'AbiDecodingZeroDataError',
|
|
25
|
+
'AbiDecodingDataSizeTooSmallError',
|
|
26
|
+
].includes(name));
|
|
27
|
+
}
|
|
28
|
+
/** Is the failed contract read evidence about the node rather than the target contract's shape? */
|
|
29
|
+
export function isRpcReadFailure(error) {
|
|
30
|
+
// Viem may wrap a revert in an execution layer that also contains RPC-ish names. The truthful
|
|
31
|
+
// contract-level classification is stronger and must win.
|
|
32
|
+
if (isMissingContractCapability(error))
|
|
33
|
+
return false;
|
|
34
|
+
return errorNames(error).some((name) => name.endsWith('RpcError') ||
|
|
35
|
+
['HttpRequestError', 'WebSocketRequestError', 'SocketClosedError', 'TimeoutError'].includes(name));
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=contract-read-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract-read-error.js","sourceRoot":"","sources":["../src/contract-read-error.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,SAAS,UAAU,CAAC,KAAc;IAChC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAW,CAAC;IAChC,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,OAAO,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QACpE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAClB,IAAI,MAAM,IAAI,OAAO,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ;YAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACpF,OAAO,GAAG,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,2BAA2B,CAAC,KAAc;IACxD,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CACrC;QACE,+BAA+B;QAC/B,+BAA+B;QAC/B,0BAA0B;QAC1B,kCAAkC;KACnC,CAAC,QAAQ,CAAC,IAAI,CAAC,CACjB,CAAC;AACJ,CAAC;AAED,mGAAmG;AACnG,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,8FAA8F;IAC9F,0DAA0D;IAC1D,IAAI,2BAA2B,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACrD,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,IAAI,CAC3B,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;QACzB,CAAC,kBAAkB,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,cAAc,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CACpG,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The structured `--dry-run --json` / `--json` deploy plan (issue #123).
|
|
3
|
+
*
|
|
4
|
+
* The issue as filed asked for ONE plan object that both the JSON payload and the human prose are
|
|
5
|
+
* rendered FROM. That full refactor is deliberately out of scope here: deploy is the highest-stakes
|
|
6
|
+
* command family (real gas, address pinning, salt reservation), 17 test files assert on the EXACT
|
|
7
|
+
* dry-run prose, and the end-user skill pattern-matches on it — rewiring the human path through a
|
|
8
|
+
* shared object risks a wording regression for no consumer that needs it yet (there is no strict
|
|
9
|
+
* JSON-schema integrator today). So this module only adds the other half: a versioned, typed object
|
|
10
|
+
* populated from the SAME locals `commands/deploy.ts` already computed for its human narration, at
|
|
11
|
+
* every existing `emit(jsonSafe({...}))` call site. The prose is untouched, byte-for-byte.
|
|
12
|
+
*
|
|
13
|
+
* A field a lane genuinely has no answer for is explicit `null`, never silently absent — that
|
|
14
|
+
* distinction (present-but-empty vs. not-applicable-here) is the whole point of a schema. See each
|
|
15
|
+
* `deploy.ts` call site for the specific reasoning behind its nulls.
|
|
16
|
+
*/
|
|
17
|
+
/** Bump whenever a field is added, renamed, or reinterpreted — a consumer keys behavior off this,
|
|
18
|
+
* not off the CLI's own package version (that changes for reasons unrelated to this shape).
|
|
19
|
+
*
|
|
20
|
+
* `as const` is load-bearing, not decoration: a plain `= 1` is a WIDENING literal, so the moment it
|
|
21
|
+
* is read into an un-annotated intermediate object (the resume lane builds one and spreads it into
|
|
22
|
+
* several emits) the property degrades to `number` and stops satisfying `DeployPlan`. Keep it. */
|
|
23
|
+
export declare const DEPLOY_PLAN_SCHEMA_VERSION: 1;
|
|
24
|
+
/** The six product lanes `deploy.ts` implements — a stable discriminator independent of the legacy
|
|
25
|
+
* `command`/`kind` fields already on the payload (which exist for backward compat and don't fully
|
|
26
|
+
* agree with each other across lanes: `kind: 'edition-code'` vs. this union's `'code-edition'`). */
|
|
27
|
+
export type DeployPlanFamily = '1of1' | '1of1-edition' | 'series' | 'series-edition' | 'code' | 'code-edition';
|
|
28
|
+
/** The three signing lanes `laneFromFlags` resolves to, reused verbatim. */
|
|
29
|
+
export type DeployPlanLane = 'send' | 'sign' | 'unsigned';
|
|
30
|
+
export interface DeployPlanTransactions {
|
|
31
|
+
/** Wallet TX SIGNATURES this run needs — the exact same count the lane's own dry-run/confirm
|
|
32
|
+
* "approvals" line reports (an off-chain storage upload is a separate signature class, never
|
|
33
|
+
* counted here — see the `approvals` local at each call site). */
|
|
34
|
+
approvals: number;
|
|
35
|
+
/** Ordered legs riding a setup multicall or a staging sequence BEYOND the deploy tx itself (e.g.
|
|
36
|
+
* `['chunks', 'param-schemas', 'dependencies', 'onchain-uri', 'mints']` for a code project, or
|
|
37
|
+
* `['onchain-image-staging']` for an image lane staging bytes into the chunk store). `null` when
|
|
38
|
+
* the deploy is a single, self-contained transaction. */
|
|
39
|
+
legs: string[] | null;
|
|
40
|
+
}
|
|
41
|
+
export interface DeployPlanRoles {
|
|
42
|
+
/** The address that signs this deploy. `null` only when genuinely unknown yet (a dry run with no
|
|
43
|
+
* `--for` and no resolvable wallet key — the plan is still previewable; just not addressed to
|
|
44
|
+
* anyone in particular). */
|
|
45
|
+
signer: string | null;
|
|
46
|
+
/** Always equal to `signer` in this codebase — every lane sets `owner: deployer` — carried as its
|
|
47
|
+
* own field because a consumer reasoning about roles shouldn't have to know that fact. */
|
|
48
|
+
owner: string | null;
|
|
49
|
+
royaltyReceiver: string | null;
|
|
50
|
+
/** `null` when no `--primary-payee` was given (sale proceeds go to the owner) — the lanes with no
|
|
51
|
+
* concept of a delegated payee at all (the plain 1/1) also report `null` here. */
|
|
52
|
+
primaryPayee: string | null;
|
|
53
|
+
/** `null` when no `--minter` was given (only the owner can mint) — same "no concept" case as
|
|
54
|
+
* `primaryPayee` on the plain 1/1 lane. */
|
|
55
|
+
minter: string | null;
|
|
56
|
+
}
|
|
57
|
+
export interface DeployPlanRoyalty {
|
|
58
|
+
bps: number;
|
|
59
|
+
capBps: number;
|
|
60
|
+
burnable: boolean;
|
|
61
|
+
}
|
|
62
|
+
export interface DeployPlanCustody {
|
|
63
|
+
/** Does `tokenURI`/`contractURI` (or `uri`/`contractURI` on an edition) resolve on-chain via the
|
|
64
|
+
* canonical renderer, vs. through a resolver base baked on-chain. */
|
|
65
|
+
onChainUri: boolean;
|
|
66
|
+
/** Are the IMAGE bytes themselves on-chain (a chunk-store `reader` field) — distinct from
|
|
67
|
+
* `onChainUri`, which only says the metadata JSON resolves on-chain (see deploy.ts's own
|
|
68
|
+
* "puts the metadata JSON on-chain, not the image" warning). `null` on the code lanes, where an
|
|
69
|
+
* image is one of several independently-disposed surfaces — see `surfaces.thumbnail` instead. */
|
|
70
|
+
imageOnChain: boolean | null;
|
|
71
|
+
/** The off-chain storage backend holding bytes this deploy custodies (e.g. `ipfs`, `arweave`,
|
|
72
|
+
* `fs`) — `null` when nothing is stored off-chain (fully on-chain content, or a code project
|
|
73
|
+
* whose script chunks are on-chain and carries no directory build). */
|
|
74
|
+
backend: string | null;
|
|
75
|
+
/** The on-chain `tokenURIBase`/`contractURIBase` this deploy writes — `null`, not `''`, when the
|
|
76
|
+
* lane deliberately leaves it empty because the on-chain renderer is authoritative (baking a
|
|
77
|
+
* base anyway would be misleading: nothing ever reads it while a renderer is set). */
|
|
78
|
+
tokenUriBase: string | null;
|
|
79
|
+
contractUriBase: string | null;
|
|
80
|
+
}
|
|
81
|
+
export interface DeployPlanMint {
|
|
82
|
+
/** True when nothing mints at deploy (mint later, or via a delegated minter/sale). */
|
|
83
|
+
deferred: boolean;
|
|
84
|
+
/** How many distinct tokens/ids mint at deploy — `0` when deferred. */
|
|
85
|
+
count: number;
|
|
86
|
+
/** Copies PER id (edition lanes only) — `null` on a unique-token lane, where the concept doesn't
|
|
87
|
+
* exist (every id is exactly one copy by construction). A bigint, stringified (see jsonSafe). */
|
|
88
|
+
amountPerId: string | null;
|
|
89
|
+
recipient: string | null;
|
|
90
|
+
}
|
|
91
|
+
export interface DeployPlanEstimate {
|
|
92
|
+
/** A rough, hedged order-of-magnitude figure — `null` on every lane that doesn't compute one
|
|
93
|
+
* (today: only the fresh `code` lane's on-chain-byte-storage guidance does). Never re-derived
|
|
94
|
+
* here; only carried over from the exact estimate the human readout already printed. */
|
|
95
|
+
ethApprox: string | null;
|
|
96
|
+
gasApprox: string | null;
|
|
97
|
+
}
|
|
98
|
+
export interface DeployPlanSurface {
|
|
99
|
+
ok: boolean;
|
|
100
|
+
detail: string;
|
|
101
|
+
}
|
|
102
|
+
/** The code lane's "every marketplace-facing dimension, resolved now" block — `null` on every other
|
|
103
|
+
* lane (an image lane's thumbnail is fully covered by `custody`; it has no separate traits/postParam
|
|
104
|
+
* disposition to report). */
|
|
105
|
+
export interface DeployPlanSurfaces {
|
|
106
|
+
thumbnail: DeployPlanSurface;
|
|
107
|
+
traits: DeployPlanSurface;
|
|
108
|
+
postParams: DeployPlanSurface;
|
|
109
|
+
}
|
|
110
|
+
/** `null` on the image lanes, which have no dependency-registry concept. */
|
|
111
|
+
export interface DeployPlanDependencies {
|
|
112
|
+
count: number;
|
|
113
|
+
registry: string | null;
|
|
114
|
+
}
|
|
115
|
+
/** Present only on a `deploy-code --resume` emit — `null` on a fresh deploy. */
|
|
116
|
+
export interface DeployPlanResume {
|
|
117
|
+
target: string;
|
|
118
|
+
sentLegs: number;
|
|
119
|
+
complete: boolean;
|
|
120
|
+
}
|
|
121
|
+
export interface DeployPlan {
|
|
122
|
+
schemaVersion: typeof DEPLOY_PLAN_SCHEMA_VERSION;
|
|
123
|
+
family: DeployPlanFamily;
|
|
124
|
+
lane: DeployPlanLane;
|
|
125
|
+
transactions: DeployPlanTransactions;
|
|
126
|
+
roles: DeployPlanRoles;
|
|
127
|
+
/** `null` on a `--resume` emit: royalty is an InitParams field fixed at the ORIGINAL deploy, and a
|
|
128
|
+
* resume never touches it — reporting the flags passed to `--resume` here would misleadingly
|
|
129
|
+
* imply this run writes them. */
|
|
130
|
+
royalty: DeployPlanRoyalty | null;
|
|
131
|
+
custody: DeployPlanCustody;
|
|
132
|
+
/** `null` on a `--resume` emit — see the field's own module doc for why the mint plan isn't
|
|
133
|
+
* cleanly reducible to one shape there (edition resume mints are a PER-ID list, not a count). */
|
|
134
|
+
mint: DeployPlanMint | null;
|
|
135
|
+
estimate: DeployPlanEstimate;
|
|
136
|
+
/** Every `warn()` line this invocation raised, ANSI-stripped, in print order — see
|
|
137
|
+
* `beginPlanWarnings`/the local `warn` wrapper in deploy.ts. Not exhaustive of every warning this
|
|
138
|
+
* FILE can print (a trust-anchor bootstrap warning from `output.ts`'s `ensureFactory`/etc. isn't
|
|
139
|
+
* captured — those only fire on a real send that also stands up a fresh trust anchor, and are
|
|
140
|
+
* file-scoped to a different module), but covers every warning the LANE ITSELF raises, which is
|
|
141
|
+
* what a dry-run consumer cares about. */
|
|
142
|
+
warnings: string[];
|
|
143
|
+
surfaces: DeployPlanSurfaces | null;
|
|
144
|
+
dependencies: DeployPlanDependencies | null;
|
|
145
|
+
resume: DeployPlanResume | null;
|
|
146
|
+
}
|
|
147
|
+
/** Strip the tiny ANSI color wrappers (`bold`/`dim`/`g` from output.ts) so a warning captured for the
|
|
148
|
+
* plan reads as plain text — a JSON consumer has no terminal to render escape codes against. */
|
|
149
|
+
export declare function stripAnsiForPlan(s: string): string;
|
|
150
|
+
//# sourceMappingURL=deploy-plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy-plan.d.ts","sourceRoot":"","sources":["../src/deploy-plan.ts"],"names":[],"mappings":"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"}
|