Token auto-discovery, tx history, balance polling, EIP-6963, UI overhaul
All checks were successful
check / check (push) Successful in 14s

Major changes:
- Fetch token balances and tx history from Blockscout API (configurable)
- Remove manual token discovery (discoverTokens) in favor of Blockscout
- HD address gap scanning on mnemonic import
- Duplicate mnemonic detection on wallet add
- EIP-6963 multi-wallet discovery + selectedAddress updates in inpage
- Two-tier balance refresh: 10s while popup open, 60s background
- Fix $0.00 flash before prices load (return null when no prices)
- No-layout-shift: min-height on total value element
- Aligned balance columns (42ch address width, consistent USD column)
- All errors use flash messages instead of off-screen error divs
- Settings gear in global title bar, add-wallet moved to settings pane
- Settings wells with light grey background, configurable Blockscout URL
- Consistent "< Back" buttons top-left on all views
- Address titles (Address 1.1, 1.2, etc.) on main and detail views
- Send view shows current balance of selected asset
- Clickable affordance policy added to README
- Shortened mnemonic backup warning
- Fix broken background script constant imports
This commit is contained in:
2026-02-26 02:13:39 +07:00
parent 2b2137716c
commit 3bd2b58543
27 changed files with 978 additions and 420 deletions

View File

@@ -1,22 +1,41 @@
// Send view: collect To, Amount, Token. Then go to confirmation.
const { $, showError, hideError } = require("./helpers");
const { $, showFlash } = require("./helpers");
const { state, currentAddress } = require("../../shared/state");
const { getProvider } = require("../../shared/balances");
function updateSendBalance() {
const addr = currentAddress();
if (!addr) return;
const token = $("send-token").value;
if (token === "ETH") {
$("send-balance").textContent =
"Current balance: " + (addr.balance || "0") + " ETH";
} else {
const tb = (addr.tokenBalances || []).find(
(t) => t.address.toLowerCase() === token.toLowerCase(),
);
const symbol = tb ? tb.symbol : "?";
const bal = tb ? tb.balance || "0" : "0";
$("send-balance").textContent =
"Current balance: " + bal + " " + symbol;
}
}
function init(ctx) {
$("send-token").addEventListener("change", updateSendBalance);
$("btn-send-review").addEventListener("click", async () => {
const to = $("send-to").value.trim();
const amount = $("send-amount").value.trim();
if (!to) {
showError("send-error", "Please enter a recipient address.");
showFlash("Please enter a recipient address.");
return;
}
if (!amount || isNaN(parseFloat(amount)) || parseFloat(amount) <= 0) {
showError("send-error", "Please enter a valid amount.");
showFlash("Please enter a valid amount.");
return;
}
hideError("send-error");
// Resolve ENS if needed
let resolvedTo = to;
@@ -26,13 +45,13 @@ function init(ctx) {
const provider = getProvider(state.rpcUrl);
const resolved = await provider.resolveName(to);
if (!resolved) {
showError("send-error", "Could not resolve " + to);
showFlash("Could not resolve " + to);
return;
}
resolvedTo = resolved;
ensName = to;
} catch (e) {
showError("send-error", "Failed to resolve ENS name.");
showFlash("Failed to resolve ENS name.");
return;
}
}
@@ -53,4 +72,4 @@ function init(ctx) {
$("btn-send-back").addEventListener("click", ctx.showAddressDetail);
}
module.exports = { init };
module.exports = { init, updateSendBalance };