update nano default node (#1408)

* update nano default node * fix node indicator * Update pr_test_build.yml * Update pr_test_build.yml * update default nano node for new wallets * support extra args on tool script * remove nano secrets from node.dart --------- Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

Matthew Fosse committed Jul 4, 2024 at 21:44 UTC 73492ad8655d8f78b3d351d654fe90ec364cada4
8 files changed +75 -88
.github/workflows/pr_test_build.yml
+3
@@ -121,6 +121,8 @@ jobs:
121 touch lib/.secrets.g.dart
122 touch cw_evm/lib/.secrets.g.dart
123 touch cw_solana/lib/.secrets.g.dart
124 + touch cw_core/lib/.secrets.g.dart
125 + touch cw_nano/lib/.secrets.g.dart
126 touch cw_tron/lib/.secrets.g.dart
127 echo "const salt = '${{ secrets.SALT }}';" > lib/.secrets.g.dart
128 echo "const keychainSalt = '${{ secrets.KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
@@ -165,6 +167,7 @@ jobs:
167 echo "const CSRFToken = '${{ secrets.CSRF_TOKEN }}';" >> lib/.secrets.g.dart
168 echo "const quantexExchangeMarkup = '${{ secrets.QUANTEX_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart
169 echo "const nano2ApiKey = '${{ secrets.NANO2_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
170 + echo "const nanoNowNodesApiKey = '${{ secrets.NANO_NOW_NODES_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
171 echo "const tronGridApiKey = '${{ secrets.TRON_GRID_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
172 echo "const tronNowNodesApiKey = '${{ secrets.TRON_NOW_NODES_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
173
assets/nano_node_list.yml
+4 -1
@@ -1,7 +1,10 @@
1 -
2 - uri: rpc.nano.to
2 + uri: nano.nownodes.io
3 useSSL: true
4 is_default: true
5 +-
6 + uri: rpc.nano.to
7 + useSSL: true
8 -
9 uri: node.nautilus.io
10 path: /api
cw_core/lib/node.dart
+1 -18
@@ -6,6 +6,7 @@ import 'package:hive/hive.dart';
6 import 'package:cw_core/hive_type_ids.dart';
7 import 'package:cw_core/wallet_type.dart';
8 import 'package:http/io_client.dart' as ioc;
9 +
10 // import 'package:tor/tor.dart';
11
12 part 'node.g.dart';
@@ -148,7 +149,6 @@ class Node extends HiveObject with Keyable {
149 return requestMoneroNode();
150 case WalletType.nano:
151 case WalletType.banano:
151 - return requestNanoNode();
152 case WalletType.bitcoin:
153 case WalletType.litecoin:
154 case WalletType.bitcoinCash:
@@ -203,23 +203,6 @@ class Node extends HiveObject with Keyable {
203 }
204 }
205
206 - Future<bool> requestNanoNode() async {
207 - http.Response response = await http.post(
208 - uri,
209 - headers: {'Content-type': 'application/json'},
210 - body: json.encode(
211 - {
212 - "action": "block_count",
213 - },
214 - ),
215 - );
216 - if (response.statusCode == 200) {
217 - return true;
218 - } else {
219 - return false;
220 - }
221 - }
222 -
206 Future<bool> requestNodeWithProxy() async {
207 if (!isValidProxyAddress /* && !Tor.instance.enabled*/) {
208 return false;
cw_nano/lib/nano_client.dart
+8 -6
@@ -10,7 +10,7 @@ import 'package:nanodart/nanodart.dart';
10 import 'package:cw_core/node.dart';
11 import 'package:nanoutil/nanoutil.dart';
12 import 'package:shared_preferences/shared_preferences.dart';
13 -import 'package:cw_nano/.secrets.g.dart' as secrets;
13 +import 'package:cw_nano/.secrets.g.dart' as nano_secrets;
14
15 class NanoClient {
16 static const Map<String, String> CAKE_HEADERS = {
@@ -54,12 +54,14 @@ class NanoClient {
54 }
55
56 Map<String, String> getHeaders() {
57 - if (_node!.uri == "https://rpc.nano.to") {
58 - return CAKE_HEADERS..addAll({
59 - "key": secrets.nano2ApiKey,
60 - });
57 + final headers = Map<String, String>.from(CAKE_HEADERS);
58 + if (_node!.uri.host == "rpc.nano.to") {
59 + headers["key"] = nano_secrets.nano2ApiKey;
60 }
62 - return CAKE_HEADERS;
61 + if (_node!.uri.host == "nano.nownodes.io") {
62 + headers["api-key"] = nano_secrets.nanoNowNodesApiKey;
63 + }
64 + return headers;
65 }
66
67 Future<NanoBalance> getBalance(String address) async {
lib/entities/default_settings_migration.dart
+24 -2
@@ -34,7 +34,7 @@ const havenDefaultNodeUri = 'nodes.havenprotocol.org:443';
34 const ethereumDefaultNodeUri = 'ethereum.publicnode.com';
35 const polygonDefaultNodeUri = 'polygon-bor.publicnode.com';
36 const cakeWalletBitcoinCashDefaultNodeUri = 'bitcoincash.stackwallet.com:50002';
37 -const nanoDefaultNodeUri = 'rpc.nano.to';
37 +const nanoDefaultNodeUri = 'nano.nownodes.io';
38 const nanoDefaultPowNodeUri = 'rpc.nano.to';
39 const solanaDefaultNodeUri = 'rpc.ankr.com';
40 const tronDefaultNodeUri = 'trx.nownodes.io';
@@ -241,6 +241,9 @@ Future<void> defaultSettingsMigration(
241 case 38:
242 await fixBtcDerivationPaths(walletInfoSource);
243 break;
244 + case 39:
245 + await changeDefaultNanoNode(nodes, sharedPreferences);
246 + break;
247 default:
248 break;
249 }
@@ -836,6 +839,25 @@ Future<void> updateBtcNanoWalletInfos(Box<WalletInfo> walletsInfoSource) async {
839 }
840 }
841
842 +Future<void> changeDefaultNanoNode(
843 + Box<Node> nodeSource, SharedPreferences sharedPreferences) async {
844 + const oldNanoNodeUriPattern = 'rpc.nano.to';
845 + final currentNanoNodeId = sharedPreferences.getInt(PreferencesKey.currentNodeIdKey);
846 + final currentNanoNode = nodeSource.values.firstWhere((node) => node.key == currentNanoNodeId);
847 +
848 + final newCakeWalletNode = Node(
849 + uri: nanoDefaultNodeUri,
850 + type: WalletType.nano,
851 + useSSL: true,
852 + );
853 +
854 + await nodeSource.add(newCakeWalletNode);
855 +
856 + if (currentNanoNode.uri.toString().contains(oldNanoNodeUriPattern)) {
857 + await sharedPreferences.setInt(PreferencesKey.currentNodeIdKey, newCakeWalletNode.key as int);
858 + }
859 +}
860 +
861 Future<void> changeDefaultBitcoinNode(
862 Box<Node> nodeSource, SharedPreferences sharedPreferences) async {
863 const cakeWalletBitcoinNodeUriPattern = '.cakewallet.com';
@@ -1225,4 +1247,4 @@ Future<void> replaceTronDefaultNode({
1247
1248 // If it's not, we switch user to the new default node: NowNodes
1249 await changeTronCurrentNodeToDefault(sharedPreferences: sharedPreferences, nodes: nodes);
1228 -}
\ No newline at end of file
1250 +}
lib/main.dart
+1 -1
@@ -203,7 +203,7 @@ Future<void> initializeAppConfigs() async {
203 transactionDescriptions: transactionDescriptions,
204 secureStorage: secureStorage,
205 anonpayInvoiceInfo: anonpayInvoiceInfo,
206 - initialMigrationVersion: 38,
206 + initialMigrationVersion: 39,
207 );
208 }
209
tool/generate_secrets_config.dart
+31 -60
@@ -3,7 +3,8 @@ import 'dart:io';
3 import 'utils/secret_key.dart';
4 import 'utils/utils.dart';
5
6 -const configPath = 'tool/.secrets-config.json';
6 +const baseConfigPath = 'tool/.secrets-config.json';
7 +const coreConfigPath = 'tool/.core-secrets-config.json';
8 const evmChainsConfigPath = 'tool/.evm-secrets-config.json';
9 const solanaConfigPath = 'tool/.solana-secrets-config.json';
10 const nanoConfigPath = 'tool/.nano-secrets-config.json';
@@ -11,6 +12,23 @@ const tronConfigPath = 'tool/.tron-secrets-config.json';
12
13 Future<void> main(List<String> args) async => generateSecretsConfig(args);
14
15 +Future<void> writeConfig(
16 + File configFile,
17 + List<SecretKey> newSecrets, {
18 + Map<String, dynamic>? existingSecrets,
19 +}) async {
20 + final secrets = existingSecrets ?? <String, dynamic>{};
21 + newSecrets.forEach((sec) {
22 + if (secrets[sec.name] != null) {
23 + return;
24 + }
25 + secrets[sec.name] = sec.generate();
26 + });
27 + String secretsJson = JsonEncoder.withIndent(' ').convert(secrets);
28 + await configFile.writeAsString(secretsJson);
29 + secrets.clear();
30 +}
31 +
32 Future<void> generateSecretsConfig(List<String> args) async {
33 final extraInfo = args.fold(<String, dynamic>{}, (Map<String, dynamic> acc, String arg) {
34 final parts = arg.split('=');
@@ -19,7 +37,8 @@ Future<void> generateSecretsConfig(List<String> args) async {
37 return acc;
38 });
39
22 - final configFile = File(configPath);
40 + final baseConfigFile = File(baseConfigPath);
41 + final coreConfigFile = File(coreConfigPath);
42 final evmChainsConfigFile = File(evmChainsConfigPath);
43 final solanaConfigFile = File(solanaConfigPath);
44 final nanoConfigFile = File(nanoConfigPath);
@@ -32,70 +51,22 @@ Future<void> generateSecretsConfig(List<String> args) async {
51 if (key.contains('--')) {
52 return true;
53 }
35 -
54 return false;
55 });
56
39 - if (configFile.existsSync()) {
57 + if (baseConfigFile.existsSync()) {
58 if (extraInfo['--force'] == 1) {
41 - await configFile.delete();
59 + await baseConfigFile.delete();
60 } else {
61 return;
62 }
63 }
46 -
47 - // base:
48 - SecretKey.base.forEach((sec) {
49 - if (secrets[sec.name] != null) {
50 - return;
51 - }
52 - secrets[sec.name] = sec.generate();
53 - });
54 - var secretsJson = JsonEncoder.withIndent(' ').convert(secrets);
55 - await configFile.writeAsString(secretsJson);
56 - secrets.clear();
57 -
58 - // evm chains:
59 - SecretKey.evmChainsSecrets.forEach((sec) {
60 - if (secrets[sec.name] != null) {
61 - return;
62 - }
63 - secrets[sec.name] = sec.generate();
64 - });
65 - secretsJson = JsonEncoder.withIndent(' ').convert(secrets);
66 - await evmChainsConfigFile.writeAsString(secretsJson);
67 - secrets.clear();
68 -
69 - // solana:
70 - SecretKey.solanaSecrets.forEach((sec) {
71 - if (secrets[sec.name] != null) {
72 - return;
73 - }
74 - secrets[sec.name] = sec.generate();
75 - });
76 - secretsJson = JsonEncoder.withIndent(' ').convert(secrets);
77 - await solanaConfigFile.writeAsString(secretsJson);
78 - secrets.clear();
79 -
80 - // nano:
81 - SecretKey.nanoSecrets.forEach((sec) {
82 - if (secrets[sec.name] != null) {
83 - return;
84 - }
85 - secrets[sec.name] = sec.generate();
86 - });
87 - secretsJson = JsonEncoder.withIndent(' ').convert(secrets);
88 - await nanoConfigFile.writeAsString(secretsJson);
89 - secrets.clear();
90 -
91 - SecretKey.tronSecrets.forEach((sec) {
92 - if (secrets[sec.name] != null) {
93 - return;
94 - }
95 -
96 - secrets[sec.name] = sec.generate();
97 - });
98 - secretsJson = JsonEncoder.withIndent(' ').convert(secrets);
99 - await tronConfigFile.writeAsString(secretsJson);
100 - secrets.clear();
64 +
65 + await writeConfig(baseConfigFile, SecretKey.base, existingSecrets: secrets);
66 +
67 + await writeConfig(coreConfigFile, SecretKey.coreSecrets);
68 + await writeConfig(evmChainsConfigFile, SecretKey.evmChainsSecrets);
69 + await writeConfig(solanaConfigFile, SecretKey.solanaSecrets);
70 + await writeConfig(nanoConfigFile, SecretKey.nanoSecrets);
71 + await writeConfig(tronConfigFile, SecretKey.tronSecrets);
72 }
tool/utils/secret_key.dart
+3
@@ -45,6 +45,8 @@ class SecretKey {
45 SecretKey('authorization', () => ''),
46 ];
47
48 + static final coreSecrets = [];
49 +
50 static final evmChainsSecrets = [
51 SecretKey('etherScanApiKey', () => ''),
52 SecretKey('polygonScanApiKey', () => ''),
@@ -57,6 +59,7 @@ class SecretKey {
59
60 static final nanoSecrets = [
61 SecretKey('nano2ApiKey', () => ''),
62 + SecretKey('nanoNowNodesApiKey', () => ''),
63 ];
64
65 static final tronSecrets = [