function setRecentTransactionsForWalletState(state) {
recentTransactionsCacheReadId += 1;
latestTransactionsSyncId += 1;
clearRecentTransactionsRows();
stopLatestDashboardTransactionsPolling();
if (state === "registered") {
setRecentTransactionsState("");
resetLatestDashboardTransactionsMemory();
updateLatestDashboardTransactionsPolling();
startBackgroundTransactionSync();
return;
}
stopBackgroundTransactionSync();
resetLatestDashboardTransactionsMemory();
if (state === "checking") {
setRecentTransactionsState("Checking address registration before loading transactions.");
return;
}
if (state === "unregistered") {
setRecentTransactionsState("Address registration required before transactions can appear.");
return;
}
setRecentTransactionsState("Load a wallet to view recent transactions.");
}
function resetBalances(message = "Load wallet", statusMessage = "Balances refresh while dashboard is open.") {
activeWalletBalances = [];
if (typeof refreshTransferAssetOptions === "function") {
refreshTransferAssetOptions();
}
if (typeof refreshActiveTransactionFormAfterWalletData === "function") {
refreshActiveTransactionFormAfterWalletData();
}
if (baseBalanceLabel) {
baseBalanceLabel.textContent = `${activeBaseCoin()} Balance`;
}
if (clcBalance) {
clcBalance.textContent = message;
}
if (tokenBalances) {
tokenBalances.innerHTML = `
Token Balances
No wallet loaded.
`;
}
dashboardLastBalanceStatus = "";
setBalanceStatus(statusMessage);
}
async function refreshDashboardBalances({ force = false, quiet = false } = {}) {
if (!walletLoaded || !registrationRegistered || currentView !== "dashboard" || balanceRefreshInFlight) {
return false;
}
const invoke = window.__TAURI__?.core?.invoke;
const broadcastNode = activeBroadcastNode();
if (!invoke || !broadcastNode) {
return false;
}
balanceRefreshInFlight = true;
const requestId = ++balanceRefreshRequestId;
if (force && !quiet) {
setBalanceStatus("Refreshing balances...");
}
try {
const balances = await invoke("get_active_wallet_balances", {
broadcastNode
});
if (requestId !== balanceRefreshRequestId || !walletLoaded) {
return false;
}
renderBalances(balances);
dashboardLastBalanceStatus = `Updated ${new Date().toLocaleTimeString()}`;
setBalanceStatus(dashboardLastBalanceStatus, "success");
return true;
} catch (error) {
if (requestId !== balanceRefreshRequestId || !walletLoaded) {
return false;
}
setBalanceStatus(String(error), "error");
return false;
} finally {
if (requestId === balanceRefreshRequestId) {
balanceRefreshInFlight = false;
}
}
}
function startBalanceRefresh({ immediate = true } = {}) {
if (balanceRefreshTimer || !walletLoaded || !registrationRegistered || currentView !== "dashboard") {
return;
}
if (immediate) {
refreshDashboardBalances({ force: true });
}
balanceRefreshTimer = setInterval(() => {
refreshDashboardBalances();
}, BALANCE_REFRESH_MS);
}
function stopBalanceRefresh() {
if (balanceRefreshTimer) {
clearInterval(balanceRefreshTimer);
balanceRefreshTimer = null;
}
}
function updateBalanceRefreshState() {
if (walletLoaded && registrationRegistered && currentView === "dashboard") {
startBalanceRefresh();
return;
}
stopBalanceRefresh();
}
function restoreLatestDashboardTransactionsFromMemory() {
if (!latestDashboardTransactionRecords.size || !latestDashboardTxids.length) {
return false;
}
const latestCache = { transactions: Object.fromEntries(latestDashboardTransactionRecords) };
updateTransactionCacheChainStatus(latestCache);
latestDashboardTransactionRecords = new Map(Object.entries(latestCache.transactions));
renderRecentTransactions(normalizeRecentTransactionRecords(
transactionRecordsForTxids(latestCache, latestDashboardTxids),
{ preserveOrder: true }
));
setRecentTransactionsState("");
return true;
}
async function startRegisteredDashboardLoadSequence({ resetTransactions = false, quiet = false } = {}) {
const loadId = ++dashboardRegisteredLoadId;
stopLatestDashboardTransactionsPolling();
stopBalanceRefresh();
if (resetTransactions) {
resetLatestDashboardTransactionsMemory();
}
const restoredTransactions = restoreLatestDashboardTransactionsFromMemory();
if (!restoredTransactions && !quiet) {
setRecentTransactionsForWalletState("checking");
}
if (!walletLoaded || !registrationRegistered || currentView !== "dashboard") {
return;
}
if (dashboardLastBalanceStatus) {
setBalanceStatus(dashboardLastBalanceStatus, "success");
}
await refreshDashboardBalances({ force: true, quiet: quiet || Boolean(dashboardLastBalanceStatus) });
if (
loadId !== dashboardRegisteredLoadId ||
!walletLoaded ||
!registrationRegistered ||
currentView !== "dashboard"
) {
return;
}
startBalanceRefresh({ immediate: false });
if (!restoredTransactions) {
setRecentTransactionsForWalletState("registered");
return;
}
updateLatestDashboardTransactionsPolling();
startBackgroundTransactionSync();
}
function startNetworkInfoRefresh() {
if (networkInfoRefreshTimer || !walletLoaded || currentView !== "dashboard") {
return;
}
refreshNetworkInfo({ target: "dashboard" });
networkInfoRefreshTimer = setInterval(() => {
refreshNetworkInfo({ target: "dashboard" });
}, NETWORK_INFO_REFRESH_MS);
}
function stopNetworkInfoRefresh() {
if (networkInfoRefreshTimer) {
clearInterval(networkInfoRefreshTimer);
networkInfoRefreshTimer = null;
}
}
function updateNetworkInfoRefreshState() {
if (walletLoaded && currentView === "dashboard") {
startNetworkInfoRefresh();
return;
}
stopNetworkInfoRefresh();
}
function startNodeInfoRefresh() {
if (nodeInfoRefreshTimer || !walletLoaded) {
renderNodeInfo(null);
return;
}
refreshNetworkInfo({ target: "node", force: true });
nodeInfoRefreshTimer = setInterval(() => {
refreshNetworkInfo({ target: "node", force: true });
}, NODE_INFO_REFRESH_MS);
}
function stopNodeInfoRefresh() {
if (nodeInfoRefreshTimer) {
clearInterval(nodeInfoRefreshTimer);
nodeInfoRefreshTimer = null;
}
}
function activeBroadcastNode() {
return broadcastNodeButton?.value || broadcastNodeButton?.dataset.broadcastNode || broadcastNodeButton?.textContent?.trim() || "";
}
function setRegistrationState(state) {
const states = ["registered", "unregistered", "checking"];
registrationBadge?.classList.remove(...states);
registrationAction?.classList.remove(...states);
registrationNotice?.classList.remove(...states);
if (state === "registered") {
registrationRegistered = true;
registrationBadge && (registrationBadge.textContent = "Registered");
registrationBadge?.classList.add("registered");
if (registrationNotice) {
registrationNotice.textContent = "Address registered. This wallet can receive coins and tokens.";
registrationNotice.classList.add("registered");
}
if (registrationAction) {
registrationAction.textContent = "Address Registered";
registrationAction.disabled = true;
registrationAction.classList.add("registered");
}
startRegisteredDashboardLoadSequence();
updateHistoryRefreshState();
updateNetworkInfoRefreshState();
refreshReceivePage();
if (typeof refreshActiveTransactionFormAfterWalletData === "function") {
refreshActiveTransactionFormAfterWalletData();
}
return;
}
if (state === "checking") {
registrationBadge && (registrationBadge.textContent = "Checking");
registrationBadge?.classList.add("checking");
if (registrationNotice) {
registrationNotice.textContent = "Checking whether this address can receive coins and tokens.";
registrationNotice.classList.add("checking");
}
if (registrationAction) {
registrationAction.textContent = "Checking...";
registrationAction.disabled = true;
registrationAction.classList.add("checking");
}
dashboardRegisteredLoadId += 1;
stopBalanceRefresh();
setRecentTransactionsForWalletState("checking");
updateHistoryRefreshState();
refreshReceivePage();
return;
}
registrationRegistered = false;
registrationBadge && (registrationBadge.textContent = "Unregistered");
registrationBadge?.classList.add("unregistered");
if (registrationNotice) {
registrationNotice.textContent = "Address must be registered before this wallet can receive coins or tokens.";
registrationNotice.classList.add("unregistered");
}
if (registrationAction) {
registrationAction.textContent = "Register Address";
registrationAction.disabled = false;
registrationAction.classList.add("unregistered");
}
dashboardRegisteredLoadId += 1;
stopBalanceRefresh();
setRecentTransactionsForWalletState("unregistered");
updateHistoryRefreshState();
updateNetworkInfoRefreshState();
refreshReceivePage();
}
async function checkWalletRegistrationOnce() {
if (!walletLoaded || registrationRegistered || registrationCheckInFlight) {
return;
}
const invoke = window.__TAURI__?.core?.invoke;
const broadcastNode = activeBroadcastNode();
if (!invoke || !broadcastNode) {
setRegistrationState("unregistered");
return;
}
registrationCheckInFlight = true;
const requestId = ++registrationRequestId;
setRegistrationState("checking");
try {
const status = await invoke("check_wallet_registration", { broadcastNode });
if (requestId !== registrationRequestId || !walletLoaded) {
return;
}
setRegistrationState(status?.registered ? "registered" : "unregistered");
} catch (_) {
if (requestId !== registrationRequestId || !walletLoaded) {
return;
}
setRegistrationState("unregistered");
} finally {
if (requestId === registrationRequestId) {
registrationCheckInFlight = false;
}
}
}
async function registerActiveWallet() {
if (!walletLoaded || registrationRegistered || registrationCheckInFlight) {
return;
}
const invoke = window.__TAURI__?.core?.invoke;
const broadcastNode = activeBroadcastNode();
if (!invoke || !broadcastNode) {
setRegistrationState("unregistered");
return;
}
registrationCheckInFlight = true;
const requestId = ++registrationRequestId;
setRegistrationState("checking");
try {
const status = await invoke("register_active_wallet", { broadcastNode });
if (requestId !== registrationRequestId || !walletLoaded) {
return;
}
setRegistrationState(status?.registered ? "registered" : "unregistered");
} catch (_) {
if (requestId !== registrationRequestId || !walletLoaded) {
return;
}
setRegistrationState("unregistered");
} finally {
if (requestId === registrationRequestId) {
registrationCheckInFlight = false;
}
}
}