@artblocks/abx-cli 0.1.0-alpha.26 → 0.1.0-alpha.27

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 CHANGED
@@ -1,5 +1,116 @@
1
1
  # @artblocks/abx-cli
2
2
 
3
+ ## 0.1.0-alpha.27
4
+
5
+ ### Patch Changes
6
+
7
+ - b1c333d: **Asking for a 15% royalty built a transaction that reverted on chain.** `RoyaltyExtension` caps every
8
+ ABX token at **1000 bps (10%)** and reverts `RoyaltyTooHigh()` above it, and no token type overrides that.
9
+ But client-side validation allowed the full ERC-2981 `0–10000` range — and the CLI's own error text
10
+ offered `10000 = 100%` as a worked example. So a creator asking for an ordinary 15% got a fully built,
11
+ fully signed transaction that failed on chain; on the wallet lane they approved it in their own wallet
12
+ and paid the gas to find out. Both usage strings said `<0-10000>`, and so did two public docs.
13
+
14
+ Now `MAX_ROYALTY_BPS` (SDK) mirrors the contract ceiling and both `prepareSetRoyalty` and the CLI's
15
+ `parseRoyaltyBps` validate against it, so the refusal is instant, local and free, and it names the cap
16
+ and the revert. Regression tests cover it from both sides — including `1500`, the value that used to
17
+ sail through. Two existing tests had to be corrected: they asserted the 0–10000 bound, which is how this
18
+ survived.
19
+
20
+ Three more surfaces that contradicted themselves or the chain:
21
+
22
+ - **`abx ping-uri --help` claimed "Permissionless by design … ANY signer may call it (no owner check)"
23
+ four lines below its own `OWNER-ONLY` header** — and `Uri1155.pingURI` is `onlyOwner`. A non-owner
24
+ following the paragraph built a reverting tx.
25
+ - **`site/content/docs/reference/contracts.mdx`** described the pre-audit library architecture: it omitted
26
+ `AbxMetadataLib` (the fourth delegatecalled library, and the one linked by **all six** token types, not
27
+ three) and still said `SeriesCode` "rides the ceiling", where `deployments.mdx` — written after the same
28
+ redeploy — says both code types now sit under EIP-170 with room to spare.
29
+ - **`deployments.mdx`'s own `specVersion()` example printed `# → 10`** under a table declaring the renderer
30
+ spec v11. And **`operate.mdx`'s self-correction had rotted**: it warned that `abx refresh`'s advisory was
31
+ stale about editions and ERC-4906, but that advisory was fixed — the doc was now the stale one.
32
+
33
+ Found by two read-only audits (29 doc files, 19 spec files) that verified every claim against contracts,
34
+ compiled ABIs, SDK and live `--help` output before reporting. Both independently re-confirmed the
35
+ no-burn property, the v11 gateway design, all ~26 canonical addresses, and the on-chain storage
36
+ thresholds.
37
+
38
+ - b1c333d: **Every deploy lane accepted a royalty the chain would refuse.** `set-royalty` was fixed to validate
39
+ against the contract's 10% cap, but all six deploy paths (`deploy`, `deploy-series`, `deploy-code` and
40
+ their edition twins) still did a bare `Number(flags['royalty-bps'] ?? 500)` with no bound at all. So
41
+ `--royalty-bps 1500` built the whole deploy, printed **`royalty 15%`** in the confirmation readout — a
42
+ promise the chain will not keep — and reverted `RoyaltyTooHigh()` on send. That is the worse half of the
43
+ bug: the deploy is the expensive transaction, and on the wallet lane the creator approves it first.
44
+
45
+ All six now route through the same `parseRoyaltyBps` the owner op uses, so an over-cap value is refused
46
+ locally, for free, with the cap and the revert named.
47
+
48
+ **`abx doctor`'s pruned-history warning is now order-aware.** It fired for any reachable endpoint that
49
+ cannot serve archive-depth logs, even when a healthy archive endpoint sat ahead of it in the list and would
50
+ answer every deep scan. Three eval rooms independently called it noise — one said it was "a poor first
51
+ impression for an already-nervous creator". The hazard it exists for is real but specifically about
52
+ _ordering_: the fallback transport rotates on error only, so a pruning endpoint listed **first** answers a
53
+ deep scan with an empty, successful `[]`. `probeRpcEndpoints` preserves list order, so the warning now
54
+ fires only when the pruning endpoint is ahead of a full-archive one — the case a reader can act on. When
55
+ no archive endpoint is configured at all, it still fires for every pruning endpoint, because then nothing
56
+ shadows them.
57
+
58
+ - b1c333d: An agent using this skill built its own smart-contract system, and neither it nor the creator noticed
59
+ that the collection had stopped being a canonical ABX clone. Canonicity is decided by which contract
60
+ deployed a token and can never be added afterwards, so the fix is a gate before the first send plus a
61
+ readout that makes the loss discoverable.
62
+
63
+ **`abx state` now reports canonicity first.** It read owner, supply, royalty and renderer off any
64
+ ERC-721-shaped address and said nothing about whether it was a factory clone — so a hand-rolled contract
65
+ was described exactly as confidently as a canonical one, and the tool whose whole job is "what IS this
66
+ contract?" left nothing behind for the creator to find. `verifyCanonical` (SDK) probes all six trust
67
+ anchors' `isAbxClone` in one multicall and returns a true tri-state; a `false` prints what was lost, that
68
+ marketplaces and the App Store recognize collections by that signal, and that the only remedy is a fresh
69
+ deploy through the factory plus moving holders. `null` (no anchors on this chain, or an RPC failure) is
70
+ never shown as a "no".
71
+
72
+ **The skill gained the boundary rule it never had.** Its trust material lived on the _last line_ of the
73
+ file, written for someone verifying a clone from outside, and the "don't hand-roll" rules that existed
74
+ were narrow — preview pages, ABI writes, token queries, nothing about contracts. There is now a
75
+ Read-first gate: if the ask seems to need something the deploy commands don't do, stop and put it to the
76
+ creator in words, because building your own contracts is a legitimate choice a creator can make and
77
+ making it _for_ them silently is not. Alongside it, the list of what the toolkit does **not** do — no
78
+ burn (verified: zero `burn` entrypoints in `contracts/src`, previously a parenthetical clause inside a
79
+ sentence about hooks), no secondary listings, no mainnet, fixed-price sales only, no post-deploy script
80
+ replace — and the two extension points that keep a collection canonical (`set-minter`, param hooks), with
81
+ the caveat that a `--transfer` hook is a **veto, not a trigger**: it can refuse a transfer but never cause
82
+ a mint or a burn, so it cannot implement "combine two into one".
83
+
84
+ Verified by two trap rooms — a creator asking for a burn-to-combine mechanic with "you've got my
85
+ go-ahead, I don't need the technical parts". Both Sonnet and Haiku refused to build a contract, cited the
86
+ canonicity loss, and returned options. The Sonnet room found the route that _preserves_ canonicity and
87
+ offered it first.
88
+
89
+ **SKILL.md was restructured** against its own "lean decision-tree router" norm, which it had drifted
90
+ ~40% past: **68,449 → 55,392 characters (−20%)**, longest bullet 2,876 → 1,465, bullets over 600 chars
91
+ 27 → 14, with depth moved into the reference files that already owned it (locks → `decisions.md`;
92
+ install/`.env` → `setup.md`, which was a 44-line stub; data plane, App Store and deploy mechanics →
93
+ `operating.md`). Also repaired: a **markdown table split in two** by a blockquote sitting between its
94
+ rows, and **four dangling anchor links** (three pre-existing) — all 96 internal links now resolve.
95
+ `setup.md` was retitled and reordered after a control room found the required install steps buried under
96
+ a title that promised RPC troubleshooting.
97
+
98
+ **Two contradictions the verification sweep caught**, both the same class as the rest of this week's
99
+ fixes. `deploy-code --dry-run` printed `render/storage ✓ fs + --image-base` a few lines below
100
+ `⚠ render storage home is fs … placeholder forever`, for the identical setup; the ✓ is legitimately
101
+ scoped to whether the `--image-base` target is a valid mutable bucket (two tests pin that), so the row now
102
+ states what it covers and points at the other line rather than appearing to overrule it. And **"not
103
+ backfillable" was overstated** in three places — the truth, which `code-projects.md` had right all along,
104
+ is that fixing a surface after deploy costs an owner-signed re-point plus a re-render on a collection that
105
+ showed a placeholder in between. Expensive and worth avoiding; not impossible.
106
+
107
+ - Updated dependencies [b1c333d]
108
+ - Updated dependencies [b1c333d]
109
+ - @artblocks/abx-sdk@0.1.0-alpha.19
110
+ - @artblocks/abx-indexer@0.1.0-alpha.20
111
+ - @artblocks/abx-storage@0.1.0-alpha.19
112
+ - @artblocks/abx-token-api@0.1.0-alpha.22
113
+
3
114
  ## 0.1.0-alpha.26
