Add ENS support: reverse lookup and forward resolution
All checks were successful
check / check (push) Successful in 14s

Reverse ENS lookup on balance refresh — if an address has an
ENS name, it's shown in the wallet list and address detail view.
Send form accepts ENS names in the To field (resolves before
sending). Placeholder updated to indicate ENS support.
This commit is contained in:
2026-02-25 17:09:44 +07:00
parent 0b102f49c2
commit 933c13ad1a
2 changed files with 51 additions and 5 deletions

View File

@@ -138,14 +138,24 @@ async function refreshBalances() {
const updates = [];
for (const wallet of state.wallets) {
for (const addr of wallet.addresses) {
// Fetch ETH balance
updates.push(
provider
.getBalance(addr.address)
.then((bal) => {
addr.balance = formatBalance(bal);
})
.catch(() => {}),
);
// Reverse ENS lookup
updates.push(
provider
.lookupAddress(addr.address)
.then((name) => {
addr.ensName = name || null;
})
.catch(() => {
// leave balance unchanged on error
addr.ensName = null;
}),
);
}
@@ -174,10 +184,15 @@ function renderWalletList() {
html += `</div>`;
wallet.addresses.forEach((addr, ai) => {
html += `<div class="address-row flex justify-between items-center py-1 border-b border-border-light cursor-pointer hover:bg-hover px-1" data-wallet="${wi}" data-address="${ai}">`;
html += `<div class="address-row py-1 border-b border-border-light cursor-pointer hover:bg-hover px-1" data-wallet="${wi}" data-address="${ai}">`;
if (addr.ensName) {
html += `<div class="text-xs font-bold">${addr.ensName}</div>`;
}
html += `<div class="flex justify-between items-center">`;
html += `<span class="text-xs break-all">${addr.address}</span>`;
html += `<span class="text-xs ml-1 whitespace-nowrap">${addr.balance} ETH</span>`;
html += `</div>`;
html += `</div>`;
});
html += `</div>`;
@@ -221,6 +236,13 @@ function showAddressDetail() {
$("address-copied-msg").textContent = "";
$("address-eth-balance").textContent = addr.balance;
$("address-usd-value").textContent = "";
const ensEl = $("address-ens");
if (addr.ensName) {
ensEl.textContent = addr.ensName;
ensEl.classList.remove("hidden");
} else {
ensEl.classList.add("hidden");
}
updateTokenList(addr);
updateSendTokenSelect(addr);
showView("address");
@@ -442,7 +464,7 @@ async function init() {
});
// -- Send --
$("btn-send-confirm").addEventListener("click", () => {
$("btn-send-confirm").addEventListener("click", async () => {
const to = $("send-to").value.trim();
const amount = $("send-amount").value.trim();
if (!to) {
@@ -455,9 +477,32 @@ async function init() {
$("send-status").classList.remove("hidden");
return;
}
// Resolve ENS name if it looks like one
let resolvedTo = to;
if (to.includes(".") && !to.startsWith("0x")) {
const statusEl = $("send-status");
statusEl.textContent = "Resolving " + to + "...";
statusEl.classList.remove("hidden");
try {
const provider = getProvider();
const resolved = await provider.resolveName(to);
if (!resolved) {
showError("send-status", "Could not resolve " + to);
return;
}
resolvedTo = resolved;
statusEl.textContent = to + " = " + resolvedTo;
} catch (e) {
showError("send-status", "Failed to resolve ENS name.");
return;
}
}
// TODO: prompt for password, decrypt key, construct and send transaction
const el = $("send-status");
el.textContent = "Sent! (stub — password/signing not yet implemented)";
el.textContent =
"Sending to " +
resolvedTo +
" (stub — password/signing not yet implemented)";
el.classList.remove("hidden");
});