fix height and amount for btcln tx details (#3201)
What changed, and why it matters
This commit fixes how Bitcoin and Bitcoin Lightning transaction details are displayed in Cake Wallet. It corrects the shown crypto amount to use the right currency symbol and decimal handling for Lightning transactions, and it prevents a crash by allowing the block height to be empty when it is missing. There is no indication this change addresses a security vulnerability or enables attacks.
No security action required; treat as a routine UI/UX bug fix. Reviewers may verify that `formattedCryptoAmount` correctly handles edge cases such as zero or negative amounts and that the null height fallback renders cleanly.
Security signals we found
UI-only display fix with no privileged operation changes
Null-safety improvement for block height rendering
No input validation, cryptography, or authorization logic modified
Evidence from the diff
The patch updates two files. In the transaction details modal, the displayed amount now uses a new formattedCryptoAmount getter instead of calling transactionInfo.amountFormatted() directly. The view model adds formattedCryptoAmount, which for WalletType.bitcoin distinguishes BTC from BTCLN via isLightning(transactionInfo), formats the amount with up to 8 decimals and the user’s locale separator, and appends the correct symbol. For other wallet types it falls back to the original behavior. The block height row now uses vm.transactionInfo.height?.toString() ?? "" instead of vm.transactionInfo.height.toString(), safely handling a null height.
Changed components
lib/new-ui/widgets/coins_page/assets_history/transaction_details_modal.dartlib/view_model/transaction_details_view_model.dartInspect captured patch +17 / −3
diff --git a/lib/new-ui/widgets/coins_page/assets_history/transaction_details_modal.dart b/lib/new-ui/widgets/coins_page/assets_history/transaction_details_modal.dart
index f7e6c952..e390203a 100644
--- a/lib/new-ui/widgets/coins_page/assets_history/transaction_details_modal.dart
+++ b/lib/new-ui/widgets/coins_page/assets_history/transaction_details_modal.dart
@@ -81,8 +81,7 @@ class _TransactionDetailsModalState extends State<TransactionDetailsModal> {
style: TextStyle(fontSize: 20, fontWeight: FontWeight.w500),
),
Text(
- widget.transactionDetailsViewModel.transactionInfo
- .amountFormatted(),
+ widget.transactionDetailsViewModel.formattedCryptoAmount,
style: TextStyle(fontSize: 28),
),
Padding(
diff --git a/lib/view_model/transaction_details_view_model.dart b/lib/view_model/transaction_details_view_model.dart
index 492c561a..2c64d6e7 100644
--- a/lib/view_model/transaction_details_view_model.dart
+++ b/lib/view_model/transaction_details_view_model.dart
@@ -6,6 +6,7 @@ import 'package:cake_wallet/store/app_store.dart';
import 'package:cake_wallet/core/address_validator.dart';
import 'package:cake_wallet/tron/tron.dart';
import 'package:cake_wallet/zano/zano.dart';
+import 'package:cw_core/crypto_amount_format.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/currency_for_wallet_type.dart';
import 'package:cw_core/utils/print_verbose.dart';
@@ -69,7 +70,7 @@ class TxDetailRowDefinition {
TxDetailRowDefinition(
keyString: "standard_list_item_transaction_details_height_key",
title: S.current.transaction_details_height,
- valueGetter: (vm) => vm.transactionInfo.height.toString(),
+ valueGetter: (vm) => vm.transactionInfo.height?.toString() ?? "",
applicable: (vm) => !([WalletType.solana, WalletType.tron].contains(vm.wallet.type) &&
!isLightning(vm.transactionInfo))),
@@ -587,6 +588,20 @@ abstract class TransactionDetailsViewModelBase with Store {
return bitcoin!.formatterBitcoinAmountToString(amount: newFee);
}
+ String get formattedCryptoAmount {
+ if (wallet.type == WalletType.bitcoin) {
+ final crypto = isLightning(transactionInfo) ? CryptoCurrency.btcln : CryptoCurrency.btc;
+ final amount = _appStore.amountParsingProxy
+ .getDisplayCryptoString(transactionInfo.amount, crypto)
+ .withMaxDecimals(8)
+ .withLocalSeperator(_appStore.settingsStore.languageCode);
+
+ return '$amount ${_appStore.amountParsingProxy.getCryptoSymbol(crypto)}';
+ }
+
+ return transactionInfo.amountFormatted();
+ }
+
void replaceByFee(String newFee) => sendViewModel.replaceByFee(transactionInfo, newFee);
@computed
Why this scored 19/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.