UNPKG

@hyperlane-xyz/sdk

Version:

The official SDK for the Hyperlane Network

65 lines 2.84 kB
import { utils } from 'ethers'; import { AbstractCcipReadIsm__factory } from '@hyperlane-xyz/core'; import { IsmType } from '../types.js'; export class OffchainLookupMetadataBuilder { type = IsmType.OFFCHAIN_LOOKUP; core; constructor(core) { this.core = core; } async build(context) { const { ism, message } = context; const provider = this.core.multiProvider.getProvider(message.parsed.destination); const contract = AbstractCcipReadIsm__factory.connect(ism.address, provider); let revertData; try { // Should revert with OffchainLookup await contract.getOffchainVerifyInfo(message.message); throw new Error('Expected OffchainLookup revert'); } catch (err) { revertData = err.error?.data || err.data; if (!revertData) throw err; } const parsed = contract.interface.parseError(revertData); if (parsed.name !== 'OffchainLookup') { throw new Error(`Unexpected error ${parsed.name}`); } const [sender, urls, callData] = parsed.args; const callDataHex = utils.hexlify(callData); const signer = this.core.multiProvider.getSigner(message.parsed.destination); for (const urlTemplate of urls) { const url = urlTemplate .replace('{sender}', sender) .replace('{data}', callDataHex); try { let responseJson; if (urlTemplate.includes('{data}')) { const res = await fetch(url); responseJson = await res.json(); } else { const signature = await signer.signMessage(utils.arrayify(offchainLookupRequestMessageHash(sender, callDataHex, urlTemplate))); const res = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ sender, data: callDataHex, signature }), }); responseJson = await res.json(); } const rawHex = responseJson.data; return rawHex.startsWith('0x') ? rawHex : `0x${rawHex}`; } catch (error) { this.core.logger.warn(`CCIP-read metadata fetch failed for ${url}: ${error}`); // try next URL } } throw new Error('Could not fetch CCIP-read metadata'); } } export function offchainLookupRequestMessageHash(sender, callData, urlTemplate) { return utils.solidityKeccak256(['string', 'address', 'bytes', 'string'], ['HYPERLANE_OFFCHAINLOOKUP', sender, callData, urlTemplate]); } //# sourceMappingURL=ccipread.js.map