The Problem

BoldWallet is a Bitcoin wallet using threshold signatures (TSS) that eliminates seed phrases, but the codebase has structural issues that increase maintenance risk and introduce security vulnerabilities. The repository contains 351 files with identifiable import cycles, oversized files, and a committed private key that must be rotated.

What This Does

BoldWallet implements a seedless Bitcoin wallet using Threshold Signatures (2-of-2 or 2-of-3) across mobile devices. Key files and their responsibilities:

  • BBMTLib/tss/mpc.go - 27 functions, defines SessionState, ClearSessionLog, SessionLog, stringJoin, getStatus; called from 6 files, makes outbound network calls
  • BBMTLib/tss/btc.go - 26 functions, defines fee APIs, network settings; called from 4 files, makes network calls
  • BBMTLib/tss/psbt.go - 9 functions, defines MpcSignPSBT, validateSignedPSBT, truncateHex; called from 2 files
  • BBMTLib/tss/nostrtransport/client.go - 6 functions, defines Nostr communication; called from 11 files
  • App.tsx - React entry point, connects 26 modules with instability 0.87
  • services/LocalCache.ts - 15 dependents, participates in circular import with utils.js

The execution flow starts at main in BBMTLib/scripts/main.go:24, which reaches 110 functions. Send in BBMTLib/tss/cmd/nostr-keygen/main.go:281 reaches 26 functions and makes outbound network calls via http.Post. Paths from entry to external effects: main -> loadAndDecryptKeyshare [filesystem via os.ReadFile]; Send [network via http.Post]; estimateFee -> EstimateFees -> FetchUTXOs [network via http.Get].

How It Is Wired

The internal call graph has 470 resolved call edges. Most connected functions: Logln called from 35 places, Logf from 27, Close from 23. The most distinct caller edges: runNostrMpcSignPSBTInternal -> Logf x53, MpcSendBTC -> Logf x50, MpcSignPSBT -> Logf x50.

Critical structural issues:

  • Import cycle: utils.js and services/LocalCache.ts mutually import each other (instability 0.03/0.06)
  • Hub modules: utils.js (32 importers), theme/index.ts (26 importers), services/LocalCache.ts (15 importers) - changes ripple widely
  • Oversized files: components/Styles.tsx, services/WalletService.ts, screens/PSBTModal.tsx (1960 lines each)
  • Deep nesting: screens/PSBTModal.tsx, components/KeyshareModal.tsx, components/TransportModeSelector.tsx (max indentation depth 8)
  • Duplicated code: 2000 repeated 6-line blocks across 70 files including BBMTLib/scripts/keygen.sh, keysign.sh, spend-bitcoin.sh

How To Use It

Setup: This is a React Native + Rails + Go project. Build the Android APK via Docker using the Dockerfile at the root; scripts are in docker/scripts/ with documentation in docker/README.md. iOS builds follow React-Native guidelines.

Configuration: No environment variables are documented in the repo structure. The committed android/app/debug.keystore contains a private key that must be reissued and purged from history.

Running it:

  • CLI entry: BBMTLib/scripts/main.go - the main Go entry point
  • Keygen: BBMTLib/tss/cmd/nostr-keygen/main.go
  • Keysign: BBMTLib/tss/cmd/nostr-keysign/main.go
  • Spend: BBMTLib/tss/cmd/bold-spend/main.go

Real-World Use

A user installs the app and pairs up to 3 devices. To send Bitcoin, the wallet creates a PSBT, which is then signed using threshold signatures across the paired devices via the Nostr or local WiFi protocol. The signed transaction is broadcast to Mempool.space (or a self-hosted instance). No seed phrase is ever generated; key material is split across devices using TSS.

Code Health & Issues

findings from static analysis (65 total: 24 high, 41 medium, 0 low):

  • CRITICAL - Rotate and purge the committed private key: android/app/debug.keystore - A published signing key cannot be unpublished; it lets anyone impersonate the service or decrypt captured traffic. Fix: reissue the key pair and purge from history.
  • HIGH - Pin third-party GitHub Actions to commit SHA: .github/workflows - codecov/codecov-action@v4 can be moved; fix: replace @vN with 40-char commit SHA.
  • HIGH - Remove continue-on-error from correctness-gating steps: .github/workflows/bbmtlib-test.yml line 66 - a failing test suite reports green check.
  • MEDIUM - Declare least-privilege GITHUB_TOKEN permissions in workflows
  • MEDIUM - Enable Dependabot or Renovate: 3 manifest(s), no update bot configured
  • MEDIUM - Gate pull requests on dependency vulnerability scan: no scan in CI
  • MEDIUM - Add pre-commit secret gate: no repo-level gate visible
  • MEDIUM - Move large binaries to Git LFS: ios/Tss.xcframework/ carries 6 blobs over 5MB (Tss 77.7MB, tss.aar 46.7MB)
  • MEDIUM - Set persist-credentials: false on checkout: .github/workflows/bbmtlib-test.yml
  • MEDIUM - Expand test suite: 1 test file against 84 source files (ratio 0.012)

Additionally, the measured analysis found 2 modules in circular dependencies, 3 hub modules with high blast radius, 18 oversized files, 27 files with deep nesting, and duplicated 6-line blocks across 70 scripts.

The Bottom Line

BoldWallet is a technically ambitious seedless Bitcoin wallet with a functional TSS implementation across mobile devices. The codebase is functional but has significant structural debt: a committed private key, import cycles, oversized and deeply nested files, and duplicated logic across 70 scripts. The CI pipeline has gates that can report success even when tests fail. This is suitable for technical teams who can address the critical key rotation and CI fixes, but requires commitment to refactor the circular dependencies and file size issues before it's maintainable for broader teams.