mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-04-14 17:21:55 +00:00
decred: Add sync.
This commit is contained in:
parent
2b808ad50a
commit
0328f9afb4
7 changed files with 248 additions and 20 deletions
cw_core/lib
cw_decred/lib
lib
entities
store
view_model/node_list
|
@ -287,8 +287,20 @@ class Node extends HiveObject with Keyable {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> requestDecredNode() async {
|
||||
final decredMainnetPort = 9108;
|
||||
if (uri.host == "" && uri.port == decredMainnetPort) {
|
||||
// Just show default port as ok. The wallet will connect to a list of known
|
||||
// nodes automatically.
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
final socket = await Socket.connect(uri.host, uri.port, timeout: Duration(seconds: 5));
|
||||
socket.destroy();
|
||||
return true;
|
||||
} catch (_) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,11 +19,10 @@ final dcrwalletApi = libdcrwallet(DynamicLibrary.open(libraryName));
|
|||
/// a wallet.
|
||||
void initLibdcrwallet(String logDir) {
|
||||
final cLogDir = logDir.toCString();
|
||||
final res = executePayloadFn(
|
||||
executePayloadFn(
|
||||
fn: () => dcrwalletApi.initialize(cLogDir),
|
||||
ptrsToFree: [cLogDir],
|
||||
);
|
||||
print(res.payload);
|
||||
}
|
||||
|
||||
/// createWalletAsync calls the libdcrwallet's createWallet function
|
||||
|
@ -46,11 +45,10 @@ void createWalletSync(Map<String, String> args) {
|
|||
final password = args["password"]!.toCString();
|
||||
final network = "testnet".toCString();
|
||||
|
||||
final res = executePayloadFn(
|
||||
executePayloadFn(
|
||||
fn: () => dcrwalletApi.createWallet(name, dataDir, network, password),
|
||||
ptrsToFree: [name, dataDir, network, password],
|
||||
);
|
||||
print(res.payload);
|
||||
}
|
||||
|
||||
/// loadWalletAsync calls the libdcrwallet's loadWallet function asynchronously.
|
||||
|
@ -67,15 +65,35 @@ void loadWalletSync(Map<String, String> args) {
|
|||
final name = args["name"]!.toCString();
|
||||
final dataDir = args["dataDir"]!.toCString();
|
||||
final network = "testnet".toCString();
|
||||
final res = executePayloadFn(
|
||||
executePayloadFn(
|
||||
fn: () => dcrwalletApi.loadWallet(name, dataDir, network),
|
||||
ptrsToFree: [name, dataDir, network],
|
||||
);
|
||||
print(res.payload);
|
||||
}
|
||||
|
||||
Future<void> startSyncAsync({required String name, required String peers}) {
|
||||
final args = <String, String>{
|
||||
"name": name,
|
||||
"peers": peers,
|
||||
};
|
||||
return compute(startSync, args);
|
||||
}
|
||||
|
||||
void startSync(Map<String, String> args) {
|
||||
final name = args["name"]!.toCString();
|
||||
final peers = args["peers"]!.toCString();
|
||||
executePayloadFn(
|
||||
fn: () => dcrwalletApi.syncWallet(name, peers),
|
||||
ptrsToFree: [name, peers],
|
||||
);
|
||||
}
|
||||
|
||||
void closeWallet(String walletName) {
|
||||
// TODO.
|
||||
final name = walletName.toCString();
|
||||
executePayloadFn(
|
||||
fn: () => dcrwalletApi.closeWallet(name),
|
||||
ptrsToFree: [name],
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> changeWalletPassword(
|
||||
|
@ -110,6 +128,15 @@ String? currentReceiveAddress(String walletName) {
|
|||
return res.payload;
|
||||
}
|
||||
|
||||
String syncStatus(String walletName) {
|
||||
final cName = walletName.toCString();
|
||||
final res = executePayloadFn(
|
||||
fn: () => dcrwalletApi.syncWalletStatus(cName),
|
||||
ptrsToFree: [cName],
|
||||
);
|
||||
return res.payload;
|
||||
}
|
||||
|
||||
Map balance(String walletName) {
|
||||
final cName = walletName.toCString();
|
||||
final res = executePayloadFn(
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'package:cw_core/transaction_direction.dart';
|
||||
import 'package:cw_decred/pending_transaction.dart';
|
||||
|
@ -38,9 +40,10 @@ abstract class DecredWalletBase extends WalletBase<DecredBalance,
|
|||
// password is currently only used for seed display, but would likely also be
|
||||
// required to sign inputs when creating transactions.
|
||||
final String _password;
|
||||
bool connecting = false;
|
||||
String persistantPeer = "";
|
||||
Timer? syncTimer;
|
||||
|
||||
// TODO: Set up a way to change the balance and sync status when dcrlibwallet
|
||||
// changes. Long polling probably?
|
||||
@override
|
||||
@observable
|
||||
SyncStatus syncStatus;
|
||||
|
@ -65,19 +68,138 @@ abstract class DecredWalletBase extends WalletBase<DecredBalance,
|
|||
|
||||
Future<void> init() async {
|
||||
updateBalance();
|
||||
// TODO: update other wallet properties such as syncStatus, walletAddresses
|
||||
// and transactionHistory with data from libdcrwallet.
|
||||
}
|
||||
|
||||
void performBackgroundTasks() {
|
||||
if (!checkSync()) {
|
||||
return;
|
||||
}
|
||||
updateBalance();
|
||||
}
|
||||
|
||||
bool checkSync() {
|
||||
final syncStatusJSON = libdcrwallet.syncStatus(walletInfo.name);
|
||||
final decoded = json.decode(syncStatusJSON);
|
||||
|
||||
final syncStatusCode = decoded["syncstatuscode"] ?? 0;
|
||||
final syncStatusStr = decoded["syncstatus"] ?? "";
|
||||
final targetHeight = decoded["targetheight"] ?? 1;
|
||||
final numPeers = decoded["numpeers"] ?? 0;
|
||||
// final cFiltersHeight = decoded["cfiltersheight"] ?? 0;
|
||||
final headersHeight = decoded["headersheight"] ?? 0;
|
||||
final rescanHeight = decoded["rescanheight"] ?? 0;
|
||||
|
||||
if (numPeers == 0) {
|
||||
syncStatus = NotConnectedSyncStatus();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Sync codes:
|
||||
// NotStarted = 0
|
||||
// FetchingCFilters = 1
|
||||
// FetchingHeaders = 2
|
||||
// DiscoveringAddrs = 3
|
||||
// Rescanning = 4
|
||||
// Complete = 5
|
||||
|
||||
if (syncStatusCode > 4) {
|
||||
syncStatus = SyncedSyncStatus();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (syncStatusCode == 0) {
|
||||
syncStatus = ConnectedSyncStatus();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (syncStatusCode == 1) {
|
||||
syncStatus = SyncingSyncStatus(targetHeight, 0.0);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (syncStatusCode == 2) {
|
||||
final headersProg = headersHeight / targetHeight;
|
||||
// Only allow headers progress to go up half way.
|
||||
syncStatus =
|
||||
SyncingSyncStatus(targetHeight - headersHeight, headersProg / 2);
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: This step takes a while so should really get more info to the UI
|
||||
// that we are discovering addresses.
|
||||
if (syncStatusCode == 3) {
|
||||
// Hover at half.
|
||||
syncStatus = SyncingSyncStatus(0, .5);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (syncStatusCode == 4) {
|
||||
// Start at 75%.
|
||||
final rescanProg = rescanHeight / targetHeight / 4;
|
||||
syncStatus =
|
||||
SyncingSyncStatus(targetHeight - rescanHeight, .75 + rescanProg);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@action
|
||||
@override
|
||||
Future<void> connectToNode({required Node node}) async {
|
||||
//throw UnimplementedError();
|
||||
if (connecting) {
|
||||
throw "decred already connecting";
|
||||
}
|
||||
connecting = true;
|
||||
String addr = "";
|
||||
if (node.uri.host != "") {
|
||||
addr = node.uri.host;
|
||||
if (node.uri.port != "") {
|
||||
addr += ":" + node.uri.port.toString();
|
||||
}
|
||||
}
|
||||
if (addr != persistantPeer) {
|
||||
if (syncTimer != null) {
|
||||
syncTimer!.cancel();
|
||||
syncTimer = null;
|
||||
}
|
||||
persistantPeer = addr;
|
||||
libdcrwallet.closeWallet(walletInfo.name);
|
||||
libdcrwallet.loadWalletSync({
|
||||
"name": walletInfo.name,
|
||||
"dataDir": walletInfo.dirPath,
|
||||
});
|
||||
}
|
||||
await this._startSync();
|
||||
connecting = false;
|
||||
}
|
||||
|
||||
@action
|
||||
@override
|
||||
Future<void> startSync() async {
|
||||
// TODO: call libdcrwallet.spvSync() and update syncStatus.
|
||||
if (connecting) {
|
||||
throw "decred already connecting";
|
||||
}
|
||||
connecting = true;
|
||||
await this._startSync();
|
||||
connecting = false;
|
||||
}
|
||||
|
||||
Future<void> _startSync() async {
|
||||
if (syncTimer != null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
syncStatus = ConnectingSyncStatus();
|
||||
libdcrwallet.startSyncAsync(
|
||||
name: walletInfo.name,
|
||||
peers: persistantPeer,
|
||||
);
|
||||
syncTimer = Timer.periodic(
|
||||
Duration(seconds: 5), (Timer t) => performBackgroundTasks());
|
||||
} catch (e) {
|
||||
print(e.toString());
|
||||
syncStatus = FailedSyncStatus();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -134,6 +256,10 @@ abstract class DecredWalletBase extends WalletBase<DecredBalance,
|
|||
|
||||
@override
|
||||
void close() {
|
||||
if (syncTimer != null) {
|
||||
syncTimer!.cancel();
|
||||
syncTimer = null;
|
||||
}
|
||||
libdcrwallet.closeWallet(walletInfo.name);
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ const tronDefaultNodeUri = 'api.trongrid.io';
|
|||
const newCakeWalletBitcoinUri = 'btc-electrum.cakewallet.com:50002';
|
||||
const wowneroDefaultNodeUri = 'node3.monerodevs.org:34568';
|
||||
const moneroWorldNodeUri = '.moneroworld.com';
|
||||
const decredDefaultUri = ":9108";
|
||||
|
||||
Future<void> defaultSettingsMigration(
|
||||
{required int version,
|
||||
|
@ -95,6 +96,7 @@ Future<void> defaultSettingsMigration(
|
|||
PreferencesKey.currentBalanceDisplayModeKey, BalanceDisplayMode.availableBalance.raw);
|
||||
await sharedPreferences.setBool('save_recipient_address', true);
|
||||
await resetToDefault(nodes);
|
||||
await setDefaultDecredNodeKey(sharedPreferences, nodes);
|
||||
await changeMoneroCurrentNodeToDefault(
|
||||
sharedPreferences: sharedPreferences, nodes: nodes);
|
||||
await changeBitcoinCurrentElectrumServerToDefault(
|
||||
|
@ -647,6 +649,11 @@ Node? getNanoDefaultNode({required Box<Node> nodes}) {
|
|||
nodes.values.firstWhereOrNull((node) => node.type == WalletType.nano);
|
||||
}
|
||||
|
||||
Node? getDecredDefaultNode({required Box<Node> nodes}) {
|
||||
return nodes.values.firstWhereOrNull((Node node) => node.uriRaw == decredDefaultUri) ??
|
||||
nodes.values.firstWhereOrNull((node) => (node.type == WalletType.decred));
|
||||
}
|
||||
|
||||
Node? getNanoDefaultPowNode({required Box<Node> nodes}) {
|
||||
return nodes.values.firstWhereOrNull((Node node) => node.uriRaw == nanoDefaultPowNodeUri) ??
|
||||
nodes.values.firstWhereOrNull((node) => (node.type == WalletType.nano));
|
||||
|
@ -812,6 +819,18 @@ Future<void> rewriteSecureStoragePin({required SecureStorage secureStorage}) asy
|
|||
);
|
||||
}
|
||||
|
||||
// If "node_list.resetToDefault" is called the old node.key will still be set in
|
||||
// preferences. Set it to whatever it is now.
|
||||
//
|
||||
// TODO: There really isn't any reason to have a default node for decred, find
|
||||
// a different way to handle this.
|
||||
Future<void> setDefaultDecredNodeKey(
|
||||
SharedPreferences sharedPreferences, Box<Node> nodeSource) async {
|
||||
final node = nodeSource.values.firstWhere((node) => node.type == WalletType.decred);
|
||||
await sharedPreferences.setInt(
|
||||
PreferencesKey.currentDecredNodeIdKey, node.key as int);
|
||||
}
|
||||
|
||||
Future<void> changeBitcoinCurrentElectrumServerToDefault(
|
||||
{required SharedPreferences sharedPreferences,
|
||||
required Box<Node> nodes,
|
||||
|
@ -1149,6 +1168,7 @@ Future<void> checkCurrentNodes(
|
|||
final currentPolygonNodeId = sharedPreferences.getInt(PreferencesKey.currentPolygonNodeIdKey);
|
||||
final currentNanoNodeId = sharedPreferences.getInt(PreferencesKey.currentNanoNodeIdKey);
|
||||
final currentNanoPowNodeId = sharedPreferences.getInt(PreferencesKey.currentNanoPowNodeIdKey);
|
||||
final currentDecredNodeId = sharedPreferences.getInt(PreferencesKey.currentDecredNodeIdKey);
|
||||
final currentBitcoinCashNodeId =
|
||||
sharedPreferences.getInt(PreferencesKey.currentBitcoinCashNodeIdKey);
|
||||
final currentSolanaNodeId = sharedPreferences.getInt(PreferencesKey.currentSolanaNodeIdKey);
|
||||
|
@ -1168,6 +1188,8 @@ Future<void> checkCurrentNodes(
|
|||
nodeSource.values.firstWhereOrNull((node) => node.key == currentPolygonNodeId);
|
||||
final currentNanoNodeServer =
|
||||
nodeSource.values.firstWhereOrNull((node) => node.key == currentNanoNodeId);
|
||||
final currentDecredNodeServer =
|
||||
nodeSource.values.firstWhereOrNull((node) => node.key == currentDecredNodeId);
|
||||
final currentNanoPowNodeServer =
|
||||
powNodeSource.values.firstWhereOrNull((node) => node.key == currentNanoPowNodeId);
|
||||
final currentBitcoinCashNodeServer =
|
||||
|
@ -1261,6 +1283,14 @@ Future<void> checkCurrentNodes(
|
|||
await nodeSource.add(node);
|
||||
await sharedPreferences.setInt(PreferencesKey.currentWowneroNodeIdKey, node.key as int);
|
||||
}
|
||||
|
||||
if (currentDecredNodeServer == null) {
|
||||
final decredMainnetPort = ":9108";
|
||||
final node = Node(uri: decredDefaultUri, type: WalletType.decred);
|
||||
await nodeSource.add(node);
|
||||
await sharedPreferences.setInt(
|
||||
PreferencesKey.currentDecredNodeIdKey, node.key as int);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> resetBitcoinElectrumServer(
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:flutter/services.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import "package:yaml/yaml.dart";
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:cw_core/node.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
|
||||
|
@ -200,6 +201,12 @@ Future<List<Node>> loadDefaultWowneroNodes() async {
|
|||
return nodes;
|
||||
}
|
||||
|
||||
Future<List<Node>> loadDefaultDecredNodes() async {
|
||||
final decredMainnetPort = ":9108";
|
||||
final node = Node(uri: decredMainnetPort, type: WalletType.decred);
|
||||
return <Node>[node];
|
||||
}
|
||||
|
||||
Future<void> resetToDefault(Box<Node> nodeSource) async {
|
||||
final moneroNodes = await loadDefaultNodes();
|
||||
final bitcoinElectrumServerList = await loadBitcoinElectrumServerList();
|
||||
|
@ -211,6 +218,7 @@ Future<void> resetToDefault(Box<Node> nodeSource) async {
|
|||
final polygonNodes = await loadDefaultPolygonNodes();
|
||||
final solanaNodes = await loadDefaultSolanaNodes();
|
||||
final tronNodes = await loadDefaultTronNodes();
|
||||
final decredNodes = await loadDefaultDecredNodes();
|
||||
|
||||
final nodes = moneroNodes +
|
||||
bitcoinElectrumServerList +
|
||||
|
@ -220,7 +228,9 @@ Future<void> resetToDefault(Box<Node> nodeSource) async {
|
|||
bitcoinCashElectrumServerList +
|
||||
nanoNodes +
|
||||
polygonNodes +
|
||||
solanaNodes + tronNodes;
|
||||
solanaNodes +
|
||||
tronNodes +
|
||||
decredNodes;
|
||||
|
||||
await nodeSource.clear();
|
||||
await nodeSource.addAll(nodes);
|
||||
|
|
|
@ -816,11 +816,6 @@ abstract class SettingsStoreBase with Store {
|
|||
Node getCurrentNode(WalletType walletType) {
|
||||
final node = nodes[walletType];
|
||||
|
||||
// TODO: Implement connecting to a user's preferred node.
|
||||
if (walletType == WalletType.decred) {
|
||||
return Node();
|
||||
}
|
||||
|
||||
if (node == null) {
|
||||
throw Exception('No node found for wallet type: ${walletType.toString()}');
|
||||
}
|
||||
|
@ -1007,6 +1002,7 @@ abstract class SettingsStoreBase with Store {
|
|||
final solanaNodeId = sharedPreferences.getInt(PreferencesKey.currentSolanaNodeIdKey);
|
||||
final tronNodeId = sharedPreferences.getInt(PreferencesKey.currentTronNodeIdKey);
|
||||
final wowneroNodeId = sharedPreferences.getInt(PreferencesKey.currentWowneroNodeIdKey);
|
||||
final decredNodeId = sharedPreferences.getInt(PreferencesKey.currentDecredNodeIdKey);
|
||||
final moneroNode = nodeSource.get(nodeId);
|
||||
final bitcoinElectrumServer = nodeSource.get(bitcoinElectrumServerId);
|
||||
final litecoinElectrumServer = nodeSource.get(litecoinElectrumServerId);
|
||||
|
@ -1015,6 +1011,7 @@ abstract class SettingsStoreBase with Store {
|
|||
final polygonNode = nodeSource.get(polygonNodeId);
|
||||
final bitcoinCashElectrumServer = nodeSource.get(bitcoinCashElectrumServerId);
|
||||
final nanoNode = nodeSource.get(nanoNodeId);
|
||||
final decredNode = nodeSource.get(decredNodeId);
|
||||
final nanoPowNode = powNodeSource.get(nanoPowNodeId);
|
||||
final solanaNode = nodeSource.get(solanaNodeId);
|
||||
final tronNode = nodeSource.get(tronNodeId);
|
||||
|
@ -1100,6 +1097,10 @@ abstract class SettingsStoreBase with Store {
|
|||
nodes[WalletType.wownero] = wowneroNode;
|
||||
}
|
||||
|
||||
if (decredNode != null) {
|
||||
nodes[WalletType.decred] = decredNode;
|
||||
}
|
||||
|
||||
final savedSyncMode = SyncMode.all.firstWhere((element) {
|
||||
return element.type.index == (sharedPreferences.getInt(PreferencesKey.syncModeKey) ?? 0);
|
||||
});
|
||||
|
@ -1334,6 +1335,11 @@ abstract class SettingsStoreBase with Store {
|
|||
priority[WalletType.bitcoinCash] = bitcoinCash!.deserializeBitcoinCashTransactionPriority(
|
||||
sharedPreferences.getInt(PreferencesKey.bitcoinCashTransactionPriority)!);
|
||||
}
|
||||
if (decred != null &&
|
||||
sharedPreferences.getInt(PreferencesKey.decredTransactionPriority) != null) {
|
||||
priority[WalletType.decred] = decred!.deserializeDecredTransactionPriority(
|
||||
sharedPreferences.getInt(PreferencesKey.decredTransactionPriority)!);
|
||||
}
|
||||
|
||||
final generateSubaddresses =
|
||||
sharedPreferences.getInt(PreferencesKey.autoGenerateSubaddressStatusKey);
|
||||
|
@ -1442,6 +1448,7 @@ abstract class SettingsStoreBase with Store {
|
|||
final solanaNodeId = sharedPreferences.getInt(PreferencesKey.currentSolanaNodeIdKey);
|
||||
final tronNodeId = sharedPreferences.getInt(PreferencesKey.currentTronNodeIdKey);
|
||||
final wowneroNodeId = sharedPreferences.getInt(PreferencesKey.currentWowneroNodeIdKey);
|
||||
final decredNodeId = sharedPreferences.getInt(PreferencesKey.currentDecredNodeIdKey);
|
||||
final moneroNode = nodeSource.get(nodeId);
|
||||
final bitcoinElectrumServer = nodeSource.get(bitcoinElectrumServerId);
|
||||
final litecoinElectrumServer = nodeSource.get(litecoinElectrumServerId);
|
||||
|
@ -1453,6 +1460,7 @@ abstract class SettingsStoreBase with Store {
|
|||
final solanaNode = nodeSource.get(solanaNodeId);
|
||||
final tronNode = nodeSource.get(tronNodeId);
|
||||
final wowneroNode = nodeSource.get(wowneroNodeId);
|
||||
final decredNode = nodeSource.get(decredNodeId);
|
||||
if (moneroNode != null) {
|
||||
nodes[WalletType.monero] = moneroNode;
|
||||
}
|
||||
|
@ -1497,6 +1505,10 @@ abstract class SettingsStoreBase with Store {
|
|||
nodes[WalletType.wownero] = wowneroNode;
|
||||
}
|
||||
|
||||
if (decredNode != null) {
|
||||
nodes[WalletType.decred] = decredNode;
|
||||
}
|
||||
|
||||
// MIGRATED:
|
||||
|
||||
useTOTP2FA = await SecureKey.getBool(
|
||||
|
@ -1633,6 +1645,9 @@ abstract class SettingsStoreBase with Store {
|
|||
case WalletType.wownero:
|
||||
await _sharedPreferences.setInt(PreferencesKey.currentWowneroNodeIdKey, node.key as int);
|
||||
break;
|
||||
case WalletType.decred:
|
||||
await _sharedPreferences.setInt(PreferencesKey.currentDecredNodeIdKey, node.key as int);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@ import 'package:cake_wallet/store/settings_store.dart';
|
|||
import 'package:cw_core/node.dart';
|
||||
import 'package:cake_wallet/entities/node_list.dart';
|
||||
import 'package:cake_wallet/entities/default_settings_migration.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
|
||||
part 'node_list_view_model.g.dart';
|
||||
|
@ -47,6 +49,9 @@ abstract class NodeListViewModelBase with Store {
|
|||
|
||||
Future<void> reset() async {
|
||||
await resetToDefault(_nodeSource);
|
||||
final decredNode = getDecredDefaultNode(nodes: _nodeSource)!;
|
||||
final sharedPrefs = getIt.get<SharedPreferences>();
|
||||
await setDefaultDecredNodeKey(sharedPrefs, _nodeSource);
|
||||
|
||||
Node node;
|
||||
|
||||
|
@ -88,6 +93,9 @@ abstract class NodeListViewModelBase with Store {
|
|||
case WalletType.wownero:
|
||||
node = getWowneroDefaultNode(nodes: _nodeSource);
|
||||
break;
|
||||
case WalletType.decred:
|
||||
node = decredNode;
|
||||
break;
|
||||
default:
|
||||
throw Exception('Unexpected wallet type: ${_appStore.wallet!.type}');
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue