Changelog
New Features
- Wipe PIN: Optional secondary PIN that, when entered on the lock screen, silently erases all wallet data on the device.
- Clear Clipboard: Option to automatically wipe the clipboard when the app locks or is closed.
- RBF On by Default: On-chain sends signal replace-by-fee by default; option to disable in settings.
- Require Coin Control: Option that forces UTXO selection before on-chain sends.
Improvements
- Reduced APK Size: Optimized package architecture to reduce app install size.
- Various UI tweaks and optimizations.
Security Audit: Grok 4.6 + Kimi K3 + DeepSeek V4
Big thanks to Bitcoin Red Team and PortlandHODL for performing a thorough security audit with Kimi K3.
The bug bounty has been awarded. The audit was not submitted as a means to claim the bug bounty, I offered it to them. All funds from the bounty will be used to further audit Bitcoin projects.
There are no known instances of fund loss in relation to these vulnerabilities.
Seed Protection
- Duress PIN isolated from the real wallet: The decoy PIN no longer unwraps the real spend master. Only decoy secrets are re-encrypted under a separate key, so Backup/export in duress mode cannot leak the real seed.
- Locked spend-secret session no longer writes plaintext: Writes after lock could persist unwrapped seeds, and a missing PIN wrap minted a new master that orphaned every secret. Locked writes now throw, locked reads return null, and PIN unlock only unwraps an existing master (
savePinstill enrolls). - A Keystore flake no longer wipes every seed: Transient EncryptedSharedPreferences errors abort startup without deleting anything. Only a confirmed permanent key invalidation recreates the store.
- Biometric enrollment no longer orphans recovery: New fingerprints now invalidate the biometric key. The PIN wrap is kept so biometric re-enrollment does not destroy spend-secret recovery.
Lightning Node (LND / CLN / NWC)
- LND/CLN no longer send credentials over unverified connections: A TLS-off connect no longer attaches the macaroon or rune to a cleartext probe. Enabling TLS requires a pasted certificate and fails closed if it does not parse. Hostname verification is on for DNS names. Accepting any certificate requires an explicit insecure-TLS opt-in.
- Tor is onion-only for Lightning Node: “Use Tor” on a clearnet host with no certificate used to accept any TLS cert, so a Tor exit could steal the macaroon or rune. Tor now applies only to
.onionhosts. Clearnet connects directly and still requires a certificate or explicit insecure TLS. - On-chain LND/CLN sends are not auto-retried: SendCoins / SendMany / withdraw no longer re-fire after a dropped response, which previously could broadcast a second independent payment.
- Payments require a real receipt: Responses must have a valid Nostr id/sig, matching pubkey/
etag/result_type, andsha256(preimage)must equal the invoice hash. Plaintextws://relays are rejected. - Invoice preview is bound to the BOLT11 amount: A failed
lookup_invoicecould show the typed amount, thenpay_invoiceretried with no amount and paid the real invoice. Local decode now binds the preview; a mismatch throws; there is no amount-less retry.
Boltz / SideSwap
- Boltz no longer pays an attacker-controlled lockup: The REST submarine fallback that funded whatever address the server returned is gone. Lightning pays only go through the LWK path that reconstructs/validates the swap script.
- Boltz
invoice.paid/transaction.claimedis not treated as settlement: Success waits for LWKcomplete()/completePay(). Refund snapshots are kept until that verification, so a fake status cannot delete the refund path. - Fee estimates and SideSwap peg-out rates are capped: Electrum/HTTP presets cannot apply uncapped sat/vB values. Peg-out review and broadcast use the same clamped Liquid fee instead of showing ~20 sats and paying the server rate.
Silent Payments
- Fee-bumps and custom-path wallets no longer burn outputs: SP keys now follow the stored derivation path (not account 0). Destinations are stored per tx and included in backup/restore. If RBF adds an input, the replacement is rebuilt from spent+unspent outputs and fails closed instead of signing a stale or partial BIP-352 key.
- Uncompressed WIF inputs are skipped: If no eligible compressed input remains, the send fails loudly.
input_hashcovers all vin outpoints. BIP-39 whitespace is normalized so SP keys match the wallet seed.
Lock, wipe, backup, and cloak
- A correct duress PIN no longer resets the failed-attempt counter: It still works during lockout, but auto-wipe progress is preserved so duress cannot be used to brute-force the real PIN.
- Lock timing and confirm dialogs resist bypass: After-1/5-min lock and the SAF skip window used wall clock. Confirm dialogs were overlayable, and NFC/URI could swap the destination mid-confirm. Lock timing is monotonic; confirm snapshots the destination and blocks obscured touches.
- Wipe and cloak secrets are hardened: Auto-wipe only ran on the lock-screen PIN, and the cloak code was stored reversibly. Wipe now also runs on spend / view-seed / per-wallet PIN failures; the cloak code is PBKDF2 + salt.
- Backup restore no longer auto-connects Lightning with insecure TLS: Restored LN host + secrets no longer connect automatically. LN now needs a Connection save; insecure TLS is forced off.
- Electrum history cache is status-bound; Boltz Tor does not leak DNS: History is served only when the cached Electrum status still matches. Boltz onion connects through SOCKS with unresolved hostnames.
- Cloak branding on notifications: Incoming-tx notifications are suppressed when cloaked. The foreground service and recents use Calculator.
-======-
SHA256: 55B0AFD1FFCD0B6687BC177123A9D1B40DD9F3A551DA7FDFD30B3822A8337AC7
MD5: F3C04715CCDB46B6BF23FA8E94FD6E72
PGP Public Key
-======-
Full Changelog: v4.6.2-beta...v4.7.0-beta