mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-12-23 20:09:23 +00:00
get token transactions refactor
This commit is contained in:
parent
58280010f8
commit
057066950e
1 changed files with 130 additions and 43 deletions
|
@ -1,16 +1,14 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:ethereum_addresses/ethereum_addresses.dart';
|
|
||||||
import 'package:http/http.dart';
|
import 'package:http/http.dart';
|
||||||
|
import 'package:stackwallet/models/ethereum/erc20_token.dart';
|
||||||
import 'package:stackwallet/models/ethereum/erc721_token.dart';
|
import 'package:stackwallet/models/ethereum/erc721_token.dart';
|
||||||
|
import 'package:stackwallet/models/ethereum/eth_token.dart';
|
||||||
import 'package:stackwallet/models/paymint/fee_object_model.dart';
|
import 'package:stackwallet/models/paymint/fee_object_model.dart';
|
||||||
import 'package:stackwallet/utilities/eth_commons.dart';
|
import 'package:stackwallet/utilities/eth_commons.dart';
|
||||||
import 'package:stackwallet/utilities/logger.dart';
|
import 'package:stackwallet/utilities/logger.dart';
|
||||||
|
|
||||||
import '../../models/ethereum/erc20_token.dart';
|
|
||||||
import '../../models/ethereum/eth_token.dart';
|
|
||||||
|
|
||||||
class AbiRequestResponse {
|
class AbiRequestResponse {
|
||||||
final String message;
|
final String message;
|
||||||
final String result;
|
final String result;
|
||||||
|
@ -31,6 +29,87 @@ class AbiRequestResponse {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class EthTokenTx {
|
||||||
|
final String blockHash;
|
||||||
|
final int blockNumber;
|
||||||
|
final int confirmations;
|
||||||
|
final String contractAddress;
|
||||||
|
final int cumulativeGasUsed;
|
||||||
|
final String from;
|
||||||
|
final int gas;
|
||||||
|
final BigInt gasPrice;
|
||||||
|
final int gasUsed;
|
||||||
|
final String hash;
|
||||||
|
final String input;
|
||||||
|
final int logIndex;
|
||||||
|
final int nonce;
|
||||||
|
final int timeStamp;
|
||||||
|
final String to;
|
||||||
|
final int tokenDecimal;
|
||||||
|
final String tokenName;
|
||||||
|
final String tokenSymbol;
|
||||||
|
final int transactionIndex;
|
||||||
|
final BigInt value;
|
||||||
|
|
||||||
|
EthTokenTx({
|
||||||
|
required this.blockHash,
|
||||||
|
required this.blockNumber,
|
||||||
|
required this.confirmations,
|
||||||
|
required this.contractAddress,
|
||||||
|
required this.cumulativeGasUsed,
|
||||||
|
required this.from,
|
||||||
|
required this.gas,
|
||||||
|
required this.gasPrice,
|
||||||
|
required this.gasUsed,
|
||||||
|
required this.hash,
|
||||||
|
required this.input,
|
||||||
|
required this.logIndex,
|
||||||
|
required this.nonce,
|
||||||
|
required this.timeStamp,
|
||||||
|
required this.to,
|
||||||
|
required this.tokenDecimal,
|
||||||
|
required this.tokenName,
|
||||||
|
required this.tokenSymbol,
|
||||||
|
required this.transactionIndex,
|
||||||
|
required this.value,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory EthTokenTx.fromMap({
|
||||||
|
required Map<String, dynamic> map,
|
||||||
|
}) {
|
||||||
|
try {
|
||||||
|
return EthTokenTx(
|
||||||
|
blockHash: map["blockHash"] as String,
|
||||||
|
blockNumber: int.parse(map["blockNumber"] as String),
|
||||||
|
confirmations: int.parse(map["confirmations"] as String),
|
||||||
|
contractAddress: map["contractAddress"] as String,
|
||||||
|
cumulativeGasUsed: int.parse(map["cumulativeGasUsed"] as String),
|
||||||
|
from: map["from"] as String,
|
||||||
|
gas: int.parse(map["gas"] as String),
|
||||||
|
gasPrice: BigInt.parse(map["gasPrice"] as String),
|
||||||
|
gasUsed: int.parse(map["gasUsed"] as String),
|
||||||
|
hash: map["hash"] as String,
|
||||||
|
input: map["input"] as String,
|
||||||
|
logIndex: int.parse(map["logIndex"] as String),
|
||||||
|
nonce: int.parse(map["nonce"] as String),
|
||||||
|
timeStamp: int.parse(map["timeStamp"] as String),
|
||||||
|
to: map["to"] as String,
|
||||||
|
tokenDecimal: int.parse(map["tokenDecimal"] as String),
|
||||||
|
tokenName: map["tokenName"] as String,
|
||||||
|
tokenSymbol: map["tokenSymbol"] as String,
|
||||||
|
transactionIndex: int.parse(map["transactionIndex"] as String),
|
||||||
|
value: BigInt.parse(map["value"] as String),
|
||||||
|
);
|
||||||
|
} catch (e, s) {
|
||||||
|
Logging.instance.log(
|
||||||
|
"EthTokenTx.fromMap() failed: $e\n$s",
|
||||||
|
level: LogLevel.Fatal,
|
||||||
|
);
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class EthereumResponse<T> {
|
class EthereumResponse<T> {
|
||||||
final T? value;
|
final T? value;
|
||||||
final Exception? exception;
|
final Exception? exception;
|
||||||
|
@ -63,6 +142,53 @@ abstract class EthereumAPI {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Future<EthereumResponse<List<EthTokenTx>>> getTokenTransactions({
|
||||||
|
required String address,
|
||||||
|
int? startBlock,
|
||||||
|
int? endBlock,
|
||||||
|
// todo add more params?
|
||||||
|
}) async {
|
||||||
|
try {
|
||||||
|
final uri = Uri.parse(
|
||||||
|
"$blockExplorer?module=account&action=tokentx&address=$address",
|
||||||
|
);
|
||||||
|
final response = await get(uri);
|
||||||
|
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
final json = jsonDecode(response.body);
|
||||||
|
if (json["message"] == "OK") {
|
||||||
|
final result =
|
||||||
|
List<Map<String, dynamic>>.from(json["result"] as List);
|
||||||
|
final List<EthTokenTx> tokenTxns = [];
|
||||||
|
for (final map in result) {
|
||||||
|
tokenTxns.add(EthTokenTx.fromMap(map: map));
|
||||||
|
}
|
||||||
|
|
||||||
|
return EthereumResponse(
|
||||||
|
tokenTxns,
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
throw Exception(json["message"] as String);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw Exception(
|
||||||
|
"getWalletTokens($address) failed with status code: "
|
||||||
|
"${response.statusCode}",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (e, s) {
|
||||||
|
Logging.instance.log(
|
||||||
|
"getWalletTokens(): $e\n$s",
|
||||||
|
level: LogLevel.Error,
|
||||||
|
);
|
||||||
|
return EthereumResponse(
|
||||||
|
null,
|
||||||
|
Exception(e.toString()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static Future<EthereumResponse<List<EthToken>>> getWalletTokens({
|
static Future<EthereumResponse<List<EthToken>>> getWalletTokens({
|
||||||
required String address,
|
required String address,
|
||||||
}) async {
|
}) async {
|
||||||
|
@ -129,45 +255,6 @@ abstract class EthereumAPI {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<List<dynamic>> getWalletTokenTransactions(
|
|
||||||
String address) async {
|
|
||||||
AddressTransaction tokens =
|
|
||||||
await fetchAddressTransactions(address, "tokentx");
|
|
||||||
List<dynamic> tokensList = [];
|
|
||||||
var tokenMap = {};
|
|
||||||
if (tokens.message == "OK") {
|
|
||||||
final allTxs = tokens.result;
|
|
||||||
allTxs.forEach((element) {
|
|
||||||
print("=========================================================");
|
|
||||||
print("THING: $element");
|
|
||||||
print("=========================================================");
|
|
||||||
|
|
||||||
String key = element["tokenSymbol"] as String;
|
|
||||||
tokenMap[key] = {};
|
|
||||||
tokenMap[key]["balance"] = 0;
|
|
||||||
|
|
||||||
if (tokenMap.containsKey(key)) {
|
|
||||||
tokenMap[key]["contractAddress"] =
|
|
||||||
element["contractAddress"] as String;
|
|
||||||
tokenMap[key]["decimals"] = element["tokenDecimal"];
|
|
||||||
tokenMap[key]["name"] = element["tokenName"];
|
|
||||||
tokenMap[key]["symbol"] = element["tokenSymbol"];
|
|
||||||
if (checksumEthereumAddress(address) == address) {
|
|
||||||
tokenMap[key]["balance"] += int.parse(element["value"] as String);
|
|
||||||
} else {
|
|
||||||
tokenMap[key]["balance"] -= int.parse(element["value"] as String);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
tokenMap.forEach((key, value) {
|
|
||||||
tokensList.add(value as Map<dynamic, dynamic>);
|
|
||||||
});
|
|
||||||
return tokensList;
|
|
||||||
}
|
|
||||||
return <dynamic>[];
|
|
||||||
}
|
|
||||||
|
|
||||||
static Future<GasTracker> getGasOracle() async {
|
static Future<GasTracker> getGasOracle() async {
|
||||||
final response = await get(Uri.parse(gasTrackerUrl));
|
final response = await get(Uri.parse(gasTrackerUrl));
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
|
|
Loading…
Reference in a new issue