@hyperlane-xyz/sdk
Version:
The official SDK for the Hyperlane Network
75 lines • 2.61 kB
JavaScript
import { compareVersions } from 'compare-versions';
import { chunk, isNullish, strip0x } from '@hyperlane-xyz/utils';
export function isValidContractVersion(currentVersion, targetVersion) {
return compareVersions(currentVersion, targetVersion) >= 0;
}
function isRecord(value) {
return typeof value === 'object' && !isNullish(value);
}
function getErrorMessage(error) {
return error instanceof Error
? error.message
: isRecord(error) && typeof error.message === 'string'
? error.message
: undefined;
}
function isEmptyProviderResponse(error) {
let current = error;
while (isRecord(current)) {
// Assumes the originating provider call was an eth_call probe. The
// HyperlaneJsonRpcProvider also emits this message for empty getBalance,
// getBlock, and getBlockNumber responses.
if (getErrorMessage(current) === 'Invalid response from provider') {
return true;
}
current = current.cause;
}
return false;
}
function findCallException(error) {
let current = error;
while (isRecord(current)) {
if (current.code === 'CALL_EXCEPTION')
return current;
current = current.cause;
}
return undefined;
}
export function isMissingSelectorCallException(error) {
if (!isRecord(error))
return false;
if (isEmptyProviderResponse(error))
return true;
const callException = findCallException(error);
if (!callException)
return false;
const nestedError = isRecord(callException.error)
? callException.error
: undefined;
const data = typeof callException.data === 'string'
? callException.data
: nestedError?.data;
if (data === '0x')
return true;
// Some ethers/provider combinations only expose empty return data in the
// formatted message.
return (typeof callException.message === 'string' &&
callException.message.includes('data="0x"'));
}
export function throwIfNotMissingSelector(error) {
if (!isMissingSelectorCallException(error))
throw error;
}
export async function contractHasString(provider, address, searchFor) {
const code = await provider.getCode(address);
const hexString = strip0x(Buffer.from(searchFor).toString('hex'));
// largest stack operation is PUSH32 https://www.evm.codes/?fork=osaka#7f
const chunks = chunk(hexString, 32 * 2);
for (const chunk of chunks) {
if (!code.includes(chunk)) {
return false;
}
}
return true;
}
//# sourceMappingURL=contract.js.map