feat(rn_cli_wallet): add Bitcoin (bip122) support#565
Conversation
Port Bitcoin (bip122) support from the web react-wallet-v2 sample into the React Native wallet, following the existing per-chain conventions. - BitcoinLib + constants/utils/handlers for signMessage, getAccountAddresses, sendTransfer and signPsbt (mainnet, P2WPKH + P2TR/ordinals). Uses pure-JS @bitcoinerlab/secp256k1 (tiny-secp256k1 is WASM and won't run under Hermes) and wires @noble/secp256k1 v3 sync hashes from @noble/hashes. - Wire bip122 into session approval, request routing, 3 signing modals, SettingsStore, init hook and PresetsUtil. - Import wallet: replace the cramped 6-item SegmentedControl with a scalable NetworkDropdown and add Bitcoin as an import option; close the dropdown when the input is focused. - Secret keys screen shows the Bitcoin recovery phrase. - Balances: request bip122 from the balance API and always show a Bitcoin row. Distinguish a confirmed 0 from an unknown balance (failed/unsupported chain) by rendering "~" instead of "0"; downgrade expected 400s from error to warn. - misc: don't warn about a missing bundle ID on web (expo-application has none). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Claude finished @ignaciosantise's task in 5m 42s —— View job PR Review: feat(rn_cli_wallet): add Bitcoin (bip122) support
🚨 PR Too Large Files: 26 Lines: ~2009 Severity: HIGH Category: maintainability 🔒 External Domain URLs (Non-blocking)
Found 7 issue(s)Issue 1:
|
- Remove misleading getPrivateKey() (dead code; returned the master mnemonic). - sendTransfer: select UTXOs with for...of + break instead of forEach+return, which never stopped and spent every UTXO. - signPsbt: validate each signed input instead of hardcoding index 0 (would throw when the dApp signs inputs not including index 0). - ImportWalletModal: refetch balances after a Bitcoin import, matching the other chains. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Thanks for the review 🙏 Actions taken in ✅ Fixed
⏸️ Deferred / won't fix (with reasons)
|
There was a problem hiding this comment.
Pull request overview
Adds Bitcoin (bip122) support to the wallets/rn_cli_wallet sample wallet, including key derivation/signing utilities, WalletConnect request handling + modals, import/secret phrase UI updates, and balance display logic for unsupported chains.
Changes:
- Introduces a Bitcoin stack (
BitcoinLib, constants, wallet + request handler utils) and wires it into initialization + WalletConnect routing and modals. - Updates import wallet and secret phrase screens to support Bitcoin mnemonic handling.
- Extends balances fetching/rendering to include
bip122and to represent “unknown” balances as~when the API rejects a chain.
Reviewed changes
Copilot reviewed 24 out of 26 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| wallets/rn_cli_wallet/yarn.lock | Adds locked dependencies for Bitcoin support and related crypto libraries. |
| wallets/rn_cli_wallet/src/utils/PresetsUtil.ts | Adds Bitcoin network images and chains into the presets registry. |
| wallets/rn_cli_wallet/src/utils/misc.ts | Suppresses “Invalid bundle ID” warning on web only. |
| wallets/rn_cli_wallet/src/utils/BitcoinWalletUtil.ts | Adds Bitcoin wallet creation/restore + import flow and persists mnemonic. |
| wallets/rn_cli_wallet/src/utils/BitcoinRequestHandlerUtil.ts | Adds WalletConnect request approve/reject handler for bip122 methods. |
| wallets/rn_cli_wallet/src/utils/BalanceTypes.ts | Adds balanceUnavailable flag to represent unknown balances. |
| wallets/rn_cli_wallet/src/store/WalletStore.ts | Adds Bitcoin address + chain support and “unknown balance” synthesis logic. |
| wallets/rn_cli_wallet/src/store/SettingsStore.ts | Stores Bitcoin address/wallet in app settings state. |
| wallets/rn_cli_wallet/src/store/ModalStore.ts | Adds Bitcoin session modal identifiers. |
| wallets/rn_cli_wallet/src/services/BalanceService.ts | Downgrades expected 400s to warnings and adjusts per-chain failure logging. |
| wallets/rn_cli_wallet/src/screens/Wallets/index.tsx | Adds Bitcoin address mapping and triggers balance fetch when BTC address exists. |
| wallets/rn_cli_wallet/src/screens/Wallets/components/TokenBalanceCard.tsx | Renders ~ SYMBOL when balanceUnavailable is true. |
| wallets/rn_cli_wallet/src/screens/SecretPhrase/index.tsx | Displays the Bitcoin recovery phrase when available. |
| wallets/rn_cli_wallet/src/modals/SessionProposalModal.tsx | Adds bip122 namespace support and exposes both BTC addresses in accounts. |
| wallets/rn_cli_wallet/src/modals/SessionBitcoinSignMessageModal.tsx | New modal to approve/reject Bitcoin message signing. |
| wallets/rn_cli_wallet/src/modals/SessionBitcoinSendTransactionModal.tsx | New modal to approve/reject Bitcoin transfer/PSBT signing. |
| wallets/rn_cli_wallet/src/modals/SessionBitcoinGetAddressesModal.tsx | New modal to approve/reject Bitcoin address sharing. |
| wallets/rn_cli_wallet/src/modals/ImportWalletModal.tsx | Replaces segmented control with a dropdown and adds Bitcoin import. |
| wallets/rn_cli_wallet/src/lib/BitcoinLib.ts | Adds Bitcoin derivation, message signing, transfers, and PSBT signing. |
| wallets/rn_cli_wallet/src/hooks/useWalletKitEventsManager.ts | Routes bip122 signing methods to the new Bitcoin modals. |
| wallets/rn_cli_wallet/src/hooks/useInitializeWalletKit.ts | Initializes/restores Bitcoin wallet on startup and stores it in SettingsStore. |
| wallets/rn_cli_wallet/src/constants/Bitcoin.ts | Adds bip122 constants (chains, methods, events, mainnet CAIP-2 ID). |
| wallets/rn_cli_wallet/src/components/NetworkDropdown.tsx | New dropdown UI component for scalable network selection. |
| wallets/rn_cli_wallet/src/components/Modal.tsx | Registers the new Bitcoin modals in the modal switch. |
| wallets/rn_cli_wallet/package.json | Adds Bitcoin dependencies and adjusts the android script invocation. |
Comments suppressed due to low confidence (1)
wallets/rn_cli_wallet/src/store/WalletStore.ts:349
fetchBalancesreturns early whenanySuccessis false, which preventsprocessBalancesfrom synthesizing the BTC (and other native) rows marked asbalanceUnavailable. With a Bitcoin-only wallet (or any address group where the balance API 400s), this will likely leave the UI without the intended "~" placeholder row because balances never get updated.
// Only update state if at least one API call succeeded
const anySuccess =
eip155Result.anySuccess ||
tonResult.anySuccess ||
tronResult.anySuccess ||
suiResult.anySuccess ||
solanaResult.anySuccess ||
bitcoinResult.anySuccess;
if (!anySuccess) {
return;
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- BalanceService: throw a typed BalanceFetchError carrying the HTTP status instead of parsing the error message suffix, and stop double-logging expected per-chain HTTP failures (already logged in fetchBalanceForChain). - BitcoinLib.createTransaction: validate all signed inputs, not just index 0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
P2TR (taproot/ordinals) addresses now derive from m/86' (BIP86) instead of m/84' (BIP84, which is for P2WPKH). Keeps ordinals addresses interoperable with other BIP86-compliant wallets. Payment (P2WPKH) addresses stay on m/84'. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Update on #3 (taproot derivation path) — decided to fix it here rather than defer to upstream, since it's an unambiguous standards issue. In Refs:
I'll still flag this to the wallet team so the upstream |
Summary
Adds Bitcoin (
bip122) support towallets/rn_cli_wallet, ported from the webreact-wallet-v2sample and wired into the existing per-chain conventions (constants + lib + wallet/handler utils + modals), plus supporting UI/balance changes.What's included
Bitcoin core (
bip122, mainnet)BitcoinLibwith HD derivation for both P2WPKH (payment) and P2TR (ordinals/taproot) addresses, and the 4 methods:signMessage,getAccountAddresses,sendTransfer,signPsbt(UTXO/fee/broadcast via mempool.space).constants/Bitcoin.ts,BitcoinWalletUtil,BitcoinRequestHandlerUtil, and 3 signing modals.SessionProposalModal), request routing (useWalletKitEventsManager),ModalStore,Modal.tsx,SettingsStore, the init hook andPresetsUtil.Crypto notes (RN/Hermes)
@bitcoinerlab/secp256k1instead of the web sample'stiny-secp256k1(WASM, won't run under Hermes);bitcoinjs-lib/bip32/ecpairaccept it via their factories.@noble/secp256k1v3 sync hashes from@noble/hashes(its schnorr sync API otherwise throws "hashes.sha256 not set").Bufferso types matchbitcoinjs-lib.Import wallet UI
SegmentedControlwith a scalableNetworkDropdown(icon + name + inline scrollable list) and adds Bitcoin as an import option.Secret keys screen
Balances
bip122from the balance API and always shows a Bitcoin row.bip122/sui), the native row renders~instead of0.errortowarn(the service already fails silently per-chain).Misc
expo-applicationhas no bundle ID there); native still warns.Verification
tscandeslintclean (only a pre-existingDesktopFrameWrapper.web.tsxwindowerror remains, untouched).bc1q…/bc1p…, ECDSA + schnorr signing, PSBT build) passes.expo export --platform iossucceeds (Hermes.hbcbundle, no WASM/resolution errors).Not yet done (manual)
bip122dApp session (approve + exercise each method).sendTransfer/signPsbtbroadcast are mainnet-only (real BTC) — usesignPsbtwithbroadcast:falseas the safe tx-path check.bip122(same assui), so BTC shows~until/unless the API adds support.🤖 Generated with Claude Code