UNPKG

@celo/explorer

Version:
136 lines (135 loc) 5.26 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()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.LogExplorer = exports.newLogExplorer = void 0; const viem_1 = require("viem"); const base_1 = require("./base"); function newLogExplorer(kit) { return __awaiter(this, void 0, void 0, function* () { return new LogExplorer(kit, yield (0, base_1.obtainKitContractDetails)(kit)); }); } exports.newLogExplorer = newLogExplorer; class LogExplorer { constructor(kit, contractDetails) { this.kit = kit; this.contractDetails = contractDetails; this.addressMapping = (0, base_1.mapFromPairs)(contractDetails.map((cd) => [ cd.address, { details: cd, logMapping: (0, base_1.mapFromPairs)(cd.jsonInterface .filter((ad) => ad.type === 'event') .map((ad) => [ad.signature, ad])), }, ])); for (const cd of contractDetails) { const fnMapping = new Map(); for (const abiDef of cd.jsonInterface) { if (abiDef.type === 'event') { fnMapping.set(abiDef.signature, abiDef); } } this.addressMapping.set(cd.address, { details: cd, logMapping: fnMapping, }); } } fetchTxReceipt(txhash) { return __awaiter(this, void 0, void 0, function* () { try { return yield this.kit.connection.viemClient.getTransactionReceipt({ hash: txhash, }); } catch (_a) { return null; } }); } getKnownLogs(tx) { const res = []; for (const log of tx.logs || []) { const event = this.tryParseLog(log); if (event != null) { res.push(event); } } return res; } tryParseLog(log) { if (log.topics.length === 0) { return null; } const contractMapping = this.addressMapping.get(log.address); if (contractMapping == null) { return null; } const logSignature = log.topics[0]; if (logSignature == null) { return null; } const matchedAbi = contractMapping.logMapping.get(logSignature); if (matchedAbi == null) { return null; } const eventInputs = (matchedAbi.inputs || []).map((input) => { var _a; return (Object.assign(Object.assign({}, input), { indexed: (_a = input.indexed) !== null && _a !== void 0 ? _a : false })); }); const eventAbi = [ { type: 'event', name: matchedAbi.name || 'Event', inputs: eventInputs }, ]; // toEventSelector expands tuple components into the canonical signature; // joining raw input types would hash 'Event(tuple,...)' and never match const eventSigHash = (0, viem_1.toEventSelector)(eventAbi[0]); const fullTopics = [eventSigHash, ...log.topics.slice(1)]; try { const result = (0, viem_1.decodeEventLog)({ abi: eventAbi, data: (log.data || '0x'), topics: fullTopics, }); const decoded = Object.assign({}, result.args); // bigint to string for backward compat for (const key of Object.keys(decoded)) { if (typeof decoded[key] === 'bigint') decoded[key] = decoded[key].toString(); } // pending logs carry null block/index fields — Number(null) would // silently report block 0 if (log.blockNumber == null || log.logIndex == null || log.transactionIndex == null) { return null; } const logEvent = { address: log.address, blockHash: log.blockHash, blockNumber: Number(log.blockNumber), logIndex: log.logIndex, transactionIndex: log.transactionIndex, transactionHash: log.transactionHash, returnValues: decoded, event: matchedAbi.name, signature: logSignature, raw: { data: log.data || '', topics: log.topics || [], }, }; return logEvent; } catch (_a) { return null; } } } exports.LogExplorer = LogExplorer;