UNPKG

@hyperlane-xyz/sdk

Version:

The official SDK for the Hyperlane Network

97 lines 3.98 kB
import { assert } from '@hyperlane-xyz/utils'; import { assertIsContractAddress, isContractAddress, } from '../../contracts/contracts.js'; function toNumber(value, field) { if (typeof value === 'number') { assert(Number.isSafeInteger(value), `${field} is not a safe integer: ${value}`); return value; } if (typeof value === 'bigint') { const num = Number(value); assert(Number.isFinite(num) && BigInt(num) === value, `${field} bigint value ${value} exceeds safe integer range`); return num; } if (typeof value === 'string') { assert(/^0x[0-9a-fA-F]+$/.test(value) || /^[0-9]+$/.test(value), `${field} string "${value}" is not a valid hex or decimal number`); const num = value.startsWith('0x') ? parseInt(value, 16) : parseInt(value, 10); assert(!Number.isNaN(num), `${field} parsed to NaN from "${value}"`); assert(Number.isSafeInteger(num), `${field} string value "${value}" exceeds safe integer range`); return num; } assert(false, `Unable to convert ${field} to number`); } function toString(value, field) { assert(typeof value === 'string', `Unable to convert ${field} to string`); return value; } function toStringArray(value, field) { assert(Array.isArray(value) && value.every((v) => typeof v === 'string'), `Unable to convert ${field} to string[]`); return value; } // calling getCode until the creation block is found export async function getContractCreationBlockFromRpc(chain, contractAddress, multiProvider) { await assertIsContractAddress(multiProvider, chain, contractAddress); const provider = multiProvider.getProvider(chain); const latestBlock = await provider.getBlockNumber(); let low = 0; let high = latestBlock; let creationBlock = latestBlock; while (low <= high) { const mid = Math.floor((low + high) / 2); const isContract = await isContractAddress(multiProvider, chain, contractAddress, mid); if (isContract) { creationBlock = mid; high = mid - 1; } else { low = mid + 1; } } return creationBlock; } export async function getLogsFromRpc({ chain, contractAddress, multiProvider, fromBlock, topic, toBlock, range = 500, }) { const provider = multiProvider.getProvider(chain); let currentStartBlock = fromBlock; const endBlock = toBlock ?? (await provider.getBlockNumber()); const logs = []; while (currentStartBlock <= endBlock) { const currentEndBlock = currentStartBlock + range < endBlock ? currentStartBlock + range : endBlock; const currentLogs = await provider.getLogs({ address: contractAddress, fromBlock: currentStartBlock, toBlock: currentEndBlock, topics: [topic], }); logs.push(...currentLogs); // +1 because getLogs range is inclusive currentStartBlock += range + 1; } return logs.map((rawLog) => { return { address: toString(rawLog.address, 'address'), blockNumber: toNumber(rawLog.blockNumber, 'blockNumber'), data: toString(rawLog.data, 'data'), logIndex: toNumber(rawLog.logIndex, 'logIndex'), topics: toStringArray(rawLog.topics, 'topics'), transactionHash: toString(rawLog.transactionHash, 'transactionHash'), transactionIndex: toNumber(rawLog.transactionIndex, 'transactionIndex'), }; }); } export function viemLogFromGetEventLogsResponse(log) { return { address: log.address, data: log.data, blockNumber: BigInt(log.blockNumber), transactionHash: log.transactionHash, logIndex: Number(log.logIndex), transactionIndex: Number(log.transactionIndex), topics: log.topics, blockHash: null, removed: false, }; } //# sourceMappingURL=utils.js.map