Skip to content

Preprod#229

Open
QSchlegel wants to merge 72 commits into
mainfrom
preprod
Open

Preprod#229
QSchlegel wants to merge 72 commits into
mainfrom
preprod

Conversation

@QSchlegel
Copy link
Copy Markdown
Collaborator

No description provided.

Andre-Diamond and others added 27 commits March 30, 2026 08:26
- Added support for an optional `paymentNativeScript` parameter in the createWallet API, allowing users to specify a custom payment script tree.
- Implemented validation to ensure the script structure adheres to required formats and that key hashes match the provided signers' addresses.
- Updated related tests to cover new functionality and ensure robust handling of various script configurations.
- Enhanced API documentation to reflect the new parameter and its usage.
- Create initial ci bot testing framework files
- Added `.gitignore` entry for CI local artifacts.
- Changed `init-db.sh` to use `sh` instead of `bash`.
- Updated `docker-compose.ci.yml` to correctly handle status variable in commands.
- Enhanced CI scripts to support multisig wallet ring transfers, including detailed documentation updates.
- Refactored transfer flow to ensure distinct source and destination wallet types for transactions.
- Improved error handling and validation in wallet script resolution logic.
- Updated README.md to clarify real transfer construction and validation notes for preprod scenarios.
- Added checks in run-route-chain.ts to ensure preprod context and testnet address validation.
- Enhanced bot authentication logic in botAuth.ts with caching and retry mechanisms.
- Improved transfer flow in transferFlow.ts to validate wallet addresses and ensure sufficient UTxO availability for transactions.
- Refactored transaction building logic to utilize MeshTxBuilder for better handling of multisig inputs.
- Updated bot authentication logic in botAuth.ts to provide clearer error messages by including the status of the authentication response.
- Enhanced test setups across multiple test files to ensure consistent initialization of session-related properties, including sessionWallets and primaryWallet.
- Refactored mock implementations in various tests for better type safety and clarity.
- Removed wallet_types input from the CI workflow configuration for simplicity.
- Added conditional execution for the multisig-v1-smoke job based on the repository.
- Updated README.md to clarify the role of native scripts in CI and added details about script payload storage.
- Implemented a new function to fetch native scripts for different wallet types in the manifest, enhancing the route health checks.
- Added additional redaction rules for sensitive information in CI logs, including mnemonics and private keys.
- Updated `create-wallets.ts` to remove transaction ID from created wallets, reflecting changes in transaction handling.
- Modified `run-pending-transactions-smoke.ts` to focus on specific pending scenarios and improve error messaging.
- Refactored context validation to make transaction ID optional, ensuring compatibility with new wallet creation logic.
- Cleaned up scenario manifest by removing obsolete pending transaction checks and clarifying wallet discovery steps.
- Updated wallet creation logic in `create-wallets.ts` to include additional scopes: `governance:read` and `ballot:write`.
- Enhanced `README.md` to document new wallet authentication and governance features, including detailed descriptions of new routes and scenarios.
- Added new scenarios in `manifest.ts` for bot identity verification and wallet authentication checks, improving overall CI coverage.
- Introduced a new `walletBalanceSummary` object in `ci-route-chain-report.json` to capture total on-chain balances per wallet.
- Updated `runScenarios` to collect wallet balance data and include it in the run report.
- Defined new types for wallet balance entries and summaries in `types.ts` to support the new reporting feature.
- Enhanced documentation in `README.md` to explain the structure and semantics of the wallet balance summary.
- Removed obsolete scripts: `create-wallets.ts`, `run-route-chain.ts`, `inspect-context.ts`, `run-pending-transactions-smoke.ts`, `sign-transaction-preprod.ts`, and `template-route-step.ts`.
- Introduced new CLI structure under `scripts/ci/cli/` with `bootstrap.ts` and `route-chain.ts` for improved organization.
- Updated `docker-compose.ci.yml` to reflect changes in script execution.
- Revised documentation in `README.md` to align with new script structure and clarify CI stages.
- Adjusted scenario descriptions in `manifest.ts` to reference new script locations.
- Modified scenario functions in `manifest.ts`, `authPlane.ts`, `datum.ts`, and `governance.ts` to accept `CIBootstrapContext` as a parameter for improved context handling.
- Updated execution logic in scenarios to utilize the provided context, enhancing flexibility and maintainability.
- Adjusted scenario descriptions to reflect changes in wallet type handling and ensure consistency across different scenarios.
- Updated `docker-compose.ci.yml` to include a new step for checking wallet status after bootstrap.
- Expanded `README.md` to clarify the CI process, detailing the new `wallet-status.ts` script and its role in confirming wallet funding.
- Modified `bootstrap.ts` to derive and store signer stake addresses, and updated the context schema to version 3 to accommodate new fields.
- Enhanced `inspect-context.ts` to display signer stake addresses and SDK multisig reward address.
- Adjusted context validation in `context.ts` to ensure compatibility with the new schema and added checks for signer stake addresses.
- Introduced new API endpoints `/api/v1/botStakeCertificate` and `/api/v1/botDRepCertificate` for building stake and DRep transactions, respectively.
- Updated `package.json` to include new unit tests for the added functionality.
- Enhanced `README.md` with detailed usage instructions for the new endpoints.
- Refactored `addTransaction.ts` to streamline transaction creation for multisig wallets.
- Updated `freeUtxos.ts` to improve UTxO resolution logic.
- Modified `stake.tsx` to integrate new staking action configurations.
…ependencies

