Skip to content

Conversation

@Gaubee
Copy link
Contributor

@Gaubee Gaubee commented Dec 25, 2025

Summary

This PR completes the transaction UI optimization with three major features:

1. PatternLock Component (钱包锁)

  • Replace password input with 9-grid pattern lock for wallet security
  • Rename passwordLockEnabledwalletLockEnabled
  • Update all i18n: 钱包密码 → 钱包锁, 输入密码 → 绘制图案

2. Chain Icon System

  • ChainIcon component with ChainIconProvider for auto chainId→iconUrl resolution
  • Icons stored at /icons/{chainId}/chain.svg
  • Fallback to letter avatar when icon not found

3. Token Icon System

  • TokenIcon component with CDN fallback capability
  • Icons stored at /icons/{chainId}/tokens/{symbol}.svg
  • TokenBadge for compact display with chain indicator

Breaking Changes

  • passwordLockEnabledwalletLockEnabled
  • PasswordConfirmJobWalletLockConfirmJob
  • PayPasswordConfirmJobTwoStepSecretConfirmJob
  • All password-related testids updated to pattern-lock

Files Changed

  • 25+ white-book documentation files
  • 13 e2e test files
  • 4 locale files (zh-CN, en, zh-TW, ar)
  • Multiple component and activity files

Testing

  • All 121 test files pass (1421 tests)
  • Typecheck passes

Task 1: Pattern Lock Component
- Replace password input with 9-grid pattern lock for wallet security
- Add PatternLock and PatternLockSetup components with touch/mouse support
- Implement error state fade-out animation (800ms) for invalid patterns
- Auto-reset on insufficient points (< minPoints)

Task 2: Chain Selector for Wallet Management
- Add ChainSelector component with hierarchical structure (tech type -> networks)
- Default select BioForest chains on wallet creation/import
- Add wallet network management page (/settings/wallet-chains)
- Auto-switch chain if current chain removed from wallet
- Move chain config to Preferences section in settings

Refactoring:
- Rename PasswordConfirmJob -> WalletLockConfirmJob
- Rename PayPasswordConfirmJob -> TwoStepSecretConfirmJob
- Rename SetPayPasswordJob -> SetTwoStepSecretJob
- Rename TransferPasswordJob -> TransferWalletLockJob (uses PatternLock)
- Update all related imports and callbacks

Additional Changes:
- Add wallet lock verification UI mode guidelines to white-book
- Update E2E tests and screenshots
- Clean up deprecated password-related components
- Add encryptedWalletLock field to WalletInfo for storing encrypted wallet lock
- Add deriveEncryptionKeyFromMnemonic() to derive encryption key from mnemonic using BIP44 path
- Add encryptWithRawKey() and decryptWithRawKey() for AES-GCM encryption with raw key
- Update createWallet() to generate both encrypted fields (bidirectional encryption)
- Rename updateMnemonicEncryption to updateWalletLockEncryption
- Add resetWalletLockByMnemonic() method to reset wallet lock using mnemonic verification
- Update wallet store with new updateWalletLock and resetWalletLockByMnemonic actions
- Add E2E test file for wallet lock encryption features
- Fix wallet-storage.test.ts to use valid BIP39 mnemonic
- Add verifyMnemonic() method to wallet storage service (read-only validation)
- Add verifyMnemonic action to wallet store
- Update change-wallet-lock.tsx with two verification methods:
  1. Pattern verification (default)
  2. Mnemonic verification (for forgotten pattern)
- Add toggle between verification methods with clear UI
- Add i18n translations for all new strings (zh-CN, en, zh-TW, ar)
- PatternLock: Cancel error animation when user starts new input
- Add animationCancelledRef to properly stop running animation
- change-wallet-lock.tsx: Clear error state on pattern change
- WalletLockConfirmJob: Clear error state on pattern change
- Use refs to track timers and clear them when starting new input

This allows users to immediately start a new pattern input without
waiting for the error animation to complete.
Use different touch thresholds for start vs move gestures:
- Start: 1/2 grid cell (larger for easier initiation)
- Move: 1/3 grid cell (smaller to prevent accidental triggers)

This prevents accidentally selecting intermediate nodes when
quickly swiping across the pattern grid.
…splay

Chain Icon System:
- Add SVG icons for all chains in public/icons/chains/
- Update default-chains.json with icon field
- Enhance ChainIcon to support iconUrl with fallback to letter

New Components:
- ChainAddressDisplay: Composite component combining ChainIcon + Address
- FeeEditJob: Stackflow Modal for editing transaction fees
- FeeDisplay: Add editable prop with edit button

Updates:
- SetTwoStepSecretJob: Use ChainAddressDisplay, editable fee
- TransferConfirmJob: Support editable fee with onFeeChange callback

i18n:
- Add feeEdit translations for all locales
- Add a11y.editFee translations
ChainIcon now supports automatic iconUrl resolution via context:
- ChainIconProvider: Inject getIconUrl function at app root
- ChainIcon: Auto-resolve iconUrl from context when chainId is provided
- Props iconUrl still takes precedence over context

