UNPKG

@agentek/tools

Version:

Blockchain tools for AI agents

94 lines 3.89 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.resolveInputToToken = resolveInputToToken; exports.enrichFromListByAddress = enrichFromListByAddress; exports.toBaseUnits = toBaseUnits; exports.asToken = asToken; const viem_1 = require("viem"); const fetch_js_1 = require("../utils/fetch.js"); let _tokenListCache = null; async function loadTokenList() { const now = Date.now(); if (_tokenListCache && now - _tokenListCache.fetchedAt < 5 * 60_000) return _tokenListCache.tokens; const res = await fetch("https://assets.zamm.finance/tokenlist.json", { signal: AbortSignal.timeout(12_000), }); await (0, fetch_js_1.assertOkResponse)(res, "Failed to fetch tokenlist"); const json = await res.json(); const tokens = Array.isArray(json?.tokens) ? json.tokens : []; _tokenListCache = { fetchedAt: now, tokens }; return tokens; } async function resolveInputToToken(input, chainId) { if (typeof input !== "string") { const enriched = await enrichFromListByAddress(input.address, chainId, input.id); if (enriched) return enriched; return { address: input.address, id: input.id, standard: input.id !== undefined ? "ERC6909" : "ERC20", decimals: input.id !== undefined ? 0 : 18, }; } const sym = input.trim().toUpperCase(); const entry = await findTokenListEntryBySymbol(sym, chainId); if (!entry) throw new Error(`Symbol "${sym}" not found on chainId ${chainId}.`); const standard = entry.extensions?.standard === "ERC6909" ? "ERC6909" : "ERC20"; const idStr = entry.extensions?.id; const id = idStr !== undefined ? BigInt(idStr) : undefined; const decimals = typeof entry.decimals === "number" ? entry.decimals : standard === "ERC6909" ? 0 : 18; return { address: entry.address, id, standard, decimals, symbol: entry.symbol, }; } async function findTokenListEntryBySymbol(symbol, chainId) { const list = await loadTokenList(); const candidates = list.filter((t) => t.chainId === chainId && t.symbol?.toUpperCase() === symbol.toUpperCase()); candidates.sort((a, b) => { const aIs20 = a.extensions?.standard !== "ERC6909"; const bIs20 = b.extensions?.standard !== "ERC6909"; return Number(bIs20) - Number(aIs20); // prefer ERC20 }); return candidates[0]; } async function enrichFromListByAddress(address, chainId, id) { const list = await loadTokenList(); const entry = list.find((t) => t.chainId === chainId && t.address.toLowerCase() === address.toLowerCase()); if (!entry) return null; const standard = entry.extensions?.standard === "ERC6909" || id !== undefined ? "ERC6909" : "ERC20"; const decimals = typeof entry.decimals === "number" ? entry.decimals : standard === "ERC6909" ? 0 : 18; const entryId = entry.extensions?.id !== undefined ? BigInt(entry.extensions.id) : undefined; return { address, id: id ?? entryId, standard, decimals, symbol: entry.symbol, }; } function toBaseUnits(amountStr, token) { if (!/^\d+(\.\d+)?$/.test(amountStr)) throw new Error(`Invalid amount "${amountStr}". Use a numeric value.`); if (token.standard === "ERC20") { return (0, viem_1.parseUnits)(amountStr, token.decimals ?? 18); } if ((token.decimals ?? 0) > 0) { return (0, viem_1.parseUnits)(amountStr, token.decimals); } if (amountStr.includes(".")) { throw new Error(`Amount "${amountStr}" must be an integer for ERC6909 token id ${token.id ?? "(unspecified)"}`); } return BigInt(amountStr); } function asToken(t) { return t.id !== undefined ? { address: t.address, id: t.id } : { address: t.address }; } //# sourceMappingURL=utils.js.map