@artblocks/abx-cli 0.1.0-alpha.9 → 0.2.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.
- package/CHANGELOG.md +429 -0
- package/assets/renderer-scaffold/README.md +44 -13
- 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 +132 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +175 -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 +483 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/contract.d.ts +19 -0
- package/dist/commands/contract.d.ts.map +1 -0
- package/dist/commands/contract.js +171 -0
- package/dist/commands/contract.js.map +1 -0
- package/dist/commands/deploy.d.ts +296 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +5756 -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 +154 -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 +458 -0
- package/dist/commands/project.d.ts.map +1 -0
- package/dist/commands/project.js +1837 -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 +881 -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 +741 -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 +761 -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 +638 -0
- package/dist/commands/submit-app.js.map +1 -0
- package/dist/config.d.ts +94 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +332 -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 +400 -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/creator-agent.d.ts +49 -0
- package/dist/creator-agent.d.ts.map +1 -0
- package/dist/creator-agent.js +363 -0
- package/dist/creator-agent.js.map +1 -0
- package/dist/creator-keyring.d.ts +26 -0
- package/dist/creator-keyring.d.ts.map +1 -0
- package/dist/creator-keyring.js +57 -0
- package/dist/creator-keyring.js.map +1 -0
- package/dist/creator-signer.d.ts +52 -0
- package/dist/creator-signer.d.ts.map +1 -0
- package/dist/creator-signer.js +267 -0
- package/dist/creator-signer.js.map +1 -0
- package/dist/deploy-plan.d.ts +218 -0
- package/dist/deploy-plan.d.ts.map +1 -0
- package/dist/deploy-plan.js +20 -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 +22 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +32 -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 +188 -0
- package/dist/flag-allowlists.js.map +1 -0
- package/dist/flags.d.ts +53 -0
- package/dist/flags.d.ts.map +1 -1
- package/dist/flags.js +151 -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 +859 -5374
- 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 +184 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +774 -0
- package/dist/output.js.map +1 -0
- package/dist/ownerops.d.ts +463 -59
- package/dist/ownerops.d.ts.map +1 -1
- package/dist/ownerops.js +2329 -366
- 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/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 +116 -9
- package/dist/remote.d.ts.map +1 -1
- package/dist/remote.js +371 -14
- package/dist/remote.js.map +1 -1
- package/dist/riskgate.d.ts +101 -0
- package/dist/riskgate.d.ts.map +1 -0
- package/dist/riskgate.js +343 -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 +20 -1
- package/dist/signer.d.ts.map +1 -1
- package/dist/signer.js +110 -18
- package/dist/signer.js.map +1 -1
- package/dist/update-check.d.ts +60 -9
- package/dist/update-check.d.ts.map +1 -1
- package/dist/update-check.js +105 -18
- package/dist/update-check.js.map +1 -1
- package/package.json +17 -12
- package/skill/SKILL.md +213 -354
- package/skill/agents/openai.yaml +4 -0
- package/skill/reference/capabilities.md +195 -0
- package/skill/reference/code.md +236 -0
- package/skill/reference/creator-token.md +94 -0
- package/skill/reference/deploy.md +191 -0
- package/skill/reference/diagnose.md +178 -0
- package/skill/reference/hosting.md +191 -102
- package/skill/reference/operate.md +237 -0
- package/skill/reference/services.md +173 -0
- package/skill/reference/setup.md +221 -42
- 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 -118
- package/skill/reference/troubleshooting.md +0 -28
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"riskgate.d.ts","sourceRoot":"","sources":["../src/riskgate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAA8C,KAAK,YAAY,EAAC,MAAM,MAAM,CAAC;AAGpF,OAAO,EAOL,KAAK,OAAO,EAEb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAS,KAAK,IAAI,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAC,MAAM,aAAa,CAAC;AAChF,OAAO,EAAW,KAAK,KAAK,EAAC,MAAM,YAAY,CAAC;AAOhD;yFACyF;AACzF,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAqBhD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAUpD;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAO9E;AAaD,MAAM,WAAW,gBAAgB;IAC/B;;;iGAG6F;IAC7F,MAAM,EAAE,eAAe,GAAG,cAAc,GAAG,SAAS,CAAC;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;2GAGuG;IACvG,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mGAAmG;IACnG,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;oCAEgC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAkBjD;AA2JD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB;+DAC2D;IAC3D,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;yFACqF;IACrF,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED;iGACiG;AACjG,wBAAgB,aAAa,CAC3B,KAAK,EAAE,KAAK,EACZ,QAAQ,CAAC,EAAE,OAAO,EAClB,UAAU,GAAE,KAAK,MAAM,EAAE,GAAG,SAA2B,GACtD,OAAO,GAAG,SAAS,CAQrB;AAED;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAoCtH"}
|
package/dist/riskgate.js
ADDED
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The CLI's one risk gate for a write — the choke point every signing path (owner-op or deploy)
|
|
3
|
+
* routes an already-prepared tx through, so `--dry-run` and `--confirm` behave IDENTICALLY no
|
|
4
|
+
* matter which command reached them.
|
|
5
|
+
*
|
|
6
|
+
* Before this module existed, the same three-part shape (preview-and-stop under `--dry-run` →
|
|
7
|
+
* optional interactive `--confirm` → pick a lane → sign) was hand-written THREE times: ownerops.ts's
|
|
8
|
+
* `runWrite` (every owner-op), a near-identical `runMinterWrite` ("the minter path does not go
|
|
9
|
+
* through runWrite, so it needs its OWN dry-run guard" — its own comment conceding the duplication),
|
|
10
|
+
* and a third copy inline in main.ts's `deploy-code --resume` send path. Each could drift from the
|
|
11
|
+
* others without anyone deciding it should — and the two owner-op copies HAD already drifted: only
|
|
12
|
+
* one of them printed the `owner` line on a dry-run preview when the caller supplied one.
|
|
13
|
+
*
|
|
14
|
+
* `gatedSend` is the merge. Callers that had NO `--confirm` support (every owner-op) gain it for
|
|
15
|
+
* free just by routing through here — there is no owner-op-specific reason they lacked it; it was
|
|
16
|
+
* simply never wired.
|
|
17
|
+
*/
|
|
18
|
+
import { decodeErrorResult, formatEther, zeroAddress } from 'viem';
|
|
19
|
+
import { privateKeyToAccount } from 'viem/accounts';
|
|
20
|
+
import { createInterface } from 'node:readline';
|
|
21
|
+
import { assertChainId, envSigningKey, makePublicClient, pinGas, seriesCodeAbi, GasEstimateBelowFloorError, } from '@artblocks/abx-sdk';
|
|
22
|
+
import { signTx } from './signer.js';
|
|
23
|
+
import { isDryRun } from './flags.js';
|
|
24
|
+
// ── tiny ANSI (kept local — every module here stands alone; see signer.ts/ownerops.ts) ───────
|
|
25
|
+
const C = { reset: '\x1b[0m', dim: '\x1b[2m', bold: '\x1b[1m', green: '\x1b[38;5;115m', orange: '\x1b[38;5;215m' };
|
|
26
|
+
const dim = (s) => `${C.dim}${s}${C.reset}`;
|
|
27
|
+
const bold = (s) => `${C.bold}${s}${C.reset}`;
|
|
28
|
+
/** Resolve the signing lane from flags: `--unsigned` (cold) · `--sign` (wallet) · `--sponsor`
|
|
29
|
+
* (ABX creator wallet) · default hot. The one place every write makes this decision. */
|
|
30
|
+
export function laneFromFlags(flags) {
|
|
31
|
+
// Two lane flags at once is always a mistake, and silently picking one is how a caller ends up in a
|
|
32
|
+
// lane they did not choose — an agent writing `--send --sign` from two different help lines gets a
|
|
33
|
+
// browser wallet page when it meant the env key, and reads the wait as a hang. Refuse instead: the
|
|
34
|
+
// precedence order below is an implementation detail, not an interface.
|
|
35
|
+
const named = ['send', 'sign', 'sponsor', 'unsigned'].filter((k) => flags[k] !== undefined);
|
|
36
|
+
if (named.length > 1) {
|
|
37
|
+
throw new Error(`pick ONE signing lane, not ${named.length}: ${named.map((n) => `--${n}`).join(' and ')}. ` +
|
|
38
|
+
`--send signs with the hot/env key (the default, so it can also be omitted) · --sign opens a ` +
|
|
39
|
+
`wallet page · --sponsor uses your ABX creator wallet · --unsigned prints the transaction for you to sign elsewhere.`);
|
|
40
|
+
}
|
|
41
|
+
// PRESENCE, not truthiness. A bare `--sign` parses to `'true'`, but `--sign=` parses to `''`, which
|
|
42
|
+
// is falsy — so a truthiness test sent that caller down the hot-key lane after they explicitly named
|
|
43
|
+
// the wallet one. That is the one direction that matters: asking for a browser approval and getting
|
|
44
|
+
// an unattended key signature instead. Naming a lane selects it, full stop.
|
|
45
|
+
if (named.includes('unsigned'))
|
|
46
|
+
return 'unsigned';
|
|
47
|
+
if (named.includes('sign'))
|
|
48
|
+
return 'sign';
|
|
49
|
+
if (named.includes('sponsor'))
|
|
50
|
+
return 'sponsor';
|
|
51
|
+
return 'send';
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Refuse a real deploy on the HOT lane when there is no key to sign with — before the command has
|
|
55
|
+
* spent anything.
|
|
56
|
+
*
|
|
57
|
+
* The signing lanes are checked at *signing* time, which is the end of a deploy. Everything that
|
|
58
|
+
* makes a deploy possible happens first, and some of it is neither free nor reversible: `--backend
|
|
59
|
+
* arweave|ipfs|cloud` UPLOADS the creator's art before any transaction is prepared. So a deploy run
|
|
60
|
+
* with no key, and no `--dry-run` to say "preview only", would mint an Arweave identity, publish the
|
|
61
|
+
* art, and only THEN discover it could never have deployed. Under Turbo's free tier the upload
|
|
62
|
+
* *succeeds*, so the art is published permanently — an irreversible side effect from a run that was
|
|
63
|
+
* always going to fail.
|
|
64
|
+
*
|
|
65
|
+
* `--dry-run` guards every signing choke point (`isDryRun`, `gatedSend`); this is the same idea one
|
|
66
|
+
* step earlier, and the rule it enforces is the sibling of that one: **a spend or a publish never
|
|
67
|
+
* precedes the check that this run can be signed at all.** Only the hot lane is checked — `--sign`
|
|
68
|
+
* (browser wallet) and `--unsigned` (offline signer) deliberately have no local key, and a preview
|
|
69
|
+
* spends nothing.
|
|
70
|
+
*/
|
|
71
|
+
export function assertLaneCanSign(flags) {
|
|
72
|
+
if (isDryRun(flags))
|
|
73
|
+
return; // a preview neither signs nor spends
|
|
74
|
+
if (laneFromFlags(flags) !== 'send')
|
|
75
|
+
return; // wallet/cold lanes have no local key BY DESIGN
|
|
76
|
+
if (envSigningKey())
|
|
77
|
+
return;
|
|
78
|
+
throw new Error('no signing key, so this run could not be sent — stopping before it uploads or spends anything. ' +
|
|
79
|
+
'Pick a lane: --sign --for 0x.. (you approve in your own wallet, no key here) · --unsigned (print the tx ' +
|
|
80
|
+
'for an offline signer) · or set ABX_DEPLOYER_PK in .env for the unattended hot lane. ' +
|
|
81
|
+
'To preview without any of them, add --dry-run --for 0x...');
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Opt-in pre-send confirmation gate (`--confirm`). OFF by default → scripted use is untouched. Even
|
|
85
|
+
* when opted in, it never blocks automation: `--yes` or a non-TTY stdin proceeds silently. Only an
|
|
86
|
+
* interactive `--confirm` prints the summary and waits for a y/N. Aborts on anything but yes.
|
|
87
|
+
*/
|
|
88
|
+
export async function confirmSend(summary, flags) {
|
|
89
|
+
if (flags.confirm === undefined)
|
|
90
|
+
return; // not opted in
|
|
91
|
+
if (flags.yes !== undefined || !process.stdin.isTTY)
|
|
92
|
+
return; // don't stall scripts/CI
|
|
93
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
94
|
+
const answer = await new Promise((resolve) => rl.question(`\n ${summary}\n Proceed? [y/N] `, resolve));
|
|
95
|
+
rl.close();
|
|
96
|
+
if (!/^y(es)?$/i.test(answer.trim()))
|
|
97
|
+
throw new Error('aborted at --confirm (nothing sent).');
|
|
98
|
+
}
|
|
99
|
+
async function resolveProvider(provider, signer) {
|
|
100
|
+
return typeof provider === 'function' ? await provider(signer) : provider;
|
|
101
|
+
}
|
|
102
|
+
function printDryRunPreview(prepared, expectedSigner) {
|
|
103
|
+
console.log(`\n ${bold('◆ ' + prepared.summary)} ${dim('(dry run — nothing sent)')}`);
|
|
104
|
+
for (const [k, v] of Object.entries(prepared.fields))
|
|
105
|
+
console.log(` ${dim(k.padEnd(12))} ${v}`);
|
|
106
|
+
console.log(` ${dim('to'.padEnd(12))} ${prepared.to ?? dim('(contract deploy)')}`);
|
|
107
|
+
if (expectedSigner)
|
|
108
|
+
console.log(` ${dim('signer'.padEnd(12))} ${expectedSigner}`);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* A revert's own name, when the payload carries one — `RoyaltyTooHigh()` instead of a raw hex dump
|
|
112
|
+
* or "reverted for an unknown reason".
|
|
113
|
+
*
|
|
114
|
+
* Whether we get one is the NODE's choice, not ours: many public endpoints (measured:
|
|
115
|
+
* `base-sepolia-rpc.publicnode.com` and `sepolia.base.org`) answer a failed `eth_call` with a bare
|
|
116
|
+
* `execution reverted` and no data at all. So the no-data case says *that*, rather than implying we
|
|
117
|
+
* looked at a reason and couldn't read it.
|
|
118
|
+
*/
|
|
119
|
+
export function revertReason(err) {
|
|
120
|
+
const data = err?.data ?? err?.cause?.data;
|
|
121
|
+
const hex = typeof data === 'string' ? data : data?.data;
|
|
122
|
+
if (typeof hex === 'string' && hex.length >= 10) {
|
|
123
|
+
try {
|
|
124
|
+
const decoded = decodeErrorResult({ abi: seriesCodeAbi, data: hex });
|
|
125
|
+
return `${decoded.errorName}(${(decoded.args ?? []).join(', ')})`;
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
/* not one of ours — fall through to the message */
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
const short = err?.shortMessage ?? err?.message ?? 'reverted';
|
|
132
|
+
// viem's phrasing for "the node sent no revert data" reads like OUR failure to decode. Say what
|
|
133
|
+
// actually happened, and what it almost always means.
|
|
134
|
+
if (/unknown reason/i.test(short)) {
|
|
135
|
+
return 'reverted (this RPC returns no revert data) — usually a precondition the contract enforces: a lock, a cap, or the wrong signer';
|
|
136
|
+
}
|
|
137
|
+
return short;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Simulate the prepared transaction against current state, and say what would happen — honestly.
|
|
141
|
+
*
|
|
142
|
+
* This is what makes `--dry-run` an *answer* rather than an echo of its own input. It matters most
|
|
143
|
+
* for a **multicall** — `attach`'s batched pairs, `deploy-code`'s setup — because a multicall is one
|
|
144
|
+
* transaction, so simulating it exercises the whole sequence atomically against real state, with no
|
|
145
|
+
* fork and no new surface.
|
|
146
|
+
*
|
|
147
|
+
* A dry run that reports `would-succeed` for a send whose real gas turned out to need 49% more than
|
|
148
|
+
* this function used to check, then failed for real, is a preview asserting an outcome it never
|
|
149
|
+
* established — the same class of bug fixed for `verify --remote --json` (see `cmdVerifyRemote`'s
|
|
150
|
+
* fail-closed comment in commands/project.ts): a payload must not claim success it hasn't earned.
|
|
151
|
+
* Two things had to be true before this could say "would succeed", and neither was checked:
|
|
152
|
+
* 1. The call executes without reverting — the ORIGINAL check (an `eth_call`, now folded into
|
|
153
|
+
* {@link pinGas} below instead of a separate unconstrained call, so the preview shares the
|
|
154
|
+
* real send's own gas math, not a second copy of it that could quietly disagree).
|
|
155
|
+
* 2. The signer can actually PAY for it. `estimateGas` succeeding proves the call is valid; it says
|
|
156
|
+
* nothing about whether the account sending it has the ETH to cover `gas × gasPrice (+ value)`.
|
|
157
|
+
* A preview that skips this is not "optimistic", it is wrong — the failure this fixes.
|
|
158
|
+
*
|
|
159
|
+
* Reports **unknown**, never a false green, whenever it cannot actually prove EITHER of those: no
|
|
160
|
+
* signer to simulate as, a contract deploy, a target that does not exist yet, an unreachable node, or
|
|
161
|
+
* a gas estimate that comes back below the transaction's provable floor even after retrying (the
|
|
162
|
+
* exact same refusal a real send makes — see {@link GasEstimateBelowFloorError}). `unknown` is never
|
|
163
|
+
* collapsed into `would-succeed` (an optimistic guess) or `would-revert` (a false alarm) — it says
|
|
164
|
+
* plainly that the question could not be answered, and why.
|
|
165
|
+
*
|
|
166
|
+
* `clientOverride` exists for tests: production callers always omit it and get a real client built
|
|
167
|
+
* from `chainKey`, exactly as before.
|
|
168
|
+
*/
|
|
169
|
+
async function simulateDryRun(prepared, chainKey, expectedSigner, narrate = true, clientOverride, sponsored = false) {
|
|
170
|
+
const label = 'simulation'.padEnd(12);
|
|
171
|
+
const unknown = (why) => {
|
|
172
|
+
if (narrate)
|
|
173
|
+
console.log(` ${dim(label)} ${dim(`unknown — ${why}`)}`);
|
|
174
|
+
return { status: 'unknown', reason: why };
|
|
175
|
+
};
|
|
176
|
+
if (!expectedSigner || expectedSigner === zeroAddress) {
|
|
177
|
+
return unknown('no signer known to simulate as the caller — set a signing key, or use --sign; some commands ' +
|
|
178
|
+
'(e.g. deploy, predict) also accept --for 0x..');
|
|
179
|
+
}
|
|
180
|
+
// Everything below is best-effort: a dry run must work OFFLINE and against an unknown chain (the
|
|
181
|
+
// preview is the product; the simulation is a bonus). So even constructing the client is guarded —
|
|
182
|
+
// `resolveChain` throws on a chain key it doesn't know, and that must degrade to `unknown`, never
|
|
183
|
+
// turn a preview into a failure.
|
|
184
|
+
let client;
|
|
185
|
+
try {
|
|
186
|
+
client = clientOverride ?? makePublicClient({ chainKey });
|
|
187
|
+
}
|
|
188
|
+
catch (err) {
|
|
189
|
+
return unknown(`could not run the simulation (${revertReason(err)})`);
|
|
190
|
+
}
|
|
191
|
+
if (prepared.to) {
|
|
192
|
+
try {
|
|
193
|
+
const code = await client.getCode({ address: prepared.to });
|
|
194
|
+
if (!code || code === '0x')
|
|
195
|
+
return unknown(`${prepared.to} has no code yet on this chain`);
|
|
196
|
+
}
|
|
197
|
+
catch (err) {
|
|
198
|
+
return unknown(`could not run the simulation (${revertReason(err)})`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
// Reuse the REAL send's own gas selection (`pinGas`, execute.ts — the exact function
|
|
202
|
+
// `makeHotSender` calls at send time) instead of a second, separately-written `eth_call`. Two
|
|
203
|
+
// benefits: (a) the preview can never independently drift from what the send would actually do,
|
|
204
|
+
// and (b) a transaction whose real send would REFUSE (every estimate attempt below the provable
|
|
205
|
+
// floor) is reported as such here too, rather than "succeeding" against an unconstrained call.
|
|
206
|
+
let gas;
|
|
207
|
+
try {
|
|
208
|
+
gas = await pinGas(client, {
|
|
209
|
+
from: expectedSigner,
|
|
210
|
+
to: prepared.to,
|
|
211
|
+
data: prepared.data,
|
|
212
|
+
value: prepared.value,
|
|
213
|
+
gasFloor: prepared.gasFloor,
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
catch (err) {
|
|
217
|
+
if (err instanceof GasEstimateBelowFloorError) {
|
|
218
|
+
// Not a contract-logic revert and not a network hiccup — this is "cannot be determined safe",
|
|
219
|
+
// the same refusal a real send makes. Reported as `unknown`, never folded into `would-revert`
|
|
220
|
+
// (nothing was proven to revert) or `would-succeed` (nothing was proven safe either).
|
|
221
|
+
return unknown(`the gas estimate (${err.estimate}) came back below the ${err.floor} this transaction provably needs, ` +
|
|
222
|
+
`even after retrying — the same reason a real send would refuse rather than risk an under-funded ` +
|
|
223
|
+
`transaction. Retry in a few seconds, or against a different RPC.`);
|
|
224
|
+
}
|
|
225
|
+
const reason = revertReason(err);
|
|
226
|
+
// A node that cannot answer is not a failing transaction — do not report one as the other.
|
|
227
|
+
if (/fetch|network|timeout|ECONN|unknown chain/i.test(reason))
|
|
228
|
+
return unknown(`could not run the simulation (${reason})`);
|
|
229
|
+
if (narrate) {
|
|
230
|
+
console.log(` ${dim(label)} ${C.orange}✗ would REVERT${C.reset} — ${reason}`);
|
|
231
|
+
console.log(` ${dim(''.padEnd(12))} ${dim('sending this now would burn gas and change nothing.')}`);
|
|
232
|
+
}
|
|
233
|
+
return { status: 'would-revert', reason };
|
|
234
|
+
}
|
|
235
|
+
// The call is provably executable at `gas`. A sponsored wallet is not the gas payer: price the
|
|
236
|
+
// request for review, but leave provider-policy acceptance pending until the live send.
|
|
237
|
+
if (sponsored) {
|
|
238
|
+
try {
|
|
239
|
+
const gasPrice = await client.getGasPrice();
|
|
240
|
+
const value = prepared.value && prepared.value !== '0x0' ? BigInt(prepared.value) : 0n;
|
|
241
|
+
const cost = gas * gasPrice + value;
|
|
242
|
+
const reason = 'the transaction executes in simulation; live sponsorship policy is checked only when it is sent';
|
|
243
|
+
if (narrate)
|
|
244
|
+
console.log(` ${dim(label)} ${dim(`provider check pending — ${reason}`)}`);
|
|
245
|
+
return { status: 'unknown', reason, estimatedGas: gas.toString(), estimatedCostWei: cost.toString() };
|
|
246
|
+
}
|
|
247
|
+
catch (err) {
|
|
248
|
+
return unknown(`the transaction executes in simulation, but its sponsored cost could not be priced (${revertReason(err)})`);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
// On every user-paid lane, what's left is whether the signer can actually PAY for it. This is the
|
|
252
|
+
// check that was missing entirely: a preview that never compares cost against balance is asserting
|
|
253
|
+
// an outcome it has not earned.
|
|
254
|
+
let gasPrice;
|
|
255
|
+
let balance;
|
|
256
|
+
try {
|
|
257
|
+
[gasPrice, balance] = await Promise.all([client.getGasPrice(), client.getBalance({ address: expectedSigner })]);
|
|
258
|
+
}
|
|
259
|
+
catch (err) {
|
|
260
|
+
// We proved the call itself would succeed; we just can't price it. Say so — do NOT fall back to
|
|
261
|
+
// a bare "would succeed" that quietly drops the affordability question it was just asked.
|
|
262
|
+
return unknown(`the call would succeed, but the cost to send it could not be priced (${revertReason(err)})`);
|
|
263
|
+
}
|
|
264
|
+
const value = prepared.value && prepared.value !== '0x0' ? BigInt(prepared.value) : 0n;
|
|
265
|
+
const cost = gas * gasPrice + value;
|
|
266
|
+
const priced = { estimatedGas: gas.toString(), estimatedCostWei: cost.toString(), balanceWei: balance.toString() };
|
|
267
|
+
if (balance < cost) {
|
|
268
|
+
const reason = `insufficient funds — this send needs ≈${formatEther(cost)} ETH (${gas} gas × ${formatEther(gasPrice)} ` +
|
|
269
|
+
`ETH/gas${value > 0n ? ` + ${formatEther(value)} ETH value` : ''}) but ${expectedSigner} has only ` +
|
|
270
|
+
`${formatEther(balance)} ETH — short by ${formatEther(cost - balance)} ETH.`;
|
|
271
|
+
if (narrate) {
|
|
272
|
+
console.log(` ${dim(label)} ${C.orange}✗ would FAIL${C.reset} — ${reason}`);
|
|
273
|
+
console.log(` ${dim(''.padEnd(12))} ${dim('sending this now would run out of funds before it lands.')}`);
|
|
274
|
+
}
|
|
275
|
+
return { status: 'would-revert', reason, ...priced };
|
|
276
|
+
}
|
|
277
|
+
if (narrate) {
|
|
278
|
+
console.log(` ${dim(label)} ${C.green}✓${C.reset} would succeed ${dim(`(≈${gas} gas, ≈${formatEther(cost)} ETH — signer holds ${formatEther(balance)} ETH)`)}`);
|
|
279
|
+
}
|
|
280
|
+
return { status: 'would-succeed', ...priced };
|
|
281
|
+
}
|
|
282
|
+
/** Resolve the signer a preview should simulate from the same source the hot send will use.
|
|
283
|
+
* Explicit owner/buyer pinning always wins; wallet and cold lanes cannot be inferred locally. */
|
|
284
|
+
export function previewSigner(flags, explicit, signingKey = envSigningKey()) {
|
|
285
|
+
if (explicit)
|
|
286
|
+
return explicit;
|
|
287
|
+
if (laneFromFlags(flags) !== 'send' || !signingKey)
|
|
288
|
+
return undefined;
|
|
289
|
+
try {
|
|
290
|
+
return privateKeyToAccount(signingKey).address;
|
|
291
|
+
}
|
|
292
|
+
catch {
|
|
293
|
+
return undefined;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* The one send choke point for a SINGLE already-prepared write: `--dry-run` preview (nothing sent,
|
|
298
|
+
* returns `null`) → optional `--confirm` prompt → lane selection → `signTx`. Every caller — an
|
|
299
|
+
* owner-op's `runWrite`/`runMinterWrite`, or the deploy family's resumed-setup send — resolves to
|
|
300
|
+
* this, so the two families can never again each carry their own (possibly diverging) idea of what
|
|
301
|
+
* `--dry-run` or `--confirm` means. The historical bug class this forecloses structurally: a write
|
|
302
|
+
* reaching the send lane under `--dry-run` because some caller re-derived the check by hand and
|
|
303
|
+
* missed a branch.
|
|
304
|
+
*/
|
|
305
|
+
export async function gatedSend(provider, flags, opts) {
|
|
306
|
+
const expectedSigner = previewSigner(flags, opts.expectedSigner);
|
|
307
|
+
const lane = laneFromFlags(flags);
|
|
308
|
+
if (isDryRun(flags)) {
|
|
309
|
+
const prepared = await resolveProvider(provider, expectedSigner ?? zeroAddress);
|
|
310
|
+
if (flags.json !== undefined) {
|
|
311
|
+
const simulation = await simulateDryRun(prepared, opts.chainKey, expectedSigner, false, opts.client, lane === 'sponsor');
|
|
312
|
+
console.log(JSON.stringify({
|
|
313
|
+
dryRun: true,
|
|
314
|
+
sent: false,
|
|
315
|
+
lane,
|
|
316
|
+
expectedSigner: expectedSigner ?? null,
|
|
317
|
+
transaction: prepared,
|
|
318
|
+
// `transaction.gasFloor` (when present) is a PROVEN MINIMUM used to detect an implausible
|
|
319
|
+
// gas estimate — not a prediction of total cost. `simulation.estimatedGas`/`estimatedCostWei`
|
|
320
|
+
// are the real numbers, from the same gas selection the send itself uses; trust those.
|
|
321
|
+
simulation,
|
|
322
|
+
}, null, 2));
|
|
323
|
+
}
|
|
324
|
+
else {
|
|
325
|
+
printDryRunPreview(prepared, expectedSigner);
|
|
326
|
+
await simulateDryRun(prepared, opts.chainKey, expectedSigner, true, opts.client, lane === 'sponsor');
|
|
327
|
+
console.log(dim(`\n Re-run without --dry-run to send (lane: ${lane}).\n`));
|
|
328
|
+
}
|
|
329
|
+
return null;
|
|
330
|
+
}
|
|
331
|
+
await assertChainId(opts.chainKey); // verify the RPC really is the target chain before any irreversible write
|
|
332
|
+
const preview = await resolveProvider(provider, expectedSigner ?? zeroAddress);
|
|
333
|
+
await confirmSend(preview.summary, flags);
|
|
334
|
+
return signTx(provider, {
|
|
335
|
+
lane,
|
|
336
|
+
chainKey: opts.chainKey,
|
|
337
|
+
expectedSigner,
|
|
338
|
+
yes: !!flags.yes,
|
|
339
|
+
port: flags.port ? Number(flags.port) : undefined,
|
|
340
|
+
signUrlFile: flags['sign-url-file'],
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
//# sourceMappingURL=riskgate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"riskgate.js","sourceRoot":"","sources":["../src/riskgate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** The file whose presence means the renderer copy genuinely happened (not just `mkdir`). */
|
|
2
|
+
export declare const SCAFFOLD_ANCHOR: string;
|
|
3
|
+
/**
|
|
4
|
+
* Copy the scaffold at `src` into `dir`, omitting build/dependency dirs.
|
|
5
|
+
*
|
|
6
|
+
* Throws if the copy produced no files — the caller must not print a success banner over an empty
|
|
7
|
+
* directory. Returns nothing on success; `anchor` is guaranteed to exist relative to `dir`.
|
|
8
|
+
*/
|
|
9
|
+
export declare function copyScaffold(src: string, dir: string, anchor: string): void;
|
|
10
|
+
/** @deprecated thin wrapper kept for the existing call sites/tests — prefer {@link copyScaffold}. */
|
|
11
|
+
export declare function copyRendererScaffold(src: string, dir: string): void;
|
|
12
|
+
//# sourceMappingURL=scaffold.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"AA6BA,6FAA6F;AAC7F,eAAO,MAAM,eAAe,QAAgC,CAAC;AAE7D;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAiB3E;AAED,qGAAqG;AACrG,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAEnE"}
|
package/dist/scaffold.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copying the bundled renderer scaffold onto a creator's disk.
|
|
3
|
+
*
|
|
4
|
+
* This lives in its own module because the inline version of it shipped broken for six releases
|
|
5
|
+
* (alpha.9 → alpha.14) and could not be reproduced in a dev checkout. `abx scaffold-renderer`
|
|
6
|
+
* created the directory, printed the whole success walkthrough, exited 0, and wrote **zero files** —
|
|
7
|
+
* for every user, on every invocation form, while working perfectly for us.
|
|
8
|
+
*
|
|
9
|
+
* The cause was a path filter that judged absolute paths:
|
|
10
|
+
*
|
|
11
|
+
* filter: (s) => !/(^|\/)(out|cache|dependencies|broadcast|node_modules)(\/|$)/.test(s)
|
|
12
|
+
*
|
|
13
|
+
* `cpSync` hands `filter` ABSOLUTE source paths. An installed CLI lives at
|
|
14
|
+
* `…/node_modules/@artblocks/abx-cli/assets/renderer-scaffold`, so that pattern matched the source
|
|
15
|
+
* ROOT — `cpSync` skips a directory's entire subtree when the directory itself is filtered out, and
|
|
16
|
+
* silently copies nothing rather than erroring. A dev checkout's path
|
|
17
|
+
* (`…/plan/abx/packages/cli/assets/…`) contains no `node_modules`, so every test we ran passed.
|
|
18
|
+
*
|
|
19
|
+
* Two rules follow, and the tests in `test/scaffold.test.ts` pin both:
|
|
20
|
+
* 1. Judge paths RELATIVE to the source root, never the absolute string.
|
|
21
|
+
* 2. Never report success without asserting the output actually landed.
|
|
22
|
+
*/
|
|
23
|
+
import { cpSync, existsSync, mkdirSync } from 'node:fs';
|
|
24
|
+
import { join, relative } from 'node:path';
|
|
25
|
+
/** Build/dependency dirs that must never ride along into a fresh scaffold. Matched against the
|
|
26
|
+
* path RELATIVE to the scaffold root — see the module note. */
|
|
27
|
+
const SKIP_DIR = /^(out|cache|dependencies|broadcast|node_modules)(\/|$)/;
|
|
28
|
+
/** The file whose presence means the renderer copy genuinely happened (not just `mkdir`). */
|
|
29
|
+
export const SCAFFOLD_ANCHOR = join('src', 'MyRenderer.sol');
|
|
30
|
+
/**
|
|
31
|
+
* Copy the scaffold at `src` into `dir`, omitting build/dependency dirs.
|
|
32
|
+
*
|
|
33
|
+
* Throws if the copy produced no files — the caller must not print a success banner over an empty
|
|
34
|
+
* directory. Returns nothing on success; `anchor` is guaranteed to exist relative to `dir`.
|
|
35
|
+
*/
|
|
36
|
+
export function copyScaffold(src, dir, anchor) {
|
|
37
|
+
mkdirSync(dir, { recursive: true });
|
|
38
|
+
cpSync(src, dir, {
|
|
39
|
+
recursive: true,
|
|
40
|
+
filter: (s) => {
|
|
41
|
+
// Normalise separators so the same pattern holds on Windows.
|
|
42
|
+
const rel = relative(src, s).split(/[/\\]/).join('/');
|
|
43
|
+
return rel === '' || !SKIP_DIR.test(rel);
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
if (!existsSync(join(dir, anchor))) {
|
|
47
|
+
throw new Error(`scaffold copy wrote no files into ${dir} (expected ${anchor}) — nothing was written, ` +
|
|
48
|
+
`so don't build here. Scaffold source: ${src}. ` +
|
|
49
|
+
`Please report this along with your install path: https://docs.abx.io`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/** @deprecated thin wrapper kept for the existing call sites/tests — prefer {@link copyScaffold}. */
|
|
53
|
+
export function copyRendererScaffold(src, dir) {
|
|
54
|
+
copyScaffold(src, dir, SCAFFOLD_ANCHOR);
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=scaffold.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAC,MAAM,SAAS,CAAC;AACtD,OAAO,EAAC,IAAI,EAAE,QAAQ,EAAC,MAAM,WAAW,CAAC;AAEzC;gEACgE;AAChE,MAAM,QAAQ,GAAG,wDAAwD,CAAC;AAE1E,6FAA6F;AAC7F,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC;AAE7D;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,GAAW,EAAE,MAAc;IACnE,SAAS,CAAC,GAAG,EAAE,EAAC,SAAS,EAAE,IAAI,EAAC,CAAC,CAAC;IAClC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE;QACf,SAAS,EAAE,IAAI;QACf,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE;YACZ,6DAA6D;YAC7D,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACtD,OAAO,GAAG,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC3C,CAAC;KACF,CAAC,CAAC;IACH,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CACb,qCAAqC,GAAG,cAAc,MAAM,2BAA2B;YACrF,yCAAyC,GAAG,IAAI;YAChD,sEAAsE,CACzE,CAAC;IACJ,CAAC;AACH,CAAC;AAED,qGAAqG;AACrG,MAAM,UAAU,oBAAoB,CAAC,GAAW,EAAE,GAAW;IAC3D,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,eAAe,CAAC,CAAC;AAC1C,CAAC"}
|
package/dist/schema.d.ts
CHANGED
|
@@ -1,15 +1,50 @@
|
|
|
1
|
-
import type { Hex } from 'viem';
|
|
1
|
+
import type { Address, Hex } from 'viem';
|
|
2
|
+
/** The `--schema` type/auth/format catalog, shown wherever the CLI nudges `--schema`. Kept accurate
|
|
3
|
+
* to the on-chain enums (PARAM_TYPES / AUTH_OPTIONS) + the Select-options / Range-bounds format —
|
|
4
|
+
* the old hint advertised non-existent `Anyone`/`Admin` auth legs. Used by both `deploy-code`
|
|
5
|
+
* (commands/deploy.ts) and `inspect` (commands/reads.ts), so it lives here beside the rest of the
|
|
6
|
+
* `--schema` machinery rather than in either command module. */
|
|
7
|
+
export declare const SCHEMA_CATALOG: string;
|
|
2
8
|
export interface ParsedSchema {
|
|
3
9
|
key: string;
|
|
4
10
|
paramType: number;
|
|
5
11
|
auth: number;
|
|
12
|
+
/** Required by (and only valid for) an Address-bearing auth leg; the contract pairs them strictly. */
|
|
13
|
+
authAddress: Address;
|
|
14
|
+
/** Unix seconds after which the VALUE can no longer change. 0 = never locks. A timestamp in the
|
|
15
|
+
* past locks it immediately and permanently — that is the supported way to retire a parameter. */
|
|
16
|
+
lockAfter: number;
|
|
6
17
|
min: Hex;
|
|
7
18
|
max: Hex;
|
|
8
19
|
selectOptions: string[];
|
|
9
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* A point in time for `lock=`: unix seconds, an ISO date, or `now` (which means "immediately and
|
|
23
|
+
* forever" — the retire idiom). Reuses the Timestamp encoder so `lock=2026-12-31` parses exactly
|
|
24
|
+
* like a `Timestamp[..]` bound does; one date grammar for the whole flag.
|
|
25
|
+
*/
|
|
26
|
+
export declare function parseWhen(raw: string): number;
|
|
10
27
|
export declare function parseSchemaSpec(spec: string): ParsedSchema;
|
|
11
28
|
/** Parse a full `--schema` value: comma-separated specs. */
|
|
12
29
|
export declare function parseSchemaSpecs(raw: string | undefined): ParsedSchema[];
|
|
30
|
+
/** The advisory an EDITION deploy needs before it commits to a schema, or `null` when there is
|
|
31
|
+
* nothing to say. Returned rather than printed so the deploy lane decides where it lands.
|
|
32
|
+
*
|
|
33
|
+
* Two things are true on an ERC-1155 edition and on nothing else, and a creator setting up their
|
|
34
|
+
* first collector-configurable drop will not have thought about either:
|
|
35
|
+
*
|
|
36
|
+
* 1. **Params are per id, so every holder of that id shares one value.** `TokenOwner` means ANY
|
|
37
|
+
* holder, and it is last-writer-wins. A "name your copy" schema does not name a copy — it
|
|
38
|
+
* renames the work for all 1,000 holders.
|
|
39
|
+
* 2. **A data param has no on-chain size budget.** One holder can store a large valid value under
|
|
40
|
+
* every declared key and make the shared id's `tokenURI` too expensive for common RPC limits —
|
|
41
|
+
* for every co-holder, permanently if a `lockAfter` then bites. That is a deliberate protocol
|
|
42
|
+
* choice (byte accounting on chain would cost every project to police a configuration almost
|
|
43
|
+
* nobody should use), which makes saying it here the actual mitigation.
|
|
44
|
+
*
|
|
45
|
+
* Both are fine when intended: a 1-of-1 edition behaves like a 721, and aggregate state (a counter,
|
|
46
|
+
* a shared mood) is exactly what shared params are good at. */
|
|
47
|
+
export declare function editionSchemaAdvisory(schemas: ParsedSchema[]): string | null;
|
|
13
48
|
/** A human one-line rendering of a parsed schema (for the confirm readout). */
|
|
14
49
|
export declare function describeSchema(s: ParsedSchema): string;
|
|
15
50
|
//# sourceMappingURL=schema.d.ts.map
|
package/dist/schema.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAC,OAAO,EAAE,GAAG,EAAC,MAAM,MAAM,CAAC;AAIvC;;;;iEAIiE;AACjE,eAAO,MAAM,cAAc,QAI+B,CAAC;AAK3D,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,sGAAsG;IACtG,WAAW,EAAE,OAAO,CAAC;IACrB;uGACmG;IACnG,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,GAAG,CAAC;IACT,GAAG,EAAE,GAAG,CAAC;IACT,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAID;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAU7C;AAQD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CA2F1D;AAED,4DAA4D;AAC5D,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,YAAY,EAAE,CAMxE;AAED;;;;;;;;;;;;;;;;gEAgBgE;AAChE,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,GAAG,IAAI,CA0B5E;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,CAatD"}
|