mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-11-17 01:37:54 +00:00
merge clean up and use out own http wrapper class
This commit is contained in:
parent
88a98953e5
commit
c9f5473493
4 changed files with 147 additions and 113 deletions
|
@ -1,34 +1,45 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:http/http.dart';
|
||||
import 'package:stackwallet/networking/http.dart';
|
||||
import 'package:stackwallet/services/coins/tezos/api/tezos_transaction.dart';
|
||||
import 'package:stackwallet/utilities/logger.dart';
|
||||
import 'package:stackwallet/services/tor_service.dart';
|
||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||
import 'package:stackwallet/utilities/logger.dart';
|
||||
import 'package:stackwallet/utilities/prefs.dart';
|
||||
|
||||
class TezosAPI {
|
||||
abstract final class TezosAPI {
|
||||
static final HTTP _client = HTTP();
|
||||
static const String _baseURL = 'https://api.tzstats.com';
|
||||
|
||||
Future<List<TezosOperation>?> getTransactions(String address) async {
|
||||
static Future<List<TezosTransaction>?> getTransactions(String address) async {
|
||||
try {
|
||||
String transactionsCall =
|
||||
"$_baseURL/explorer/account/$address/operations";
|
||||
var response = jsonDecode(
|
||||
await get(Uri.parse(transactionsCall)).then((value) => value.body));
|
||||
List<TezosOperation> txs = [];
|
||||
for (var tx in response as List) {
|
||||
final transactionsCall = "$_baseURL/explorer/account/$address/operations";
|
||||
|
||||
final response = await _client.get(
|
||||
url: Uri.parse(transactionsCall),
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
proxyInfo: Prefs.instance.useTor
|
||||
? TorService.sharedInstance.getProxyInfo()
|
||||
: null,
|
||||
);
|
||||
|
||||
final result = jsonDecode(response.body) as List;
|
||||
|
||||
List<TezosTransaction> txs = [];
|
||||
for (var tx in result) {
|
||||
if (tx["type"] == "transaction") {
|
||||
int? burnedAmountInMicroTez;
|
||||
int? storage_limit;
|
||||
int? storageLimit;
|
||||
if (tx["burned"] != null) {
|
||||
burnedAmountInMicroTez = double.parse(
|
||||
(tx["burned"] * pow(10, Coin.tezos.decimals)).toString())
|
||||
.toInt();
|
||||
}
|
||||
if (tx["storage_limit"] != null) {
|
||||
storage_limit = tx["storage_limit"] as int;
|
||||
storageLimit = tx["storage_limit"] as int;
|
||||
}
|
||||
final theTx = TezosOperation(
|
||||
final theTx = TezosTransaction(
|
||||
id: tx["id"] as int,
|
||||
hash: tx["hash"] as String,
|
||||
type: tx["type"] as String,
|
||||
|
@ -39,13 +50,13 @@ class TezosAPI {
|
|||
1000,
|
||||
cycle: tx["cycle"] as int,
|
||||
counter: tx["counter"] as int,
|
||||
op_n: tx["op_n"] as int,
|
||||
op_p: tx["op_p"] as int,
|
||||
opN: tx["op_n"] as int,
|
||||
opP: tx["op_p"] as int,
|
||||
status: tx["status"] as String,
|
||||
is_success: tx["is_success"] as bool,
|
||||
gas_limit: tx["gas_limit"] as int,
|
||||
gas_used: tx["gas_used"] as int,
|
||||
storage_limit: storage_limit,
|
||||
isSuccess: tx["is_success"] as bool,
|
||||
gasLimit: tx["gas_limit"] as int,
|
||||
gasUsed: tx["gas_used"] as int,
|
||||
storageLimit: storageLimit,
|
||||
amountInMicroTez: double.parse(
|
||||
(tx["volume"] * pow(10, Coin.tezos.decimals)).toString())
|
||||
.toInt(),
|
||||
|
@ -63,23 +74,35 @@ class TezosAPI {
|
|||
return txs;
|
||||
} catch (e) {
|
||||
Logging.instance.log(
|
||||
"Error occured in tezos_api.dart while getting transactions for $address: $e",
|
||||
level: LogLevel.Error);
|
||||
"Error occurred in tezos_api.dart while getting transactions for $address: $e",
|
||||
level: LogLevel.Error,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<int?> getFeeEstimationFromLastDays(int days) async {
|
||||
static Future<int?> getFeeEstimationFromLastDays(int days) async {
|
||||
try {
|
||||
var api = "$_baseURL/series/op?start_date=today&collapse=$days";
|
||||
var response = jsonDecode((await get(Uri.parse(api))).body);
|
||||
double totalFees = response[0][4] as double;
|
||||
int totalTxs = response[0][8] as int;
|
||||
|
||||
final response = await _client.get(
|
||||
url: Uri.parse(api),
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
proxyInfo: Prefs.instance.useTor
|
||||
? TorService.sharedInstance.getProxyInfo()
|
||||
: null,
|
||||
);
|
||||
|
||||
final result = jsonDecode(response.body);
|
||||
|
||||
double totalFees = result[0][4] as double;
|
||||
int totalTxs = result[0][8] as int;
|
||||
return ((totalFees / totalTxs * Coin.tezos.decimals).floor());
|
||||
} catch (e) {
|
||||
Logging.instance.log(
|
||||
"Error occured in tezos_api.dart while getting fee estimation for tezos: $e",
|
||||
level: LogLevel.Error);
|
||||
"Error occurred in tezos_api.dart while getting fee estimation for tezos: $e",
|
||||
level: LogLevel.Error,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -1,52 +1,71 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:http/http.dart';
|
||||
|
||||
import 'package:stackwallet/networking/http.dart';
|
||||
import 'package:stackwallet/services/tor_service.dart';
|
||||
import 'package:stackwallet/utilities/logger.dart';
|
||||
import 'package:stackwallet/utilities/prefs.dart';
|
||||
|
||||
class TezosRpcAPI {
|
||||
Future<BigInt?> getBalance(
|
||||
{required ({String host, int port}) nodeInfo,
|
||||
required String address}) async {
|
||||
abstract final class TezosRpcAPI {
|
||||
static final HTTP _client = HTTP();
|
||||
|
||||
static Future<BigInt?> getBalance({
|
||||
required ({String host, int port}) nodeInfo,
|
||||
required String address,
|
||||
}) async {
|
||||
try {
|
||||
String balanceCall =
|
||||
"${nodeInfo.host}:${nodeInfo.port}/chains/main/blocks/head/context/contracts/$address/balance";
|
||||
var response =
|
||||
await get(Uri.parse(balanceCall)).then((value) => value.body);
|
||||
var balance = BigInt.parse(response.substring(1, response.length - 2));
|
||||
|
||||
final response = await _client.get(
|
||||
url: Uri.parse(balanceCall),
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
proxyInfo: Prefs.instance.useTor
|
||||
? TorService.sharedInstance.getProxyInfo()
|
||||
: null,
|
||||
);
|
||||
|
||||
final balance =
|
||||
BigInt.parse(response.body.substring(1, response.body.length - 2));
|
||||
return balance;
|
||||
} catch (e) {
|
||||
Logging.instance.log(
|
||||
"Error occured in tezos_rpc_api.dart while getting balance for $address: $e",
|
||||
level: LogLevel.Error);
|
||||
"Error occurred in tezos_rpc_api.dart while getting balance for $address: $e",
|
||||
level: LogLevel.Error,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<int?> getChainHeight(
|
||||
{required ({String host, int port}) nodeInfo}) async {
|
||||
static Future<int?> getChainHeight({
|
||||
required ({String host, int port}) nodeInfo,
|
||||
}) async {
|
||||
try {
|
||||
var api =
|
||||
final api =
|
||||
"${nodeInfo.host}:${nodeInfo.port}/chains/main/blocks/head/header/shell";
|
||||
var jsonParsedResponse =
|
||||
jsonDecode(await get(Uri.parse(api)).then((value) => value.body));
|
||||
|
||||
final response = await _client.get(
|
||||
url: Uri.parse(api),
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
proxyInfo: Prefs.instance.useTor
|
||||
? TorService.sharedInstance.getProxyInfo()
|
||||
: null,
|
||||
);
|
||||
|
||||
final jsonParsedResponse = jsonDecode(response.body);
|
||||
return int.parse(jsonParsedResponse["level"].toString());
|
||||
} catch (e) {
|
||||
Logging.instance.log(
|
||||
"Error occured in tezos_rpc_api.dart while getting chain height for tezos: $e",
|
||||
level: LogLevel.Error);
|
||||
"Error occurred in tezos_rpc_api.dart while getting chain height for tezos: $e",
|
||||
level: LogLevel.Error,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<bool> testNetworkConnection(
|
||||
{required ({String host, int port}) nodeInfo}) async {
|
||||
try {
|
||||
await get(Uri.parse(
|
||||
"${nodeInfo.host}:${nodeInfo.port}/chains/main/blocks/head/header/shell"));
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
static Future<bool> testNetworkConnection({
|
||||
required ({String host, int port}) nodeInfo,
|
||||
}) async {
|
||||
final result = await getChainHeight(nodeInfo: nodeInfo);
|
||||
return result != null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,44 +1,45 @@
|
|||
class TezosOperation {
|
||||
int? id;
|
||||
String hash;
|
||||
String? type;
|
||||
int height;
|
||||
int timestamp;
|
||||
int? cycle;
|
||||
int? counter;
|
||||
int? op_n;
|
||||
int? op_p;
|
||||
String? status;
|
||||
bool? is_success;
|
||||
int? gas_limit;
|
||||
int? gas_used;
|
||||
int? storage_limit;
|
||||
int amountInMicroTez;
|
||||
int feeInMicroTez;
|
||||
int? burnedAmountInMicroTez;
|
||||
String senderAddress;
|
||||
String receiverAddress;
|
||||
int? confirmations;
|
||||
class TezosTransaction {
|
||||
final int? id;
|
||||
final String hash;
|
||||
final String? type;
|
||||
final int height;
|
||||
final int timestamp;
|
||||
final int? cycle;
|
||||
final int? counter;
|
||||
final int? opN;
|
||||
final int? opP;
|
||||
final String? status;
|
||||
final bool? isSuccess;
|
||||
final int? gasLimit;
|
||||
final int? gasUsed;
|
||||
final int? storageLimit;
|
||||
final int amountInMicroTez;
|
||||
final int feeInMicroTez;
|
||||
final int? burnedAmountInMicroTez;
|
||||
final String senderAddress;
|
||||
final String receiverAddress;
|
||||
final int? confirmations;
|
||||
|
||||
TezosOperation(
|
||||
{this.id,
|
||||
required this.hash,
|
||||
this.type,
|
||||
required this.height,
|
||||
required this.timestamp,
|
||||
this.cycle,
|
||||
this.counter,
|
||||
this.op_n,
|
||||
this.op_p,
|
||||
this.status,
|
||||
this.is_success,
|
||||
this.gas_limit,
|
||||
this.gas_used,
|
||||
this.storage_limit,
|
||||
required this.amountInMicroTez,
|
||||
required this.feeInMicroTez,
|
||||
this.burnedAmountInMicroTez,
|
||||
required this.senderAddress,
|
||||
required this.receiverAddress,
|
||||
this.confirmations});
|
||||
TezosTransaction({
|
||||
this.id,
|
||||
required this.hash,
|
||||
this.type,
|
||||
required this.height,
|
||||
required this.timestamp,
|
||||
this.cycle,
|
||||
this.counter,
|
||||
this.opN,
|
||||
this.opP,
|
||||
this.status,
|
||||
this.isSuccess,
|
||||
this.gasLimit,
|
||||
this.gasUsed,
|
||||
this.storageLimit,
|
||||
required this.amountInMicroTez,
|
||||
required this.feeInMicroTez,
|
||||
this.burnedAmountInMicroTez,
|
||||
required this.senderAddress,
|
||||
required this.receiverAddress,
|
||||
this.confirmations,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:decimal/decimal.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
|
@ -10,9 +9,9 @@ import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart'
|
|||
import 'package:stackwallet/models/isar/models/blockchain_data/utxo.dart';
|
||||
import 'package:stackwallet/models/node_model.dart';
|
||||
import 'package:stackwallet/models/paymint/fee_object_model.dart';
|
||||
import 'package:stackwallet/networking/http.dart';
|
||||
import 'package:stackwallet/services/coins/coin_service.dart';
|
||||
import 'package:stackwallet/services/coins/tezos/api/tezos_api.dart';
|
||||
import 'package:stackwallet/services/coins/tezos/api/tezos_rpc_api.dart';
|
||||
import 'package:stackwallet/services/coins/tezos/api/tezos_transaction.dart';
|
||||
import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart';
|
||||
import 'package:stackwallet/services/event_bus/events/global/updated_in_background_event.dart';
|
||||
|
@ -21,7 +20,6 @@ import 'package:stackwallet/services/event_bus/global_event_bus.dart';
|
|||
import 'package:stackwallet/services/mixins/wallet_cache.dart';
|
||||
import 'package:stackwallet/services/mixins/wallet_db.dart';
|
||||
import 'package:stackwallet/services/node_service.dart';
|
||||
import 'package:stackwallet/services/tor_service.dart';
|
||||
import 'package:stackwallet/services/transaction_notification_tracker.dart';
|
||||
import 'package:stackwallet/utilities/amount/amount.dart';
|
||||
import 'package:stackwallet/utilities/constants.dart';
|
||||
|
@ -34,8 +32,6 @@ import 'package:stackwallet/utilities/prefs.dart';
|
|||
import 'package:tezart/tezart.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
|
||||
import 'api/tezos_rpc_api.dart';
|
||||
|
||||
const int MINIMUM_CONFIRMATIONS = 1;
|
||||
const int _gasLimit = 10200;
|
||||
|
||||
|
@ -59,9 +55,6 @@ class TezosWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
|||
|
||||
NodeModel? _xtzNode;
|
||||
|
||||
TezosAPI tezosAPI = TezosAPI();
|
||||
TezosRpcAPI tezosRpcAPI = TezosRpcAPI();
|
||||
|
||||
NodeModel getCurrentNode() {
|
||||
return _xtzNode ??
|
||||
NodeService(secureStorageInterface: _secureStore)
|
||||
|
@ -109,8 +102,6 @@ class TezosWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
|||
@override
|
||||
bool get shouldAutoSync => _shouldAutoSync;
|
||||
|
||||
HTTP client = HTTP();
|
||||
|
||||
@override
|
||||
set shouldAutoSync(bool shouldAutoSync) {
|
||||
if (_shouldAutoSync != shouldAutoSync) {
|
||||
|
@ -248,7 +239,7 @@ class TezosWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
|||
|
||||
@override
|
||||
Future<Amount> estimateFeeFor(Amount amount, int feeRate) async {
|
||||
int? feePerTx = await tezosAPI.getFeeEstimationFromLastDays(1);
|
||||
int? feePerTx = await TezosAPI.getFeeEstimationFromLastDays(1);
|
||||
feePerTx ??= 0;
|
||||
return Amount(
|
||||
rawValue: BigInt.from(feePerTx),
|
||||
|
@ -264,7 +255,7 @@ class TezosWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
|||
|
||||
@override
|
||||
Future<FeeObject> get fees async {
|
||||
int? feePerTx = await tezosAPI.getFeeEstimationFromLastDays(1);
|
||||
int? feePerTx = await TezosAPI.getFeeEstimationFromLastDays(1);
|
||||
feePerTx ??= 0;
|
||||
Logging.instance.log("feePerTx:$feePerTx", level: LogLevel.Info);
|
||||
return FeeObject(
|
||||
|
@ -494,7 +485,7 @@ class TezosWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
|||
Future<void> updateBalance() async {
|
||||
try {
|
||||
NodeModel currentNode = getCurrentNode();
|
||||
BigInt? balance = await tezosRpcAPI.getBalance(
|
||||
BigInt? balance = await TezosRpcAPI.getBalance(
|
||||
nodeInfo: (host: currentNode.host, port: currentNode.port),
|
||||
address: await currentReceivingAddress);
|
||||
if (balance == null) {
|
||||
|
@ -522,8 +513,8 @@ class TezosWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
|||
}
|
||||
|
||||
Future<void> updateTransactions() async {
|
||||
List<TezosOperation>? txs =
|
||||
await tezosAPI.getTransactions(await currentReceivingAddress);
|
||||
List<TezosTransaction>? txs =
|
||||
await TezosAPI.getTransactions(await currentReceivingAddress);
|
||||
Logging.instance.log("Transactions: $txs", level: LogLevel.Info);
|
||||
if (txs == null) {
|
||||
return;
|
||||
|
@ -592,7 +583,7 @@ class TezosWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
|||
Future<void> updateChainHeight() async {
|
||||
try {
|
||||
NodeModel currentNode = getCurrentNode();
|
||||
int? intHeight = await tezosRpcAPI.getChainHeight(
|
||||
int? intHeight = await TezosRpcAPI.getChainHeight(
|
||||
nodeInfo: (host: currentNode.host, port: currentNode.port));
|
||||
if (intHeight == null) {
|
||||
return;
|
||||
|
@ -677,7 +668,7 @@ class TezosWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
|||
@override
|
||||
Future<bool> testNetworkConnection() async {
|
||||
NodeModel currentNode = getCurrentNode();
|
||||
return await tezosRpcAPI.testNetworkConnection(
|
||||
return await TezosRpcAPI.testNetworkConnection(
|
||||
nodeInfo: (host: currentNode.host, port: currentNode.port));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue