diff --git a/cw_bitcoin/lib/electrum_transaction_info.dart b/cw_bitcoin/lib/electrum_transaction_info.dart index 8d6ef0fea..4f7f6b62d 100644 --- a/cw_bitcoin/lib/electrum_transaction_info.dart +++ b/cw_bitcoin/lib/electrum_transaction_info.dart @@ -235,4 +235,6 @@ class ElectrumTransactionInfo extends TransactionInfo { m['fee'] = fee; return m; } + @override + String? unlockTimeFormatted() => null; } diff --git a/cw_core/lib/transaction_info.dart b/cw_core/lib/transaction_info.dart index b8e4a5e0c..f1900ee49 100644 --- a/cw_core/lib/transaction_info.dart +++ b/cw_core/lib/transaction_info.dart @@ -10,10 +10,12 @@ abstract class TransactionInfo extends Object with Keyable { late DateTime date; late int height; late int confirmations; + int? unlockTime; String amountFormatted(); String fiatAmount(); String? feeFormatted(); void changeFiatAmount(String amount); + String? unlockTimeFormatted(); @override dynamic get keyIndex => id; diff --git a/cw_haven/lib/haven_transaction_info.dart b/cw_haven/lib/haven_transaction_info.dart index 277370467..62519487b 100644 --- a/cw_haven/lib/haven_transaction_info.dart +++ b/cw_haven/lib/haven_transaction_info.dart @@ -66,4 +66,7 @@ class HavenTransactionInfo extends TransactionInfo { @override String feeFormatted() => '${formatAmount(moneroAmountToString(amount: fee))} $assetType'; + + @override + String? unlockTimeFormatted() => null; } diff --git a/cw_monero/ios/Classes/monero_api.cpp b/cw_monero/ios/Classes/monero_api.cpp index 117214295..f6d4acde1 100644 --- a/cw_monero/ios/Classes/monero_api.cpp +++ b/cw_monero/ios/Classes/monero_api.cpp @@ -134,6 +134,7 @@ extern "C" uint64_t blockHeight; uint64_t confirmations; uint32_t subaddrAccount; + uint64_t unlockTime; int8_t direction; int8_t isPending; uint32_t subaddrIndex; @@ -152,6 +153,7 @@ extern "C" std::set::iterator it = transaction->subaddrIndex().begin(); subaddrIndex = *it; confirmations = transaction->confirmations(); + unlockTime = transaction->unlockTime(); datetime = static_cast(transaction->timestamp()); direction = transaction->direction(); isPending = static_cast(transaction->isPending()); diff --git a/cw_monero/lib/api/structs/transaction_info_row.dart b/cw_monero/lib/api/structs/transaction_info_row.dart index bdcc64d3f..cd7f4dacb 100644 --- a/cw_monero/lib/api/structs/transaction_info_row.dart +++ b/cw_monero/lib/api/structs/transaction_info_row.dart @@ -14,6 +14,9 @@ class TransactionInfoRow extends Struct { @Uint64() external int confirmations; + @Uint64() + external int unlockTime; + @Uint32() external int subaddrAccount; diff --git a/cw_monero/lib/monero_transaction_info.dart b/cw_monero/lib/monero_transaction_info.dart index 2dfdaf408..4e78bca05 100644 --- a/cw_monero/lib/monero_transaction_info.dart +++ b/cw_monero/lib/monero_transaction_info.dart @@ -8,7 +8,7 @@ import 'package:cw_monero/api/transaction_history.dart'; class MoneroTransactionInfo extends TransactionInfo { MoneroTransactionInfo(this.id, this.height, this.direction, this.date, - this.isPending, this.amount, this.accountIndex, this.addressIndex, this.fee); + this.isPending, this.amount, this.accountIndex, this.addressIndex, this.fee, this.unlockTime); MoneroTransactionInfo.fromMap(Map map) : id = (map['hash'] ?? '') as String, @@ -22,6 +22,7 @@ class MoneroTransactionInfo extends TransactionInfo { amount = map['amount'] as int, accountIndex = int.parse(map['accountIndex'] as String), addressIndex = map['addressIndex'] as int, + unlockTime = map['unlockTime'] as int, key = getTxKey((map['hash'] ?? '') as String), fee = map['fee'] as int ?? 0 { additionalInfo = { @@ -41,6 +42,7 @@ class MoneroTransactionInfo extends TransactionInfo { amount = row.getAmount(), accountIndex = row.subaddrAccount, addressIndex = row.subaddrIndex, + unlockTime = row.unlockTime, key = getTxKey(row.getHash()), fee = row.fee { additionalInfo = { @@ -59,6 +61,7 @@ class MoneroTransactionInfo extends TransactionInfo { final int amount; final int fee; final int addressIndex; + final int unlockTime; String? recipientAddress; String? key; String? _fiatAmount; @@ -76,4 +79,17 @@ class MoneroTransactionInfo extends TransactionInfo { @override String feeFormatted() => '${formatAmount(moneroAmountToString(amount: fee))} XMR'; + + @override + String? unlockTimeFormatted() { + final formattedTime = unlockTime * 2; + if (direction == TransactionDirection.outgoing || unlockTime == 0) { + return null; + } + + if (formattedTime > 500000) { + return '>1 year'; + } + return '~ $formattedTime minutes'; + } } diff --git a/lib/view_model/transaction_details_view_model.dart b/lib/view_model/transaction_details_view_model.dart index f8729715b..5328ea295 100644 --- a/lib/view_model/transaction_details_view_model.dart +++ b/lib/view_model/transaction_details_view_model.dart @@ -37,8 +37,12 @@ abstract class TransactionDetailsViewModelBase with Store { final key = tx.additionalInfo['key'] as String?; final accountIndex = tx.additionalInfo['accountIndex'] as int; final addressIndex = tx.additionalInfo['addressIndex'] as int; + final unlockTimeFormatted = tx.unlockTimeFormatted(); final feeFormatted = tx.feeFormatted(); final _items = [ + if (unlockTimeFormatted != null) + StandartListItem( + title: 'Unlock time', value: unlockTimeFormatted), StandartListItem( title: S.current.transaction_details_transaction_id, value: tx.id), StandartListItem(