@xid/walletkit
v0.0.23
Published
A React component library for wallet functionality
Maintainers
Readme
@xid/walletkit
一个强大的 React 多链钱包连接组件库,支持 EVM、Solana、Tron 和 BTC 等多种区块链网络,提供统一的 API 接口。
特性
- 🔗 多链支持: EVM、Solana、Tron 和 BTC 区块链
- 💼 钱包连接器: 支持 MetaMask、OKX Wallet、Phantom、TronLink、Trust Wallet、Bitget Wallet、TokenPocket 和 TokenUp
- 🎨 主题与国际化: 内置明暗主题切换和多语言支持(8种语言)
- 📱 响应式设计: 移动端优先设计,桌面端优化
- 🔄 自动重连: 页面刷新时自动重连钱包
- 📝 合约交互: 内置合约读写和批量调用支持
- 🌐 RPC 支持: 无需连接钱包的直接 RPC 调用
- 🌍 域名解析: ENS 域名解析和反向查询
- 🎯 TypeScript: 完整的 TypeScript 支持和全面的类型定义
- ⚡ 性能优化: 优化的包大小,支持 tree-shaking
安装
NPM 安装
npm install @xid/walletkit
# 或
yarn add @xid/walletkit
# 或
pnpm add @xid/walletkitCDN 引入(UMD 格式)
<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/@xid/walletkit@latest/dist/style.css">
<!-- 引入 React 和 ReactDOM -->
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
<!-- 引入 WalletKit UMD 版本 -->
<script src="https://unpkg.com/@xid/walletkit@latest/dist/index.umd.js"></script>
<script>
const { WalletKitProvider, ConnectButton, useWalletKit, ChainType } = WalletKit;
// 使用 WalletKit 组件
function App() {
const { walletAddress, connect, disconnect } = useWalletKit();
return React.createElement('div', null, [
React.createElement('h1', null, 'WalletKit 示例'),
React.createElement('p', null, `钱包地址: ${walletAddress || '未连接'}`),
React.createElement(ConnectButton)
]);
}
ReactDOM.render(
React.createElement(WalletKitProvider, {
language: 'zh',
defaultChainType: ChainType.EVM
}, React.createElement(App)),
document.getElementById('root')
);
</script>快速开始
基本用法
import { WalletKitProvider, ConnectButton, useWalletKit } from '@xid/walletkit';
// 导入样式(必需)
import '@xid/walletkit/style.css';
function App() {
return (
<WalletKitProvider
language="zh"
theme="light"
defaultChainType={ChainType.EVM}
defaultChainId={1}
showNetwork={true}
allowSwitchWallet={true}
>
<YourApp />
</WalletKitProvider>
);
}
function YourApp() {
const { connect, walletAddress, currentChainType, disconnect } = useWalletKit();
return (
<div>
<ConnectButton />
{walletAddress ? (
<div>
<p>已连接钱包: {walletAddress}</p>
<button onClick={disconnect}>断开连接</button>
</div>
) : (
<button onClick={connect}>连接钱包</button>
)}
<div>当前链类型: {currentChainType}</div>
</div>
);
}⚠️ 重要: 请务必导入 CSS 文件
@xid/walletkit/style.css以确保正确的样式显示。
样式
组件库包含内置样式,导入 CSS 文件后会自动加载。样式支持明暗主题,并且完全响应式。
CSS 导入方法
// 方法 1: 直接导入(推荐)
import '@xid/walletkit/style.css';
// 方法 2: 从 dist 目录导入
import '@xid/walletkit/dist/style.css';主题变量
组件库使用 CSS 自定义属性进行主题设置。您可以覆盖这些变量来自定义外观:
:root {
--walletkit-primary-color: #1890ff;
--walletkit-text-color: rgba(0, 0, 0, 0.88);
--walletkit-background-color: #ffffff;
/* ... 更多变量 */
}API 文档
组件
WalletKitProvider
提供钱包连接上下文,必须包裹在应用最外层。
<WalletKitProvider
language="zh" // 多语言,支持 zh、en、ja、ko、ms、th、vi、zhTW
theme="light" // 主题,支持 dark、light
defaultChainType={ChainType.EVM}
defaultChainId={1}
reconnect={true}
supportWallets={[]}
customEvmNetworks={[]}
showNetwork={true}
allowSwitchWallet={true}
productName="My App"
>
<YourApp />
</WalletKitProvider>参数
| 参数名 | 类型 | 默认值 | 描述 | |---------------------|---------------------------------------------------|------------------|------------------------------| | language | 'zh'|'en'|'ja'|'ko'|'ms'|'th'|'vi'|'zhTW' | 'zh' | 界面语言 | | theme | 'dark'|'light' | 'light' | 主题 | | defaultChainType | ChainType | ChainType.EVM | 默认链类型 | | defaultChainId | number | 1 | 默认链 ID | | reconnect | boolean | true | 是否自动重连 | | supportWallets | SupportWallet[] | 全部支持 | 支持的钱包类型 | | customEvmNetworks | NetworkInfo[] | [] | 自定义 EVM 网络列表 | | showNetwork | boolean | false | 是否显示网络切换 | | allowSwitchWallet | boolean | false | 是否允许切换钱包 | | productName | string | undefined | 展示由...提供 |
ChainType、SupportWallet、NetworkInfo类型见下文。
ConnectButton
内置钱包连接按钮组件,支持响应式设计。
<ConnectButton />ConnectModal
钱包选择和连接弹窗组件。
<ConnectModal />ThemeToggle
主题切换组件。
<ThemeToggle />Hooks
useWalletKit
提供钱包连接相关的所有状态和方法。
const {
connect, // 连接钱包
disconnect, // 断开钱包
currentChainType, // 当前链类型
setChainType, // 设置链类型
currentConnector, // 当前连接器实例
theme, // 当前主题
toggleTheme, // 切换主题
language, // 当前语言
setLanguage, // 设置语言
walletAddress, // 钱包地址
currentNetwork, // 当前网络信息
setCurrentNetwork, // 设置当前网络
getProvider, // 获取 provider
provider, // provider 实例
showWalletInfo, // 显示钱包信息弹窗
signMessage, // 签名消息
signTransaction, // 签名交易
sendTransaction, // 发送交易
readContract, // 读取合约
writeContract, // 写入合约
multicall, // 批量调用合约
switchNetwork, // 切换网络
waitForTransactionReceipt, // 等待交易收据
getSupportNets // 获取支持的网络列表
} = useWalletKit();主要 API 说明
连接与断开
connect(): 连接钱包,返回 Promise<Connector>disconnect(): 断开钱包连接getProvider(): 获取当前 provider 实例
链和网络管理
currentChainType: 当前链类型 (EVM, SOL, Tron, BTC)setChainType(chainType): 设置链类型currentNetwork: 当前网络信息setCurrentNetwork(networkId): 设置当前网络switchNetwork(chainId): 切换网络getSupportNets(): 获取支持的网络列表
交易与合约
signMessage(message): 签名消息signTransaction(tx): 签名交易sendTransaction(tx): 发送交易readContract(params): 读取合约数据writeContract(params): 写入合约数据multicall(calls, option): 批量调用合约waitForTransactionReceipt(hash, timeout?): 等待交易收据
UI 相关
theme: 当前主题toggleTheme(): 切换主题language: 当前语言setLanguage(lang): 设置语言showWalletInfo(): 显示钱包信息弹窗
其他高级用法
readContractRpc(params): 直接通过 RPC 读取合约(无需连接钱包)multicallRpc(calls, option): 直接通过 RPC 批量读取合约evmSilentConnect(walletType, chainId): EVM 静默连接getWalletKit(): 获取全局 walletKit 实例(适合非 React 场景)
域名解析
resolveDomainToAddress(name, chainId): 将 ENS 域名解析为地址reverseResolveAddressToName(addr, chainId, verifyForward?): 将地址反向解析为 ENS 域名resolveDomainToAddresses(name, chainId, coinTypes?): 批量解析域名到多个链的地址(返回以链名称为键的对象)
类型说明
主题类型
Theme: 'dark' | 'light'
语言类型
Locals: 'zh' | 'en' | 'ja' | 'ko' | 'ms' | 'th' | 'vi' | 'zhTW'
链类型
import { ChainType } from '@xid/walletkit';
// ChainType.EVM // 以太坊虚拟机链
// ChainType.SOL // Solana 链
// ChainType.Tron // Tron 链
// ChainType.BTC // 比特币链钱包类型
import { SupportWallet } from '@xid/walletkit';
// 例如:SupportWallet.METAMASK、SupportWallet.OKX_WALLET 等网络类型
import type { NetworkInfo } from '@xid/walletkit';
// chainId, chainName, rpcUrls, nativeCurrency, blockExplorerUrls 等支持的钱包
EVM 钱包
- MetaMask
- OKX Wallet
- Trust Wallet
- Bitget Wallet
- TokenPocket
- TokenUp
Solana 钱包
- Phantom
- OKX Wallet
- Bitget Wallet
- TokenUp
Tron 钱包
- TronLink
- OKX Wallet
- TokenUp
Bitcoin 钱包
- Phantom
示例
切换链类型
import { ChainType, useWalletKit } from '@xid/walletkit';
function ChainSwitcher() {
const { setChainType, currentChainType } = useWalletKit();
return (
<div>
<button onClick={() => setChainType(ChainType.EVM)}>切换到EVM</button>
<button onClick={() => setChainType(ChainType.SOL)}>切换到Solana</button>
<button onClick={() => setChainType(ChainType.Tron)}>切换到Tron</button>
<button onClick={() => setChainType(ChainType.BTC)}>切换到BTC</button>
<div>当前链类型: {currentChainType}</div>
</div>
);
}切换网络
import { useWalletKit } from '@xid/walletkit';
function NetworkSwitcher() {
const { getSupportNets, switchNetwork, setCurrentNetwork, provider, currentNetwork } = useWalletKit();
return (
<div>
<h3>切换网络</h3>
<div>
{getSupportNets().map((net) => (
<button
key={net.chainId}
onClick={async () => {
if (provider) {
await switchNetwork(net.chainId);
} else {
setCurrentNetwork(net.chainId);
}
}}
>
切换到 {net.chainName}
</button>
))}
</div>
<div>当前网络: {currentNetwork?.chainName}</div>
</div>
);
}合约交互
import { useWalletKit } from '@xid/walletkit';
function ContractInteraction() {
const { readContract, writeContract, multicall } = useWalletKit();
const handleReadContract = async () => {
const result = await readContract({
address: '0x...', // 合约地址
abi: [...], // 合约ABI
functionName: 'balanceOf',
args: ['0x...'] // 参数
});
console.log('读取结果:', result);
};
const handleWriteContract = async () => {
const result = await writeContract({
address: '0x...', // 合约地址
abi: [...], // 合约ABI
functionName: 'transfer',
args: ['0x...', 1000000] // 参数
});
console.log('写入结果:', result);
};
const handleMulticall = async () => {
const result = await multicall(
[
{
address: '0x...',
abi: [...],
functionName: 'balanceOf',
args: ['0x...']
},
{
address: '0x...',
abi: [...],
functionName: 'totalSupply'
}
],
{
multicallAddress: '0x...',
multicallAbi: [...]
}
);
console.log('批量调用结果:', result);
};
return (
<div>
<button onClick={handleReadContract}>读取合约</button>
<button onClick={handleWriteContract}>写入合约</button>
<button onClick={handleMulticall}>批量调用</button>
</div>
);
}直接 RPC 合约调用
import { readContractRpc, multicallRpc } from '@xid/walletkit';
// 单个合约读取
const res = await readContractRpc({
abi: [...],
address: '0x...',
functionName: 'balanceOf',
args: ['0x...'],
rpcUrl: 'https://<your-rpc-url>'
});
// 批量合约读取
const res2 = await multicallRpc(
[
{
address: '0x...',
abi: [...],
functionName: 'totalSupply'
},
{
address: '0x...',
abi: [...],
functionName: 'balanceOf',
args: ['0x...']
}
],
{
multicallAddress: '0x...',
multicallAbi: [...],
rpcUrl: 'https://<your-rpc-url>'
}
);域名解析
import { resolveDomainToAddress, reverseResolveAddressToName, resolveDomainToAddresses } from '@xid/walletkit';
import { useState } from 'react';
function DomainResolver() {
const [domain, setDomain] = useState('<your-domain>.xone');
const [address, setAddress] = useState('0x...');
const [result, setResult] = useState('');
const [chainId, setChainId] = useState(33772211);
// 将域名解析为地址
const handleResolveDomain = async () => {
try {
const resolvedAddress = await resolveDomainToAddress(
domain,
chainId
);
setResult(`域名解析地址: ${domain} -> ${resolvedAddress || 'null'}`);
} catch (error) {
setResult(`错误: ${error.message}`);
}
};
// 将地址反向解析为域名
const handleReverseResolve = async () => {
try {
const resolvedDomain = await reverseResolveAddressToName(
address,
chainId,
true // 启用前向验证
);
setResult(`地址解析域名: ${address} -> ${resolvedDomain || 'null'}`);
} catch (error) {
setResult(`错误: ${error.message}`);
}
};
// 批量解析域名到多个链的地址
const handleResolveDomainToAddresses = async () => {
try {
const multiAddresses = await resolveDomainToAddresses(domain, chainId);
if (multiAddresses) {
const formatted = Object.entries(multiAddresses)
.map(([chain, addr]) => `${chain}: ${addr}`)
.join('\n');
setResult(`域名解析到多个地址:\n${formatted}`);
} else {
setResult('未找到地址');
}
} catch (error) {
setResult(`错误: ${error.message}`);
}
};
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 8, maxWidth: 640 }}>
<select
value={chainId}
onChange={(e) => setChainId(Number(e.target.value))}
>
<option value={33772211}>测试网 (33772211)</option>
<option value={3721}>主网 (3721)</option>
</select>
<div style={{ display: 'flex', gap: 8 }}>
<input
style={{ flex: 1 }}
placeholder="域名 例如 <your-domain>.xone"
value={domain}
onChange={(e) => setDomain(e.target.value)}
/>
<button onClick={handleResolveDomain}>域名 → 地址</button>
<button onClick={handleResolveDomainToAddresses}>域名 → 多个地址</button>
</div>
<div style={{ display: 'flex', gap: 8 }}>
<input
style={{ flex: 1 }}
placeholder="地址 0x..."
value={address}
onChange={(e) => setAddress(e.target.value)}
/>
<button onClick={handleReverseResolve}>地址 → 域名</button>
</div>
<pre style={{ padding: 8, borderRadius: 6, backgroundColor: '#f5f5f5' }}>
{result}
</pre>
</div>
);
}
// 基本使用示例
const basicExamples = async () => {
// 将 ENS 域名解析为地址(使用测试网 chainId)
const address = await resolveDomainToAddress('<your-domain>.xone', 33772211);
console.log('解析的地址:', address);
// 将地址反向解析为 ENS 域名(使用测试网 chainId)
const name = await reverseResolveAddressToName('0x...', 33772211);
console.log('解析的域名:', name);
// 使用主网 chainId 解析域名
const mainnetAddress = await resolveDomainToAddress('<your-domain>.xone', 3721);
// 禁用前向验证的反向解析
const nameWithoutVerification = await reverseResolveAddressToName(
'0x...',
33772211,
false // 禁用前向验证
);
// 批量解析域名到多个链的地址
const multiAddresses = await resolveDomainToAddresses('<your-domain>.xone', 33772211);
console.log('多链地址:', multiAddresses);
// 示例输出: { "Ethereum": "0x...", "Solana": "5Q544...", "Tron": "TXYZ..." }
};主题和国际化
import { useWalletKit, supportedLanguages } from '@xid/walletkit';
import type { Locals } from '@xid/walletkit';
function ThemeAndLanguage() {
const { theme, toggleTheme, language, setLanguage } = useWalletKit();
return (
<div>
<div>当前主题: {theme},当前语言: {language}</div>
<div>
<button onClick={() => toggleTheme()}>切换主题</button>
<select
value={language}
onChange={e => setLanguage(e.target.value as Locals)}
>
{supportedLanguages.map(lng => (
<option key={lng} value={lng}>
{lng}
</option>
))}
</select>
</div>
</div>
);
}
supportedLanguages为内置多语言列表,可用于动态渲染语言选择项。
事件监听
import { useEffect } from 'react';
import { useWalletKit } from '@xid/walletkit';
function EventListener() {
const { currentConnector } = useWalletKit();
useEffect(() => {
const handleConnect = (address) => {
console.log('钱包已连接:', address);
};
const handleChainChanged = (chainId) => {
console.log('链已更改:', chainId);
};
const handleAccountChanged = (address) => {
console.log('账户已更改:', address);
};
const handleDisconnect = () => {
console.log('钱包已断开连接');
};
if (currentConnector) {
currentConnector.on('connect', handleConnect);
currentConnector.on('chainChanged', handleChainChanged);
currentConnector.on('accountsChanged', handleAccountChanged);
currentConnector.on('disconnect', handleDisconnect);
}
return () => {
if (currentConnector) {
currentConnector.off('connect', handleConnect);
currentConnector.off('chainChanged', handleChainChanged);
currentConnector.off('accountsChanged', handleAccountChanged);
currentConnector.off('disconnect', handleDisconnect);
}
};
}, [currentConnector]);
return <div>事件监听示例</div>;
}许可证
MIT
