@hyperlane-xyz/sdk
Version:
The official SDK for the Hyperlane Network
97 lines • 3.98 kB
JavaScript
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