mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-01-18 16:44:32 +00:00
use new transaction nonce property
This commit is contained in:
parent
f969179ea6
commit
c8139007e3
20 changed files with 110 additions and 4 deletions
|
@ -28,6 +28,7 @@ class Transaction {
|
|||
required this.otherData,
|
||||
required this.inputs,
|
||||
required this.outputs,
|
||||
required this.nonce,
|
||||
});
|
||||
|
||||
Tuple2<Transaction, Address?> copyWith({
|
||||
|
@ -46,6 +47,7 @@ class Transaction {
|
|||
String? otherData,
|
||||
List<Input>? inputs,
|
||||
List<Output>? outputs,
|
||||
int? nonce,
|
||||
Id? id,
|
||||
Address? address,
|
||||
}) {
|
||||
|
@ -64,6 +66,7 @@ class Transaction {
|
|||
isLelantus: isLelantus ?? this.isLelantus,
|
||||
slateId: slateId ?? this.slateId,
|
||||
otherData: otherData ?? this.otherData,
|
||||
nonce: nonce ?? this.nonce,
|
||||
inputs: inputs ?? this.inputs,
|
||||
outputs: outputs ?? this.outputs)
|
||||
..id = id ?? this.id,
|
||||
|
@ -147,6 +150,7 @@ class Transaction {
|
|||
"isLelantus: $isLelantus, "
|
||||
"slateId: $slateId, "
|
||||
"otherData: $otherData, "
|
||||
"nonce: $nonce, "
|
||||
"address: ${address.value}, "
|
||||
"inputsLength: ${inputs.length}, "
|
||||
"outputsLength: ${outputs.length}, "
|
||||
|
@ -167,6 +171,7 @@ class Transaction {
|
|||
"isLelantus": isLelantus,
|
||||
"slateId": slateId,
|
||||
"otherData": otherData,
|
||||
"nonce": nonce,
|
||||
"address": address.value?.toJsonString(),
|
||||
"inputs": inputs.map((e) => e.toJsonString()).toList(),
|
||||
"outputs": outputs.map((e) => e.toJsonString()).toList(),
|
||||
|
@ -193,6 +198,7 @@ class Transaction {
|
|||
isLelantus: json["isLelantus"] as bool?,
|
||||
slateId: json["slateId"] as String?,
|
||||
otherData: json["otherData"] as String?,
|
||||
nonce: json["nonce"] as int?,
|
||||
inputs: List<String>.from(json["inputs"] as List)
|
||||
.map((e) => Input.fromJsonString(e))
|
||||
.toList(),
|
||||
|
|
|
@ -268,6 +268,7 @@ Transaction _transactionDeserialize(
|
|||
[],
|
||||
isCancelled: reader.readBool(offsets[5]),
|
||||
isLelantus: reader.readBoolOrNull(offsets[6]),
|
||||
nonce: reader.readLongOrNull(offsets[7]),
|
||||
otherData: reader.readStringOrNull(offsets[8]),
|
||||
outputs: reader.readObjectList<Output>(
|
||||
offsets[9],
|
||||
|
@ -287,7 +288,6 @@ Transaction _transactionDeserialize(
|
|||
walletId: reader.readString(offsets[15]),
|
||||
);
|
||||
object.id = id;
|
||||
object.nonce = reader.readLongOrNull(offsets[7]);
|
||||
return object;
|
||||
}
|
||||
|
||||
|
|
|
@ -1346,6 +1346,7 @@ class BitcoinWallet extends CoinServiceAPI
|
|||
isLelantus: false,
|
||||
otherData: null,
|
||||
slateId: null,
|
||||
nonce: null,
|
||||
inputs: [],
|
||||
outputs: [],
|
||||
);
|
||||
|
|
|
@ -1261,6 +1261,7 @@ class BitcoinCashWallet extends CoinServiceAPI
|
|||
isLelantus: false,
|
||||
otherData: null,
|
||||
slateId: null,
|
||||
nonce: null,
|
||||
inputs: [],
|
||||
outputs: [],
|
||||
);
|
||||
|
@ -2326,6 +2327,7 @@ class BitcoinCashWallet extends CoinServiceAPI
|
|||
isLelantus: false,
|
||||
slateId: null,
|
||||
otherData: null,
|
||||
nonce: null,
|
||||
inputs: inputs,
|
||||
outputs: outputs,
|
||||
);
|
||||
|
|
|
@ -1128,6 +1128,7 @@ class DogecoinWallet extends CoinServiceAPI
|
|||
isLelantus: false,
|
||||
otherData: null,
|
||||
slateId: null,
|
||||
nonce: null,
|
||||
inputs: [],
|
||||
outputs: [],
|
||||
);
|
||||
|
|
|
@ -1699,6 +1699,7 @@ class EpicCashWallet extends CoinServiceAPI
|
|||
tx["tx_type"] == "TxReceivedCancelled",
|
||||
isLelantus: false,
|
||||
slateId: slateId,
|
||||
nonce: null,
|
||||
otherData: tx["id"].toString(),
|
||||
inputs: [],
|
||||
outputs: [],
|
||||
|
|
|
@ -868,12 +868,26 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
|||
Future<void> _refreshTransactions() async {
|
||||
String thisAddress = await currentReceivingAddress;
|
||||
|
||||
final txsResponse = await EthereumAPI.getEthTransactions(thisAddress);
|
||||
final response = await EthereumAPI.getEthTransactions(thisAddress);
|
||||
|
||||
if (response.value == null) {
|
||||
Logging.instance.log(
|
||||
"Failed to refresh transactions for ${coin.prettyName} $walletName "
|
||||
"$walletId: ${response.exception}",
|
||||
level: LogLevel.Warning,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final txsResponse =
|
||||
await EthereumAPI.getEthTransactionNonces(response.value!);
|
||||
|
||||
if (txsResponse.value != null) {
|
||||
final allTxs = txsResponse.value!;
|
||||
final List<Tuple2<Transaction, Address?>> txnsData = [];
|
||||
for (final element in allTxs) {
|
||||
for (final tuple in allTxs) {
|
||||
final element = tuple.item1;
|
||||
|
||||
Amount transactionAmount = element.value;
|
||||
|
||||
bool isIncoming;
|
||||
|
@ -909,6 +923,7 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
|||
isLelantus: false,
|
||||
slateId: null,
|
||||
otherData: null,
|
||||
nonce: tuple.item2,
|
||||
inputs: [],
|
||||
outputs: [],
|
||||
);
|
||||
|
@ -966,7 +981,8 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
|||
}
|
||||
} else {
|
||||
Logging.instance.log(
|
||||
"Failed to refresh transactions for ${coin.prettyName} $walletName $walletId",
|
||||
"Failed to refresh transactions with nonces for ${coin.prettyName} "
|
||||
"$walletName $walletId: ${txsResponse.exception}",
|
||||
level: LogLevel.Warning,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -483,6 +483,7 @@ Future<Map<dynamic, dynamic>> staticProcessRestore(
|
|||
isLelantus: true,
|
||||
slateId: null,
|
||||
otherData: txid,
|
||||
nonce: null,
|
||||
inputs: element.inputs,
|
||||
outputs: element.outputs,
|
||||
)..address.value = element.address.value;
|
||||
|
@ -914,6 +915,7 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive {
|
|||
isLelantus: false,
|
||||
otherData: null,
|
||||
slateId: null,
|
||||
nonce: null,
|
||||
inputs: [],
|
||||
outputs: [],
|
||||
);
|
||||
|
@ -3070,6 +3072,7 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive {
|
|||
isCancelled: false,
|
||||
isLelantus: true,
|
||||
slateId: null,
|
||||
nonce: null,
|
||||
otherData: transactionInfo["otherData"] as String?,
|
||||
inputs: [],
|
||||
outputs: [],
|
||||
|
@ -3631,6 +3634,7 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive {
|
|||
isLelantus: false,
|
||||
slateId: null,
|
||||
otherData: null,
|
||||
nonce: null,
|
||||
inputs: ins,
|
||||
outputs: outs,
|
||||
);
|
||||
|
@ -4971,6 +4975,7 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive {
|
|||
isLelantus: true,
|
||||
slateId: null,
|
||||
otherData: null,
|
||||
nonce: null,
|
||||
inputs: [],
|
||||
outputs: [],
|
||||
);
|
||||
|
|
|
@ -1253,6 +1253,7 @@ class LitecoinWallet extends CoinServiceAPI
|
|||
isLelantus: false,
|
||||
otherData: null,
|
||||
slateId: null,
|
||||
nonce: null,
|
||||
inputs: [],
|
||||
outputs: [],
|
||||
);
|
||||
|
|
|
@ -937,6 +937,7 @@ class MoneroWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
|||
isLelantus: false,
|
||||
slateId: null,
|
||||
otherData: null,
|
||||
nonce: null,
|
||||
inputs: [],
|
||||
outputs: [],
|
||||
);
|
||||
|
|
|
@ -1243,6 +1243,7 @@ class NamecoinWallet extends CoinServiceAPI
|
|||
isLelantus: false,
|
||||
otherData: null,
|
||||
slateId: null,
|
||||
nonce: null,
|
||||
inputs: [],
|
||||
outputs: [],
|
||||
);
|
||||
|
|
|
@ -1172,6 +1172,7 @@ class ParticlWallet extends CoinServiceAPI
|
|||
isLelantus: false,
|
||||
otherData: null,
|
||||
slateId: null,
|
||||
nonce: null,
|
||||
inputs: [],
|
||||
outputs: [],
|
||||
);
|
||||
|
@ -2367,6 +2368,7 @@ class ParticlWallet extends CoinServiceAPI
|
|||
outputs: outputs,
|
||||
isCancelled: false,
|
||||
isLelantus: false,
|
||||
nonce: null,
|
||||
slateId: null,
|
||||
otherData: null,
|
||||
);
|
||||
|
|
|
@ -1016,6 +1016,7 @@ class WowneroWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
|||
isLelantus: false,
|
||||
slateId: null,
|
||||
otherData: null,
|
||||
nonce: null,
|
||||
inputs: [],
|
||||
outputs: [],
|
||||
);
|
||||
|
|
|
@ -11,6 +11,7 @@ import 'package:stackwallet/models/paymint/fee_object_model.dart';
|
|||
import 'package:stackwallet/utilities/default_nodes.dart';
|
||||
import 'package:stackwallet/utilities/eth_commons.dart';
|
||||
import 'package:stackwallet/utilities/logger.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
|
||||
class EthApiException with Exception {
|
||||
EthApiException(this.message);
|
||||
|
@ -89,6 +90,64 @@ abstract class EthereumAPI {
|
|||
}
|
||||
}
|
||||
|
||||
static Future<EthereumResponse<List<Tuple2<EthTxDTO, int?>>>>
|
||||
getEthTransactionNonces(
|
||||
List<EthTxDTO> txns,
|
||||
) async {
|
||||
try {
|
||||
final response = await get(
|
||||
Uri.parse(
|
||||
"$stackBaseServer/transactions?transactions=${txns.map((e) => e.hash).join(" ")}",
|
||||
),
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
if (response.body.isNotEmpty) {
|
||||
final json = jsonDecode(response.body) as Map;
|
||||
final list = List<Map<String, dynamic>>.from(json["data"] as List);
|
||||
|
||||
final List<Tuple2<EthTxDTO, int?>> result = [];
|
||||
|
||||
for (final dto in txns) {
|
||||
final data =
|
||||
list.firstWhere((e) => e["hash"] == dto.hash, orElse: () => {});
|
||||
|
||||
final nonce = data["nonce"] as int?;
|
||||
result.add(Tuple2(dto, nonce));
|
||||
}
|
||||
return EthereumResponse(
|
||||
result,
|
||||
null,
|
||||
);
|
||||
} else {
|
||||
throw EthApiException(
|
||||
"getEthTransactionNonces($txns) response is empty but status code is "
|
||||
"${response.statusCode}",
|
||||
);
|
||||
}
|
||||
} else {
|
||||
throw EthApiException(
|
||||
"getEthTransactionNonces($txns) failed with status code: "
|
||||
"${response.statusCode}",
|
||||
);
|
||||
}
|
||||
} on EthApiException catch (e) {
|
||||
return EthereumResponse(
|
||||
null,
|
||||
e,
|
||||
);
|
||||
} catch (e, s) {
|
||||
Logging.instance.log(
|
||||
"getEthTransactionNonces($txns): $e\n$s",
|
||||
level: LogLevel.Error,
|
||||
);
|
||||
return EthereumResponse(
|
||||
null,
|
||||
EthApiException(e.toString()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static Future<EthereumResponse<List<EthTokenTxExtraDTO>>>
|
||||
getEthTokenTransactionsByTxids(List<String> txids) async {
|
||||
try {
|
||||
|
|
|
@ -447,6 +447,7 @@ class EthTokenWallet extends ChangeNotifier with EthTokenCache {
|
|||
isCancelled: false,
|
||||
isLelantus: false,
|
||||
slateId: null,
|
||||
nonce: tuple.item2.nonce,
|
||||
otherData: tuple.item1.address,
|
||||
inputs: [],
|
||||
outputs: [],
|
||||
|
|
|
@ -231,6 +231,7 @@ mixin ElectrumXParsing {
|
|||
isLelantus: false,
|
||||
slateId: null,
|
||||
otherData: null,
|
||||
nonce: null,
|
||||
inputs: ins,
|
||||
outputs: outs,
|
||||
);
|
||||
|
|
|
@ -349,6 +349,7 @@ class DbVersionMigrator with WalletDB {
|
|||
isLelantus: false,
|
||||
slateId: tx.slateId,
|
||||
otherData: tx.otherData,
|
||||
nonce: null,
|
||||
inputs: [],
|
||||
outputs: [],
|
||||
);
|
||||
|
|
|
@ -108,6 +108,7 @@ void main() {
|
|||
isLelantus: null,
|
||||
slateId: t.slateId,
|
||||
otherData: t.otherData,
|
||||
nonce: null,
|
||||
inputs: [],
|
||||
outputs: [],
|
||||
),
|
||||
|
|
|
@ -115,6 +115,7 @@ void main() {
|
|||
isLelantus: true,
|
||||
slateId: null,
|
||||
otherData: null,
|
||||
nonce: null,
|
||||
inputs: [],
|
||||
outputs: [],
|
||||
);
|
||||
|
|
|
@ -64,6 +64,7 @@ void main() {
|
|||
isLelantus: null,
|
||||
slateId: '',
|
||||
otherData: '',
|
||||
nonce: null,
|
||||
inputs: [],
|
||||
outputs: [],
|
||||
)..address.value = Address(
|
||||
|
@ -169,6 +170,7 @@ void main() {
|
|||
isLelantus: null,
|
||||
slateId: '',
|
||||
otherData: '',
|
||||
nonce: null,
|
||||
inputs: [],
|
||||
outputs: [],
|
||||
)..address.value = Address(
|
||||
|
@ -271,6 +273,7 @@ void main() {
|
|||
isLelantus: null,
|
||||
slateId: '',
|
||||
otherData: '',
|
||||
nonce: null,
|
||||
inputs: [],
|
||||
outputs: [],
|
||||
)..address.value = Address(
|
||||
|
@ -367,6 +370,7 @@ void main() {
|
|||
isLelantus: null,
|
||||
slateId: '',
|
||||
otherData: '',
|
||||
nonce: null,
|
||||
inputs: [],
|
||||
outputs: [],
|
||||
)..address.value = Address(
|
||||
|
|
Loading…
Reference in a new issue