Tezos LogoTezos Boilerplate

Tezos Wallet Boilerplate Docs

Wallet Integration Guide

Complete guide to the modern wallet system with automatic initialization and state restoration.

Architecture Overview

The wallet system is built on three core components working together to provide seamless wallet integration.

๐Ÿช Wallet Store

Zustand-based global state management for wallet connections and Tezos instances.

๐Ÿช useTezos Hook

React hook that provides easy access to wallet functionality and auto-initialization.

๐Ÿ”Œ WalletProvider

React provider that ensures wallet initialization happens at the app level.

System Flow

App Startup โ†’ WalletProvider โ†’ initializeWallets() โ†’ Check Existing Connections

1. Beacon Wallet Check:
   - Initialize BeaconWallet instance
   - Call wallet.client.getActiveAccount()
   - If account exists โ†’ set address in store

2. Kukai Check:
   - Initialize KukaiEmbed instance
   - Check kukai.user.pkh for existing session
   - If session exists โ†’ set address in store

3. State Ready:
   - Components receive wallet state via useTezos()
   - UI reflects connection status automatically

Wallet Store Details

The Zustand store manages all wallet state and provides methods for connection management.

Store Interface

interface WalletState {
  // Core instances
  Tezos: TezosToolkit;           // Main Taquito instance
  wallet: BeaconWallet | null;   // Beacon wallet instance
  kukai: KukaiEmbed | null;      // Kukai wallet instance
  
  // Connection state
  address: string | null;        // Connected wallet address
  isInitialized: boolean;        // Initialization status
  
  // Methods
  initializeWallets: () => Promise<void>;     // Auto-init on startup
  connectWallet: () => Promise<void>;         // Connect Beacon wallet
  connectKukai: () => Promise<void>;          // Connect Kukai wallet  
  disconnectWallet: () => Promise<void>;      // Disconnect all wallets
}

Key Features

  • โœ… Auto-initialization: Checks for existing connections on app start
  • โœ… Multi-wallet support: Handles both Beacon and Kukai simultaneously
  • โœ… Network awareness: Automatically configures for testnet/mainnet
  • โœ… Error handling: Graceful degradation when wallets fail to initialize
  • โœ… Type safety: Full TypeScript support with proper error types

Initialization Process

Understanding how wallet initialization works helps you debug connection issues and optimize performance.

Initialization Flow

async initializeWallets() {
  try {
    // 1. Import wallet libraries dynamically
    const { BeaconWallet } = await import('@taquito/beacon-wallet');
    const { KukaiEmbed, Networks } = await import('kukai-embed');
    
    // 2. Initialize Beacon Wallet
    const wallet = new BeaconWallet({
      name: 'Tezos Boilerplate',
      preferredNetwork: ENV === 'dev' ? NetworkType.GHOSTNET : NetworkType.MAINNET
    });
    
    // 3. Set as Tezos provider
    Tezos.setWalletProvider(wallet);
    
    // 4. Check for existing active account
    const activeAccount = await wallet.client.getActiveAccount();
    if (activeAccount) {
      // User was previously connected โ†’ restore state
      set({ address: activeAccount.address });
    }
    
    // 5. Initialize Kukai
    const kukai = new KukaiEmbed({
      net: ENV === 'dev' ? Networks.ghostnet : Networks.mainnet
    });
    await kukai.init();
    
    // 6. Check for existing Kukai session
    if (kukai.user?.pkh) {
      // Kukai session exists โ†’ restore state
      if (!activeAccount) { // Only if no Beacon connection
        set({ address: kukai.user.pkh });
      }
    }
    
    // 7. Mark as initialized
    set({ isInitialized: true });
    
  } catch (error) {
    console.error('Wallet initialization failed:', error);
    set({ isInitialized: true }); // Still mark as initialized to prevent retries
  }
}

Using the useTezos Hook

The useTezos hook is your main interface to the wallet system. It handles initialization and provides a clean API.

Hook Implementation

export const useTezos = () => {
  const store = useWalletStore();
  
  // Auto-initialize on first use
  useEffect(() => {
    if (!store.isInitialized) {
      store.initializeWallets();
    }
  }, [store.isInitialized, store.initializeWallets]);
  
  return {
    Tezos: store.Tezos,
    wallet: store.wallet,
    address: store.address,
    kukai: store.kukai,
    isInitialized: store.isInitialized,
    connectWallet: store.connectWallet,
    connectKukai: store.connectKukai,
    disconnectWallet: store.disconnectWallet
  };
};

Hook Usage Patterns

Check initializationif (!isInitialized) return <Loading />
Check connectionif (address) โ†’ show connected state
Connect walletawait connectWallet() โ†’ handles permissions
Send transactionawait Tezos.wallet.transfer(...).send()
Get balanceawait Tezos.tz.getBalance(address)
Disconnectawait disconnectWallet() โ†’ clears all state

State Restoration

One of the key features is automatic state restoration - your users stay connected across page refreshes.

๐Ÿ”„ How State Restoration Works

  1. User connects wallet in your dApp
  2. Wallet stores connection info in browser storage (handled by Beacon/Kukai)
  3. User refreshes page or navigates away and back
  4. WalletProvider runs initializeWallets() on app start
  5. System checks for existing wallet connections
  6. If found, automatically restores the connected state
  7. UI immediately shows connected state - no re-login required!

Testing State Restoration

// Test the restoration flow:

1. Connect wallet in your dApp
2. Open browser dev tools โ†’ Application tab โ†’ Local Storage
3. Look for beacon: or kukai: entries (these persist the connection)
4. Refresh the page (Cmd+R / Ctrl+R)
5. Watch the wallet button - it should show "Disconnect" immediately
6. No login prompt should appear

// If restoration fails:
// - Check browser console for errors
// - Verify WalletProvider is wrapping your app
// - Ensure useTezos is called in components that need wallet state

Best Practices

Follow these patterns to get the most out of the wallet system.

โœ… Do

  • โ€ข Check isInitialized before showing wallet buttons
  • โ€ข Use the address to determine connection state
  • โ€ข Handle connection errors gracefully
  • โ€ข Show loading states during operations
  • โ€ข Use Tezos.wallet for transaction operations

โŒ Don't

  • โ€ข Create multiple TezosToolkit instances
  • โ€ข Initialize wallets outside the store
  • โ€ข Block UI while waiting for initialization
  • โ€ข Assume wallet state without checking
  • โ€ข Forget to handle disconnection

Next Steps

๐Ÿš€ Try It Out

Test the wallet system with the interactive components

Go to playground โ†’

๐Ÿ”ง Troubleshooting

Having issues? Check the troubleshooting guide

Get help โ†’