@@ -25,6 +25,17 @@ import '../intermediate/bip39_wallet.dart';
2525// const _kWorkServer = "https://rpc.nano.to";
2626const _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+
2839mixin 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