Added "dev": true to multiple entries in package-lock.json, indicating that these packages are development dependencies. This change helps clarify the purpose of these packages in the project.
ROADMAP.md seeded from docs/roadmap-v3 and extended with a
Task ownership section splitting all 12 months of work into
per-contributor lists, plus a Month 1 proof-of-completion
table tracking actual status of each M1 task.

CONTRIBUTING.md captures the review process, branch and
commit conventions, PR checklist, and merge rules. Contributions
are accepted against preprod, which graduates to main after
clean runs in the preprod environment.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
docs: add roadmap and contributing guide
- Refactor botDRepCertificate to streamline transaction input handling and certificate script application.
- Update botStakeCertificate to utilize a unified spend script for transaction inputs.
- Introduce fresh query parameter in freeUtxos to allow fetching unspent transaction outputs directly from the blockchain.
- Implement stake key witness validation in signTransaction to support transactions with staking certificates.
- Add new flow for signing stake certificates that includes both payment and stake key witnesses.
- Create comprehensive CI scenarios for DRep registration and retirement, as well as stake registration and deregistration.
- Implement stakeAccountInfo API to fetch stake account status and pool information.
Reject unparseable txCbor/txJson at the addTransaction API boundary so a
malformed 4-element CBOR can never be persisted, and render a degraded
card with a Reject button when an existing row's txJson cannot be
parsed, so a single bad row no longer crashes the whole Transactions
page and locks up its UTxOs.

Closes #211

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- #223 marked Done — PR #225 merged, issue closed
- #211 moved to In review — PR #227 open with API validation + degraded card
- External PRs row updated with review status (#212 awaiting rebase, #208 superset)
- #213 note clarifies CI smoke is skipping due to missing SMOKE_* secrets

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
docs: refresh M1 proof of completion (2026-04-23)
Build-phase migrations fail on Railway because postgres.railway.internal
is only reachable at runtime. The prestart hook already handles this.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
fix: guard against invalid CBOR in addTransaction and transaction card
Adds deployment_status trigger so smoke runs against the freshly deployed
preprod environment. Filters to Railway bot + preprod env, and checks out
the exact deployed SHA.

Note: deployment_status only fires from workflows on the default branch,
so this must also land on main for the trigger to activate.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 23, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
multisig Ready Ready Preview, Comment May 29, 2026 12:15pm

Request Review

@railway-app railway-app Bot temporarily deployed to victorious-warmth / preprod April 23, 2026 13:00 Inactive
Andre-Diamond and others added 9 commits May 22, 2026 16:14
- Updated `proxySpend.ts` and `proxyVote.ts` to use `selectAuthTokenUtxo` for selecting the auth token UTxO, incorporating blocked UTxO references.
- Introduced new utility functions in `utxoUtils.ts` for selecting UTxOs and checking asset presence.
- Added comprehensive tests for UTxO selection logic in `proxy-utxo-selection.test.ts`.
- Created `txBuilders.ts` to encapsulate transaction building logic for proxy actions, including setup, spending, voting, and DRep certificate management.
- Implemented cross-verification tests in `proxy-cross-verify.test.ts` to ensure consistency between direct and browser-based transaction builders.
…st the tx body

A user submitting a "Ballot Vote" on a 2-of-3 DRep multisig hit
`ConwayUtxowFailure (InvalidWitnessesUTXOW [VKey ce7cbe8f...])`. Decoding the
failing tx with this repo's CSL showed the witness's vkey hashes to a *valid*
script signer, but its Ed25519 signature does not verify against the tx body
hash. The body itself is byte-stable across CSL round-trips, so the wallet
must have signed a different (re-canonicalised) body.

Cause: package.json had `^1.9.0-beta.87` on @meshsdk/core/core-csl/core-cst/
provider/react; the lockfile had drifted to 1.9.0-beta.102. Some patch in
those 15 betas changed how Mesh emits CBOR (likely voting_procedures), so
app-built bodies no longer match what the wallet's encoder produces — the
wallet's signature verifies against its body but not ours.

Fix:
- Pin Mesh deps to exact .87 (.86 for provider) — no more silent patch drift.
- `mergeSignerWitnesses` returns `{ txHex, invalidVkeyPubKeysHex }`,
  verifying each newly-merged vkey's signature against the merged tx body
  hash. Witnesses already on the tx are not re-verified.
- transaction-card.signTx() and useTransaction.newTransaction() abort with a
  destructive toast (and skip submission + persistence) when the wallet
  returns a witness that doesn't verify. Offending pubkey is logged for
  debugging. The wallet user gets an actionable message instead of a chain
  rejection.
- jest.config.mjs: one-line moduleNameMapper for libsodium-wrappers-sumo's
  broken relative `./libsodium-sumo.mjs` import (pre-existing CI gap).
- .gitattributes: mark package-lock.json as linguist-generated so diff
  reviewers can skip the lockfile churn.

Test plan:
- New unit test `mergeSignerWitnesses.test.ts`: 3 cases (happy, mismatched
  body, pre-existing witness preserved) — all pass.
- `npx tsc --noEmit` on touched files: clean.
- Manual: decoded the user-shared failing txCbor; confirmed
  `blake2b-224(vkey) == 'f6ed79ef...'` (valid signer) but
  `pk.verify(body, sig)` is false. The new guard catches exactly this case
  before submit.
- Pre-existing test failures on preprod (proxyCiPreflight, proxyDRepInfo,
  signTransaction mock missing isBotJwt, pendingTransactions, apiSecurity)
  are in files unrelated to this fix.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…resolution

The 0.7.16 release ships `dist/modules-sumo-esm/libsodium-wrappers.mjs` with
a relative `import "./libsodium-sumo.mjs"` whose target file isn't in the
package — the actual sumo binary lives in the separate `libsodium-sumo`
package and is wired up via package.json `exports`. Node's strict ESM
resolver (used by `tsx` in the CI smoke runner, and by Next.js at build
time) doesn't follow the cross-package indirection and throws
`ERR_MODULE_NOT_FOUND` before any Mesh helper has a chance to run.

Preprod's pre-existing lockfile pinned 0.7.10, which works. Regenerating the
lockfile to land the Mesh pin pulled 0.7.16 (the latest in the ^0.7.5 range
the cardano-sdk transitively allows), breaking both `multisig-v1-smoke` and
the Vercel build. Override to 0.7.10 forces all `@cardano-sdk/crypto`
copies onto the working version.

Verified: `node --input-type=module -e "import('@meshsdk/core')"` now
succeeds (failed before the override). Unit tests still pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… first signer

CI failure on the previous push exposed two issues with my initial pin to
.87:

1. **Smoke test "libsodium not initialized"**: pinning Mesh to `.87` pulled
   in different `@cardano-sdk/*` transitive versions than preprod's known-
   good lockfile, and the resulting libsodium-wrappers-sumo / libsodium-sumo
   combination fails WASM init under Node 20 in CI. Preprod runs Mesh
   `.102` for `core/core-csl/core-cst`, `.100` for `provider`, `-40` for
   `react`, and its smoke test passes — so pin to those exact versions.

2. **Pin alone doesn't fix the user**: with `.102` we're back on the same
   CBOR-encoding Mesh that broke their wallet's signature in the first
   place. The verify guard added in the previous commit converts that into
   a friendly error, but the user still can't vote.

   Extended `mergeSignerWitnesses`: when the wallet returns a full signed
   Transaction (not just a witness set), and its body bytes differ from
   ours, and we have no pre-existing witnesses to invalidate, *use the
   wallet's body*. The wallet's vkey signature was made over its body, so
   adopting it makes the signature verify and lets the submit succeed.
   This handles the first-signer case — which is the typical case for
   "I clicked Approve & Sign and it failed" — without changing behaviour
   for multi-signer flows where prior witnesses would be invalidated.

Also dropped the libsodium override commit's package.json entry — it's not
needed once we match preprod's exact Mesh versions, and trying to pin
`libsodium-sumo` to 0.7.10 broke Node 22's WASM loader.

Added unit test covering the body-swap recovery path; existing 3 tests
still pass (4 total).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…alpine

The previous push's lockfile was generated with my local npm 11.10.1, which
produces a `lockfileVersion: 3` lockfile npm 10 considers inconsistent:
`@simplewebauthn/browser@9.0.1` + `@simplewebauthn/types@9.0.1` were marked
"Missing from lock file" and `npm ci` refused to proceed in the Dockerfile.ci
build step. (CI runs `node:20-alpine`, which bundles npm 10.8.2 — the same
notice line in the failure log.)

Same fix the repo has applied twice before: regenerate with the matching
npm version. Confirmed:
- lockfile contains 14 @simplewebauthn entries
- Mesh resolved to the pinned versions (.102 / .100 / -40)
- mergeSignerWitnesses tests still 4/4 pass

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ild green

Vercel's previous attempts failed during webpack compile with:
  Module build failed: UnhandledSchemeError: Reading from "node:crypto" /
  "node:process" is not handled by plugins (Unhandled scheme).
  Import trace: @peculiar/webcrypto → @meshsdk/web3-sdk → @meshsdk/react

`@peculiar/webcrypto@1.7.x` switched its compiled output from `require('crypto')`
to ESM `import "node:crypto"`. webpack 5 (Next 16 `--webpack` mode) doesn't
handle the `node:` scheme without an explicit plugin, and we don't want to
add one — preprod's known-good lockfile resolves to `1.5.0`, which still
uses bare `crypto`. Regenerating the lockfile after pinning Mesh re-resolved
this to `1.7.1` (latest matching `^1.5.0`), reintroducing the issue. Pin to
1.5.0 to match preprod.

Verified: with the override, `node:` imports no longer appear in the webpack
trace; the residual local build failure is missing
`NEXT_PUBLIC_BLOCKFROST_API_KEY_PREPROD` env (Vercel has it set).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…handling

- Updated proxy transaction APIs to utilize `completeTxWithFreshCostModels` for transaction completion, enhancing cost model handling.
- Adjusted `getTxBuilder` to accept a flag for using the CSL serializer, improving flexibility in transaction building.
- Enhanced unit tests for proxy cleanup, setup, spend, vote, and DRep certificate APIs to validate the new transaction completion logic.
- Added error handling for PPView hash mismatches during transaction submission, ensuring better feedback on transaction integrity issues.
…e tests

- Refactored imports to streamline the usage of `completeTxWithFreshCostModels` across the codebase.
- Updated unit tests to reflect changes in cost model handling, including support for raw arrays and ordering of indexed cost model objects.
- Added new test cases to validate the rejection of improperly ordered cost model objects, ensuring robustness in transaction processing.
…eprod

fix(signing): pin Mesh SDK + reject witnesses that don't verify against the tx body
Andre-Diamond and others added 4 commits May 25, 2026 08:02
Adds an Import Wallet entry point alongside New Wallet with a single-page
wizard covering four sources: another multisig instance (deep link or
root URL + signer picker, with CIP-30 nonce-sign against the origin),
Summon (forwards into the existing /wallets/invite flow), manual
native-script CBOR paste, and JSON backup upload. Wires up a paired
Download JSON backup action on the wallet info page so users can
round-trip exports between instances.

Backend: new wallet.importWallet/exportWallet tRPC procedures sharing
the wallet.createWallet write path, plus /api/v1/exportWallet/{getNonce,
redeem,listMine} cross-instance endpoints that reuse the existing CIP-8
checkSignature verification. No Prisma schema change — provenance lives
in the existing rawImportBodies JSON, with a lockedSigners flag the
wallet info Edit Signers gate respects so imported wallets can't
silently diverge from their origin.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The audit observability module hasn't landed on preprod yet, so the
audit() call I copied from other procedures in main's version of this
file was unresolved at build time. Drop it for now; can be re-added
once main's observability work merges into preprod.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Conflict resolution
- jest.config.mjs: union both moduleNameMapper entries (libsodium ESM
  redirect from preprod + styleMock from main)
- package.json: keep preprod's expanded bot test scripts and Mesh SDK
  1.9.0-beta.102 pins; honor main's removal of @jinglescode/nostr-chat-
  plugin (no remaining source refs on either branch)
- package-lock.json: regenerated from the merged package.json
- src/__tests__/{apiSecurity,botBallotsUpsert,governanceActiveProposals,
  signTransaction}.test.ts: take preprod; tighter generics and preprod-
  shaped tRPC ctx (sessionWallets/primaryWallet) match the live router
- src/components/pages/wallet/transactions/transaction-card.tsx: take
  preprod's defensive JSON.parse guard (#211 — malformed txJson must not
  crash the Transactions page)

