BitSleuth Wallet is a privacy-focused, non-custodial Bitcoin mobile wallet built with React Native and Expo. The app provides secure key management, multi-wallet support, coin control, transaction fee bumping (RBF/CPFP), and real-time price tracking—all without analytics or cloud dependencies.
- 🔐 Non-custodial: Private keys never leave the device; encrypted locally
- 🪙 Bitcoin-only: Focused on BTC with HD wallet support (BIP32/39/44/84/141/173)
- 🎨 Multi-wallet: Create and manage multiple wallets with custom names and colors
- 🔒 Security: PIN/biometric authentication, auto-lock, encrypted mnemonic storage
- 🪙 Coin Control: Manual UTXO selection for advanced privacy and fee optimization
- ⚡ Fee Bumping: RBF (Replace-By-Fee) and CPFP (Child-Pays-For-Parent) support
- 📊 Price Tracking: Real-time BTC prices in multiple fiat currencies
- 🌐 Mainnet/Testnet: Support for both Bitcoin networks
- 🚫 No Analytics: Only Firebase Crashlytics for error reporting (no tracking)
- Framework: React Native + Expo SDK 52
- Language: TypeScript (strict mode)
- State: Zustand + AsyncStorage (encrypted)
- Navigation: Expo Router (file-based)
- Bitcoin: bitcoinjs-lib, bip32, bip39, tiny-secp256k1
- APIs: Blockstream Esplora (UTXO/tx data), CoinGecko (prices)
- Security: expo-local-authentication, expo-secure-store
- Crash Reporting: Firebase Crashlytics (only)
app/ # Screens (Expo Router file-based navigation)
services/ # Core business logic (wallet, bitcoin, esplora, fee, rbf/cpfp)
components/ # Reusable UI components
hooks/ # Zustand stores and custom hooks
types/ # TypeScript type definitions
constants/ # Themes, colors, configuration
scripts/ # Manual test scripts (biometric, crashlytics, firebase)
android/, ios/ # Native platform code and configuration
npm start # Start Expo dev server
npm run ios # Build and run on iOS simulator
npm run android # Build and run on Android emulator
npm run start-tunnel # Start with tunnel for device testing
npx expo start --clear # Clear cache and start dev server
npx expo install <package> # Install packages with compatible versions
npx expo doctor # Check project health and dependencies
npm run lint # Run ESLintnpx expo prebuild # Generate native projects (when modifying native code)
npx expo run:ios # Build and run on iOS device
npx expo run:android # Build and run on Android device
eas build --platform ios # Build iOS app via EAS
eas build --platform android # Build Android app via EAS
eas build --platform all --profile production # Production builds for both platformscd ios && pod install && cd .. # Install iOS dependencies
cd android && ./gradlew clean && cd .. # Clean Android build
npx expo prebuild --clean # Clean and regenerate native projects# Metro bundler issues
npx expo start -c # Clear Metro cache
# iOS issues
cd ios && pod deintegrate && pod install && cd ..
# Android issues
cd android && ./gradlew clean && cd ..
# Test Firebase/Crashlytics connectivity
node scripts/test-firebase-connectivity.js
node scripts/test-crashlytics-simple.js
# Test biometric authentication
node scripts/test-biometric.jsAll markdown documentation files MUST be stored in the docs/ folder, with the following exceptions:
These files should remain in the root directory:
README.md- Project overview and getting started guideCONTRIBUTING.md- Contribution guidelinesLICENSE.mdorLICENSE- License informationCHANGELOG.md- Version historyAGENTS.md- Agent configuration and guidelines.github/copilot-instructions.md- GitHub Copilot instructions
All other markdown files should be placed in the docs/ folder, including but not limited to:
- Product requirements and specifications (e.g.,
PRD.md) - Implementation summaries and technical documentation
- Testing guides and procedures
- Migration guides
- Design documents
- API documentation
- Architecture documentation
- Deployment guides
- Troubleshooting guides
- TODO lists and planning documents
When creating new markdown documentation:
- Create the file in the
docs/folder - Use descriptive, UPPERCASE_SNAKE_CASE filenames (e.g.,
WALLET_PERSISTENCE_SUMMARY.md) - Add a clear title at the top of the document
- Include a brief description or table of contents for longer documents
- TypeScript First: Use TypeScript for all new code with strict type checking
- No
anyTypes: Avoid usingany; use proper types orunknownwith type guards - Naming Conventions:
- Components: PascalCase (
WalletCard.tsx) - Files: kebab-case for screens (
wallet-setup.tsx) - Functions/variables: camelCase
- Constants: UPPER_SNAKE_CASE
- Components: PascalCase (
- Functional Components: Use function components with hooks exclusively
- Self-Documenting Code: Write clear code; add comments only for complex Bitcoin logic or security considerations
- No Analytics: Never add Google Analytics, Firebase Analytics, or any tracking
- Crashlytics Only: Firebase Crashlytics is the only permitted telemetry
- Security First: All cryptographic operations must be reviewed
- Client-Side Only: Private keys and mnemonics never leave the device
- Encrypted Storage: All sensitive data stored via
expo-secure-store - PIN/Biometric Required: Authentication enforced for all sensitive operations
- Zustand: Primary state management via
hooks/wallet-store.ts - AsyncStorage: Persistence layer (encrypted for sensitive data)
- Auto-lock: Session management via
hooks/auto-lock-store.ts - No Redux: We use Zustand for simplicity and performance
- Expo Router: File-based routing in
app/directory - Tabs Layout: Main navigation in
app/(tabs)/ - Modal Screens: Transactions, settings, etc. as separate screens
- Deep Linking: Support for
bitcoin:URIs and app-specific schemes
- Reusable Components: All UI in
components/ - Optimized Touchables: Use
OptimizedTouchableOpacityfor better performance - Animations: Prefer
react-native-reanimatedfor smooth, native-thread animations - Platform-Specific: Use
Platform.select()for iOS/Android differences - Safe Areas: Always use
SafeAreaVieworAndroidSafeContainer
- HD Wallets: BIP32/39/44/84 compliant (SegWit native by default)
- Derivation Paths:
- Mainnet:
m/84'/0'/0'/0/x(Native SegWit) - Testnet:
m/84'/1'/0'/0/x
- Mainnet:
- Address Types: Support P2WPKH (Native SegWit) primarily
- Gap Limit: Standard 20 address gap limit for address discovery
- UTXO Management: Manual coin control via
services/address-cache-service.ts
- Fee Estimation: Dynamic fees via Esplora API (
services/esplora-service.ts) - RBF Support: Replace-By-Fee for stuck transactions (
services/rbf-service.ts) - CPFP Support: Child-Pays-For-Parent for incoming stuck TXs (
services/cpfp-service.ts) - Coin Control: Manual UTXO selection in
app/coin-control.tsx - PSBT: Use Partially Signed Bitcoin Transactions for complex workflows
- Blockstream Esplora: Primary API for blockchain data
- Rate Limiting: Implement exponential backoff for API failures
- Caching: Cache UTXOs, addresses, and transaction data locally
- Testnet/Mainnet: Support both networks; never mix data between them
- Price Data: CoinGecko API with local caching
- Mnemonic Generation: Use
bip39with crypto-secure randomness - Key Derivation: Never store private keys; derive on-demand
- Encryption: All mnemonics encrypted via
expo-secure-store - No Screenshots: Disable screenshots on sensitive screens
- Auto-lock: Configurable auto-lock timeout
- Biometric/PIN: Required for wallet access and transaction signing
- Navigation:
expo-router(file-based routing) - State: Zustand + AsyncStorage
- Bitcoin:
bitcoinjs-lib,bip32,bip39,tiny-secp256k1 - Crypto:
expo-crypto,expo-random,crypto-js - Security:
expo-local-authentication,expo-secure-store - Animations:
react-native-reanimated - QR:
expo-camera,react-native-qrcode-svg - Charts: Custom implementation (see
components/PriceChart.tsx)
# Test biometric authentication
node scripts/test-biometric.js
# Test Firebase Crashlytics
node scripts/test-crashlytics-simple.js
# Test Firebase connectivity
node scripts/test-firebase-connectivity.js- Wallet Creation: Verify mnemonic generation, encryption, storage
- Transaction Sending: Test fee calculation, signing, broadcasting
- Coin Control: Validate UTXO selection and address labeling
- Fee Bumping: Test RBF and CPFP flows
- Multi-wallet: Ensure proper wallet isolation
- Network Switching: Verify testnet/mainnet separation
- Authentication: Test PIN, biometric, auto-lock
- Price Updates: Verify price fetch and display
- Crash Handling: Ensure Crashlytics captures errors
services/wallet-service.ts: Wallet creation, import, encryptionservices/bitcoin-service.ts: Transaction building, signing, broadcastingservices/esplora-service.ts: Blockchain API client (UTXO, TX, fees)services/fee-service.ts: Fee estimation and calculationservices/rbf-service.ts: Replace-By-Fee implementationservices/cpfp-service.ts: Child-Pays-For-Parent implementationservices/address-cache-service.ts: Address generation and cachingservices/secure-auth-service.ts: PIN/biometric authentication
hooks/wallet-store.ts: Main Zustand store (wallets, balances, transactions)hooks/auto-lock-store.ts: Auto-lock timer and session management
app/wallet-setup.tsx: Wallet creation/import flowapp/(tabs)/index.tsx: Home screen (wallet overview)app/(tabs)/send.tsx: Send Bitcoin screenapp/(tabs)/receive.tsx: Receive screen (addresses, QR)app/coin-control.tsx: Manual UTXO selectionapp/fee-bump.tsx: RBF/CPFP interfaceapp/transaction-details.tsx: Transaction detail view
components/WalletCard.tsx: Main wallet display cardcomponents/TransactionItem.tsx: Transaction list itemcomponents/QRScanner.tsx: Bitcoin address/URI scannercomponents/PinUnlockScreen.tsx: PIN entry interfacecomponents/MonzoButton.tsx: Primary button componentcomponents/PriceChart.tsx: Bitcoin price chart
User Action → Screen → Service Layer → Bitcoin/Esplora APIs
↓ ↓
Zustand Store ← AsyncStorage (encrypted)
↓
UI Update
- Mnemonic: Generated → Encrypted → Stored in
expo-secure-store - Private Keys: Never stored; derived on-demand from mnemonic
- PIN: Hashed and stored securely; validated via
secure-auth-service.ts - Biometric: Managed by OS; used to unlock secure storage
- UTXOs: Cached locally with labels; no sensitive data
- Blockstream Esplora: Read-only blockchain data (no keys transmitted)
- CoinGecko: Price data only (no user information)
- Firebase Crashlytics: Error reports only (no PII, no analytics)
import { WalletService } from '@/services/wallet-service';
import { useWalletStore } from '@/hooks/wallet-store';
// Generate new wallet
const mnemonic = WalletService.generateMnemonic();
const wallet = await WalletService.createWallet(mnemonic, 'bitcoin', 'My Wallet', '#FF6B6B');
useWalletStore.getState().addWallet(wallet);
// Import existing wallet
const imported = await WalletService.importWallet(existingMnemonic, 'bitcoin', 'Imported');
useWalletStore.getState().addWallet(imported);import { BitcoinService } from '@/services/bitcoin-service';
import { EsploraService } from '@/services/esplora-service';
// Fetch UTXOs
const utxos = await EsploraService.getAddressUtxos(address, network);
// Build transaction
const psbt = await BitcoinService.buildTransaction({
utxos: selectedUtxos,
outputs: [{ address: recipientAddress, value: amountSats }],
feeRate,
network,
});
// Sign and broadcast
const signedTx = await BitcoinService.signTransaction(psbt, wallet);
const txid = await EsploraService.broadcastTransaction(signedTx.toHex(), network);import { RBFService } from '@/services/rbf-service';
// Check if transaction supports RBF
const canReplace = RBFService.isRBFEligible(transaction);
// Create replacement transaction with higher fee
const newPsbt = await RBFService.createReplacementTransaction(
originalTx,
newFeeRate,
wallet,
network
);
const signed = await BitcoinService.signTransaction(newPsbt, wallet);
const txid = await EsploraService.broadcastTransaction(signed.toHex(), network);import { AddressCacheService } from '@/services/address-cache-service';
// Get all addresses with labels
const addresses = await AddressCacheService.getAddressesForWallet(walletId);
// Select specific UTXOs
const selectedUtxos = utxos.filter(utxo =>
selectedAddresses.includes(utxo.address)
);
// Build transaction with selected UTXOs only
const tx = await BitcoinService.buildTransaction({
utxos: selectedUtxos,
outputs,
feeRate,
network,
});- Device Compromise: Mitigated by PIN/biometric + encrypted storage
- Network Monitoring: Use Tor or VPN (future feature)
- Physical Access: Auto-lock prevents unauthorized access
- Backup Loss: Only mnemonic can recover; no cloud backups
- Phishing: Always verify addresses and amounts before signing
- Coin Control: Use to prevent address reuse and UTXO linking
- Address Rotation: Generate new receive address after each use
- No Address Reuse: Warn users when reusing addresses
- No Cloud Sync: All data stays local
- No KYC: No user accounts or identity verification
- No IP Tracking: No analytics or telemetry (except Crashlytics errors)
npx expo start -c
# or
rm -rf node_modules .expo
npm installcd ios
pod deintegrate
pod cache clean --all
pod install
cd ..cd android
./gradlew clean
cd ..
# Then rebuild
npm run android# Verify configuration files exist
ls GoogleService-Info.plist # iOS
ls google-services.json # Android
# Test connectivity
node scripts/test-firebase-connectivity.js- Check network connection
- Verify Esplora API is accessible
- Ensure sufficient fees (compare to network mempool)
- Check RBF eligibility for replacement transactions
node scripts/test-biometric.js- Ensure device has biometrics enrolled
- Check permissions in device settings
- React Native Debugger: Use Flipper or React Native DevTools
- Console Logs: Check terminal for errors and warnings
- Crashlytics: Review Firebase console for production crashes
- Network Inspector: Monitor API calls in DevTools
- Redux DevTools: (Not used) - we use Zustand
- Lightning Network: LN payments and channel management
- Hardware Wallet Support: Ledger, Trezor integration
- Multisig: Support for multi-signature wallets
- Tor Integration: Route all network traffic through Tor
- Contact Management: Label and manage frequent recipients
- Spending Limits: Daily/transaction spending limits
- Watch-Only Wallets: Import via xpub for read-only monitoring
- PSBT Import/Export: For offline/multisig signing
- Advanced Coin Control: UTXO merging, consolidation tools
- Improve address cache performance for large wallets
- Add comprehensive unit tests (Jest + React Native Testing Library)
- Optimize transaction list rendering for wallets with 1000+ TXs
- Implement proper error boundaries across all screens
- Add retry logic with exponential backoff for all API calls
- Migrate to SQLite for better performance (currently using AsyncStorage)
- Expo Docs: https://docs.expo.dev/
- React Native: https://reactnative.dev/
- Bitcoin Core: https://developer.bitcoin.org/
- BIPs: https://github.com/bitcoin/bips
- Blockstream Esplora: https://github.com/Blockstream/esplora
- bitcoinjs-lib: https://github.com/bitcoinjs/bitcoinjs-lib
- bip39: https://github.com/bitcoinjs/bip39
- tiny-secp256k1: https://github.com/bitcoinjs/tiny-secp256k1
BitSleuth Wallet implements a self-improving skills system where agent skills evolve based on real-world usage outcomes. This creates a living, adaptive knowledge base rather than static documentation.
Skills (like developer-guide, frontend-design, webapp-testing) learn from experience through a structured feedback loop:
- Skill Usage: Agent invokes a skill to complete a task
- Outcome Observation: Task succeeds, fails, or partially succeeds
- Reflection: Agent reflects on what worked, what didn't, and what was learned
- Recording: Agent logs the experience in the skill's
SKILL_MEMORY.mdfile - Pattern Recognition: Over time, patterns emerge from accumulated feedback
- Skill Evolution: When patterns are validated,
SKILL.mdis updated with improvements
Each skill directory (.github/skills/[skill-name]/) contains:
SKILL.md- Core skill instructions (updated deliberately based on validated patterns)SKILL_MEMORY.md- Learning memory that captures feedback from each usage (updated frequently)- Relationship:
SKILL_MEMORY.mdacts as a buffer where experiences accumulate; proven patterns graduate toSKILL.md
- Read both files: Check
SKILL.mdfor core guidance andSKILL_MEMORY.mdfor recent learnings - Execute the task: Apply the guidance from the skill
- Observe the outcome: Did it succeed? Partially? Fail?
-
Reflect on the experience:
- What specific task did you perform?
- What aspects of the skill's guidance were helpful?
- What was missing or misleading?
- What did you learn that others should know?
-
Record feedback in
SKILL_MEMORY.md:- Add an entry to the Feedback Log section
- Follow the template in
.github/skills/FEEDBACK_TEMPLATE.md - Be specific with examples and context
- Assign impact level: HIGH, MEDIUM, or LOW
-
Identify patterns (if multiple feedback entries exist):
- Do you see repeated successes or failures?
- Are there common gaps in coverage?
- Should any learnings be elevated to
SKILL.md?
-
Propose updates (if warranted):
- Add recommendations to "Pending SKILL.md Updates" section
- Don't edit
SKILL.mddirectly yet—let patterns accumulate - High-impact security learnings may warrant immediate updates
Update a skill's core instructions when:
- ✅ Strong pattern emerges: Multiple feedback entries point to the same issue
- ✅ Critical gap found: Missing guidance causes repeated failures
- ✅ Best practice validated: A technique succeeds consistently across different contexts
- ✅ Ecosystem evolves: Libraries, frameworks, or Bitcoin protocol updates
- ✅ Security issue discovered: Any security-related learning (immediate update)
Do NOT update based on:
- ❌ Single isolated incidents (unless security-critical)
- ❌ Unvalidated theories or hunches
- ❌ Temporary workarounds
- ❌ Personal preferences without evidence
### 2026-01-11 18:30 - SUCCESS
**Skill Used**: frontend-design
**Task Context**:
Created transaction details screen with hash display, confirmations, and status.
**Outcome**:
Successfully implemented with positive feedback. Discovered monospace font
requirement for Bitcoin data not covered in SKILL.md.
**What Worked Well**:
- Typography scale perfect for titles
- Spring animations felt natural
- Haptic feedback on copy actions (from previous SKILL_MEMORY insight)
**What Didn't Work**:
- No guidance on monospace fonts for transaction hashes/addresses
- Missing "copy to clipboard" interaction pattern
**Key Learnings**:
- Bitcoin technical data (hashes, addresses) MUST use monospace fonts
- Copy actions need: haptic + visual + temporal feedback
- Technical data benefits from smaller font size (14pt vs 16pt)
**Recommended Updates**:
1. Add section: "Displaying Technical/Monospace Data" to SKILL.md
2. Add pattern: "Copy to Clipboard Interactions" with example
3. Update typography guidance with technical data exceptions
**Impact Level**: MEDIUM- Continuous Improvement: Skills get better with every use
- Evidence-Based: Changes based on real outcomes, not speculation
- Institutional Memory: Knowledge persists across agent sessions
- Collaborative Learning: Multiple agents contribute to shared skills
- Balanced Stability: Core guidance stays stable while memory captures variation
- Feedback Loop Guide:
.github/skills/FEEDBACK_LOOP_GUIDE.md- Complete system documentation - Feedback Template:
.github/skills/FEEDBACK_TEMPLATE.md- Template for recording outcomes - Skill Memories: Each skill has its own
SKILL_MEMORY.mdfile for accumulated learnings
Skills are living systems. Don't just follow instructions—observe outcomes, record learnings, and contribute to collective improvement. Your feedback makes the next agent more effective.
For unclear conventions or missing patterns, refer to recent code changes, check skill memory files, or ask the development team for clarification.