May 03, 9-10 AM (3)
May 03, 10-11 AM (10)
May 03, 11-12 PM (11)
May 03, 12-1 PM (16)
May 03, 1-2 PM (11)
May 03, 2-3 PM (2)
May 03, 3-4 PM (2)
May 03, 4-5 PM (5)
May 03, 5-6 PM (0)
May 03, 6-7 PM (5)
May 03, 7-8 PM (6)
May 03, 8-9 PM (8)
May 03, 9-10 PM (15)
May 03, 10-11 PM (23)
May 03, 11-12 AM (17)
May 04, 12-1 AM (4)
May 04, 1-2 AM (4)
May 04, 2-3 AM (10)
May 04, 3-4 AM (9)
May 04, 4-5 AM (5)
May 04, 5-6 AM (6)
May 04, 6-7 AM (6)
May 04, 7-8 AM (28)
May 04, 8-9 AM (26)
May 04, 9-10 AM (43)
May 04, 10-11 AM (36)
May 04, 11-12 PM (61)
May 04, 12-1 PM (34)
May 04, 1-2 PM (49)
May 04, 2-3 PM (64)
May 04, 3-4 PM (33)
May 04, 4-5 PM (64)
May 04, 5-6 PM (49)
May 04, 6-7 PM (13)
May 04, 7-8 PM (32)
May 04, 8-9 PM (45)
May 04, 9-10 PM (9)
May 04, 10-11 PM (54)
May 04, 11-12 AM (24)
May 05, 12-1 AM (4)
May 05, 1-2 AM (5)
May 05, 2-3 AM (5)
May 05, 3-4 AM (11)
May 05, 4-5 AM (11)
May 05, 5-6 AM (50)
May 05, 6-7 AM (16)
May 05, 7-8 AM (37)
May 05, 8-9 AM (81)
May 05, 9-10 AM (68)
May 05, 10-11 AM (34)
May 05, 11-12 PM (72)
May 05, 12-1 PM (115)
May 05, 1-2 PM (118)
May 05, 2-3 PM (66)
May 05, 3-4 PM (91)
May 05, 4-5 PM (41)
May 05, 5-6 PM (26)
May 05, 6-7 PM (28)
May 05, 7-8 PM (73)
May 05, 8-9 PM (31)
May 05, 9-10 PM (18)
May 05, 10-11 PM (25)
May 05, 11-12 AM (17)
May 06, 12-1 AM (10)
May 06, 1-2 AM (5)
May 06, 2-3 AM (9)
May 06, 3-4 AM (23)
May 06, 4-5 AM (7)
May 06, 5-6 AM (13)
May 06, 6-7 AM (30)
May 06, 7-8 AM (11)
May 06, 8-9 AM (106)
May 06, 9-10 AM (27)
May 06, 10-11 AM (41)
May 06, 11-12 PM (46)
May 06, 12-1 PM (86)
May 06, 1-2 PM (53)
May 06, 2-3 PM (43)
May 06, 3-4 PM (33)
May 06, 4-5 PM (18)
May 06, 5-6 PM (8)
May 06, 6-7 PM (12)
May 06, 7-8 PM (26)
May 06, 8-9 PM (13)
May 06, 9-10 PM (9)
May 06, 10-11 PM (30)
May 06, 11-12 AM (23)
May 07, 12-1 AM (7)
May 07, 1-2 AM (2)
May 07, 2-3 AM (1)
May 07, 3-4 AM (10)
May 07, 4-5 AM (4)
May 07, 5-6 AM (33)
May 07, 6-7 AM (97)
May 07, 7-8 AM (235)
May 07, 8-9 AM (42)
May 07, 9-10 AM (29)
May 07, 10-11 AM (55)
May 07, 11-12 PM (39)
May 07, 12-1 PM (59)
May 07, 1-2 PM (48)
May 07, 2-3 PM (47)
May 07, 3-4 PM (42)
May 07, 4-5 PM (58)
May 07, 5-6 PM (10)
May 07, 6-7 PM (24)
May 07, 7-8 PM (30)
May 07, 8-9 PM (12)
May 07, 9-10 PM (18)
May 07, 10-11 PM (65)
May 07, 11-12 AM (20)
May 08, 12-1 AM (6)
May 08, 1-2 AM (19)
May 08, 2-3 AM (19)
May 08, 3-4 AM (8)
May 08, 4-5 AM (3)
May 08, 5-6 AM (20)
May 08, 6-7 AM (19)
May 08, 7-8 AM (53)
May 08, 8-9 AM (34)
May 08, 9-10 AM (12)
May 08, 10-11 AM (32)
May 08, 11-12 PM (40)
May 08, 12-1 PM (30)
May 08, 1-2 PM (45)
May 08, 2-3 PM (46)
May 08, 3-4 PM (26)
May 08, 4-5 PM (23)
May 08, 5-6 PM (29)
May 08, 6-7 PM (15)
May 08, 7-8 PM (10)
May 08, 8-9 PM (14)
May 08, 9-10 PM (16)
May 08, 10-11 PM (23)
May 08, 11-12 AM (12)
May 09, 12-1 AM (4)
May 09, 1-2 AM (1)
May 09, 2-3 AM (0)
May 09, 3-4 AM (6)
May 09, 4-5 AM (6)
May 09, 5-6 AM (2)
May 09, 6-7 AM (6)
May 09, 7-8 AM (4)
May 09, 8-9 AM (4)
May 09, 9-10 AM (3)
May 09, 10-11 AM (9)
May 09, 11-12 PM (6)
May 09, 12-1 PM (18)
May 09, 1-2 PM (23)
May 09, 2-3 PM (12)
May 09, 3-4 PM (14)
May 09, 4-5 PM (7)
May 09, 5-6 PM (0)
May 09, 6-7 PM (2)
May 09, 7-8 PM (3)
May 09, 8-9 PM (1)
May 09, 9-10 PM (8)
May 09, 10-11 PM (33)
May 09, 11-12 AM (16)
May 10, 12-1 AM (15)
May 10, 1-2 AM (0)
May 10, 2-3 AM (0)
May 10, 3-4 AM (5)
May 10, 4-5 AM (0)
May 10, 5-6 AM (4)
May 10, 6-7 AM (0)
May 10, 7-8 AM (17)
May 10, 8-9 AM (8)
May 10, 9-10 AM (0)
4,345 commits this week May 03, 2026 - May 10, 2026
dummy-ghc: extend Android branch to cover pkgsStatic
The Android dummy-ghc branch added in 491a91d13 reports a stage-1
GHC built without dynamic support: no `_dyn` RTS ways,
`GHC Dynamic: NO`, no `Support shared libraries` field.  The same
shape applies to nixpkgs's `pkgsStatic` (the haskell.nix `static`
jobset) — its real GHC is also built without dynamic support.
The only difference is `Stage`: Android cross is stage-1, the
static GHC is stage-2.

