UNPKG

@celo/explorer

Version:
89 lines (88 loc) 3.82 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.fetchAbiFromExplorer = exports.abiToContractMapping = void 0; const cross_fetch_1 = __importDefault(require("cross-fetch")); const viem_1 = require("viem"); const base_1 = require("./base"); const sourcify_1 = require("./sourcify"); /** * Keyless Blockscout API base URL per chain id. Blockscout exposes the * Etherscan-compatible `getsourcecode` action and holds Celo's verifications. */ const BLOCKSCOUT_API_BY_CHAIN = { 42220: 'https://celo.blockscout.com/api', 11142220: 'https://celo-sepolia.blockscout.com/api', }; /** * Build a ContractMapping (selector -> ABI item) from a raw ABI, mirroring the * Sourcify Metadata path so downstream decoding behaves identically. */ function abiToContractMapping(name, address, abi) { const fnMapping = (0, base_1.mapFromPairs)(abi .filter((item) => item.type === 'function') .map((item) => { const sig = `${item.name}(${(item.inputs || []) .map((i) => (0, sourcify_1.formatAbiInputType)(i)) .join(',')})`; return Object.assign(Object.assign({}, item), { signature: (0, viem_1.toFunctionSelector)(sig) }); }) .map((item) => [item.signature, item])); return { details: { name: name || 'Unknown', address, jsonInterface: abi, isCore: false }, fnMapping, }; } exports.abiToContractMapping = abiToContractMapping; /** * Fetch a verified contract's ABI from the chain's Blockscout instance. * Returns null when the chain is unsupported, the request fails, or the * contract is not verified. */ function fetchAbiFromExplorer(connection, address) { return __awaiter(this, void 0, void 0, function* () { let chainId; try { chainId = yield connection.viemClient.getChainId(); } catch (_a) { return null; } const base = BLOCKSCOUT_API_BY_CHAIN[chainId]; if (!base) { return null; } try { const resp = yield (0, cross_fetch_1.default)(`${base}?module=contract&action=getsourcecode&address=${address}`); if (!resp.ok) { return null; } const data = yield resp.json(); const result = Array.isArray(data === null || data === void 0 ? void 0 : data.result) ? data.result[0] : undefined; const rawAbi = result === null || result === void 0 ? void 0 : result.ABI; if (!rawAbi || rawAbi === 'Contract source code not verified') { return null; } const abi = JSON.parse(rawAbi); if (!Array.isArray(abi) || abi.length === 0) { return null; } return { name: (result === null || result === void 0 ? void 0 : result.ContractName) || 'Unknown', abi }; } catch (_b) { return null; } }); } exports.fetchAbiFromExplorer = fetchAbiFromExplorer;