4
115
 
5
116
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"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"}
@@ -26,7 +26,7 @@ import { isEditionContract } from '../kind.js';
26
26
  import { jsonSafe, withJson } from '../jsonout.js';
27
27
  import { planOnChainScript } from '../script-chunks.js';
28
28
  import { bold, c, dim, ensureFactory, ensureRenderer, ensureSeedSource, ensureSeriesCodeFactory, ensureSeriesFactory, ensureOneOfOneEditionFactory, ensureEditionFactory, ensureEditionCodeFactory, g, info, keepAlive, ok, p, portInUse, printServing, registerAndIndexLocally, reindexAfterDeploy, step, warn, } from '../output.js';
29
- import { AUTHORSHIP_DEPLOY_FIELDS, ONCHAIN_PROJECT_SOFT_LIMIT, ONCHAIN_READ_WARN_BYTES, tokenUriGasEstimate, authorshipContractFields, gatewayContractFields, servingGateway, computeContentPlan, envStagingSender, parseCompress, parseSeedSourceValue, canonicalSeedSource, refuseUnusableSeedSource, parseTransferValidatorValue, guardOnChainSize, previewImageStaging, refusePrewrappedImage, sessionStagingSender, stageImageField, stageImageFieldsBatch, } from '../ownerops.js';
29
+ import { parseRoyaltyBps, AUTHORSHIP_DEPLOY_FIELDS, ONCHAIN_PROJECT_SOFT_LIMIT, ONCHAIN_READ_WARN_BYTES, tokenUriGasEstimate, authorshipContractFields, gatewayContractFields, servingGateway, computeContentPlan, envStagingSender, parseCompress, parseSeedSourceValue, canonicalSeedSource, refuseUnusableSeedSource, parseTransferValidatorValue, guardOnChainSize, previewImageStaging, refusePrewrappedImage, sessionStagingSender, stageImageField, stageImageFieldsBatch, } from '../ownerops.js';
30
30
  import { canonicalLabel } from '../remote.js';
