Skip to content

Commit d4d6c7a

Browse files
authored
Merge pull request #1688 from SatoshiPortal/custom-mempool-server
feat: custom mempool url
2 parents 9de4e7b + cdca1d3 commit d4d6c7a

67 files changed

Lines changed: 3769 additions & 125 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

lib/core/core_locator.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'package:bb_mobile/core/exchange/exchange_locator.dart';
66
import 'package:bb_mobile/core/fees/fees_locator.dart';
77
import 'package:bb_mobile/core/labels/labels_locator.dart';
88
import 'package:bb_mobile/core/ledger/ledger_locator.dart';
9+
import 'package:bb_mobile/core/mempool/mempool_locator.dart';
910
import 'package:bb_mobile/core/payjoin/payjoin_locator.dart';
1011
import 'package:bb_mobile/core/recoverbull/recoverbull_locator.dart';
1112
import 'package:bb_mobile/core/seed/seed_locator.dart';
@@ -29,6 +30,7 @@ class CoreLocator {
2930
await ElectrumLocator.registerDatasources(locator);
3031
ExchangeLocator.registerDatasources(locator);
3132
FeesLocator.registerDatasources(locator);
33+
await MempoolLocator.registerDatasources(locator);
3234
PayjoinLocator.registerDatasources(locator);
3335
await RecoverbullLocator.registerDatasources(locator);
3436
SeedLocator.registerDatasources(locator);
@@ -44,6 +46,7 @@ class CoreLocator {
4446
static void registerPorts() {
4547
ElectrumLocator.registerPorts(locator);
4648
BlockchainLocator.registerPorts(locator);
49+
MempoolLocator.registerPorts(locator);
4750
SwapsLocator.registerPorts(locator);
4851
WalletLocator.registerPorts(locator);
4952
}
@@ -55,6 +58,7 @@ class CoreLocator {
5558
ElectrumLocator.registerRepositories(locator);
5659
ExchangeLocator.registerRepositories(locator);
5760
FeesLocator.registerRepositories(locator);
61+
MempoolLocator.registerRepositories(locator);
5862
PayjoinLocator.registerRepositories(locator);
5963
SeedLocator.registerRepositories(locator);
6064
StorageLocator.registerRepositories(locator);
@@ -68,6 +72,7 @@ class CoreLocator {
6872
}
6973

7074
static void registerServices() {
75+
MempoolLocator.registerServices(locator);
7176
SeedLocator.registerServices(locator);
7277
SwapsLocator.registerServices(locator);
7378
}
@@ -78,6 +83,7 @@ class CoreLocator {
7883
BlockchainLocator.registerUsecases(locator);
7984
ExchangeLocator.registerUseCases(locator);
8085
FeesLocator.registerUseCases(locator);
86+
MempoolLocator.registerUsecases(locator);
8187
PayjoinLocator.registerUsecases(locator);
8288
RecoverbullLocator.registerUsecases(locator);
8389
SeedLocator.registerUsecases(locator);

lib/core/fees/data/fees_datasource.dart

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,47 @@
11
import 'package:bb_mobile/core/fees/domain/fees_entity.dart';
2+
import 'package:bb_mobile/core/mempool/application/usecases/get_active_mempool_server_usecase.dart';
3+
import 'package:bb_mobile/core/mempool/domain/repositories/mempool_settings_repository.dart';
4+
import 'package:bb_mobile/core/mempool/domain/value_objects/mempool_server_network.dart';
25
import 'package:bb_mobile/core/utils/constants.dart';
36
import 'package:dio/dio.dart';
47

58
class FeesDatasource {
6-
final Dio _bitcoinMainnetMempoolHttpClient;
7-
final Dio _bitcoinTestnetMempoolHttpClient;
9+
final GetActiveMempoolServerUsecase _getActiveMempoolServerUsecase;
10+
final MempoolSettingsRepository _mempoolSettingsRepository;
811

912
FeesDatasource({
10-
String? bitcoinMainnetMempoolUrl,
11-
String? bitcoinTestnetMempoolUrl,
12-
}) : _bitcoinMainnetMempoolHttpClient = Dio(
13-
BaseOptions(
14-
baseUrl:
15-
bitcoinMainnetMempoolUrl ??
16-
'https://${ApiServiceConstants.bbMempoolUrlPath}',
17-
),
18-
),
19-
_bitcoinTestnetMempoolHttpClient = Dio(
20-
BaseOptions(
21-
baseUrl:
22-
bitcoinTestnetMempoolUrl ??
23-
'https://${ApiServiceConstants.testnetMempoolUrlPath}',
24-
),
25-
);
13+
required GetActiveMempoolServerUsecase getActiveMempoolServerUsecase,
14+
required MempoolSettingsRepository mempoolSettingsRepository,
15+
}) : _getActiveMempoolServerUsecase = getActiveMempoolServerUsecase,
16+
_mempoolSettingsRepository = mempoolSettingsRepository;
2617

2718
Future<FeeOptions> getBitcoinNetworkFeeOptions({
2819
required bool isTestnet,
2920
}) async {
30-
final http =
31-
isTestnet
32-
? _bitcoinTestnetMempoolHttpClient
33-
: _bitcoinMainnetMempoolHttpClient;
21+
// Get network settings
22+
final network = MempoolServerNetwork.fromEnvironment(
23+
isTestnet: isTestnet,
24+
isLiquid: false,
25+
);
26+
final settings = await _mempoolSettingsRepository.fetchByNetwork(network);
27+
28+
// Determine which mempool server to use
29+
String baseUrl;
30+
if (settings.useForFeeEstimation) {
31+
// Use custom or default mempool server from settings
32+
final server = await _getActiveMempoolServerUsecase.execute(
33+
isTestnet: isTestnet,
34+
isLiquid: false,
35+
);
36+
baseUrl = server.fullUrl;
37+
} else {
38+
// Fall back to BB's mempool
39+
baseUrl = isTestnet
40+
? 'https://${ApiServiceConstants.testnetMempoolUrlPath}'
41+
: 'https://${ApiServiceConstants.bbMempoolUrlPath}';
42+
}
43+
44+
final http = Dio(BaseOptions(baseUrl: baseUrl));
3445
const path = '/api/v1/fees/recommended';
3546

3647
final resp = await http.get(path);

lib/core/fees/fees_locator.dart

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
11
import 'package:bb_mobile/core/fees/data/fees_datasource.dart';
22
import 'package:bb_mobile/core/fees/data/fees_repository.dart';
33
import 'package:bb_mobile/core/fees/domain/get_network_fees_usecase.dart';
4+
import 'package:bb_mobile/core/mempool/application/usecases/get_active_mempool_server_usecase.dart';
5+
import 'package:bb_mobile/core/mempool/domain/repositories/mempool_settings_repository.dart';
46
import 'package:bb_mobile/core/settings/data/settings_repository.dart';
57
import 'package:get_it/get_it.dart';
68

79
class FeesLocator {
810
static void registerDatasources(GetIt locator) {
9-
locator.registerLazySingleton<FeesDatasource>(() => FeesDatasource());
11+
locator.registerLazySingleton<FeesDatasource>(
12+
() => FeesDatasource(
13+
getActiveMempoolServerUsecase:
14+
locator<GetActiveMempoolServerUsecase>(),
15+
mempoolSettingsRepository: locator<MempoolSettingsRepository>(),
16+
),
17+
);
1018
}
1119

1220
static void registerRepositories(GetIt locator) {
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import 'package:bb_mobile/core/mempool/domain/entities/mempool_server.dart';
2+
3+
class MempoolServerDto {
4+
final String url;
5+
final bool isCustom;
6+
final bool isTestnet;
7+
final bool isLiquid;
8+
9+
MempoolServerDto({
10+
required this.url,
11+
required this.isCustom,
12+
required this.isTestnet,
13+
required this.isLiquid,
14+
});
15+
16+
factory MempoolServerDto.fromEntity(MempoolServer entity) {
17+
return MempoolServerDto(
18+
url: entity.url,
19+
isCustom: entity.isCustom,
20+
isTestnet: entity.isTestnet,
21+
isLiquid: entity.isLiquid,
22+
);
23+
}
24+
25+
String get fullUrl => 'https://$url';
26+
27+
@override
28+
bool operator ==(Object other) =>
29+
identical(this, other) ||
30+
other is MempoolServerDto &&
31+
runtimeType == other.runtimeType &&
32+
url == other.url &&
33+
isCustom == other.isCustom &&
34+
isTestnet == other.isTestnet &&
35+
isLiquid == other.isLiquid;
36+
37+
@override
38+
int get hashCode =>
39+
url.hashCode ^
40+
isCustom.hashCode ^
41+
isTestnet.hashCode ^
42+
isLiquid.hashCode;
43+
44+
@override
45+
String toString() =>
46+
'MempoolServerDto(url: $url, isCustom: $isCustom, isTestnet: $isTestnet, isLiquid: $isLiquid)';
47+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import 'package:bb_mobile/core/mempool/domain/entities/mempool_settings.dart';
2+
3+
class MempoolSettingsDto {
4+
final String network;
5+
final bool useForFeeEstimation;
6+
7+
MempoolSettingsDto({
8+
required this.network,
9+
required this.useForFeeEstimation,
10+
});
11+
12+
factory MempoolSettingsDto.fromEntity(MempoolSettings entity) {
13+
return MempoolSettingsDto(
14+
network: entity.network.networkString,
15+
useForFeeEstimation: entity.useForFeeEstimation,
16+
);
17+
}
18+
19+
@override
20+
bool operator ==(Object other) =>
21+
identical(this, other) ||
22+
other is MempoolSettingsDto &&
23+
runtimeType == other.runtimeType &&
24+
network == other.network &&
25+
useForFeeEstimation == other.useForFeeEstimation;
26+
27+
@override
28+
int get hashCode => network.hashCode ^ useForFeeEstimation.hashCode;
29+
30+
@override
31+
String toString() =>
32+
'MempoolSettingsDto(network: $network, useForFeeEstimation: $useForFeeEstimation)';
33+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
class DeleteCustomMempoolServerRequest {
2+
final bool isLiquid;
3+
4+
DeleteCustomMempoolServerRequest({
5+
required this.isLiquid,
6+
});
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
class LoadMempoolServerDataRequest {
2+
final bool isLiquid;
3+
4+
LoadMempoolServerDataRequest({
5+
required this.isLiquid,
6+
});
7+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class SetCustomMempoolServerRequest {
2+
final String url;
3+
final bool isLiquid;
4+
5+
SetCustomMempoolServerRequest({
6+
required this.url,
7+
required this.isLiquid,
8+
});
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class UpdateMempoolSettingsRequest {
2+
final bool isLiquid;
3+
final bool useForFeeEstimation;
4+
5+
UpdateMempoolSettingsRequest({
6+
required this.isLiquid,
7+
required this.useForFeeEstimation,
8+
});
9+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import 'package:bb_mobile/core/mempool/application/dtos/mempool_server_dto.dart';
2+
import 'package:bb_mobile/core/mempool/application/dtos/mempool_settings_dto.dart';
3+
4+
class LoadMempoolServerDataResponse {
5+
final MempoolServerDto defaultServer;
6+
final MempoolServerDto? customServer;
7+
final MempoolSettingsDto settings;
8+
9+
LoadMempoolServerDataResponse({
10+
required this.defaultServer,
11+
this.customServer,
12+
required this.settings,
13+
});
14+
15+
bool get hasCustomServer => customServer != null;
16+
17+
@override
18+
String toString() =>
19+
'LoadMempoolServerDataResponse(defaultServer: $defaultServer, customServer: $customServer, settings: $settings)';
20+
}

0 commit comments

Comments
 (0)