Frontend

The Web3 variant adds blockchain-specific frontend components, hooks, and configuration on top of the base package's React setup.

Configuration

The createWeb3Config() function sets up RainbowKit with the supported chains and WalletConnect project ID. It uses RainbowKit's getDefaultConfig() for a simple setup with standard wallet options.

Chain configuration lives in src/shared/contracts/chain.ts. The WEB3_SUPPORTED_CHAINS environment variable specifies which networks to enable. Supported chains include anvil (local development), mainnet, sepolia, and base. The first chain in the list becomes the primary chain.

Provider Structure

The Web3 variant wraps the base provider stack with WagmiProvider and RainbowKitProvider:

<ThemeProvider>
  <WagmiProvider config={web3Config}>
    <QueryClientProvider client={queryClient}>
      <RainbowKitProvider theme={rainbowKitTheme}>
        <AuthProvider>
          <SocketProvider>
            <ToastProvider>
              {/* App content */}
            </ToastProvider>
          </SocketProvider>
        </AuthProvider>
      </RainbowKitProvider>
    </QueryClientProvider>
  </WagmiProvider>
</ThemeProvider>

RainbowKit's theme automatically adapts to the app's light/dark mode via the useTheme() hook.

Wallet Connection

The ConnectWallet component uses RainbowKit's ConnectButton.Custom API to render wallet connection UI. It coordinates with AuthContext to trigger SIWE authentication after wallet connection.

The component shows different states: a connect button when disconnected, a "Wrong network" warning for unsupported chains, and the connected account address when authenticated. The optional showNetwork prop adds a chain selector button.

Token Hooks

Two hooks handle ERC-20 token operations:

useTokens.ts provides read operations:

  • useMyTokens() — Fetches all tokens where the connected wallet has a balance, using multicall for efficiency
  • useTokenInfo(address) — Fetches details for a specific token (name, symbol, decimals, balance)
  • useTokenCount() — Returns the total number of tokens deployed through the factory

useTokenActions.ts provides write operations:

  • useCreateToken() — Deploys a new ERC-20 token through the factory contract
  • useTransferToken() — Transfers tokens to another address
  • useTransactionStatus(hash) — Tracks transaction confirmation status

These hooks use React Query for caching and automatic refetching. Token queries refresh every 5-30 seconds to keep balances current.

Contract Utilities

The src/shared/contracts/ folder provides utilities for contract interactions:

  • getFactoryContractInfo() — Returns the factory contract address and ABI
  • getERC20ContractInfo(address) — Returns ERC-20 ABI for any token address
  • readContract() — Reads contract state with proper typing
  • writeContract() — Sends transactions through the wallet
  • fetchTokenWithBalance() — Fetches token metadata and balance in one multicall

Contract ABIs are generated from Solidity files during build. See src/shared/abi/generated.ts for the generated types.

Token Components

Several components handle token display and management:

Multicall

Token operations use Viem's multicall support to batch multiple contract reads into a single RPC request. The fetchMultipleTokensWithBalances() function demonstrates this — it fetches name, symbol, decimals, and balance for multiple tokens in one call.

For development on Anvil, QuickDapp automatically deploys Multicall3 if it doesn't exist. See Chain Monitoring for details on the deployMulticall3 worker job.

Error Handling

Transaction errors are caught and displayed through the toast system. Common errors include:

  • User rejected the transaction
  • Insufficient funds for gas
  • Contract reverted (with the revert reason if available)

The hooks return error and isError states so components can display appropriate feedback.