Usage:
```tsx
// In app root
<ChainIconProvider getIconUrl={(id) => chainConfigs[id]?.icon}>
  <App />
</ChainIconProvider>

// In components - just use chainId, icon resolved automatically
<ChainIcon chainId="ethereum" />
```
- Add ChainIconProviderWrapper using chain-config store
- ChainIcon now auto-resolves iconUrl from context based on chainId
- No need to manually pass iconUrl to ChainIcon components
- Replace self-made chain icons with official token SVGs
- Bio ecosystem chains use mainToken icon (symbol field)
- Remove icon field for biwmeta and malibu (no official icons)
- Icons sourced from btg-meta/components/icon/assets/images
Icon organization:
- /icons/chains/ - chain icons (by chainId)
- /icons/tokens/ - token icons (by symbol lowercase)

TokenIcon system:
- TokenIconProvider: Inject at app root with basePath
- TokenIcon: Auto-resolve iconUrl from `{basePath}/{symbol.toLowerCase()}.svg`
- TokenBadge: Icon + label badge component
- Sizes: xs, sm, md, lg

Token icons added:
- Bio ecosystem: bfm, ccc, pmc, bft, btgm, ethm, usdm, ftc, gfs, snp
- Public chains: eth, bnb, trx, btc
- Stablecoins: usdt, usdc, dai
Directory structure:
  /icons/{chainId}/
    chain.svg         # Chain icon (= mainToken icon)
    tokens/
      {symbol}.svg    # Token icons

TokenIcon fallback priority:
1. iconUrl prop (manual override)
2. Local: /icons/{chainId}/tokens/{symbol}.svg
3. CDN: https://bfm-fonts-cdn.oss-cn-hongkong.aliyuncs.com/meta-icon/{chainId}/icon-{symbol}.png
4. Letter fallback (first character)

Notes:
- Avoid *-n.svg (no-color) icons, use {Chain}-{symbol}.svg format
- chainId is now required for TokenIcon to resolve local/CDN paths
- Chain icons sourced from official token icons (mainToken = symbol)
- ChainIcon: simple string icon URL (stable chains)
- TokenIcon: tokenIconBase[] with multi-fallback [local, CDN, GitHub]
- URL building: local='{base}/{symbol}.svg', remote='{base}/icon-{symbol}.png'
- Updated schema, providers, and frontend-main integration
BREAKING: Removed components/token/token-icon.tsx

- Unified TokenIcon: supports both imageUrl prop and Provider+chainId
- Priority: imageUrl > TokenIconProvider(chainId) > letter fallback
- Updated all imports to use @/components/wallet/token-icon
- Size variants: xs(4), sm(6), md(8), lg(10)
- Replace manual img/fallback with TokenIcon component
- Pass chainId to enable Provider-based icon resolution
- Remove conflicting className size overrides
…ize prop

- All sizes now include aspect-square for proper circular rendering
- lg size includes @xs:w-12 for responsive container query
- Added best practices for circular elements and responsive sizing
- WalletDeleteJob: use PatternLock instead of PasswordInput
- SetTwoStepSecretJob: walletLock step now uses PatternLock
- PasswordInput retained only for TwoStepSecret (chain transaction password)
- wallet.json: deleteWarning uses pattern, passwordError → patternError
- settings.json: viewMnemonic uses pattern verification
- Removed obsolete passwordPlaceholder keys
- Remove legacy wallet password related keys (replaced by PatternLock)
- Keep only actively used keys: patternLock, walletLock, twoStepSecret, mnemonicConfirm, etc.
- Update all 4 locales: zh-CN, en, zh-TW, ar
Breaking changes:
- WalletAppSettings.passwordLockEnabled → walletLockEnabled
- MpayWalletAppSettings.passwordLock → walletLock
- Updated all i18n: 钱包密码 → 钱包锁/图案锁
- Updated white-book docs with new terminology
- Updated code comments
- Updated e2e test comments
- Updated scripts comments
- Updated .env.example
- Updated openspec docs
- Updated test names
…tLock

- 00-必读: PasswordConfirmSheetActivity → WalletLockConfirmJob
- 03-架构篇/错误处理: WrongPassword → WrongPattern
- 03-架构篇/导航系统: SettingsPassword → SettingsWalletLock
- 04-服务篇/钱包存储: password参数 → patternKey
- 06-安全篇/DWEB授权: requestPassword → requestWalletLock
…attern lock

Breaking changes in documentation:
- 密码 → 图案/图案锁
- password → pattern/patternKey
- PasswordConfirmSheet → WalletLockConfirmJob
- settingPassword → settingPattern
- auth_password_* → auth_pattern_*

Updated files:
- 01-产品篇/用户故事: 流程图和验收标准
- 02-设计篇/交互设计: 流程图
- 03-架构篇: 错误处理、导航系统
- 04-服务篇: 平台服务、钱包存储
- 06-安全篇: 身份认证、密钥管理、DWEB授权
- 08-测试篇: 安全测试、E2E测试
- 09-部署篇: 监控告警
- 附录: 状态机、边界条件
Changes:
- authorize.json (all 4 locales):
  - confirmDescription: 输入密码 → 绘制图案
  - button.confirm: 输入密码确认 → 绘制图案确认
  - error.passwordIncorrect → patternIncorrect
- wallet.json: securityWarning 验证密码 → 验证钱包锁
- Updated test files to use pattern-lock-input testid
@Gaubee Gaubee merged commit 690203b into main Dec 25, 2025
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants