Viem 钱包客户端(Wallet Client)核心解析 Link to heading
核心定位 Link to heading
Viem 的 Wallet Client 是用于与以太坊账户交互的核心工具,专注于区块链状态修改操作(如发送交易、签名消息、调用合约写方法等)。它支持两种账户类型:JSON-RPC 账户(如 MetaMask 等浏览器钱包)和本地账户(如私钥、助记词管理的账户),是处理 “写操作” 的核心组件。
核心功能 Link to heading
- 账户管理
- 支持获取账户地址(
getAddresses
)、请求账户授权(requestAddresses
)。 - 兼容 JSON-RPC 账户(依赖外部钱包签名)和本地账户(直接用私钥签名)。
- 支持获取账户地址(
- 交易与签名
- 发送原生代币转账(
sendTransaction
)。 - 调用合约写方法(
writeContract
),支持 ABI 编码和签名。 - 签名消息(
signMessage
)、签名交易(signTransaction
)等安全操作。
- 发送原生代币转账(
- 与公共客户端集成
可扩展公共客户端(Public Client)的功能(如
publicActions
),同时处理读写操作,避免重复配置。
核心配置与使用 Link to heading
1. 初始化钱包客户端 Link to heading
通过 createWalletClient
创建实例,需指定传输层(Transport),可选配账户(Account) 和区块链网络(Chain)。
(1)对接 JSON-RPC 账户(如 MetaMask) Link to heading
import { createWalletClient, custom } from 'viem'
import { mainnet } from 'viem/chains'
// 连接 MetaMask 等浏览器钱包
const walletClient = createWalletClient({
chain: mainnet, // 目标网络
transport: custom(window.ethereum!), // 使用钱包提供的 provider
})
// 获取钱包地址(需用户授权)
const [address] = await walletClient.requestAddresses()
(2)使用本地账户(如私钥) Link to heading
import { createWalletClient, http } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { mainnet } from 'viem/chains'
// 从私钥创建本地账户
const account = privateKeyToAccount('0x你的私钥...')
// 初始化钱包客户端
const walletClient = createWalletClient({
account, // 挂载本地账户(可选,避免每次操作传账户)
chain: mainnet,
transport: http('https://mainnet.infura.io/v3/你的API密钥'), // 直接连接节点
})
2. 核心 API 示例 Link to heading
(1)发送原生代币转账 Link to heading
import { parseEther } from 'viem'
// 发送 0.001 ETH 到目标地址
const hash = await walletClient.sendTransaction({
account: address, // 发送账户(JSON-RPC 账户需显式传入)
to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', // 接收地址
value: parseEther('0.001'), // 金额(转换为 wei)
})
(2)调用合约写方法 Link to heading
// 调用 ERC20 合约的 transfer 方法
const hash = await walletClient.writeContract({
address: '0x合约地址', // 合约地址
abi: erc20Abi, // 合约 ABI
functionName: 'transfer', // 方法名
args: ['0x接收地址', parseEther('1')], // 方法参数(接收地址和金额)
account: address, // 签名账户
})
(3)扩展公共客户端功能 Link to heading
import { createWalletClient, http, publicActions } from 'viem'
// 扩展公共客户端功能,同时处理读写操作
const walletClient = createWalletClient({
account,
chain: mainnet,
transport: http(),
}).extend(publicActions) // 扩展公共操作
// 先用公共客户端模拟交易(读操作)
const { request } = await walletClient.simulateContract({
address: '0x合约地址',
abi: erc20Abi,
functionName: 'transfer',
args: ['0x接收地址', 100n],
})
// 再用钱包客户端发送交易(写操作)
const hash = await walletClient.writeContract(request)
关键参数说明 Link to heading
参数 | 类型 | 说明 |
---|---|---|
account |
`Account | Address` |
chain |
Chain |
目标区块链网络,用于校验交易网络是否匹配钱包当前网络。 |
transport |
Transport |
传输层,JSON-RPC 账户用 custom(window.ethereum) ,本地账户用 http() 。 |
pollingInterval |
number |
轮询频率(毫秒),用于监听交易状态等实时更新(默认 4000ms)。 |
cacheTime |
number |
缓存时长(毫秒),减少重复请求(默认与 pollingInterval 一致)。 |
核心价值 Link to heading
- 统一接口:无论对接外部钱包还是本地账户,均通过相同 API 处理写操作。
- 安全签名:JSON-RPC 账户的签名在外部钱包完成,本地账户支持私钥安全管理。
- 功能扩展:可集成公共客户端功能,一站式处理读写操作,简化代码。