Skip to content

Wallet 组件

源码: src/components/wallet/

组件列表

组件文件说明
WalletCardwallet-card.tsx3D 钱包卡片
WalletCardCarouselwallet-card-carousel.tsx卡片轮播
AddressDisplayaddress-display.tsx地址显示
ChainIconchain-icon.tsx链图标
ChainBadgechain-icon.tsx链标签
ChainAddressSelectorchain-address-selector.tsx链地址选择器
ChainAddressDisplaychain-address-display.tsx链地址显示
TokenIcontoken-icon.tsx代币图标
WalletAddressPortfoliowallet-address-portfolio.tsx钱包资产组合

WalletCard

3D 全息钱包卡片,支持陀螺仪/触摸交互。

行为约束

约束级别要求
MUST显示钱包名称
MUST显示缩略地址(使用 AddressDisplay)
MUST地址可复制
MUST应用 themeHue 主题色
SHOULD支持触控倾斜交互
SHOULD显示动态光泽效果
SHOULD显示链图标水印
SHOULD提供链切换入口
MAY自定义水印尺寸
MAY禁用 3D 效果(性能优化)

Props

typescript
interface WalletCardProps {
  wallet: Wallet
  chain: ChainType
  chainName: string
  priority?: 'high' | 'low'     // 渲染优先级
  address?: string
  chainIconUrl?: string         // 水印图标
  watermarkLogoSize?: number    // 水印尺寸 (默认 60)
  themeHue?: number             // 主题色相 (默认 323)
  onCopyAddress?: () => void
  onOpenChainSelector?: () => void
  onOpenSettings?: () => void
  disableWatermarkRefraction?: boolean
  disablePatternRefraction?: boolean
  enableGyro?: boolean
  className?: string
}

特性

  • 3D 倾斜: 基于触摸/陀螺仪的 3D 旋转
  • 全息效果: Canvas 渲染的彩虹光影
  • 水印层: 链图标单色遮罩平铺
  • GPU 加速: CSS 变量驱动动画

交互系统

typescript
// CSS 变量驱动所有动画
const cssVars = {
  '--tilt-x': tiltX,           // 倾斜角度 X
  '--tilt-y': tiltY,           // 倾斜角度 Y
  '--tilt-nx': normalizedTiltX, // 归一化 X (-1~1)
  '--tilt-ny': normalizedTiltY, // 归一化 Y (-1~1)
  '--tilt-intensity': tiltIntensity,  // 强度 (0~1)
  '--tilt-direction': tiltDirection,  // 方向角
}

渲染结构

┌─────────────────────────────────────────────┐
│ [🔷 Ethereum ▾]                    [⚙️]    │  ← 顶部工具栏
│                                             │
│              My Wallet                      │  ← 居中标题
│                                             │
│ 0x742d...6634                      [📋]    │  ← 底部地址栏
│                                             │
│ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │  ← 链图标水印层
└─────────────────────────────────────────────┘
     ↑ 3D 倾斜 + 全息光影 + 渐变背景(themeHue)

设计规格

部分规格
卡片比例1.6:1 (宽:高)
卡片圆角16px (rounded-2xl)
卡片内边距20px
钱包名字号24px / font-bold
地址字号14px / font-mono
水印尺寸24px (实际) / 40px (含间距)

3D 效果参数

参数
最大倾斜角度±15°
透视距离1000px
过渡曲线cubic-bezier(0.34, 1.56, 0.64, 1)
过渡时长400ms

主题色渐变

使用 OKLCH 色彩空间生成和谐渐变:

typescript
const gradient = `linear-gradient(
  135deg,
  oklch(0.5 0.2 ${themeHue}) 0%,
  oklch(0.4 0.22 ${themeHue + 20}) 50%,
  oklch(0.3 0.18 ${themeHue + 40}) 100%
)`;

AddressDisplay

智能截断的地址显示,支持复制。

行为约束

约束级别要求
MUST显示完整地址的前后部分
MUST支持复制到剪贴板
MUST复制后显示反馈 (Toast/振动)
SHOULD根据容器宽度自动调整截断
SHOULD使用等宽字体
MAY自定义前后字符数

Props

typescript
interface AddressDisplayProps {
  address: string
  startChars?: number          // 开头字符数
  endChars?: number            // 结尾字符数
  placeholder?: string
  copyable?: boolean           // 可复制 (默认 true)
  onCopy?: () => void
  className?: string
}

智能截断算法

typescript
// 1. 使用 Canvas 测量文字宽度
// 2. 根据容器宽度计算可显示字符数
// 3. 按 55:45 比例分配前后字符
// 4. 响应容器尺寸变化自动调整

使用示例

tsx
// 自动截断
<AddressDisplay address="0x742d35Cc6634C0532925a3b844Bc9e7595f..." />
// 显示: 0x742d35Cc...7595f

// 固定截断
<AddressDisplay address={address} startChars={8} endChars={6} />
// 显示: 0x742d35...e7595f

ChainIcon

链图标组件,支持图片和首字母回退。

Props

typescript
interface ChainIconProps {
  chainId?: string
  iconUrl?: string             // 优先使用
  symbol?: string              // 回退显示
  size?: 'sm' | 'md' | 'lg'
  className?: string
}

优先级

  1. iconUrl prop
  2. ChainIconProvider context
  3. 首字母 + 背景色

使用示例

tsx
// 从 context 自动获取图标
<ChainIconProvider getIconUrl={(id) => configs[id]?.icon}>
  <ChainIcon chainId="ethereum" />
</ChainIconProvider>

// 手动指定
<ChainIcon chainId="ethereum" iconUrl="/icons/eth.svg" />

预设背景色

Chain颜色
ethereum蓝紫
bitcoin橙色
tron红色
binance黄色
bfmeta自定义

ChainBadge

链标签,图标 + 文字。

tsx
<ChainBadge chainId="ethereum" />
// 渲染: [🔷 ETH]

TokenIcon

代币图标,支持 URL 和符号回退。

tsx
<TokenIcon symbol="ETH" imageUrl="/icons/eth.png" size="lg" />
<TokenIcon symbol="UNKNOWN" />  // 显示首字母 U

ChainAddressSelector

链地址选择下拉框。

tsx
<ChainAddressSelector
  addresses={wallet.chainAddresses}
  value={selectedChain}
  onChange={setSelectedChain}
/>

WalletCardCarousel

钱包卡片轮播,支持左右滑动切换。

tsx
<WalletCardCarousel
  wallets={wallets}
  activeIndex={currentIndex}
  onIndexChange={setCurrentIndex}
/>

Released under the MIT License.