Bull Bitcoin Mobile 6.15.0 — Release Notes
Release version: 6.15.0+228
New Features
- Confidential SEPA: Create recipients, set up and activate a virtual IBAN, and choose Regular or Confidential SEPA for recipients and withdrawals. Eligible non-corporate EU accounts can also activate a virtual IBAN to fund their exchange account, subject to account permissions. (#2982)
- EUR Sell to a bank account: Receive EUR sale proceeds in your account balance or through Instant, Regular or Confidential SEPA, with recipient selection and any required activation steps. (#3032)
- Payjoin controls per action: Payjoin defaults to on for Buy, Sell and bill payments with Bull Bitcoin, and off for Send and Receive with other users. Each action has its own switch; updating preserves your previous Send and Receive setting, and individual exchange orders can still opt out. Advanced settings use compact numeric fields, with minimum amounts in sats and session expiry in minutes. (#2978)
- Swap recovery: Swaps waiting for a claim or refund now show a Retry claim / refund button in transaction details. It completes the swap directly on-chain through your own Electrum server, without needing Boltz to cooperate, so a stranded swap can be recovered even when Boltz is unreachable. (#3043)
Security And Privacy
- Protection against malicious Electrum servers when accelerating a transaction: before offering to speed up an unconfirmed transaction (Replace-By-Fee), the app now checks that the transaction in your history carries valid signatures from your own wallet. This blocks an attack seen in the wild, where a malicious Electrum server hides your broadcast and shows a look-alike transaction that pays the attacker, so that accelerating it would send your funds to them (GHSA-6jp4-8v48-cc5v). If the check fails, acceleration is refused and the screen offers to report the transaction to support. If the transaction cannot be checked yet, for example while the wallet is still syncing, acceleration stays disabled until it can. The risk applied mainly to users connected to a custom Electrum server. (#3048, bull_sdk#36)
- Payjoin requests use a relay on a different domain from their directory, trying other relays when one is unreachable. Relay redirects are rejected to prevent a direct connection that would expose your IP address to the directory. (#3037)
- Payjoin 1.2.0 strengthens validation of proposals, fees, amounts, endpoint URLs and directory responses. Proposals that drop or reorder the sender’s original inputs are rejected, and malformed messages or unsupported BIP 78-only receivers return errors instead of crashing the engine. (#3033)
Privacy Trade-off
- Faster Payjoin status updates come with a temporary privacy trade-off. Default Electrum servers already receive your wallet’s addresses during synchronization. The app now also queries its Electrum server for the original and proposed transaction IDs before broadcast. A shared server observing both participants can link their Payjoin sessions, even if negotiation fails and nothing is broadcast. Tor hides IP addresses but does not prevent this correlation. A transaction ID alone does not reveal the original transaction’s inputs or outputs unless it is later broadcast as a fallback. Running your own Electrum server keeps these lookups on your infrastructure. (#2977, included through #3002)
Reliability And UX
- Payjoin now uses
pj.bullbitcoin.com,pj.bobspacebkk.com,payjoin.lab.vinteum.organdpj.pow.plan-b.foundationas directories and OHTTP relays, replacingpayjo.in, which is shutting down. Receiver discovery has a 30-second total budget so unavailable servers do not delay the Bitcoin QR for several minutes. (#3037) - Payjoin outcomes are detected through targeted transaction lookups while balances and history catch up in the background. Servers without a usable lookup fall back to wallet synchronization. (#2977, included through #3002)
- After sending a Payjoin proposal, receivers wait 60 seconds before being offered “Receive payment normally.” Receive and transaction details share this wait; fallback checks recognize payments already visible and retry temporary verification failures. (#2977, included through #3002)
- Payjoin sessions reserve time for fallback before exchange deadlines. If a Sell or Pay order is reported expired after payment, its confirmation screen shows the transaction ID and lets you leave. After a Buy, the success screen stops showing “Payjoin in progress” and checking the order once the payout Payjoin window ends. (#3016, #3030)
- Buy, Sell and Pay quotes refresh when their price lock expires, with limited retries and an error if refreshing fails. Expired quotes cannot be confirmed or paid. (#3016)
- When prices are unavailable, Send and Receive offer bitcoin units without fiat equivalents; Buy, Sell and Pay show an unavailable estimate instead of missing or outdated rates. Duplicate price requests have also been reduced. (#3022)
- Confidential SEPA availability failures during withdrawals and funding show an error and retry action. Saved recipients require the same virtual IBAN setup as new recipients; activation screens update when activation is reported, explain that you will be notified when ready, and offer a return-home button. Labels also clarify self-transfers, bank accounts and virtual IBANs. (#3023, #3024, #3025, #3026, #3032)
- Encrypted-vault backup and recovery reuse the verified Tor key-server connection across screens, wait until Tor can carry traffic, and allow up to two minutes for the first onion connection. The connecting screen no longer reports Tor as connected too early. (#2985, included through #3002, #3036, #3053)
- Buy confirmations open while quotes load, show loading feedback and accommodate larger text. Buy orders appear in transaction details before wallet synchronization completes; recipient pickers and payment confirmations show loading placeholders. (#2978)
- Exchange sign-in and identity-verification screens offer an exit when their web view fails. (#2972)
Bug Fixes
- Fixed a permanent startup error ("App Init Error") that could affect users updating to 6.14.0 from 6.12.x or earlier when the first launch after the update overlapped a background task: both upgraded the wallet database at the same time and left it in a state that failed on every later launch. Affected devices recover on their first launch of 6.15.0, with no data loss. Updates from older versions are protected as well: updating from 6.2.3 or earlier could hit the same startup error, and updating from 6.5.4 or earlier could lose wallet labels if the upgrade was interrupted or overlapped a background task. Database upgrades now run only in the app, never in a background task; each upgrade step completes fully or not at all, every step is safe to repeat, and a first launch that was interrupted is rebuilt cleanly on the next launch. (#3045, #3051)
- Sell and Pay display and verify the deposit address for the order’s network, preventing Bitcoin and Liquid addresses from being mixed up. (#3032)
- Fixed currency changes that could display a rate for the wrong currency. (#3022)
- Confirmed Buy orders are no longer re-quoted when read. (#3030)
- Fixed invisible dark-theme button labels, including Confirm express, and restored visibility of the indeterminate loading bar. (#3030, #3032)
- Bill-payment amount-limit messages preserve the precision of exchange limits. (#2978)
Translations
- Improved Italian translations for funding, withdrawals, balances, fees, PIN and limit orders, while preserving product names such as Lightning and Liquid. Thanks to @loop-btc. (#3031, #3040, #3049)
- Updated German translations. Special shout-out to @bsn21m, who keeps the German translation up to date with every release. (#2979, #3017)
Under the Hood
- The database upgrade path is tested by re-running every upgrade step over a database holding user data, by stopping the upgrade after every write and relaunching, and by two connections upgrading the same database at once, from every past schema. (#3046, #3047, #3051)
- Updated Payjoin from 1.0.0-rc.8 to 1.2.0 through Dart bindings 0.25.1. Native builds use the release’s locked dependencies and omit build paths to help reproducibility. (#3033)
- Exported Payjoin diagnostics provide clearer session milestones, startup failures, fallback outcomes and exchange status. Tor readiness changes are logged once per change, and a missing wallet before onboarding produces a warning instead of repeated error reports. (#3013, #3036)
- Continued consolidating shared interface components in
bull_ui, including shared loading feedback and frosted top notifications. (#2845, #2851, #2859, #2860, #2861, #2865, #2866, #2867, #2870, #2871, #2874, #2875, #2883, #2884, #2972, #2973, #2975, #2978) - Aligned iOS CocoaPods dependency checksums with release CI to prevent dependency-installation failures. (#3008)
Android APK Verification
The GitHub release provides a universal APK containing all supported Android ABIs.
- Signed APK SHA-256:
f50a86f502e67f0b1e2d9ea047abc2676d2136ebed3e2a5a0134d0bb9a636bf4 - Signing certificate SHA-256:
9e1394519875c7a92e00f137a711df3c66684dd1f47db91817501c68a8e63ed8 - Reproducible unsigned APK SHA-256: pending — will be added once the unsigned build has been reproduced
HASHSUMS256 lists the APK's SHA-256 and is signed by 72478AF18BD0F9553A16B9F19F4E17C3203E0D49 (i5hi) in HASHSUMS256.asc. To verify, download all three assets into one folder and run:
shasum -a 256 -c HASHSUMS256
gpg --verify HASHSUMS256.asc HASHSUMS256
New Contributors
Contributors
@basantagoswami, @bsn21m, @ethicnology, @loop-btc, @wired-pasteque, @i5hi
Full Changelog: v6.14.0...v6.15.0