Skip to content

sdk: round-2 CLI follow-ups — producer guards, DRY, build-bid parity, coverage (#0422-#0427)#242

Merged
trevormil merged 1 commit into
mainfrom
feat/0422-0427-cli-followups-r2
May 15, 2026
Merged

sdk: round-2 CLI follow-ups — producer guards, DRY, build-bid parity, coverage (#0422-#0427)#242
trevormil merged 1 commit into
mainfrom
feat/0422-0427-cli-followups-r2

Conversation

@trevormil
Copy link
Copy Markdown
Collaborator

Summary

Round-2 audit follow-ups on the post-#241 CLI/SDK surface (same angles as #240/#241: frontend-parity, producer-side correctness, DRY, test-bar). Six tickets, behavior + coverage.

  • #0422 toBaseUnits now throws on negative / non-finite / precision-losing amounts instead of silently Math.round-coercing — the bb build * JSON-input path bypassed resolveAmount's guard, so every amount-taking builder was exposed. bb build product-catalog maxSupply rejects negative/non-integer instead of silently emitting an unlimited catalog (0/omitted = unlimited stays, documented).
  • #0423 Shared splitCsv (cli/utils/csv-options.ts) replaces two byte-identical private clones (dynamic-stores, price) + three inlined sites (assets, pools, pairs). resolveRecipientList (address.ts) dedups the split→trim→filter→requireBb1AddressStrict sequence in custom-2fa + dynamic-stores.
  • #0424 bb build bid reaches parity with bb nfts bid: omit --token-ids ⇒ collection-wide bid; new --token-amount; --expiration accepts ms-since-epoch (new core resolveExpiration) — it was duration-only and silently rejected the ms input its sibling's --help advertises.
  • #0425 Producer↔recognizer drift guard: buildSubscription output is run through the indexer's bigint normalization and asserted to satisfy isSubscriptionFaucetApproval + doesCollectionFollowSubscriptionProtocol (single + multi-tier). Closes the 0407-class gap where the sole producer and the bb subscriptions status|claim|charge-due consumers could drift apart with a green suite.
  • #0426 Determinism stragglers: custom-2fa / quests / pm-buy-intent gain two-call byte-identical tests; bounty strengthened from proposalId-only to a full msg-equal with the Date.now expiry window normalized out (not flaky).
  • #0427 bb subscriptions enable-renewal|subscribe --approval-id (#0418): shape test + integration pin assertion.

Scope notes

  • 0423: build.ts subscription-payouts loop left as-is (it validates a JSON object array per-element, not a comma-string split — not the same resolution logic; adopting the helper would be churn).
  • 0426: did not add expectCleanVerification to the 5 delegating approval builders. Verified verifyStandardsCompliance only traverses collectionApprovals, so it would pass a MsgSet*Approval vacuously — the masking anti-pattern. Delegation-parity + integration chain-acceptance remain the contract (reconfirms #0421's documented call).

Validation

  • Build clean — tsc ×2, no circular dependencies.
  • Unit: 140 suites / 3077 tests green (+1 suite, +25 tests).
  • Integration: 20 suites / 186 tests green (devnet live).

Test plan

  • bun run build clean
  • bun run test:unit green
  • bun run test:integration green
  • Spot-check bb build bid --address … --collection-id 1 --price 5 --denom USDC (no --token-ids) emits a collection-wide bid
  • bb build product-catalog with a negative maxSupply now errors

🤖 Generated with Claude Code

… coverage (#0422-#0427)

0422 toBaseUnits throws on negative/non-finite/precision-losing amounts
     (the bb build * JSON-input path bypassed resolveAmount's guard);
     product-catalog maxSupply rejects negative/non-integer instead of
     silently going unlimited.
0423 shared splitCsv (cli/utils/csv-options) replaces 2 byte-identical
     clones + 3 inlined sites; resolveRecipientList (address.ts) dedups
     the split+strict-bb1 sequence in custom-2fa + dynamic-stores.
0424 bb build bid reaches parity with bb nfts bid: collection-wide bid
     when --token-ids omitted, new --token-amount, ms-since-epoch
     --expiration (via new core resolveExpiration) — was duration-only.
0425 producer↔recognizer drift guard: buildSubscription output is run
     through the indexer's bigint normalization and asserted to satisfy
     isSubscriptionFaucetApproval + doesCollectionFollowSubscriptionProtocol.
0426 determinism stragglers: custom-2fa / quests / pm-buy-intent gain
     two-call byte-identical tests; bounty strengthened to a full
     msg-equal (Date.now expiry window normalized out).
0427 subscriptions enable-renewal/subscribe --approval-id covered:
     shape test + integration pin assertion.

Build clean (no circular deps); unit 140 suites / 3077 tests;
integration 20 suites / 186 tests.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant