With debug mode on, debugFetch logged every request's full URL and body, so an RPC endpoint with an API key in its path or query string printed that key to the console on every request. It now logs the HTTP method, the URL's origin and, for a JSON-RPC body, the method name. The balance refresh and token lookup log the RPC endpoint by its origin too. Failed RPC calls print ethers' short message, since its full message for an HTTP error carries the request URL. A failed endpoint check in settings prints the endpoint's origin, since fetch's error for a URL with a user name and password carries the whole URL. The README's DEBUG Mode Policy says what debug mode logs. Model: opus-5-5
66 lines
2.0 KiB
JavaScript
66 lines
2.0 KiB
JavaScript
// Cached ENS reverse resolution.
|
|
// Resolves addresses to ENS names via ethers provider.lookupAddress(),
|
|
// caching results in localStorage with a 12-hour TTL.
|
|
//
|
|
// POPUP ONLY. localStorage does not exist in the Chrome MV3 service worker,
|
|
// so this module must not be pulled into src/background/. Anything the
|
|
// background context needs to cache goes in extension storage instead.
|
|
|
|
const { getProvider } = require("./balances");
|
|
const { log } = require("./log");
|
|
|
|
const CACHE_TTL_MS = 43200000; // 12 hours
|
|
const CACHE_PREFIX = "ens:";
|
|
|
|
function getCached(address) {
|
|
const key = CACHE_PREFIX + address.toLowerCase();
|
|
try {
|
|
const raw = localStorage.getItem(key);
|
|
if (!raw) return undefined;
|
|
const entry = JSON.parse(raw);
|
|
if (Date.now() - entry.ts < CACHE_TTL_MS) {
|
|
return entry.name;
|
|
}
|
|
} catch {
|
|
// Corrupt cache entry — treat as miss.
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
function setCache(address, name) {
|
|
const key = CACHE_PREFIX + address.toLowerCase();
|
|
localStorage.setItem(key, JSON.stringify({ name, ts: Date.now() }));
|
|
}
|
|
|
|
async function resolveEnsName(address, rpcUrl, networkId) {
|
|
const cached = getCached(address);
|
|
if (cached !== undefined) return cached;
|
|
|
|
const provider = getProvider(rpcUrl, networkId);
|
|
try {
|
|
const name = (await provider.lookupAddress(address)) || null;
|
|
setCache(address, name);
|
|
return name;
|
|
} catch (e) {
|
|
log.errorf(
|
|
"ENS reverse lookup failed",
|
|
address,
|
|
e.shortMessage || e.message,
|
|
);
|
|
// Don't cache failures — let subsequent lookups retry
|
|
return null;
|
|
}
|
|
}
|
|
|
|
async function resolveEnsNames(addresses, rpcUrl, networkId) {
|
|
const results = new Map();
|
|
await Promise.all(
|
|
addresses.map(async (addr) => {
|
|
results.set(addr, await resolveEnsName(addr, rpcUrl, networkId));
|
|
}),
|
|
);
|
|
return results;
|
|
}
|
|
|
|
module.exports = { resolveEnsName, resolveEnsNames };
|