Skip to content

Commit 130e1b3

Browse files
committed
update (ba)nano servers
1 parent 203744d commit 130e1b3

File tree

4 files changed

+107
-60
lines changed

4 files changed

+107
-60
lines changed

lib/services/nano_api.dart

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import 'dart:convert';
22

33
import 'package:nanodart/nanodart.dart';
4+
45
import '../networking/http.dart';
5-
import 'tor_service.dart';
66
import '../utilities/prefs.dart';
7+
import 'tor_service.dart';
78

89
class NanoAPI {
910
static Future<
@@ -14,6 +15,7 @@ class NanoAPI {
1415
required Uri server,
1516
required bool representative,
1617
required String account,
18+
required Map<String, String> headers,
1719
}) async {
1820
NAccountInfo? accountInfo;
1921
Exception? exception;
@@ -23,9 +25,7 @@ class NanoAPI {
2325
try {
2426
final response = await client.post(
2527
url: server,
26-
headers: {
27-
"Content-Type": "application/json",
28-
},
28+
headers: headers,
2929
body: jsonEncode({
3030
"action": "account_info",
3131
"representative": "true",
@@ -64,6 +64,7 @@ class NanoAPI {
6464
required String balance,
6565
required String privateKey,
6666
required String work,
67+
required Map<String, String> headers,
6768
}) async {
6869
final Map<String, String> block = {
6970
"type": "state",
@@ -98,7 +99,11 @@ class NanoAPI {
9899

99100
block["signature"] = signature;
100101

101-
final map = await postBlock(server: server, block: block);
102+
final map = await postBlock(
103+
server: server,
104+
block: block,
105+
headers: headers,
106+
);
102107

103108
if (map is Map && map["error"] != null) {
104109
throw Exception(map["error"].toString());
@@ -111,14 +116,13 @@ class NanoAPI {
111116
static Future<dynamic> postBlock({
112117
required Uri server,
113118
required Map<String, dynamic> block,
119+
required Map<String, String> headers,
114120
}) async {
115121
final HTTP client = HTTP();
116122

117123
final response = await client.post(
118124
url: server,
119-
headers: {
120-
"Content-Type": "application/json",
121-
},
125+
headers: headers,
122126
body: jsonEncode({
123127
"action": "process",
124128
"json_block": "true",

lib/wallets/crypto_currency/coins/banano.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'package:nanodart/nanodart.dart';
2+
23
import '../../../models/isar/models/blockchain_data/address.dart';
34
import '../../../models/node_model.dart';
45
import '../../../utilities/default_nodes.dart';
@@ -66,7 +67,8 @@ class Banano extends NanoCurrency {
6667
switch (network) {
6768
case CryptoCurrencyNetwork.main:
6869
return NodeModel(
69-
host: "https://kaliumapi.appditto.com/api",
70+
// host: "https://kaliumapi.appditto.com/api",
71+
host: "https://nodes.nanswap.com/BAN",
7072
port: 443,
7173
name: DefaultNodes.defaultName,
7274
id: DefaultNodes.buildId(this),

lib/wallets/crypto_currency/coins/nano.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'package:nanodart/nanodart.dart';
2+
23
import '../../../models/isar/models/isar_models.dart';
34
import '../../../models/node_model.dart';
45
import '../../../utilities/default_nodes.dart';
@@ -66,7 +67,8 @@ class Nano extends NanoCurrency {
6667
switch (network) {
6768
case CryptoCurrencyNetwork.main:
6869
return NodeModel(
69-
host: "https://rainstorm.city/api",
70+
// host: "https://rainstorm.city/api",
71+
host: "https://nodes.nanswap.com/XNO",
7072
port: 443,
7173
name: DefaultNodes.defaultName,
7274
id: DefaultNodes.buildId(this),

lib/wallets/wallet/wallet_mixin_interfaces/nano_interface.dart

Lines changed: 89 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,17 @@ import '../intermediate/bip39_wallet.dart';
2525
// const _kWorkServer = "https://rpc.nano.to";
2626
const _kWorkServer = "https://nodes.nanswap.com/XNO";
2727

28+
Map<String, String> _buildHeaders(String url) {
29+
final result = {
30+
'Content-type': 'application/json',
31+
};
32+
if (url
33+
case "https://nodes.nanswap.com/XNO" || "https://nodes.nanswap.com/BAN") {
34+
result["nodes-api-key"] = kNanoSwapRpcApiKey;
35+
}
36+
return result;
37+
}
38+
2839
mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
2940
// since nano based coins only have a single address/account we can cache
3041
// the address instead of fetching from db every time we need it in certain
@@ -39,10 +50,7 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
3950
return _httpClient
4051
.post(
4152
url: Uri.parse(_kWorkServer), // this should be a
42-
headers: {
43-
'Content-type': 'application/json',
44-
"nodes-api-key": kNanoSwapRpcApiKey,
45-
},
53+
headers: _buildHeaders(_kWorkServer),
4654
body: json.encode(
4755
{
4856
"action": "work_generate",
@@ -99,20 +107,17 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
99107
// TODO: the opening block of an account is a special case
100108
bool openBlock = false;
101109

102-
final headers = {
103-
"Content-Type": "application/json",
104-
};
105-
106110
// first check if the account is open:
107111
// get the account info (we need the frontier and representative):
108112
final infoBody = jsonEncode({
109113
"action": "account_info",
110114
"representative": "true",
111115
"account": publicAddress,
112116
});
117+
final node = getCurrentNode();
113118
final infoResponse = await _httpClient.post(
114-
url: Uri.parse(getCurrentNode().host),
115-
headers: headers,
119+
url: Uri.parse(node.host),
120+
headers: _buildHeaders(node.host),
116121
body: infoBody,
117122
proxyInfo: prefs.useTor ? TorService.sharedInstance.getProxyInfo() : null,
118123
);
@@ -130,8 +135,8 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
130135
});
131136

132137
final balanceResponse = await _httpClient.post(
133-
url: Uri.parse(getCurrentNode().host),
134-
headers: headers,
138+
url: Uri.parse(node.host),
139+
headers: _buildHeaders(node.host),
135140
body: balanceBody,
136141
proxyInfo: prefs.useTor ? TorService.sharedInstance.getProxyInfo() : null,
137142
);
@@ -204,8 +209,8 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
204209
"block": receiveBlock,
205210
});
206211
final processResponse = await _httpClient.post(
207-
url: Uri.parse(getCurrentNode().host),
208-
headers: headers,
212+
url: Uri.parse(node.host),
213+
headers: _buildHeaders(node.host),
209214
body: processBody,
210215
proxyInfo: prefs.useTor ? TorService.sharedInstance.getProxyInfo() : null,
211216
);
@@ -218,14 +223,14 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
218223
}
219224

220225
Future<void> _confirmAllReceivable(String accountAddress) async {
226+
final node = getCurrentNode();
221227
final receivableResponse = await _httpClient.post(
222-
url: Uri.parse(getCurrentNode().host),
223-
headers: {"Content-Type": "application/json"},
228+
url: Uri.parse(node.host),
229+
headers: _buildHeaders(node.host),
224230
body: jsonEncode({
225231
"action": "receivable",
226232
"source": "true",
227233
"account": accountAddress,
228-
"count": "-1",
229234
}),
230235
proxyInfo: prefs.useTor ? TorService.sharedInstance.getProxyInfo() : null,
231236
);
@@ -253,10 +258,12 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
253258
final address =
254259
(_cachedAddress ?? await getCurrentReceivingAddress())!.value;
255260

261+
final node = getCurrentNode();
256262
final response = await NanoAPI.getAccountInfo(
257263
server: serverURI,
258264
representative: true,
259265
account: address,
266+
headers: _buildHeaders(node.host),
260267
);
261268

262269
return response.accountInfo?.representative ??
@@ -265,7 +272,8 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
265272

266273
Future<bool> changeRepresentative(String newRepresentative) async {
267274
try {
268-
final serverURI = Uri.parse(getCurrentNode().host);
275+
final node = getCurrentNode();
276+
final serverURI = Uri.parse(node.host);
269277
await updateBalance();
270278
final balance = info.cachedBalance.spendable.raw.toString();
271279
final String privateKey = await _getPrivateKeyFromMnemonic();
@@ -276,6 +284,7 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
276284
server: serverURI,
277285
representative: true,
278286
account: address,
287+
headers: _buildHeaders(node.host),
279288
);
280289

281290
if (response.accountInfo == null) {
@@ -293,6 +302,7 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
293302
balance: balance,
294303
privateKey: privateKey,
295304
work: work!,
305+
headers: _buildHeaders(node.host),
296306
);
297307
} catch (_) {
298308
rethrow;
@@ -337,11 +347,11 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
337347

338348
@override
339349
Future<bool> pingCheck() async {
340-
final uri = Uri.parse(getCurrentNode().host);
341-
350+
final node = getCurrentNode();
351+
final uri = Uri.parse(node.host);
342352
final response = await _httpClient.post(
343353
url: uri,
344-
headers: {"Content-Type": "application/json"},
354+
headers: _buildHeaders(node.host),
345355
body: jsonEncode(
346356
{
347357
"action": "version",
@@ -390,13 +400,10 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
390400
"account": publicAddress,
391401
});
392402

393-
final headers = {
394-
"Content-Type": "application/json",
395-
};
396-
403+
final node = getCurrentNode();
397404
final infoResponse = await _httpClient.post(
398-
url: Uri.parse(getCurrentNode().host),
399-
headers: headers,
405+
url: Uri.parse(node.host),
406+
headers: _buildHeaders(node.host),
400407
body: infoBody,
401408
proxyInfo:
402409
prefs.useTor ? TorService.sharedInstance.getProxyInfo() : null,
@@ -449,8 +456,8 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
449456
"block": sendBlock,
450457
});
451458
final processResponse = await _httpClient.post(
452-
url: Uri.parse(getCurrentNode().host),
453-
headers: headers,
459+
url: Uri.parse(node.host),
460+
headers: _buildHeaders(node.host),
454461
body: processBody,
455462
proxyInfo:
456463
prefs.useTor ? TorService.sharedInstance.getProxyInfo() : null,
@@ -491,24 +498,59 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
491498
}
492499
}
493500

501+
// recurse over api calls if required
502+
// (if more than 200 history items)
503+
Future<Map<String, dynamic>> _fetchAll(
504+
String publicAddress,
505+
String? previous,
506+
Map<String, dynamic>? data,
507+
) async {
508+
final node = getCurrentNode();
509+
final body = {
510+
"action": "account_history",
511+
"account": publicAddress,
512+
"count": "200",
513+
};
514+
515+
if (previous is String) {
516+
body["head"] = previous;
517+
}
518+
519+
final response = await _httpClient.post(
520+
url: Uri.parse(node.host),
521+
headers: _buildHeaders(node.host),
522+
body: jsonEncode(body),
523+
proxyInfo: prefs.useTor ? TorService.sharedInstance.getProxyInfo() : null,
524+
);
525+
526+
// this should really have proper type checking and error propagation but I'm out of time
527+
final newData =
528+
Map<String, dynamic>.from((await jsonDecode(response.body)) as Map);
529+
530+
if (newData["previous"] is String) {
531+
if (data?["history"] is List) {
532+
(newData["history"] as List).addAll(data!["history"] as List);
533+
}
534+
return await _fetchAll(
535+
publicAddress,
536+
newData["previous"] as String,
537+
newData,
538+
);
539+
}
540+
541+
return newData;
542+
}
543+
494544
@override
495545
Future<void> updateTransactions() async {
496546
await updateChainHeight();
497547
final receivingAddress =
498548
(_cachedAddress ?? await getCurrentReceivingAddress())!;
499549
final String publicAddress = receivingAddress.value;
500550
await _confirmAllReceivable(publicAddress);
501-
final response = await _httpClient.post(
502-
url: Uri.parse(getCurrentNode().host),
503-
headers: {"Content-Type": "application/json"},
504-
body: jsonEncode({
505-
"action": "account_history",
506-
"account": publicAddress,
507-
"count": "-1",
508-
}),
509-
proxyInfo: prefs.useTor ? TorService.sharedInstance.getProxyInfo() : null,
510-
);
511-
final data = await jsonDecode(response.body);
551+
552+
final data = await _fetchAll(publicAddress, null, null);
553+
512554
final transactions = data["history"] is List
513555
? data["history"] as List<dynamic>
514556
: <dynamic>[];
@@ -577,13 +619,11 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
577619
"action": "account_balance",
578620
"account": addressString,
579621
});
580-
final headers = {
581-
"Content-Type": "application/json",
582-
};
583622

623+
final node = getCurrentNode();
584624
final response = await _httpClient.post(
585-
url: Uri.parse(getCurrentNode().host),
586-
headers: headers,
625+
url: Uri.parse(node.host),
626+
headers: _buildHeaders(node.host),
587627
body: body,
588628
proxyInfo:
589629
prefs.useTor ? TorService.sharedInstance.getProxyInfo() : null,
@@ -628,12 +668,11 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
628668
"action": "account_info",
629669
"account": publicAddress,
630670
});
631-
final headers = {
632-
"Content-Type": "application/json",
633-
};
671+
672+
final node = getCurrentNode();
634673
final infoResponse = await _httpClient.post(
635-
url: Uri.parse(getCurrentNode().host),
636-
headers: headers,
674+
url: Uri.parse(node.host),
675+
headers: _buildHeaders(node.host),
637676
body: infoBody,
638677
proxyInfo:
639678
prefs.useTor ? TorService.sharedInstance.getProxyInfo() : null,

0 commit comments

Comments
 (0)