Rebase node-sqlite-migration onto dev
What changed, and why it matters
This is a large code refactor that moves Cake Wallet's saved blockchain node list from the Hive key-value store to a SQLite database. It also updates the bundled default nodes for many cryptocurrencies, changes which node is the default for several coins, and adds labels/official flags. The change touches how the app picks which server it talks to when sending or receiving transaction data. There is no clear security bug in the diff, but any data migration this large carries some risk of losing or mis-mapping user node settings, which could cause wallets to connect to an unexpected server after update.
Treat this as a high-risk migration rather than an active vulnerability. Review the migration path carefully: verify that custom user nodes and proxy settings survive the Hive→SQLite transition, that default node IDs referenced in SharedPreferences remain consistent, and that the new default nodes are trustworthy. Run integration tests covering app upgrade from older versions and confirm no wallet connects to an unintended node after migration. No immediate exploit mitigation is indicated by the diff alone.
Security signals we found
Large data migration from Hive to SQLite with custom migration logic
Default node list changes for multiple cryptocurrencies
New isOfficial / isBuiltin / isDefault flags added to node metadata
Migration deletes old built-in Hive nodes and re-adds them from YAML
Node identity logic changed from Hive key to SQLite integer id
Proxy settings are preserved during built-in node validation
Evidence from the diff
The commit migrates Node storage from Hive (NoSQL boxes) to SQLite via sqflite. A new Node table is created in cw_core/lib/db/sqlite.dart, Node becomes a plain Dart class with toMap/fromMap/save/delete helpers, and a node_legacy.dart file retains the Hive adapter only for one-time migration. Default node YAMLs are updated: fields renamed (is_default -> isDefault), labels and isOfficial/isBuiltin flags added, and several default nodes changed (e.g., Arbitrum default moved from nownodes to publicnode, Base default moved to nownodes, Nano default moved to nano.to, Solana default moved to Chainstack, Tron default moved to trongrid, Zcash default moved to Cake Wallet node). The migration logic deletes old Hive nodes that match the new built-in list and migrates custom nodes into SQLite while preserving their IDs. Node switching and settings code are refactored to use async SQLite queries instead of Hive boxes.
Changed components
cw_core/lib/db/sqlite.dartcw_core/lib/node.dartcw_core/lib/node_legacy.dartcw_core/lib/node_list.dartlib/entities/default_settings_migration.dartlib/entities/node_check.dartlib/core/node_switching_service.dartlib/di.dartlib/main.dartassets/*_node_list.ymlInspect captured patch +1201 / −1052
diff --git a/assets/arbitrum_node_list.yml b/assets/arbitrum_node_list.yml
index 63894f18..019a5838 100644
--- a/assets/arbitrum_node_list.yml
+++ b/assets/arbitrum_node_list.yml
@@ -1,12 +1,15 @@
-
uri: arbitrum.nownodes.io
- is_default: true
useSSL: true
isEnabledForAutoSwitching: true
+ label: "NOWNodes"
-
uri: arbitrum.drpc.org
useSSL: true
+ label: "dRPC"
-
uri: arbitrum-one-rpc.publicnode.com
useSSL: true
- isEnabledForAutoSwitching: true
\ No newline at end of file
+ isDefault: true
+ isEnabledForAutoSwitching: true
+ label: "PublicNode"
\ No newline at end of file
diff --git a/assets/base_node_list.yml b/assets/base_node_list.yml
index 990e972a..05388263 100644
--- a/assets/base_node_list.yml
+++ b/assets/base_node_list.yml
@@ -1,15 +1,19 @@
-
uri: base.nownodes.io
+ isDefault: true
useSSL: true
isEnabledForAutoSwitching: true
+ label: "NOWNodes"
-
uri: base.llamarpc.com
useSSL: true
+ label: "LlamaNodes"
-
uri: base-rpc.publicnode.com
- is_default: true
useSSL: true
isEnabledForAutoSwitching: true
+ label: "PublicNode"
-
uri: 1rpc.io/base
- useSSL: true
\ No newline at end of file
+ useSSL: true
+ label: "1RPC"
\ No newline at end of file
diff --git a/assets/bitcoin_cash_electrum_server_list.yml b/assets/bitcoin_cash_electrum_server_list.yml
index 770bdbc0..b8c4e17d 100644
--- a/assets/bitcoin_cash_electrum_server_list.yml
+++ b/assets/bitcoin_cash_electrum_server_list.yml
@@ -1,12 +1,11 @@
-
uri: bitcoincash.stackwallet.com:50002
- is_default: true
+ isDefault: true
useSSL: true
isEnabledForAutoSwitching: true
+ label: "Stack Wallet"
-
uri: bch.aftrek.org:50002
useSSL: true
isEnabledForAutoSwitching: true
--
- uri: node.minisatoshi.cash:50002
- useSSL: true
+ label: "Aftrek"
diff --git a/assets/bitcoin_electrum_server_list.yml b/assets/bitcoin_electrum_server_list.yml
index c3a92e94..4346d1d3 100644
--- a/assets/bitcoin_electrum_server_list.yml
+++ b/assets/bitcoin_electrum_server_list.yml
@@ -2,14 +2,21 @@
uri: btc-electrum.cakewallet.com:50002
useSSL: true
isDefault: true
+ isOfficial: true
isEnabledForAutoSwitching: true
+ label: "Cake Wallet Electrum"
-
uri: electrs.cakewallet.com:50001
+ isOfficial: true
+ label: "Cake Wallet Electrs"
-
uri: fulcrum.sethforprivacy.com:50002
useSSL: true
isEnabledForAutoSwitching: true
+ label: "Seth For Privacy"
-
uri: electrum.cakewallet.com:50002
+ isOfficial: true
useSSL: true
isEnabledForAutoSwitching: true
+ label: "Cake Wallet (Legacy)"
diff --git a/assets/bsc_node_list.yml b/assets/bsc_node_list.yml
index 20e0cdcc..4403b6b0 100644
--- a/assets/bsc_node_list.yml
+++ b/assets/bsc_node_list.yml
@@ -3,26 +3,33 @@
useSSL: true
isDefault: true
isEnabledForAutoSwitching: true
+ label: "BNBChain"
-
uri: bsc-dataseed2.bnbchain.org
useSSL: true
isEnabledForAutoSwitching: true
+ label: "BNBChain #2"
-
uri: bsc-dataseed.nariox.org
useSSL: true
isEnabledForAutoSwitching: true
+ label: "Nariox"
-
uri: bsc-dataseed.defibit.io
useSSL: true
isEnabledForAutoSwitching: true
+ label: "DeFibit"
-
uri: bsc-dataseed.ninicoin.io
useSSL: true
isEnabledForAutoSwitching: true
+ label: "NiniCoin"
-
uri: bsc.nodereal.io
useSSL: true
isEnabledForAutoSwitching: true
+ label: "NodeReal"
-
uri: bsc-dataseed-public.bnbchain.org
useSSL: true
+ label: "BNBChain Public"
\ No newline at end of file
diff --git a/assets/decred_node_list.yml b/assets/decred_node_list.yml
index 9f5938e8..7121867e 100644
--- a/assets/decred_node_list.yml
+++ b/assets/decred_node_list.yml
@@ -1,8 +1,10 @@
-
uri: default-spv-nodes
- is_default: true
+ isDefault: true
isEnabledForAutoSwitching: true
+ label: "Decred"
-
uri: dcrd.sethforprivacy.com:9108
useSSL: true
- isEnabledForAutoSwitching: true
\ No newline at end of file
+ isEnabledForAutoSwitching: true
+ label: "Seth For Privacy"
\ No newline at end of file
diff --git a/assets/dogecoin_electrum_server_list.yml b/assets/dogecoin_electrum_server_list.yml
index 087b0af2..010535be 100644
--- a/assets/dogecoin_electrum_server_list.yml
+++ b/assets/dogecoin_electrum_server_list.yml
@@ -1,12 +1,15 @@
-
uri: dogecoin.stackwallet.com:50022
- is_default: true
+ isDefault: true
useSSL: true
isEnabledForAutoSwitching: true
+ label: "Stack Wallet"
-
uri: doge.aftrek.org:50002
useSSL: true
isEnabledForAutoSwitching: true
+ label: "Aftrek"
-
uri: electrum1.cipig.net:20060
- useSSL: true
\ No newline at end of file
+ useSSL: true
+ label: "Cipig"
\ No newline at end of file
diff --git a/assets/ethereum_server_list.yml b/assets/ethereum_server_list.yml
index 0ba098fc..08c2f4ae 100644
--- a/assets/ethereum_server_list.yml
+++ b/assets/ethereum_server_list.yml
@@ -3,18 +3,21 @@
useSSL: true
isDefault: true
isEnabledForAutoSwitching: true
+ label: "PublicNode"
-
uri: eth.llamarpc.com
useSSL: true
+ label: "LlamaNodes"
-
uri: rpc.flashbots.net
useSSL: true
+ label: "Flashbots"
-
uri: eth-mainnet.public.blastapi.io
useSSL: true
+ label: "Blast"
-
uri: eth.nownodes.io
useSSL: true
isEnabledForAutoSwitching: true
--
- uri: ethereum.publicnode.com
\ No newline at end of file
+ label: "NOWNodes"
\ No newline at end of file
diff --git a/assets/haven_node_list.yml b/assets/haven_node_list.yml
index 27d9ee61..2dfa644b 100644
--- a/assets/haven_node_list.yml
+++ b/assets/haven_node_list.yml
@@ -1,4 +1,4 @@
-
uri: nodes.havenprotocol.org:443
useSSL: true
- is_default: true
\ No newline at end of file
+ isDefault: true
\ No newline at end of file
diff --git a/assets/lightning_deposit_help.svg b/assets/lightning_deposit_help.svg
deleted file mode 100644
index 5cecc0ba..00000000
--- a/assets/lightning_deposit_help.svg
+++ /dev/null
@@ -1,99 +0,0 @@
-<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
- <g clip-path="url(#clip0_14800_609868)">
- <g opacity="0.5">
- <path d="M65.6689 41.3975C61.2164 59.2548 43.128 70.1225 25.2667 65.6694C7.41273 61.2173 -3.45614 43.1298 0.998503 25.2735C5.44898 7.41416 23.5374 -3.45459 41.3934 0.997495C59.2537 5.44958 70.1215 23.5392 65.6689 41.3975Z" fill="url(#paint0_linear_14800_609868)"/>
- <path d="M65.6689 41.3975C61.2164 59.2548 43.128 70.1225 25.2667 65.6694C7.41273 61.2173 -3.45614 43.1298 0.998503 25.2735C5.44898 7.41416 23.5374 -3.45459 41.3934 0.997495C59.2537 5.44958 70.1215 23.5392 65.6689 41.3975Z" fill="url(#paint1_linear_14800_609868)"/>
- <path d="M0.998503 25.2735C5.44902 7.41421 23.5374 -3.45458 41.3934 0.997489C59.2536 5.44957 70.1214 23.5392 65.669 41.3975L65.5622 41.8149C60.9703 59.2852 43.2701 69.9194 25.6853 65.7709L25.2667 65.6693C7.41273 61.2173 -3.45614 43.1298 0.998503 25.2735ZM41.0708 2.29124C23.9295 -1.9826 6.56484 8.45112 2.29239 25.5959V25.5964C-1.98393 42.7381 8.44993 60.1016 25.5892 64.3756C42.7359 68.6506 60.1007 58.2178 64.3751 41.0751C68.6495 23.9311 58.2162 6.56514 41.0708 2.29124Z" fill="url(#paint2_linear_14800_609868)"/>
- <path d="M0.998503 25.2735C5.44902 7.41421 23.5374 -3.45458 41.3934 0.997489C59.2536 5.44957 70.1214 23.5392 65.669 41.3975L65.5622 41.8149C60.9703 59.2852 43.2701 69.9194 25.6853 65.7709L25.2667 65.6693C7.41273 61.2173 -3.45614 43.1298 0.998503 25.2735ZM41.0708 2.29124C23.9295 -1.9826 6.56484 8.45112 2.29239 25.5959V25.5964C-1.98393 42.7381 8.44993 60.1016 25.5892 64.3756C42.7359 68.6506 60.1007 58.2178 64.3751 41.0751C68.6495 23.9311 58.2162 6.56514 41.0708 2.29124Z" fill="url(#paint3_linear_14800_609868)"/>
- <path d="M0.998503 25.2735C5.44902 7.41421 23.5374 -3.45458 41.3934 0.997489C59.2536 5.44957 70.1214 23.5392 65.669 41.3975L65.5622 41.8149C60.9703 59.2852 43.2701 69.9194 25.6853 65.7709L25.2667 65.6693C7.41273 61.2173 -3.45614 43.1298 0.998503 25.2735ZM41.0708 2.29124C23.9295 -1.9826 6.56484 8.45112 2.29239 25.5959V25.5964C-1.98393 42.7381 8.44993 60.1016 25.5892 64.3756C42.7359 68.6506 60.1007 58.2178 64.3751 41.0751C68.6495 23.9311 58.2162 6.56514 41.0708 2.29124Z" fill="url(#paint4_linear_14800_609868)"/>
- <path d="M48.0289 30.1837C48.6924 25.7482 45.3154 23.3639 40.6977 21.7732L42.1956 15.7649L38.5383 14.8535L37.0799 20.7035C36.1185 20.4639 35.131 20.2378 34.1497 20.0139L35.6185 14.1253L31.9633 13.2139L30.4643 19.2201C29.6685 19.0389 28.8872 18.8597 28.1289 18.6712L28.1331 18.6524L23.0893 17.393L22.1164 21.2993C22.1164 21.2993 24.8299 21.9212 24.7727 21.9597C26.2539 22.3295 26.5216 23.3097 26.4768 24.0868L24.7706 30.9316C24.8727 30.9576 25.0049 30.9951 25.1508 31.0534C25.0289 31.0232 24.8987 30.9899 24.7643 30.9576L22.3727 40.5462C22.1914 40.9962 21.732 41.6712 20.6966 41.4149C20.7331 41.468 18.0383 40.7514 18.0383 40.7514L16.2227 44.9378L20.982 46.1243C21.8674 46.3462 22.7352 46.5784 23.5893 46.7972L22.0758 52.8743L25.7289 53.7857L27.2279 47.7732C28.2258 48.0441 29.1945 48.2941 30.1424 48.5295L28.6487 54.5139L32.306 55.4253L33.8195 49.3597C40.056 50.5399 44.7456 50.0639 46.7195 44.4232C48.3102 39.8816 46.6404 37.2618 43.3591 35.5534C45.7487 35.0024 47.5487 33.4305 48.0289 30.1837ZM39.6727 41.9014C38.5424 46.443 30.8956 43.9878 28.4164 43.3722L30.4247 35.3212C32.9039 35.9399 40.8539 37.1649 39.6727 41.9014ZM40.8039 30.118C39.7727 34.2493 33.4081 32.1503 31.3435 31.6357L33.1643 24.3337C35.2289 24.8482 41.8779 25.8087 40.8039 30.118Z" fill="url(#paint5_linear_14800_609868)"/>
- <path d="M48.0289 28.5836C48.6924 24.1481 45.3154 21.7638 40.6977 20.1731L42.1956 14.1648L38.5383 13.2534L37.0799 19.1034C36.1185 18.8638 35.131 18.6377 34.1497 18.4138L35.6185 12.5252L31.9633 11.6138L30.4643 17.62C29.6685 17.4388 28.8872 17.2596 28.1289 17.0711L28.1331 17.0523L23.0893 15.7929L22.1164 19.6992C22.1164 19.6992 24.8299 20.3211 24.7727 20.3596C26.2539 20.7294 26.5216 21.7096 26.4768 22.4867L24.7706 29.3315C24.8727 29.3575 25.0049 29.395 25.1508 29.4534C25.0289 29.4231 24.8987 29.3898 24.7643 29.3575L22.3727 38.9461C22.1914 39.3961 21.732 40.0711 20.6966 39.8148C20.7331 39.8679 18.0383 39.1513 18.0383 39.1513L16.2227 43.3377L20.982 44.5242C21.8674 44.7461 22.7352 44.9784 23.5893 45.1971L22.0758 51.2742L25.7289 52.1856L27.2279 46.1731C28.2258 46.444 29.1945 46.694 30.1424 46.9294L28.6487 52.9138L32.306 53.8252L33.8195 47.7596C40.056 48.9398 44.7456 48.4638 46.7195 42.8231C48.3102 38.2815 46.6404 35.6617 43.3591 33.9534C45.7487 33.4023 47.5487 31.8304 48.0289 28.5836ZM39.6727 40.3013C38.5424 44.8429 30.8956 42.3877 28.4164 41.7721L30.4247 33.7211C32.9039 34.3398 40.8539 35.5648 39.6727 40.3013ZM40.8039 28.5179C39.7727 32.6492 33.4081 30.5502 31.3435 30.0356L33.1643 22.7336C35.2289 23.2481 41.8779 24.2086 40.8039 28.5179Z" fill="white"/>
- <path d="M48.0289 28.5836C48.6924 24.1481 45.3154 21.7638 40.6977 20.1731L42.1956 14.1648L38.5383 13.2534L37.0799 19.1034C36.1185 18.8638 35.131 18.6377 34.1497 18.4138L35.6185 12.5252L31.9633 11.6138L30.4643 17.62C29.6685 17.4388 28.8872 17.2596 28.1289 17.0711L28.1331 17.0523L23.0893 15.7929L22.1164 19.6992C22.1164 19.6992 24.8299 20.3211 24.7727 20.3596C26.2539 20.7294 26.5216 21.7096 26.4768 22.4867L24.7706 29.3315C24.8727 29.3575 25.0049 29.395 25.1508 29.4534C25.0289 29.4231 24.8987 29.3898 24.7643 29.3575L22.3727 38.9461C22.1914 39.3961 21.732 40.0711 20.6966 39.8148C20.7331 39.8679 18.0383 39.1513 18.0383 39.1513L16.2227 43.3377L20.982 44.5242C21.8674 44.7461 22.7352 44.9784 23.5893 45.1971L22.0758 51.2742L25.7289 52.1856L27.2279 46.1731C28.2258 46.444 29.1945 46.694 30.1424 46.9294L28.6487 52.9138L32.306 53.8252L33.8195 47.7596C40.056 48.9398 44.7456 48.4638 46.7195 42.8231C48.3102 38.2815 46.6404 35.6617 43.3591 33.9534C45.7487 33.4023 47.5487 31.8304 48.0289 28.5836ZM39.6727 40.3013C38.5424 44.8429 30.8956 42.3877 28.4164 41.7721L30.4247 33.7211C32.9039 34.3398 40.8539 35.5648 39.6727 40.3013ZM40.8039 28.5179C39.7727 32.6492 33.4081 30.5502 31.3435 30.0356L33.1643 22.7336C35.2289 23.2481 41.8779 24.2086 40.8039 28.5179Z" fill="url(#paint6_linear_14800_609868)"/>
- <path d="M48.0289 28.5836C48.6924 24.1481 45.3154 21.7638 40.6977 20.1731L42.1956 14.1648L38.5383 13.2534L37.0799 19.1034C36.1185 18.8638 35.131 18.6377 34.1497 18.4138L35.6185 12.5252L31.9633 11.6138L30.4643 17.62C29.6685 17.4388 28.8872 17.2596 28.1289 17.0711L28.1331 17.0523L23.0893 15.7929L22.1164 19.6992C22.1164 19.6992 24.8299 20.3211 24.7727 20.3596C26.2539 20.7294 26.5216 21.7096 26.4768 22.4867L24.7706 29.3315C24.8727 29.3575 25.0049 29.395 25.1508 29.4534C25.0289 29.4231 24.8987 29.3898 24.7643 29.3575L22.3727 38.9461C22.1914 39.3961 21.732 40.0711 20.6966 39.8148C20.7331 39.8679 18.0383 39.1513 18.0383 39.1513L16.2227 43.3377L20.982 44.5242C21.8674 44.7461 22.7352 44.9784 23.5893 45.1971L22.0758 51.2742L25.7289 52.1856L27.2279 46.1731C28.2258 46.444 29.1945 46.694 30.1424 46.9294L28.6487 52.9138L32.306 53.8252L33.8195 47.7596C40.056 48.9398 44.7456 48.4638 46.7195 42.8231C48.3102 38.2815 46.6404 35.6617 43.3591 33.9534C45.7487 33.4023 47.5487 31.8304 48.0289 28.5836ZM39.6727 40.3013C38.5424 44.8429 30.8956 42.3877 28.4164 41.7721L30.4247 33.7211C32.9039 34.3398 40.8539 35.5648 39.6727 40.3013ZM40.8039 28.5179C39.7727 32.6492 33.4081 30.5502 31.3435 30.0356L33.1643 22.7336C35.2289 23.2481 41.8779 24.2086 40.8039 28.5179Z" fill="url(#paint7_linear_14800_609868)"/>
- <path d="M35.6185 12.5252L34.1497 18.4138C34.8857 18.5817 35.6251 18.7509 36.3544 18.926L37.0799 19.1034L38.5383 13.2534L42.1956 14.1648L40.6977 20.1731C45.3154 21.7638 48.6924 24.1481 48.0289 28.5836C47.5487 31.8304 45.7487 33.4023 43.3591 33.9534C46.6404 35.6617 48.3102 38.2815 46.7195 42.8231C44.7456 48.4638 40.056 48.9398 33.8195 47.7596L32.306 53.8252L28.6487 52.9138L30.1424 46.9294C29.1945 46.694 28.2258 46.444 27.2279 46.1731L25.7289 52.1856L22.0758 51.2742L23.5893 45.1971C22.7352 44.9784 21.8674 44.7461 20.982 44.5242L16.2227 43.3377L18.0383 39.1513C18.0383 39.1513 20.7331 39.8679 20.6966 39.8148C21.732 40.0711 22.1914 39.3961 22.3727 38.9461L24.7643 29.3575C24.8987 29.3898 25.0289 29.4231 25.1508 29.4534C25.0049 29.395 24.8727 29.3575 24.7706 29.3315L26.4768 22.4867C26.5216 21.7096 26.2539 20.7294 24.7727 20.3596C24.8299 20.3211 22.1184 19.6996 22.1164 19.6992L23.0893 15.7929L28.1331 17.0523L28.1289 17.0711C28.5081 17.1653 28.893 17.2574 29.2826 17.3484L30.4643 17.62L31.9633 11.6138L35.6185 12.5252ZM30.8552 18.256L30.3458 18.1401C29.5502 17.9589 28.7643 17.7785 28.0003 17.5885L27.4953 17.4632L27.4995 17.4437L23.4776 16.4396L22.7646 19.3021C23.0032 19.3576 23.2971 19.4264 23.5898 19.4963C23.9261 19.5766 24.264 19.6589 24.5154 19.7239C24.6397 19.7561 24.7494 19.7857 24.8286 19.8096C24.8651 19.8206 24.9101 19.8347 24.9497 19.8505C24.954 19.8522 24.9643 19.8564 24.9784 19.8627C25.7828 20.0791 26.3243 20.4754 26.6474 20.9846C26.9735 21.4985 27.0357 22.061 27.0094 22.5174L27.0065 22.5672L26.9943 22.6156L25.288 29.4604L25.1943 29.4369L25.1862 29.4627L25.2818 29.4867L22.8901 39.0752L22.8812 39.1109L22.8674 39.1453C22.7572 39.419 22.5476 39.8027 22.1674 40.0776C21.7796 40.358 21.268 40.4848 20.6432 40.3489C20.6232 40.3474 20.6088 40.3457 20.6034 40.345C20.5651 40.34 20.5217 40.3315 20.4849 40.3239C20.4057 40.3076 20.2964 40.2821 20.1716 40.252C19.9199 40.1913 19.583 40.1059 19.2479 40.0195C18.9218 39.9354 18.595 39.8496 18.3451 39.7838L16.9622 42.9724L21.1109 44.0067H21.1117C21.9966 44.2285 22.8772 44.4642 23.7216 44.6804L24.2349 44.8119L22.7219 50.8856L25.3404 51.539L26.8422 45.5159L27.3674 45.6586C28.3612 45.9283 29.3264 46.1771 30.2711 46.4117L30.7893 46.5406L29.2953 52.5252L31.9174 53.1786L33.424 47.1419L33.9187 47.2356C37.0189 47.8223 39.6425 47.9761 41.7112 47.3396C43.7316 46.7178 45.2792 45.3243 46.2161 42.6471C46.9818 40.4608 46.9366 38.8163 46.3776 37.5395C45.8155 36.2558 44.693 35.2493 43.1128 34.4265L41.8302 33.7586L43.2393 33.4336C44.3532 33.1767 45.2981 32.6901 46.0198 31.9159C46.741 31.142 47.2738 30.0439 47.5013 28.5054L47.5016 28.5047C47.8072 26.4614 47.1908 24.9228 45.9651 23.6872C44.7129 22.4249 42.8067 21.4636 40.524 20.6773L40.062 20.5182L41.549 14.5531L38.9266 13.8997L37.4685 19.7497L36.951 19.6208C35.9955 19.3827 35.0128 19.1579 34.031 18.9338L33.5005 18.8127L34.9719 12.9135L32.3516 12.2601L30.8552 18.256ZM30.5539 33.2036C31.7395 33.4995 34.4332 33.9792 36.6417 34.9815C37.7505 35.4847 38.8004 36.1452 39.4948 37.0336C40.2086 37.9469 40.5272 39.0789 40.1901 40.4304C39.8638 41.7411 39.0508 42.5639 37.999 43.0226C36.9747 43.4693 35.7396 43.5667 34.5227 43.5034C32.0931 43.3768 29.4876 42.5878 28.2878 42.2898L27.7698 42.1612L30.0365 33.0744L30.5539 33.2036ZM28.4164 41.7721C30.8956 42.3877 38.5424 44.8429 39.6727 40.3013C40.8539 35.5648 32.9039 34.3398 30.4247 33.7211L28.4164 41.7721ZM33.2932 22.2161C34.2662 22.4586 36.5394 22.8473 38.3888 23.7203C39.3203 24.16 40.2074 24.7487 40.7872 25.5578C41.3838 26.3903 41.6272 27.4193 41.3214 28.6468C41.0242 29.8374 40.3257 30.6069 39.4141 31.05C38.5281 31.4805 37.4712 31.5899 36.4417 31.552C34.3912 31.4767 32.2032 30.7995 31.2146 30.5531L30.6969 30.4242L32.7758 22.0872L33.2932 22.2161ZM31.3435 30.0356C33.4081 30.5502 39.7727 32.6492 40.8039 28.5179C41.8779 24.2086 35.2289 23.2481 33.1643 22.7336L31.3435 30.0356Z" fill="url(#paint8_linear_14800_609868)"/>
- </g>
- <path d="M96.2235 71.9527C91.7714 89.81 73.6849 100.678 55.8255 96.2245C37.9735 91.7725 27.1058 73.685 31.5599 55.8287C36.0099 37.9693 54.0964 27.1006 71.9505 31.5527C89.8089 36.0048 100.676 54.0943 96.2235 71.9527Z" fill="#F7931A"/>
- <path d="M96.2235 71.9527C91.7714 89.81 73.6849 100.678 55.8255 96.2245C37.9735 91.7725 27.1058 73.685 31.5599 55.8287C36.0099 37.9693 54.0964 27.1006 71.9505 31.5527C89.8089 36.0048 100.676 54.0943 96.2235 71.9527Z" fill="url(#paint9_linear_14800_609868)"/>
- <path d="M96.2235 71.9527C91.7714 89.81 73.6849 100.678 55.8255 96.2245C37.9735 91.7725 27.1058 73.685 31.5599 55.8287C36.0099 37.9693 54.0964 27.1006 71.9505 31.5527C89.8089 36.0048 100.676 54.0943 96.2235 71.9527Z" fill="url(#paint10_linear_14800_609868)"/>
- <path d="M96.2235 71.9527C91.7714 89.81 73.6849 100.678 55.8255 96.2245C37.9735 91.7725 27.1058 73.685 31.5599 55.8287C36.0099 37.9693 54.0964 27.1006 71.9505 31.5527C89.8089 36.0048 100.676 54.0943 96.2235 71.9527Z" fill="url(#paint11_linear_14800_609868)"/>
- <path d="M31.5599 55.8287C36.01 37.9694 54.0964 27.1006 71.9506 31.5527C89.8089 36.0047 100.676 54.0944 96.2235 71.9526L96.1167 72.3701C91.5253 89.8403 73.827 100.475 56.244 96.3261L55.8256 96.2245C37.9735 91.7724 27.1058 73.6849 31.5599 55.8287ZM71.6279 32.8464C54.4885 28.5726 37.1257 39.0063 32.8537 56.1511V56.1516C28.5778 73.2933 39.0106 90.6568 56.148 94.9308C73.2928 99.2057 90.6558 88.7729 94.9297 71.6303C99.2037 54.4862 88.7715 37.1203 71.6279 32.8464Z" fill="url(#paint12_linear_14800_609868)"/>
- <path d="M31.5599 55.8287C36.01 37.9694 54.0964 27.1006 71.9506 31.5527C89.8089 36.0047 100.676 54.0944 96.2235 71.9526L96.1167 72.3701C91.5253 89.8403 73.827 100.475 56.244 96.3261L55.8256 96.2245C37.9735 91.7724 27.1058 73.6849 31.5599 55.8287ZM71.6279 32.8464C54.4885 28.5726 37.1257 39.0063 32.8537 56.1511V56.1516C28.5778 73.2933 39.0106 90.6568 56.148 94.9308C73.2928 99.2057 90.6558 88.7729 94.9297 71.6303C99.2037 54.4862 88.7715 37.1203 71.6279 32.8464Z" fill="url(#paint13_linear_14800_609868)"/>
- <path d="M31.5599 55.8287C36.01 37.9694 54.0964 27.1006 71.9506 31.5527C89.8089 36.0047 100.676 54.0944 96.2235 71.9526L96.1167 72.3701C91.5253 89.8403 73.827 100.475 56.244 96.3261L55.8256 96.2245C37.9735 91.7724 27.1058 73.6849 31.5599 55.8287ZM71.6279 32.8464C54.4885 28.5726 37.1257 39.0063 32.8537 56.1511V56.1516C28.5778 73.2933 39.0106 90.6568 56.148 94.9308C73.2928 99.2057 90.6558 88.7729 94.9297 71.6303C99.2037 54.4862 88.7715 37.1203 71.6279 32.8464Z" fill="url(#paint14_linear_14800_609868)"/>
- <path d="M46.5206 67.6513L71.4546 46.1656C72.5411 45.4698 73.5767 46.1656 72.9135 47.3592L64.9559 63.0094H79.147C79.147 63.0094 81.4017 63.0094 79.147 64.8662L54.6109 86.4844C52.8868 87.9434 51.6931 87.1476 52.8868 84.8929L60.5792 69.6408H46.5206C46.5206 69.6408 44.266 69.6408 46.5206 67.6513Z" fill="url(#paint15_linear_14800_609868)"/>
- <path d="M46.5206 64.9843L71.4546 43.4986C72.5411 42.8028 73.5767 43.4986 72.9135 44.6922L64.9559 60.3424H79.147C79.147 60.3424 81.4017 60.3424 79.147 62.1992L54.6109 83.8175C52.8868 85.2764 51.6931 84.4806 52.8868 82.2259L60.5792 66.9738H46.5206C46.5206 66.9738 44.266 66.9738 46.5206 64.9843Z" fill="url(#paint16_linear_14800_609868)"/>
- <path d="M71.4547 43.4985C72.5412 42.8028 73.5767 43.4987 72.9136 44.6922L64.9558 60.3425H79.1469C79.1469 60.3425 81.4016 60.3425 79.1469 62.1993L54.611 83.8175L54.5305 83.8842C52.8501 85.2511 51.7118 84.4453 52.8868 82.2258L60.5792 66.9738H46.5206L46.4282 66.9699C46.0347 66.9431 44.6002 66.7328 46.4183 65.0761L46.5206 64.9844L71.4547 43.4985ZM72.5183 43.812C72.4487 43.7593 72.185 43.6755 71.7693 43.931L46.8688 65.3883C46.3257 65.8682 46.1264 66.1691 46.0683 66.323C46.065 66.3316 46.0628 66.3394 46.0607 66.3462C46.1043 66.369 46.1825 66.3974 46.2962 66.4175C46.3611 66.429 46.4211 66.4349 46.4644 66.4378C46.4856 66.4393 46.502 66.4399 46.512 66.4402C46.517 66.4403 46.5204 66.4404 46.5219 66.4404H61.4454L53.3631 82.4662L53.3605 82.4709L53.3581 82.4756C53.0793 83.0022 52.963 83.4021 52.9417 83.6727C52.9312 83.8059 52.945 83.8923 52.961 83.9422C52.9759 83.9887 52.9913 84.0006 52.9925 84.0016C52.9944 84.0032 53.0085 84.0146 53.0527 84.0196C53.1015 84.0251 53.1828 84.0218 53.3006 83.9883C53.5397 83.9204 53.8712 83.7446 54.2665 83.4102L78.7943 61.799L78.8011 61.793L78.8079 61.7876C79.3195 61.3662 79.5217 61.0955 79.5902 60.9537C79.5427 60.9347 79.4718 60.9133 79.3774 60.8977C79.311 60.8868 79.25 60.881 79.2058 60.8782C79.184 60.8768 79.167 60.8761 79.1566 60.8758H64.0863L72.4381 44.4506L72.4425 44.4417L72.4472 44.4331C72.5755 44.2022 72.5953 44.0424 72.587 43.954C72.5796 43.8743 72.5499 43.836 72.5183 43.812Z" fill="white"/>
- </g>
- <defs>
- <linearGradient id="paint0_linear_14800_609868" x1="33.3333" y1="0" x2="33.3333" y2="66.6673" gradientUnits="userSpaceOnUse">
- <stop stop-color="#F7BC1A"/>
- <stop offset="1" stop-color="#FF6A00"/>
- </linearGradient>
- <linearGradient id="paint1_linear_14800_609868" x1="33.3333" y1="0" x2="33.3333" y2="66.6673" gradientUnits="userSpaceOnUse">
- <stop offset="0.725084" stop-color="#C94701" stop-opacity="0"/>
- <stop offset="1" stop-color="#C94701" stop-opacity="0.3"/>
- </linearGradient>
- <linearGradient id="paint2_linear_14800_609868" x1="33.3333" y1="9.32637e-05" x2="33.3333" y2="66.6674" gradientUnits="userSpaceOnUse">
- <stop stop-color="#FFE091"/>
- <stop offset="1" stop-color="#FF9735"/>
- </linearGradient>
- <linearGradient id="paint3_linear_14800_609868" x1="33.3333" y1="9.32637e-05" x2="33.3333" y2="66.6674" gradientUnits="userSpaceOnUse">
- <stop offset="0.85" stop-color="#FFA54D" stop-opacity="0"/>
- <stop offset="1" stop-color="#FFA54D"/>
- </linearGradient>
- <linearGradient id="paint4_linear_14800_609868" x1="33.3333" y1="9.32637e-05" x2="33.3333" y2="66.6674" gradientUnits="userSpaceOnUse">
- <stop stop-color="#FFF3DA"/>
- <stop offset="0.15" stop-color="#FFF3DA" stop-opacity="0"/>
- </linearGradient>
- <linearGradient id="paint5_linear_14800_609868" x1="32.1674" y1="13.2139" x2="32.1674" y2="55.4253" gradientUnits="userSpaceOnUse">
- <stop stop-color="#F89A02"/>
- <stop offset="1" stop-color="#F56600"/>
- </linearGradient>
- <linearGradient id="paint6_linear_14800_609868" x1="32.1675" y1="11.6138" x2="32.1675" y2="53.8252" gradientUnits="userSpaceOnUse">
- <stop stop-color="white"/>
- <stop offset="1" stop-color="#FFF1CF"/>
- </linearGradient>
- <linearGradient id="paint7_linear_14800_609868" x1="32.1675" y1="11.6138" x2="32.1675" y2="53.8252" gradientUnits="userSpaceOnUse">
- <stop stop-color="white"/>
- <stop offset="1" stop-color="#FEEABD"/>
- </linearGradient>
- <linearGradient id="paint8_linear_14800_609868" x1="32.1675" y1="11.6138" x2="32.1675" y2="53.8252" gradientUnits="userSpaceOnUse">
- <stop stop-color="white"/>
- <stop offset="1" stop-color="white"/>
- </linearGradient>
- <linearGradient id="paint9_linear_14800_609868" x1="63.8913" y1="30.5552" x2="63.8913" y2="97.2225" gradientUnits="userSpaceOnUse">
- <stop stop-color="#F7BC1A"/>
- <stop offset="1" stop-color="#FF7700"/>
- </linearGradient>
- <linearGradient id="paint10_linear_14800_609868" x1="63.8913" y1="30.5552" x2="63.8913" y2="97.2225" gradientUnits="userSpaceOnUse">
- <stop stop-color="#F7BC1A"/>
- <stop offset="1" stop-color="#FF6A00"/>
- </linearGradient>
- <linearGradient id="paint11_linear_14800_609868" x1="63.8913" y1="30.5552" x2="63.8913" y2="97.2225" gradientUnits="userSpaceOnUse">
- <stop offset="0.725084" stop-color="#C94701" stop-opacity="0"/>
- <stop offset="1" stop-color="#C94701" stop-opacity="0.3"/>
- </linearGradient>
- <linearGradient id="paint12_linear_14800_609868" x1="63.8913" y1="30.5553" x2="63.8913" y2="97.2226" gradientUnits="userSpaceOnUse">
- <stop stop-color="#FFE091"/>
- <stop offset="1" stop-color="#FF9735"/>
- </linearGradient>
- <linearGradient id="paint13_linear_14800_609868" x1="63.8913" y1="30.5553" x2="63.8913" y2="97.2226" gradientUnits="userSpaceOnUse">
- <stop offset="0.85" stop-color="#FFA54D" stop-opacity="0"/>
- <stop offset="1" stop-color="#FFA54D"/>
- </linearGradient>
- <linearGradient id="paint14_linear_14800_609868" x1="63.8913" y1="30.5553" x2="63.8913" y2="97.2226" gradientUnits="userSpaceOnUse">
- <stop stop-color="#FFF3DA"/>
- <stop offset="0.15" stop-color="#FFF3DA" stop-opacity="0"/>
- </linearGradient>
- <linearGradient id="paint15_linear_14800_609868" x1="62.8338" y1="45.8887" x2="62.8338" y2="87.222" gradientUnits="userSpaceOnUse">
- <stop stop-color="#F89A02"/>
- <stop offset="1" stop-color="#F56600"/>
- </linearGradient>
- <linearGradient id="paint16_linear_14800_609868" x1="62.8338" y1="43.2217" x2="62.8338" y2="84.555" gradientUnits="userSpaceOnUse">
- <stop stop-color="white"/>
- <stop offset="1" stop-color="#FEEABD"/>
- </linearGradient>
- <clipPath id="clip0_14800_609868">
- <rect width="100" height="100" fill="white"/>
- </clipPath>
- </defs>
-</svg>
diff --git a/assets/litecoin_electrum_server_list.yml b/assets/litecoin_electrum_server_list.yml
index 18b982aa..b2c55991 100644
--- a/assets/litecoin_electrum_server_list.yml
+++ b/assets/litecoin_electrum_server_list.yml
@@ -2,20 +2,27 @@
uri: ltc-electrum.cakewallet.com:50002
useSSL: true
isDefault: true
+ isOfficial: true
isEnabledForAutoSwitching: true
+ label: "Cake Wallet"
-
uri: litecoin.stackwallet.com:20063
useSSL: true
isEnabledForAutoSwitching: true
+ label: "Stack Wallet"
-
uri: electrum-ltc.bysh.me:50002
useSSL: true
+ label: "Bysh"
-
uri: lightweight.fiatfaucet.com:50002
useSSL: true
+ label: "Fiat Faucet"
-
uri: electrum.ltc.xurious.com:50002
useSSL: true
+ label: "Xurious"
-
uri: backup.electrum-ltc.org:443
useSSL: true
+ label: "Electrum-LTC"
diff --git a/assets/nano_node_list.yml b/assets/nano_node_list.yml
index aa1d8e3c..1f153a29 100644
--- a/assets/nano_node_list.yml
+++ b/assets/nano_node_list.yml
@@ -1,34 +1,37 @@
-
- uri: nano.nownodes.io
+ uri: rpc.nano.to
+ isDefault: true
useSSL: true
isEnabledForAutoSwitching: true
+ label: "Nano.to"
-
- uri: rpc.nano.to
- is_default: true
+ uri: nano.nownodes.io
useSSL: true
isEnabledForAutoSwitching: true
+ label: "NOWNodes"
-
uri: node.nautilus.io
path: /api
useSSL: true
isEnabledForAutoSwitching: true
+ label: "Nautilus"
-
uri: app.natrium.io
path: /api
useSSL: true
+ label: "Natrium"
-
uri: rainstorm.city
path: /api
useSSL: true
+ label: "Rainstorm City"
-
uri: node.somenano.com
path: /proxy
useSSL: true
+ label: "SomeNano"
-
uri: nanoslo.0x.no
path: /proxy
useSSL: true
--
- uri: www.bitrequest.app
- port: 8020
- useSSL: true
\ No newline at end of file
+ label: "0x.no"
\ No newline at end of file
diff --git a/assets/node_list.yml b/assets/node_list.yml
index 568bffb2..a1568319 100644
--- a/assets/node_list.yml
+++ b/assets/node_list.yml
@@ -1,34 +1,36 @@
-
+ label: "Cake Wallet"
uri: xmr-node.cakewallet.com:18081
- is_default: true
+ isDefault: true
+ isOfficial: true
trusted: true
useSSL: true
isEnabledForAutoSwitching: true
-
+ label: "Cake Wallet (Onion)"
uri: cakexmrl7bonq7ovjka5kuwuyd3f7qnkz6z6s6dmsy3uckwra7bvggyd.onion:18081
- is_default: false
-
+ label: "Seth For Privacy"
uri: node.sethforprivacy.com:443
useSSL: true
- is_default: false
isEnabledForAutoSwitching: true
-
+ label: "MoneroDevs"
uri: node.monerodevs.org:18089
useSSL: true
- is_default: false
-
+ label: "MoneroDevs #2"
uri: node2.monerodevs.org:18089
useSSL: true
- is_default: false
-
+ label: "MoneroDevs #3"
uri: node3.monerodevs.org:18089
useSSL: true
- is_default: false
-
+ label: "Feather Wallet"
uri: selsta1.featherwallet.net:18081
useSSL: true
- is_default: false
-
+ label: "StormyCloud"
uri: xmr.stormycloud.org:18089
useSSL: true
- is_default: false
diff --git a/assets/polygon_node_list.yml b/assets/polygon_node_list.yml
index 822a8b4f..9760dd7a 100644
--- a/assets/polygon_node_list.yml
+++ b/assets/polygon_node_list.yml
@@ -1,14 +1,14 @@
--
- uri: polygon-rpc.com
-
uri: polygon-bor-rpc.publicnode.com
useSSL: true
isDefault: true
isEnabledForAutoSwitching: true
+ label: "polygon-bor-rpc.publicnode.com"
-
- uri: polygon.llamarpc.com
- useSSL: true
+ uri: polygon-rpc.com
+ label: "Ankr"
-
uri: matic.nownodes.io
useSSL: true
- isEnabledForAutoSwitching: true
\ No newline at end of file
+ isEnabledForAutoSwitching: true
+ label: "NOWNodes"
\ No newline at end of file
diff --git a/assets/solana_node_list.yml b/assets/solana_node_list.yml
index e1d7971c..e2ad7a27 100644
--- a/assets/solana_node_list.yml
+++ b/assets/solana_node_list.yml
@@ -1,16 +1,20 @@
+-
+ uri: solana-mainnet.core.chainstack.com
+ useSSL: true
+ isDefault: true
+ isEnabledForAutoSwitching: true
+ label: "Chainstack"
-
uri: rpc.ankr.com
useSSL: true
+ label: "Ankr"
-
uri: api.mainnet-beta.solana.com:443
useSSL: true
isEnabledForAutoSwitching: true
+ label: "Solana Beta"
-
uri: solana-rpc.publicnode.com:443
useSSL: true
isEnabledForAutoSwitching: true
--
- uri: solana-mainnet.core.chainstack.com
- useSSL: true
- is_default: true
- isEnabledForAutoSwitching: true
\ No newline at end of file
+ label: "PublicNode"
\ No newline at end of file
diff --git a/assets/tron_node_list.yml b/assets/tron_node_list.yml
index 595bba97..3837ec4e 100644
--- a/assets/tron_node_list.yml
+++ b/assets/tron_node_list.yml
@@ -1,13 +1,15 @@
--
- uri: tron-rpc.publicnode.com:443
- is_default: false
- useSSL: true
-
uri: api.trongrid.io
- is_default: true
+ isDefault: true
useSSL: true
isEnabledForAutoSwitching: true
+ label: "TronGrid"
+-
+ uri: tron-rpc.publicnode.com:443
+ useSSL: true
+ label: "PublicNode"
-
uri: trx.nownodes.io
useSSL: true
- isEnabledForAutoSwitching: true
\ No newline at end of file
+ isEnabledForAutoSwitching: true
+ label: "NOWNodes"
\ No newline at end of file
diff --git a/assets/wownero_node_list.yml b/assets/wownero_node_list.yml
index 893f8298..5356fa5d 100644
--- a/assets/wownero_node_list.yml
+++ b/assets/wownero_node_list.yml
@@ -1,14 +1,12 @@
-
uri: node3.monerodevs.org:34568
- is_default: true
+ isDefault: true
useSSL: false
isEnabledForAutoSwitching: true
-
uri: node2.monerodevs.org:34568
- is_default: false
useSSL: false
isEnabledForAutoSwitching: true
-
uri: node.monerodevs.org:34568
- is_default: false
useSSL: false
diff --git a/assets/zano_node_list.yml b/assets/zano_node_list.yml
index 17bba5f4..93923e6b 100644
--- a/assets/zano_node_list.yml
+++ b/assets/zano_node_list.yml
@@ -1,9 +1,12 @@
-
uri: 37.27.100.59:10500
- is_default: true
+ isDefault: true
useSSL: false
isEnabledForAutoSwitching: true
+ label: "Zano"
-
uri: zano.cakewallet.com:11211
useSSL: false
- isEnabledForAutoSwitching: true
\ No newline at end of file
+ isOfficial: true
+ isEnabledForAutoSwitching: true
+ label: "Cake Wallet"
diff --git a/assets/zcash_node_list.yml b/assets/zcash_node_list.yml
index 88db5c54..afdd4959 100644
--- a/assets/zcash_node_list.yml
+++ b/assets/zcash_node_list.yml
@@ -1,12 +1,20 @@
-- uri: zec.rocks:443
- is_default: false
+-
+ uri: zec-node.cakewallet.com:443
+ isDefault: true
+ isOfficial: true
useSSL: true
isEnabledForAutoSwitching: true
-- uri: zec-node.cakewallet.com:443
- is_default: true
+ label: "Cake Wallet"
+-
+ uri: zec.rocks:443
useSSL: true
isEnabledForAutoSwitching: true
-- uri: 2c4whzg26j6hgjh22rxynj3oig4gm22ga7x74weclujywxye23v3u5id.onion:9067
+ label: "Zec.rocks"
+-
+ uri: 2c4whzg26j6hgjh22rxynj3oig4gm22ga7x74weclujywxye23v3u5id.onion:9067
useSSL: false
-- uri: bvp2l442g5ogma7rywzahm7eqyhpp3g26n3gvvxeioqn5csio2ir6myd.onion:9067
+ label: "Cake Wallet (Tor)"
+-
+ uri: bvp2l442g5ogma7rywzahm7eqyhpp3g26n3gvvxeioqn5csio2ir6myd.onion:9067
useSSL: false
+ label: "Cake Wallet (Tor #2)"
\ No newline at end of file
diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart
index 243a88b2..ec549211 100644
--- a/cw_bitcoin/lib/electrum_wallet.dart
+++ b/cw_bitcoin/lib/electrum_wallet.dart
@@ -790,9 +790,10 @@ abstract class ElectrumWalletBase
if (server.toLowerCase().contains('electrs')) {
node!.isElectrs = true;
- if (node!.isInBox) {
+ // TODO figure out why condition was needed
+ // if (node!.isInBox) {
node!.save();
- }
+ // }
return node!.isElectrs!;
}
}
diff --git a/cw_core/lib/db/sqlite.dart b/cw_core/lib/db/sqlite.dart
index 593b1b14..eea479a8 100644
--- a/cw_core/lib/db/sqlite.dart
+++ b/cw_core/lib/db/sqlite.dart
@@ -41,7 +41,7 @@ Future<void> initDb({String? pathOverride}) async {
}
}
await db?.close();
- db = await openDatabase(dbFile.path, version: 7,
+ db = await openDatabase(dbFile.path, version: 8,
onUpgrade: (Database db, int oldVersion, int newVersion) async {
printV("migrating: $oldVersion, $newVersion");
if (oldVersion <= 1) {
@@ -104,6 +104,9 @@ CREATE TABLE IF NOT EXISTS BalanceCardStyleSettings (
definition: 'TEXT',
);
}
+ if(oldVersion <= 7) {
+ await _createNodeTable(db);
+ }
},
onCreate: (Database db, int version) async {
await db.execute(
@@ -202,6 +205,7 @@ CREATE TABLE BalanceCardStyleSettings (
);
''');
await _createBridgeTransferTable(db);
+ await _createNodeTable(db);
await _createTradeTable(db);
}
);
@@ -330,4 +334,26 @@ CREATE TABLE IF NOT EXISTS BridgeTransfer (
CREATE INDEX IF NOT EXISTS idx_bridgetransfer_wallet_id
ON BridgeTransfer(wallet_id);
''');
+}
+
+Future<void> _createNodeTable(Database db) async {
+ db.execute("""
+CREATE TABLE Node (
+NodeId INTEGER PRIMARY KEY,
+uri TEXT NOT NULL,
+path TEXT,
+login TEXT,
+label TEXT,
+password TEXT,
+isPow INTEGER NOT NULL,
+useSSL INTEGER,
+typeRaw INTEGER NOT NULL,
+trusted INTEGER NOT NULL,
+socksProxyAddress TEXT,
+isEnabledForAutoSwitching BOOLEAN DEFAULT FALSE,
+isOfficial BOOLEAN DEFAULT FALSE,
+isBuiltin BOOLEAN DEFAULT FALSE,
+isDefault BOOLEAN DEFAULT FALSE
+);
+ """);
}
\ No newline at end of file
diff --git a/cw_core/lib/node.dart b/cw_core/lib/node.dart
index 6ed3964a..b3478ed4 100644
--- a/cw_core/lib/node.dart
+++ b/cw_core/lib/node.dart
@@ -1,33 +1,62 @@
+import 'dart:convert';
import 'dart:io';
-import 'package:cw_core/keyable.dart';
+import 'dart:math' as math;
+
+import 'package:blockchain_utils/hex/hex.dart';
+import 'package:cw_core/node_list.dart';
+import 'package:cw_core/utils/print_verbose.dart';
import 'package:cw_core/utils/proxy_socket/abstract.dart';
import 'package:cw_core/utils/proxy_wrapper.dart';
-import 'package:cw_core/utils/print_verbose.dart';
-import 'dart:convert';
-import 'package:hive/hive.dart';
-import 'package:cw_core/hive_type_ids.dart';
import 'package:cw_core/wallet_type.dart';
-import 'dart:math' as math;
-import 'package:convert/convert.dart';
-
import 'package:crypto/crypto.dart';
+import 'package:sqflite/sqflite.dart';
-part 'node.g.dart';
+import 'db/sqlite.dart';
Uri createUriFromElectrumAddress(String address, String path) =>
Uri.tryParse('tcp://$address$path')!;
-@HiveType(typeId: Node.typeId)
-class Node extends HiveObject with Keyable {
+Future<void> validateBuiltinNodes() async {
+ // ensures nodes stored as builtin in the db correspond to the nodes in the .yml files
+
+ final builtinFromDb = await Node.getAllBuiltin();
+ final builtinFromList = await loadAllDefaultNodes();
+
+ for (final listNode in builtinFromList) {
+ // preserve proxy settings from user
+ try {
+ final matchedDbNode = builtinFromDb.firstWhere(
+ (dbNode) => dbNode.uri == listNode.uri
+ );
+ listNode.socksProxyAddress = matchedDbNode.socksProxyAddress;
+ } catch(e) {}
+ }
+
+ final dbSet = builtinFromDb.toSet();
+ final listSet = builtinFromList.toSet();
+
+ final nodesToDelete = dbSet.difference(listSet);
+ final nodesToAdd = listSet.difference(dbSet);
+
+ for (final node in nodesToDelete) await node.delete();
+ for (final node in nodesToAdd) await node.save();
+}
+
+class Node {
Node({
+ this.id = 0,
this.label,
this.login,
this.password,
this.useSSL,
+ this.isPow = false,
this.trusted = false,
this.socksProxyAddress,
this.path = '',
this.isEnabledForAutoSwitching = false,
+ this.isOfficial = false,
+ this.isBuiltin = false,
+ this.isDefault = false,
String? uri,
WalletType? type,
}) {
@@ -50,62 +79,144 @@ class Node extends HiveObject with Keyable {
trusted: $trusted,
socksProxyAddress: $socksProxyAddress,
isEnabledForAutoSwitching: $isEnabledForAutoSwitching,
+ isOfficial: $isOfficial,
+ isBuiltin: $isBuiltin,
+ isDefault: $isDefault
})""";
}
Node.fromMap(Map<String, Object?> map)
- : uriRaw = map['uri'] as String? ?? '',
+ : id = (map[selfIdColumn] ?? 0) as int,
+ uriRaw = map['uri'] as String? ?? '',
path = map['path'] as String? ?? '',
login = map['login'] as String?,
label = map['label'] as String?,
password = map['password'] as String?,
- useSSL = map['useSSL'] as bool?,
- trusted = map['trusted'] as bool? ?? false,
- socksProxyAddress = map['socksProxyPort'] as String?,
- isEnabledForAutoSwitching = map['isEnabledForAutoSwitching'] as bool? ?? false;
+ isPow = (map["isPow"] != null && map['isPow'] != 0) as bool? ?? false,
+ useSSL = (map['useSSL'] != 0) as bool?,
+ typeRaw = (map["typeRaw"] ?? 0) as int,
+ trusted = (map['trusted'] != 0) as bool? ?? false,
+ socksProxyAddress = map['socksProxyAddress'] as String?,
+ isEnabledForAutoSwitching = (map['isEnabledForAutoSwitching'] != 0) as bool? ?? false,
+ isOfficial = (map['isOfficial'] != 0) as bool? ?? false,
+ isBuiltin = (map['isBuiltin'] != 0) as bool? ?? false,
+ isDefault = (map['isDefault'] != 0) as bool? ?? false;
+
+ Map<String, dynamic> toMap() {
+ return {
+ selfIdColumn: id,
+ 'uri': uriRaw,
+ 'path': path,
+ 'login': login,
+ "label": label,
+ 'password': password,
+ "isPow": isPow,
+ 'useSSL': useSSL,
+ "typeRaw": typeRaw,
+ 'trusted': trusted,
+ 'socksProxyAddress': socksProxyAddress,
+ 'isEnabledForAutoSwitching': isEnabledForAutoSwitching,
+ "isOfficial": isOfficial,
+ "isBuiltin": isBuiltin,
+ "isDefault": isDefault
+ };
+ }
- static const typeId = NODE_TYPE_ID;
- static const boxName = 'Nodes';
+ Future<int> delete() async {
+ return await db!.delete(tableName, where: '${selfIdColumn} = ?', whereArgs: [id]);
+ }
- @HiveField(0, defaultValue: '')
- late String uriRaw;
+ static Future<int> deleteAll() async {
+ return await db!.delete(tableName, where: "isPow = ?", whereArgs: [false]);
+ }
- @HiveField(1)
- String? login;
+ static Future<int> deleteAllPow() async {
+ return await db!.delete(tableName, where: "isPow = ?", whereArgs: [true]);
+ }
- @HiveField(2)
- String? password;
+ Future<int> save() async {
- @HiveField(3, defaultValue: 0)
- late int typeRaw;
+ final json = toMap();
+ if (json[selfIdColumn] == 0) {
+ json[selfIdColumn] = null;
+ }
+ id = await db!.insert(tableName, json, conflictAlgorithm: ConflictAlgorithm.replace);
+ return id;
+ }
- @HiveField(4)
- bool? useSSL;
- @HiveField(5, defaultValue: false)
- bool trusted;
+ static Future<List<Node>> selectList(String where, List<dynamic> whereArgs, {String? orderBy}) async {
+ if(orderBy == null) {
+ orderBy = selfIdColumn;
+ }
+ final list = await db!.query(
+ tableName,
+ where: where.isNotEmpty ? where : "1 = 1",
+ whereArgs: whereArgs.isNotEmpty ? whereArgs : null,
+ orderBy: orderBy,
+ );
+ printV("selectList: $list");
+ return List.generate(list.length, (index) => Node.fromMap(list[index]));
+ }
- @HiveField(6)
- String? socksProxyAddress;
- @HiveField(7, defaultValue: '')
- String? path;
+ static Future<List<Node>> getAll() async {
+ return selectList("isPow = ?", [false]);
+ }
- @HiveField(8)
- bool? isElectrs;
+ static Future<List<Node>> getAllBuiltin() async {
+ return selectList("isPow = ? AND isBuiltin = ?", [false, true]);
+ }
- @HiveField(9)
- bool? supportsSilentPayments;
+ static Future<List<Node>> getAllPowBuiltin() async {
+ return selectList("isPow = ? AND isBuiltin = ?", [true, true]);
+ }
- @HiveField(10)
- bool? supportsMweb;
+ static Future<List<Node>> getAllForWalletType(WalletType type) async {
+ return selectList("typeRaw = ? AND isPow = ?", [serializeToInt(type), false]);
+ }
+
+ static Future<Node?> getDefaultForWalletType(WalletType type) async {
+ return (await selectList("typeRaw = ? AND isPow = ? AND isDefault = ?", [serializeToInt(type), false, true])).firstOrNull;
+ }
- @HiveField(11, defaultValue: false)
+ static Future<Node?> getDefaultPowForWalletType(WalletType type) async {
+ return (await selectList("typeRaw = ? AND isPow = ? AND isDefault = ?", [serializeToInt(type), true, true])).firstOrNull;
+ }
+
+ static Future<List<Node>> getAllForWalletTypePow(WalletType type) async {
+ return selectList("typeRaw = ? AND isPow = ?", [serializeToInt(type), true]);
+ }
+
+ static Future<List<Node>> getAllPow() async {
+ return selectList("isPow = ?", [true]);
+ }
+
+
+ int id;
+ late String uriRaw;
+ String? login;
+ String? password;
+ late int typeRaw;
+ bool? useSSL;
+ bool trusted;
+ bool isPow;
+ String? socksProxyAddress;
+ String? path;
+ bool? isElectrs;
+ bool? supportsSilentPayments;
+ bool? supportsMweb;
bool isEnabledForAutoSwitching;
+ bool isOfficial;
+ bool isBuiltin;
+ bool isDefault;
- @HiveField(12, defaultValue: '')
String? label;
+ static String get tableName => "Node";
+ static String get selfIdColumn => "${tableName}Id";
+
+
bool get isSSL => useSSL ?? false;
bool get useSocksProxy => socksProxyAddress == null ? false : socksProxyAddress!.isNotEmpty;
@@ -167,18 +278,11 @@ class Node extends HiveObject with Keyable {
socksProxyAddress.hashCode ^
path.hashCode;
- @override
- dynamic get keyIndex {
- _keyIndex ??= key;
- return _keyIndex;
- }
WalletType get type => deserializeFromInt(typeRaw);
set type(WalletType type) => typeRaw = serializeToInt(type);
- dynamic _keyIndex;
-
Future<bool> requestNode() async {
try {
switch (type) {
@@ -228,7 +332,7 @@ class Node extends HiveObject with Keyable {
body: jsonBody,
);
-
+
final resBody = json.decode(response.body) as Map<String, dynamic>;
return resBody['result']['height'] != null;
diff --git a/cw_core/lib/node_legacy.dart b/cw_core/lib/node_legacy.dart
new file mode 100644
index 00000000..3c39b6f9
--- /dev/null
+++ b/cw_core/lib/node_legacy.dart
@@ -0,0 +1,237 @@
+import 'dart:io';
+import 'package:cw_core/keyable.dart';
+import 'package:cw_core/node_list.dart';
+import 'package:cw_core/utils/proxy_socket/abstract.dart';
+import 'package:cw_core/utils/proxy_wrapper.dart';
+import 'package:cw_core/utils/print_verbose.dart';
+import 'dart:convert';
+import 'package:hive/hive.dart';
+import 'package:cw_core/hive_type_ids.dart';
+import 'package:cw_core/wallet_type.dart';
+import 'dart:math' as math;
+import 'package:convert/convert.dart';
+
+import 'package:crypto/crypto.dart';
+
+import 'cake_hive.dart';
+import 'node.dart' as node_new;
+
+part "node_legacy.g.dart";
+
+Future<void> performNodeHiveMigration() async {
+ if(!CakeHive.isAdapterRegistered(Node.typeId)) {
+ CakeHive.registerAdapter(NodeAdapter());
+ }
+
+ final nodeBox = await CakeHive.openBox<Node>(Node.boxName);
+ final powNodeBox = await CakeHive.openBox<Node>(Node.boxName+"pow");
+ final builtinNodes = await loadAllDefaultNodes();
+ final builtinPowNodes = await loadDefaultNanoPowNodes();
+ await Node.migrateAllToSqlite(nodeBox, powNodeBox, builtinNodes, builtinPowNodes);
+
+
+}
+
+Uri createUriFromElectrumAddress(String address, String path) =>
+ Uri.tryParse('tcp://$address$path')!;
+
+@HiveType(typeId: Node.typeId)
+class Node extends HiveObject with Keyable {
+ Node({
+ this.label,
+ this.login,
+ this.password,
+ this.useSSL,
+ this.trusted = false,
+ this.socksProxyAddress,
+ this.path = '',
+ this.isEnabledForAutoSwitching = false,
+ String? uri,
+ WalletType? type,
+ }) {
+ if (uri != null) {
+ uriRaw = uri;
+ }
+ if (type != null) {
+ this.type = type;
+ }
+ }
+
+ static Future<void> migrateAllToSqlite(Box<Node> nodeBox, Box<Node> powNodeBox,
+ List<node_new.Node> defaultNodes, List<node_new.Node> defaultPowNodes) async {
+ final list = nodeBox.values.toList();
+ final powList = powNodeBox.values.toList();
+ for (final node in list) {
+ if(defaultNodes.any((item)=>item.uri == node.uri)) {
+ // default nodes will be added by validateBuiltinNodes(), no need to migrate them.
+ await node.delete();
+ continue;
+ }
+ await node.migrateToSqlite(
+ isPow: false,
+ isBuiltin: false,
+ isOfficial: false);
+ await node.delete();
+ }
+ for (final node in powList) {
+ if(defaultPowNodes.any((item)=>item.uri == node.uri)) {
+ await node.delete();
+ continue;
+ }
+ await node.migrateToSqlite(
+ isPow: true,
+ isBuiltin: false,
+ isOfficial: false);
+ await node.delete();
+ }
+ }
+
+ Future<void> migrateToSqlite({required bool isPow, required bool isBuiltin, required bool isOfficial}) async {
+ final newNode = node_new.Node(
+ id: key as int,
+ login: login,
+ label: label,
+ password: password,
+ type: type,
+ useSSL: useSSL,
+ trusted: trusted,
+ socksProxyAddress: socksProxyAddress,
+ isPow: isPow,
+ path: path,
+ uri: uriRaw,
+ isEnabledForAutoSwitching: isEnabledForAutoSwitching,
+ isOfficial: isOfficial,
+ isBuiltin: isBuiltin,
+ );
+ await newNode.save();
+ }
+
+
+ Node.fromMap(Map<String, Object?> map)
+ : uriRaw = map['uri'] as String? ?? '',
+ path = map['path'] as String? ?? '',
+ login = map['login'] as String?,
+ label = map['label'] as String?,
+ password = map['password'] as String?,
+ useSSL = map['useSSL'] as bool?,
+ trusted = map['trusted'] as bool? ?? false,
+ socksProxyAddress = map['socksProxyPort'] as String?,
+ isEnabledForAutoSwitching = map['isEnabledForAutoSwitching'] as bool? ?? false;
+
+ static const typeId = NODE_TYPE_ID;
+ static const boxName = 'Nodes';
+
+ @HiveField(0, defaultValue: '')
+ late String uriRaw;
+
+ @HiveField(1)
+ String? login;
+
+ @HiveField(2)
+ String? password;
+
+ @HiveField(3, defaultValue: 0)
+ late int typeRaw;
+
+ @HiveField(4)
+ bool? useSSL;
+
+ @HiveField(5, defaultValue: false)
+ bool trusted;
+
+ @HiveField(6)
+ String? socksProxyAddress;
+
+ @HiveField(7, defaultValue: '')
+ String? path;
+
+ @HiveField(8)
+ bool? isElectrs;
+
+ @HiveField(9)
+ bool? supportsSilentPayments;
+
+ @HiveField(10)
+ bool? supportsMweb;
+
+ @HiveField(11, defaultValue: false)
+ bool isEnabledForAutoSwitching;
+
+ @HiveField(12, defaultValue: '')
+ String? label;
+
+ bool get isSSL => useSSL ?? false;
+
+ bool get useSocksProxy => socksProxyAddress == null ? false : socksProxyAddress!.isNotEmpty;
+
+ Uri get uri {
+ switch (type) {
+ case WalletType.monero:
+ case WalletType.zcash:
+ case WalletType.haven:
+ case WalletType.wownero:
+ return Uri.http(uriRaw, '');
+ case WalletType.bitcoin:
+ case WalletType.litecoin:
+ case WalletType.bitcoinCash:
+ case WalletType.dogecoin:
+ return createUriFromElectrumAddress(uriRaw, path!);
+ case WalletType.nano:
+ case WalletType.banano:
+ case WalletType.ethereum:
+ case WalletType.polygon:
+ case WalletType.base:
+ case WalletType.bsc:
+ case WalletType.arbitrum:
+ case WalletType.solana:
+ case WalletType.tron:
+ case WalletType.zano:
+ case WalletType.decred:
+ return Uri.parse(
+ "http${isSSL ? "s" : ""}://$uriRaw${path!.startsWith("/") || path!.isEmpty ? path : "/$path"}");
+ case WalletType.none:
+ throw Exception('Unexpected type ${type.toString()} for Node uri');
+ }
+ }
+
+ bool get isValidProxyAddress => socksProxyAddress?.contains(':') ?? false;
+
+ @override
+ bool operator ==(other) =>
+ other is Node &&
+ (other.uriRaw == uriRaw &&
+ other.login == login &&
+ other.label == label &&
+ other.password == password &&
+ other.typeRaw == typeRaw &&
+ other.useSSL == useSSL &&
+ other.trusted == trusted &&
+ other.socksProxyAddress == socksProxyAddress &&
+ other.path == path);
+
+ @override
+ int get hashCode =>
+ uriRaw.hashCode ^
+ login.hashCode ^
+ label.hashCode ^
+ password.hashCode ^
+ typeRaw.hashCode ^
+ useSSL.hashCode ^
+ trusted.hashCode ^
+ socksProxyAddress.hashCode ^
+ path.hashCode;
+
+ @override
+ dynamic get keyIndex {
+ _keyIndex ??= key;
+ return _keyIndex;
+ }
+
+ WalletType get type => deserializeFromInt(typeRaw);
+
+ set type(WalletType type) => typeRaw = serializeToInt(type);
+
+ dynamic _keyIndex;
+
+
+}
\ No newline at end of file
diff --git a/cw_core/lib/node_list.dart b/cw_core/lib/node_list.dart
new file mode 100644
index 00000000..e46f0eee
--- /dev/null
+++ b/cw_core/lib/node_list.dart
@@ -0,0 +1,188 @@
+import 'package:flutter/services.dart';
+import 'package:hive/hive.dart';
+import "package:yaml/yaml.dart";
+import 'package:cw_core/node.dart';
+import 'package:cw_core/wallet_type.dart';
+
+Future<List<Node>> loadDefaultNodes(WalletType type) async {
+ String path;
+ switch (type) {
+ case WalletType.monero:
+ path = 'assets/node_list.yml';
+ break;
+ case WalletType.bitcoin:
+ path = 'assets/bitcoin_electrum_server_list.yml';
+ break;
+ case WalletType.litecoin:
+ path = 'assets/litecoin_electrum_server_list.yml';
+ break;
+ case WalletType.haven:
+ path = 'assets/haven_node_list.yml';
+ break;
+ // TODO: (refactoring) each wallet would have its path, so `wallet.nodePath` would be decided based on chain id in Evm wallet
+ case WalletType.ethereum:
+ path = 'assets/ethereum_server_list.yml';
+ break;
+ case WalletType.nano:
+ path = 'assets/nano_node_list.yml';
+ break;
+ case WalletType.bitcoinCash:
+ path = 'assets/bitcoin_cash_electrum_server_list.yml';
+ break;
+ case WalletType.polygon:
+ path = 'assets/polygon_node_list.yml';
+ break;
+ case WalletType.solana:
+ path = 'assets/solana_node_list.yml';
+ break;
+ case WalletType.tron:
+ path = 'assets/tron_node_list.yml';
+ break;
+ case WalletType.wownero:
+ path = 'assets/wownero_node_list.yml';
+ break;
+ case WalletType.zano:
+ path = 'assets/zano_node_list.yml';
+ break;
+ case WalletType.decred:
+ path = 'assets/decred_node_list.yml';
+ break;
+ case WalletType.dogecoin:
+ path = 'assets/dogecoin_electrum_server_list.yml';
+ break;
+ case WalletType.base:
+ path = 'assets/base_node_list.yml';
+ break;
+ case WalletType.arbitrum:
+ path = 'assets/arbitrum_node_list.yml';
+ break;
+ case WalletType.zcash:
+ path = 'assets/zcash_node_list.yml';
+ break;
+ case WalletType.bsc:
+ path = 'assets/bsc_node_list.yml';
+ break;
+ case WalletType.banano:
+ case WalletType.none:
+ path = '';
+ break;
+ }
+
+ final nodesRaw = await rootBundle.loadString(path);
+ final loadedNodes = loadYaml(nodesRaw) as YamlList;
+ final nodes = <Node>[];
+
+ for (final raw in loadedNodes) {
+ if (raw is Map) {
+ final map = Map.from(raw);
+ map["isBuiltin"] = 1;
+ map["isOfficial"] = ((map["isOfficial"] as bool? ?? false) ? 1 : 0);
+ map["isDefault"] = ((map["isDefault"] as bool? ?? false) ? 1 : 0);
+ final node = Node.fromMap(Map<String, Object>.from(map));
+ node.type = type;
+ nodes.add(node);
+ }
+ }
+
+ return nodes;
+}
+
+Future<List<Node>> loadDefaultNanoPowNodes() async {
+ final powNodesRaw = await rootBundle.loadString('assets/nano_pow_node_list.yml');
+ final loadedPowNodes = loadYaml(powNodesRaw) as YamlList;
+ final nodes = <Node>[];
+
+ for (final raw in loadedPowNodes) {
+ if (raw is Map) {
+ final node = Node.fromMap(Map<String, Object>.from(raw));
+ node.isPow = true;
+ node.type = WalletType.nano;
+ nodes.add(node);
+ }
+ }
+
+ return nodes;
+}
+
+Future<List<Node>> loadAllDefaultNodes() async {
+ final moneroNodes = await loadDefaultNodes(WalletType.monero);
+ final bitcoinElectrumServerList = await loadDefaultNodes(WalletType.bitcoin);
+ final litecoinElectrumServerList = await loadDefaultNodes(WalletType.litecoin);
+ final bitcoinCashElectrumServerList = await loadDefaultNodes(WalletType.bitcoinCash);
+ final havenNodes = await loadDefaultNodes(WalletType.haven);
+ final ethereumNodes = await loadDefaultNodes(WalletType.ethereum);
+ final nanoNodes = await loadDefaultNodes(WalletType.nano);
+ final polygonNodes = await loadDefaultNodes(WalletType.polygon);
+ final solanaNodes = await loadDefaultNodes(WalletType.solana);
+ final tronNodes = await loadDefaultNodes(WalletType.tron);
+ final decredNodes = await loadDefaultNodes(WalletType.decred);
+ final zanoNodes = await loadDefaultNodes(WalletType.zano);
+ final dogecoinElectrumServerList = await loadDefaultNodes(WalletType.dogecoin);
+ final baseNodes = await loadDefaultNodes(WalletType.base);
+ final arbitrumNodes = await loadDefaultNodes(WalletType.arbitrum);
+ final zcashNodes = await loadDefaultNodes(WalletType.zcash);
+ final bscNodes = await loadDefaultNodes(WalletType.bsc);
+
+ return moneroNodes +
+ bitcoinElectrumServerList +
+ litecoinElectrumServerList +
+ havenNodes +
+ ethereumNodes +
+ bitcoinCashElectrumServerList +
+ nanoNodes +
+ polygonNodes +
+ solanaNodes +
+ tronNodes +
+ zanoNodes +
+ decredNodes +
+ dogecoinElectrumServerList +
+ baseNodes +
+ arbitrumNodes +
+ zcashNodes +
+ bscNodes;
+}
+
+Future<void> resetToDefault() async {
+
+ final nodes = await loadAllDefaultNodes();
+
+ final currentNodes = await Node.getAll();
+
+ // after reset, nodes should retain the id to correspond with the ones in shared prefs.
+ // alternative would be nuking the shared prefs on reset
+ for (final node in nodes) {
+ try {
+ final curr = currentNodes.firstWhere(
+ (item) => item.uri == node.uri && item.typeRaw == node.typeRaw,
+ );
+ node.id = curr.id;
+ } catch(e) {}
+
+ }
+
+ await Node.deleteAll();
+ for(final node in nodes) {
+ await node.save();
+ }
+}
+
+Future<void> resetPowToDefault() async {
+ final nanoPowNodes = await loadDefaultNanoPowNodes();
+ await Node.deleteAllPow();
+ for(final node in nanoPowNodes) {
+ node.save();
+ }
+}
+
+Future<Node> getDefaultNodeFromFiles(WalletType type, {bool isPow = false}) async {
+ final nodes = isPow ? await loadDefaultNanoPowNodes() : await loadDefaultNodes(type);
+ try {
+ return nodes.firstWhere((item)=>item.isDefault);
+ } catch(e) {
+ // ideally the yamls would always have a default, but this is better than nothing
+ return nodes.first;
+ }
+}
+
+
+
diff --git a/lib/core/node_switching_service.dart b/lib/core/node_switching_service.dart
index c17ec2e4..d7908eeb 100644
--- a/lib/core/node_switching_service.dart
+++ b/lib/core/node_switching_service.dart
@@ -14,7 +14,6 @@ class NodeSwitchingService {
NodeSwitchingService({
required this.appStore,
required this.settingsStore,
- required this.nodeSource,
});
static const int _healthCheckIntervalSeconds = 30;
@@ -38,7 +37,6 @@ class NodeSwitchingService {
final AppStore appStore;
final SettingsStore settingsStore;
- final Box<Node> nodeSource;
final Map<WalletType, List<dynamic>> _usedNodeKeys = {};
@@ -118,13 +116,13 @@ class NodeSwitchingService {
WalletType walletType,
) async {
for (final node in nodes) {
- if (!_usedNodeKeys[walletType]!.contains(node.key)) {
+ if (!_usedNodeKeys[walletType]!.contains(node.id)) {
final isActive = await node.requestNode();
if (isActive) {
return node;
} else {
printV('Node ${node.uriRaw} is not active. Marking as used.');
- _usedNodeKeys[walletType]!.add(node.key);
+ _usedNodeKeys[walletType]!.add(node.id);
}
}
}
@@ -157,7 +155,7 @@ class NodeSwitchingService {
final currentNode = settingsStore.getCurrentNode(nodeWalletType, chainId: chainId);
// Get all trusted nodes for this wallet type
- final trustedNodes = nodeSource.values
+ final trustedNodes = (await Node.getAll())
.where((node) => node.type == nodeWalletType && node.isEnabledForAutoSwitching)
.toList();
@@ -171,8 +169,8 @@ class NodeSwitchingService {
_usedNodeKeys.putIfAbsent(nodeWalletType, () => []);
// Add current node to used list if not already there
- if (!_usedNodeKeys[nodeWalletType]!.contains(currentNode.key)) {
- _usedNodeKeys[nodeWalletType]!.add(currentNode.key);
+ if (!_usedNodeKeys[nodeWalletType]!.contains(currentNode.id)) {
+ _usedNodeKeys[nodeWalletType]!.add(currentNode.id);
}
// Try to find an active unused node
@@ -199,8 +197,8 @@ class NodeSwitchingService {
}
// Ensure the selected node is marked as used
- if (!_usedNodeKeys[nodeWalletType]!.contains(nextNode.key)) {
- _usedNodeKeys[nodeWalletType]!.add(nextNode.key);
+ if (!_usedNodeKeys[nodeWalletType]!.contains(nextNode.id)) {
+ _usedNodeKeys[nodeWalletType]!.add(nextNode.id);
}
printV(
diff --git a/lib/di.dart b/lib/di.dart
index 50a7cefc..aa42887d 100644
--- a/lib/di.dart
+++ b/lib/di.dart
@@ -326,8 +326,8 @@ import 'src/screens/buy/buy_sell_page.dart';
final getIt = GetIt.instance;
var _isSetupFinished = false;
-late Box<Node> _nodeSource;
-late Box<Node> _powNodeSource;
+// late Box<Node> _nodeSource;
+// late Box<Node> _powNodeSource;
late Box<Contact> _contactSource;
late Box<Template> _templates;
late Box<ExchangeTemplate> _exchangeTemplates;
@@ -337,8 +337,6 @@ late Box<UnspentCoinsInfo> _unspentCoinsInfoSource;
late Box<PayjoinSession> _payjoinSessionSource;
late Box<AnonpayInvoiceInfo> _anonpayInvoiceInfoSource;
Future<void> setup({
- required Box<Node> nodeSource,
- required Box<Node> powNodeSource,
required Box<Contact> contactSource,
required Box<Template> templates,
required Box<ExchangeTemplate> exchangeTemplates,
@@ -350,8 +348,6 @@ Future<void> setup({
required SecureStorage secureStorage,
required GlobalKey<NavigatorState> navigatorKey,
}) async {
- _nodeSource = nodeSource;
- _powNodeSource = powNodeSource;
_contactSource = contactSource;
_templates = templates;
_exchangeTemplates = exchangeTemplates;
@@ -376,8 +372,6 @@ Future<void> setup({
(secrets.wyreAccountId.isNotEmpty);
final settingsStore = await SettingsStoreBase.load(
- nodeSource: _nodeSource,
- powNodeSource: _powNodeSource,
isBitcoinBuyEnabled: isBitcoinBuyEnabled,
);
@@ -385,18 +379,16 @@ Future<void> setup({
return;
}
- getIt.registerFactory<Box<Node>>(() => _nodeSource);
- getIt.registerFactory<Box<Node>>(() => _powNodeSource, instanceName: Node.boxName + "pow");
getIt.registerSingleton(AuthenticationStore());
getIt.registerSingleton<WalletListStore>(WalletListStore());
- getIt.registerSingleton(NodeListStoreBase.instance);
+ // getIt.registerSingleton(NodeListStoreBase.instance);
getIt.registerSingleton<SettingsStore>(settingsStore);
getIt.registerSingleton<AppStore>(AppStore(
authenticationStore: getIt.get<AuthenticationStore>(),
walletList: getIt.get<WalletListStore>(),
settingsStore: getIt.get<SettingsStore>(),
- nodeListStore: getIt.get<NodeListStore>(),
+ // nodeListStore: getIt.get<NodeListStore>(),
themeStore: getIt.get<ThemeStore>()));
getIt.registerSingleton<TradesStore>(
TradesStore(appStore: getIt.get<AppStore>()));
@@ -1126,22 +1118,22 @@ Future<void> setup({
getIt.registerFactory(() => AddressListPage(getIt.get<WalletAddressListViewModel>()));
+ getIt.registerLazySingleton(() {
+ final appStore = getIt.get<AppStore>();
+ return NodeListViewModel(appStore);
+ });
+
getIt.registerFactoryParam<NewAddressesPage, bool, void>(
- (showHidden, _) => NewAddressesPage(
+ (showHidden, _) => NewAddressesPage(
showHidden: showHidden,
addressListViewModel: getIt<WalletAddressListViewModel>(),
dashboardViewModel: getIt<DashboardViewModel>(),
),
);
- getIt.registerFactory(() {
+ getIt.registerLazySingleton(() {
final appStore = getIt.get<AppStore>();
- return NodeListViewModel(_nodeSource, appStore);
- });
-
- getIt.registerFactory(() {
- final appStore = getIt.get<AppStore>();
- return PowNodeListViewModel(_powNodeSource, appStore);
+ return PowNodeListViewModel(appStore);
});
getIt.registerFactory(() => ConnectionSyncViewModel(getIt.get<SettingsStore>(), getIt.get<AppStore>().wallet!));
@@ -1184,12 +1176,14 @@ Future<void> setup({
final WalletType type = args['type'] as WalletType? ?? getIt.get<AppStore>().wallet!.type;
final bool isPow = args['isPow'] as bool? ?? false;
final Node? editingNode = args['editingNode'] as Node?;
- final nodeSourceArgs = isPow ? _powNodeSource : _nodeSource;
return NodeCreateOrEditViewModel(
- nodeSourceArgs,
- type,
- editingNode,
- getIt.get<SettingsStore>());
+ isPow,
+ getIt.get<NodeListViewModel>(),
+ getIt.get<PowNodeListViewModel>(),
+ type,
+ getIt.get<SettingsStore>(),
+ editingNode: editingNode
+ );
}
);
@@ -1791,7 +1785,6 @@ Future<void> setup({
getIt.registerLazySingleton(() => NodeSwitchingService(
appStore: getIt.get<AppStore>(),
settingsStore: getIt.get<SettingsStore>(),
- nodeSource: _nodeSource,
));
getIt.registerFactoryParam<BridgeAmountPage, CryptoCurrency, void>(
diff --git a/lib/entities/default_settings_migration.dart b/lib/entities/default_settings_migration.dart
index df3977d0..e578a34a 100644
--- a/lib/entities/default_settings_migration.dart
+++ b/lib/entities/default_settings_migration.dart
@@ -18,6 +18,7 @@ import 'package:cake_wallet/wownero/wownero.dart';
import 'package:collection/collection.dart';
import 'package:cw_core/node.dart';
import 'package:cake_wallet/entities/sync_status_display_mode.dart';
+import 'package:cw_core/node_list.dart';
import 'package:cw_core/pathForWallet.dart';
import 'package:cw_core/root_dir.dart';
import 'package:cw_core/spl_token.dart';
@@ -61,8 +62,6 @@ Future<void> defaultSettingsMigration(
{required int version,
required SharedPreferences sharedPreferences,
required SecureStorage secureStorage,
- required Box<Node> nodes,
- required Box<Node> powNodes,
required Box<Contact> contactSource,
required Box<HavenSeedStore> havenSeedStore}) async {
if (Platform.isIOS) {
@@ -70,7 +69,7 @@ Future<void> defaultSettingsMigration(
}
// check current nodes for nullability regardless of the version
- await checkCurrentNodes(nodes, powNodes, sharedPreferences);
+ // await checkCurrentNodes(sharedPreferences);
final isNewInstall =
sharedPreferences.getInt(PreferencesKey.currentDefaultSettingsMigrationVersion) == null;
@@ -103,10 +102,9 @@ Future<void> defaultSettingsMigration(
await sharedPreferences.setInt(
PreferencesKey.currentBalanceDisplayModeKey, BalanceDisplayMode.availableBalance.raw);
await sharedPreferences.setBool('save_recipient_address', true);
- await resetToDefault(nodes);
+ await resetToDefault();
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.monero,
currentNodePreferenceKey: PreferencesKey.currentNodeIdKey,
@@ -114,30 +112,26 @@ Future<void> defaultSettingsMigration(
trusted: true,
);
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.bitcoin,
currentNodePreferenceKey: PreferencesKey.currentBitcoinElectrumSererIdKey,
useSSL: true,
);
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.litecoin,
currentNodePreferenceKey: PreferencesKey.currentLitecoinElectrumSererIdKey,
useSSL: true,
);
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.haven,
currentNodePreferenceKey: PreferencesKey.currentHavenNodeIdKey,
);
break;
case 2:
- await replaceNodesMigration(nodes: nodes);
+ await replaceNodesMigration();
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.monero,
newDefaultUri: newCakeWalletMoneroUri,
@@ -152,13 +146,12 @@ Future<void> defaultSettingsMigration(
);
break;
case 3:
- await updateNodeTypes(nodes: nodes);
- await addWalletNodeList(nodes: nodes, type: WalletType.bitcoin);
+ await updateNodeTypes();
+ await addWalletNodeList(type: WalletType.bitcoin);
break;
case 4:
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.bitcoin,
newDefaultUri: newCakeWalletBitcoinUri,
@@ -185,7 +178,6 @@ Future<void> defaultSettingsMigration(
case 11:
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.monero,
newDefaultUri: newCakeWalletMoneroUri,
@@ -196,38 +188,35 @@ Future<void> defaultSettingsMigration(
break;
case 12:
- await checkCurrentNodes(nodes, powNodes, sharedPreferences);
+ // await checkCurrentNodes(sharedPreferences);
break;
case 13:
- await resetBitcoinElectrumServer(nodes, sharedPreferences);
+ await resetBitcoinElectrumServer(sharedPreferences);
break;
case 15:
- await addWalletNodeList(nodes: nodes, type: WalletType.litecoin);
+ await addWalletNodeList(type: WalletType.litecoin);
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.litecoin,
currentNodePreferenceKey: PreferencesKey.currentLitecoinElectrumSererIdKey,
);
- await checkCurrentNodes(nodes, powNodes, sharedPreferences);
+ // await checkCurrentNodes(sharedPreferences);
break;
case 16:
- await addWalletNodeList(nodes: nodes, type: WalletType.haven);
+ await addWalletNodeList(type: WalletType.haven);
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.haven,
currentNodePreferenceKey: PreferencesKey.currentHavenNodeIdKey,
);
- await checkCurrentNodes(nodes, powNodes, sharedPreferences);
+ // await checkCurrentNodes(sharedPreferences);
break;
case 17:
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.haven,
currentNodePreferenceKey: PreferencesKey.currentHavenNodeIdKey,
@@ -235,7 +224,7 @@ Future<void> defaultSettingsMigration(
break;
case 18:
- addWalletNodeList(nodes: nodes, type: WalletType.monero);
+ addWalletNodeList(type: WalletType.monero);
break;
case 19:
@@ -245,25 +234,22 @@ Future<void> defaultSettingsMigration(
await migrateExchangeStatus(sharedPreferences);
break;
case 21:
- await addWalletNodeList(nodes: nodes, type: WalletType.ethereum);
+ await addWalletNodeList(type: WalletType.ethereum);
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.ethereum,
currentNodePreferenceKey: PreferencesKey.currentEthereumNodeIdKey,
);
break;
case 22:
- await addWalletNodeList(nodes: nodes, type: WalletType.nano);
- await addNanoPowNodeList(nodes: powNodes);
+ await addWalletNodeList(type: WalletType.nano);
+ await addNanoPowNodeList();
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.nano,
currentNodePreferenceKey: PreferencesKey.currentNanoNodeIdKey,
);
await _changeDefaultNode(
- nodes: powNodes,
sharedPreferences: sharedPreferences,
type: WalletType.nano,
currentNodePreferenceKey: PreferencesKey.currentNanoPowNodeIdKey,
@@ -271,18 +257,16 @@ Future<void> defaultSettingsMigration(
);
break;
case 23:
- await addWalletNodeList(nodes: nodes, type: WalletType.bitcoinCash);
+ await addWalletNodeList(type: WalletType.bitcoinCash);
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.bitcoinCash,
currentNodePreferenceKey: PreferencesKey.currentBitcoinCashNodeIdKey,
);
break;
case 24:
- await addWalletNodeList(nodes: nodes, type: WalletType.polygon);
+ await addWalletNodeList(type: WalletType.polygon);
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.polygon,
currentNodePreferenceKey: PreferencesKey.currentPolygonNodeIdKey,
@@ -299,9 +283,8 @@ Future<void> defaultSettingsMigration(
// await insecureStorageMigration(secureStorage: secureStorage, sharedPreferences: sharedPreferences);
break;
case 27:
- await addWalletNodeList(nodes: nodes, type: WalletType.solana);
+ await addWalletNodeList( type: WalletType.solana);
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.solana,
currentNodePreferenceKey: PreferencesKey.currentSolanaNodeIdKey,
@@ -313,7 +296,6 @@ Future<void> defaultSettingsMigration(
break;
case 29:
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.bitcoin,
newDefaultUri: newCakeWalletBitcoinUri,
@@ -326,25 +308,23 @@ Future<void> defaultSettingsMigration(
await disableServiceStatusFiatDisabled(sharedPreferences);
break;
case 31:
- await updateNanoNodeList(nodes: nodes);
+ await updateNanoNodeList();
break;
case 32:
await updateBtcNanoWalletInfos();
break;
case 33:
- await addWalletNodeList(nodes: nodes, type: WalletType.tron);
+ await addWalletNodeList(type: WalletType.tron);
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.tron,
currentNodePreferenceKey: PreferencesKey.currentTronNodeIdKey,
);
break;
case 34:
- addWalletNodeList(nodes: nodes, type: WalletType.bitcoin);
+ addWalletNodeList(type: WalletType.bitcoin);
case 35:
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.bitcoin,
newDefaultUri: newCakeWalletBitcoinUri,
@@ -354,9 +334,8 @@ Future<void> defaultSettingsMigration(
);
break;
case 36:
- await addWalletNodeList(nodes: nodes, type: WalletType.wownero);
+ await addWalletNodeList(type: WalletType.wownero);
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.wownero,
currentNodePreferenceKey: PreferencesKey.currentWowneroNodeIdKey,
@@ -370,9 +349,8 @@ Future<void> defaultSettingsMigration(
await fixBtcDerivationPaths();
break;
case 39:
- _fixNodesUseSSLFlag(nodes);
+ _fixNodesUseSSLFlag();
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.nano,
newDefaultUri: nanoDefaultNodeUri,
@@ -382,7 +360,7 @@ Future<void> defaultSettingsMigration(
);
break;
case 40:
- await removeMoneroWorld(sharedPreferences: sharedPreferences, nodes: nodes);
+ await removeMoneroWorld(sharedPreferences: sharedPreferences);
break;
case 41:
_changeExchangeProviderAvailability(
@@ -390,14 +368,14 @@ Future<void> defaultSettingsMigration(
providerName: "SwapTrade",
enabled: false,
);
- addWalletNodeList(nodes: nodes, type: WalletType.bitcoin);
- addWalletNodeList(nodes: nodes, type: WalletType.tron);
+ addWalletNodeList(type: WalletType.bitcoin);
+ addWalletNodeList(type: WalletType.tron);
break;
case 42:
- _fixNodesUseSSLFlag(nodes);
+ _fixNodesUseSSLFlag();
break;
case 43:
- _fixNodesUseSSLFlag(nodes);
+ _fixNodesUseSSLFlag();
_changeExchangeProviderAvailability(
sharedPreferences,
providerName: "THORChain",
@@ -410,9 +388,8 @@ Future<void> defaultSettingsMigration(
);
break;
case 44:
- _fixNodesUseSSLFlag(nodes);
+ _fixNodesUseSSLFlag();
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.bitcoin,
newDefaultUri: newCakeWalletBitcoinUri,
@@ -421,7 +398,6 @@ Future<void> defaultSettingsMigration(
oldUri: ['cakewallet.com'],
);
_changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.tron,
newDefaultUri: tronDefaultNodeUri,
@@ -436,10 +412,9 @@ Future<void> defaultSettingsMigration(
case 45:
// await _backupHavenSeeds(havenSeedStore);
- addWalletNodeList(nodes: nodes, type: WalletType.polygon);
- addWalletNodeList(nodes: nodes, type: WalletType.ethereum);
+ addWalletNodeList(type: WalletType.polygon);
+ addWalletNodeList(type: WalletType.ethereum);
_changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.tron,
newDefaultUri: tronDefaultNodeUri,
@@ -451,7 +426,6 @@ Future<void> defaultSettingsMigration(
],
);
_changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.solana,
newDefaultUri: solanaDefaultNodeUri,
@@ -461,10 +435,9 @@ Future<void> defaultSettingsMigration(
);
break;
case 46:
- await _fixNodesUseSSLFlag(nodes);
- await addWalletNodeList(nodes: nodes, type: WalletType.litecoin);
+ await _fixNodesUseSSLFlag();
+ await addWalletNodeList(type: WalletType.litecoin);
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.solana,
newDefaultUri: solanaDefaultNodeUri,
@@ -477,21 +450,18 @@ Future<void> defaultSettingsMigration(
],
);
await _updateNode(
- nodes: nodes,
currentUri: "ethereum.publicnode.com",
newUri: "ethereum-rpc.publicnode.com",
useSSL: true,
);
await _updateNode(
- nodes: nodes,
currentUri: "polygon-bor.publicnode.com",
newUri: "polygon-bor-rpc.publicnode.com",
useSSL: true,
);
case 47:
- await addWalletNodeList(nodes: nodes, type: WalletType.zano);
+ await addWalletNodeList(type: WalletType.zano);
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.zano,
currentNodePreferenceKey: PreferencesKey.currentZanoNodeIdKey,
@@ -508,9 +478,8 @@ Future<void> defaultSettingsMigration(
);
break;
case 48:
- await addWalletNodeList(nodes: nodes, type: WalletType.decred);
+ await addWalletNodeList(type: WalletType.decred);
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.decred,
currentNodePreferenceKey: PreferencesKey.currentDecredNodeIdKey,
@@ -524,36 +493,32 @@ Future<void> defaultSettingsMigration(
);
break;
case 50:
- migrateExistingNodesToUseAutoSwitching(nodes: nodes, powNodes: powNodes);
+ migrateExistingNodesToUseAutoSwitching();
break;
case 51:
_changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.zano,
currentNodePreferenceKey: PreferencesKey.currentZanoNodeIdKey,
);
- await addWalletNodeList(nodes: nodes, type: WalletType.dogecoin);
+ await addWalletNodeList(type: WalletType.dogecoin);
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.dogecoin,
currentNodePreferenceKey: PreferencesKey.currentDogecoinNodeIdKey,
);
break;
case 52:
- await addWalletNodeList(nodes: nodes, type: WalletType.base);
+ await addWalletNodeList(type: WalletType.base);
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.base,
currentNodePreferenceKey: PreferencesKey.currentBaseNodeIdKey,
);
break;
- case 53:
- await addWalletNodeList(nodes: nodes, type: WalletType.arbitrum);
+ case 53:
+ await addWalletNodeList(type: WalletType.arbitrum);
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.arbitrum,
currentNodePreferenceKey: PreferencesKey.currentArbitrumNodeIdKey,
@@ -563,9 +528,8 @@ Future<void> defaultSettingsMigration(
await _backupWowneroSeeds(havenSeedStore);
break;
case 55:
- await addWalletNodeList(nodes: nodes, type: WalletType.zcash);
+ await addWalletNodeList(type: WalletType.zcash);
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.zcash,
currentNodePreferenceKey: PreferencesKey.currentZcashNodeIdKey,
@@ -577,9 +541,8 @@ Future<void> defaultSettingsMigration(
case 57:
await _addXautTokenToExistingEthereumWallets();
- await addWalletNodeList(nodes: nodes, type: WalletType.bsc);
+ await addWalletNodeList(type: WalletType.bsc);
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.bsc,
currentNodePreferenceKey: PreferencesKey.currentBscNodeIdKey,
@@ -624,13 +587,18 @@ Future<void> defaultSettingsMigration(
break;
case 65:
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.base,
currentNodePreferenceKey: PreferencesKey.currentBaseNodeIdKey,
oldUri: ['base.nownodes.io'],
);
break;
+ case 66:
+ await _changeDefaultNode(
+ sharedPreferences: sharedPreferences,
+ type: WalletType.arbitrum,
+ currentNodePreferenceKey: PreferencesKey.currentArbitrumNodeIdKey,
+ oldUri: ["arbitrum.nownodes.io"]);
default:
break;
}
@@ -647,12 +615,13 @@ Future<void> defaultSettingsMigration(
}
Future<void> _updateNode({
- required Box<Node> nodes,
required String currentUri,
String? newUri,
bool? useSSL,
}) async {
- for (Node node in nodes.values) {
+ final nodes = await Node.getAll();
+
+ for (Node node in nodes) {
if (node.uriRaw == currentUri) {
if (newUri != null) {
node.uriRaw = newUri;
@@ -668,7 +637,6 @@ Future<void> _updateNode({
/// generic function for changing any wallet default node
/// instead of making a new function for each change
Future<void> _changeDefaultNode({
- required Box<Node> nodes,
required SharedPreferences sharedPreferences,
required WalletType type,
required String currentNodePreferenceKey,
@@ -678,19 +646,21 @@ Future<void> _changeDefaultNode({
List<String>?
oldUri, // ignore, if you want to force replace the node regardless of the user's current node
}) async {
+ List<Node> nodes = await Node.getAll();
+
final currentNodeId = sharedPreferences.getInt(currentNodePreferenceKey);
final bool shouldReplace;
if (currentNodeId == null) {
shouldReplace = true;
} else {
- final currentNode = nodes.values.firstWhere((node) => node.key == currentNodeId);
- shouldReplace = oldUri?.any((e) => currentNode.uriRaw.contains(e)) ?? true;
+ final currentNode = nodes.firstWhereOrNull((node) => node.id == currentNodeId);
+ shouldReplace = currentNode == null || oldUri?.any((e) => currentNode!.uriRaw.contains(e)) ?? true;
}
if (shouldReplace) {
- newDefaultUri ??= _getDefaultNodeUri(type);
+ newDefaultUri ??= (await getDefaultNodeFromFiles(type)).uriRaw;
var newNodeId =
- nodes.values.firstWhereOrNull((element) => element.uriRaw == newDefaultUri)?.key;
+ nodes.firstWhereOrNull((element) => element.uriRaw == newDefaultUri)?.id;
// new node doesn't exist, then add it
if (newNodeId == null) {
@@ -701,55 +671,11 @@ Future<void> _changeDefaultNode({
trusted: trusted,
);
- await nodes.add(newNode);
- newNodeId = newNode.key;
+ await newNode.save();
+ newNodeId = newNode.id;
}
- await sharedPreferences.setInt(currentNodePreferenceKey, newNodeId as int);
- }
-}
-
-String _getDefaultNodeUri(WalletType type) {
- switch (type) {
- case WalletType.monero:
- return newCakeWalletMoneroUri;
- case WalletType.bitcoin:
- return newCakeWalletBitcoinUri;
- case WalletType.litecoin:
- return cakeWalletLitecoinElectrumUri;
- case WalletType.haven:
- return havenDefaultNodeUri;
- case WalletType.ethereum:
- return ethereumDefaultNodeUri;
- case WalletType.nano:
- return nanoDefaultNodeUri;
- case WalletType.bitcoinCash:
- return cakeWalletBitcoinCashDefaultNodeUri;
- case WalletType.polygon:
- return polygonDefaultNodeUri;
- case WalletType.solana:
- return solanaDefaultNodeUri;
- case WalletType.tron:
- return tronDefaultNodeUri;
- case WalletType.wownero:
- return wowneroDefaultNodeUri;
- case WalletType.zano:
- return zanoDefaultNodeUri;
- case WalletType.decred:
- return decredDefaultUri;
- case WalletType.dogecoin:
- return dogecoinDefaultNodeUri;
- case WalletType.base:
- return baseDefaultNodeUri;
- case WalletType.arbitrum:
- return arbitrumDefaultNodeUri;
- case WalletType.bsc:
- return bscDefaultNodeUri;
- case WalletType.zcash:
- return zcashDefaultNodeUri;
- case WalletType.banano:
- case WalletType.none:
- return '';
+ await sharedPreferences.setInt(currentNodePreferenceKey, newNodeId);
}
}
@@ -767,8 +693,9 @@ Future<void> _changeExchangeProviderAvailability(SharedPreferences sharedPrefere
);
}
-Future<void> _fixNodesUseSSLFlag(Box<Node> nodes) async {
- for (Node node in nodes.values) {
+Future<void> _fixNodesUseSSLFlag() async {
+ final nodes = await Node.getAll();
+ for (Node node in nodes) {
switch (node.uriRaw) {
case cakeWalletLitecoinElectrumUri:
case cakeWalletBitcoinElectrumUri:
@@ -781,7 +708,8 @@ Future<void> _fixNodesUseSSLFlag(Box<Node> nodes) async {
}
}
-Future<void> updateNanoNodeList({required Box<Node> nodes}) async {
+Future<void> updateNanoNodeList() async {
+ final nodes = await Node.getAll();
final nodeList = await loadDefaultNodes(WalletType.nano);
var listOfNewEndpoints = <String>[
"app.natrium.io",
@@ -792,14 +720,14 @@ Future<void> updateNanoNodeList({required Box<Node> nodes}) async {
];
// add new nodes:
for (final node in nodeList) {
- if (listOfNewEndpoints.contains(node.uriRaw) && !nodes.values.contains(node)) {
- await nodes.add(node);
+ if (listOfNewEndpoints.contains(node.uriRaw) && !nodes.contains(node)) {
+ await node.save();
}
}
// update the nautilus node:
final nautilusNode =
- nodes.values.firstWhereOrNull((element) => element.uriRaw == "node.perish.co");
+ nodes.firstWhereOrNull((element) => element.uriRaw == "node.perish.co");
if (nautilusNode != null) {
nautilusNode.uriRaw = "node.nautilus.io";
nautilusNode.path = "/api";
@@ -916,16 +844,17 @@ Future<void> validateBitcoinSavedTransactionPriority(SharedPreferences sharedPre
}
}
-Future<void> replaceNodesMigration({required Box<Node> nodes}) async {
+Future<void> replaceNodesMigration() async {
final replaceNodes = <String, Node>{
'eu-node.cakewallet.io:18081':
- Node(uri: 'xmr-node-eu.cakewallet.com:18081', type: WalletType.monero),
+ Node(uri: 'xmr-node-eu.cakewallet.com:18081', type: WalletType.monero),
'node.cakewallet.io:18081':
- Node(uri: 'xmr-node-usa-east.cakewallet.com:18081', type: WalletType.monero),
+ Node(uri: 'xmr-node-usa-east.cakewallet.com:18081', type: WalletType.monero),
'node.xmr.ru:13666': Node(uri: 'node.monero.net:18081', type: WalletType.monero)
};
- nodes.values.forEach((Node node) async {
+ List<Node> nodes = await Node.getAll();
+ nodes.forEach((Node node) async {
final nodeToReplace = replaceNodes[node.uri];
if (nodeToReplace != null) {
@@ -937,16 +866,12 @@ Future<void> replaceNodesMigration({required Box<Node> nodes}) async {
});
}
-Node? getBitcoinTestnetDefaultElectrumServer({required Box<Node> nodes}) {
- return nodes.values
- .firstWhereOrNull((Node node) => node.uriRaw == publicBitcoinTestnetElectrumUri) ??
- nodes.values.firstWhereOrNull((node) => node.type == WalletType.bitcoin);
-}
+Future<Node?> getBitcoinTestnetDefaultElectrumServer()async {
+ final nodes = await Node.getAll();
-Node? getDefaultNode({required Box<Node> nodes, required WalletType type}) {
- final defaultUri = _getDefaultNodeUri(type);
- return nodes.values.firstWhereOrNull((Node node) => node.uriRaw == defaultUri) ??
- nodes.values.firstWhereOrNull((node) => node.type == type);
+ return nodes
+ .firstWhereOrNull((Node node) => node.uriRaw == publicBitcoinTestnetElectrumUri) ??
+ nodes.firstWhereOrNull((node) => node.type == WalletType.bitcoin);
}
Future<void> insecureStorageMigration({
@@ -1057,8 +982,9 @@ Future<void> rewriteSecureStoragePin({required SecureStorage secureStorage}) asy
);
}
-Future<void> updateNodeTypes({required Box<Node> nodes}) async {
- nodes.values.forEach((node) async {
+Future<void> updateNodeTypes() async {
+ List<Node> nodes = await Node.getAll();
+ nodes.forEach((node) async {
if (node.type == null) {
node.type = WalletType.monero;
await node.save();
@@ -1146,206 +1072,13 @@ Future<void> updateBtcNanoWalletInfos() async {}
// }
// }
-Future<void> checkCurrentNodes(
- Box<Node> nodeSource, Box<Node> powNodeSource, SharedPreferences sharedPreferences) async {
- final currentMoneroNodeId = sharedPreferences.getInt(PreferencesKey.currentNodeIdKey);
- final currentBitcoinElectrumSeverId =
- sharedPreferences.getInt(PreferencesKey.currentBitcoinElectrumSererIdKey);
- final currentLitecoinElectrumSeverId =
- sharedPreferences.getInt(PreferencesKey.currentLitecoinElectrumSererIdKey);
- final currentHavenNodeId = sharedPreferences.getInt(PreferencesKey.currentHavenNodeIdKey);
- final currentEthereumNodeId = sharedPreferences.getInt(PreferencesKey.currentEthereumNodeIdKey);
- final currentPolygonNodeId = sharedPreferences.getInt(PreferencesKey.currentPolygonNodeIdKey);
- final currentBaseNodeId = sharedPreferences.getInt(PreferencesKey.currentBaseNodeIdKey);
- final currentArbitrumNodeId = sharedPreferences.getInt(PreferencesKey.currentArbitrumNodeIdKey);
- final currentBscNodeId = sharedPreferences.getInt(PreferencesKey.currentBscNodeIdKey);
- 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 currentDogecoinNodeId = sharedPreferences.getInt(PreferencesKey.currentDogecoinNodeIdKey);
- final currentSolanaNodeId = sharedPreferences.getInt(PreferencesKey.currentSolanaNodeIdKey);
- final currentTronNodeId = sharedPreferences.getInt(PreferencesKey.currentTronNodeIdKey);
- final currentWowneroNodeId = sharedPreferences.getInt(PreferencesKey.currentWowneroNodeIdKey);
- final currentZanoNodeId = sharedPreferences.getInt(PreferencesKey.currentZanoNodeIdKey);
- final currentZcashNodeId = sharedPreferences.getInt(PreferencesKey.currentZcashNodeIdKey);
- final currentMoneroNode =
- nodeSource.values.firstWhereOrNull((node) => node.key == currentMoneroNodeId);
- final currentBitcoinElectrumServer =
- nodeSource.values.firstWhereOrNull((node) => node.key == currentBitcoinElectrumSeverId);
- final currentLitecoinElectrumServer =
- nodeSource.values.firstWhereOrNull((node) => node.key == currentLitecoinElectrumSeverId);
- final currentHavenNodeServer =
- nodeSource.values.firstWhereOrNull((node) => node.key == currentHavenNodeId);
- final currentEthereumNodeServer =
- nodeSource.values.firstWhereOrNull((node) => node.key == currentEthereumNodeId);
- final currentPolygonNodeServer =
- nodeSource.values.firstWhereOrNull((node) => node.key == currentPolygonNodeId);
- final currentBaseNodeServer =
- nodeSource.values.firstWhereOrNull((node) => node.key == currentBaseNodeId);
- final currentArbitrumNodeServer =
- nodeSource.values.firstWhereOrNull((node) => node.key == currentArbitrumNodeId);
- final currentBscNodeServer =
- nodeSource.values.firstWhereOrNull((node) => node.key == currentBscNodeId);
- 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 =
- nodeSource.values.firstWhereOrNull((node) => node.key == currentBitcoinCashNodeId);
- final currentDogecoinNodeServer =
- nodeSource.values.firstWhereOrNull((node) => node.key == currentDogecoinNodeId);
- final currentSolanaNodeServer =
- nodeSource.values.firstWhereOrNull((node) => node.key == currentSolanaNodeId);
- final currentTronNodeServer =
- nodeSource.values.firstWhereOrNull((node) => node.key == currentTronNodeId);
- final currentWowneroNodeServer =
- nodeSource.values.firstWhereOrNull((node) => node.key == currentWowneroNodeId);
- final currentZanoNode =
- nodeSource.values.firstWhereOrNull((node) => node.key == currentZanoNodeId);
- final currentZcashNode =
- nodeSource.values.firstWhereOrNull((node) => node.key == currentZcashNodeId);
-
- if (currentMoneroNode == null) {
- final newCakeWalletNode = Node(uri: newCakeWalletMoneroUri, type: WalletType.monero);
- await nodeSource.add(newCakeWalletNode);
- await sharedPreferences.setInt(PreferencesKey.currentNodeIdKey, newCakeWalletNode.key as int);
- }
-
- if (currentBitcoinElectrumServer == null) {
- final cakeWalletElectrum = Node(
- uri: cakeWalletBitcoinElectrumUri,
- type: WalletType.bitcoin,
- useSSL: false,
- isEnabledForAutoSwitching: true);
- await nodeSource.add(cakeWalletElectrum);
- final cakeWalletElectrumTestnet =
- Node(uri: publicBitcoinTestnetElectrumUri, type: WalletType.bitcoin, useSSL: false);
- await nodeSource.add(cakeWalletElectrumTestnet);
- await sharedPreferences.setInt(
- PreferencesKey.currentBitcoinElectrumSererIdKey, cakeWalletElectrum.key as int);
- }
-
- if (currentLitecoinElectrumServer == null) {
- final cakeWalletElectrum =
- Node(uri: cakeWalletLitecoinElectrumUri, type: WalletType.litecoin, useSSL: false);
- await nodeSource.add(cakeWalletElectrum);
- await sharedPreferences.setInt(
- PreferencesKey.currentLitecoinElectrumSererIdKey, cakeWalletElectrum.key as int);
- }
-
- if (currentHavenNodeServer == null) {
- final node = Node(uri: havenDefaultNodeUri, type: WalletType.haven);
- await nodeSource.add(node);
- await sharedPreferences.setInt(PreferencesKey.currentHavenNodeIdKey, node.key as int);
- }
-
- if (currentEthereumNodeServer == null) {
- final node = Node(uri: ethereumDefaultNodeUri, type: WalletType.ethereum);
- await nodeSource.add(node);
- await sharedPreferences.setInt(PreferencesKey.currentEthereumNodeIdKey, node.key as int);
- }
-
- if (currentNanoNodeServer == null) {
- final node = Node(uri: nanoDefaultNodeUri, useSSL: true, type: WalletType.nano);
- await nodeSource.add(node);
- await sharedPreferences.setInt(PreferencesKey.currentNanoNodeIdKey, node.key as int);
- }
-
- if (currentNanoPowNodeServer == null) {
- Node? node = powNodeSource.values
- .firstWhereOrNull((node) => node.uri.toString() == nanoDefaultPowNodeUri);
- if (node == null) {
- node = Node(uri: nanoDefaultPowNodeUri, useSSL: true, type: WalletType.nano);
- await powNodeSource.add(node);
- }
- await sharedPreferences.setInt(PreferencesKey.currentNanoPowNodeIdKey, node.key as int);
- }
-
- if (currentBitcoinCashNodeServer == null) {
- final node =
- Node(uri: cakeWalletBitcoinCashDefaultNodeUri, type: WalletType.bitcoinCash, useSSL: false);
- await nodeSource.add(node);
- await sharedPreferences.setInt(PreferencesKey.currentBitcoinCashNodeIdKey, node.key as int);
- }
-
- if (currentDogecoinNodeServer == null) {
- final node = Node(uri: dogecoinDefaultNodeUri, type: WalletType.dogecoin, useSSL: true);
- await nodeSource.add(node);
- await sharedPreferences.setInt(PreferencesKey.currentDogecoinNodeIdKey, node.key as int);
- }
-
- if (currentPolygonNodeServer == null) {
- final node = Node(uri: polygonDefaultNodeUri, type: WalletType.polygon);
- await nodeSource.add(node);
- await sharedPreferences.setInt(PreferencesKey.currentPolygonNodeIdKey, node.key as int);
- }
-
- if (currentBaseNodeServer == null) {
- final node = Node(uri: baseDefaultNodeUri, type: WalletType.base);
- await nodeSource.add(node);
- await sharedPreferences.setInt(PreferencesKey.currentBaseNodeIdKey, node.key as int);
- }
-
- if (currentArbitrumNodeServer == null) {
- final node = Node(uri: arbitrumDefaultNodeUri, type: WalletType.arbitrum);
- await nodeSource.add(node);
- await sharedPreferences.setInt(PreferencesKey.currentArbitrumNodeIdKey, node.key as int);
- }
-
- if (currentBscNodeServer == null) {
- final node = Node(uri: bscDefaultNodeUri, type: WalletType.bsc);
- await nodeSource.add(node);
- await sharedPreferences.setInt(PreferencesKey.currentBscNodeIdKey, node.key as int);
- }
-
- if (currentSolanaNodeServer == null) {
- final node = Node(uri: solanaDefaultNodeUri, type: WalletType.solana);
- await nodeSource.add(node);
- await sharedPreferences.setInt(PreferencesKey.currentSolanaNodeIdKey, node.key as int);
- }
-
- if (currentTronNodeServer == null) {
- final node = Node(uri: tronDefaultNodeUri, type: WalletType.tron);
- await nodeSource.add(node);
- await sharedPreferences.setInt(PreferencesKey.currentTronNodeIdKey, node.key as int);
- }
-
- if (currentWowneroNodeServer == null) {
- final node = Node(uri: wowneroDefaultNodeUri, type: WalletType.wownero);
- await nodeSource.add(node);
- await sharedPreferences.setInt(PreferencesKey.currentWowneroNodeIdKey, node.key as int);
- }
-
- if (currentZanoNode == null) {
- final node = Node(uri: zanoDefaultNodeUri, type: WalletType.zano);
- await nodeSource.add(node);
- await sharedPreferences.setInt(PreferencesKey.currentZanoNodeIdKey, node.key as int);
- }
-
- if (currentDecredNodeServer == null) {
- final node = Node(uri: decredDefaultUri, type: WalletType.decred);
- await nodeSource.add(node);
- await sharedPreferences.setInt(PreferencesKey.currentDecredNodeIdKey, node.key as int);
- }
-
- if (currentZcashNode == null) {
- final node = Node(uri: zcashDefaultNodeUri, type: WalletType.zcash, useSSL: true);
- await nodeSource.add(node);
- await sharedPreferences.setInt(PreferencesKey.currentZcashNodeIdKey, node.key as int);
- }
-}
-
-Future<void> resetBitcoinElectrumServer(
- Box<Node> nodeSource, SharedPreferences sharedPreferences) async {
+Future<void> resetBitcoinElectrumServer(SharedPreferences sharedPreferences) async {
+ final nodeSource = await Node.getAll();
final currentElectrumSeverId =
sharedPreferences.getInt(PreferencesKey.currentBitcoinElectrumSererIdKey);
- final oldElectrumServer = nodeSource.values
+ final oldElectrumServer = nodeSource
.firstWhereOrNull((node) => node.uri.toString().contains('electrumx.cakewallet.com'));
- var cakeWalletNode = nodeSource.values
+ var cakeWalletNode = nodeSource
.firstWhereOrNull((node) => node.uriRaw.toString() == cakeWalletBitcoinElectrumUri);
if (cakeWalletNode == null) {
@@ -1357,12 +1090,12 @@ Future<void> resetBitcoinElectrumServer(
// final cakeWalletElectrumTestnet =
// Node(uri: publicBitcoinTestnetElectrumUri, type: WalletType.bitcoin, useSSL: false);
// await nodeSource.add(cakeWalletElectrumTestnet);
- await nodeSource.add(cakeWalletNode);
+ await cakeWalletNode.save();
}
- if (currentElectrumSeverId == oldElectrumServer?.key) {
+ if (currentElectrumSeverId == oldElectrumServer?.id) {
await sharedPreferences.setInt(
- PreferencesKey.currentBitcoinElectrumSererIdKey, cakeWalletNode.key as int);
+ PreferencesKey.currentBitcoinElectrumSererIdKey, cakeWalletNode.id);
}
await oldElectrumServer?.delete();
@@ -1380,38 +1113,42 @@ Future<void> migrateExchangeStatus(SharedPreferences sharedPreferences) async {
await sharedPreferences.remove(PreferencesKey.disableExchangeKey);
}
-Future<void> addNanoPowNodeList({required Box<Node> nodes}) async {
+Future<void> addNanoPowNodeList() async {
final nodeList = await loadDefaultNanoPowNodes();
+ final nodes = await Node.getAllPow();
for (var node in nodeList) {
- if (nodes.values.firstWhereOrNull((element) => element.uriRaw == node.uriRaw) == null) {
- await nodes.add(node);
+ if (nodes.firstWhereOrNull((element) => element.uriRaw == node.uriRaw) == null) {
+ await node.save();
}
}
}
-Node? getNanoDefaultPowNode({required Box<Node> nodes}) {
- return nodes.values.firstWhereOrNull((Node node) => node.uriRaw == nanoDefaultPowNodeUri) ??
- nodes.values.firstWhereOrNull((node) => (node.type == WalletType.nano));
+Future<Node?> getNanoDefaultPowNode() async {
+ final nodes = await Node.getAll();
+ return nodes.firstWhereOrNull((Node node) => node.uriRaw == nanoDefaultPowNodeUri) ??
+ nodes.firstWhereOrNull((node) => (node.type == WalletType.nano));
}
-Future<void> addWalletNodeList({required Box<Node> nodes, required WalletType type}) async {
+Future<void> addWalletNodeList({required WalletType type}) async {
+ final nodes = await Node.getAll();
final List<Node> nodeList = await loadDefaultNodes(type);
for (var node in nodeList) {
- if (nodes.values.firstWhereOrNull((element) => element.uriRaw == node.uriRaw) == null) {
- await nodes.add(node);
+ if (nodes.firstWhereOrNull((element) => element.uriRaw == node.uriRaw) == null) {
+ await node.save();
}
}
}
Future<void> removeMoneroWorld(
- {required SharedPreferences sharedPreferences, required Box<Node> nodes}) async {
+ {required SharedPreferences sharedPreferences}) async {
+ final nodes = await Node.getAll();
const cakeWalletMoneroNodeUriPattern = '.moneroworld.com';
final currentMoneroNodeId = sharedPreferences.getInt(PreferencesKey.currentNodeIdKey);
- final currentMoneroNode = nodes.values.firstWhere((node) => node.key == currentMoneroNodeId);
+ final currentMoneroNode = nodes.firstWhere((node) => node.id == currentMoneroNodeId);
final needToReplaceCurrentMoneroNode =
currentMoneroNode.uri.toString().contains(cakeWalletMoneroNodeUriPattern);
- nodes.values.forEach((node) async {
+ nodes.forEach((node) async {
if (node.type == WalletType.monero &&
node.uri.toString().contains(cakeWalletMoneroNodeUriPattern)) {
await node.delete();
@@ -1420,7 +1157,6 @@ Future<void> removeMoneroWorld(
if (needToReplaceCurrentMoneroNode) {
await _changeDefaultNode(
- nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.monero,
newDefaultUri: newCakeWalletMoneroUri,
@@ -1430,8 +1166,7 @@ Future<void> removeMoneroWorld(
}
}
-Future<void> migrateExistingNodesToUseAutoSwitching(
- {required Box<Node> nodes, required Box<Node> powNodes}) async {
+Future<void> migrateExistingNodesToUseAutoSwitching() async {
final listOfDefaultNodesWithAutoSwitching = [
'bitcoincash.stackwallet.com:50002',
'bch.aftrek.org:50002',
@@ -1465,12 +1200,24 @@ Future<void> migrateExistingNodesToUseAutoSwitching(
'zano.cakewallet.com:11211',
'electrum.cakewallet.com:50002',
];
- for (var node in [...nodes.values.toList(), ...powNodes.values.toList()]) {
+ final nodes = await Node.getAll();
+ for (var node in nodes) {
if (listOfDefaultNodesWithAutoSwitching.contains(node.uriRaw)) {
node.isEnabledForAutoSwitching = true;
await node.save();
}
}
+
+ final powNodes = await Node.getAllPow();
+
+ for(var node in powNodes) {
+ if (listOfDefaultNodesWithAutoSwitching.contains(node.uriRaw)) {
+ node.isEnabledForAutoSwitching = true;
+ node.isPow = true;
+ await node.save();
+ }
+ }
+
}
Future<void> _addXautTokenToExistingEthereumWallets() async {
diff --git a/lib/entities/node_check.dart b/lib/entities/node_check.dart
new file mode 100644
index 00000000..aee8e404
--- /dev/null
+++ b/lib/entities/node_check.dart
@@ -0,0 +1,69 @@
+import 'package:cake_wallet/core/utilities.dart';
+import 'package:cake_wallet/entities/preferences_key.dart';
+import 'package:cake_wallet/store/settings_store.dart';
+import 'package:cw_core/node.dart';
+import 'package:cw_core/node_list.dart';
+import 'package:cw_core/wallet_type.dart';
+import 'package:shared_preferences/shared_preferences.dart';
+
+const Map<WalletType, String> nodePreferenceKeys = {
+ WalletType.monero: PreferencesKey.currentNodeIdKey,
+ WalletType.bitcoin: PreferencesKey.currentBitcoinElectrumSererIdKey,
+ WalletType.litecoin: PreferencesKey.currentLitecoinElectrumSererIdKey,
+ WalletType.haven: PreferencesKey.currentHavenNodeIdKey,
+ WalletType.ethereum: PreferencesKey.currentEthereumNodeIdKey,
+ WalletType.polygon: PreferencesKey.currentPolygonNodeIdKey,
+ WalletType.base: PreferencesKey.currentBaseNodeIdKey,
+ WalletType.arbitrum: PreferencesKey.currentArbitrumNodeIdKey,
+ WalletType.bsc: PreferencesKey.currentBscNodeIdKey,
+ WalletType.nano: PreferencesKey.currentNanoNodeIdKey,
+ WalletType.decred: PreferencesKey.currentDecredNodeIdKey,
+ WalletType.bitcoinCash: PreferencesKey.currentBitcoinCashNodeIdKey,
+ WalletType.dogecoin: PreferencesKey.currentDogecoinNodeIdKey,
+ WalletType.solana: PreferencesKey.currentSolanaNodeIdKey,
+ WalletType.tron: PreferencesKey.currentTronNodeIdKey,
+ WalletType.wownero: PreferencesKey.currentWowneroNodeIdKey,
+ WalletType.zano: PreferencesKey.currentZanoNodeIdKey,
+ WalletType.zcash: PreferencesKey.currentZcashNodeIdKey,
+};
+
+const Map<WalletType, String> powNodePreferenceKeys = {
+ WalletType.nano: PreferencesKey.currentNanoPowNodeIdKey
+};
+
+Future<void> checkNodeForWalletType(SharedPreferences sharedPreferences, SettingsStore settingsStore, WalletType type, bool isPow) async {
+ final preferenceKey = isPow ? powNodePreferenceKeys[type] : nodePreferenceKeys[type];
+
+ if(preferenceKey == null) {
+ return;
+ }
+
+ final currentId = await sharedPreferences.getInt(preferenceKey);
+
+ final nodes = isPow ? await Node.getAllForWalletTypePow(type) : await Node.getAllForWalletType(type);
+ final currentNode = nodes.firstWhereOrNull((item)=>item.id == currentId);
+
+ if(currentNode == null) {
+ final newNode = (isPow
+ ? await Node.getDefaultPowForWalletType(type)
+ : await Node.getDefaultForWalletType(type)) ??
+ await getDefaultNodeFromFiles(type, isPow: isPow);
+ final newId = await newNode.save();
+ sharedPreferences.setInt(preferenceKey, newId);
+ settingsStore.nodes[type] = newNode;
+ } else {
+ settingsStore.nodes[type] = currentNode;
+ }
+
+}
+
+
+Future<void> checkCurrentNodes(SharedPreferences sharedPreferences, SettingsStore settingsStore) async {
+ for(final walletType in nodePreferenceKeys.keys) {
+ await checkNodeForWalletType(sharedPreferences, settingsStore, walletType, false);
+ }
+
+ for(final walletType in powNodePreferenceKeys.keys) {
+ await checkNodeForWalletType(sharedPreferences, settingsStore, walletType, true);
+ }
+}
\ No newline at end of file
diff --git a/lib/entities/node_list.dart b/lib/entities/node_list.dart
index bf4e0586..e69de29b 100644
--- a/lib/entities/node_list.dart
+++ b/lib/entities/node_list.dart
@@ -1,148 +0,0 @@
-import 'package:flutter/services.dart';
-import 'package:hive/hive.dart';
-import "package:yaml/yaml.dart";
-import 'package:cw_core/node.dart';
-import 'package:cw_core/wallet_type.dart';
-
-Future<List<Node>> loadDefaultNodes(WalletType type) async {
- String path;
- switch (type) {
- case WalletType.monero:
- path = 'assets/node_list.yml';
- break;
- case WalletType.bitcoin:
- path = 'assets/bitcoin_electrum_server_list.yml';
- break;
- case WalletType.litecoin:
- path = 'assets/litecoin_electrum_server_list.yml';
- break;
- case WalletType.haven:
- path = 'assets/haven_node_list.yml';
- break;
- // TODO: (refactoring) each wallet would have its path, so `wallet.nodePath` would be decided based on chain id in Evm wallet
- case WalletType.ethereum:
- path = 'assets/ethereum_server_list.yml';
- break;
- case WalletType.nano:
- path = 'assets/nano_node_list.yml';
- break;
- case WalletType.bitcoinCash:
- path = 'assets/bitcoin_cash_electrum_server_list.yml';
- break;
- case WalletType.polygon:
- path = 'assets/polygon_node_list.yml';
- break;
- case WalletType.solana:
- path = 'assets/solana_node_list.yml';
- break;
- case WalletType.tron:
- path = 'assets/tron_node_list.yml';
- break;
- case WalletType.wownero:
- path = 'assets/wownero_node_list.yml';
- break;
- case WalletType.zano:
- path = 'assets/zano_node_list.yml';
- break;
- case WalletType.decred:
- path = 'assets/decred_node_list.yml';
- break;
- case WalletType.dogecoin:
- path = 'assets/dogecoin_electrum_server_list.yml';
- break;
- case WalletType.base:
- path = 'assets/base_node_list.yml';
- break;
- case WalletType.arbitrum:
- path = 'assets/arbitrum_node_list.yml';
- break;
- case WalletType.zcash:
- path = 'assets/zcash_node_list.yml';
- break;
- case WalletType.bsc:
- path = 'assets/bsc_node_list.yml';
- break;
- case WalletType.banano:
- case WalletType.none:
- path = '';
- break;
- }
-
- final nodesRaw = await rootBundle.loadString(path);
- final loadedNodes = loadYaml(nodesRaw) as YamlList;
- final nodes = <Node>[];
-
- for (final raw in loadedNodes) {
- if (raw is Map) {
- final node = Node.fromMap(Map<String, Object>.from(raw));
- node.type = type;
- nodes.add(node);
- }
- }
-
- return nodes;
-}
-
-Future<List<Node>> loadDefaultNanoPowNodes() async {
- final powNodesRaw = await rootBundle.loadString('assets/nano_pow_node_list.yml');
- final loadedPowNodes = loadYaml(powNodesRaw) as YamlList;
- final nodes = <Node>[];
-
- for (final raw in loadedPowNodes) {
- if (raw is Map) {
- final node = Node.fromMap(Map<String, Object>.from(raw));
- node.type = WalletType.nano;
- nodes.add(node);
- }
- }
-
- return nodes;
-}
-
-Future<void> resetToDefault(Box<Node> nodeSource) async {
- final moneroNodes = await loadDefaultNodes(WalletType.monero);
- final bitcoinElectrumServerList = await loadDefaultNodes(WalletType.bitcoin);
- final litecoinElectrumServerList = await loadDefaultNodes(WalletType.litecoin);
- final bitcoinCashElectrumServerList = await loadDefaultNodes(WalletType.bitcoinCash);
- final havenNodes = await loadDefaultNodes(WalletType.haven);
- final ethereumNodes = await loadDefaultNodes(WalletType.ethereum);
- final nanoNodes = await loadDefaultNodes(WalletType.nano);
- final polygonNodes = await loadDefaultNodes(WalletType.polygon);
- final solanaNodes = await loadDefaultNodes(WalletType.solana);
- final tronNodes = await loadDefaultNodes(WalletType.tron);
- final decredNodes = await loadDefaultNodes(WalletType.decred);
- final zanoNodes = await loadDefaultNodes(WalletType.zano);
- final dogecoinElectrumServerList = await loadDefaultNodes(WalletType.dogecoin);
- final baseNodes = await loadDefaultNodes(WalletType.base);
- final arbitrumNodes = await loadDefaultNodes(WalletType.arbitrum);
- final zcashNodes = await loadDefaultNodes(WalletType.zcash);
- final bscNodes = await loadDefaultNodes(WalletType.bsc);
-
- final nodes = moneroNodes +
- bitcoinElectrumServerList +
- litecoinElectrumServerList +
- havenNodes +
- ethereumNodes +
- bitcoinCashElectrumServerList +
- nanoNodes +
- polygonNodes +
- solanaNodes +
- tronNodes +
- zanoNodes +
- decredNodes +
- dogecoinElectrumServerList +
- baseNodes +
- arbitrumNodes +
- zcashNodes +
- bscNodes;
-
- await nodeSource.clear();
- await nodeSource.addAll(nodes);
-}
-
-Future<void> resetPowToDefault(Box<Node> powNodeSource) async {
- final nanoPowNodes = await loadDefaultNanoPowNodes();
- final nodes = nanoPowNodes;
- await powNodeSource.clear();
- await powNodeSource.addAll(nodes);
-}
diff --git a/lib/main.dart b/lib/main.dart
index 61dea0d6..d8a66241 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -16,6 +16,7 @@ import 'package:cake_wallet/entities/default_settings_migration.dart';
import 'package:cake_wallet/entities/get_encryption_key.dart';
import 'package:cake_wallet/entities/haven_seed_store.dart';
import 'package:cake_wallet/entities/language_service.dart';
+import 'package:cake_wallet/entities/node_check.dart';
import 'package:cake_wallet/entities/template.dart';
import 'package:cake_wallet/entities/transaction_description.dart';
import 'package:cake_wallet/exchange/exchange_template.dart';
@@ -46,6 +47,7 @@ import 'package:cw_core/hive_type_ids.dart';
import 'package:cw_core/key.dart';
import 'package:cw_core/mweb_utxo.dart';
import 'package:cw_core/node.dart';
+import 'package:cw_core/node_legacy.dart' show performNodeHiveMigration;
import 'package:cw_core/payjoin_session.dart';
import 'package:cw_core/root_dir.dart';
import 'package:cw_core/spl_token.dart';
@@ -220,9 +222,6 @@ Future<void> initializeAppConfigs({bool loadWallet = true}) async {
CakeHive.registerAdapter(ContactAdapter());
}
- if (!CakeHive.isAdapterRegistered(Node.typeId)) {
- CakeHive.registerAdapter(NodeAdapter());
- }
if (!CakeHive.isAdapterRegistered(TransactionDescription.typeId)) {
CakeHive.registerAdapter(TransactionDescriptionAdapter());
@@ -286,13 +285,12 @@ Future<void> initializeAppConfigs({bool loadWallet = true}) async {
await getEncryptionKey(secureStorage: secureStorage, forKey: TransactionDescription.boxKey);
final ordersBoxKey = await getEncryptionKey(secureStorage: secureStorage, forKey: Order.boxKey);
final contacts = await CakeHive.openBox<Contact>(Contact.boxName);
- final nodes = await CakeHive.openBox<Node>(Node.boxName);
- final powNodes =
- await CakeHive.openBox<Node>(Node.boxName + "pow"); // must be different from Node.boxName
final transactionDescriptions = await CakeHive.openBox<TransactionDescription>(
TransactionDescription.boxName,
encryptionKey: transactionDescriptionsBoxKey);
await performTradeHiveMigration(secureStorage);
+ await performNodeHiveMigration();
+ await validateBuiltinNodes();
final orders = await CakeHive.openBox<Order>(Order.boxName, encryptionKey: ordersBoxKey);
final templates = await CakeHive.openBox<Template>(Template.boxName);
@@ -309,8 +307,6 @@ Future<void> initializeAppConfigs({bool loadWallet = true}) async {
await initialSetup(
loadWallet: loadWallet,
sharedPreferences: await SharedPreferences.getInstance(),
- nodes: nodes,
- powNodes: powNodes,
contactSource: contacts,
ordersSource: orders,
unspentCoinsInfoSource: unspentCoinsInfoSource,
@@ -322,15 +318,13 @@ Future<void> initializeAppConfigs({bool loadWallet = true}) async {
payjoinSessionSource: payjoinSessionSource,
anonpayInvoiceInfo: anonpayInvoiceInfo,
havenSeedStore: havenSeedStore,
- initialMigrationVersion: 65,
+ initialMigrationVersion: 66,
);
}
Future<void> initialSetup({
required bool loadWallet,
required SharedPreferences sharedPreferences,
- required Box<Node> nodes,
- required Box<Node> powNodes,
required Box<Contact> contactSource,
required Box<Order> ordersSource,
// required FiatConvertationService fiatConvertationService,
@@ -350,13 +344,9 @@ Future<void> initialSetup({
version: initialMigrationVersion,
sharedPreferences: sharedPreferences,
contactSource: contactSource,
- nodes: nodes,
- powNodes: powNodes,
havenSeedStore: havenSeedStore,
);
await setup(
- nodeSource: nodes,
- powNodeSource: powNodes,
contactSource: contactSource,
ordersSource: ordersSource,
templates: templates,
@@ -368,11 +358,12 @@ Future<void> initialSetup({
navigatorKey: navigatorKey,
secureStorage: secureStorage,
);
+ final settingsStore = getIt<SettingsStore>();
+ await checkCurrentNodes(sharedPreferences, settingsStore);
await getIt.get<ResetService>().resetAuthDataOnNewInstall(sharedPreferences);
await bootstrapOffline();
- final settingsStore = getIt<SettingsStore>();
if (!settingsStore.currentBuiltinTor) {
bootstrapOnline(navigatorKey, loadWallet: loadWallet);
}
diff --git a/lib/new-ui/widgets/send_page/send_confirm_sheet.dart b/lib/new-ui/widgets/send_page/send_confirm_sheet.dart
index 853a82ad..65e6f8d6 100644
--- a/lib/new-ui/widgets/send_page/send_confirm_sheet.dart
+++ b/lib/new-ui/widgets/send_page/send_confirm_sheet.dart
@@ -15,6 +15,7 @@ import 'package:cw_core/crypto_amount_format.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
+import 'package:flutter_svg/flutter_svg.dart';
import 'package:mobx/mobx.dart';
class SendConfirmSheet extends StatefulWidget {
diff --git a/lib/src/screens/nodes/node_create_or_edit_page.dart b/lib/src/screens/nodes/node_create_or_edit_page.dart
index bc407531..92bccb27 100644
--- a/lib/src/screens/nodes/node_create_or_edit_page.dart
+++ b/lib/src/screens/nodes/node_create_or_edit_page.dart
@@ -128,15 +128,16 @@ class _NodeCreateOrEditPageState extends State<NodeCreateOrEditPage> {
),
) ??
false;
-
+
if (confirmed) {
- await widget.editingNode!.delete();
+ await widget.nodeCreateOrEditViewModel.delete(editingNode: widget.editingNode!);
Navigator.of(context).pop();
}
},
text: S.of(context).delete,
isDisabled: widget.editingNode == null ||
!widget.nodeCreateOrEditViewModel.isReady ||
+ widget.editingNode!.isBuiltin ||
(widget.isSelected ?? false),
color: Theme.of(context).colorScheme.errorContainer,
textColor: Theme.of(context).colorScheme.onErrorContainer,
@@ -151,9 +152,9 @@ class _NodeCreateOrEditPageState extends State<NodeCreateOrEditPage> {
if (_nodeFormKey.currentState != null && !_nodeFormKey.currentState!.validate()) {
return;
}
-
+
await widget.nodeCreateOrEditViewModel.save(
- editingNode: widget.editingNode, saveAsCurrent: widget.isSelected ?? false);
+ saveAsCurrent: widget.isSelected ?? false);
if (context.mounted) {
Navigator.of(context).pop();
}
diff --git a/lib/src/screens/nodes/pow_node_create_or_edit_page.dart b/lib/src/screens/nodes/pow_node_create_or_edit_page.dart
index 44968836..72b64ed8 100644
--- a/lib/src/screens/nodes/pow_node_create_or_edit_page.dart
+++ b/lib/src/screens/nodes/pow_node_create_or_edit_page.dart
@@ -143,7 +143,7 @@ class _PowNodeCreateOrEditPageState extends State<PowNodeCreateOrEditPage> {
}
await widget.nodeCreateOrEditViewModel.save(
- editingNode: widget.editingNode, saveAsCurrent: widget.isSelected ?? false);
+ saveAsCurrent: widget.isSelected ?? false);
Navigator.of(context).pop();
},
text: S.of(context).save,
diff --git a/lib/src/screens/nodes/widgets/node_form.dart b/lib/src/screens/nodes/widgets/node_form.dart
index 525252d8..19a23be4 100644
--- a/lib/src/screens/nodes/widgets/node_form.dart
+++ b/lib/src/screens/nodes/widgets/node_form.dart
@@ -65,66 +65,77 @@ class NodeFormState extends State<NodeForm> {
key: _formKey,
child: NewListSections(
sections: {
- 'main': [
- ListItemTextField(
- keyValue: vm.nodeLabelUIKey,
- label: 'Node label',
- initialValue: vm.label,
- ),
- ListItemTextField(
- keyValue: vm.nodeAddressUIKey,
- label: S.current.node_address,
- initialValue: vm.address,
- validator: vm.walletType == WalletType.decred
- ? NodeAddressValidatorDecredBlankException()
- : NodeAddressValidator(),
- ),
- if (vm.hasPathSupport)
+ if(!(vm.editingNode?.isBuiltin ?? false)) ...{
+ 'main': [
ListItemTextField(
- keyValue: vm.nodePathUIKey,
- label: '/path',
- initialValue: vm.path,
- validator: NodePathValidator(),
+ keyValue: vm.nodeLabelUIKey,
+ label: 'Node label',
+ initialValue: vm.label,
),
- ListItemTextField(
- keyValue: vm.nodePortUIKey,
- label: S.current.node_port,
- initialValue: '',
- //keyboardType: TextInputType.numberWithOptions(signed: false, decimal: false),
- validator: NodePortValidator(),
- ),
- if (vm.hasAuthCredentials) ...[
ListItemTextField(
- keyValue: vm.nodeUsernameUIKey,
- label: S.current.login,
- initialValue: vm.login,
+ keyValue: vm.nodeAddressUIKey,
+ label: S.current.node_address,
+ initialValue: vm.address,
+ validator: vm.walletType == WalletType.decred
+ ? NodeAddressValidatorDecredBlankException()
+ : NodeAddressValidator(),
),
+ if (vm.hasPathSupport)
+ ListItemTextField(
+ keyValue: vm.nodePathUIKey,
+ label: '/path',
+ initialValue: vm.path,
+ validator: NodePathValidator(),
+ ),
ListItemTextField(
- keyValue: vm.nodePasswordUIKey,
- label: S.current.password,
- initialValue: vm.password,
+ keyValue: vm.nodePortUIKey,
+ label: S.current.node_port,
+ initialValue: '',
+ //keyboardType: TextInputType.numberWithOptions(signed: false, decimal: false),
+ validator: NodePortValidator(),
),
- ]
- ],
- 'advanced': [
- ListItemCheckbox(
- keyValue: vm.useSSLUIKey,
- label: S.current.use_ssl,
- value: vm.useSSL,
- onChanged: (value) => vm.useSSL = value),
- ListItemCheckbox(
- keyValue: vm.nodeTrustedUIKey,
- label: S.current.trusted,
- value: vm.trusted,
- onChanged: (value) => vm.trusted = value,
- ),
- if (vm.usesEmbeddedProxy)
+ if (vm.hasAuthCredentials) ...[
+ ListItemTextField(
+ keyValue: vm.nodeUsernameUIKey,
+ label: S.current.login,
+ initialValue: vm.login,
+ ),
+ ListItemTextField(
+ keyValue: vm.nodePasswordUIKey,
+ label: S.current.password,
+ initialValue: vm.password,
+ ),
+ ]
+ ],
+ 'advanced': [
ListItemCheckbox(
- keyValue: vm.nodeEmbeddedTorProxyUIKey,
- label: 'Embedded Tor SOCKS Proxy',
- value: vm.usesEmbeddedProxy,
- onChanged: (_) {},
+ keyValue: vm.useSSLUIKey,
+ label: S.current.use_ssl,
+ value: vm.useSSL,
+ onChanged: (value) => vm.useSSL = value),
+ ListItemCheckbox(
+ keyValue: vm.nodeTrustedUIKey,
+ label: S.current.trusted,
+ value: vm.trusted,
+ onChanged: (value) => vm.trusted = value,
),
+ if (vm.usesEmbeddedProxy)
+ ListItemCheckbox(
+ keyValue: vm.nodeEmbeddedTorProxyUIKey,
+ label: 'Embedded Tor SOCKS Proxy',
+ value: vm.usesEmbeddedProxy,
+ onChanged: (_) {},
+ ),
+ if(FeatureFlag.isAutomaticNodeSwitchingEnabled)
+ ListItemCheckbox(
+ keyValue: vm.autoSwitchingUIKey,
+ label: S.current.enable_for_auto_switching,
+ value: vm.isEnabledForAutoSwitching,
+ onChanged: (value) => vm.isEnabledForAutoSwitching = value),
+ ],
+ },
+
+ "proxy" : [
ListItemCheckbox(
keyValue: vm.useSocksProxyUIKey,
label: 'Use SOCKS Proxy',
@@ -141,13 +152,7 @@ class NodeFormState extends State<NodeForm> {
initialValue: vm.socksProxyAddress,
validator: SocksProxyNodeAddressValidator(),
),
- if(FeatureFlag.isAutomaticNodeSwitchingEnabled)
- ListItemCheckbox(
- keyValue: vm.autoSwitchingUIKey,
- label: S.current.enable_for_auto_switching,
- value: vm.isEnabledForAutoSwitching,
- onChanged: (value) => vm.isEnabledForAutoSwitching = value),
- ],
+ ]
},
controllers: _controllers,
getCheckboxValue: vm.getCheckboxValue,
diff --git a/lib/src/screens/settings/manage_nodes_page.dart b/lib/src/screens/settings/manage_nodes_page.dart
index 841a440c..02c2e4e6 100644
--- a/lib/src/screens/settings/manage_nodes_page.dart
+++ b/lib/src/screens/settings/manage_nodes_page.dart
@@ -94,9 +94,9 @@ class ManageNodesPage extends BasePage {
nodeListViewModel?.nodes[index] ?? powNodeListViewModel!.nodes[index];
late bool isSelected;
if (isPow) {
- isSelected = node.keyIndex == powNodeListViewModel!.currentNode.keyIndex;
+ isSelected = node.id == powNodeListViewModel!.currentNode.id;
} else {
- isSelected = node.keyIndex == nodeListViewModel!.currentNode.keyIndex;
+ isSelected = node.id == nodeListViewModel!.currentNode.id;
}
final nodeListRow = NodeListRow(
title: node.uriRaw,
diff --git a/lib/store/app_store.dart b/lib/store/app_store.dart
index 466b235a..dd41fe94 100644
--- a/lib/store/app_store.dart
+++ b/lib/store/app_store.dart
@@ -14,7 +14,6 @@ import 'package:cw_core/transaction_history.dart';
import 'package:cake_wallet/store/wallet_list_store.dart';
import 'package:cake_wallet/store/authentication_store.dart';
import 'package:cake_wallet/store/settings_store.dart';
-import 'package:cake_wallet/store/node_list_store.dart';
import 'package:shared_preferences/shared_preferences.dart';
part 'app_store.g.dart';
@@ -26,7 +25,6 @@ abstract class AppStoreBase with Store {
required this.authenticationStore,
required this.walletList,
required this.settingsStore,
- required this.nodeListStore,
required this.themeStore,
}) : _amountParsingProxy = AmountParsingProxy(settingsStore.displayAmountsInSatoshi) {
reaction(
@@ -47,7 +45,6 @@ abstract class AppStoreBase with Store {
SettingsStore settingsStore;
- NodeListStore nodeListStore;
ThemeStore themeStore;
diff --git a/lib/store/node_list_store.dart b/lib/store/node_list_store.dart
index 2990f957..e69de29b 100644
--- a/lib/store/node_list_store.dart
+++ b/lib/store/node_list_store.dart
@@ -1,34 +0,0 @@
-import 'dart:async';
-import 'package:hive/hive.dart';
-import 'package:mobx/mobx.dart';
-import 'package:cake_wallet/di.dart';
-import 'package:cw_core/node.dart';
-import 'package:cake_wallet/utils/mobx.dart';
-
-part 'node_list_store.g.dart';
-
-class NodeListStore = NodeListStoreBase with _$NodeListStore;
-
-abstract class NodeListStoreBase with Store {
- NodeListStoreBase() : nodes = ObservableList<Node>();
-
- static StreamSubscription<BoxEvent>? _onNodesSourceChange;
- static NodeListStore? _instance;
-
- static NodeListStore get instance {
- if (_instance != null) {
- return _instance!;
- }
-
- final nodeSource = getIt.get<Box<Node>>();
- _instance = NodeListStore();
- _instance!.nodes.clear();
- _instance!.nodes.addAll(nodeSource.values);
- _onNodesSourceChange?.cancel();
- _onNodesSourceChange = nodeSource.bindToList(_instance!.nodes);
-
- return _instance!;
- }
-
- final ObservableList<Node> nodes;
-}
diff --git a/lib/store/settings_store.dart b/lib/store/settings_store.dart
index 9551942e..d1320565 100644
--- a/lib/store/settings_store.dart
+++ b/lib/store/settings_store.dart
@@ -995,7 +995,7 @@ abstract class SettingsStoreBase with Store {
@observable
bool mwebCardDisplay;
-
+
@observable
bool showZcashMissingFundsCard;
@@ -1104,8 +1104,7 @@ abstract class SettingsStoreBase with Store {
_sharedPreferences.setBool(PreferencesKey.shouldShowReceiveWarning, value);
static Future<SettingsStore> load(
- {required Box<Node> nodeSource,
- required Box<Node> powNodeSource,
+ {
required bool isBitcoinBuyEnabled,
FiatCurrency initialFiatCurrency = FiatCurrency.usd,
BalanceDisplayMode initialBalanceDisplayMode = BalanceDisplayMode.availableBalance}) async {
@@ -1318,43 +1317,66 @@ abstract class SettingsStoreBase with Store {
final decredNodeId = sharedPreferences.getInt(PreferencesKey.currentDecredNodeIdKey);
final dogecoinNodeId = sharedPreferences.getInt(PreferencesKey.currentDogecoinNodeIdKey);
+
+ final nodeSource = await Node.getAll();
+ final powNodeSource = await Node.getAllPow();
+
/// get the selected node, if null, then use the default
- final moneroNode = nodeSource.get(nodeId) ??
- nodeSource.values.firstWhereOrNull((e) => e.uriRaw == newCakeWalletMoneroUri);
- final bitcoinElectrumServer = nodeSource.get(bitcoinElectrumServerId) ??
- nodeSource.values.firstWhereOrNull((e) => e.uriRaw == newCakeWalletBitcoinUri);
- final litecoinElectrumServer = nodeSource.get(litecoinElectrumServerId) ??
- nodeSource.values.firstWhereOrNull((e) => e.uriRaw == cakeWalletLitecoinElectrumUri);
- final ethereumNode = nodeSource.get(ethereumNodeId) ??
- nodeSource.values.firstWhereOrNull((e) => e.uriRaw == ethereumDefaultNodeUri);
- final polygonNode = nodeSource.get(polygonNodeId) ??
- nodeSource.values.firstWhereOrNull((e) => e.uriRaw == polygonDefaultNodeUri);
- final baseNode = nodeSource.get(baseNodeId) ??
- nodeSource.values.firstWhereOrNull((e) => e.uriRaw == baseDefaultNodeUri);
- final arbitrumNode = nodeSource.get(arbitrumNodeId) ??
- nodeSource.values.firstWhereOrNull((e) => e.uriRaw == arbitrumDefaultNodeUri);
- final bscNode = nodeSource.get(bscNodeId) ??
- nodeSource.values.firstWhereOrNull((e) => e.uriRaw == bscDefaultNodeUri);
- final bitcoinCashElectrumServer = nodeSource.get(bitcoinCashElectrumServerId) ??
- nodeSource.values.firstWhereOrNull((e) => e.uriRaw == cakeWalletBitcoinCashDefaultNodeUri);
- final nanoNode = nodeSource.get(nanoNodeId) ??
- nodeSource.values.firstWhereOrNull((e) => e.uriRaw == nanoDefaultNodeUri);
- final decredNode = nodeSource.get(decredNodeId) ??
- nodeSource.values.firstWhereOrNull((e) => e.uriRaw == decredDefaultUri);
- final nanoPowNode = powNodeSource.get(nanoPowNodeId) ??
- nodeSource.values.firstWhereOrNull((e) => e.uriRaw == nanoDefaultPowNodeUri);
- final solanaNode = nodeSource.get(solanaNodeId) ??
- nodeSource.values.firstWhereOrNull((e) => e.uriRaw == solanaDefaultNodeUri);
- final tronNode = nodeSource.get(tronNodeId) ??
- nodeSource.values.firstWhereOrNull((e) => e.uriRaw == tronDefaultNodeUri);
- final wowneroNode = nodeSource.get(wowneroNodeId) ??
- nodeSource.values.firstWhereOrNull((e) => e.uriRaw == wowneroDefaultNodeUri);
- final zanoNode = nodeSource.get(zanoNodeId) ??
- nodeSource.values.firstWhereOrNull((e) => e.uriRaw == zanoDefaultNodeUri);
- final zcashNode = nodeSource.get(zcashNodeId) ??
- nodeSource.values.firstWhereOrNull((e) => e.uriRaw == zcashDefaultNodeUri);
- final dogecoinNode = nodeSource.get(dogecoinNodeId) ??
- nodeSource.values.firstWhereOrNull((e) => e.uriRaw == dogecoinDefaultNodeUri);
+ final moneroNode = nodeSource.firstWhereOrNull((e) => e.id == nodeId) ??
+ nodeSource.firstWhereOrNull((e) => e.uriRaw == newCakeWalletMoneroUri);
+ final bitcoinElectrumServer =
+ nodeSource.firstWhereOrNull((e) => e.id == bitcoinElectrumServerId) ??
+ nodeSource.firstWhereOrNull((e) => e.uriRaw == newCakeWalletBitcoinUri);
+ final litecoinElectrumServer =
+ nodeSource.firstWhereOrNull((e) => e.id == litecoinElectrumServerId) ??
+ nodeSource.firstWhereOrNull((e) => e.uriRaw == cakeWalletLitecoinElectrumUri);
+ final ethereumNode =
+ nodeSource.firstWhereOrNull((e) => e.id == ethereumNodeId) ??
+ nodeSource.firstWhereOrNull((e) => e.uriRaw == ethereumDefaultNodeUri);
+ final polygonNode =
+ nodeSource.firstWhereOrNull((e) => e.id == polygonNodeId) ??
+ nodeSource.firstWhereOrNull((e) => e.uriRaw == polygonDefaultNodeUri);
+ final baseNode =
+ nodeSource.firstWhereOrNull((e) => e.id == baseNodeId) ??
+ nodeSource.firstWhereOrNull((e) => e.uriRaw == baseDefaultNodeUri);
+ final arbitrumNode =
+ nodeSource.firstWhereOrNull((e) => e.id == arbitrumNodeId) ??
+ nodeSource.firstWhereOrNull((e) => e.uriRaw == arbitrumDefaultNodeUri);
+ final bitcoinCashElectrumServer =
+ nodeSource.firstWhereOrNull((e) => e.id == bitcoinCashElectrumServerId) ??
+ nodeSource.firstWhereOrNull(
+ (e) => e.uriRaw == cakeWalletBitcoinCashDefaultNodeUri);
+ final nanoNode =
+ nodeSource.firstWhereOrNull((e) => e.id == nanoNodeId) ??
+ nodeSource.firstWhereOrNull((e) => e.uriRaw == nanoDefaultNodeUri);
+ final decredNode =
+ nodeSource.firstWhereOrNull((e) => e.id == decredNodeId) ??
+ nodeSource.firstWhereOrNull((e) => e.uriRaw == decredDefaultUri);
+ final nanoPowNode =
+ powNodeSource.firstWhereOrNull((e) => e.id == nanoPowNodeId) ??
+ powNodeSource.firstWhereOrNull(
+ (e) => e.uriRaw == nanoDefaultPowNodeUri);
+ final solanaNode =
+ nodeSource.firstWhereOrNull((e) => e.id == solanaNodeId) ??
+ nodeSource.firstWhereOrNull((e) => e.uriRaw == solanaDefaultNodeUri);
+ final tronNode =
+ nodeSource.firstWhereOrNull((e) => e.id == tronNodeId) ??
+ nodeSource.firstWhereOrNull((e) => e.uriRaw == tronDefaultNodeUri);
+ final wowneroNode =
+ nodeSource.firstWhereOrNull((e) => e.id == wowneroNodeId) ??
+ nodeSource.firstWhereOrNull((e) => e.uriRaw == wowneroDefaultNodeUri);
+ final zanoNode =
+ nodeSource.firstWhereOrNull((e) => e.id == zanoNodeId) ??
+ nodeSource.firstWhereOrNull((e) => e.uriRaw == zanoDefaultNodeUri);
+ final dogecoinNode =
+ nodeSource.firstWhereOrNull((e) => e.id == dogecoinNodeId) ??
+ nodeSource.firstWhereOrNull((e) => e.uriRaw == dogecoinDefaultNodeUri);
+ final zcashNode =
+ nodeSource.firstWhereOrNull((e) => e.id == zcashNodeId) ??
+ nodeSource.firstWhereOrNull((e) => e.uriRaw == zcashDefaultNodeUri);
+ final bscNode =
+ nodeSource.firstWhereOrNull((e) => e.id == bscNodeId) ??
+ nodeSource.firstWhereOrNull((e) => e.uriRaw == bscDefaultNodeUri);
final packageInfo = await PackageInfo.fromPlatform();
final deviceName = await _getDeviceName() ?? '';
@@ -1572,7 +1594,7 @@ abstract class SettingsStoreBase with Store {
final mwebAdDismissed =
await sharedPreferences.getBool(PreferencesKey.mwebAdDismissed) ?? false;
-
+
final balanceHideCounter = await sharedPreferences.getInt(PreferencesKey.balanceHideCounter) ?? 0;
return SettingsStore(
@@ -2085,20 +2107,21 @@ abstract class SettingsStoreBase with Store {
}
Future<void> _saveCurrentNode(Node node, WalletType walletType) async {
+
switch (walletType) {
case WalletType.bitcoin:
await _sharedPreferences.setInt(
- PreferencesKey.currentBitcoinElectrumSererIdKey, node.key as int);
+ PreferencesKey.currentBitcoinElectrumSererIdKey, node.id);
break;
case WalletType.litecoin:
await _sharedPreferences.setInt(
- PreferencesKey.currentLitecoinElectrumSererIdKey, node.key as int);
+ PreferencesKey.currentLitecoinElectrumSererIdKey, node.id);
break;
case WalletType.monero:
- await _sharedPreferences.setInt(PreferencesKey.currentNodeIdKey, node.key as int);
+ await _sharedPreferences.setInt(PreferencesKey.currentNodeIdKey, node.id);
break;
case WalletType.haven:
- await _sharedPreferences.setInt(PreferencesKey.currentHavenNodeIdKey, node.key as int);
+ await _sharedPreferences.setInt(PreferencesKey.currentHavenNodeIdKey, node.id);
break;
case WalletType.ethereum:
case WalletType.polygon:
@@ -2107,36 +2130,36 @@ abstract class SettingsStoreBase with Store {
case WalletType.bsc:
final chainId = evm!.getChainIdByWalletType(node.type);
final preferenceKey = _getEVMNodePreferenceKey(chainId);
- await _sharedPreferences.setInt(preferenceKey, node.key as int);
+ await _sharedPreferences.setInt(preferenceKey, node.id);
nodes[node.type] = node;
break;
case WalletType.bitcoinCash:
await _sharedPreferences.setInt(
- PreferencesKey.currentBitcoinCashNodeIdKey, node.key as int);
+ PreferencesKey.currentBitcoinCashNodeIdKey, node.id);
break;
case WalletType.nano:
- await _sharedPreferences.setInt(PreferencesKey.currentNanoNodeIdKey, node.key as int);
+ await _sharedPreferences.setInt(PreferencesKey.currentNanoNodeIdKey, node.id);
break;
case WalletType.solana:
- await _sharedPreferences.setInt(PreferencesKey.currentSolanaNodeIdKey, node.key as int);
+ await _sharedPreferences.setInt(PreferencesKey.currentSolanaNodeIdKey, node.id);
break;
case WalletType.tron:
- await _sharedPreferences.setInt(PreferencesKey.currentTronNodeIdKey, node.key as int);
+ await _sharedPreferences.setInt(PreferencesKey.currentTronNodeIdKey, node.id);
break;
case WalletType.wownero:
- await _sharedPreferences.setInt(PreferencesKey.currentWowneroNodeIdKey, node.key as int);
+ await _sharedPreferences.setInt(PreferencesKey.currentWowneroNodeIdKey, node.id);
break;
case WalletType.decred:
- await _sharedPreferences.setInt(PreferencesKey.currentDecredNodeIdKey, node.key as int);
+ await _sharedPreferences.setInt(PreferencesKey.currentDecredNodeIdKey, node.id);
break;
case WalletType.zano:
- await _sharedPreferences.setInt(PreferencesKey.currentZanoNodeIdKey, node.key as int);
+ await _sharedPreferences.setInt(PreferencesKey.currentZanoNodeIdKey, node.id);
break;
case WalletType.dogecoin:
- await _sharedPreferences.setInt(PreferencesKey.currentDogecoinNodeIdKey, node.key as int);
+ await _sharedPreferences.setInt(PreferencesKey.currentDogecoinNodeIdKey, node.id);
break;
case WalletType.zcash:
- await _sharedPreferences.setInt(PreferencesKey.currentZcashNodeIdKey, node.key as int);
+ await _sharedPreferences.setInt(PreferencesKey.currentZcashNodeIdKey, node.id);
break;
case WalletType.none:
throw UnimplementedError();
@@ -2150,7 +2173,7 @@ abstract class SettingsStoreBase with Store {
Future<void> _saveCurrentPowNode(Node node, WalletType walletType) async {
switch (walletType) {
case WalletType.nano:
- await _sharedPreferences.setInt(PreferencesKey.currentNanoPowNodeIdKey, node.key as int);
+ await _sharedPreferences.setInt(PreferencesKey.currentNanoPowNodeIdKey, node.id);
break;
default:
break;
diff --git a/lib/utils/exception_handler.dart b/lib/utils/exception_handler.dart
index 42d289dd..e3f101c1 100644
--- a/lib/utils/exception_handler.dart
+++ b/lib/utils/exception_handler.dart
@@ -117,7 +117,7 @@ class ExceptionHandler {
if (await onLedgerError(errorDetails)) return;
if (kDebugMode || kProfileMode) {
- if (_ignoreError(errorDetails.exception.toString()) ||
+ if(_ignoreError(errorDetails.exception.toString()) ||
_ignoreError(errorDetails.stack.toString())) {
printV("(BELOW ERROR IS IGNORED AND WILL NOT TRIGGER POPUP IN PROD)");
}
@@ -127,8 +127,7 @@ class ExceptionHandler {
}
if (_ignoreError(errorDetails.exception.toString()) ||
- _ignoreError(errorDetails.stack.toString()) ||
- _flutterErrorIgnore(errorDetails)) {
+ _ignoreError(errorDetails.stack.toString())) {
return;
}
@@ -216,7 +215,8 @@ class ExceptionHandler {
return S.current.ledger_error_tx_rejected_by_user;
} else if (errorCode.contains("5515")) {
return S.current.ledger_error_device_locked;
- } else if (["6e01", "6d02", "6511", "6e00"].any((e) => errorCode.contains(e))) {
+ } else
+ if (["6e01", "6d02", "6511", "6e00"].any((e) => errorCode.contains(e))) {
return S.current.ledger_error_wrong_app;
}
return null;
@@ -229,8 +229,9 @@ class ExceptionHandler {
context: navigatorKey.currentContext!,
builder: (context) => AlertWithOneAction(
alertTitle: "Ledger Error",
- alertContent: interpretErrorCode(errorDetails.exception.toString()) ??
- S.of(context).ledger_connection_error,
+ alertContent:
+ interpretErrorCode(errorDetails.exception.toString()) ??
+ S.of(context).ledger_connection_error,
buttonText: S.of(context).close,
buttonAction: () => Navigator.of(context).pop(),
),
@@ -295,7 +296,7 @@ class ExceptionHandler {
"Wallet is null",
"Wrong Device Status: 0x5515 (UNKNOWN)",
"Command handling failed. With error: hostUnreachable",
-
+
"FocusScopeNode was used after being disposed",
"_getDismissibleFlushbar",
"_QueuedFuture.execute (package:universal_ble/src/queue.dart:65)",
@@ -438,10 +439,4 @@ class ExceptionHandler {
_hasError = false;
}
-
- static bool _flutterErrorIgnore(FlutterErrorDetails errorDetails) {
- // most probably a flutter context error so just ignore it if there is no stack we can debug with
- return errorDetails.exception.toString().contains("Null check operator used on a null value") &&
- errorDetails.stack == null;
- }
}
diff --git a/lib/view_model/node_list/node_create_or_edit_view_model.dart b/lib/view_model/node_list/node_create_or_edit_view_model.dart
index a238b0d1..774136ac 100644
--- a/lib/view_model/node_list/node_create_or_edit_view_model.dart
+++ b/lib/view_model/node_list/node_create_or_edit_view_model.dart
@@ -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;
diff --git a/lib/view_model/node_list/node_list_view_model.dart b/lib/view_model/node_list/node_list_view_model.dart
index e64b9473..55207f0d 100644
--- a/lib/view_model/node_list/node_list_view_model.dart
+++ b/lib/view_model/node_list/node_list_view_model.dart
@@ -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));
+
}
}
diff --git a/lib/view_model/node_list/pow_node_list_view_model.dart b/lib/view_model/node_list/pow_node_list_view_model.dart
index d917779c..b7e185e2 100644
--- a/lib/view_model/node_list/pow_node_list_view_model.dart
+++ b/lib/view_model/node_list/pow_node_list_view_model.dart
@@ -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());
}
}
diff --git a/lib/view_model/restore_from_backup_view_model.dart b/lib/view_model/restore_from_backup_view_model.dart
index 3794d12d..a1a273eb 100644
--- a/lib/view_model/restore_from_backup_view_model.dart
+++ b/lib/view_model/restore_from_backup_view_model.dart
@@ -62,7 +62,7 @@ abstract class RestoreFromBackupViewModelBase with Store {
final store = getIt.get<AppStore>();
ReactionDisposer? reaction;
- await store.settingsStore.reload(nodeSource: getIt.get<Box<Node>>());
+ //await store.settingsStore.reload(nodeSource: getIt.get<Box<Node>>());
await store.themeStore.loadSavedTheme(isFromBackup: true);
reaction = autorun((_) {
final wallet = store.wallet;
diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb
index d779be35..6adcddda 100644
--- a/res/values/strings_ar.arb
+++ b/res/values/strings_ar.arb
@@ -1377,4 +1377,4 @@
"zcash_card_missing_funds": "هل أموالك مفقودة؟",
"zcash_card_scan": "مسح",
"zcash_card_warning": "لا تُغلق التطبيق حتى يكتمل الإجراء، لأنك إن فعلت ذلك فستحتاج هذه العملية إلى البدء من جديد من البداية."
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb
index b10eb982..07ac4cb2 100644
--- a/res/values/strings_bg.arb
+++ b/res/values/strings_bg.arb
@@ -1377,4 +1377,4 @@
"zcash_card_missing_funds": "Липсват средства?",
"zcash_card_scan": "Сканирай",
"zcash_card_warning": "Не затваряйте приложението, докато процедурата не приключи. Ако го направите, процесът ще трябва да започне отначало."
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb
index 46197778..17311f76 100644
--- a/res/values/strings_cs.arb
+++ b/res/values/strings_cs.arb
@@ -1377,4 +1377,4 @@
"zcash_card_missing_funds": "Chybějící prostředky?",
"zcash_card_scan": "Skenovat",
"zcash_card_warning": "Nezavírejte aplikaci, dokud se postup nedokončí. Pokud tak učiníte, bude nutné tento proces spustit znovu od začátku."
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb
index c8a562a3..85b08578 100644
--- a/res/values/strings_de.arb
+++ b/res/values/strings_de.arb
@@ -1381,4 +1381,4 @@
"zcash_card_missing_funds": "Fehlende Gelder?",
"zcash_card_scan": "Scannen",
"zcash_card_warning": "Schließen Sie die App nicht, bis der Vorgang abgeschlossen ist. Andernfalls muss der Vorgang von Grund auf neu gestartet werden."
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb
index 7c972bd0..7093d823 100644
--- a/res/values/strings_es.arb
+++ b/res/values/strings_es.arb
@@ -1379,4 +1379,4 @@
"zcash_card_missing_funds": "¿Faltan fondos?",
"zcash_card_scan": "Escanear",
"zcash_card_warning": "No cierre la aplicación hasta que se complete el procedimiento; si lo hace, este proceso deberá reiniciarse desde cero."
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_fa.arb b/res/values/strings_fa.arb
index 937d906a..f75cf9c4 100644
--- a/res/values/strings_fa.arb
+++ b/res/values/strings_fa.arb
@@ -1374,4 +1374,4 @@
"zcash_card_missing_funds": "موجودی گم شده؟",
"zcash_card_scan": "اسکن",
"zcash_card_warning": "تا زمانی که این فرایند کامل نشده است، برنامه را نبندید؛ در غیر این صورت، این فرایند باید از ابتدا دوباره شروع شود."
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb
index ecfb6ad4..1fe1f36e 100644
--- a/res/values/strings_fr.arb
+++ b/res/values/strings_fr.arb
@@ -1377,4 +1377,4 @@
"zcash_card_missing_funds": "Fonds manquants ?",
"zcash_card_scan": "Scanner",
"zcash_card_warning": "Ne fermez pas l'application tant que la procédure n'est pas terminée. Si vous le faites, ce processus devra redémarrer depuis le début."
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_gn.arb b/res/values/strings_gn.arb
index 36418cfa..70a0def4 100644
--- a/res/values/strings_gn.arb
+++ b/res/values/strings_gn.arb
@@ -1116,4 +1116,4 @@
"zcash_card_missing_funds": "¿Nde fondo okañy?",
"zcash_card_scan": "Escanear",
"zcash_card_warning": "Ani remboty pe app pe procedimiento opa hag̃ua, rejapo ramo upéicha ko proceso tekotevẽta oñepyrũ jey cero guive."
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb
index e966ac2e..e7d46a28 100644
--- a/res/values/strings_ha.arb
+++ b/res/values/strings_ha.arb
@@ -1380,4 +1380,4 @@
"zcash_card_missing_funds": "Kuɗi sun ɓace?",
"zcash_card_scan": "Duba",
"zcash_card_warning": "Kada ku rufe manhajar har sai an kammala aikin; idan kun yi haka, wannan tsari zai buƙaci a sake farawa daga farko."
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb
index 67fd75d5..232c9668 100644
--- a/res/values/strings_hi.arb
+++ b/res/values/strings_hi.arb
@@ -736,8 +736,8 @@
"payjoin_unavailable_sheet_title": "Payjoin उपलब्ध क्यों नहीं है?",
"payment_id": "भुगतान आईडी: ",
"payment_made_easy": "भुगतान करना आसान",
- "payment_was_received": "आपका भुगतान प्राप्त हो गया।",
"Payment_was_received": "आपका भुगतान प्राप्त हो गया था।",
+ "payment_was_received": "आपका भुगतान प्राप्त हो गया।",
"payments": "भुगतान",
"pending": " (लंबित)",
"percentageOf": "${amount} का",
@@ -1379,4 +1379,4 @@
"zcash_card_missing_funds": "फंड गायब हैं?",
"zcash_card_scan": "स्कैन",
"zcash_card_warning": "प्रक्रिया पूरी होने तक ऐप बंद न करें। यदि आप ऐसा करते हैं, तो यह प्रक्रिया शुरू से फिर से शुरू करनी होगी।"
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb
index 6b449111..10f8e27a 100644
--- a/res/values/strings_hr.arb
+++ b/res/values/strings_hr.arb
@@ -1377,4 +1377,4 @@
"zcash_card_missing_funds": "Nedostaju sredstva?",
"zcash_card_scan": "Skeniraj",
"zcash_card_warning": "Ne zatvarajte aplikaciju dok se postupak ne dovrši; ako to učinite, postupak će se morati ponovno pokrenuti ispočetka."
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_hy.arb b/res/values/strings_hy.arb
index 21182981..2c1da86a 100644
--- a/res/values/strings_hy.arb
+++ b/res/values/strings_hy.arb
@@ -1375,4 +1375,4 @@
"zcash_card_missing_funds": "Միջոցները բացակա՞յում են",
"zcash_card_scan": "Սկանավորել",
"zcash_card_warning": "Մի փակեք հավելվածը մինչև ընթացակարգի ավարտը, քանի որ հակառակ դեպքում այս գործընթացը պետք է վերագործարկվի զրոյից։"
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb
index 7dff8cb8..7a36f533 100644
--- a/res/values/strings_id.arb
+++ b/res/values/strings_id.arb
@@ -1380,4 +1380,4 @@
"zcash_card_missing_funds": "Dana hilang?",
"zcash_card_scan": "Pindai",
"zcash_card_warning": "Jangan tutup aplikasi sampai prosedur selesai. Jika Anda melakukannya, proses ini harus dimulai ulang dari awal."
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb
index 30cc7479..e0e1c0c6 100644
--- a/res/values/strings_it.arb
+++ b/res/values/strings_it.arb
@@ -1379,4 +1379,4 @@
"zcash_card_missing_funds": "Fondi mancanti?",
"zcash_card_scan": "Scansiona",
"zcash_card_warning": "Non chiudere l'app finché la procedura non è completata, altrimenti sarà necessario riavviare il processo da zero."
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb
index aefc4fa7..8b0ce5d4 100644
--- a/res/values/strings_ja.arb
+++ b/res/values/strings_ja.arb
@@ -1377,4 +1377,4 @@
"zcash_card_missing_funds": "資金が見当たりませんか?",
"zcash_card_scan": "スキャン",
"zcash_card_warning": "手順が完了するまでアプリを閉じないでください。閉じると、このプロセスを最初からやり直す必要があります。"
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb
index 5f762a9f..7c83c1b4 100644
--- a/res/values/strings_ko.arb
+++ b/res/values/strings_ko.arb
@@ -1377,4 +1377,4 @@
"zcash_card_missing_funds": "자금이 사라졌나요?",
"zcash_card_scan": "스캔",
"zcash_card_warning": "절차가 완료될 때까지 앱을 닫지 마십시오. 닫으면 이 과정을 처음부터 다시 시작해야 합니다."
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb
index a5a7cf60..33287b74 100644
--- a/res/values/strings_my.arb
+++ b/res/values/strings_my.arb
@@ -1376,4 +1376,4 @@
"zcash_card_missing_funds": "ငွေကြေး ပျောက်ဆုံးနေပါသလား?",
"zcash_card_scan": "စကင်",
"zcash_card_warning": "လုပ်ငန်းစဉ် ပြီးဆုံးသည်အထိ အက်ပ်ကို မပိတ်ပါနှင့်။ ပိတ်လိုက်ပါက ဤလုပ်ငန်းစဉ်ကို အစမှ ပြန်လည်စတင်ရမည်ဖြစ်သည်။"
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb
index 8acc1558..f69dcc08 100644
--- a/res/values/strings_nl.arb
+++ b/res/values/strings_nl.arb
@@ -1374,4 +1374,4 @@
"zcash_card_missing_funds": "Fondsen ontbreken?",
"zcash_card_scan": "Scannen",
"zcash_card_warning": "Sluit de app niet voordat de procedure is voltooid. Als je dit wel doet, moet dit proces helemaal opnieuw worden gestart."
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb
index e4f72081..4df026b9 100644
--- a/res/values/strings_pl.arb
+++ b/res/values/strings_pl.arb
@@ -1375,4 +1375,4 @@
"zcash_card_missing_funds": "Brakuje środków?",
"zcash_card_scan": "Skanuj",
"zcash_card_warning": "Nie zamykaj aplikacji do czasu zakończenia procedury. Jeśli to zrobisz, proces będzie musiał rozpocząć się od nowa."
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb
index fd938d12..3b2dc1bb 100644
--- a/res/values/strings_pt.arb
+++ b/res/values/strings_pt.arb
@@ -1379,4 +1379,4 @@
"zcash_card_missing_funds": "Fundos em falta?",
"zcash_card_scan": "Escanear",
"zcash_card_warning": "Não feche o aplicativo até que o procedimento seja concluído; se você fizer isso, esse processo precisará ser reiniciado do zero."
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb
index cd85cdfb..1b8ec615 100644
--- a/res/values/strings_ru.arb
+++ b/res/values/strings_ru.arb
@@ -1377,4 +1377,4 @@
"zcash_card_missing_funds": "Не хватает средств?",
"zcash_card_scan": "Сканировать",
"zcash_card_warning": "Не закрывайте приложение до завершения процедуры. Если вы это сделаете, процесс придется перезапустить с нуля."
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb
index e2b41f44..71061321 100644
--- a/res/values/strings_th.arb
+++ b/res/values/strings_th.arb
@@ -1376,4 +1376,4 @@
"zcash_card_missing_funds": "ยอดเงินหายไป?",
"zcash_card_scan": "สแกน",
"zcash_card_warning": "อย่าปิดแอปจนกว่าขั้นตอนจะเสร็จสิ้น หากคุณปิดแอป กระบวนการนี้จะต้องเริ่มใหม่ตั้งแต่ต้น"
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb
index 98d6d91d..8d2ff2e9 100644
--- a/res/values/strings_tl.arb
+++ b/res/values/strings_tl.arb
@@ -1376,4 +1376,4 @@
"zcash_card_missing_funds": "Nawawalang pondo?",
"zcash_card_scan": "I-scan",
"zcash_card_warning": "Huwag isara ang app hanggang sa makumpleto ang proseso; kung gagawin mo ito, kakailanganing magsimula muli mula sa simula."
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb
index 1f2a1219..1ce2f60d 100644
--- a/res/values/strings_tr.arb
+++ b/res/values/strings_tr.arb
@@ -1376,4 +1376,4 @@
"zcash_card_missing_funds": "Bakiye eksik mi?",
"zcash_card_scan": "Tara",
"zcash_card_warning": "İşlem tamamlanana kadar uygulamayı kapatmayın; aksi takdirde bu işlemin baştan yeniden başlatılması gerekecektir."
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb
index 63ed3b1e..515faa41 100644
--- a/res/values/strings_uk.arb
+++ b/res/values/strings_uk.arb
@@ -1377,4 +1377,4 @@
"zcash_card_missing_funds": "Зникли кошти?",
"zcash_card_scan": "Сканувати",
"zcash_card_warning": "Не закривайте застосунок, доки процедура не завершиться. Якщо ви це зробите, цей процес потрібно буде перезапустити з нуля."
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb
index b4307505..67be12de 100644
--- a/res/values/strings_ur.arb
+++ b/res/values/strings_ur.arb
@@ -1378,4 +1378,4 @@
"zcash_card_missing_funds": "فنڈز غائب ہیں؟",
"zcash_card_scan": "اسکین کریں",
"zcash_card_warning": "طریقہ کار مکمل ہونے تک ایپ بند نہ کریں۔ اگر آپ ایسا کریں گے تو یہ عمل شروع سے دوبارہ شروع کرنا پڑے گا۔"
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_vi.arb b/res/values/strings_vi.arb
index f53e3a8a..cf47aab4 100644
--- a/res/values/strings_vi.arb
+++ b/res/values/strings_vi.arb
@@ -1373,4 +1373,4 @@
"zcash_card_missing_funds": "Thiếu tiền?",
"zcash_card_scan": "Quét",
"zcash_card_warning": "Không đóng ứng dụng cho đến khi quy trình hoàn tất; nếu bạn làm vậy, quy trình này sẽ phải bắt đầu lại từ đầu."
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb
index 2039dd57..3188cd5d 100644
--- a/res/values/strings_yo.arb
+++ b/res/values/strings_yo.arb
@@ -1377,4 +1377,4 @@
"zcash_card_missing_funds": "Ṣe owó rẹ sọnù?",
"zcash_card_scan": "Ṣàwárí",
"zcash_card_warning": "Maṣe pa ohun elo naa titi ilana naa yoo fi pari; bí o bá ṣe bẹ́ẹ̀, ilana yìí yóò ní láti tún bẹ̀rẹ̀ láti ìbẹ̀rẹ̀."
-}
\ No newline at end of file
+}
diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb
index 1691da60..4a00f0a1 100644
--- a/res/values/strings_zh.arb
+++ b/res/values/strings_zh.arb
@@ -1376,4 +1376,4 @@
"zcash_card_missing_funds": "资金不见了?",
"zcash_card_scan": "扫描",
"zcash_card_warning": "在该过程完成之前请勿关闭应用程序,否则该过程将需要从头重新开始。"
-}
\ No newline at end of file
+}
Why this scored 36/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.