Without this branch, plan-to-nix records `--enable-shared` for
static-target packages while the slice's real ghc silently flips
to `--disable-shared`, forking the UnitId on `pkgHashSharedLib`
and breaking the slice's expected-package check.

Extend the Android branch's predicate to
`isAndroid || isStatic` and emit the right `Stage` per platform.
Reference: `pkgsStatic.haskell-nix.compiler.ghc9141 --info` on
the live `x86_64-unknown-linux-musl` derivation.

Verified: `tests.js-template-haskell.check` on
`x86_64-linux.unstable.ghc9141.static` builds end-to-end (slices
align, the test exe links statically as expected, the `.check`
derivation completes).
chore(deps-dev): bump @types/formidable in the types group
Bumps the types group with 1 update: [@types/formidable](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/formidable).


Updates `@types/formidable` from 3.5.0 to 3.5.1
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/formidable)

---
updated-dependencies:
- dependency-name: "@types/formidable"
  dependency-version: 3.5.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: types
...

Signed-off-by: dependabot[bot] <[email protected]>
chore(deps): bump the trpc group with 4 updates
Bumps the trpc group with 4 updates: [@trpc/client](https://github.com/trpc/trpc/tree/HEAD/packages/client), [@trpc/next](https://github.com/trpc/trpc/tree/HEAD/packages/next), [@trpc/react-query](https://github.com/trpc/trpc/tree/HEAD/packages/react) and [@trpc/server](https://github.com/trpc/trpc/tree/HEAD/packages/server).


Updates `@trpc/client` from 11.16.0 to 11.17.0
- [Release notes](https://github.com/trpc/trpc/releases)
- [Commits](https://github.com/trpc/trpc/commits/v11.17.0/packages/client)

Updates `@trpc/next` from 11.16.0 to 11.17.0
- [Release notes](https://github.com/trpc/trpc/releases)
- [Commits](https://github.com/trpc/trpc/commits/v11.17.0/packages/next)

Updates `@trpc/react-query` from 11.16.0 to 11.17.0
- [Release notes](https://github.com/trpc/trpc/releases)
- [Commits](https://github.com/trpc/trpc/commits/v11.17.0/packages/react)

Updates `@trpc/server` from 11.16.0 to 11.17.0
- [Release notes](https://github.com/trpc/trpc/releases)
- [Commits](https://github.com/trpc/trpc/commits/v11.17.0/packages/server)

---
updated-dependencies:
- dependency-name: "@trpc/client"
  dependency-version: 11.17.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: trpc
- dependency-name: "@trpc/next"
  dependency-version: 11.17.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: trpc
- dependency-name: "@trpc/react-query"
  dependency-version: 11.17.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: trpc
- dependency-name: "@trpc/server"
  dependency-version: 11.17.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: trpc
...

Signed-off-by: dependabot[bot] <[email protected]>
chore(deps): bump the prisma group with 2 updates
Bumps the prisma group with 2 updates: [@prisma/client](https://github.com/prisma/prisma/tree/HEAD/packages/client) and [prisma](https://github.com/prisma/prisma/tree/HEAD/packages/cli).


Updates `@prisma/client` from 6.19.2 to 7.8.0
- [Release notes](https://github.com/prisma/prisma/releases)
- [Commits](https://github.com/prisma/prisma/commits/7.8.0/packages/client)

Updates `prisma` from 6.19.2 to 7.8.0
- [Release notes](https://github.com/prisma/prisma/releases)
- [Commits](https://github.com/prisma/prisma/commits/7.8.0/packages/cli)

---
updated-dependencies:
- dependency-name: "@prisma/client"
  dependency-version: 7.8.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: prisma
- dependency-name: prisma
  dependency-version: 7.8.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: prisma
...

Signed-off-by: dependabot[bot] <[email protected]>
chore(deps): bump the next group with 3 updates
Bumps the next group with 3 updates: [next](https://github.com/vercel/next.js), [next-auth](https://github.com/nextauthjs/next-auth) and [@next/bundle-analyzer](https://github.com/vercel/next.js/tree/HEAD/packages/next-bundle-analyzer).


Updates `next` from 16.1.6 to 16.2.6
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v16.1.6...v16.2.6)

Updates `next-auth` from 4.24.13 to 4.24.14
- [Release notes](https://github.com/nextauthjs/next-auth/releases)
- [Commits](https://github.com/nextauthjs/next-auth/compare/[email protected]@4.24.14)

Updates `@next/bundle-analyzer` from 16.2.1 to 16.2.6
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/commits/v16.2.6/packages/next-bundle-analyzer)

---
updated-dependencies:
- dependency-name: next
  dependency-version: 16.2.6
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: next
- dependency-name: next-auth
  dependency-version: 4.24.14
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: next
- dependency-name: "@next/bundle-analyzer"
  dependency-version: 16.2.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: next
...

Signed-off-by: dependabot[bot] <[email protected]>
chore(deps): bump @meshsdk/react in the mesh-sdk group
Bumps the mesh-sdk group with 1 update: [@meshsdk/react](https://github.com/MeshJS/mesh).


Updates `@meshsdk/react` from 1.9.0-beta-40 to 2.0.0-beta.2
- [Release notes](https://github.com/MeshJS/mesh/releases)
- [Commits](https://github.com/MeshJS/mesh/commits)

---
updated-dependencies:
- dependency-name: "@meshsdk/react"
  dependency-version: 2.0.0-beta.2
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: mesh-sdk
...

Signed-off-by: dependabot[bot] <[email protected]>
chore(deps): bump actions/setup-node from 4 to 6
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 6.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v4...v6)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
chore(deps): bump actions/checkout from 4 to 6
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
chore(deps): bump actions/upload-artifact from 4 to 7
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 7.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
chore(deps): bump github/codeql-action from 3 to 4
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3 to 4.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
chore(proxy): remove three write-only useState declarations
ProxyControl had three state variables whose values were never read,
only their setters. Calling them produced empty re-renders.

- setLocalLoading: paralleled setSetupLoading and setSpendLoading; the
  read-side `setupLoading` and `spendLoading` are the live signals
- setSelectedUtxos / setManualSelected: stored values from the UTxO
  selector callback that nothing downstream consumed; the contract
  already uses all UTxOs from the multisig wallet (per existing
  comment), so the selection is purely visual

The UTxOSelector callback is preserved as a no-op (the prop is
required) with a comment explaining the visual-only intent.

Net -11 lines, zero behavior change.
fix(wallet-assets): show actual IPFS NFT image instead of hardcoded CID
The IPFS branch of the asset card was passing a single hardcoded ipfs://
literal to <IPFSImage>, so every IPFS-based NFT in the wallet rendered
the same placeholder image instead of its own metadata.image. The
non-IPFS sibling already uses imageSrc / name / 60x60 correctly; this
brings the IPFS branch in line.

Also fixes:
- alt text now uses the asset name (was "IPFS Image" — bad a11y)
- width/height set to 60 to match the parent 60x60 div (was 300, was
  being clipped by overflow-hidden + wasting bandwidth)

Single occurrence in the codebase. Introduced 2025-03-27.
chore(ui): a11y skip-link, useMemo transaction parse, cleanup deletions
Small UI/hook cleanup that fell out of the audit:

- overall-layout: add skip-link + main-content anchor; aria-label on the
  main form. Trims unused legacy nav code.
- transaction-card: useMemo the JSON.parse(transaction.txJson) so the
  parse only runs when txJson changes, not on every render. Removes a
  dead `import { get } from \"http\"` that was sneaking into the client
  bundle.
- signable-card: defensive parse for legacy payload shapes.
- card-show-signers, signing/index: small render fixes.
- ImgDragAndDrop, MeshProviderClient, BotManagementCard, background.tsx:
  drop dead state vars / unused imports surfaced by the audit.
- useAppWallet, useMultisigWallet: stable returns; missing-wallet path
  no longer spins indefinitely.
- Delete `src/components/multisig/proxy/ProxyControlExample.tsx`. It was
  example-only code, not exported from the proxy index, never rendered
  anywhere. The barrel import is updated.

Test plan
- 165/165 staged-suite tests pass on top of #237
- Typecheck clean

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
refactor(wallet-flow): stable signerIds for React keys; tripwire test
The new-wallet-flow and wallet-migration flow used the raw signer
address as a React key in ReviewSignersCard. Two issues:

1. The address can be empty/undefined while the user is editing, which
   makes the key non-unique → React reuses inputs across rows, swapping
   names and addresses while typing.
2. Two signers can momentarily share the same partial input, again
   producing duplicate keys.

Fix: every row gets a stable opaque `signerId` generated when the row
is created; the component uses `signerId` as the React key. Address
becomes regular state, free to be empty/duplicate transiently without
breaking React identity.

The same fix applied to both `useWalletFlowState` (new wallet) and
`useMigrationWalletFlowState` (migration). The shared `signerRows.ts`
module emits the id and keeps the parallel arrays in sync.

`reviewSignersCardKey.test.ts` is a tripwire suite that:
- greps the source to assert the raw address is never used as a key
- verifies both flow-state hooks expose signerIds parallel to
  signersAddresses

This catches future regressions structurally — the type system can't
enforce \"don't use address as key\", but a regex over source can.

Test plan
- 171/171 tests pass deterministically on top of #237
- Typecheck clean

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
feat(server): AuditLog table, DB indexes, security hardening, observability
Comprehensive server-side hardening pass: closes auth/security gaps,
adds an append-only AuditLog for security-relevant events, indexes
frequently queried columns, centralizes ctx typing, and lands shared
auth helpers.

## Database (already deployed to prod via prisma migrate deploy)

- New `AuditLog` table for append-only security audit trail
  (auth flows, wallet/transaction mutations, privilege grants, signer
  changes). Five indexes for the common access patterns.
- Btree indexes on Wallet/NewWallet `ownerAddress`, Signable+Transaction
  `walletId`/`state`/`(walletId, state)`, Proxy `walletId`/`userId`/
  `(walletId, isActive)`/`(userId, isActive)`, Ballot `walletId`,
  BalanceSnapshot `walletId`/`(walletId, snapshotDate)`.
- GIN indexes on Wallet/NewWallet `signersAddresses` (array_ops) — the
  signer-membership query was a full table scan.
- Restored `Crowdfund` model declaration (production drift: table exists
  in prod but was never declared in main's schema; see PR description
  for full archaeology). Marked as retained-but-unused.
- WalletBotAccess: `@@unique` -> `@@id` to match prod (drift from
  PR #207 / commit 1facdc3 where schema and migration disagreed at
  landing).
- Ballot.updatedAt: restored `@default(now()) @updatedAt` to match
  prod's column default (drift accumulated across multiple commits).
- Ballot.anchorUrls / anchorHashes: added `DEFAULT ARRAY[]::TEXT[]` to
  match the schema's `@default([])` annotation.

## Observability primitives

- `src/lib/observability/audit.ts` — `audit(db, event)` emitter; never
  throws (audit miss must not break user flow); redacts secrets in
  metadata before write.
- `src/lib/observability/logger.ts` — structured logger; JSON in prod,
  human-readable in dev; never logs raw tokens/signatures/cookies.

## Security fixes (Wave 1-3)

- Closed `ownerAddress === "all"` bypass in `assertWalletAccess`. The
  string "all" was being treated as a wildcard owner — any session
  could claim ownership of any wallet whose `ownerAddress` happened to
  contain that literal.
- `lookupMultisigWallet`: validate stake-credential-hash format before
  query (prevents prefix-match abuse and full-table scans on malformed
  input).
- Centralized rate-limit and request-guard surface (`src/lib/security/
  rateLimit.ts`, `requestGuards`). Bot routes now use bot-scoped
  rate limit; user routes use IP-scoped.
- `verifyJwt`: stricter token-type narrowing; explicit `isBotJwt`
  predicate.
- `walletSession`: tighter expiry handling, no implicit refresh.

## Auth helpers (Wave 8)

- New `src/server/api/auth.ts` consolidates `requireSessionAddress`,
  `getSessionAddresses`, and wallet-access checks that were duplicated
  in nearly every router. One source of truth, one place to extend.
- All routers and v1 API handlers migrated.

## ctx typing (Wave 2)

- New `AuthCtx` and `TRPCContext` exported from `src/server/api/trpc.ts`.
- All router helpers use `AuthCtx` instead of `any`.
- `protectedProcedure` middleware: type-narrows `sessionWallets`,
  `primaryWallet`, `sessionAddress` correctly.

## Audit emitters (Wave 5)

Wired into:
- auth flow (login success/failure, JWT mint, bot auth)
- wallet mutations (create, update, archive, transfer, signer changes)
- signable + transaction mutations (sign, reject, broadcast)
- bot privilege grants

All emitters fire after the underlying action and never block it.

## SSRF defense for `/api/v1/og`

The OG metadata endpoint now:
- requires https, denies non-allowlisted hosts
- DNS-resolves and rejects private/loopback/link-local addresses
- denies upstream redirects (no auto-follow)

`OG_ALLOWED_HOSTS` env var configures the allow list; "*" allows any
public host (still SSRF-guarded).

## Test infrastructure

- jest.config.mjs — moduleNameMapper for CSS, transformIgnorePatterns
  for ESM-only deps (superjson, @trpc, @meshsdk, jose, etc.)
- setupEnv.cjs — pre-test env bootstrap (SKIP_ENV_VALIDATION=1, dummy
  DB/JWT/Blockfrost values) so `src/env.js` doesn't throw on import.
- Frozen wall clock (`Date.now`/`new Date`) for byte-identical test
  runs; real timer APIs preserved.
- `__mocks__/styleMock.cjs` — CSS imports mock for jest.

## Tests

- New: `og.test.ts` (SSRF tripwire suite — 9 cases for the og handler).
- New: `signing.test.ts` (source tripwires preventing the
  `return true ? signature : undefined` regression and similar).
- Updated existing tests to match Jest 30 strict mock typing
  (jest.fn<...>() generics) and new ctx fields.

## Verification

- Typecheck clean
- All 165 staged-suite tests pass deterministically across two runs
- Migration `20260510160404_audit_log_and_indexes` already applied to
  the multisig Supabase production DB — `prisma migrate deploy` on
  this branch is a no-op (idempotent).

Depends on: #236 (build fix; without it `next build --webpack` will
crash on `/wallets/[wallet]/transactions/new`).

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
fix(build): lazy-init mainnet provider; remove global sideEffects:false
Two interacting issues caused the production build to crash on routes
that imported resolve-adahandle (notably /wallets/[wallet]/transactions/new):

1. resolve-adahandle.tsx called getProvider(1) at module top level. Under
   `next build` page-data collection, every server-rendered page imports
   that module, which constructs BlockfrostProvider(undefined) when
   NEXT_PUBLIC_BLOCKFROST_API_KEY_MAINNET isn't readable at build time
   (e.g. SKIP_ENV_VALIDATION=true). The constructor throws and the
   webpack runtime reports it as a generic "factory error".

2. next.config.js had `optimization.sideEffects: false` set globally,
   which tells webpack that *every* file is side-effect-free. That
   silently strips global CSS imports and any module-level initialization,
   masking issues like (1) until you hit a route that exercises them.

Fix:
- Lazy-init the mainnet provider with a cached singleton, so import is
  free and instantiation only happens when a caller actually resolves a
  handle (always client-side).
- Remove the global sideEffects:false override. Per-package sideEffects
  declarations in package.json are the correct mechanism; the global
  override was masking real bugs.
- Move swagger-ui-react CSS import from api-docs.tsx into _app.tsx so
  Next.js Pages Router's "global CSS only from _app" rule is satisfied.

Verified locally: `next build --webpack` completes; both
/wallets/[wallet]/transactions/new and /api-docs render.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
chore(ci): gate typecheck/test/build; add dependabot
PR checks were silently passing because typecheck, test, and build steps
were marked continue-on-error, so the gates only reported status, never
blocked merges. Drop continue-on-error from those three; keep it on lint
until the rule set is cleaned up.

Add dependabot config for npm + github-actions, with grouping for
@meshsdk/*, next/@next/*, prisma/@prisma/*, @trpc/*, and @types/*.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>