or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

i18n.mdindex.mdreact-provider.mdtypes.mdutilities.mdweb3-provider.md
tile.json

web3-provider.mddocs/

Universal Web3 Provider Interface

Abstract interface for wallet providers that enables consistent interaction across different wallet implementations. This interface standardizes wallet connection, chain switching, and account management across various Web3 wallet providers.

Capabilities

Universal Web3 Provider Interface

The core interface that defines the standard API for Web3 wallet providers, abstracting differences between wallet implementations.

/**
 * Universal interface for Web3 wallet providers
 * Standardizes wallet connection, account management, and blockchain interactions
 */
interface UniversalWeb3ProviderInterface {
  /** Currently connected account, undefined if not connected */
  account?: Account;
  
  /** Currently connected blockchain, undefined if not connected */
  chain?: Chain;
  
  /** Current account balance, undefined if not available */
  balance?: Balance;
  
  /** Array of available wallet providers for connection */
  availableWallets?: Wallet[];
  
  /** Array of blockchain networks available for switching */
  availableChains?: Chain[];
  
  /** 
   * Connect to a specified wallet or prompt user to select
   * @param wallet - Optional specific wallet to connect to
   */
  connect?: (wallet?: Wallet) => Promise<void>;
  
  /** Disconnect from the current wallet */
  disconnect?: () => Promise<void>;
  
  /** 
   * Switch to a different blockchain network
   * @param chain - Target blockchain to switch to
   */
  switchChain?: (chain: Chain) => Promise<void>;
  
  /** 
   * Retrieve NFT metadata for a specific token
   * @param params - Object containing contract address and token ID
   */
  getNFTMetadata?: (params: { 
    address: string; 
    tokenId: bigint 
  }) => Promise<NFTMetadata>;
}

Implementation Examples

Basic Provider Implementation

import { 
  UniversalWeb3ProviderInterface, 
  Account, 
  Chain, 
  ChainIds 
} from "@ant-design/web3-common";

class MyWalletProvider implements UniversalWeb3ProviderInterface {
  account?: Account;
  chain?: Chain;
  balance?: Balance;
  availableWallets?: Wallet[];
  availableChains?: Chain[];

  async connect(wallet?: Wallet): Promise<void> {
    // Implementation for connecting to wallet
    if (wallet) {
      // Connect to specific wallet
      console.log(`Connecting to ${wallet.name}`);
    } else {
      // Show wallet selection UI
      console.log("Show wallet selection");
    }
    
    // After successful connection
    this.account = {
      address: "0x742d35cc6634c0532925a3b8d6ac013bbce29cd4",
      name: "User Wallet"
    };
    
    this.chain = {
      id: ChainIds.Mainnet,
      name: "Ethereum Mainnet"
    };
  }

  async disconnect(): Promise<void> {
    // Implementation for disconnecting
    this.account = undefined;
    this.chain = undefined;
    this.balance = undefined;
  }

  async switchChain(chain: Chain): Promise<void> {
    // Implementation for switching chains
    console.log(`Switching to ${chain.name}`);
    this.chain = chain;
    
    // Update balance for new chain
    this.balance = undefined;
  }

  async getNFTMetadata(params: { 
    address: string; 
    tokenId: bigint 
  }): Promise<NFTMetadata> {
    // Implementation for fetching NFT metadata
    const response = await fetch(`/api/nft/${params.address}/${params.tokenId}`);
    return response.json();
  }
}

Provider with Error Handling

class RobustWalletProvider implements UniversalWeb3ProviderInterface {
  account?: Account;
  chain?: Chain;
  balance?: Balance;
  availableWallets?: Wallet[];
  availableChains?: Chain[];

  async connect(wallet?: Wallet): Promise<void> {
    try {
      // Check if wallet is available
      if (wallet && wallet.hasWalletReady) {
        const isReady = await wallet.hasWalletReady();
        if (!isReady) {
          throw new Error(`${wallet.name} is not available`);
        }
      }

      // Perform connection logic
      await this.performConnection(wallet);
      
    } catch (error) {
      console.error("Connection failed:", error);
      throw error;
    }
  }

