Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ All notable changes to Bull Bitcoin Mobile will be documented in this file.

## [Unreleased]

_Nothing yet._
### Bug Fixes

#### Swaps
- Suspended unavailable Boltz network processing while preserving legacy swap history, and migrated testnet Lightning sends, receives, and cross-chain transfers to the public Exchange swap API with crash-safe transaction recovery, serialized polling, duplicate-order protection, and labels applied only after swap completion and on-chain confirmation.

---

Expand Down
3 changes: 3 additions & 0 deletions FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,14 @@ graph TB
SETTINGS --> BULL_PAYJOIN
STATUS --> BULL_PAYJOIN
SWAPS --> BULL_PAYJOIN
SWAPS --> LABELS
SWAPS --> UTXO_MGMT
TOR --> CORE
TRANSFER --> CONSOLIDATION
TRANSFER --> SEND
TRANSFER --> RECEIVE
TX_HISTORY --> BULL_PAYJOIN
TX_HISTORY --> SWAPS
TX_HISTORY --> WALLETS
UTXO_MGMT --> LABELS
UTXO_MGMT --> WALLETS
Expand All @@ -118,6 +120,7 @@ graph TB
WALLETS --> NETWORK
WALLETS --> SECRETS
WALLETS --> SETTINGS
WALLETS --> SWAPS
WITHDRAWAL --> RECIPIENTS

