mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-26 06:08:40 +01:00
Rebase node-sqlite-migration onto dev
Squashed migration of node Hive→SQLite, default-node handling, isPow/proxy support, arbitrum node updates, and related fixes. Replays node-sqlite-migration on top of current dev without the amount-refactor merge that the original branch carried. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,10 +5,11 @@ import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/utils/permission_handler.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:cw_core/node.dart';
|
||||
import 'package:cake_wallet/view_model/node_list/node_list_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/node_list/pow_node_list_view_model.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
|
||||
@@ -19,7 +20,7 @@ class NodeCreateOrEditViewModel = NodeCreateOrEditViewModelBase
|
||||
|
||||
abstract class NodeCreateOrEditViewModelBase with Store {
|
||||
NodeCreateOrEditViewModelBase(
|
||||
this._nodeSource, this.walletType, this.editingNode, this._settingsStore)
|
||||
this.isPow, this.nodeListViewModel,this.powNodeListViewModel, this.walletType, this._settingsStore, {this.editingNode})
|
||||
: state = InitialExecutionState(),
|
||||
connectionState = InitialExecutionState(),
|
||||
label = editingNode?.label ?? '',
|
||||
@@ -36,8 +37,7 @@ abstract class NodeCreateOrEditViewModelBase with Store {
|
||||
editingNode?.isEnabledForAutoSwitching ?? false,
|
||||
useSocksProxy = editingNode?.socksProxyAddress != null &&
|
||||
editingNode!.socksProxyAddress!.isNotEmpty,
|
||||
useSSL = editingNode?.useSSL ?? false {
|
||||
}
|
||||
useSSL = editingNode?.useSSL ?? false {}
|
||||
|
||||
final nodeLabelUIKey = 'node_label_row_key';
|
||||
final nodeAddressUIKey = 'node_address_row_key';
|
||||
@@ -110,6 +110,15 @@ abstract class NodeCreateOrEditViewModelBase with Store {
|
||||
@observable
|
||||
String socksProxyAddress;
|
||||
|
||||
@observable
|
||||
Node? editingNode;
|
||||
|
||||
@observable
|
||||
bool isPow;
|
||||
|
||||
final NodeListViewModel? nodeListViewModel;
|
||||
final PowNodeListViewModel? powNodeListViewModel;
|
||||
|
||||
@computed
|
||||
bool get isReady =>
|
||||
(address.isNotEmpty) ||
|
||||
@@ -158,8 +167,6 @@ abstract class NodeCreateOrEditViewModelBase with Store {
|
||||
}
|
||||
|
||||
final WalletType walletType;
|
||||
final Node? editingNode;
|
||||
final Box<Node> _nodeSource;
|
||||
final SettingsStore _settingsStore;
|
||||
|
||||
void updateViewModelFromText(String key, String value) {
|
||||
@@ -248,33 +255,45 @@ abstract class NodeCreateOrEditViewModelBase with Store {
|
||||
void setSocksProxyAddress(String val) => socksProxyAddress = val;
|
||||
|
||||
@action
|
||||
Future<void> save({Node? editingNode, bool saveAsCurrent = false}) async {
|
||||
final node = Node(
|
||||
label: label,
|
||||
uri: uri,
|
||||
path: path,
|
||||
type: walletType,
|
||||
login: login,
|
||||
password: password,
|
||||
useSSL: useSSL,
|
||||
trusted: trusted,
|
||||
isEnabledForAutoSwitching: isEnabledForAutoSwitching,
|
||||
socksProxyAddress: socksProxyAddress);
|
||||
Future<void> delete({required Node editingNode}) async {
|
||||
await editingNode.delete();
|
||||
if(nodeListViewModel != null) {
|
||||
nodeListViewModel!.bindNodes();
|
||||
}
|
||||
if(powNodeListViewModel != null) {
|
||||
powNodeListViewModel!.bindNodes();
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
Future<void> save({bool saveAsCurrent = false}) async {
|
||||
editingNode ??= Node();
|
||||
editingNode!.type = walletType;
|
||||
editingNode!.label = label;
|
||||
editingNode!.uriRaw = uri;
|
||||
editingNode!.path = path;
|
||||
editingNode!.login = login;
|
||||
editingNode!.password = password;
|
||||
editingNode!.isPow = isPow;
|
||||
editingNode!.useSSL = useSSL;
|
||||
editingNode!.trusted = trusted;
|
||||
editingNode!.socksProxyAddress = socksProxyAddress;
|
||||
|
||||
try {
|
||||
state = IsExecutingState();
|
||||
if (editingNode != null) {
|
||||
await _nodeSource.put(editingNode.key, node);
|
||||
} else if (_existingNode(node) != null) {
|
||||
setAsCurrent(_existingNode(node)!);
|
||||
} else {
|
||||
await _nodeSource.add(node);
|
||||
setAsCurrent(_nodeSource.values.last);
|
||||
}
|
||||
await editingNode!.save();
|
||||
if (saveAsCurrent) {
|
||||
setAsCurrent(node);
|
||||
setAsCurrent(editingNode!);
|
||||
}
|
||||
|
||||
state = ExecutedSuccessfullyState();
|
||||
if(nodeListViewModel != null) {
|
||||
nodeListViewModel!.bindNodes();
|
||||
}
|
||||
if(powNodeListViewModel != null) {
|
||||
powNodeListViewModel!.bindNodes();
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
state = FailureState(e.toString());
|
||||
}
|
||||
@@ -301,15 +320,6 @@ abstract class NodeCreateOrEditViewModelBase with Store {
|
||||
}
|
||||
}
|
||||
|
||||
Node? _existingNode(Node node) {
|
||||
final nodes = _nodeSource.values.toList();
|
||||
nodes.forEach((item) {
|
||||
item.login ??= '';
|
||||
item.password ??= '';
|
||||
item.useSSL ??= false;
|
||||
});
|
||||
return nodes.firstWhereOrNull((item) => item == node);
|
||||
}
|
||||
|
||||
@action
|
||||
void setAsCurrent(Node node) => _settingsStore.nodes[walletType] = node;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/store/app_store.dart';
|
||||
import 'package:cake_wallet/utils/mobx.dart';
|
||||
import 'package:cw_core/node_list.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
@@ -18,13 +17,13 @@ part 'node_list_view_model.g.dart';
|
||||
class NodeListViewModel = NodeListViewModelBase with _$NodeListViewModel;
|
||||
|
||||
abstract class NodeListViewModelBase with Store {
|
||||
NodeListViewModelBase(this._nodeSource, this._appStore)
|
||||
NodeListViewModelBase(this._appStore)
|
||||
: nodes = ObservableList<Node>(),
|
||||
settingsStore = _appStore.settingsStore {
|
||||
_bindNodes();
|
||||
bindNodes();
|
||||
|
||||
reaction((_) => _appStore.wallet, (WalletBase? _wallet) {
|
||||
_bindNodes();
|
||||
bindNodes();
|
||||
});
|
||||
|
||||
reaction((_) {
|
||||
@@ -35,7 +34,7 @@ abstract class NodeListViewModelBase with Store {
|
||||
}
|
||||
return null;
|
||||
}, (_) {
|
||||
_bindNodes();
|
||||
bindNodes();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -73,24 +72,24 @@ abstract class NodeListViewModelBase with Store {
|
||||
|
||||
final ObservableList<Node> nodes;
|
||||
final SettingsStore settingsStore;
|
||||
final Box<Node> _nodeSource;
|
||||
final AppStore _appStore;
|
||||
|
||||
Future<void> reset() async {
|
||||
await resetToDefault(_nodeSource);
|
||||
await resetToDefault();
|
||||
|
||||
final wallet = _appStore.wallet!;
|
||||
final walletType = wallet.type;
|
||||
|
||||
Node node;
|
||||
if (walletType == WalletType.bitcoin && wallet.isTestnet) {
|
||||
node = getBitcoinTestnetDefaultElectrumServer(nodes: _nodeSource)!;
|
||||
node = (await getBitcoinTestnetDefaultElectrumServer())!;
|
||||
|
||||
} else if (isEVMCompatibleChain(walletType)) {
|
||||
final chainId = evm!.getSelectedChainId(wallet);
|
||||
if (chainId != null) {
|
||||
final nodeWalletType = evm!.getWalletTypeByChainId(chainId);
|
||||
if (nodeWalletType != null) {
|
||||
node = getDefaultNode(nodes: _nodeSource, type: nodeWalletType)!;
|
||||
node = (await Node.getDefaultForWalletType(nodeWalletType))!;
|
||||
} else {
|
||||
throw Exception(
|
||||
'Cannot reset node for EVM wallet: wallet type not found for chainId: $chainId');
|
||||
@@ -99,7 +98,7 @@ abstract class NodeListViewModelBase with Store {
|
||||
throw Exception('Cannot reset node for EVM wallet: chainId is null');
|
||||
}
|
||||
} else {
|
||||
node = getDefaultNode(nodes: _nodeSource, type: walletType)!;
|
||||
node = (await Node.getDefaultForWalletType(_appStore.wallet!.type))!;
|
||||
}
|
||||
|
||||
await setAsCurrent(node);
|
||||
@@ -130,7 +129,7 @@ abstract class NodeListViewModelBase with Store {
|
||||
}
|
||||
|
||||
@action
|
||||
void _bindNodes() {
|
||||
Future<void> bindNodes() async {
|
||||
nodes.clear();
|
||||
final wallet = _appStore.wallet!;
|
||||
final walletType = wallet.type;
|
||||
@@ -141,11 +140,8 @@ abstract class NodeListViewModelBase with Store {
|
||||
if (chainId != null) {
|
||||
final nodeWalletType = evm!.getWalletTypeByChainId(chainId);
|
||||
if (nodeWalletType != null) {
|
||||
_nodeSource.bindToList(
|
||||
nodes,
|
||||
filter: (val) => val.type == nodeWalletType,
|
||||
initialFire: true,
|
||||
);
|
||||
nodes.addAll(await Node.getAllForWalletType(nodeWalletType));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -154,10 +150,7 @@ abstract class NodeListViewModelBase with Store {
|
||||
}
|
||||
|
||||
// For non-EVM wallets, use the wallet type directly
|
||||
_nodeSource.bindToList(
|
||||
nodes,
|
||||
filter: (val) => val.type == walletType,
|
||||
initialFire: true,
|
||||
);
|
||||
nodes.addAll(await Node.getAllForWalletType(walletType));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/store/app_store.dart';
|
||||
import 'package:cake_wallet/utils/mobx.dart';
|
||||
import 'package:cw_core/node_list.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
@@ -16,13 +17,13 @@ part 'pow_node_list_view_model.g.dart';
|
||||
class PowNodeListViewModel = PowNodeListViewModelBase with _$PowNodeListViewModel;
|
||||
|
||||
abstract class PowNodeListViewModelBase with Store {
|
||||
PowNodeListViewModelBase(this._nodeSource, this._appStore)
|
||||
PowNodeListViewModelBase(this._appStore)
|
||||
: nodes = ObservableList<Node>(),
|
||||
settingsStore = _appStore.settingsStore {
|
||||
_bindNodes();
|
||||
bindNodes();
|
||||
|
||||
reaction((_) => _appStore.wallet, (WalletBase? _wallet) {
|
||||
_bindNodes();
|
||||
bindNodes();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -50,17 +51,16 @@ abstract class PowNodeListViewModelBase with Store {
|
||||
|
||||
final ObservableList<Node> nodes;
|
||||
final SettingsStore settingsStore;
|
||||
final Box<Node> _nodeSource;
|
||||
final AppStore _appStore;
|
||||
|
||||
Future<void> reset() async {
|
||||
await resetPowToDefault(_nodeSource);
|
||||
await resetPowToDefault();
|
||||
|
||||
Node node;
|
||||
|
||||
switch (_appStore.wallet!.type) {
|
||||
case WalletType.nano:
|
||||
node = getNanoDefaultPowNode(nodes: _nodeSource)!;
|
||||
node = (await getNanoDefaultPowNode())!;
|
||||
break;
|
||||
default:
|
||||
throw Exception('Unexpected wallet type: ${_appStore.wallet!.type} for pow node list');
|
||||
@@ -76,12 +76,8 @@ abstract class PowNodeListViewModelBase with Store {
|
||||
settingsStore.powNodes[_appStore.wallet!.type] = node;
|
||||
|
||||
@action
|
||||
void _bindNodes() {
|
||||
Future<void> bindNodes() async {
|
||||
nodes.clear();
|
||||
_nodeSource.bindToList(
|
||||
nodes,
|
||||
filter: (val) => val.type == _appStore.wallet!.type,
|
||||
initialFire: true,
|
||||
);
|
||||
nodes.addAll(await Node.getAllPow());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user