  async switchChain(chain: Chain): Promise<void> {
    if (!this.account) {
      throw new Error("No wallet connected");
    }

    try {
      // Validate chain is available
      if (this.availableChains && 
          !this.availableChains.find(c => c.id === chain.id)) {
        throw new Error(`Chain ${chain.name} is not supported`);
      }

      await this.performChainSwitch(chain);
      this.chain = chain;
      
    } catch (error) {
      console.error("Chain switch failed:", error);
      throw error;
    }
  }

  private async performConnection(wallet?: Wallet): Promise<void> {
    // Implementation details...
  }

  private async performChainSwitch(chain: Chain): Promise<void> {
    // Implementation details...
  }
}

Provider State Management

class StatefulWalletProvider implements UniversalWeb3ProviderInterface {
  private listeners: Array<(state: Partial<UniversalWeb3ProviderInterface>) => void> = [];
  
  account?: Account;
  chain?: Chain;
  balance?: Balance;
  availableWallets?: Wallet[] = [
    {
      name: "MetaMask",
      remark: "Connect using MetaMask browser extension",
      key: "metamask"
    },
    {
      name: "WalletConnect",
      remark: "Connect using WalletConnect protocol",
      key: "walletconnect"
    }
  ];
  availableChains?: Chain[] = [
    {
      id: ChainIds.Mainnet,
      name: "Ethereum Mainnet"
    },
    {
      id: ChainIds.Polygon,
      name: "Polygon"
    }
  ];

  // Subscribe to state changes
  subscribe(callback: (state: Partial<UniversalWeb3ProviderInterface>) => void): () => void {
    this.listeners.push(callback);
    
    // Return unsubscribe function
    return () => {
      const index = this.listeners.indexOf(callback);
      if (index > -1) {
        this.listeners.splice(index, 1);
      }
    };
  }

  private notifyListeners(): void {
    const state = {
      account: this.account,
      chain: this.chain,
      balance: this.balance,
      availableWallets: this.availableWallets,
      availableChains: this.availableChains
    };
    
    this.listeners.forEach(listener => listener(state));
  }

  async connect(wallet?: Wallet): Promise<void> {
    // Connection implementation
    this.account = { address: "0x...", name: "Connected Account" };
    this.notifyListeners();
  }

  async disconnect(): Promise<void> {
    this.account = undefined;
    this.chain = undefined;
    this.balance = undefined;
    this.notifyListeners();
  }

  async switchChain(chain: Chain): Promise<void> {
    this.chain = chain;
    this.balance = undefined; // Reset balance for new chain
    this.notifyListeners();
  }
}

Usage Patterns

React Hook Integration

import { useState, useEffect } from 'react';
import { UniversalWeb3ProviderInterface } from '@ant-design/web3-common';

function useWeb3Provider(provider: UniversalWeb3ProviderInterface) {
  const [account, setAccount] = useState(provider.account);
  const [chain, setChain] = useState(provider.chain);
  const [balance, setBalance] = useState(provider.balance);

  useEffect(() => {
    // If provider supports state subscriptions
    if ('subscribe' in provider && typeof provider.subscribe === 'function') {
      const unsubscribe = provider.subscribe((state) => {
        setAccount(state.account);
        setChain(state.chain);
        setBalance(state.balance);
      });

      return unsubscribe;
    }
  }, [provider]);

  return {
    account,
    chain,
    balance,
    connect: provider.connect,
    disconnect: provider.disconnect,
    switchChain: provider.switchChain
  };
}

The Universal Web3 Provider Interface serves as the foundation for wallet abstraction in the Ant Design Web3 ecosystem, enabling consistent interaction patterns regardless of the underlying wallet implementation.