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