mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-01-18 16:44:32 +00:00
Merge branch 'staging' into dev
This commit is contained in:
commit
80005221b2
3 changed files with 48 additions and 74 deletions
|
@ -114,7 +114,6 @@ class ElectrumXClient {
|
||||||
required Prefs prefs,
|
required Prefs prefs,
|
||||||
required List<ElectrumXNode> failovers,
|
required List<ElectrumXNode> failovers,
|
||||||
Coin? coin,
|
Coin? coin,
|
||||||
JsonRPC? client,
|
|
||||||
this.connectionTimeoutForSpecialCaseJsonRPCClients =
|
this.connectionTimeoutForSpecialCaseJsonRPCClients =
|
||||||
const Duration(seconds: 60),
|
const Duration(seconds: 60),
|
||||||
TorService? torService,
|
TorService? torService,
|
||||||
|
@ -125,7 +124,6 @@ class ElectrumXClient {
|
||||||
_host = host;
|
_host = host;
|
||||||
_port = port;
|
_port = port;
|
||||||
_useSSL = useSSL;
|
_useSSL = useSSL;
|
||||||
_rpcClient = client;
|
|
||||||
_coin = coin;
|
_coin = coin;
|
||||||
|
|
||||||
final bus = globalEventBusForTesting ?? GlobalEventBus.instance;
|
final bus = globalEventBusForTesting ?? GlobalEventBus.instance;
|
||||||
|
@ -155,23 +153,10 @@ class ElectrumXClient {
|
||||||
// case TorStatus.disabled:
|
// case TorStatus.disabled:
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// might be ok to just reset/kill the current _jsonRpcClient
|
|
||||||
|
|
||||||
// since disconnecting is async and we want to ensure instant change over
|
|
||||||
// we will keep temp reference to current rpc client to call disconnect
|
|
||||||
// on before awaiting the disconnection future
|
|
||||||
|
|
||||||
final temp = _rpcClient;
|
|
||||||
|
|
||||||
// setting to null should force the creation of a new json rpc client
|
// setting to null should force the creation of a new json rpc client
|
||||||
// on the next request sent through this electrumx instance
|
// on the next request sent through this electrumx instance
|
||||||
_rpcClient = null;
|
|
||||||
_electrumAdapterChannel = null;
|
_electrumAdapterChannel = null;
|
||||||
_electrumAdapterClient = null;
|
_electrumAdapterClient = null;
|
||||||
|
|
||||||
await temp?.disconnect(
|
|
||||||
reason: "Tor status changed to \"${event.status}\"",
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -204,58 +189,6 @@ class ElectrumXClient {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _checkRpcClient() {
|
|
||||||
// If we're supposed to use Tor...
|
|
||||||
if (_prefs.useTor) {
|
|
||||||
// But Tor isn't running...
|
|
||||||
if (_torService.status != TorConnectionStatus.connected) {
|
|
||||||
// And the killswitch isn't set...
|
|
||||||
if (!_prefs.torKillSwitch) {
|
|
||||||
// Then we'll just proceed and connect to ElectrumX through clearnet at the bottom of this function.
|
|
||||||
Logging.instance.log(
|
|
||||||
"Tor preference set but Tor is not enabled, killswitch not set, connecting to ElectrumX through clearnet",
|
|
||||||
level: LogLevel.Warning,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// ... But if the killswitch is set, then we throw an exception.
|
|
||||||
throw Exception(
|
|
||||||
"Tor preference and killswitch set but Tor is not enabled, not connecting to ElectrumX");
|
|
||||||
// TODO [prio=low]: Try to start Tor.
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Get the proxy info from the TorService.
|
|
||||||
final proxyInfo = _torService.getProxyInfo();
|
|
||||||
|
|
||||||
if (currentFailoverIndex == -1) {
|
|
||||||
_rpcClient ??= JsonRPC(
|
|
||||||
host: host,
|
|
||||||
port: port,
|
|
||||||
useSSL: useSSL,
|
|
||||||
connectionTimeout: connectionTimeoutForSpecialCaseJsonRPCClients,
|
|
||||||
proxyInfo: proxyInfo,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
_rpcClient ??= JsonRPC(
|
|
||||||
host: failovers![currentFailoverIndex].address,
|
|
||||||
port: failovers![currentFailoverIndex].port,
|
|
||||||
useSSL: failovers![currentFailoverIndex].useSSL,
|
|
||||||
connectionTimeout: connectionTimeoutForSpecialCaseJsonRPCClients,
|
|
||||||
proxyInfo: proxyInfo,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_rpcClient!.proxyInfo != proxyInfo) {
|
|
||||||
_rpcClient!.proxyInfo = proxyInfo;
|
|
||||||
_rpcClient!.disconnect(
|
|
||||||
reason: "Tor proxyInfo does not match current info",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> checkElectrumAdapter() async {
|
Future<void> checkElectrumAdapter() async {
|
||||||
({InternetAddress host, int port})? proxyInfo;
|
({InternetAddress host, int port})? proxyInfo;
|
||||||
|
|
||||||
|
@ -402,6 +335,12 @@ class ElectrumXClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
currentFailoverIndex = -1;
|
currentFailoverIndex = -1;
|
||||||
|
|
||||||
|
// If the command is a ping, a good return should always be null.
|
||||||
|
if (command.contains("ping")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
} on WifiOnlyException {
|
} on WifiOnlyException {
|
||||||
rethrow;
|
rethrow;
|
||||||
|
@ -525,13 +464,23 @@ class ElectrumXClient {
|
||||||
/// Returns true if ping succeeded
|
/// Returns true if ping succeeded
|
||||||
Future<bool> ping({String? requestID, int retryCount = 1}) async {
|
Future<bool> ping({String? requestID, int retryCount = 1}) async {
|
||||||
try {
|
try {
|
||||||
final response = await request(
|
// This doesn't work because electrum_adapter only returns the result:
|
||||||
|
// (which is always `null`).
|
||||||
|
// await checkElectrumAdapter();
|
||||||
|
// final response = await electrumAdapterClient!
|
||||||
|
// .ping()
|
||||||
|
// .timeout(const Duration(seconds: 2));
|
||||||
|
// return (response as Map<String, dynamic>).isNotEmpty;
|
||||||
|
|
||||||
|
// Because request() has been updated to use electrum_adapter, and because
|
||||||
|
// electrum_adapter returns the result of the request, request() has been
|
||||||
|
// updated to return a bool on a server.ping command as a special case.
|
||||||
|
return await request(
|
||||||
requestID: requestID,
|
requestID: requestID,
|
||||||
command: 'server.ping',
|
command: 'server.ping',
|
||||||
requestTimeout: const Duration(seconds: 2),
|
requestTimeout: const Duration(seconds: 2),
|
||||||
retries: retryCount,
|
retries: retryCount,
|
||||||
).timeout(const Duration(seconds: 2)) as Map<String, dynamic>;
|
).timeout(const Duration(seconds: 2)) as bool;
|
||||||
return response.isNotEmpty; // TODO [prio=extreme]: Fix this.
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import 'package:coinlib_flutter/coinlib_flutter.dart' as coinlib;
|
||||||
import 'package:electrum_adapter/electrum_adapter.dart' as electrum_adapter;
|
import 'package:electrum_adapter/electrum_adapter.dart' as electrum_adapter;
|
||||||
import 'package:electrum_adapter/electrum_adapter.dart';
|
import 'package:electrum_adapter/electrum_adapter.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
|
import 'package:mutex/mutex.dart';
|
||||||
import 'package:stackwallet/electrumx_rpc/cached_electrumx_client.dart';
|
import 'package:stackwallet/electrumx_rpc/cached_electrumx_client.dart';
|
||||||
import 'package:stackwallet/electrumx_rpc/electrumx_chain_height_service.dart';
|
import 'package:stackwallet/electrumx_rpc/electrumx_chain_height_service.dart';
|
||||||
import 'package:stackwallet/electrumx_rpc/electrumx_client.dart';
|
import 'package:stackwallet/electrumx_rpc/electrumx_client.dart';
|
||||||
|
@ -16,6 +17,9 @@ import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2
|
||||||
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
||||||
import 'package:stackwallet/models/paymint/fee_object_model.dart';
|
import 'package:stackwallet/models/paymint/fee_object_model.dart';
|
||||||
import 'package:stackwallet/models/signing_data.dart';
|
import 'package:stackwallet/models/signing_data.dart';
|
||||||
|
import 'package:stackwallet/services/event_bus/events/global/tor_connection_status_changed_event.dart';
|
||||||
|
import 'package:stackwallet/services/event_bus/events/global/tor_status_changed_event.dart';
|
||||||
|
import 'package:stackwallet/services/event_bus/global_event_bus.dart';
|
||||||
import 'package:stackwallet/services/tor_service.dart';
|
import 'package:stackwallet/services/tor_service.dart';
|
||||||
import 'package:stackwallet/utilities/amount/amount.dart';
|
import 'package:stackwallet/utilities/amount/amount.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
|
@ -32,9 +36,6 @@ import 'package:stackwallet/wallets/wallet/intermediate/bip39_hd_wallet.dart';
|
||||||
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/paynym_interface.dart';
|
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/paynym_interface.dart';
|
||||||
import 'package:stream_channel/stream_channel.dart';
|
import 'package:stream_channel/stream_channel.dart';
|
||||||
|
|
||||||
import '../../../services/event_bus/events/global/tor_connection_status_changed_event.dart';
|
|
||||||
import '../../../services/event_bus/events/global/tor_status_changed_event.dart';
|
|
||||||
|
|
||||||
mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
|
mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
|
||||||
late ElectrumXClient electrumXClient;
|
late ElectrumXClient electrumXClient;
|
||||||
late StreamChannel electrumAdapterChannel;
|
late StreamChannel electrumAdapterChannel;
|
||||||
|
@ -46,6 +47,11 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
|
||||||
|
|
||||||
StreamSubscription<TorPreferenceChangedEvent>? _torPreferenceListener;
|
StreamSubscription<TorPreferenceChangedEvent>? _torPreferenceListener;
|
||||||
StreamSubscription<TorConnectionStatusChangedEvent>? _torStatusListener;
|
StreamSubscription<TorConnectionStatusChangedEvent>? _torStatusListener;
|
||||||
|
final Mutex _torConnectingLock = Mutex();
|
||||||
|
bool _requireMutex = false;
|
||||||
|
Timer? _aliveTimer;
|
||||||
|
static const Duration _keepAlive = Duration(minutes: 1);
|
||||||
|
bool _isConnected = false;
|
||||||
|
|
||||||
static const _kServerBatchCutoffVersion = [1, 6];
|
static const _kServerBatchCutoffVersion = [1, 6];
|
||||||
List<int>? _serverVersion;
|
List<int>? _serverVersion;
|
||||||
|
@ -893,6 +899,16 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
final newNode = await getCurrentElectrumXNode();
|
final newNode = await getCurrentElectrumXNode();
|
||||||
|
try {
|
||||||
|
await electrumXClient.electrumAdapterClient?.close();
|
||||||
|
} catch (e, s) {
|
||||||
|
if (e.toString().contains("initialized")) {
|
||||||
|
// Ignore. This should happen every first time the wallet is opened.
|
||||||
|
} else {
|
||||||
|
Logging.instance
|
||||||
|
.log("Error closing electrumXClient: $e", level: LogLevel.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
electrumXClient = ElectrumXClient.from(
|
electrumXClient = ElectrumXClient.from(
|
||||||
node: newNode,
|
node: newNode,
|
||||||
prefs: prefs,
|
prefs: prefs,
|
||||||
|
@ -943,6 +959,15 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
|
||||||
// host: newNode.address, port: newNode.port);
|
// host: newNode.address, port: newNode.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Update the connection status and call the onConnectionStatusChanged callback if it exists.
|
||||||
|
void _updateConnectionStatus(bool connectionStatus) {
|
||||||
|
// TODO [prio=low]: Set onConnectionStatusChanged callback.
|
||||||
|
// if (_isConnected != connectionStatus && onConnectionStatusChanged != null) {
|
||||||
|
// onConnectionStatusChanged!(connectionStatus);
|
||||||
|
// }
|
||||||
|
_isConnected = connectionStatus;
|
||||||
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
Future<({List<Address> addresses, int index})> checkGapsBatched(
|
Future<({List<Address> addresses, int index})> checkGapsBatched(
|
||||||
|
|
|
@ -11,7 +11,7 @@ description: Stack Wallet
|
||||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||||
# Read more about iOS versioning at
|
# Read more about iOS versioning at
|
||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
version: 1.9.3+204
|
version: 1.10.0+206
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=3.0.2 <4.0.0"
|
sdk: ">=3.0.2 <4.0.0"
|
||||||
|
|
Loading…
Reference in a new issue