Lux Wallet
Multi-Platform HD Wallet
Overview
Lux Wallet is a multi-platform HD wallet application built as a Yarn Berry monorepo (@luxwallet/monorepo v1.0.0). It ships Desktop (Electron), Web, Mobile (iOS/Android), and Browser Extension from a single TypeScript codebase. Fork of OneKey v5, extensively customized with @luxfi/* packages for Lux Network integration, supporting 27 blockchain families and hardware wallet signing.
Quick Reference
| Item | Value |
|---|---|
| Repo | github.com/luxfi/wallet |
| Local path | ~/work/lux/wallet/ |
| Root package | @luxwallet/monorepo v1.0.0 |
| Package manager | Yarn 4.1.0 (Berry) -- NOT pnpm |
| Node requirement | >= 20 |
| License | BSD 3-Clause (Lux Industries Inc. 2020-2025) |
| TypeScript | Strict mode, ES6 target, CommonJS module |
| React | 18.x (root), 17.x (ext app) |
| React Native | 0.73.7 |
| Expo | 50.0.5 |
| UI framework | Tamagui 1.79.19 (cross-platform) |
| EVM libs | viem 2.9.x, ethers 5.4.x, ethereumjs-util |
| Local DB | IndexedDB (web/ext), Realm (native) -- OneKeyV5 |
Architecture
@luxwallet/monorepo
|
+-- apps/
| +-- ext/ @luxwallet/x v0.92.79 (Chrome/Firefox/Safari extension)
| +-- desktop/ @onekeyhq/desktop (Electron 27)
| +-- mobile/ @onekeyhq/mobile (React Native + Expo)
| +-- web/ @onekeyhq/web (SPA, webpack, port 3000)
| +-- web-embed/ @onekeyhq/web-embed (Embedded webview, port 3008)
|
+-- packages/
+-- core/ @onekeyhq/core (Chain APIs, crypto, HD derivation)
+-- kit/ @onekeyhq/kit (UI views, Redux state, navigation)
+-- kit-bg/ @onekeyhq/kit-bg (Background services, vaults, DB)
+-- shared/ @onekeyhq/shared (Constants, config, utils, platform)
+-- components/ @onekeyhq/components (Tamagui UI component library)
+-- qr-wallet-sdk/ @onekeyhq/qr-wallet-sdk (Air-gapped QR signing, Keystone)Layer Diagram
+---------------------------------------------------------+
| App Layer (apps/*) |
| ext | desktop | mobile | web | web-embed |
+---------------------------------------------------------+
| UI Layer (packages/kit) |
| Views: Home, Send, Receive, Swap, Staking, DApp, ... |
| State: Redux Toolkit + jotai + redux-persist |
+---------------------------------------------------------+
| Background Layer (packages/kit-bg) |
| Services: 40+ background services |
| Vaults: Per-chain keyring + vault implementations |
| DB: IndexedDB (web) / Realm (native) |
+---------------------------------------------------------+
| Core Layer (packages/core) |
| Chains: 27 chain implementations |
| Secret: BIP-32/39/340, AES-256-CBC, curves |
| Base: CoreChainApiBase, ChainSigner |
+---------------------------------------------------------+
| Shared Layer (packages/shared) |
| Config, constants, preset networks, platform env |
+---------------------------------------------------------+Core Concepts
HD Key Derivation
The wallet implements BIP-32 (SLIP-0010 variant) hierarchical deterministic key derivation with three elliptic curves:
| Curve | Seed Key | Used By |
|---|---|---|
secp256k1 | Bitcoin seed | BTC, EVM, Cosmos, Tron, XRP, Doge, LTC, BCH, Kaspa, CKB |
ed25519 | ed25519 seed | SOL, Aptos, SUI, NEAR, Algo, Cardano, Polkadot, Nostr |
nistp256 | Nist256p1 seed | (Reserved, supported but not primary for any chain) |
Key derivation flow:
Mnemonic (BIP-39, English wordlist)
|
v
mnemonicToSeedSync(mnemonic, passphrase?) -- 512-bit seed
|
v
HMAC-SHA512(curve_seed_key, seed) -- master key + chain code
|
v
CKDPriv(parent, index) -- child key derivation
| hardened: index >= 2^31
| ed25519: hardened only (SLIP-0010)
v
Per-chain address generationMaster key generation follows SLIP-0010 retry logic: if the derived key is invalid ( >= group order or zero), re-derive using HMAC-SHA512(key, I) recursively.
Entropy storage: Mnemonic entropy is stored with a 2-byte prefix (language code + length) padded to 32 bytes with random data, then encrypted. Supports 12/15/18/21/24-word mnemonics (entropy lengths 16/20/24/28/32 bytes).
BIP Path Templates by Chain
| Chain | Default Template | Coin Type | Address Encoding |
|---|---|---|---|
| BTC Nested SegWit | m/49'/0'/\{i\}'/0/0 | 0 | P2SH_P2WPKH |
| BTC Taproot | m/86'/0'/\{i\}'/0/0 | 0 | P2TR |
| BTC Native SegWit | m/84'/0'/\{i\}'/0/0 | 0 | P2WPKH |
| BTC Legacy | m/44'/0'/\{i\}'/0/0 | 0 | P2PKH |
| EVM (standard) | m/44'/60'/0'/0/\{i\} | 60 | keccak256 |
| EVM (Ledger Live) | m/44'/60'/\{i\}'/0/0 | 60 | keccak256 |
| SOL (standard) | m/44'/501'/\{i\}'/0' | 501 | ed25519 pubkey |
| SOL (Ledger Live) | m/44'/501'/\{i\}' | 501 | ed25519 pubkey |
| Cosmos | m/44'/118'/0'/0/\{i\} | 118 | bech32 |
| Cardano | m/1852'/1815'/\{i\}' | 1815 | bech32 |
| Polkadot | m/44'/354'/0'/0/\{i\} | 354 | SS58 |
| Tron | m/44'/195'/0'/0/\{i\} | 195 | base58check |
| XRP | m/44'/144'/0'/0/\{i\} | 144 | base58 |
| Aptos | m/44'/637'/\{i\}' | 637 | hex |
| SUI | m/44'/784'/\{i\}'/0'/0' | 784 | hex |
| NEAR | m/44'/397'/\{i\}' | 397 | implicit/named |
| Filecoin | m/44'/461'/0'/0/\{i\} | 461 | f1/f3 |
| Kaspa | m/44'/111111'/\{i\}' | 111111 | bech32 |
| Lightning | m/44'/81297820149147'/0'/0/\{i\} | 81297820149147 | invoice |
Supported Chains (27 Families)
Production-enabled chain implementations with vault + keyring + core API:
| # | Impl ID | Chain | Account Type | Curve | UTXO | NFT |
|---|---|---|---|---|---|---|
| 1 | evm | Ethereum + all EVM (Lux C-Chain, BSC, Polygon, Arbitrum, Optimism, etc.) | SIMPLE | secp256k1 | No | Yes |
| 2 | btc | Bitcoin | UTXO | secp256k1 | Yes | No |
| 3 | tbtc | Bitcoin Testnet | UTXO | secp256k1 | Yes | No |
| 4 | sol | Solana | SIMPLE | ed25519 | No | Yes |
| 5 | ada | Cardano | UTXO | ed25519 | Yes | No |
| 6 | dot | Polkadot / Substrate | VARIANT | ed25519 | No | No |
| 7 | cosmos | Cosmos Hub, Osmosis, Juno, Akash, Fetch, Celestia, Secret Network, Crypto.org | VARIANT | secp256k1 | No | No |
| 8 | near | NEAR Protocol | VARIANT | ed25519 | No | No |
| 9 | algo | Algorand | SIMPLE | ed25519 | No | No |
| 10 | aptos | Aptos | SIMPLE | ed25519 | No | No |
| 11 | sui | Sui | SIMPLE | ed25519 | No | No |
| 12 | tron | TRON | SIMPLE | secp256k1 | No | No |
| 13 | xrp | XRP Ledger | SIMPLE | secp256k1 | No | No |
| 14 | doge | Dogecoin | UTXO | secp256k1 | Yes | No |
| 15 | ltc | Litecoin | UTXO | secp256k1 | Yes | No |
| 16 | bch | Bitcoin Cash | UTXO | secp256k1 | Yes | No |
| 17 | neurai | Neurai | UTXO | secp256k1 | Yes | No |
| 18 | fil | Filecoin | SIMPLE | secp256k1 | No | No |
| 19 | cfx | Conflux | SIMPLE | secp256k1 | No | No |
| 20 | kaspa | Kaspa | SIMPLE | secp256k1 | No | No |
| 21 | nexa | Nexa | UTXO | secp256k1 | Yes | No |
| 22 | lightning | Lightning Network | SIMPLE | secp256k1 | No | No |
| 23 | tlightning | Lightning Testnet | SIMPLE | secp256k1 | No | No |
| 24 | nostr | Nostr | SIMPLE | secp256k1 | No | No |
| 25 | dynex | Dynex | SIMPLE | ed25519 | No | No |
| 26 | nervos | Nervos CKB | SIMPLE | secp256k1 | No | No |
| 27 | xmr | Monero | SIMPLE | ed25519 | No | No |
EVM networks include: Ethereum, Lux C-Chain, BSC, Polygon, Arbitrum, Optimism, Fantom, Mantle, Manta Pacific, Blast, and many more via the preset networks configuration.
Key Management and Encryption
At-rest encryption: All private keys and seed material are encrypted with AES-256-CBC before storage.
Encryption: AES-256-CBC
KDF: PBKDF2-HMAC-SHA256 (5000 iterations, 32-byte salt)
Key length: 256-bit (32 bytes)
IV: 128-bit (16 bytes, random per encrypt)
Storage: salt(32) || iv(16) || ciphertextPassword encoding: Passwords are never passed as raw strings in non-production builds. A SENSITIVE_ENCODE prefix mechanism encrypts passwords with a per-session random key (UUID-based) so they cannot be read from debugger breakpoints.
Credential types:
|RP|prefix: HD credential (recovery phrase -- encrypted\{entropyWithLangPrefixed, seed\}JSON)|PK|prefix: Imported credential (encrypted\{privateKey\}JSON)|VS|prefix: Verify string (encrypted known plaintext for password verification)
Additional encryptors:
- RSA (1024-bit, PKCS8) for inter-process secure key exchange
- BIP-340 Schnorr (Taproot tagged hashes: TapLeaf, TapBranch, TapSighash, TapTweak)
Keyring Architecture
Each chain vault has 6 keyring types:
| Keyring | Class | Purpose |
|---|---|---|
KeyringHd | KeyringHdBase | HD wallet (mnemonic-derived) |
KeyringImported | KeyringImportedBase | Imported private key |
KeyringHardware | KeyringHardwareBase | Hardware wallet (OneKey, Ledger, Trezor) |
KeyringWatching | KeyringWatchingBase | Watch-only (address or xpub) |
KeyringQr | KeyringQrBase | Air-gapped QR signing (Keystone) |
KeyringExternal | KeyringExternalBase | External wallet (WalletConnect, injected) |
All keyrings implement:
prepareAccounts()-- derive or import accountssignTransaction()-- sign and returnISignedTxProsignMessage()-- sign arbitrary messagesgetPrivateKeys()/exportAccountSecretKeys()(HD/imported only)
Hardware Wallet Integration
Hardware support via @onekeyfe/hd-core v1.0.3 SDK:
| Device | Transport | SDK Package |
|---|---|---|
| OneKey Classic/Touch/Mini/Pro | BLE, USB | @onekeyfe/hd-ble-sdk, @onekeyfe/hd-web-sdk |
| Ledger | WebHID | @ledgerhq/hw-app-eth v6.34.9, @ledgerhq/hw-transport-webhid v6.27.20 |
| Trezor | WebExtension | @trezor/connect-webextension v9.2.2 |
| Keystone | QR (air-gapped) | @keystonehq/keystone-sdk v0.4.1 |
| BitBox | WebUSB | bitbox-api v0.3.2 |
| GridPlus Lattice | HTTP | @luxfi/eth-lattice-keyring v1.1.1 |
Hardware signing flow (EVM example):
KeyringHardware.signTransaction()gets SDK instance and account path- Encodes transaction as
EVMTransactionorEVMTransactionEIP1559 - Calls
sdk.evmSignTransaction(connectId, deviceId, \{path, transaction\}) - Receives
\{v, r, s\}signature from device buildSignedTxFromSignatureEvm()assembles and serializes the signed tx- Returns
\{txid, rawTx, encodedTx\}
Transaction Building
The wallet uses a typed transaction system:
IUnsignedTxPro = {
encodedTx: IEncodedTx; // Chain-specific encoded transaction
feeInfo?: IFeeInfoUnit; // Gas/fee estimation
swapInfo?: ISwapTxInfo; // DEX swap metadata
stakingInfo?: IStakingInfo; // Staking operation metadata
transfersInfo?: ITransferInfo[];
}
ISignedTxPro = {
txid: string;
rawTx: string;
encodedTx: IEncodedTx | null;
signature?: string;
publicKey?: string;
}Each chain's CoreChainSoftware handles:
packUnsignedTxForSign()-- serialize tx to signing digestsigner.sign(digest)-- ECDSA/EdDSA signature with recoverybuildSignedTx()-- attach signature, compute txid
DApp Connection
The wallet supports DApp interaction via:
- Injected provider:
@onekeyfe/cross-inpage-provider-*packages injectwindow.ethereum(EVM),window.solana, etc. - WalletConnect v2:
@walletconnect/universal-providerv2.11.2,@walletconnect/web3walletv1.10.2 - Coinbase Wallet SDK:
@coinbase/wallet-sdkv3.8.x - Gnosis Safe:
@gnosis.pm/safe-core-sdkv1.1.1,@luxfi/eth-gnosis-keyringv0.0.2
The ServiceDApp (946 lines) manages connection lifecycle, permission grants, and method routing.
Database Layer
| Platform | Engine | DB Name |
|---|---|---|
| Web / Extension | IndexedDB | OneKeyV5 |
| iOS / Android | Realm | OneKeyV5 |
Account types stored:
SIMPLE-- single address (EVM, SOL, etc.)UTXO-- multi-address (BTC, DOGE, LTC, BCH)VARIANT-- address varies by network (Cosmos, NEAR)
Store names include: Wallet, Account, Device, Credential, SignedMessage, SignedTransaction, ConnectedSite, and more.
Lux-Specific Packages
The browser extension (apps/ext) uses @luxfi/* packages for Lux Network integration:
| Package | Version | Purpose |
|---|---|---|
@luxfi/common | ^0.3.61 | Shared Lux utilities |
@luxfi/lux-api | 0.7.23 | Lux Network RPC client |
@luxfi/lux-security-engine | 2.0.4 | Transaction security analysis |
@luxfi/lux-swap | 0.0.39 | DEX aggregation |
@luxfi/eth-hd-keyring | 4.3.2 | HD keyring for EVM |
@luxfi/eth-simple-keyring | 5.0.1 | Simple key import |
@luxfi/eth-trezor-keyring | 2.5.2 | Trezor hardware signing |
@luxfi/eth-lattice-keyring | 1.1.1 | GridPlus Lattice signing |
@luxfi/eth-walletconnect-keyring | 2.1.3 | WalletConnect keyring |
@luxfi/eth-coinbase-keyring | 0.0.1 | Coinbase wallet keyring |
@luxfi/eth-gnosis-keyring | 0.0.2 | Gnosis Safe multisig |
@luxfi/eth-watch-keyring | 1.0.0 | Watch-only addresses |
@luxfi/gnosis-sdk | 1.3.6 | Gnosis Safe SDK |
@luxfi/festats | 1.0.1 | Frontend analytics |
@luxfi/page-provider | 0.3.5 | DApp page injection |
@luxfi/widgets | 1.0.9 | Embeddable UI widgets |
blake2b-lux | github:luxfi/blake2b-lux | Blake2b hash (resolution) |
Platforms
| Platform | App Package | Technology | Key Deps |
|---|---|---|---|
| Chrome/Firefox/Safari | @luxwallet/x v0.92.79 | Webpack 5, MV2/MV3, Tailwind | antd 4.x, styled-components |
| Desktop | @onekeyhq/desktop | Electron 27, webpack | electron-root-path, keytar |
| iOS | @onekeyhq/mobile | React Native 0.73.7, Expo 50 | expo-camera, react-native-ble |
| Android | @onekeyhq/mobile | React Native 0.73.7, Expo 50 | expo-camera, react-native-ble |
| Web | @onekeyhq/web | webpack-dev-server, port 3000 | -- |
| Web Embed | @onekeyhq/web-embed | webpack, port 3008 | Cardano WASM agent |
Background Services (40+)
Key services in packages/kit-bg/src/services/:
| Service | Purpose |
|---|---|
ServiceAccount | Account creation, derivation, management |
ServicePassword | Password encoding, biometric auth |
ServiceSend | Transaction construction and broadcasting |
ServiceSwap | DEX swap routing and execution |
ServiceStaking | Staking delegation and rewards |
ServiceDApp | DApp connection and method dispatch |
ServiceHardware | Hardware device management, firmware updates |
ServiceNetwork | Network configuration and switching |
ServiceToken | Token discovery, balances, prices |
ServiceNFT | NFT indexing and display |
ServiceHistory | Transaction history (local + on-chain) |
ServiceDiscovery | DApp browser and discovery |
ServiceCloudBackup | iCloud/Google Drive backup |
ServiceLightning | Lightning Network invoice management |
ServiceNostr | Nostr key and event signing |
ServiceWalletConnect | WalletConnect v2 session management |
ServiceFirmwareUpdate | Hardware wallet firmware OTA |
ServiceQrWallet | Air-gapped QR wallet protocol |
ServiceValidator | Address and transaction validation |
UI Views
Primary views in packages/kit/src/views/:
Home | Send | Receive | Swap | Staking | Market | Discovery (DApp browser) | AssetList | AssetDetails | AccountManagerStacks | Setting | Onboarding | FirmwareUpdate | LightningNetwork | ScanQrCode | AddressBook | FiatCrypto | CloudBackup | KeyTag | LiteCard | UniversalSearch
Development
# Install (requires Node >= 20, git-lfs)
yarn
# Development
yarn app:web # Web on port 3000
yarn app:ext # Browser extension (MV3 dev build)
yarn app:desktop # Electron desktop
yarn app:ios # iOS via USB
yarn app:android # Android
# Building
yarn app:ext:build # Production extension
yarn app:web:build # Production web
# Testing
yarn test # Jest test suite
# Linting
yarn lint # TSC + ESLint + folder lint + i18n check
# Clean
yarn clean # Full workspace clean
yarn reinstall # Clean + installSecurity Model
- Mnemonic never stored in plaintext -- encrypted as
IBip39RevealableSeedwith AES-256-CBC - Private keys encrypted at rest -- PBKDF2 KDF with 5000 iterations
- Password verification -- encrypted known string (
DEFAULT_VERIFY_STRING) used to check password correctness without storing the password - Session encoding -- passwords encoded with per-session random key to prevent debugger interception
- Extension isolation --
decodePassword()throws if called from extension UI process (must use background) - Hardware signing -- private keys never leave the hardware device
- QR air-gap -- Keystone SDK for fully offline signing via animated QR codes
Patches
15 patch-package patches maintained in /patches/:
@kaspa/core-lib,coinselect(UTXO selection fix)@tamagui/animate,@tamagui/switch(UI fixes)@walletconnect/modal-react-native(RN compat)react-native-*(various RN fixes)expo-camera,metro(build fixes)protobufjs(serialization fix)
Related Skills
lux/lux-crypto.md-- Cryptographic primitives and curveslux/lux-safe.md-- Multisig wallets (Gnosis Safe fork)lux/lux-sdk.md-- Go SDK wallet utilitieslux/lux-ledger.md-- Ledger hardware integration