refactor(react): move wallet integration to apps/next#102
refactor(react): move wallet integration to apps/next#102gaboesquivel merged 12 commits intomainfrom
Conversation
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. WalkthroughThis PR refactors wallet-related hooks architecture by moving implementations from centralized Changes
Sequence Diagram(s)sequenceDiagram
participant Client as Next Component
participant Auth as useWalletAuth Hook
participant Adapter as Wallet Adapter
participant Verify as useVerifyWeb3Auth
participant Backend as API Backend
rect rgba(100, 150, 200, 0.5)
Note over Client,Backend: Old Flow (Removed)
Client->>Auth: signIn()
Auth->>Adapter: signMessage(message)
Adapter-->>Auth: signature
Auth->>Backend: POST /auth/verify (direct call)
Backend-->>Auth: verify response
Auth-->>Client: result
end
rect rgba(150, 200, 100, 0.5)
Note over Client,Backend: New Flow (With Verify Hooks)
Client->>Auth: signIn()
Auth->>Adapter: signMessage(message)
Adapter-->>Auth: signature
Auth->>Verify: mutateAsync({chain, message, signature, domain})
Verify->>Backend: POST /auth/verify (via mutation)
Backend-->>Verify: verify response
Verify-->>Auth: result + session invalidation
Auth-->>Client: result
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
apps/next/hooks/use-link-wallet.ts (1)
73-76:⚠️ Potential issue | 🟡 MinorMisleading error message when only
signMessageis absent.
if (!address || !signMessage)covers two distinct missing states, but the thrown message'No wallet address'only describes one. A caller debugging a missingsignMessage(e.g., before wallet adapters are wired up) would get a confusing error.🛠️ Proposed fix
- if (!address || !signMessage) { - throw new Error('No wallet address') - } + if (!address) throw new Error('No wallet connected') + if (!signMessage) throw new Error('Wallet does not support message signing')🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/next/hooks/use-link-wallet.ts` around lines 73 - 76, The mutationFn currently throws a misleading generic error when either address or signMessage is missing; update mutationFn in use-link-wallet.ts to validate each dependency separately (check address and check signMessage) and throw distinct, descriptive errors (e.g., "No wallet address" when address is missing and "No signMessage function" or similar when signMessage is missing) so callers can identify which piece is not wired up.apps/next/hooks/use-wallet-auth.ts (1)
79-81:⚠️ Potential issue | 🟡 MinorError message "No wallet address" is misleading when
chainorsignMessageis absentThe guard condition covers three different failure modes, but only one message is surfaced — making it hard to diagnose which field is actually missing.
🐛 Proposed fix
- if (!address || !signMessage || !chain) { - throw new Error('No wallet address') - } + if (!chain) throw new Error('No wallet chain specified') + if (!address) throw new Error('No wallet address') + if (!signMessage) throw new Error('No signMessage function provided')🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/next/hooks/use-wallet-auth.ts` around lines 79 - 81, The current guard in the hook checks address, signMessage, and chain but always throws "No wallet address", which is misleading; update the check in use-wallet-auth (the block that evaluates address, signMessage, chain) to detect which of address, signMessage, or chain is missing and throw or return a clear, specific error message for each (e.g., "No wallet address", "No signMessage function", "No chain configured") or build a combined message listing missing fields so callers can immediately see which dependency (address, signMessage, or chain) is absent.
🧹 Nitpick comments (7)
packages/react/src/hooks/use-verify-link-wallet.ts (1)
5-5:Web3Chainimported from a sibling hook — consider a shared types module.
use-verify-link-wallet.tsimportsWeb3Chainfrom./use-verify-web3-auth, creating a lateral dependency between two peer hooks. Ifuse-verify-web3-authever changes its public surface, it could unintentionally breakuse-verify-link-wallet. A dedicatedpackages/react/src/types.ts(orpackages/react/src/wallet/types.ts) would give the type a stable, purpose-built home.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/react/src/hooks/use-verify-link-wallet.ts` at line 5, The hook use-verify-link-wallet.ts currently imports the Web3Chain type from a sibling hook use-verify-web3-auth, creating a lateral dependency; extract Web3Chain into a stable shared types module (e.g., packages/react/src/types.ts or packages/react/src/wallet/types.ts), export the type from there, and update use-verify-link-wallet.ts and use-verify-web3-auth to import Web3Chain from the new types module to remove the peer-hook coupling.apps/next/hooks/use-wallet.ts (1)
15-15: Redundant ternary —chainis already the correct index.
chain === 'eip155' ? 'eip155' : 'solana'always equalschainfor aWeb3Chain-typed argument. The ternary adds noise without guarding anything.♻️ Proposed simplification
- if (chain) return ctx.adapters[chain === 'eip155' ? 'eip155' : 'solana'] + if (chain) return ctx.adapters[chain]🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/next/hooks/use-wallet.ts` at line 15, The conditional uses a redundant ternary when selecting an adapter: in the use-wallet hook replace the expression ctx.adapters[chain === 'eip155' ? 'eip155' : 'solana'] with a direct lookup using ctx.adapters[chain]; update the return path that currently reads if (chain) return ctx.adapters[...] to simply return ctx.adapters[chain] (still guarding for a falsy chain first) so the code uses the Web3Chain-typed chain value directly.apps/next/hooks/use-link-wallet.test.tsx (1)
28-59: Consider adding a test for the Solana chain path.The suite only exercises
eip155. ThebuildSiwsMessagepath (Solana) has different message formatting logic and is untested. Adding a seconditblock withchain: 'solana'and a bs58-encoded signature mock would complete coverage here.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/next/hooks/use-link-wallet.test.tsx` around lines 28 - 59, Add a second test case exercising the Solana path: create a new it block that calls useLinkWallet with chain: 'solana', address formatted for Solana, and a signMessage mock that resolves to a bs58-encoded signature; render the hook with createWrapper(client), call result.current.linkWallet(), then assert signMessage was called and client.account.link.wallet.verify was invoked with an object containing body.message (matching buildSiwsMessage/solana format), chain: 'solana', and the bs58 signature, keeping throwOnError: true; reference useLinkWallet, linkWallet, buildSiwsMessage, and client.account.link.wallet.verify to locate the code under test.apps/next/hooks/use-web3-nonce.test.tsx (2)
8-13: Shared mock prevents distinguishing chain branches; consider splitting.Both
eip155.nonceandsolana.noncepoint to the samevi.fn()reference (line 11). If the implementation accidentally called the wrong branch, the test would still pass. Using separate mocks and asserting only the expected one was called would catch a branch regression.🛠️ Proposed fix
function createMockClient() { - const nonce = vi.fn().mockResolvedValue({ data: { nonce: 'testnonce' } }) + const eip155Nonce = vi.fn().mockResolvedValue({ data: { nonce: 'testnonce' } }) + const solanaNonce = vi.fn().mockResolvedValue({ data: { nonce: 'testnonce' } }) return { - auth: { web3: { eip155: { nonce }, solana: { nonce } } }, + auth: { web3: { eip155: { nonce: eip155Nonce }, solana: { nonce: solanaNonce } } }, } as unknown as ReturnType<typeof import('@repo/core').createClient> }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/next/hooks/use-web3-nonce.test.tsx` around lines 8 - 13, The shared vi.fn() used in createMockClient makes eip155.nonce and solana.nonce identical; split them into two distinct mocks (e.g., nonceEip155 and nonceSolana) so the test can assert which branch was called. Update createMockClient to return auth.web3.eip155.nonce = nonceEip155 and auth.web3.solana.nonce = nonceSolana (each mockResolvedValue as needed) and adjust tests to expect the appropriate mock to have been called and the other not called.
26-36: Add edge-case tests forsolanachain,address: undefined, andenabled: false.The package-level test at
packages/react/src/hooks/use-web3-nonce.test.tsx(per context) covers these scenarios. The app-level hook re-exports the same logic, so parity in coverage would be valuable, particularly for thesolanacode path (which uses a different client method) and theenabledguard (which prevents redundant API calls on address absence).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/next/hooks/use-web3-nonce.test.tsx` around lines 26 - 36, Add three edge-case tests mirroring the package-level coverage: (1) for chain: 'solana' render the hook with address '0x1234' and assert client.auth.web3.solana.nonce was called with { query: { address: '0x1234' } } and result.current.data?.nonce equals the mocked value; (2) for address: undefined render useWeb3Nonce({ chain: 'eip155', address: undefined }) and assert the client eip155 nonce method was not called and result.current.data is undefined; (3) for enabled: false render useWeb3Nonce({ chain: 'eip155', address: '0x1234', enabled: false }) and assert no client call was made (client.auth.web3.eip155.nonce not called) and result.current.data is undefined; use the same helpers (createMockClient, createWrapper, renderHook, waitFor) and the existing test structure to add these cases to use-web3-nonce.test.tsx.apps/next/wallet/types.ts (1)
2-2:Web3Chainis duplicated — re-export from@repo/reactinstead
packages/react/src/hooks/use-verify-web3-auth.tsalready exportsWeb3Chain = 'eip155' | 'solana', andpackages/react/src/index.tsre-exports it. Having a second, identical definition here means a new chain added to the shared package won't automatically propagate to app-local code.♻️ Proposed fix
-/** SIWE/SIWS chain identifier */ -export type Web3Chain = 'eip155' | 'solana' +export type { Web3Chain } from '@repo/react'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/next/wallet/types.ts` at line 2, Remove the duplicate local type Web3Chain and import the shared type from the react package instead: replace the local export "export type Web3Chain = 'eip155' | 'solana'" with an import of Web3Chain from the shared package (the type exported by use-verify-web3-auth.ts and re-exported in packages/react's index.ts), then update any references in this file to use the imported Web3Chain to ensure future chain additions propagate from `@repo/react`.apps/next/hooks/use-wallet.test.tsx (1)
64-69: Consider adding a test for "chain specified but not in provider"Currently there's no test covering
useWallet('solana')when only theeip155adapter is registered. This is the key boundary case that verifies the hook returnsundefined(not an incorrect adapter) when the requested chain is absent.♻️ Suggested additional test
+ it('returns undefined when requested chain is not in provider', () => { + const { result } = renderHook(() => useWallet('solana'), { + wrapper: createWrapper({ eip155: mockEvmAdapter }), + }) + expect(result.current).toBeUndefined() + })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/next/hooks/use-wallet.test.tsx` around lines 64 - 69, Add a unit test in apps/next/hooks/use-wallet.test.tsx that calls useWallet('solana') while creating the wrapper with only the eip155 adapter (createWrapper({ eip155: mockEvmAdapter })) and assert that result.current is undefined; this covers the boundary where a requested chain (solana) is not registered and ensures useWallet('solana') does not return the eip155 adapter (reference the useWallet hook and the existing mockEvmAdapter/mockSolanaAdapter identifiers to locate the test file and mocks).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/react/src/hooks/use-verify-link-wallet.test.tsx`:
- Around line 33-44: The test fires result.current.mutateAsync inside act but
doesn't await the mutation, causing flakiness; update both test cases to await
the mutation inside the act wrapper so the Promise chain settles before
assertions (i.e., call await result.current.mutateAsync(...) from within the
async act block) so that client.account.link.wallet.verify is guaranteed to have
been invoked before the expect runs.
In `@packages/react/src/hooks/use-verify-web3-auth.test.tsx`:
- Around line 38-91: In the three tests exercising the useVerifyWeb3Auth hook
(the "calls eip155 verify", "calls solana verify" and "POSTs tokens to
authCallbackUrl when set" cases), the calls to result.current.mutateAsync(...)
inside their act(...) callbacks must be awaited; update each act callback to use
await result.current.mutateAsync(...) so the mutation completes before
assertions run (look for the mutateAsync calls in the tests that call
client.auth.web3.eip155.verify, client.auth.web3.solana.verify, and the
fetch-backed authCallbackUrl test).
In `@packages/react/src/hooks/use-verify-web3-auth.ts`:
- Around line 32-50: The verify calls return a wrapper object with a data
property, but the code double-casts to
Web3Eip155VerifyResponse/Web3SolanaVerifyResponse and then reads
verifyResult.token / verifyResult.refreshToken which are undefined; update the
branch that assigns verifyResult (the results of client.auth.web3.eip155.verify
and client.auth.web3.solana.verify) to unwrap the wrapper (e.g., const { data:
verifyResult } = await client.auth.web3.eip155.verify(...) or const
verifyResponse = await ...; const verifyResult = verifyResponse.data) and then
use verifyResult.token and verifyResult.refreshToken when posting to
authCallbackUrl so the actual token values are sent.
---
Outside diff comments:
In `@apps/next/hooks/use-link-wallet.ts`:
- Around line 73-76: The mutationFn currently throws a misleading generic error
when either address or signMessage is missing; update mutationFn in
use-link-wallet.ts to validate each dependency separately (check address and
check signMessage) and throw distinct, descriptive errors (e.g., "No wallet
address" when address is missing and "No signMessage function" or similar when
signMessage is missing) so callers can identify which piece is not wired up.
In `@apps/next/hooks/use-wallet-auth.ts`:
- Around line 79-81: The current guard in the hook checks address, signMessage,
and chain but always throws "No wallet address", which is misleading; update the
check in use-wallet-auth (the block that evaluates address, signMessage, chain)
to detect which of address, signMessage, or chain is missing and throw or return
a clear, specific error message for each (e.g., "No wallet address", "No
signMessage function", "No chain configured") or build a combined message
listing missing fields so callers can immediately see which dependency (address,
signMessage, or chain) is absent.
---
Nitpick comments:
In `@apps/next/hooks/use-link-wallet.test.tsx`:
- Around line 28-59: Add a second test case exercising the Solana path: create a
new it block that calls useLinkWallet with chain: 'solana', address formatted
for Solana, and a signMessage mock that resolves to a bs58-encoded signature;
render the hook with createWrapper(client), call result.current.linkWallet(),
then assert signMessage was called and client.account.link.wallet.verify was
invoked with an object containing body.message (matching buildSiwsMessage/solana
format), chain: 'solana', and the bs58 signature, keeping throwOnError: true;
reference useLinkWallet, linkWallet, buildSiwsMessage, and
client.account.link.wallet.verify to locate the code under test.
In `@apps/next/hooks/use-wallet.test.tsx`:
- Around line 64-69: Add a unit test in apps/next/hooks/use-wallet.test.tsx that
calls useWallet('solana') while creating the wrapper with only the eip155
adapter (createWrapper({ eip155: mockEvmAdapter })) and assert that
result.current is undefined; this covers the boundary where a requested chain
(solana) is not registered and ensures useWallet('solana') does not return the
eip155 adapter (reference the useWallet hook and the existing
mockEvmAdapter/mockSolanaAdapter identifiers to locate the test file and mocks).
In `@apps/next/hooks/use-wallet.ts`:
- Line 15: The conditional uses a redundant ternary when selecting an adapter:
in the use-wallet hook replace the expression ctx.adapters[chain === 'eip155' ?
'eip155' : 'solana'] with a direct lookup using ctx.adapters[chain]; update the
return path that currently reads if (chain) return ctx.adapters[...] to simply
return ctx.adapters[chain] (still guarding for a falsy chain first) so the code
uses the Web3Chain-typed chain value directly.
In `@apps/next/hooks/use-web3-nonce.test.tsx`:
- Around line 8-13: The shared vi.fn() used in createMockClient makes
eip155.nonce and solana.nonce identical; split them into two distinct mocks
(e.g., nonceEip155 and nonceSolana) so the test can assert which branch was
called. Update createMockClient to return auth.web3.eip155.nonce = nonceEip155
and auth.web3.solana.nonce = nonceSolana (each mockResolvedValue as needed) and
adjust tests to expect the appropriate mock to have been called and the other
not called.
- Around line 26-36: Add three edge-case tests mirroring the package-level
coverage: (1) for chain: 'solana' render the hook with address '0x1234' and
assert client.auth.web3.solana.nonce was called with { query: { address:
'0x1234' } } and result.current.data?.nonce equals the mocked value; (2) for
address: undefined render useWeb3Nonce({ chain: 'eip155', address: undefined })
and assert the client eip155 nonce method was not called and result.current.data
is undefined; (3) for enabled: false render useWeb3Nonce({ chain: 'eip155',
address: '0x1234', enabled: false }) and assert no client call was made
(client.auth.web3.eip155.nonce not called) and result.current.data is undefined;
use the same helpers (createMockClient, createWrapper, renderHook, waitFor) and
the existing test structure to add these cases to use-web3-nonce.test.tsx.
In `@apps/next/wallet/types.ts`:
- Line 2: Remove the duplicate local type Web3Chain and import the shared type
from the react package instead: replace the local export "export type Web3Chain
= 'eip155' | 'solana'" with an import of Web3Chain from the shared package (the
type exported by use-verify-web3-auth.ts and re-exported in packages/react's
index.ts), then update any references in this file to use the imported Web3Chain
to ensure future chain additions propagate from `@repo/react`.
In `@packages/react/src/hooks/use-verify-link-wallet.ts`:
- Line 5: The hook use-verify-link-wallet.ts currently imports the Web3Chain
type from a sibling hook use-verify-web3-auth, creating a lateral dependency;
extract Web3Chain into a stable shared types module (e.g.,
packages/react/src/types.ts or packages/react/src/wallet/types.ts), export the
type from there, and update use-verify-link-wallet.ts and use-verify-web3-auth
to import Web3Chain from the new types module to remove the peer-hook coupling.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
.github/workflows/docu-deploy.yml (1)
44-45:corepack enableshould be placed beforepnpm install, not after.
--cwdis a valid global Vercel CLI option — unrelated concern here — but thecorepack enableplacement is the issue: Corepack works by installing shims for package manager binaries so that the version declared inpackageManager(inpackage.json) is enforced at invocation time. Enabling it afterpnpm installmeans the install step already ran without corepack interception.In practice this isn't broken today because
pnpm/action-setup@v4withversion: 10.29.3already pins pnpm independently, but the step ordering is semantically wrong and will silently fail to enforce thepackageManagerconstraint if thepnpm/action-setupstrategy ever changes.The standard setup order should be:
setup-node→pnpm/action-setup→corepack enable→ cache →pnpm install.♻️ Proposed fix: move corepack enable before install
+ - name: Enable Corepack + run: corepack enable - name: Get pnpm store directory shell: bash run: echo "STORE_PATH=$(pnpm store path --silent)" >> "$GITHUB_ENV" - uses: actions/cache@v4 with: path: ${{ env.STORE_PATH }} key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} restore-keys: | ${{ runner.os }}-pnpm-store- - name: Install dependencies run: pnpm install --frozen-lockfile - - name: Enable Corepack - run: corepack enable🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/docu-deploy.yml around lines 44 - 45, The "Enable Corepack" step is currently placed after the pnpm install step; move the Corepack enabling step so it runs before any pnpm install invocation. Specifically, ensure the workflow executes setup-node, then pnpm/action-setup@v4, then the "Enable Corepack" step (running corepack enable), followed by caching and the pnpm install step; update the job steps ordering so the step named "Enable Corepack" appears before the step that runs pnpm install to ensure Corepack shims intercept the install.apps/next/vercel.json (1)
3-3: Minor:turbo run buildvsturbo buildinconsistency across apps.
apps/nextusesnpx pnpm turbo run buildwhileapps/fastifyandapps/docuuse the shorthandnpx pnpm turbo build. The two forms are equivalent in Turbo, but picking one form consistently across all three files avoids confusion during future edits.♻️ Align to shorthand form (matching the other two apps)
- "buildCommand": "cd ../.. && npx pnpm turbo run build --filter=@repo/next", + "buildCommand": "cd ../.. && npx pnpm turbo build --filter=@repo/next",🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/next/vercel.json` at line 3, Update the buildCommand entry named "buildCommand" to use the shorthand Turbo invocation to match the other apps: replace the string "npx pnpm turbo run build --filter=@repo/next" with the shorthand form "npx pnpm turbo build --filter=@repo/next" so the apps/next vercel.json is consistent with apps/fastify and apps/docu..github/workflows/next-deploy-e2e.yml (1)
145-149: "Deploy Next" has no build-failure fallback or diagnostic, unlike the Fastify deploy.The Fastify deploy (lines 110–115) wraps
vercel buildin anif/elsethat falls back to a full deploy and emits a::notice::annotation. The Next deploy runsvercel build(line 146) withoutset +eor any error handling: a build failure exits the step immediately,DEPLOY_OUTPUTis never captured,next_urlis left empty, and the downstream E2E job silently fails against an empty URL with no diagnostic breadcrumb.Even if a full-deploy fallback isn't meaningful for Next.js (since
--prebuiltrequires a successful build artifact), at minimum an explicit::error::annotation and early exit would improve debuggability.♻️ Suggested improvement: explicit failure annotation
- pnpm exec vercel pull --yes --environment=preview --token=$VERCEL_TOKEN --cwd apps/next - pnpm exec vercel build --token=$VERCEL_TOKEN --cwd apps/next + pnpm exec vercel pull --yes --environment=preview --token=$VERCEL_TOKEN --cwd apps/next + + if ! pnpm exec vercel build --token=$VERCEL_TOKEN --cwd apps/next; then + echo "::error::vercel build failed for apps/next — no prebuilt artifact available for deploy" + exit 1 + fi🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/next-deploy-e2e.yml around lines 145 - 149, Wrap the Next build/deploy steps so build failures are detected and annotated: run pnpm exec vercel build with set +e and capture its output/exit code (similar to how DEPLOY_OUTPUT captures vercel deploy), then if the build exit code is non‑zero emit an explicit GitHub Actions annotation (echo "::error::Next build failed: $BUILD_OUTPUT") and exit early (or optionally run a fallback deploy path), and ensure DEPLOY_OUTPUT/next_url are only used when the build succeeded; reference the vercel build invocation, DEPLOY_OUTPUT/BUILD_OUTPUT variables, and next_url to locate where to add the check and annotation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/fastify/vercel.json`:
- Around line 5-7: The Vercel commands (buildCommand, installCommand,
devCommand) use unversioned "npx pnpm" which can ignore the root packageManager
pin; update each command in apps/fastify vercel.json to explicitly pin pnpm to
the declared version (e.g., use "npx pnpm@10.29.3" for buildCommand,
installCommand, and devCommand) or alternatively enable corepack in .npmrc so
the pinned "pnpm@10.29.3" is respected; ensure you change the three keys
(buildCommand, installCommand, devCommand) to use the chosen pinned invocation
consistently.
---
Nitpick comments:
In @.github/workflows/docu-deploy.yml:
- Around line 44-45: The "Enable Corepack" step is currently placed after the
pnpm install step; move the Corepack enabling step so it runs before any pnpm
install invocation. Specifically, ensure the workflow executes setup-node, then
pnpm/action-setup@v4, then the "Enable Corepack" step (running corepack enable),
followed by caching and the pnpm install step; update the job steps ordering so
the step named "Enable Corepack" appears before the step that runs pnpm install
to ensure Corepack shims intercept the install.
In @.github/workflows/next-deploy-e2e.yml:
- Around line 145-149: Wrap the Next build/deploy steps so build failures are
detected and annotated: run pnpm exec vercel build with set +e and capture its
output/exit code (similar to how DEPLOY_OUTPUT captures vercel deploy), then if
the build exit code is non‑zero emit an explicit GitHub Actions annotation (echo
"::error::Next build failed: $BUILD_OUTPUT") and exit early (or optionally run a
fallback deploy path), and ensure DEPLOY_OUTPUT/next_url are only used when the
build succeeded; reference the vercel build invocation,
DEPLOY_OUTPUT/BUILD_OUTPUT variables, and next_url to locate where to add the
check and annotation.
In `@apps/next/vercel.json`:
- Line 3: Update the buildCommand entry named "buildCommand" to use the
shorthand Turbo invocation to match the other apps: replace the string "npx pnpm
turbo run build --filter=@repo/next" with the shorthand form "npx pnpm turbo
build --filter=@repo/next" so the apps/next vercel.json is consistent with
apps/fastify and apps/docu.
| "buildCommand": "cd ../.. && npx pnpm turbo build --filter=@repo/fastify", | ||
| "installCommand": "cd ../.. && npx pnpm install", | ||
| "devCommand": "cd ../.. && npx pnpm dev --filter=@repo/fastify", |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Check root package.json for packageManager field and examine vercel.json files
cd /repo
echo "=== Root package.json packageManager field ==="
jq '.packageManager' package.json 2>/dev/null || echo "No packageManager field found"
echo -e "\n=== Root package.json name ==="
jq '.name' package.json 2>/dev/null
echo -e "\n=== Checking vercel.json files ==="
for file in apps/fastify/vercel.json apps/docu/vercel.json apps/next/vercel.json; do
if [ -f "$file" ]; then
echo -e "\n--- $file ---"
cat "$file" | head -20
else
echo "File not found: $file"
fi
done
echo -e "\n=== Checking for .npmrc or pnpm-workspace.yaml ==="
ls -la | grep -E '\.npmrc|pnpm-workspace|\.corepackrc'Repository: blockmatic/basilic
Length of output: 2183
🏁 Script executed:
echo "=== .npmrc content ==="
cat .npmrc
echo -e "\n=== pnpm-workspace.yaml content ==="
cat pnpm-workspace.yamlRepository: blockmatic/basilic
Length of output: 413
🏁 Script executed:
# Search for other vercel.json or similar deployment configs
echo "=== All vercel.json files in repo ==="
find . -name "vercel.json" -type f 2>/dev/null
echo -e "\n=== Search for 'npx pnpm' pattern in config files ==="
rg "npx pnpm" --type json --type yaml --type toml 2>/dev/null | head -20Repository: blockmatic/basilic
Length of output: 1048
🏁 Script executed:
echo "=== packages/email/vercel.json content ==="
cat packages/email/vercel.jsonRepository: blockmatic/basilic
Length of output: 221
Pin pnpm version in Vercel commands to match the declared packageManager field.
The root package.json declares "packageManager": "pnpm@10.29.3", but all three vercel.json files (apps/fastify, apps/docu, and apps/next) use unversioned npx pnpm. Since .npmrc does not enable ENABLE_EXPERIMENTAL_COREPACK, the unversioned npx pnpm will resolve from the npm registry at runtime and ignore the pinned version, risking silent major-version drift.
Either enable corepack in .npmrc or pin the version explicitly in the commands (e.g., npx pnpm@10 install or npx pnpm@10.29.3 install) to ensure consistent pnpm versions across environments.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/fastify/vercel.json` around lines 5 - 7, The Vercel commands
(buildCommand, installCommand, devCommand) use unversioned "npx pnpm" which can
ignore the root packageManager pin; update each command in apps/fastify
vercel.json to explicitly pin pnpm to the declared version (e.g., use "npx
pnpm@10.29.3" for buildCommand, installCommand, and devCommand) or alternatively
enable corepack in .npmrc so the pinned "pnpm@10.29.3" is respected; ensure you
change the three keys (buildCommand, installCommand, devCommand) to use the
chosen pinned invocation consistently.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
- await mutateAsync in act for useVerifyLinkWallet/useVerifyWeb3Auth tests - unwrap data from verify response in use-verify-web3-auth for authCallbackUrl - distinct error messages in use-link-wallet and use-wallet-auth - extract Web3Chain to packages/react/src/types, import in apps/next - use direct chain lookup in use-wallet (ctx.adapters[chain]) - split nonce mocks in use-web3-nonce tests, add edge-case coverage - add Solana path test for use-link-wallet, undefined-chain test for use-wallet - eslint-disable SKIP_BUILD in run-e2e-local.mjs
Re-add git.deploymentEnabled for main and develop branches in apps/next, apps/docu, and apps/fastify vercel.json
There was a problem hiding this comment.
🧹 Nitpick comments (12)
apps/next/scripts/run-e2e-local.mjs (1)
63-71:SKIP_BUILD=0/SKIP_BUILD=falsewill still skip the build.
!process.env.SKIP_BUILDtreats any non-empty string as truthy, soSKIP_BUILD=0orSKIP_BUILD=falseunexpectedly skips the build. The header documentsSKIP_BUILD=1as the intended value, but a developer who setsSKIP_BUILD=0to "disable skipping" will get the opposite effect.This pattern already exists for
SKIP_KILL_PORTSon Line 53, so it's consistent within the file — but worth making explicit in both places if confusion is possible.🛡️ Optional: guard against `SKIP_BUILD=0` / `SKIP_BUILD=false`
- // eslint-disable-next-line turbo/no-undeclared-env-vars -- set by root test:e2e or user - if (!process.env.SKIP_BUILD) { + // eslint-disable-next-line turbo/no-undeclared-env-vars -- set by root test:e2e or user + if (process.env.SKIP_BUILD !== '1') {Apply the same treatment to
SKIP_KILL_PORTSon Line 53 for consistency:- if (!process.env.SKIP_KILL_PORTS) { + if (process.env.SKIP_KILL_PORTS !== '1') {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/next/scripts/run-e2e-local.mjs` around lines 63 - 71, The current check uses `!process.env.SKIP_BUILD` which treats any non-empty string (like "0" or "false") as truthy and incorrectly skips builds; change the condition that decides whether to run the build to explicitly test the environment variable value (e.g., only skip when `process.env.SKIP_BUILD === '1'` or another explicit truthy token), and apply the same explicit-value check to the `SKIP_KILL_PORTS` check so both `process.env.SKIP_BUILD` and `process.env.SKIP_KILL_PORTS` behave predictably (use the exact string comparison against the documented token such as '1' in the `run-e2e-local.mjs` logic that spawns `pnpm ... build:e2e` and the port-killing branch).apps/fastify/vercel.json (1)
8-8: Confirm thedevelopbranch deployment target is intentional for this backend.Switching from
deploymentEnabled: falseto{ "main": true, "develop": true }means every push todevelopproduces a live Vercel deployment of the Fastify API. Unlike a frontend preview, this backend deployment will carry real CORS settings (Access-Control-Allow-Origin: *) and presumably connect to real downstream services. Verify that:
- The
developdeployment targets a dedicated staging environment (separate env vars, non-production DB, etc.).- There is no risk of the staging API being reachable as a production-equivalent endpoint.
If
developdeployments are not intended to be live, consider using Vercel preview deployment protection or reverting tofalsefordevelopwhile keepingmain: true.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/fastify/vercel.json` at line 8, The git deployment setting for Vercel currently enables both branches via the "git" -> "deploymentEnabled" object with "main": true and "develop": true; confirm whether enabling "develop" to produce live backend deployments is intentional and either 1) ensure "develop" is configured to target a dedicated staging environment (separate env vars, non-production DB, restricted CORS and endpoints) or 2) revert "develop" to false and rely on preview/protected deployments while keeping "main": true; update the "deploymentEnabled" entry accordingly to reflect the chosen option and add a short repo comment or PR note documenting the decision.packages/react/src/hooks/use-verify-web3-auth.ts (2)
47-66: Auth callback flow looks correct.The
credentials: 'include'+redirect: 'follow'+ explicitwindow.location.hrefnavigation pattern properly handles cookie-based auth with server-side redirects. One minor note: thefetchtoauthCallbackUrlhas no timeout — if the callback endpoint is unresponsive, the mutation will hang indefinitely. Consider adding anAbortSignal.timeout()if the target environment supports it.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/react/src/hooks/use-verify-web3-auth.ts` around lines 47 - 66, The fetch to authCallbackUrl in the use-verify-web3-auth hook can hang because it has no timeout; update the fetch call in the use-verify-web3-auth function to use an AbortController (or AbortSignal.timeout when available) to enforce a reasonable timeout, pass signal into fetch, and ensure you abort the controller on timeout or on cleanup so the mutation doesn't hang waiting for the callback endpoint.
43-45: Type assertion for response unwrapping works but is fragile.The
as { data: ... }cast correctly unwraps the hey-api response (addressing the prior review), but it will silently break if the response shape changes. A safer approach could be to assert the presence of.dataat runtime or use a type guard, though this is acceptable for now given the generated client.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/react/src/hooks/use-verify-web3-auth.ts` around lines 43 - 45, The current untyped cast that unwraps the API response into verifyResult (using verifyResponse as { data: Web3Eip155VerifyResponse | Web3SolanaVerifyResponse }).data is fragile; change it to first assert at runtime that verifyResponse is an object with a data property (or use a small type guard function) before extracting .data, and if the check fails throw/log a clear error; reference the verifyResult and verifyResponse variables and the Web3Eip155VerifyResponse / Web3SolanaVerifyResponse types in use-verify-web3-auth.ts so the guard verifies the shape and then safely assigns verifyResult.apps/next/hooks/use-wallet-auth.ts (1)
9-14: Duplicated helpers acrossuse-wallet-auth.tsanduse-link-wallet.ts.
REJECTION_PATTERNS,isWalletRejection, andbuildSiwsMessageare duplicated almost identically in both files. Consider extracting them into a shared module (e.g.,@/wallet/utils.ts) to keep things DRY.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/next/hooks/use-wallet-auth.ts` around lines 9 - 14, The REJECTION_PATTERNS array, isWalletRejection(error) function, and buildSiwsMessage(...) are duplicated; extract these helpers into a single shared module (e.g., wallet utils) and replace the copies in use-wallet-auth.ts and use-link-wallet.ts with imports from that new module. Create a new file exporting REJECTION_PATTERNS, isWalletRejection, and buildSiwsMessage, update both hooks to import those symbols, and ensure any types used by buildSiwsMessage are exported or adapted so the hooks compile without changing their local logic.apps/next/hooks/use-web3-nonce.test.tsx (2)
28-50: No error-path test for a rejected nonce callBoth success-path tests are solid, but there's no coverage for when the nonce endpoint rejects. Since this hook feeds an auth flow, a rejected fetch producing a defined
error(anddataremainingundefined) is worth asserting.♻️ Suggested additional test case
+ it('surfaces error when nonce fetch rejects', async () => { + const client = createMockClient() + const apiError = new Error('network error') + vi.mocked(client.auth.web3.eip155.nonce).mockRejectedValueOnce(apiError) + + const { result } = renderHook(() => useWeb3Nonce({ chain: 'eip155', address: '0x1234' }), { + wrapper: createWrapper(client), + }) + + await waitFor(() => expect(result.current.isError).toBe(true)) + expect(result.current.error).toBe(apiError) + expect(result.current.data).toBeUndefined() + })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/next/hooks/use-web3-nonce.test.tsx` around lines 28 - 50, Add a test covering the error path where the nonce endpoint rejects: in apps/next/hooks/use-web3-nonce.test.tsx create a new it(...) that uses createMockClient() but configures client.auth.web3.eip155.nonce (or solana.nonce) to return a rejected promise (e.g., mockRejectedValueOnce) before rendering useWeb3Nonce; render the hook with createWrapper(client), await waitFor that result.current.error is defined and result.current.data is undefined, and assert the correct client.auth.web3.<chain>.nonce mock was called while the other chain's nonce was not called (use the same call shape as existing tests).
58-60: Replace trivialtoBeDefined()check with explicittoBe('idle')assertionIn React Query v5,
fetchStatusis always initialised to one of'idle','fetching', or'paused'— neverundefined. ThewaitFor(() => expect(result.current.fetchStatus).toBeDefined())condition is trivially satisfied on the first render and provides no assurance that the disabled query reached an idle state. Assert the expected settled state explicitly with.toBe('idle')instead.♻️ Proposed fix
- await waitFor(() => expect(result.current.fetchStatus).toBeDefined()) + await waitFor(() => expect(result.current.fetchStatus).toBe('idle')) expect(client.auth.web3.eip155.nonce).not.toHaveBeenCalled() expect(result.current.data).toBeUndefined()Apply the same change at line 70.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/next/hooks/use-web3-nonce.test.tsx` around lines 58 - 60, Replace the trivial existence assertion with an explicit idle-state check: change the waitFor assertion that currently checks result.current.fetchStatus with toBeDefined() to assert toBe('idle') so the test verifies the disabled query reached the settled idle state; do the same replacement for the second occurrence around the later assertion (the one mirrored at line 70). Ensure you reference result.current.fetchStatus in the updated expectations and keep the surrounding checks for client.auth.web3.eip155.nonce and result.current.data unchanged.apps/next/hooks/use-wallet.test.tsx (1)
64-69: Consider adding a test for solana-only fallback when chain is omitted.The current test covers
eip155 ?? solanawith both adapters present (eip155 wins). The right-hand side of the??— where only solana is registered — isn't exercised.✨ Suggested additional test
+ it('returns solana adapter when chain omitted and only solana is registered', () => { + const { result } = renderHook(() => useWallet(), { + wrapper: createWrapper({ solana: mockSolanaAdapter }), + }) + expect(result.current).toEqual(mockSolanaAdapter) + })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/next/hooks/use-wallet.test.tsx` around lines 64 - 69, The test coverage misses the branch where eip155 is absent and the hook should fallback to Solana; add a new test in use-wallet.test.tsx that calls renderHook(() => useWallet(), { wrapper: createWrapper({ solana: mockSolanaAdapter }) }) and assert expect(result.current).toEqual(mockSolanaAdapter) so useWallet's solana-only fallback is exercised (referencing useWallet, createWrapper, mockSolanaAdapter)..github/workflows/api-e2e.yml (4)
16-18:cancel-in-progress: falsewill queue—not cancel—stale PR runs, wasting CI minutes.For a PR workflow the idiomatic setting is
true: when a new commit lands, any still-running run for the samerefis cancelled immediately.♻️ Proposed fix
concurrency: group: api-e2e-${{ github.ref }} - cancel-in-progress: false + cancel-in-progress: true🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/api-e2e.yml around lines 16 - 18, The workflow's concurrency block currently sets cancel-in-progress: false which queues stale PR runs; change cancel-in-progress to true in the concurrency section (the concurrency.group and cancel-in-progress keys) so that when a new run for the same ref starts it immediately cancels any in-progress run rather than queuing it.
29-30: Consider adding atimeout-minutesto guard against hung runs.A frozen Playwright browser or stalled turbo build will hold the runner until GitHub's default 6-hour cap. A shorter limit (e.g. 30–45 min) improves feedback latency and reduces wasted runner time.
♻️ Proposed addition
build-and-test: runs-on: ubuntu-latest + timeout-minutes: 45🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/api-e2e.yml around lines 29 - 30, Add a timeout to the GitHub Actions job "build-and-test" to prevent hung runs: update the job definition for build-and-test by adding a timeout-minutes property (e.g., timeout-minutes: 45) under the job configuration so the runner will cancel the job if it exceeds the specified duration.
26-26: Simplify theOPEN_ROUTER_API_KEYfallback expression.Empty string is falsy in GitHub Actions expressions, so the
!= '' &&guard is redundant and adds noise.♻️ Proposed simplification
- OPEN_ROUTER_API_KEY: ${{ secrets.OPEN_ROUTER_API_KEY != '' && secrets.OPEN_ROUTER_API_KEY || 'sk-or-v1-dummy-key-for-unit-tests' }} + OPEN_ROUTER_API_KEY: ${{ secrets.OPEN_ROUTER_API_KEY || 'sk-or-v1-dummy-key-for-unit-tests' }}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/api-e2e.yml at line 26, The fallback expression for OPEN_ROUTER_API_KEY is overly verbose: remove the redundant "!= '' &&" guard and simplify the value to use the secret directly with a logical-or fallback (i.e., replace the current expression with one that uses secrets.OPEN_ROUTER_API_KEY || 'sk-or-v1-dummy-key-for-unit-tests') so empty string falsiness is handled by the OR; update the OPEN_ROUTER_API_KEY entry accordingly.
1-18: Add apermissionsblock for least-privilege GITHUB_TOKEN access.Without an explicit
permissionsdeclaration the workflow inherits whatever the repository-level default is. For a read-only test pipeline, lock it down explicitly.🔒️ Proposed fix
name: API (E2E) +permissions: + contents: read + on:🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/api-e2e.yml around lines 1 - 18, Add an explicit top-level GitHub Actions permissions block to the "API (E2E)" workflow to enforce least-privilege GITHUB_TOKEN access; update the workflow (the file containing the "name: API (E2E)" and "concurrency: group: api-e2e-${{ github.ref }}" entries) to include a permissions section granting only the minimum scopes your E2E tests need (for example: contents: read and packages: read if you only need repository and package read access), removing implicit broader defaults—place the permissions block at the top level of the workflow YAML so the workflow runs with the reduced privileges.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In @.github/workflows/next-e2e.yml:
- Around line 19-21: The workflow's concurrency block sets cancel-in-progress:
false which mirrors the same risky behavior flagged in api-e2e.yml; update the
concurrency configuration in this file by changing cancel-in-progress to true
(or remove the explicit key to use the default) so in-progress runs are
cancelled when a new run for the same group starts—look for the concurrency
block and the cancel-in-progress key in the next-e2e workflow and make the
change.
- Around line 1-18: The workflow "Next (E2E)" is missing the top-level
permissions block present in api-e2e.yml; add a permissions section at the
top-level of the workflow (alongside name and on) matching api-e2e.yml so the
job has the same required GitHub Actions permissions (e.g., appropriate
read/write scopes for contents, actions, packages, etc.), ensuring the workflow
behaves the same as api-e2e.yml.
- Line 30: The OPEN_ROUTER_API_KEY expression in next-e2e.yml is redundant (same
as api-e2e.yml); simplify by using a single clear fallback pattern for
OPEN_ROUTER_API_KEY (e.g., use the secrets value or a dummy default) and make it
consistent with api-e2e.yml so both workflows use the same expression for
OPEN_ROUTER_API_KEY; update the OPEN_ROUTER_API_KEY line in next-e2e.yml to
match the canonical form used in api-e2e.yml to remove duplication.
- Around line 32-34: The workflow job "build-and-test" is missing a timeout
setting; in the next-e2e.yml job definition (job name build-and-test, currently
with runs-on: ubuntu-latest) add a timeout-minutes field matching the value used
in api-e2e.yml (e.g., timeout-minutes: 10) directly under the job declaration so
the GitHub Actions runner will cancel long-running runs.
In `@apps/fastify/vercel.json`:
- Around line 5-7: The build/install/dev commands use unversioned "npx pnpm"
calls; change each "npx pnpm" in the buildCommand, installCommand, and
devCommand to a version-pinned invocation (e.g. "npx pnpm@<version>") that
matches the packageManager declaration in package.json so the runtime pnpm
version is deterministic; update buildCommand, installCommand, and devCommand to
use the exact version string from packageManager.
---
Nitpick comments:
In @.github/workflows/api-e2e.yml:
- Around line 16-18: The workflow's concurrency block currently sets
cancel-in-progress: false which queues stale PR runs; change cancel-in-progress
to true in the concurrency section (the concurrency.group and cancel-in-progress
keys) so that when a new run for the same ref starts it immediately cancels any
in-progress run rather than queuing it.
- Around line 29-30: Add a timeout to the GitHub Actions job "build-and-test" to
prevent hung runs: update the job definition for build-and-test by adding a
timeout-minutes property (e.g., timeout-minutes: 45) under the job configuration
so the runner will cancel the job if it exceeds the specified duration.
- Line 26: The fallback expression for OPEN_ROUTER_API_KEY is overly verbose:
remove the redundant "!= '' &&" guard and simplify the value to use the secret
directly with a logical-or fallback (i.e., replace the current expression with
one that uses secrets.OPEN_ROUTER_API_KEY ||
'sk-or-v1-dummy-key-for-unit-tests') so empty string falsiness is handled by the
OR; update the OPEN_ROUTER_API_KEY entry accordingly.
- Around line 1-18: Add an explicit top-level GitHub Actions permissions block
to the "API (E2E)" workflow to enforce least-privilege GITHUB_TOKEN access;
update the workflow (the file containing the "name: API (E2E)" and "concurrency:
group: api-e2e-${{ github.ref }}" entries) to include a permissions section
granting only the minimum scopes your E2E tests need (for example: contents:
read and packages: read if you only need repository and package read access),
removing implicit broader defaults—place the permissions block at the top level
of the workflow YAML so the workflow runs with the reduced privileges.
In `@apps/fastify/vercel.json`:
- Line 8: The git deployment setting for Vercel currently enables both branches
via the "git" -> "deploymentEnabled" object with "main": true and "develop":
true; confirm whether enabling "develop" to produce live backend deployments is
intentional and either 1) ensure "develop" is configured to target a dedicated
staging environment (separate env vars, non-production DB, restricted CORS and
endpoints) or 2) revert "develop" to false and rely on preview/protected
deployments while keeping "main": true; update the "deploymentEnabled" entry
accordingly to reflect the chosen option and add a short repo comment or PR note
documenting the decision.
In `@apps/next/hooks/use-wallet-auth.ts`:
- Around line 9-14: The REJECTION_PATTERNS array, isWalletRejection(error)
function, and buildSiwsMessage(...) are duplicated; extract these helpers into a
single shared module (e.g., wallet utils) and replace the copies in
use-wallet-auth.ts and use-link-wallet.ts with imports from that new module.
Create a new file exporting REJECTION_PATTERNS, isWalletRejection, and
buildSiwsMessage, update both hooks to import those symbols, and ensure any
types used by buildSiwsMessage are exported or adapted so the hooks compile
without changing their local logic.
In `@apps/next/hooks/use-wallet.test.tsx`:
- Around line 64-69: The test coverage misses the branch where eip155 is absent
and the hook should fallback to Solana; add a new test in use-wallet.test.tsx
that calls renderHook(() => useWallet(), { wrapper: createWrapper({ solana:
mockSolanaAdapter }) }) and assert
expect(result.current).toEqual(mockSolanaAdapter) so useWallet's solana-only
fallback is exercised (referencing useWallet, createWrapper, mockSolanaAdapter).
In `@apps/next/hooks/use-web3-nonce.test.tsx`:
- Around line 28-50: Add a test covering the error path where the nonce endpoint
rejects: in apps/next/hooks/use-web3-nonce.test.tsx create a new it(...) that
uses createMockClient() but configures client.auth.web3.eip155.nonce (or
solana.nonce) to return a rejected promise (e.g., mockRejectedValueOnce) before
rendering useWeb3Nonce; render the hook with createWrapper(client), await
waitFor that result.current.error is defined and result.current.data is
undefined, and assert the correct client.auth.web3.<chain>.nonce mock was called
while the other chain's nonce was not called (use the same call shape as
existing tests).
- Around line 58-60: Replace the trivial existence assertion with an explicit
idle-state check: change the waitFor assertion that currently checks
result.current.fetchStatus with toBeDefined() to assert toBe('idle') so the test
verifies the disabled query reached the settled idle state; do the same
replacement for the second occurrence around the later assertion (the one
mirrored at line 70). Ensure you reference result.current.fetchStatus in the
updated expectations and keep the surrounding checks for
client.auth.web3.eip155.nonce and result.current.data unchanged.
In `@apps/next/scripts/run-e2e-local.mjs`:
- Around line 63-71: The current check uses `!process.env.SKIP_BUILD` which
treats any non-empty string (like "0" or "false") as truthy and incorrectly
skips builds; change the condition that decides whether to run the build to
explicitly test the environment variable value (e.g., only skip when
`process.env.SKIP_BUILD === '1'` or another explicit truthy token), and apply
the same explicit-value check to the `SKIP_KILL_PORTS` check so both
`process.env.SKIP_BUILD` and `process.env.SKIP_KILL_PORTS` behave predictably
(use the exact string comparison against the documented token such as '1' in the
`run-e2e-local.mjs` logic that spawns `pnpm ... build:e2e` and the port-killing
branch).
In `@packages/react/src/hooks/use-verify-web3-auth.ts`:
- Around line 47-66: The fetch to authCallbackUrl in the use-verify-web3-auth
hook can hang because it has no timeout; update the fetch call in the
use-verify-web3-auth function to use an AbortController (or AbortSignal.timeout
when available) to enforce a reasonable timeout, pass signal into fetch, and
ensure you abort the controller on timeout or on cleanup so the mutation doesn't
hang waiting for the callback endpoint.
- Around line 43-45: The current untyped cast that unwraps the API response into
verifyResult (using verifyResponse as { data: Web3Eip155VerifyResponse |
Web3SolanaVerifyResponse }).data is fragile; change it to first assert at
runtime that verifyResponse is an object with a data property (or use a small
type guard function) before extracting .data, and if the check fails throw/log a
clear error; reference the verifyResult and verifyResponse variables and the
Web3Eip155VerifyResponse / Web3SolanaVerifyResponse types in
use-verify-web3-auth.ts so the guard verifies the shape and then safely assigns
verifyResult.
Reverts npx pnpm to pnpm in build/install/dev commands to fix 'No Next.js version detected' Vercel build error.
Summary by CodeRabbit
Release Notes
New Features
Documentation
Refactor