Skip to content

refactor: replace withWalletStatusVerifier HoC with useWalletStatus hook#427

Open
fernandomg wants to merge 7 commits intodevelopfrom
feat/303-hoc-to-hooks
Open

refactor: replace withWalletStatusVerifier HoC with useWalletStatus hook#427
fernandomg wants to merge 7 commits intodevelopfrom
feat/303-hoc-to-hooks

Conversation

@fernandomg
Copy link
Copy Markdown
Member

Summary

Replaces the withWalletStatusVerifier HoC with a new useWalletStatus hook. Shared components (TransactionButton, SignButton) now internalize wallet verification — they're fully self-contained. The WalletStatusVerifier wrapper component stays as the primary external API for app developers and agents.

Closes #303

Changes

  • New useWalletStatus hook — state-only, built on top of useWeb3Status
  • WalletStatusVerifier refactored to use the hook, HoC export removed
  • TransactionButton and SignButton internalize wallet verification via the hook
  • Demo components migrated from HoC to <WalletStatusVerifier> wrapper
  • SwitchChainButton extracted to shared ui/ to avoid duplication
  • TypeDoc blockTags config fixed (reduced warnings from 330 to 9)

Design decisions

  • Hooks return state only, never JSX — components own their rendering
  • Two audiences, two patternsWalletStatusVerifier wrapper for external consumers (declarative, agent-friendly), useWalletStatus hook for internal/advanced use
  • Redundant verification in demos is intentional — they serve as standalone copy-paste examples
  • ChainsIds type used throughout instead of plain number

Acceptance criteria

  • withWalletStatusVerifier HoC removed — zero references in src/
  • WalletStatusVerifier wrapper component API unchanged
  • TransactionButton and SignButton self-contained with wallet verification
  • All demo components migrated from HoC to wrapper
  • 20 new tests (67 total, all passing)
  • TypeDoc generates without component-specific warnings

Test plan

  • pnpm test — 12 files, 67 tests, all green
  • pnpm tsc --noEmit — clean
  • pnpm typedoc:build — 9 warnings (pre-existing, unrelated files)
  • pnpm docs:build — success
  • grep -r "withWalletStatusVerifier" src/ — zero results

Breaking changes

withWalletStatusVerifier removed. All consumers updated in this PR. Not a public API yet (dAppBooster is a template, not a published SDK).

Checklist

  • Self-reviewed my own diff
  • Tests added or updated
  • Docs updated (if applicable)
  • No unrelated changes bundled in

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 30, 2026

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

Project Deployment Actions Updated (UTC)
components.dappbooster Ready Ready Preview, Comment Mar 30, 2026 8:05pm
demo.dappbooster Ready Ready Preview, Comment Mar 30, 2026 8:05pm
docs.dappbooster Ready Ready Preview, Comment Mar 30, 2026 8:05pm

Request Review

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors wallet-status gating from the withWalletStatusVerifier HoC pattern to a state-only useWalletStatus hook, keeping WalletStatusVerifier as the primary wrapper API while making shared buttons self-contained. Also includes related demo migrations and documentation/test configuration updates.

Changes:

  • Added useWalletStatus hook and refactored WalletStatusVerifier, TransactionButton, and SignButton to use it (HoC removed).
  • Extracted a shared SwitchChainButton and migrated demos to use <WalletStatusVerifier>.
  • Reduced TypeDoc warnings via blockTags config updates and improved test typing via tsconfig.json types.

Reviewed changes

Copilot reviewed 13 out of 14 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
typedoc.json Expands recognized TSDoc block tags to reduce TypeDoc warnings.
tsconfig.json Adds jest-dom Vitest matcher types to TS global types.
src/hooks/useWalletStatus.ts Introduces hook providing wallet gating state based on useWeb3Status.
src/hooks/useWalletStatus.test.ts Unit tests for useWalletStatus behavior and chain selection.
src/components/sharedComponents/ui/SwitchChainButton.tsx Extracts reusable styled “switch chain” button.
src/components/sharedComponents/WalletStatusVerifier.tsx Refactors wrapper component to use useWalletStatus (HoC removed).
src/components/sharedComponents/WalletStatusVerifier.test.tsx Adds tests covering fallback, chain switch UI, and children rendering.
src/components/sharedComponents/TransactionButton.tsx Internalizes wallet verification and chain switching before sending tx.
src/components/sharedComponents/TransactionButton.test.tsx Adds tests for connect fallback, chain switch UI, and ready state rendering.
src/components/sharedComponents/SignButton.tsx Internalizes wallet verification and chain switching before signing.
src/components/sharedComponents/SignButton.test.tsx Adds tests for connect fallback, chain switch UI, and ready state rendering.
src/components/pageComponents/home/Examples/demos/TransactionButton/NativeToken.tsx Migrates demo from HoC usage to <WalletStatusVerifier>.
src/components/pageComponents/home/Examples/demos/TransactionButton/ERC20ApproveAndTransferButton/index.tsx Migrates demo from HoC to wrapper; keeps suspense wrapper.
src/components/pageComponents/home/Examples/demos/OptimismCrossDomainMessenger/index.tsx Migrates demo from HoC usage to <WalletStatusVerifier>.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@gabitoesmiapodo
Copy link
Copy Markdown
Collaborator

