创建React项目

如何轻松对接以太坊钱包(MetaMask/Trust Wallet等)

在区块链应用(如DeFi、NFT、DApp)开发中,对接以太坊钱包是连接用户与去中心化世界的核心环节,无论是让用户管理数字资产、签名交易,还是与智能合约交互,都需要通过钱包完成,本文将以MetaMask(最主流的浏览器钱包)Trust Wallet(移动端钱包)为例,详细讲解如何从零开始对接以太坊钱包,涵盖环境准备、核心步骤、代码实现及常见问题解决。

前置准备:理解以太坊钱包与核心概念

在对接前,需先明确几个关键概念:

以太坊钱包的本质

以太坊钱包(如MetaMask)并非存储“币”,而是存储私钥的助记词/私钥,通过私钥管理链上地址的资产与签名权限,用户通过钱包与以太坊网络交互时,实际是通过钱包软件构造交易、用私钥签名,再广播到节点。

核心工具/库

  • Web3.jsethers.js:以太坊生态的JavaScript库,用于与区块链节点交互(如查询余额、发送交易、调用合约)。
  • 钱包连接库:如 viem(新一代以太坊交互库,兼容钱包连接)、web3-onboard(多钱包连接解决方案),简化与钱包的连接流程。
  • 测试环境:优先在Sepolia测试网(以太坊测试网)开发,避免消耗真实ETH,可通过 AlchemyInfura 免费获取测试节点。

对接以太坊钱包的完整流程

步骤1:项目初始化与依赖安装

以React/Vue项目为例,先初始化项目并安装必要的库:

cd dapp-wallet-demo  
# 安装ethers.js(或web3.js)  
npm install ethers  

步骤2:检测浏览器是否安装钱包(MetaMask为例)

MetaMask通过window.ethereum向浏览器注入全局对象,可通过以下方式检测:

// 在React组件中  
const checkWalletInstalled = () => {  
  if (typeof window.ethereum !== 'undefined') {  
    console.log('MetaMask已安装!');  
    return true;  
  } else {  
    console.log('请先安装MetaMask:https://metamask.io/');  
    return false;  
  }  
};  

步骤3:连接钱包(核心代码)

连接钱包的核心是调用window.ethereum.request({ method: 'eth_requestAccounts' }),该方法会触发MetaMask的账户选择弹窗,用户授权后返回地址列表。

示例(使用ethers.js):

import { ethers } from 'ethers';  
const connectWallet = async () => {  
  if (!window.ethereum) {  
    alert('请安装MetaMask!');  
    return;  
  }  
  try {  
    // 请求用户授权连接账户  
    const accounts = await window.ethereum.request({  
      method: 'eth_requestAccounts',  
    });  
    const address = accounts[0];  
    console.log('已连接钱包地址:', address);  
    // 创建provider(连接以太坊节点)  
    const provider = new ethers.BrowserProvider(window.ethereum);  
    const signer = await provider.getSigner(); // 获取签名者(用于发送交易)  
    // 获取用户余额(示例)  
    const balance = await provider.getBalance(address);  
    console.log('余额:', ethers.formatEther(balance), 'ETH');  
    return { address, signer, provider };  
  } catch (error) {  
    console.error('连接失败:', error);  
    alert('连接钱包失败,请重试');  
  }  
};  

步骤4:监听账户/网络变化

用户可能切换账户或网络(如从主网切到测试网),需监听事件并更新UI:

// 监听账户变化  
window.ethereum.on('accountsChanged', (accounts) => {  
  if (accounts.length === 0) {  
    console.log('用户已断开钱包连接');  
  } else {  
    console.log('切换账户:', accounts[0]);  
    // 更新UI中的地址信息  
  }  
});  
// 监听网络变化  
window.ethereum.on('chainChanged', (chainId) => {  
  console.log('切换网络:', chainId);  
  // 提示用户刷新页面或重新连接  
  alert('网络已切换,请刷新页面');  
});  

步骤5:发送交易与调用合约(进阶)

连接钱包后,用户可能需要发送ETH或与智能合约交互:

发送ETH示例:

const sendETH = async (toAddress, amount) => {  
  if (!signer) {  
    alert('请先连接钱包!');  
    return;  
  }  
  try {  
    const tx = await signer.sendTransaction({  
      to: toAddress,  
      value: ethers.parseEther(amount), // 转换为wei(1 ETH = 1e18 wei)  
    });  
    console.log('交易哈希:', tx.hash);  
    await tx.wait(); // 等待交易上链  
    alert('交易成功!');  
  } catch (error) {  
    console.error('交易失败:', error);  
    alert('交易失败,请检查余额和网络');  
  }  
};  

调用合约示例(假设已部署ERC20合约):

const contractAddress = '0x...'; // 合约地址  
const contractABI = [...]; // 合约ABI  
const getContractBalance = async (userAddress) => {  
  const contract = new ethers.Contract(contractAddress, contractABI, provider);  
  const balance = await contract.balanceOf(userAddress);  
  console.log('代币余额:', ethers.formatUnits(balance, 18));  
};  

支持多钱包(MetaMask + Trust Wallet)

若需同时支持MetaMask(浏览器)和Trust Wallet(移动端),可通过web3-onboard库简化实现:

安装与配置:

npm install @web3-onboard/core @web3-onboard/injected-wallets  
import initOnboard from '@web3-onboard/core';  
import injectedModule from '@web3-onboard/injected-wallets';  
const injected = injectedModule();  
const onboard = initOnboard({  
  wallets: [injected],  
  chains: [  
    {  
      id: '0xaa36a7', // Sepolia测试网ChainID  
      token: 'sepETH',  
      label: 'Sepolia Testnet',  
      rpcUrl: 'https://sepolia.infura.io/v3/YOUR_INFURA_ID',  
    },  
  ],  
});  
// 连接钱包  
const connectWallet = async () => {  
  const wallets = await onboard.connectWallet();  
  const state = onboard.getState();  
  const address = state.wallets[0].accounts[0].address;  
  console.log('连接地址:', address);  
};  

常见问题与解决方案

用户拒绝连接或未安装钱包

  • 提示安装:检测到window.ethereum不存在时,引导用户到官网下载钱包(如MetaMask、Trust Wallet)。
  • 友好UI:添加“连接钱包”按钮,点击后先检测钱包,再触发连接请求。

交易失败(余额不足、gas费不足、网络错误)

  • 检查余额:通过provider.getBalance()确认ETH余额是否足够支付gas费。
  • 动态gas费:使用provider.getFeeData()获取当前建议的gas价格(如maxPriorityFeePerGas)。
  • 网络匹配:确保钱包网络与DApp网络一致(如DApp接的是Sepolia测试网,钱包也需切到测试网)。

移动端Trust Wallet连接失败

  • 使用Trust
    随机配图
    Wallet的DApp浏览器
    :Trust Wallet内置DApp浏览器,可通过window.ethereum连接,与MetaMask逻辑一致。
  • Deep Link:若在普通浏览器中,可通过trust://协议唤起Trust Wallet(需用户已安装)。

跨链钱包支持(如币安智能链BSC)

  • 配置多链:在web3-onboardethers.js中配置不同链的RPC地址(如BSC的https://bsc-dataseed.binance.org)。
  • 切换网络:调用`window.ethereum.request({ method: 'wallet_switchEthereumChain', params: [{ chainId: '

本文由用户投稿上传,若侵权请提供版权资料并联系删除!