@ens-rush-resolution/auto-resolve
Version:
Auto-detection and resolution of Ethereum addresses in web pages
111 lines • 3.8 kB
JavaScript
// src/index.ts
import { resolve } from "@ens-rush-resolution/core";
var ETHEREUM_ADDRESS_REGEX = /0x[a-fA-F0-9]{40}/g;
function findAddressesInTextNode(textNode) {
const text = textNode.textContent || "";
const addresses = [];
let match;
ETHEREUM_ADDRESS_REGEX.lastIndex = 0;
while ((match = ETHEREUM_ADDRESS_REGEX.exec(text)) !== null) {
addresses.push({
address: match[0],
element: textNode.parentElement,
textNode,
startIndex: match.index,
endIndex: match.index + match[0].length
});
}
return addresses;
}
function findAllAddresses(root = document.body) {
const walker = document.createTreeWalker(
root,
NodeFilter.SHOW_TEXT,
{
acceptNode(node2) {
let parent = node2.parentElement;
while (parent) {
if (parent.dataset.ensRush === "false" || parent.dataset.ensRush === "skip") {
return NodeFilter.FILTER_REJECT;
}
parent = parent.parentElement;
}
return NodeFilter.FILTER_ACCEPT;
}
}
);
const allAddresses = [];
let node;
while (node = walker.nextNode()) {
const textNode = node;
const addresses = findAddressesInTextNode(textNode);
allAddresses.push(...addresses);
}
return allAddresses;
}
function updateAddressInDOM(addressElement, ensName) {
const { textNode, startIndex, endIndex, address } = addressElement;
const text = textNode.textContent || "";
if (!ensName) {
return;
}
const beforeText = text.substring(0, startIndex);
const afterText = text.substring(endIndex);
const ensSpan = document.createElement("span");
ensSpan.textContent = ensName;
ensSpan.title = address;
const parentElement = textNode.parentElement;
if (beforeText) {
parentElement.insertBefore(document.createTextNode(beforeText), textNode);
}
parentElement.insertBefore(ensSpan, textNode);
if (afterText) {
parentElement.insertBefore(document.createTextNode(afterText), textNode);
}
parentElement.removeChild(textNode);
}
async function autoResolve(options = {}) {
const { selector, onResolve, ...resolveOptions } = options;
const root = selector ? document.querySelector(selector) : document.body;
if (!root) {
console.warn("Auto-resolve: Root element not found");
return;
}
const addressElements = findAllAddresses(root);
if (addressElements.length === 0) {
console.log("Auto-resolve: No Ethereum addresses found");
return;
}
const uniqueAddresses = [...new Set(addressElements.map((ae) => ae.address))];
console.log(`Auto-resolve: Found ${addressElements.length} addresses (${uniqueAddresses.length} unique)`);
try {
const resolutions = await resolve(uniqueAddresses, resolveOptions);
const resolutionMap = new Map(resolutions.map((r) => [r.address, r.name]));
addressElements.forEach((addressElement) => {
const ensName = resolutionMap.get(addressElement.address);
if (onResolve) {
onResolve(addressElement.address, ensName || null, addressElement.element);
}
updateAddressInDOM(addressElement, ensName || null);
});
const resolvedCount = resolutions.filter((r) => r.name).length;
console.log(`Auto-resolve: Resolved ${resolvedCount}/${uniqueAddresses.length} addresses to ENS names`);
} catch (error) {
console.error("Auto-resolve: Failed to resolve addresses", error);
}
}
if (typeof window !== "undefined") {
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", () => {
console.log("Auto-resolve: DOM loaded, starting auto-resolution...");
autoResolve();
});
} else {
console.log("Auto-resolve: DOM already loaded, starting auto-resolution...");
autoResolve();
}
}
export {
autoResolve
};
//# sourceMappingURL=index.mjs.map