11import 'dart:convert' ;
2- import 'dart:io' show SecureSocket;
2+ import 'dart:io' show SecureSocket, Socket ;
33
4+ import 'package:bb_mobile/core/electrum/domain/value_objects/electrum_connection.dart' ;
45import 'package:bb_mobile/core/storage/sqlite_database.dart' ;
56import 'package:bb_mobile/core/utils/bitcoin_tx.dart' ;
67import 'package:convert/convert.dart' ;
@@ -11,7 +12,7 @@ class ElectrumRemoteDatasource {
1112 ElectrumRemoteDatasource ({required this ._sqlite});
1213
1314 Future <TransactionModel > fetch ({
14- required String serverUrl ,
15+ required ElectrumConnection connection ,
1516 required String txid,
1617 }) async {
1718 final cachedTransaction = await _sqlite.managers.transactions
@@ -20,7 +21,7 @@ class ElectrumRemoteDatasource {
2021
2122 if (cachedTransaction != null ) return cachedTransaction;
2223
23- final txBytes = await _getTransaction (Uri . parse (serverUrl) , txid);
24+ final txBytes = await _getTransaction (connection , txid);
2425 final tx = await BitcoinTx .fromBytes (txBytes);
2526
2627 final txModel = TransactionModel (
@@ -37,9 +38,12 @@ class ElectrumRemoteDatasource {
3738 return txModel;
3839 }
3940
40- Future <List <int >> _getTransaction (Uri serverUri, String txid) async {
41+ Future <List <int >> _getTransaction (
42+ ElectrumConnection connection,
43+ String txid,
44+ ) async {
4145 try {
42- final socket = await SecureSocket . connect (serverUri.host, serverUri.port );
46+ final socket = await _connect (connection );
4347
4448 final request = {
4549 'id' : 1 ,
@@ -58,4 +62,36 @@ class ElectrumRemoteDatasource {
5862 throw Exception ('Electrum RPC error: $e ' );
5963 }
6064 }
65+
66+ /// Opens the socket described by the resolved [connection] rather than
67+ /// assuming a CA-validated TLS endpoint.
68+ ///
69+ /// A `tcp://` server is reached in the clear, and certificates are validated
70+ /// according to the user's `validateDomain` setting — the very flag the
71+ /// BDK/LWK sync obeys — so a personal node with a self-signed certificate
72+ /// behaves the same on both paths instead of syncing fine but failing here.
73+ Future <Socket > _connect (ElectrumConnection connection) {
74+ final uri = _parseUrl (connection.url);
75+ final timeout = Duration (seconds: connection.timeout);
76+
77+ if (uri.scheme == 'tcp' ) {
78+ return Socket .connect (uri.host, uri.port, timeout: timeout);
79+ }
80+
81+ return SecureSocket .connect (
82+ uri.host,
83+ uri.port,
84+ timeout: timeout,
85+ onBadCertificate: connection.validateDomain ? null : (_) => true ,
86+ );
87+ }
88+
89+ /// Servers are stored either with an explicit `ssl://` / `tcp://` scheme or
90+ /// as a bare `host:port` (how Liquid urls are persisted), which `Uri.parse`
91+ /// would otherwise read as the scheme. Bare urls default to TLS, matching
92+ /// the rest of the electrum module.
93+ Uri _parseUrl (String url) =>
94+ url.startsWith ('ssl://' ) || url.startsWith ('tcp://' )
95+ ? Uri .parse (url)
96+ : Uri .parse ('ssl://$url ' );
6197}
0 commit comments