Security fixes flagged by CodeQL on the merge
- src/lib/server/resolveDRepAnchorFromUrl.ts: close the DNS-rebinding
  TOCTOU window. assertUrlSafeForFetch now returns the resolved IP, and
  the fetch goes through an undici Agent with a buildConnector-pinned
  lookup so the actual TCP connect uses the pre-validated IP. Switched
  from global.fetch to undici.request for the same reason; existing
  hostname blocklist, private/loopback IP rejection, redirect=error,
  body size cap and timeout are all preserved.
- src/__tests__/resolveDRepAnchorFromUrl.test.ts: mock undici instead of
  global.fetch to match the new transport.
- scripts/ci/framework/markdown.ts: rewrite escapeCell as a single
  character-class regex (\\ and | escaped in one pass) so there's no
  ordering ambiguity that triggers js/incomplete-sanitization.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
QSchlegel and others added 2 commits May 26, 2026 10:51
git's three-way merge of preprod←main reported a clean merge of
prisma/schema.prisma and src/server/api/trpc.ts but silently dropped
main's additions — both files had only end-of-file additions on main,
which the auto-merge resolved by taking preprod's tail without pulling
in main's new symbols. The Vercel build then failed on three downstream
references.

prisma/schema.prisma
- Add model AuditLog (referenced by src/lib/observability/audit.ts;
  migration 20260510160404_audit_log_and_indexes already in the tree)
