ADd address validation and convert receive addresses as checksum addresses

This commit is contained in:
likho 2023-01-05 14:39:21 +02:00
parent a6c2750f20
commit 5d77dcafbe
3 changed files with 181 additions and 127 deletions

View file

@ -3,11 +3,14 @@ import 'dart:convert';
import 'dart:math';
import 'package:bip39/bip39.dart' as bip39;
import 'package:decimal/decimal.dart';
import 'package:devicelocale/devicelocale.dart';
import 'package:ethereum_addresses/ethereum_addresses.dart';
import 'package:flutter/foundation.dart';
import 'package:stackwallet/models/paymint/fee_object_model.dart';
import 'package:stackwallet/models/paymint/transactions_model.dart';
import 'package:stackwallet/models/paymint/utxo_model.dart';
import 'package:stackwallet/services/price.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
import 'package:stackwallet/utilities/format.dart';
@ -16,6 +19,7 @@ import 'package:string_to_hex/string_to_hex.dart';
import 'package:web3dart/web3dart.dart';
import 'package:web3dart/web3dart.dart' as web3;
import 'package:web3dart/web3dart.dart' as Transaction;
import 'package:stackwallet/models/models.dart' as models;
import 'package:http/http.dart';
@ -142,7 +146,9 @@ class EthereumWallet extends CoinServiceAPI {
@override
Future<String> get currentReceivingAddress async {
final _currentReceivingAddress = _credentials.address;
return _currentReceivingAddress.toString();
final checkSumAddress =
checksumEthereumAddress(_currentReceivingAddress.toString());
return checkSumAddress;
}
@override
@ -360,13 +366,13 @@ class EthereumWallet extends CoinServiceAPI {
@override
Future<void> refresh() async {
print("CALLING REFRESH");
// if (refreshMutex) {
// Logging.instance.log("$walletId $walletName refreshMutex denied",
// level: LogLevel.Info);
// return;
// } else {
// refreshMutex = true;
// }
if (refreshMutex) {
Logging.instance.log("$walletId $walletName refreshMutex denied",
level: LogLevel.Info);
return;
} else {
refreshMutex = true;
}
print("SYNC STATUS IS ");
final blockNumber = await _client.getBlockNumber();
@ -468,15 +474,51 @@ class EthereumWallet extends CoinServiceAPI {
}
@override
Future<void> updateSentCachedTxData(Map<String, dynamic> txData) {
// TODO: implement updateSentCachedTxData
throw UnimplementedError();
Future<void> updateSentCachedTxData(Map<String, dynamic> txData) async {
final priceData =
await _priceAPI.getPricesAnd24hChange(baseCurrency: _prefs.currency);
Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero;
final locale = await Devicelocale.currentLocale;
final String worthNow = Format.localizedStringAsFixed(
value:
((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /
Decimal.fromInt(Constants.satsPerCoin(coin)))
.toDecimal(scaleOnInfinitePrecision: 2),
decimalPlaces: 2,
locale: locale!);
final tx = models.Transaction(
txid: txData["txid"] as String,
confirmedStatus: false,
timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000,
txType: "Sent",
amount: txData["recipientAmt"] as int,
worthNow: worthNow,
worthAtBlockTimestamp: worthNow,
fees: txData["fee"] as int,
inputSize: 0,
outputSize: 0,
inputs: [],
outputs: [],
address: txData["address"] as String,
height: -1,
confirmations: 0,
);
if (cachedTxData == null) {
final data = await _fetchTransactionData();
_transactionData = Future(() => data);
} else {
final transactions = cachedTxData!.getAllTransactions();
transactions[tx.txid] = tx;
cachedTxData = models.TransactionData.fromMap(transactions);
_transactionData = Future(() => cachedTxData!);
}
}
@override
bool validateAddress(String address) {
// TODO: implement validateAddress
return true;
return isValidEthereumAddress(address);
}
Future<TransactionData> _fetchTransactionData() async {
@ -491,123 +533,127 @@ class EthereumWallet extends CoinServiceAPI {
print("HEIGHT TO HEX IS $hexHeight");
print('0x$hexHeight');
final cachedTransactions =
DB.instance.get<dynamic>(boxName: walletId, key: 'latest_tx_model')
as TransactionData?;
final priceData =
await _priceAPI.getPricesAnd24hChange(baseCurrency: _prefs.currency);
Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero;
//Initilaize empty transactions array
final List<Map<String, dynamic>> midSortedArray = [];
Map<String, dynamic> midSortedTx = {};
for (int i = currentBlock;
i >= 0 && (n > 0 || balance.toDouble() > 0.0);
--i) {
try {
// print(StringToHex.toHexString(i.toString()))
print(
"BLOCK IS $i AND HEX IS --------->>>>>>> ${StringToHex.toHexString(i.toString())}");
String blockHex = i.toRadixString(16);
var block = await _client.getBlockInformation(
blockNumber: '0x$blockHex', isContainFullObj: true);
if (block != null && block.transactions != null) {
block.transactions.forEach((element) {
// print("TRANSACTION OBJECT IS $element");
final jsonObject = json.encode(element);
final decodedTransaction = jsonDecode(jsonObject);
// print(somethingElse['from']);
// print(jsonObject.containsKey(other));
Logging.instance.log(decodedTransaction,
level: LogLevel.Info, printFullLength: true);
if (thisAddress == decodedTransaction['from']) {
//Ensure this is not a self send
if (decodedTransaction['from'] != decodedTransaction['to']) {
midSortedTx["txType"] = "Sent";
midSortedTx["txid"] = decodedTransaction["hash"];
midSortedTx["height"] = i;
midSortedTx["address"] = decodedTransaction['to'];
int confirmations = 0;
try {
confirmations = currentBlock - i;
} catch (e, s) {
debugPrint("$e $s");
}
midSortedTx["confirmations"] = confirmations;
midSortedTx["inputSize"] = 1;
midSortedTx["outputSize"] = 1;
midSortedTx["aliens"] = <dynamic>[];
midSortedTx["inputs"] = <dynamic>[];
midSortedTx["outputs"] = <dynamic>[];
midSortedArray.add(midSortedTx);
Logging.instance.log(
"TX SENT FROM THIS ACCOUNT ${decodedTransaction['from']} ${decodedTransaction['to']}",
level: LogLevel.Info);
--n;
}
if (thisAddress == decodedTransaction['to']) {
if (decodedTransaction['from'] != decodedTransaction['to']) {
midSortedTx["txType"] = "Received";
midSortedTx["txid"] = decodedTransaction["hash"];
midSortedTx["height"] = i;
midSortedTx["address"] = decodedTransaction['from'];
int confirmations = 0;
try {
confirmations = currentBlock - i;
} catch (e, s) {
debugPrint("$e $s");
}
midSortedTx["confirmations"] = confirmations;
midSortedTx["inputSize"] = 1;
midSortedTx["outputSize"] = 1;
midSortedTx["aliens"] = <dynamic>[];
midSortedTx["inputs"] = <dynamic>[];
midSortedTx["outputs"] = <dynamic>[];
midSortedArray.add(midSortedTx);
}
}
}
});
}
} catch (e, s) {
print("Error getting transactions ${e.toString()} $s");
}
}
midSortedArray
.sort((a, b) => (b["timestamp"] as int) - (a["timestamp"] as int));
final Map<String, dynamic> result = {"dateTimeChunks": <dynamic>[]};
final dateArray = <dynamic>[];
for (int i = 0; i < midSortedArray.length; i++) {
final txObject = midSortedArray[i];
final date = extractDateFromTimestamp(txObject["timestamp"] as int);
final txTimeArray = [txObject["timestamp"], date];
if (dateArray.contains(txTimeArray[1])) {
result["dateTimeChunks"].forEach((dynamic chunk) {
if (extractDateFromTimestamp(chunk["timestamp"] as int) ==
txTimeArray[1]) {
if (chunk["transactions"] == null) {
chunk["transactions"] = <Map<String, dynamic>>[];
}
chunk["transactions"].add(txObject);
}
});
} else {
dateArray.add(txTimeArray[1]);
final chunk = {
"timestamp": txTimeArray[0],
"transactions": [txObject],
};
result["dateTimeChunks"].add(chunk);
}
}
final transactionsMap = cachedTransactions?.getAllTransactions() ?? {};
transactionsMap
.addAll(TransactionData.fromJson(result).getAllTransactions());
// for (int i = currentBlock;
// i >= 0 && (n > 0 || balance.toDouble() > 0.0);
// --i) {
// try {
// // print(StringToHex.toHexString(i.toString()))
// print(
// "BLOCK IS $i AND HEX IS --------->>>>>>> ${StringToHex.toHexString(i.toString())}");
// String blockHex = i.toRadixString(16);
// var block = await _client.getBlockInformation(
// blockNumber: '0x$blockHex', isContainFullObj: true);
//
// if (block != null && block.transactions != null) {
// block.transactions.forEach((element) {
// // print("TRANSACTION OBJECT IS $element");
// final jsonObject = json.encode(element);
// final decodedTransaction = jsonDecode(jsonObject);
// // print(somethingElse['from']);
// // print(jsonObject.containsKey(other));
// Logging.instance.log(decodedTransaction,
// level: LogLevel.Info, printFullLength: true);
//
// if (thisAddress == decodedTransaction['from']) {
// //Ensure this is not a self send
// if (decodedTransaction['from'] != decodedTransaction['to']) {
// midSortedTx["txType"] = "Sent";
// midSortedTx["txid"] = decodedTransaction["hash"];
// midSortedTx["height"] = i;
// midSortedTx["address"] = decodedTransaction['to'];
// int confirmations = 0;
// try {
// confirmations = currentBlock - i;
// } catch (e, s) {
// debugPrint("$e $s");
// }
// midSortedTx["confirmations"] = confirmations;
// midSortedTx["inputSize"] = 1;
// midSortedTx["outputSize"] = 1;
// midSortedTx["aliens"] = <dynamic>[];
// midSortedTx["inputs"] = <dynamic>[];
// midSortedTx["outputs"] = <dynamic>[];
//
// midSortedArray.add(midSortedTx);
// Logging.instance.log(
// "TX SENT FROM THIS ACCOUNT ${decodedTransaction['from']} ${decodedTransaction['to']}",
// level: LogLevel.Info);
// --n;
// }
//
// if (thisAddress == decodedTransaction['to']) {
// if (decodedTransaction['from'] != decodedTransaction['to']) {
// midSortedTx["txType"] = "Received";
// midSortedTx["txid"] = decodedTransaction["hash"];
// midSortedTx["height"] = i;
// midSortedTx["address"] = decodedTransaction['from'];
// int confirmations = 0;
// try {
// confirmations = currentBlock - i;
// } catch (e, s) {
// debugPrint("$e $s");
// }
// midSortedTx["confirmations"] = confirmations;
// midSortedTx["inputSize"] = 1;
// midSortedTx["outputSize"] = 1;
// midSortedTx["aliens"] = <dynamic>[];
// midSortedTx["inputs"] = <dynamic>[];
// midSortedTx["outputs"] = <dynamic>[];
// midSortedArray.add(midSortedTx);
// }
// }
// }
// });
// }
// } catch (e, s) {
// print("Error getting transactions ${e.toString()} $s");
// }
// }
// midSortedArray
// .sort((a, b) => (b["timestamp"] as int) - (a["timestamp"] as int));
// final Map<String, dynamic> result = {"dateTimeChunks": <dynamic>[]};
// final dateArray = <dynamic>[];
//
// for (int i = 0; i < midSortedArray.length; i++) {
// final txObject = midSortedArray[i];
// final date = extractDateFromTimestamp(txObject["timestamp"] as int);
// final txTimeArray = [txObject["timestamp"], date];
//
// if (dateArray.contains(txTimeArray[1])) {
// result["dateTimeChunks"].forEach((dynamic chunk) {
// if (extractDateFromTimestamp(chunk["timestamp"] as int) ==
// txTimeArray[1]) {
// if (chunk["transactions"] == null) {
// chunk["transactions"] = <Map<String, dynamic>>[];
// }
// chunk["transactions"].add(txObject);
// }
// });
// } else {
// dateArray.add(txTimeArray[1]);
// final chunk = {
// "timestamp": txTimeArray[0],
// "transactions": [txObject],
// };
// result["dateTimeChunks"].add(chunk);
// }
// }
//
// final transactionsMap = cachedTransactions?.getAllTransactions() ?? {};
// transactionsMap
// .addAll(TransactionData.fromJson(result).getAllTransactions());
print("THIS CURRECT ADDRESS IS $thisAddress");
print("THIS CURRECT BLOCK IS $currentBlock");

View file

@ -225,7 +225,7 @@ packages:
name: code_builder
url: "https://pub.dartlang.org"
source: hosted
version: "4.3.0"
version: "4.4.0"
collection:
dependency: transitive
description:
@ -429,6 +429,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "5.0.1"
ethereum_addresses:
dependency: "direct main"
description:
name: ethereum_addresses
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
event_bus:
dependency: "direct main"
description:
@ -1284,7 +1291,7 @@ packages:
name: shared_preferences_linux
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
version: "2.1.2"
shared_preferences_macos:
dependency: transitive
description:
@ -1312,7 +1319,7 @@ packages:
name: shared_preferences_windows
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
version: "2.1.2"
shelf:
dependency: transitive
description:
@ -1683,7 +1690,7 @@ packages:
name: win32
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.2"
version: "3.1.3"
window_size:
dependency: "direct main"
description:

View file

@ -91,6 +91,7 @@ dependencies:
# Eth Plugins
web3dart: 2.3.5
string_to_hex: 0.2.2
ethereum_addresses: 1.0.2
# Storage plugins
flutter_secure_storage: ^5.0.2