31
31
  import { assertLaneCanSign, confirmSend, gatedSend, laneFromFlags } from '../riskgate.js';
32
32
  import { describeSchema, editionSchemaAdvisory, parseSchemaSpecs } from '../schema.js';
@@ -634,7 +634,10 @@ export async function cmdDeployBody(flags, serveAfter, emit) {
634
634
  }
635
635
  const name = flags.name ?? 'ABX Self-Host Demo';
636
636
  const symbol = flags.symbol ?? 'ABXSH';
637
- const royaltyBps = Number(flags['royalty-bps'] ?? 500);
637
+ // Validate against the CONTRACT's cap here, not just in `set-royalty`: a bare Number() accepted
638
+ // 1500, printed "royalty 15%" in the confirmation readout, and then lost the whole deploy to a
639
+ // RoyaltyTooHigh() revert — the expensive tx, and one the creator had already approved.
640
+ const royaltyBps = flags['royalty-bps'] === undefined ? 500 : parseRoyaltyBps(String(flags['royalty-bps']));
638
641
  const port = Number(flags.port ?? process.env.ABX_PORT ?? DEFAULT_PORT);
639
642
  const baseUrl = flags['public-base-url'] ?? resolveBaseUrl(port);
640
643
  // Creator traits (real OpenSea attributes). Off-chain operator metadata by default (cheap,
@@ -1277,7 +1280,7 @@ export async function cmdDeployOneOfOneEditionBody(flags, emit) {
1277
1280
  const editionSize = parseCopies(flags.copies);
1278
1281
  const name = flags.name ?? 'ABX Edition';
1279
1282
  const symbol = flags.symbol ?? 'ABXE';
1280
- const royaltyBps = Number(flags['royalty-bps'] ?? 500);
1283
+ const royaltyBps = flags['royalty-bps'] === undefined ? 500 : parseRoyaltyBps(String(flags['royalty-bps']));
1281
1284
  const port = Number(flags.port ?? process.env.ABX_PORT ?? DEFAULT_PORT);
1282
1285
  const baseUrl = flags['public-base-url'] ?? resolveBaseUrl(port);
1283
1286
  const traits = parseDeployTraits(flags);
@@ -1638,7 +1641,7 @@ export async function cmdDeploySeriesBody(flags, emit) {
1638
1641
  warnSignWithoutFor(flags);
1639
1642
  const name = flags.name ?? 'ABX Series';
1640
1643
  const symbol = flags.symbol ?? 'ABXS';
1641
- const royaltyBps = Number(flags['royalty-bps'] ?? 500);
1644
+ const royaltyBps = flags['royalty-bps'] === undefined ? 500 : parseRoyaltyBps(String(flags['royalty-bps']));
1642
1645
  const port = Number(flags.port ?? process.env.ABX_PORT ?? DEFAULT_PORT);
1643
1646
  const baseUrl = flags['public-base-url'] ?? resolveBaseUrl(port);
1644
1647
  console.log(bold(`\n ABX Self-Host Toolkit — deploy series\n ${dim('a multi-token drop, served from chain alone')}`));
@@ -2199,7 +2202,7 @@ export async function cmdDeployEditionImageBody(flags, emit) {
2199
2202
  const editionSize = parseCopies(flags.copies);
2200
2203
  const name = flags.name ?? 'ABX Edition Series';
2201
2204
  const symbol = flags.symbol ?? 'ABXES';
2202
- const royaltyBps = Number(flags['royalty-bps'] ?? 500);
2205
+ const royaltyBps = flags['royalty-bps'] === undefined ? 500 : parseRoyaltyBps(String(flags['royalty-bps']));
2203
2206
  const port = Number(flags.port ?? process.env.ABX_PORT ?? DEFAULT_PORT);
2204
2207
  const baseUrl = flags['public-base-url'] ?? resolveBaseUrl(port);
2205
2208
  console.log(bold(`\n ABX Self-Host Toolkit — deploy edition series\n ${dim(editionSize === 0n
@@ -2952,7 +2955,7 @@ export async function cmdDeployCodeBody(flags, emit) {
2952
2955
  if (mintCount > max)
2953
2956
  throw new Error(`--mint-count ${mintCount} exceeds --max ${max}`);
2954
2957
  const paused = flags.unpaused === undefined;
2955
- const royaltyBps = Number(flags['royalty-bps'] ?? 500);
2958
+ const royaltyBps = flags['royalty-bps'] === undefined ? 500 : parseRoyaltyBps(String(flags['royalty-bps']));
2956
2959
  const port = Number(flags.port ?? process.env.ABX_PORT ?? DEFAULT_PORT);
2957
2960
  const baseUrl = (flags['public-base-url'] ?? resolveBaseUrl(port)).replace(/\/$/, '');
2958
2961
  const hasPublicUrl = !!(flags['public-base-url'] || process.env.ABX_PUBLIC_BASE_URL);
@@ -3434,7 +3437,7 @@ export async function cmdDeployCodeBody(flags, emit) {
3434
3437
  (transferValidator !== zeroAddress ? ` ERC-721C: enrolled at deploy, permanently (validator ${transferValidator}).` : '') + `\n` +
3435
3438
  ` Surfaces — thumbnail: ${imageDisposition}. traits: ${traitsDisposition}. postparams: ${paramsDisposition}.` +
3436
3439
  ((imageOrphaned || traitsBroken || undeclaredParams.length)
3437
- ? `\n ⚠ One or more surfaces resolve to NOTHING marketplaces can see these are DEPLOY-TIME decisions, not backfillable. Re-run --dry-run after fixing, or pass --yes to ship as-is.`
3440
+ ? `\n ⚠ One or more surfaces resolve to NOTHING marketplaces can see. Settle them now: fixing one after deploy is an owner-signed re-point + re-render, on a collection that showed a placeholder in between. Re-run --dry-run after fixing, or pass --yes to ship as-is.`
3438
3441
  : ''), flags);
3439
3442
  }
3440
3443
  // --dry-run: emit the full plan (the on-chain values the skill formats into its confirm table),
@@ -3567,16 +3570,18 @@ export async function cmdDeployCodeBody(flags, emit) {
3567
3570
  // were already set. The alarm now covers only the surfaces it can honestly speak for, and names
3568
3571
  // only the remedies for what is actually broken.
3569
3572
  const anySurfaceBroken = imageOrphaned || traitsBroken;
3570
- step('Surfaces — what marketplaces will see (all DEPLOY-TIME; not backfillable)');
3573
+ step('Surfaces — what marketplaces will see (settle them NOW; fixing one later is an owner-signed re-point + re-render)');
3571
3574
  (imageOrphaned ? warn : info)(`thumbnail: ${imageDisposition}`);
3572
3575
  // Render-mode / render-home guidance is for the RENDERED-still lanes only. The in-chain
3573
3576
  // Solidity image (--image-renderer) has no off-chain still — nothing to render, host, or refresh.
3577
+ // Hoisted: the `render/storage` row further down needs the same fact, so that a managed provider
3578
+ // (which owns rendering) never trips the fs warning there either.
3579
+ let renderAttached = false;
3574
3580
  if (!imageOrphaned && !hasImageRenderer) {
3575
3581
  if (!hasPublicUrl)
3576
3582
  info(` ${dim('render mode (a still is never on-chain):')} ${bold('service')} (auto-render every mint/param change — a live/for-sale drop) · ${bold('once')} (fixed supply) · ${bold('none')} (placeholder). ${dim('freshness: no resolver ⇒ no chain-watcher ⇒ MANUAL/backfill (`abx render` after mints + each param change; the on-chain animation updates live, the bucket still does NOT). Continuous/live stills ⇒ run a resolver.')}`);
3577
3583
  // A managed provider whose descriptor says `render.attached` owns rendering — local
3578
3584
  // ABX_STORAGE_BACKEND is irrelevant, and warning "placeholder forever" is a lie.
3579
- let renderAttached = false;
3580
3585
  if (hasPublicUrl && !loopbackBaseUrl(baseUrl)) {
3581
3586
  try {
3582
3587
  const d = await new AbxServiceClient({ baseUrl, timeoutMs: 2_500 }).descriptor();
@@ -3642,8 +3647,24 @@ export async function cmdDeployCodeBody(flags, emit) {
3642
3647
  cloudHasPublicBase: renderStorageBackendId === 'cloud' ? !!renderStorageOpts.cloud?.publicBase : undefined,
3643
3648
  publishesToRemoteResolver: !hasImageRenderer && !(onChainUri && hasImageBase),
3644
3649
  });
3645
- if (renderStorageCombo.ok)
3646
- info(`render/storage ✓ ${renderStorageBackendId}${hasImageBase ? ' + --image-base' : ''}`);
3650
+ // `validateRenderStorageCombo` deliberately scopes itself to the --image-base URL SHAPE and the
3651
+ // remote-resolver lane, so it returns ok for `fs` + --image-base while the render-home check a
3652
+ // few lines above correctly warns that an fs home means nothing ever uploads the still to that
3653
+ // bucket. Both lines described the same setup and only one said it was broken, and a creator
3654
+ // skimming for the checkmark reads ✓ as approval. The row now defers to that warning rather than
3655
+ // overriding it: same fact, one verdict.
3656
+ // This row is deliberately scoped to whether the --image-base TARGET is valid (a mutable bucket,
3657
+ // not a content-addressed gateway) and whether a remote resolver could fetch what we store — it
3658
+ // is NOT a verdict on the render home, which has its own warning above. Unqualified, though, a
3659
+ // bare `✓ fs + --image-base` sat a few lines under "render storage home is fs … placeholder
3660
+ // forever" and read as though it overruled it. Name what the ✓ covers, and point at the other
3661
+ // line when that one is unhappy, so one setup stops producing two verdicts.
3662
+ const fsHomeUnresolved = renderHome === 'fs' && !renderAttached && !imageOrphaned && !hasImageRenderer;
3663
+ if (renderStorageCombo.ok) {
3664
+ const scope = hasImageBase ? '--image-base is a valid mutable target' : `${renderStorageBackendId} can serve what it stores`;
3665
+ info(`render/storage ✓ ${scope}` +
3666
+ (fsHomeUnresolved ? dim(` — but the render home is still ${bold('fs')}; see the warning above, this ✓ does not cover it`) : ''));
3667
+ }
3647
3668
  else
3648
3669
  warn(`render/storage ✗ ${renderStorageCombo.reason}`);
3649
3670
  }
@@ -4118,7 +4139,7 @@ export async function cmdDeployEditionCodeBody(flags, emit) {
4118
4139
  throw new Error('--mint-amount 0 with ids being pre-minted at deploy makes no sense — pass a positive --mint-amount, or drop --mint-all/--mint-count to defer minting entirely.');
4119
4140
  }
4120
4141
  const paused = flags.unpaused === undefined;
4121
- const royaltyBps = Number(flags['royalty-bps'] ?? 500);
4142
+ const royaltyBps = flags['royalty-bps'] === undefined ? 500 : parseRoyaltyBps(String(flags['royalty-bps']));
4122
4143
  const port = Number(flags.port ?? process.env.ABX_PORT ?? DEFAULT_PORT);
4123
4144
  const baseUrl = (flags['public-base-url'] ?? resolveBaseUrl(port)).replace(/\/$/, '');
4124
4145
  const hasPublicUrl = !!(flags['public-base-url'] || process.env.ABX_PUBLIC_BASE_URL);