Skip to content

EVM Wallet Adapter

EVM Wallet Adapter helps dApps interact with EVM wallets easily.

Introduction

The EVM Wallet Adapter provides a unified, abstract interface for interacting with various EVM-compatible wallets. It simplifies the integration process by encapsulating connection logic, event handling, signing methods, and chain management into a single, consistent API.

Instead of managing unique provider injections (e.g., window.ethereum vs window.binance), developers can use this standardized Adapter class to support multiple wallets seamlessly.

Key Features

  • Unified Interface: One API for connecting, signing, and sending transactions across different wallets.

  • State Management: Built-in tracking of wallet readiness (Loading, Found, NotFound) and connection status.

  • Event Driven: Extends EventEmitter to listen for account changes, network switches, and connection states.

  • EIP Support: Built-in support for EIP-712 (Typed Data) and EIP-1193 providers.

Supported Wallets

Currently, the EVM Wallet Adapter includes implementations for the following wallets:

Quick Start

Installation

bash
npm install @tronweb3/abstract-adapter-evm \
@tronweb3/tronwallet-adapter-metamask-evm \
@tronweb3/tronwallet-adapter-tronlink-evm \
@tronweb3/tronwallet-adapter-binance-evm \
@tronweb3/tronwallet-adapter-trust-evm \
@tronweb3/tronwallet-adapter-okxwallet-evm

Basic Usage Here is an example of how to initialize an adapter, listen for state changes, and connect to a wallet.

ts
import { MetaMaskEvmAdapter } from '@tronweb3/tronwallet-adapter-metamask-evm';
import { WalletReadyState } from '@tronweb3/abstract-adapter-evm';

// 1. Initialize the adapter
const adapter = new MetaMaskEvmAdapter();

// 2. Listen for readiness (e.g., is the extension installed?)
adapter.on('readyStateChanged', (state) => {
  if (state === WalletReadyState.NotFound) {
    console.log('Please install MetaMask');
  } else if (state === WalletReadyState.Found) {
    console.log('MetaMask detected');
  }
});

// 3. Connect to wallet
async function connectWallet() {
  try {
    const address = await adapter.connect();
    console.log('Connected:', address);
  } catch (error) {
    console.error('Connection failed', error);
  }
}

// 4. Listen for account changes
adapter.on('accountsChanged', (accounts) => {
  console.log('New account:', accounts[0]);
});

API Reference

Properties

PropertyTypeDescription
namestringDisplay name (e.g., "MetaMask").
iconstringURL to the wallet's icon.
readyStateWalletReadyStateCurrent availability status (Loading, Found, NotFound).
addressstring | nullThe connected wallet address.
connectedbooleantrue if an address is connected.
connectingbooleantrue if a connection request is pending.

Connection Methods

  • connect() Initiates the connection flow.

    Returns: Promise<string> (The wallet address)

    Throws: WalletError if rejected.

  • getProvider() Returns the raw EIP-1193 provider object.

    Returns: Promise<EIP1193Provider | null>

Signing Methods

  • signMessage(params) Signs a plain text message (personal_sign).

    Params: { message: string, address?: string }

    Returns: Promise<string> (Hex signature)

  • signTypedData(params) Signs EIP-712 Typed Data (eth_signTypedData_v4).

    Params: { typedData: TypedData, address?: string } (See Types)

    Returns: Promise<string> (Hex signature)

  • sendTransaction(transaction) Sends a transaction object.

    Params: transaction: Transaction (See Types)

    Returns: Promise<string> (Transaction Hash)

Network & Assets

  • switchChain(chainId) Requests the wallet to switch networks.

    Params: chainId: HexString (e.g., 0x38 for BSC)

  • addChain(chainInfo) Requests the wallet to add a new network.

    Params: chainInfo: Chain (See Types)

  • watchAsset(asset) Requests the wallet to track a token.

    Params: asset: Asset (See Types)

Events

The Adapter class extends EventEmitter.

  • readyStateChanged: WalletAdapter will check if the wallet is ready to use. If the wallet is detected, state will be Found otherwise it will be NotFound.

  • accountsChanged / chainChanged / disconnect: Same as EIP-1193 events.

Example:

ts
adapter.on('readyStateChanged', (state: WalletReadyState) => void);
adapter.on('accountsChanged', (accounts: string[]) => void);
adapter.on('chainChanged', (chainId: string) => void);
adapter.on('disconnect', (error: Error) => void);

Type Definitions

  • WalletReadyState
ts
enum WalletReadyState {
  Loading = 'Loading', // Checking for injection
  NotFound = 'NotFound', // Extension not installed
  Found = 'Found', // Ready to connect
}
  • TypedData
ts
interface EIP712Domain {
  name?: string;
  version?: string;
  chainId?: number;
  verifyingContract?: string;
  salt?: string;
}
interface TypedData {
  domain: EIP712Domain;
  primaryType: string;
  types: {
    [k: string]: { name: string; type: string }[];
  };
  message: Record<string, unknown>;
}
  • Chain
ts
interface Chain {
  chainId: `0x${string}`;
  chainName: string;
  nativeCurrency: {
    name: string;
    symbol: string;
    decimals: 18;
  };
  rpcUrls: string[];
  blockExplorerUrls?: string[];
}
  • Asset
ts
interface Asset {
  type: 'ERC20' | 'ERC721' | 'ERC1155';
  options: {
    address: `0x${string}`;
    symbol?: string;
    decimals?: number;
    image?: string;
    tokenId?: string;
  };
}
  • Transaction

    A union of the three transaction types. The primitives below are all 0x-prefixed hex strings:

ts
type Address = `0x${string}`;
type Hex = `0x${string}`;
// Hex-encoded unsigned integer (e.g. `0x1a4`)
type Quantity = `0x${string}`;

// Standard EIP-2930 access list
type AccessList = Array<{
  address: Address;
  storageKeys: Hex[];
}>;

interface BaseTransaction {
  from: Address; // Sender address; tells the wallet which account signs
  to?: Address; // Recipient; omit for contract deployment
  gas?: Quantity; // Gas limit
  value?: Quantity; // Wei value transferred
  data?: Hex; // Encoded call data
  nonce?: Quantity;
  chainId?: Quantity;
}

// Pre-EIP-2718 legacy transaction (type 0x0)
interface LegacyTransaction extends BaseTransaction {
  type?: '0x0';
  gasPrice?: Quantity;
}

// EIP-2930 transaction (type 0x1) — adds access lists
interface EIP2930Transaction extends BaseTransaction {
  type: '0x1';
  gasPrice?: Quantity;
  accessList?: AccessList;
}

// EIP-1559 transaction (type 0x2) — dynamic fee market
interface EIP1559Transaction extends BaseTransaction {
  type?: '0x2';
  maxFeePerGas?: Quantity;
  maxPriorityFeePerGas?: Quantity;
  accessList?: AccessList;
}

type Transaction = LegacyTransaction | EIP2930Transaction | EIP1559Transaction;