commit 1b900bbc729849ec1539ddb11cd93c5e83913e86
parent babc1d549d5ce2c0aa28baa0fcba347e470c51a8
Author: Joris Hartog <jorishartog@hotmail.com>
Date: Wed, 9 Sep 2026 12:06:39 +0200
fix(wallet): show all transaction types by default
Diffstat:
4 files changed, 39 insertions(+), 17 deletions(-)
diff --git a/src/adapters/http/types.rs b/src/adapters/http/types.rs
@@ -248,8 +248,8 @@ impl Default for WalletTransactionFilters {
fn default() -> Self {
Self {
transfer: true,
- mine: false,
- burn: false,
+ mine: true,
+ burn: true,
reward: true,
}
}
@@ -259,8 +259,8 @@ impl WalletTransactionFilters {
pub(super) fn from_query(query: WalletTransactionsQuery) -> Self {
Self {
transfer: query.tx.unwrap_or(true),
- mine: query.mine.unwrap_or(false),
- burn: query.burn.unwrap_or(false),
+ mine: query.mine.unwrap_or(true),
+ burn: query.burn.unwrap_or(true),
reward: query.reward.unwrap_or(true),
}
}
diff --git a/src/main_tests.rs b/src/main_tests.rs
@@ -211,6 +211,24 @@ fn management_ui_wallet_transactions_share_the_generic_detail_flow() {
assert!(javascript.contains("outpoint: { txid: input.signature, index: \"fee\" }"));
}
+#[test]
+fn transaction_filters_default_to_every_transaction_type() {
+ let management_javascript = include_str!("../www/assets/iuna-ui.js");
+ let wallet_javascript = include_str!("../wallet/app.js");
+ let all_filters = "{ transfer: true, mine: true, burn: true, reward: true }";
+
+ assert!(management_javascript.contains(&format!("walletTxFilters: {all_filters}")));
+ assert!(wallet_javascript.contains(&format!("const ALL_TRANSACTION_FILTERS = {all_filters}")));
+}
+
+#[test]
+fn lightweight_wallet_recent_activity_does_not_use_view_all_filters() {
+ let javascript = include_str!("../wallet/app.js");
+
+ assert!(javascript.contains("api(transactionPath(0, 5, ALL_TRANSACTION_FILTERS))"));
+ assert!(javascript.contains("activityList(5, false, state.recentTransactions)"));
+}
+
fn ledger_with_one_spendable_iuna(wallet: &Wallet) -> Ledger {
let mut genesis = BTreeMap::new();
genesis.insert(wallet.address().to_string(), 3);
diff --git a/wallet/app.js b/wallet/app.js
@@ -8,10 +8,11 @@ import { generateMnemonic, validateMnemonic } from "./mnemonic.js";
const app = document.querySelector("#app");
const toastElement = document.querySelector("#toast");
const TRANSACTION_PAGE_SIZE = 25;
+const ALL_TRANSACTION_FILTERS = { transfer: true, mine: true, burn: true, reward: true };
const state = {
store: null, wallet: null, walletMeta: null, status: null, address: "", balance: null,
- utxos: [], transactions: [], view: "home", timer: null,
- transactionFilters: { transfer: true, mine: false, burn: false, reward: true },
+ utxos: [], transactions: [], recentTransactions: [], view: "home", timer: null,
+ transactionFilters: { ...ALL_TRANSACTION_FILTERS },
transactionPage: { offset: 0, total: 0, hasMore: true, loading: false, error: "" },
transactionRequest: 0,
activityObserver: null,
@@ -136,6 +137,7 @@ async function fetchWalletData() {
const address = encodeAddress(state.wallet.publicKey, state.status.chain_id);
if (state.address && state.address !== address) {
state.transactions = [];
+ state.recentTransactions = [];
Object.assign(state.transactionPage, { offset: 0, total: 0, hasMore: true, loading: false, error: "" });
}
state.address = address;
@@ -144,25 +146,27 @@ async function fetchWalletData() {
const transactionLimit = Math.min(100, Math.max(TRANSACTION_PAGE_SIZE, previousTransactionCount));
const refreshTransactions = !state.transactionPage.loading;
const transactionRequest = refreshTransactions ? ++state.transactionRequest : null;
- const [balance, utxos, transactions] = await Promise.all([
+ const [balance, utxos, transactions, recentTransactions] = await Promise.all([
api(`/addresses/${encoded}/balance`),
api(`/addresses/${encoded}/utxos`),
refreshTransactions ? api(transactionPath(0, transactionLimit)) : Promise.resolve(null),
+ api(transactionPath(0, 5, ALL_TRANSACTION_FILTERS)),
]);
state.balance = balance;
state.utxos = utxos.utxos || [];
+ state.recentTransactions = Array.isArray(recentTransactions?.items) ? recentTransactions.items : [];
if (transactions && transactionRequest === state.transactionRequest) {
applyTransactionPage(transactions, true, previousTransactionCount);
}
}
-function transactionPath(offset, limit) {
+function transactionPath(offset, limit, filters = state.transactionFilters) {
const encoded = encodeURIComponent(state.address);
const params = new URLSearchParams({
- tx: String(state.transactionFilters.transfer),
- mine: String(state.transactionFilters.mine),
- burn: String(state.transactionFilters.burn),
- reward: String(state.transactionFilters.reward),
+ tx: String(filters.transfer),
+ mine: String(filters.mine),
+ burn: String(filters.burn),
+ reward: String(filters.reward),
offset: String(offset),
limit: String(limit),
});
@@ -290,9 +294,9 @@ function formatTransactionDate(item) {
}).replace(",", "");
}
-function activityList(limit, filtered = false) {
- const items = typeof limit === "number" ? state.transactions.slice(0, limit) : state.transactions;
- if (!items.length && state.transactionPage.loading) return '';
+function activityList(limit, filtered = false, source = state.transactions) {
+ const items = typeof limit === "number" ? source.slice(0, limit) : source;
+ if (!items.length && filtered && state.transactionPage.loading) return '';
if (!items.length) return filtered
? '<div class="empty">No transactions match these filters.</div>'
: '<div class="empty">No transactions yet.<br>Your new wallet is ready to use.</div>';
@@ -305,7 +309,7 @@ function activityList(limit, filtered = false) {
function renderHome() {
const readonly = state.walletMeta?.type === "readonly";
- return `${topbar()}<section>${readonly ? '<div class="mode-badge">Watch-only · signing disabled</div>' : ""}<p class="eyebrow">Available balance</p><h1 class="balance">${formatIuna(state.balance?.spendable, 6)} <span>IUNA</span></h1><p class="subbalance">${formatIuna(state.balance?.confirmed, 6)} confirmed · block ${escapeHtml(state.balance?.height)}</p><div class="actions"><button class="button" data-view="send" ${readonly ? "disabled" : ""}>${icon("send")} Send</button><button class="button secondary" data-view="receive">${icon("receive")} Receive</button></div><div class="section-head"><h2>Recent activity</h2><button data-view="activity">View all</button></div><div class="panel">${activityList(5)}</div></section>`;
+ return `${topbar()}<section>${readonly ? '<div class="mode-badge">Watch-only · signing disabled</div>' : ""}<p class="eyebrow">Available balance</p><h1 class="balance">${formatIuna(state.balance?.spendable, 6)} <span>IUNA</span></h1><p class="subbalance">${formatIuna(state.balance?.confirmed, 6)} confirmed · block ${escapeHtml(state.balance?.height)}</p><div class="actions"><button class="button" data-view="send" ${readonly ? "disabled" : ""}>${icon("send")} Send</button><button class="button secondary" data-view="receive">${icon("receive")} Receive</button></div><div class="section-head"><h2>Recent activity</h2><button data-view="activity">View all</button></div><div class="panel">${activityList(5, false, state.recentTransactions)}</div></section>`;
}
function renderSend() {
diff --git a/www/assets/iuna-ui.js b/www/assets/iuna-ui.js
@@ -125,7 +125,7 @@ window.iunaApp = function iunaApp() {
selectedTransferUtxos: [],
selectedTransferUtxoAmounts: {},
lastSelectedTransferUtxo: null,
- walletTxFilters: { transfer: true, mine: false, burn: false, reward: true },
+ walletTxFilters: { transfer: true, mine: true, burn: true, reward: true },
setupPeerAddress: "iuna.jhx.app:9444",
peerAddress: "",
flash: null,