diff --git a/lib/models/paymint/transactions_model.dart b/lib/models/paymint/transactions_model.dart index 6eba877c4..1d40ac01c 100644 --- a/lib/models/paymint/transactions_model.dart +++ b/lib/models/paymint/transactions_model.dart @@ -362,12 +362,16 @@ class Input { class Output { // @HiveField(0) final String? scriptpubkey; + // @HiveField(1) final String? scriptpubkeyAsm; + // @HiveField(2) final String? scriptpubkeyType; + // @HiveField(3) final String scriptpubkeyAddress; + // @HiveField(4) final int value; @@ -381,9 +385,6 @@ class Output { factory Output.fromJson(Map<String, dynamic> json) { // TODO determine if any of this code is needed. try { - // Particl has different tx types that need to be detected and handled here - // if (json.containsKey('scriptPubKey') as bool) { - // output is transparent final address = json["scriptPubKey"]["addresses"] == null ? json['scriptPubKey']['type'] as String : json["scriptPubKey"]["addresses"][0] as String; @@ -392,35 +393,13 @@ class Output { scriptpubkeyAsm: json['scriptPubKey']['asm'] as String?, scriptpubkeyType: json['scriptPubKey']['type'] as String?, scriptpubkeyAddress: address, - value: (Decimal.parse(json["value"].toString()) * + value: (Decimal.parse( + (json["value"] ?? 0).toString()) * Decimal.fromInt(Constants.satsPerCoin(Coin .firo))) // dirty hack but we need 8 decimal places here to keep consistent data structure .toBigInt() .toInt(), ); - // } /* else if (json.containsKey('ct_fee') as bool) { - // // or type: data - // // output is blinded (CT) - // } else if (json.containsKey('rangeproof') as bool) { - // // or valueCommitment or type: anon - // // output is private (RingCT) - // } */ - // else { - // // TODO detect staking - // // TODO handle CT, RingCT, and staking accordingly - // // print("transaction not supported: ${json}"); - // return Output( - // // Return output object with null values; allows wallet history to be built - // scriptpubkey: "", - // scriptpubkeyAsm: "", - // scriptpubkeyType: "", - // scriptpubkeyAddress: "", - // value: (Decimal.parse(0.toString()) * - // Decimal.fromInt(Constants.satsPerCoin(Coin - // .firo))) // dirty hack but we need 8 decimal places here to keep consistent data structure - // .toBigInt() - // .toInt()); - // } } catch (s, e) { return Output( // Return output object with null values; allows wallet history to be built diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart index 1ed87681b..bfacb6b2a 100644 --- a/lib/services/coins/bitcoin/bitcoin_wallet.dart +++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart @@ -1297,7 +1297,8 @@ class BitcoinWallet extends CoinServiceAPI { final priceData = await _priceAPI.getPricesAnd24hChange(baseCurrency: _prefs.currency); Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero; - final locale = Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; + final locale = + Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; final String worthNow = Format.localizedStringAsFixed( value: ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) / @@ -2502,7 +2503,7 @@ class BitcoinWallet extends CoinServiceAPI { for (final out in tx["vout"] as List) { if (prevOut == out["n"]) { - final address = out["scriptPubKey"]["address"] as String?; + final address = getAddress(out) as String?; if (address != null) { sendersArray.add(address); } @@ -2513,7 +2514,7 @@ class BitcoinWallet extends CoinServiceAPI { Logging.instance.log("sendersArray: $sendersArray", level: LogLevel.Info); for (final output in txObject["vout"] as List) { - final address = output["scriptPubKey"]["address"] as String?; + final address = getAddress(output); if (address != null) { recipientsArray.add(address); } @@ -2553,7 +2554,7 @@ class BitcoinWallet extends CoinServiceAPI { int totalOutput = 0; for (final output in txObject["vout"] as List) { - final String address = output["scriptPubKey"]!["address"] as String; + final String address = getAddress(output) as String; final value = output["value"]!; final _value = (Decimal.parse(value.toString()) * Decimal.fromInt(Constants.satsPerCoin(coin))) @@ -2578,7 +2579,7 @@ class BitcoinWallet extends CoinServiceAPI { // add up received tx value for (final output in txObject["vout"] as List) { - final address = output["scriptPubKey"]["address"]; + final address = getAddress(output); if (address != null) { final value = (Decimal.parse(output["value"].toString()) * Decimal.fromInt(Constants.satsPerCoin(coin))) @@ -3095,7 +3096,7 @@ class BitcoinWallet extends CoinServiceAPI { for (final output in tx["vout"] as List) { final n = output["n"]; if (n != null && n == utxosToUse[i].vout) { - final address = output["scriptPubKey"]["address"] as String; + final address = getAddress(output) as String; if (!addressTxid.containsKey(address)) { addressTxid[address] = <String>[]; } diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index b18a97186..ebd2e2df8 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -1174,7 +1174,8 @@ class BitcoinCashWallet extends CoinServiceAPI { final priceData = await _priceAPI.getPricesAnd24hChange(baseCurrency: _prefs.currency); Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero; - final locale = Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; + final locale = + Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; final String worthNow = Format.localizedStringAsFixed( value: ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) / @@ -2300,7 +2301,7 @@ class BitcoinCashWallet extends CoinServiceAPI { for (final out in tx["vout"] as List) { if (prevOut == out["n"]) { - final address = out["scriptPubKey"]["addresses"][0] as String?; + final address = getAddress(out); if (address != null) { sendersArray.add(address); } @@ -2311,7 +2312,7 @@ class BitcoinCashWallet extends CoinServiceAPI { Logging.instance.log("sendersArray: $sendersArray", level: LogLevel.Info); for (final output in txObject["vout"] as List) { - final address = output["scriptPubKey"]["addresses"][0] as String?; + final address = getAddress(output); if (address != null) { recipientsArray.add(address); } @@ -2352,7 +2353,7 @@ class BitcoinCashWallet extends CoinServiceAPI { int totalOutput = 0; for (final output in txObject["vout"] as List) { - final address = output["scriptPubKey"]["addresses"][0]; + final address = getAddress(output); final value = output["value"]; final _value = (Decimal.parse(value.toString()) * Decimal.fromInt(Constants.satsPerCoin(coin))) @@ -2377,9 +2378,9 @@ class BitcoinCashWallet extends CoinServiceAPI { // add up received tx value for (final output in txObject["vout"] as List) { - final address = output["scriptPubKey"]["addresses"][0]; + final address = getAddress(output); if (address != null) { - final value = (Decimal.parse(output["value"].toString()) * + final value = (Decimal.parse((output["value"] ?? 0).toString()) * Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() .toInt(); @@ -2902,7 +2903,7 @@ class BitcoinCashWallet extends CoinServiceAPI { for (final output in tx["vout"] as List) { final n = output["n"]; if (n != null && n == utxosToUse[i].vout) { - String address = output["scriptPubKey"]["addresses"][0] as String; + String address = getAddress(output) as String; if (bitbox.Address.detectFormat(address) == bitbox.Address.formatCashAddr) { if (validateCashAddr(address)) { diff --git a/lib/services/coins/coin_service.dart b/lib/services/coins/coin_service.dart index a690157ee..f0c154ba7 100644 --- a/lib/services/coins/coin_service.dart +++ b/lib/services/coins/coin_service.dart @@ -307,4 +307,46 @@ abstract class CoinServiceAPI { // used for electrumx coins Future<void> updateSentCachedTxData(Map<String, dynamic> txData); + + // Certain outputs return address as an array/list of strings like List<String> ["addresses"][0], some return it as a string like String ["address"] + String? getAddress(dynamic output) { + // Julian's code from https://github.com/cypherstack/stack_wallet/blob/35a8172d35f1b5cdbd22f0d56c4db02f795fd032/lib/services/coins/coin_paynym_extension.dart#L170 wins codegolf for this, I'd love to commit it now but need to retest this section ... should make unit tests for this case + // final String? address = output["scriptPubKey"]?["addresses"]?[0] as String? ?? output["scriptPubKey"]?["address"] as String?; + String? address; + if (output.containsKey('scriptPubKey') as bool) { + // Make sure the key exists before using it + if (output["scriptPubKey"].containsKey('address') as bool) { + address = output["scriptPubKey"]["address"] as String?; + } else if (output["scriptPubKey"].containsKey('addresses') as bool) { + address = output["scriptPubKey"]["addresses"][0] as String?; + // TODO determine cases in which there are multiple addresses in the array + } + } /*else { + // TODO detect cases in which no scriptPubKey exists + Logging.instance.log("output type not detected; output: ${output}", + level: LogLevel.Info); + }*/ + + return address; + } + + // Firo wants an array/list of address strings like List<String> + List? getAddresses(dynamic output) { + // Inspired by Julian's code as referenced above, need to test before committing + // final List? addresses = output["scriptPubKey"]?["addresses"] as List? ?? [output["scriptPubKey"]?["address"]] as List?; + List? addresses; + if (output.containsKey('scriptPubKey') as bool) { + if (output["scriptPubKey"].containsKey('addresses') as bool) { + addresses = output["scriptPubKey"]["addresses"] as List?; + } else if (output["scriptPubKey"].containsKey('address') as bool) { + addresses = [output["scriptPubKey"]["address"]]; + } + } /*else { + // TODO detect cases in which no scriptPubKey exists + Logging.instance.log("output type not detected; output: ${output}", + level: LogLevel.Info); + }*/ + + return addresses; + } } diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart index 5b0da3fb3..f8a9809d1 100644 --- a/lib/services/coins/dogecoin/dogecoin_wallet.dart +++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart @@ -1064,7 +1064,8 @@ class DogecoinWallet extends CoinServiceAPI { final priceData = await _priceAPI.getPricesAnd24hChange(baseCurrency: _prefs.currency); Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero; - final locale = Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; + final locale = + Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; final String worthNow = Format.localizedStringAsFixed( value: ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) / @@ -2113,7 +2114,7 @@ class DogecoinWallet extends CoinServiceAPI { for (final out in tx["vout"] as List) { if (prevOut == out["n"]) { - final address = out["scriptPubKey"]["addresses"][0] as String?; + final address = getAddress(out); if (address != null) { sendersArray.add(address); } @@ -2124,7 +2125,7 @@ class DogecoinWallet extends CoinServiceAPI { Logging.instance.log("sendersArray: $sendersArray", level: LogLevel.Info); for (final output in txObject["vout"] as List) { - final address = output["scriptPubKey"]["addresses"][0] as String?; + final address = getAddress(output); if (address != null) { recipientsArray.add(address); } @@ -2164,7 +2165,7 @@ class DogecoinWallet extends CoinServiceAPI { int totalOutput = 0; for (final output in txObject["vout"] as List) { - final address = output["scriptPubKey"]["addresses"][0]; + final address = getAddress(output); final value = output["value"]; final _value = (Decimal.parse(value.toString()) * Decimal.fromInt(Constants.satsPerCoin(coin))) @@ -2189,7 +2190,7 @@ class DogecoinWallet extends CoinServiceAPI { // add up received tx value for (final output in txObject["vout"] as List) { - final address = output["scriptPubKey"]["addresses"][0]; + final address = getAddress(output); if (address != null) { final value = (Decimal.parse(output["value"].toString()) * Decimal.fromInt(Constants.satsPerCoin(coin))) @@ -2712,7 +2713,7 @@ class DogecoinWallet extends CoinServiceAPI { for (final output in tx["vout"] as List) { final n = output["n"]; if (n != null && n == utxosToUse[i].vout) { - final address = output["scriptPubKey"]["addresses"][0] as String; + final address = getAddress(output) as String; if (!addressTxid.containsKey(address)) { addressTxid[address] = <String>[]; } diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index 5d29bd0a9..89d912fe1 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -883,7 +883,8 @@ class FiroWallet extends CoinServiceAPI { @override Future<void> updateSentCachedTxData(Map<String, dynamic> txData) async { final currentPrice = await firoPrice; - final locale = Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; + final locale = + Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; final String worthNow = Format.localizedStringAsFixed( value: ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) / @@ -1691,7 +1692,7 @@ class FiroWallet extends CoinServiceAPI { for (final output in tx["vout"] as List) { final n = output["n"]; if (n != null && n == utxosToUse[i].vout) { - final address = output["scriptPubKey"]["addresses"][0] as String; + final address = getAddress(output) as String; if (!addressTxid.containsKey(address)) { addressTxid[address] = <String>[]; @@ -2654,8 +2655,7 @@ class FiroWallet extends CoinServiceAPI { final vouts = tx["vout"] as List?; if (vouts != null && outputIndex < vouts.length) { - final address = - vouts[outputIndex]["scriptPubKey"]["addresses"][0] as String?; + final address = getAddress(vouts[outputIndex]); if (address != null) { addressesToDerive.add(address); } @@ -2756,7 +2756,8 @@ class FiroWallet extends CoinServiceAPI { var price = await firoPrice; var builtHex = txb.build(); // return builtHex; - final locale =Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; + final locale = + Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; return { "transaction": builtHex, "txid": txId, @@ -2810,7 +2811,8 @@ class FiroWallet extends CoinServiceAPI { final currentPrice = await firoPrice; // Grab the most recent information on all the joinsplits - final locale = Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; + final locale = + Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; final updatedJSplit = await getJMintTransactions(cachedElectrumXClient, joinsplits, _prefs.currency, coin, currentPrice, locale!); @@ -3249,7 +3251,8 @@ class FiroWallet extends CoinServiceAPI { final currentPrice = await firoPrice; final List<Map<String, dynamic>> midSortedArray = []; - final locale = Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; + final locale = + Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; Logging.instance.log("refresh the txs", level: LogLevel.Info); for (final txObject in allTransactions) { @@ -3275,7 +3278,7 @@ class FiroWallet extends CoinServiceAPI { // Logging.instance.log("sendersArray: $sendersArray"); for (final output in txObject["vout"] as List) { - final addresses = output["scriptPubKey"]["addresses"] as List?; + final addresses = getAddresses(output); if (addresses != null && addresses.isNotEmpty) { recipientsArray.add(addresses[0] as String); } @@ -3319,8 +3322,8 @@ class FiroWallet extends CoinServiceAPI { } for (final output in txObject["vout"] as List) { - final addresses = output["scriptPubKey"]["addresses"] as List?; - final value = output["value"]; + final addresses = getAddresses(output); + final value = output["value"] ?? 0; if (addresses != null && addresses.isNotEmpty) { final address = addresses[0] as String; if (value != null) { @@ -3359,7 +3362,7 @@ class FiroWallet extends CoinServiceAPI { final addresses = output["scriptPubKey"]["addresses"] as List?; if (addresses != null && addresses.isNotEmpty) { final address = addresses[0] as String; - final value = output["value"]; + final value = output["value"] ?? 0; // Logging.instance.log(address + value.toString()); if (allAddresses.contains(address)) { @@ -4375,7 +4378,8 @@ class FiroWallet extends CoinServiceAPI { final lelantusEntry = await _getLelantusEntry(); final anonymitySets = await fetchAnonymitySets(); final locktime = await getBlockHead(electrumXClient); - final locale = Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; + final locale = + Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; ReceivePort receivePort = await getIsolate({ "function": "createJoinSplit", @@ -4742,7 +4746,7 @@ class FiroWallet extends CoinServiceAPI { } tx["amount"] = tx["vout"][sendIndex]["value"]; - tx["address"] = tx["vout"][sendIndex]["scriptPubKey"]["addresses"][0]; + tx["address"] = getAddress(tx["vout"][sendIndex]) as String; tx["fees"] = tx["vin"][0]["nFees"]; tx["inputSize"] = tx["vin"].length; diff --git a/lib/services/coins/litecoin/litecoin_wallet.dart b/lib/services/coins/litecoin/litecoin_wallet.dart index 269f59610..6379ced7c 100644 --- a/lib/services/coins/litecoin/litecoin_wallet.dart +++ b/lib/services/coins/litecoin/litecoin_wallet.dart @@ -1299,7 +1299,8 @@ class LitecoinWallet extends CoinServiceAPI { final priceData = await _priceAPI.getPricesAnd24hChange(baseCurrency: _prefs.currency); Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero; - final locale = Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; + final locale = + Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; final String worthNow = Format.localizedStringAsFixed( value: ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) / @@ -2513,7 +2514,7 @@ class LitecoinWallet extends CoinServiceAPI { for (final out in tx["vout"] as List) { if (prevOut == out["n"]) { - final address = out["scriptPubKey"]["addresses"][0] as String?; + final address = getAddress(out) as String?; if (address != null) { sendersArray.add(address); } @@ -2524,7 +2525,7 @@ class LitecoinWallet extends CoinServiceAPI { Logging.instance.log("sendersArray: $sendersArray", level: LogLevel.Info); for (final output in txObject["vout"] as List) { - final address = output["scriptPubKey"]["addresses"][0] as String?; + final address = getAddress(output); if (address != null) { recipientsArray.add(address); } @@ -2564,9 +2565,8 @@ class LitecoinWallet extends CoinServiceAPI { int totalOutput = 0; for (final output in txObject["vout"] as List) { - final String address = - output["scriptPubKey"]!["addresses"][0] as String; - final value = output["value"]!; + final String address = getAddress(output) as String; + final value = output["value"] ?? 0; final _value = (Decimal.parse(value.toString()) * Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() @@ -2590,9 +2590,9 @@ class LitecoinWallet extends CoinServiceAPI { // add up received tx value for (final output in txObject["vout"] as List) { - final address = output["scriptPubKey"]["addresses"][0]; + final address = getAddress(output); if (address != null) { - final value = (Decimal.parse(output["value"].toString()) * + final value = (Decimal.parse((output["value"] ?? 0).toString()) * Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() .toInt(); @@ -3107,7 +3107,7 @@ class LitecoinWallet extends CoinServiceAPI { for (final output in tx["vout"] as List) { final n = output["n"]; if (n != null && n == utxosToUse[i].vout) { - final address = output["scriptPubKey"]["addresses"][0] as String; + final address = getAddress(output) as String; if (!addressTxid.containsKey(address)) { addressTxid[address] = <String>[]; } diff --git a/lib/services/coins/namecoin/namecoin_wallet.dart b/lib/services/coins/namecoin/namecoin_wallet.dart index 85fea61ad..eb0655b4f 100644 --- a/lib/services/coins/namecoin/namecoin_wallet.dart +++ b/lib/services/coins/namecoin/namecoin_wallet.dart @@ -1287,7 +1287,8 @@ class NamecoinWallet extends CoinServiceAPI { final priceData = await _priceAPI.getPricesAnd24hChange(baseCurrency: _prefs.currency); Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero; - final locale = Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; + final locale = + Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; final String worthNow = Format.localizedStringAsFixed( value: ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) / @@ -2494,11 +2495,7 @@ class NamecoinWallet extends CoinServiceAPI { for (final out in tx["vout"] as List) { if (prevOut == out["n"]) { - String? address = out["scriptPubKey"]["address"] as String?; - if (address == null && out["scriptPubKey"]["address"] != null) { - address = out["scriptPubKey"]["address"] as String?; - } - + String? address = getAddress(out); if (address != null) { sendersArray.add(address); } @@ -2509,10 +2506,7 @@ class NamecoinWallet extends CoinServiceAPI { Logging.instance.log("sendersArray: $sendersArray", level: LogLevel.Info); for (final output in txObject["vout"] as List) { - String? address = output["scriptPubKey"]["address"] as String?; - if (address == null && output["scriptPubKey"]["address"] != null) { - address = output["scriptPubKey"]["address"] as String?; - } + String? address = getAddress(output); if (address != null) { recipientsArray.add(address); } @@ -2553,8 +2547,8 @@ class NamecoinWallet extends CoinServiceAPI { for (final output in txObject["vout"] as List) { Logging.instance.log(output, level: LogLevel.Info); - final address = output["scriptPubKey"]["address"]; - final value = output["value"]; + final address = getAddress(output); + final value = output["value"] ?? 0; final _value = (Decimal.parse(value.toString()) * Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() @@ -2578,12 +2572,9 @@ class NamecoinWallet extends CoinServiceAPI { // add up received tx value for (final output in txObject["vout"] as List) { - String? address = output["scriptPubKey"]["address"] as String?; - if (address == null && output["scriptPubKey"]["address"] != null) { - address = output["scriptPubKey"]["address"] as String?; - } + String? address = getAddress(output); if (address != null) { - final value = (Decimal.parse(output["value"].toString()) * + final value = (Decimal.parse((output["value"] ?? 0).toString()) * Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() .toInt(); @@ -3101,7 +3092,7 @@ class NamecoinWallet extends CoinServiceAPI { for (final output in tx["vout"] as List) { final n = output["n"]; if (n != null && n == utxosToUse[i].vout) { - final address = output["scriptPubKey"]["address"] as String; + final address = getAddress(output) as String; if (!addressTxid.containsKey(address)) { addressTxid[address] = <String>[]; } diff --git a/lib/services/coins/particl/particl_wallet.dart b/lib/services/coins/particl/particl_wallet.dart index fe535dbf0..ff04d0fc4 100644 --- a/lib/services/coins/particl/particl_wallet.dart +++ b/lib/services/coins/particl/particl_wallet.dart @@ -1200,7 +1200,8 @@ class ParticlWallet extends CoinServiceAPI { final priceData = await _priceAPI.getPricesAnd24hChange(baseCurrency: _prefs.currency); Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero; - final locale = Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; + final locale = + Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; final String worthNow = Format.localizedStringAsFixed( value: ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) / @@ -2288,7 +2289,7 @@ class ParticlWallet extends CoinServiceAPI { for (final out in tx["vout"] as List) { if (prevOut == out["n"]) { - final address = out["scriptPubKey"]["addresses"][0] as String?; + final address = getAddress(out); if (address != null) { sendersArray.add(address); } @@ -2302,7 +2303,7 @@ class ParticlWallet extends CoinServiceAPI { // Particl has different tx types that need to be detected and handled here if (output.containsKey('scriptPubKey') as bool) { // Logging.instance.log("output is transparent", level: LogLevel.Info); - final address = output["scriptPubKey"]["addresses"][0] as String?; + final address = getAddress(output); if (address != null) { recipientsArray.add(address); } @@ -2361,7 +2362,7 @@ class ParticlWallet extends CoinServiceAPI { try { final String address = output["scriptPubKey"]!["addresses"][0] as String; - final value = output["value"]!; + final value = output["value"] ?? 0; final _value = (Decimal.parse(value.toString()) * Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() @@ -2417,9 +2418,9 @@ class ParticlWallet extends CoinServiceAPI { // add up received tx value for (final output in txObject["vout"] as List) { try { - final address = output["scriptPubKey"]["addresses"][0]; + final address = getAddress(output); if (address != null) { - final value = (Decimal.parse(output["value"].toString()) * + final value = (Decimal.parse((output["value"] ?? 0).toString()) * Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() .toInt();