Hooks return state only, never JSX

Yay.

New state-only hook that answers "is the wallet ready to interact
with this chain?" Built on top of useWeb3Status.

Closes part of #303
The withWalletStatusVerifier HoC is removed. The WalletStatusVerifier
wrapper component now uses the useWalletStatus hook internally.
Extracts shared SwitchChainButton to ui/SwitchChainButton.tsx.
Same external API — no breaking change for wrapper consumers.

Closes part of #303
TransactionButton now uses useWalletStatus hook directly instead of
being wrapped with withWalletStatusVerifier HoC. Adds optional
chainId, fallback, and switchChainLabel props.

Closes part of #303
SignButton now uses useWalletStatus hook directly instead of
withWalletStatusVerifier HoC. Adds optional chainId, fallback,
and switchChainLabel props.

Closes part of #303
… HoC

NativeToken, ERC20ApproveAndTransferButton, and
OptimismCrossDomainMessenger now use the declarative
<WalletStatusVerifier> wrapper instead of withWalletStatusVerifier.
Suspense HoCs (withSuspense, withSuspenseAndRetry) are preserved.

Closes #303
Add @param, @returns, @example, @throws to TypeDoc blockTags config
(they were being treated as unknown). Move param docs to interface
properties where TypeDoc can resolve them for destructured params.

Reduces TypeDoc warnings from 330 to 9 (remaining are in unrelated files).
- Add targetChainId to useWalletStatus return, removing unsafe
  `as ChainsIds` casts from all consumers
- Fix onSuccess callback in ERC20ApproveAndTransferButton demo
  (was returning refetchBalance instead of passing it directly)
import { useSignMessage } from 'wagmi'

interface SignButtonProps extends Omit<ButtonProps, 'onError'> {
/** Target chain ID for wallet status verification. */
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure we need all these comments, the prop names are descriptive enough.

import { useWaitForTransactionReceipt } from 'wagmi'

interface TransactionButtonProps extends ButtonProps {
/** Target chain ID for wallet status verification. */
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

import PrimaryButton from '@/src/components/sharedComponents/ui/PrimaryButton'
import { chakra } from '@chakra-ui/react'

const SwitchChainButton = chakra(PrimaryButton, {
Copy link
Copy Markdown
Collaborator

@gabitoesmiapodo gabitoesmiapodo Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(feel free to ignore)

Do wee need this as a separate component for this? I don't remember if PrimaryButton has variants (we should use it if it does), but also I don't know if the changes here are so profound that merit a new component.

Maybe we could just use PrimaryButton and be done with it.

/** Custom fallback when wallet needs connection. Defaults to ConnectWalletButton. */
fallback?: ReactElement
/** Alternative label for the button. */
label?: string
Copy link
Copy Markdown
Collaborator

@gabitoesmiapodo gabitoesmiapodo Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

label is not used and destructured with ...restProps, it should be removed

@@ -48,75 +29,22 @@ const WalletStatusVerifier: FC<WalletStatusVerifierProps> = ({
fallback = <ConnectWalletButton />,
labelSwitchChain = 'Switch to',
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is called switchChainLabel in SignButton.tsx and TransactionButton.tsx, probably better if all are called the same.

@gabitoesmiapodo
Copy link
Copy Markdown
Collaborator

The demo for Optimism throws if the wallet's not connected:

vendor-react-DzBA3unl.js:24 Error: Use useWeb3StatusConnected only when a wallet is connected
    at h_ (index-eu5b904j.js:3873:11898)
    at index-DmQV0up2.js:1:67001
    at qn (vendor-react-DzBA3unl.js:24:34104)
    at Wn (vendor-react-DzBA3unl.js:24:61918)
    at A1 (vendor-react-DzBA3unl.js:24:72412)
    at r1 (vendor-react-DzBA3unl.js:24:106219)
    at Th (vendor-react-DzBA3unl.js:24:105320)
    at zc (vendor-react-DzBA3unl.js:24:105158)
    at K1 (vendor-react-DzBA3unl.js:24:102305)
    at nv (vendor-react-DzBA3unl.js:24:113707)    

possibly because useWeb3StatusConnected() is called at the top of the component body (the hook throws when the wallet is not connected, so it throws before WalletStatusVerifier is ever rendered)

Maybe wrapping with <WalletStatusVerifier> at the parent level or moving the useWeb3StatusConnected() call into a sub-component rendered only inside the verified tree.

I think something similar should be done in TransactionButton/NativeToken.tsx and TransactionButton/ERC20ApproveAndTransferButton/index.tsx (those don't actually throw, though, so they might be fine).

@gabitoesmiapodo gabitoesmiapodo self-requested a review March 30, 2026 20:24
Copy link
Copy Markdown
Collaborator

@gabitoesmiapodo gabitoesmiapodo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a few comments, I think only the last one is critical.

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.

HoC to hooks

3 participants