Skip to content

Wallet Integration

Fetch Quests uses wagmi + viem for Ethereum wallet connectivity with SIWE for authentication.

Supported Wallets

  • MetaMask (injected provider)
  • WalletConnect (coming soon)
  • Coinbase Wallet (coming soon)

Configuration

Chain Setup

typescript
// frontend/src/config/web3.ts

export const BASE_SEPOLIA = {
  id: 84532,
  name: 'Base Sepolia',
  testnet: true,
  blockExplorerUrl: 'https://sepolia.basescan.org',
  blockExplorerName: 'BaseScan',
};

export const BASE_MAINNET = {
  id: 8453,
  name: 'Base',
  testnet: false,
  blockExplorerUrl: 'https://basescan.org',
  blockExplorerName: 'BaseScan',
};

// Toggle via environment variable
export const ACTIVE_CHAIN = import.meta.env.VITE_NETWORK === 'mainnet'
  ? BASE_MAINNET
  : BASE_SEPOLIA;

export const SUPPORTED_CHAIN_ID = ACTIVE_CHAIN.id;

wagmi Configuration

typescript
// frontend/src/config/wagmi.ts

import { createConfig, http } from 'wagmi';
import { baseSepolia, base } from 'wagmi/chains';
import { ACTIVE_CHAIN } from './web3';

export const config = ACTIVE_CHAIN.testnet
  ? createConfig({
      chains: [baseSepolia],
      transports: { [baseSepolia.id]: http() },
    })
  : createConfig({
      chains: [base],
      transports: { [base.id]: http() },
    });

Connection Flow

1. User Clicks "Connect Wallet"

typescript
const { connect } = useConnect();

// Trigger MetaMask popup
connect({ connector: injected() });

2. Network Detection

typescript
const chainId = useChainId();
const isCorrectNetwork = chainId === SUPPORTED_CHAIN_ID;

3. Network Switch (if needed)

typescript
const { switchChain } = useSwitchChain();

// Prompt user to switch to Base
await switchChain({ chainId: SUPPORTED_CHAIN_ID });

4. MetaMask Detection

typescript
// Check if MetaMask is installed
const hasInjected = typeof window !== 'undefined' 
  && typeof window.ethereum !== 'undefined';

if (!hasInjected) {
  // Show "Install MetaMask" UI
}

Block Explorer URLs

Helper functions for linking to block explorers:

typescript
export function getExplorerAddressUrl(address: string): string {
  return `${BLOCK_EXPLORER_URL}/address/${address}`;
}

export function getExplorerTxUrl(txHash: string): string {
  return `${BLOCK_EXPLORER_URL}/tx/${txHash}`;
}

export function getExplorerTokenUrl(tokenAddress: string): string {
  return `${BLOCK_EXPLORER_URL}/token/${tokenAddress}`;
}

ENS Resolution

typescript
// frontend/src/config/ens.ts

export async function lookupEnsName(address: string): Promise<string | null> {
  // Uses mainnet ENS (works for all addresses)
  const client = createPublicClient({
    chain: mainnet,
    transport: http('https://cloudflare-eth.com'),
  });
  return client.getEnsName({ address });
}

export async function resolveEnsAddress(name: string): Promise<string | null> {
  const client = createPublicClient({
    chain: mainnet,
    transport: http('https://cloudflare-eth.com'),
  });
  return client.getEnsAddress({ name });
}

AppContext Integration

The AppContext manages wallet state globally:

typescript
const { address: account } = useAccount();
const { connect } = useConnect();
const { disconnect } = useDisconnect();
const { switchChain } = useSwitchChain();

// Expose to components
<AppContext.Provider value={{
  account,
  connect,
  disconnect,
  switchNetwork,
  isCorrectNetwork,
  // ...
}}>

Network Banner

When user is on wrong network, a banner appears:

tsx
function NetworkBanner() {
  const { isCorrectNetwork, switchNetwork } = useApp();
  
  if (isCorrectNetwork) return null;
  
  return (
    <div className="bg-yellow-500 text-black p-2 text-center">
      Wrong network. Please switch to Base.
      <button onClick={switchNetwork}>Switch Network</button>
    </div>
  );
}

Environment Variables

VariableDescriptionExample
VITE_NETWORKTarget networkmainnet or omit for testnet

Troubleshooting

"MetaMask not detected"

User needs to install MetaMask browser extension or use a Web3-enabled browser.

"Wrong network"

User needs to switch to Base (or Base Sepolia for testnet). The app will prompt automatically.

Connection fails silently

Check browser console for errors. Common causes:

  • User rejected connection request
  • MetaMask locked
  • RPC endpoint unreachable

Fetch Quests — Decentralized Gig-Work Platform