- Make User.nostrKey String? (matches migration
  20260510170000_make_user_nostrkey_optional)

src/server/api/trpc.ts
- Re-export TRPCContext and AuthCtx (used by src/server/api/auth.ts
  added in main's audit-log PR)

Drop the Nostr chat system on preprod to match main
- Remove src/components/pages/wallet/chat and src/pages/wallets/[wallet]/chat
- Drop @jinglescode/nostr-chat-plugin imports from _app.tsx + layout.tsx
- Remove the Chat menu entry from the wallet sidebar
- userRouter.createUser: nostrKey becomes optional (matches the now-
  nullable column) and is only written when supplied
- User profile page: scope nostrKey to a non-null local inside the
  existing `user.nostrKey &&` guard so it still renders for legacy
  users without tripping the nullable narrowing

The repo's nostr-chat-plugin dep was already removed in the prior
merge commit; this commit removes the last call sites and brings the
user-row contract in line with the schema.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
merge(preprod): resolve PR #229 conflicts + fix CodeQL findings
- Updated README.md to reflect new CI stages and detailed descriptions for proxy-related scripts.
- Refactored proxyBot.ts to utilize new UTxO selection utilities for setup and auth token UTxOs.
- Added unit tests for new UTxO selection functions: selectSetupUtxo and accumulateFundingUtxos.
- Improved proxy transaction builders to accumulate funding UTxOs and ensure sufficient lovelace for operations.
- Implemented cleanupProxy method in MeshProxyContract to handle proxy UTxO cleanup and burning of auth tokens.
- Enhanced error handling for insufficient lovelace scenarios in proxy operations.
…ng-alignment

Refactor/ci-and-browser-tx-building-alignment
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.

3 participants