%% Styling
Expand Down
4 changes: 0 additions & 4 deletions ios/Runner/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@ import workmanager_apple
withIdentifier: "com.bullbitcoin.mobile.liquid-sync-id",
frequency: NSNumber(value: 20 * 60)
)
WorkmanagerPlugin.registerPeriodicTask(
withIdentifier: "com.bullbitcoin.mobile.swaps-sync-id",
frequency: NSNumber(value: 20 * 60)
)
WorkmanagerPlugin.registerPeriodicTask(
withIdentifier: "com.bullbitcoin.mobile.logs-prune-id",
frequency: NSNumber(value: 20 * 60)
Expand Down
1 change: 0 additions & 1 deletion ios/Runner/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@
<array>
<string>com.bullbitcoin.mobile.bitcoin-sync-id</string>
<string>com.bullbitcoin.mobile.liquid-sync-id</string>
<string>com.bullbitcoin.mobile.swaps-sync-id</string>
<string>com.bullbitcoin.mobile.logs-prune-id</string>
<string>com.bullbitcoin.mobile.services-check-id</string>
</array>
Expand Down
18 changes: 2 additions & 16 deletions lib/core/background_tasks/handler.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'package:bb_mobile/core/background_tasks/tasks.dart';
import 'package:bb_mobile/core/storage/sqlite_database.dart';
import 'package:bb_mobile/core/swaps/domain/usecases/process_ongoing_swaps_usecase.dart';
import 'package:bb_mobile/core/utils/logger.dart' show log;
import 'package:bb_mobile/core/wallet/domain/usecases/get_wallets_usecase.dart';
import 'package:bb_mobile/core/wallet/domain/usecases/sync_wallet_usecase.dart';
Expand Down Expand Up @@ -48,8 +47,6 @@ Future<bool> tasksHandler(String task) async {

final syncWalletUsecase = locator<SyncWalletUsecase>();
final getWalletsUsecase = locator<GetWalletsUsecase>();
final processOngoingSwapsUsecase = locator<ProcessOngoingSwapsUsecase>();

final backgroundTask = BackgroundTask.fromName(task);

switch (backgroundTask) {
Expand All @@ -66,19 +63,8 @@ Future<bool> tasksHandler(String task) async {
log.fine('Liquid Wallet ${wallet.id} synced');
}
case BackgroundTask.swapsSync:
final wallets = await getWalletsUsecase.execute();
if (wallets.isEmpty) {
log.warning('No wallets to sync');
} else {
// Poll + act to completion: the BG isolate dies right after this
// returns, so a websocket-based restart would never see an event.
// Bounded to respect the iOS background budget.
await processOngoingSwapsUsecase.execute().timeout(
const Duration(seconds: 25),
onTimeout: () =>
log.warning('Swaps background processing hit time budget'),
);
}
// Kept as a no-op for tasks scheduled by an older app version.
log.info('Legacy swaps background processing is disabled');
case BackgroundTask.logsPrune:
await log.prune();
}
Expand Down
2 changes: 0 additions & 2 deletions lib/core/core_locator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ class CoreLocator {
static void registerPorts(GetIt locator) {
ElectrumLocator.registerPorts(locator);
MempoolLocator.registerPorts(locator);
SwapsLocator.registerPorts(locator);
LabelsLocator.registerPorts(locator);
}

Expand All @@ -68,7 +67,6 @@ class CoreLocator {
ExchangeLocator.registerServices(locator);
MempoolLocator.registerServices(locator);
SeedLocator.registerServices(locator);
SwapsLocator.registerServices(locator);
}

static void registerUsecases(GetIt locator) {
Expand Down
14 changes: 9 additions & 5 deletions lib/core/screens/send_confirm_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -601,12 +601,16 @@ class CommonChainSwapSendInfoSection extends StatelessWidget {
mainAxisAlignment: .end,
mainAxisSize: .min,
children: [
BBText(
swap.id,
style: context.font.bodyLarge?.copyWith(
color: context.appColors.secondary,
Expanded(
child: BBText(
swap.id,
style: context.font.bodyLarge?.copyWith(
color: context.appColors.secondary,
),
textAlign: .end,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
textAlign: .end,
),
const Gap(4),
InkWell(
Expand Down
9 changes: 0 additions & 9 deletions lib/core/status/domain/entity/service_status.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,6 @@ sealed class AllServicesStatus with _$AllServicesStatus {
),
)
ServiceStatusInfo liquidElectrum,
@Default(
ServiceStatusInfo(
status: ServiceStatus.unknown,
name: 'Boltz',
lastChecked: null,
),
)
ServiceStatusInfo boltz,
@Default(
ServiceStatusInfo(
status: ServiceStatus.unknown,
Expand Down Expand Up @@ -107,7 +99,6 @@ sealed class AllServicesStatus with _$AllServicesStatus {
internetConnection.isOnline &&
bitcoinElectrum.isOnline &&
liquidElectrum.isOnline &&
boltz.isOnline &&
// Payjoin is opt-in: disabled is not a fault (see _checkPayjoinService).
(payjoin.isOnline || payjoin.isDisabled) &&
pricer.isOnline &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import 'package:bb_mobile/core/fees/domain/repositories/fees_repository.dart';
import 'package:bb_mobile/core/recoverbull/data/repository/recoverbull_repository.dart';
import 'package:bb_mobile/core/status/domain/entity/service_status.dart';
import 'package:bb_mobile/core/status/domain/ports/electrum_connectivity_port.dart';
import 'package:bb_mobile/core/swaps/data/repository/boltz_swap_repository.dart';
import 'package:bb_mobile/core/swaps/domain/entity/swap.dart';
import 'package:bb_mobile/core/tor/data/usecases/tor_status_usecase.dart';
import 'package:bb_mobile/core/tor/tor_status.dart';
import 'package:bb_mobile/core/utils/logger.dart';
Expand All @@ -17,7 +15,6 @@ import 'package:primitives/primitives.dart' show Err, Ok;

class CheckAllServiceStatusUsecase {
final ElectrumConnectivityPort _electrumConnectivityPort;
final BoltzSwapRepository _boltzSwapRepository;
final ExchangeRateRepository _exchangeRateRepository;
final PayjoinPolicyAccess _payjoinPolicy;
final PayjoinDiagnostics _payjoinDiagnostics;
Expand All @@ -28,7 +25,6 @@ class CheckAllServiceStatusUsecase {

CheckAllServiceStatusUsecase({
required this._electrumConnectivityPort,
required this._boltzSwapRepository,
required this._exchangeRateRepository,
required this._payjoinPolicy,
required this._payjoinDiagnostics,
Expand All @@ -46,7 +42,6 @@ class CheckAllServiceStatusUsecase {
_checkInternetConnection(),
_checkBitcoinElectrumServer(network),
_checkLiquidElectrumServer(network),
_checkBoltzService(network),
_checkPayjoinService(),
_checkPricerService(network),
_checkMempoolService(network),
Expand All @@ -58,12 +53,11 @@ class CheckAllServiceStatusUsecase {
internetConnection: results[0],
bitcoinElectrum: results[1],
liquidElectrum: results[2],
boltz: results[3],
payjoin: results[4],
pricer: results[5],
mempool: results[6],
tor: results[7],
recoverbull: results[8],
payjoin: results[3],
pricer: results[4],
mempool: results[5],
tor: results[6],
recoverbull: results[7],
lastChecked: now,
);
} catch (e) {
Expand Down Expand Up @@ -118,26 +112,6 @@ class CheckAllServiceStatusUsecase {
}
}

Future<ServiceStatusInfo> _checkBoltzService(Network network) async {
try {
await _boltzSwapRepository.updateSwapLimitsAndFees(
SwapType.bitcoinToLightning,
);

return ServiceStatusInfo(
status: ServiceStatus.online,
name: 'Boltz',
lastChecked: DateTime.now(),
);
} catch (e) {
return ServiceStatusInfo(
status: ServiceStatus.offline,
name: 'Boltz',
lastChecked: DateTime.now(),
);
}
}

Future<ServiceStatusInfo> _checkPayjoinService() async {
try {
// Payjoin is opt-in: when it's disabled in settings the OHTTP relay is
Expand Down Expand Up @@ -304,11 +278,6 @@ class CheckAllServiceStatusUsecase {
name: 'Liquid Electrum',
lastChecked: now,
),
boltz: ServiceStatusInfo(
status: ServiceStatus.unknown,
name: 'Boltz',
lastChecked: now,
),
payjoin: ServiceStatusInfo(
status: ServiceStatus.unknown,
name: 'Payjoin',
Expand Down
6 changes: 0 additions & 6 deletions lib/core/status/status_locator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ import 'package:bb_mobile/core/recoverbull/data/repository/recoverbull_repositor
import 'package:bb_mobile/core/status/domain/ports/electrum_connectivity_port.dart';
import 'package:bb_mobile/core/status/domain/usecases/check_all_service_status_usecase.dart';
import 'package:bb_mobile/core/status/interface_adapters/adapter/electrum_connectivity_adapter.dart';
import 'package:bb_mobile/core/swaps/data/repository/boltz_swap_repository.dart';
import 'package:bb_mobile/core/tor/data/usecases/tor_status_usecase.dart';
import 'package:bb_mobile/core/utils/constants.dart';
import 'package:bb_mobile/core/wallet/data/repositories/wallet_repository.dart';
import 'package:bull_payjoin/bull_payjoin.dart';
import 'package:get_it/get_it.dart';
Expand All @@ -28,10 +26,6 @@ class StatusLocator {
// Usecase
locator.registerFactory<CheckAllServiceStatusUsecase>(
() => CheckAllServiceStatusUsecase(
boltzSwapRepository: locator<BoltzSwapRepository>(
instanceName:
LocatorInstanceNameConstants.boltzSwapRepositoryInstanceName,
),
exchangeRateRepository: locator<ExchangeRateRepository>(
instanceName: 'mainnetExchangeRateRepository',
),
Expand Down
11 changes: 11 additions & 0 deletions lib/core/storage/migrations/schema_13_to_14.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import 'package:drift/drift.dart';
/// database (payjoin.sqlite, see the bull_payjoin package), and 14 was never
/// released — every tag up to v6.12.5 ships schema 13 — so those columns were
/// folded out of this step rather than added and then migrated away.
///
/// Adds the order_swaps table and indexes for crash-safe Exchange transfers.
class Schema13To14 {
static Future<void> migrate(Migrator m, Schema14 schema14) async {
// New dismissed_announcements table: one row per home announcement the
Expand All @@ -30,5 +32,14 @@ class Schema13To14 {
error: e,
);
}

await m.createTable(schema14.orderSwaps);
await m.createIndex(schema14.orderSwapsRequestId);
await m.createIndex(schema14.orderSwapsLocalStatus);
await m.createIndex(schema14.orderSwapsSourceWallet);
await m.createIndex(schema14.orderSwapsDestinationWallet);
await m.createIndex(schema14.orderSwapsBitcoinTxid);
await m.createIndex(schema14.orderSwapsLiquidTxid);
await m.createIndex(schema14.orderSwapsLocalPayinTxid);
}
}
Loading
Loading