mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-01-03 09:19:22 +00:00
update (ba)nano servers
This commit is contained in:
parent
203744d4f0
commit
130e1b37d6
4 changed files with 107 additions and 60 deletions
|
@ -1,9 +1,10 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:nanodart/nanodart.dart';
|
||||
|
||||
import '../networking/http.dart';
|
||||
import 'tor_service.dart';
|
||||
import '../utilities/prefs.dart';
|
||||
import 'tor_service.dart';
|
||||
|
||||
class NanoAPI {
|
||||
static Future<
|
||||
|
@ -14,6 +15,7 @@ class NanoAPI {
|
|||
required Uri server,
|
||||
required bool representative,
|
||||
required String account,
|
||||
required Map<String, String> headers,
|
||||
}) async {
|
||||
NAccountInfo? accountInfo;
|
||||
Exception? exception;
|
||||
|
@ -23,9 +25,7 @@ class NanoAPI {
|
|||
try {
|
||||
final response = await client.post(
|
||||
url: server,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
headers: headers,
|
||||
body: jsonEncode({
|
||||
"action": "account_info",
|
||||
"representative": "true",
|
||||
|
@ -64,6 +64,7 @@ class NanoAPI {
|
|||
required String balance,
|
||||
required String privateKey,
|
||||
required String work,
|
||||
required Map<String, String> headers,
|
||||
}) async {
|
||||
final Map<String, String> block = {
|
||||
"type": "state",
|
||||
|
@ -98,7 +99,11 @@ class NanoAPI {
|
|||
|
||||
block["signature"] = signature;
|
||||
|
||||
final map = await postBlock(server: server, block: block);
|
||||
final map = await postBlock(
|
||||
server: server,
|
||||
block: block,
|
||||
headers: headers,
|
||||
);
|
||||
|
||||
if (map is Map && map["error"] != null) {
|
||||
throw Exception(map["error"].toString());
|
||||
|
@ -111,14 +116,13 @@ class NanoAPI {
|
|||
static Future<dynamic> postBlock({
|
||||
required Uri server,
|
||||
required Map<String, dynamic> block,
|
||||
required Map<String, String> headers,
|
||||
}) async {
|
||||
final HTTP client = HTTP();
|
||||
|
||||
final response = await client.post(
|
||||
url: server,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
headers: headers,
|
||||
body: jsonEncode({
|
||||
"action": "process",
|
||||
"json_block": "true",
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:nanodart/nanodart.dart';
|
||||
|
||||
import '../../../models/isar/models/blockchain_data/address.dart';
|
||||
import '../../../models/node_model.dart';
|
||||
import '../../../utilities/default_nodes.dart';
|
||||
|
@ -66,7 +67,8 @@ class Banano extends NanoCurrency {
|
|||
switch (network) {
|
||||
case CryptoCurrencyNetwork.main:
|
||||
return NodeModel(
|
||||
host: "https://kaliumapi.appditto.com/api",
|
||||
// host: "https://kaliumapi.appditto.com/api",
|
||||
host: "https://nodes.nanswap.com/BAN",
|
||||
port: 443,
|
||||
name: DefaultNodes.defaultName,
|
||||
id: DefaultNodes.buildId(this),
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:nanodart/nanodart.dart';
|
||||
|
||||
import '../../../models/isar/models/isar_models.dart';
|
||||
import '../../../models/node_model.dart';
|
||||
import '../../../utilities/default_nodes.dart';
|
||||
|
@ -66,7 +67,8 @@ class Nano extends NanoCurrency {
|
|||
switch (network) {
|
||||
case CryptoCurrencyNetwork.main:
|
||||
return NodeModel(
|
||||
host: "https://rainstorm.city/api",
|
||||
// host: "https://rainstorm.city/api",
|
||||
host: "https://nodes.nanswap.com/XNO",
|
||||
port: 443,
|
||||
name: DefaultNodes.defaultName,
|
||||
id: DefaultNodes.buildId(this),
|
||||
|
|
|
@ -25,6 +25,17 @@ import '../intermediate/bip39_wallet.dart';
|
|||
// const _kWorkServer = "https://rpc.nano.to";
|
||||
const _kWorkServer = "https://nodes.nanswap.com/XNO";
|
||||
|
||||
Map<String, String> _buildHeaders(String url) {
|
||||
final result = {
|
||||
'Content-type': 'application/json',
|
||||
};
|
||||
if (url
|
||||
case "https://nodes.nanswap.com/XNO" || "https://nodes.nanswap.com/BAN") {
|
||||
result["nodes-api-key"] = kNanoSwapRpcApiKey;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
|
||||
// since nano based coins only have a single address/account we can cache
|
||||
// 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> {
|
|||
return _httpClient
|
||||
.post(
|
||||
url: Uri.parse(_kWorkServer), // this should be a
|
||||
headers: {
|
||||
'Content-type': 'application/json',
|
||||
"nodes-api-key": kNanoSwapRpcApiKey,
|
||||
},
|
||||
headers: _buildHeaders(_kWorkServer),
|
||||
body: json.encode(
|
||||
{
|
||||
"action": "work_generate",
|
||||
|
@ -99,10 +107,6 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
|
|||
// TODO: the opening block of an account is a special case
|
||||
bool openBlock = false;
|
||||
|
||||
final headers = {
|
||||
"Content-Type": "application/json",
|
||||
};
|
||||
|
||||
// first check if the account is open:
|
||||
// get the account info (we need the frontier and representative):
|
||||
final infoBody = jsonEncode({
|
||||
|
@ -110,9 +114,10 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
|
|||
"representative": "true",
|
||||
"account": publicAddress,
|
||||
});
|
||||
final node = getCurrentNode();
|
||||
final infoResponse = await _httpClient.post(
|
||||
url: Uri.parse(getCurrentNode().host),
|
||||
headers: headers,
|
||||
url: Uri.parse(node.host),
|
||||
headers: _buildHeaders(node.host),
|
||||
body: infoBody,
|
||||
proxyInfo: prefs.useTor ? TorService.sharedInstance.getProxyInfo() : null,
|
||||
);
|
||||
|
@ -130,8 +135,8 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
|
|||
});
|
||||
|
||||
final balanceResponse = await _httpClient.post(
|
||||
url: Uri.parse(getCurrentNode().host),
|
||||
headers: headers,
|
||||
url: Uri.parse(node.host),
|
||||
headers: _buildHeaders(node.host),
|
||||
body: balanceBody,
|
||||
proxyInfo: prefs.useTor ? TorService.sharedInstance.getProxyInfo() : null,
|
||||
);
|
||||
|
@ -204,8 +209,8 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
|
|||
"block": receiveBlock,
|
||||
});
|
||||
final processResponse = await _httpClient.post(
|
||||
url: Uri.parse(getCurrentNode().host),
|
||||
headers: headers,
|
||||
url: Uri.parse(node.host),
|
||||
headers: _buildHeaders(node.host),
|
||||
body: processBody,
|
||||
proxyInfo: prefs.useTor ? TorService.sharedInstance.getProxyInfo() : null,
|
||||
);
|
||||
|
@ -218,14 +223,14 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
|
|||
}
|
||||
|
||||
Future<void> _confirmAllReceivable(String accountAddress) async {
|
||||
final node = getCurrentNode();
|
||||
final receivableResponse = await _httpClient.post(
|
||||
url: Uri.parse(getCurrentNode().host),
|
||||
headers: {"Content-Type": "application/json"},
|
||||
url: Uri.parse(node.host),
|
||||
headers: _buildHeaders(node.host),
|
||||
body: jsonEncode({
|
||||
"action": "receivable",
|
||||
"source": "true",
|
||||
"account": accountAddress,
|
||||
"count": "-1",
|
||||
}),
|
||||
proxyInfo: prefs.useTor ? TorService.sharedInstance.getProxyInfo() : null,
|
||||
);
|
||||
|
@ -253,10 +258,12 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
|
|||
final address =
|
||||
(_cachedAddress ?? await getCurrentReceivingAddress())!.value;
|
||||
|
||||
final node = getCurrentNode();
|
||||
final response = await NanoAPI.getAccountInfo(
|
||||
server: serverURI,
|
||||
representative: true,
|
||||
account: address,
|
||||
headers: _buildHeaders(node.host),
|
||||
);
|
||||
|
||||
return response.accountInfo?.representative ??
|
||||
|
@ -265,7 +272,8 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
|
|||
|
||||
Future<bool> changeRepresentative(String newRepresentative) async {
|
||||
try {
|
||||
final serverURI = Uri.parse(getCurrentNode().host);
|
||||
final node = getCurrentNode();
|
||||
final serverURI = Uri.parse(node.host);
|
||||
await updateBalance();
|
||||
final balance = info.cachedBalance.spendable.raw.toString();
|
||||
final String privateKey = await _getPrivateKeyFromMnemonic();
|
||||
|
@ -276,6 +284,7 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
|
|||
server: serverURI,
|
||||
representative: true,
|
||||
account: address,
|
||||
headers: _buildHeaders(node.host),
|
||||
);
|
||||
|
||||
if (response.accountInfo == null) {
|
||||
|
@ -293,6 +302,7 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
|
|||
balance: balance,
|
||||
privateKey: privateKey,
|
||||
work: work!,
|
||||
headers: _buildHeaders(node.host),
|
||||
);
|
||||
} catch (_) {
|
||||
rethrow;
|
||||
|
@ -337,11 +347,11 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
|
|||
|
||||
@override
|
||||
Future<bool> pingCheck() async {
|
||||
final uri = Uri.parse(getCurrentNode().host);
|
||||
|
||||
final node = getCurrentNode();
|
||||
final uri = Uri.parse(node.host);
|
||||
final response = await _httpClient.post(
|
||||
url: uri,
|
||||
headers: {"Content-Type": "application/json"},
|
||||
headers: _buildHeaders(node.host),
|
||||
body: jsonEncode(
|
||||
{
|
||||
"action": "version",
|
||||
|
@ -390,13 +400,10 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
|
|||
"account": publicAddress,
|
||||
});
|
||||
|
||||
final headers = {
|
||||
"Content-Type": "application/json",
|
||||
};
|
||||
|
||||
final node = getCurrentNode();
|
||||
final infoResponse = await _httpClient.post(
|
||||
url: Uri.parse(getCurrentNode().host),
|
||||
headers: headers,
|
||||
url: Uri.parse(node.host),
|
||||
headers: _buildHeaders(node.host),
|
||||
body: infoBody,
|
||||
proxyInfo:
|
||||
prefs.useTor ? TorService.sharedInstance.getProxyInfo() : null,
|
||||
|
@ -449,8 +456,8 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
|
|||
"block": sendBlock,
|
||||
});
|
||||
final processResponse = await _httpClient.post(
|
||||
url: Uri.parse(getCurrentNode().host),
|
||||
headers: headers,
|
||||
url: Uri.parse(node.host),
|
||||
headers: _buildHeaders(node.host),
|
||||
body: processBody,
|
||||
proxyInfo:
|
||||
prefs.useTor ? TorService.sharedInstance.getProxyInfo() : null,
|
||||
|
@ -491,6 +498,49 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
|
|||
}
|
||||
}
|
||||
|
||||
// recurse over api calls if required
|
||||
// (if more than 200 history items)
|
||||
Future<Map<String, dynamic>> _fetchAll(
|
||||
String publicAddress,
|
||||
String? previous,
|
||||
Map<String, dynamic>? data,
|
||||
) async {
|
||||
final node = getCurrentNode();
|
||||
final body = {
|
||||
"action": "account_history",
|
||||
"account": publicAddress,
|
||||
"count": "200",
|
||||
};
|
||||
|
||||
if (previous is String) {
|
||||
body["head"] = previous;
|
||||
}
|
||||
|
||||
final response = await _httpClient.post(
|
||||
url: Uri.parse(node.host),
|
||||
headers: _buildHeaders(node.host),
|
||||
body: jsonEncode(body),
|
||||
proxyInfo: prefs.useTor ? TorService.sharedInstance.getProxyInfo() : null,
|
||||
);
|
||||
|
||||
// this should really have proper type checking and error propagation but I'm out of time
|
||||
final newData =
|
||||
Map<String, dynamic>.from((await jsonDecode(response.body)) as Map);
|
||||
|
||||
if (newData["previous"] is String) {
|
||||
if (data?["history"] is List) {
|
||||
(newData["history"] as List).addAll(data!["history"] as List);
|
||||
}
|
||||
return await _fetchAll(
|
||||
publicAddress,
|
||||
newData["previous"] as String,
|
||||
newData,
|
||||
);
|
||||
}
|
||||
|
||||
return newData;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> updateTransactions() async {
|
||||
await updateChainHeight();
|
||||
|
@ -498,17 +548,9 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
|
|||
(_cachedAddress ?? await getCurrentReceivingAddress())!;
|
||||
final String publicAddress = receivingAddress.value;
|
||||
await _confirmAllReceivable(publicAddress);
|
||||
final response = await _httpClient.post(
|
||||
url: Uri.parse(getCurrentNode().host),
|
||||
headers: {"Content-Type": "application/json"},
|
||||
body: jsonEncode({
|
||||
"action": "account_history",
|
||||
"account": publicAddress,
|
||||
"count": "-1",
|
||||
}),
|
||||
proxyInfo: prefs.useTor ? TorService.sharedInstance.getProxyInfo() : null,
|
||||
);
|
||||
final data = await jsonDecode(response.body);
|
||||
|
||||
final data = await _fetchAll(publicAddress, null, null);
|
||||
|
||||
final transactions = data["history"] is List
|
||||
? data["history"] as List<dynamic>
|
||||
: <dynamic>[];
|
||||
|
@ -577,13 +619,11 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
|
|||
"action": "account_balance",
|
||||
"account": addressString,
|
||||
});
|
||||
final headers = {
|
||||
"Content-Type": "application/json",
|
||||
};
|
||||
|
||||
final node = getCurrentNode();
|
||||
final response = await _httpClient.post(
|
||||
url: Uri.parse(getCurrentNode().host),
|
||||
headers: headers,
|
||||
url: Uri.parse(node.host),
|
||||
headers: _buildHeaders(node.host),
|
||||
body: body,
|
||||
proxyInfo:
|
||||
prefs.useTor ? TorService.sharedInstance.getProxyInfo() : null,
|
||||
|
@ -628,12 +668,11 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
|
|||
"action": "account_info",
|
||||
"account": publicAddress,
|
||||
});
|
||||
final headers = {
|
||||
"Content-Type": "application/json",
|
||||
};
|
||||
|
||||
final node = getCurrentNode();
|
||||
final infoResponse = await _httpClient.post(
|
||||
url: Uri.parse(getCurrentNode().host),
|
||||
headers: headers,
|
||||
url: Uri.parse(node.host),
|
||||
headers: _buildHeaders(node.host),
|
||||
body: infoBody,
|
||||
proxyInfo:
|
||||
prefs.useTor ? TorService.sharedInstance.getProxyInfo() : null,
|
||||
|
|
Loading…
Reference in a new issue