feat(wallet): decode OP_RETURN payloads and coinbase pool tags in tx details

Transaction detail view silently dropped OP_RETURN messages and coinbase
scriptSig text (e.g. pool tags), since TransactionInspector discarded
scriptPubKey/scriptSig bytes once no destination address could be derived.
Each output/input is decoded independently, so multiple OP_RETURN outputs
in one tx are all shown.
This commit is contained in:
2026-07-09 08:35:34 +02:00
parent 663460d62e
commit 077835a30b
3 changed files with 194 additions and 6 deletions
@@ -64,13 +64,17 @@ public sealed class TransactionDetailsViewModel
RbfText = loc[d.RbfSignaled ? "tx.yes" : "tx.no"];
Inputs = new ObservableCollection<TxIoRow>(d.Inputs.Select((i, n) => new TxIoRow(
i.IsCoinbase ? loc["tx.coinbase"] : $"{i.PrevTxid}:{i.PrevIndex}",
i.IsCoinbase ? loc["tx.coinbase.newcoins"] : i.Address ?? "—",
i.IsCoinbase
? i.CoinbaseTag is { Length: > 0 } tag
? $"{loc["tx.coinbase.newcoins"]} — {tag}"
: loc["tx.coinbase.newcoins"]
: i.Address ?? "—",
i.AmountSats is { } a ? CoinAmount.FormatIn(a, unit) : "—",
i.IsMine)));
Outputs = new ObservableCollection<TxIoRow>(d.Outputs.Select(o => new TxIoRow(
$"#{o.Index}",
o.Address ?? $"({o.ScriptType})",
o.Address ?? (o.OpReturnText is { Length: > 0 } msg ? $"OP_RETURN: {msg}" : $"({o.ScriptType})"),
CoinAmount.FormatIn(o.AmountSats, unit),
o.IsMine)));
}