Back to experience

Conflux · BIM Wallet · React Native

BIM Wallet

My first wallet: built from zero and shipped as a dual-Space mobile product.

BIM Wallet 1.0 shipped. This local-first, self-custodial wallet manages account and asset data locally, supporting both software accounts and China Telecom BSIM hardware signing.

513
personal commits in the Venus repository
2 Spaces
Conflux Core Space and EVM / eSpace
11 commits
building the reusable Gas Station
7 states
the local transaction lifecycle led by Wang

11 chapters · 3 min 18 sec

01

Two chain Spaces should not become two wallets

BIM Wallet supports Conflux Core Space and EVM / eSpace. Instead of scattering conditionals across screens, Network stores networkType, chainId, RPC, and HD Path; each Account owns an Address for every Network; Address returns Base32 or Hex by network; and the Transaction plugin selects EVM or Conflux estimation, signing, and broadcasting. Product flows stay shared while RPC, address, and finality semantics remain chain-specific.

  • Core Space: cfx_*, Base32, epochHeight, and storageLimit
  • eSpace: eth_*, Hex, legacy, and EIP-1559
  • Shared account selection, Send, Confirm, and Activity flows

02

The mnemonic system became an operable account tree

Vault stores an encrypted mnemonic, private key, BSIM, hardware, or watch-only source. AccountGroup represents the accounts from one source. Account stores index, nickname, visibility, and selection. Each Account then creates an Address for every Network. Vault and account creation batch these related records so UI, in-memory objects, and persistence do not maintain competing relationship models.

03

HD Manage derives five addresses per page

Optimization started below the UI. The October 10, 2023 initial commit added react-native-quick-crypto and routed ethers PBKDF2 through its C/C++ JSI implementation, shortening the CPU-heavy mnemonic-to-seed path; the HD root and derivePath were cached on October 19. HD supports up to 255 indexes but derives five addresses per page, with a 360ms debounce and fixed placeholders. BSIM instead creates accounts up to the requested index and reads the card list within its own limits. Both share pagination, batch visibility changes, and create local records only for new indexes.

  • Native acceleration: QuickCrypto owns PBKDF2; Jie later completed randomBytes, HMAC, and SHA registration
  • Compute less: HD derives five addresses per page and reuses the memoized HD root and derivePath
  • Write less: commit visibility changes in one batch and create only missing indexes
  • Industry comparison: MetaMask’s similar 2022 PR was not merged; the library entered main on Jan 25, 2024, and its May 2025 Encryptor migration reduced Android keyFromPassword from about 5.15s to 1.41s

04

Asset management is not a static token list

The asset screen does not simply render a token list. AssetTracker first asks the server and chain what this address actually holds, then applies local AssetRule choices for pinned or hidden assets. It uses Multicall or JSON-RPC batch when possible and falls back to individual reads when necessary. Every result belongs to one space, chainId, and address. If a five-second poll returns the same result, the old object stays in place; the UI updates only when balances, assets, or ordering actually change.

  • No mixed data: switching network or account selects only its matching asset result
  • No dead end: server, Multicall, and Batch RPC failures fall back to the next method
  • No wasted redraw: identical polling results keep the existing object and UI
  • Real changes update: balances, the asset set, or ordering trigger the next render

05

Every external request enters through one path

Raw addresses, camera and photo QR codes, system deep links, ethereum:/conflux: payment URIs, and wc: URIs all enter through ExternalInputHandler. It checks Space, chainId, address, asset, and amount before opening the matching Send step or WalletConnect. Jie built the initial pairing, proposal, and approval flows; I later took over this area, adding the RxJS concatMap queue, the shared external entry, and CIP-155 / EIP-155 dual-Space translation.

06

Gas Station is more than a modal on the Send screen

One sending flow must handle two fee models and DApp fee parameters. Eleven key commits extended Gas Station after 1.0 shipped. EVM and Core inspect baseFeePerGas on the latest block or epoch: present yields estimateOf1559; absent yields a legacy estimate. Gas and nonce resolve through Promise.all every 15 seconds; unchanged results retain state. Send Step 4 and WalletConnect Transaction share GasSetting, AdvanceSetting, and EstimateFee.

  • Two fee models: legacy uses suggestedGasPrice; 1559 uses maxFeePerGas plus priorityFee
  • Product policy: Slow / Average / Fast use 0.9 / 1.0 / 1.2 of the baseline; Customize edits fee, gasLimit, storageLimit, and nonce
  • Safety bounds: Core minimum 1 Gwei, eSpace minimum 20 Gwei, gasLimit at least 21000, and priorityFee no greater than maxFee
  • DApp parameters enter Customize visibly; type 0 / 1 forces legacy; low values offer wallet recommendations or retention; Reset restores Average and the latest estimate

07

Wang’s transaction work went far beyond TxTracker

Wang began building Tx, TxPayload, and TxExtra persistence in December 2023, then added transaction status and Activity before expanding into BaseTxTrack, Core / EVM tracking, send-failure data, signature records, transaction detail, same-nonce deduplication, speed-up/cancel, and pending counts. The original diagram shown in the film captures the hardest loop: three-second executed checks, five-second confirmed checks, thirty-second finalized checks, and nonce-aware resend or replacement decisions when a hash temporarily disappears.

Zero to 1.0

Oct 2023

Built accounts and local data first

Initialized the project, WatermelonDB, HD Vaults, account groups, and one Address per network. The initial commit routed ethers PBKDF2 through C/C++ JSI QuickCrypto; the HD root and derivePath were cached on October 19.

Nov–Dec 2023

Asset tracking became a working system

Rebuilt the relationships among Asset, AssetRule, Address, and Network, then added server discovery, chain reads, Batch / Multicall, and address-scoped UI state.

Feb 2024

Manage stayed responsive as accounts grew

Rebuilt account management around five-address pages, cached HD derivation, 360ms debounce, and batched database writes.

Mar 2024

Completed Core Space send and signing

The Transaction plugin selected EVM or Conflux behavior by NetworkType, including Base32, epoch, storageLimit, estimation, signing, and broadcasting.

Apr 24, 2024

BIM Wallet 1.0 shipped

Accounts, assets, transfers, Core / eSpace, and the main product UI were ready to ship. Gas Station, WalletConnect, and transaction tracking kept improving afterward, but zero-to-one was complete here.

Selected source

This case study is based on Venus source and commit history. Jie led BSIM native and hardware work, while Wang led transaction persistence, status tracking, TxTracker, and the surrounding transaction experience. The links below point to source that directly supports the sections above.