mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-01-10 12:44:31 +00:00
ADd address validation and convert receive addresses as checksum addresses
This commit is contained in:
parent
a6c2750f20
commit
5d77dcafbe
3 changed files with 181 additions and 127 deletions
|
@ -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");
|
||||
|
|
15
pubspec.lock
15
pubspec.lock
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue