viem
Version:
126 lines • 5.42 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getAbiItem = getAbiItem;
exports.isArgOfType = isArgOfType;
exports.getAmbiguousTypes = getAmbiguousTypes;
const abi_js_1 = require("../../errors/abi.js");
const isHex_js_1 = require("../../utils/data/isHex.js");
const isAddress_js_1 = require("../address/isAddress.js");
const toEventSelector_js_1 = require("../hash/toEventSelector.js");
const toFunctionSelector_js_1 = require("../hash/toFunctionSelector.js");
function getAbiItem(parameters) {
const { abi, args = [], name } = parameters;
const isSelector = (0, isHex_js_1.isHex)(name, { strict: false });
const abiItems = abi.filter((abiItem) => {
if (isSelector) {
if (abiItem.type === 'function')
return (0, toFunctionSelector_js_1.toFunctionSelector)(abiItem) === name;
if (abiItem.type === 'event')
return (0, toEventSelector_js_1.toEventSelector)(abiItem) === name;
return false;
}
return 'name' in abiItem && abiItem.name === name;
});
if (abiItems.length === 0)
return undefined;
if (abiItems.length === 1)
return abiItems[0];
let matchedAbiItem = undefined;
for (const abiItem of abiItems) {
if (!('inputs' in abiItem))
continue;
if (!args || args.length === 0) {
if (!abiItem.inputs || abiItem.inputs.length === 0)
return abiItem;
continue;
}
if (!abiItem.inputs)
continue;
if (abiItem.inputs.length === 0)
continue;
if (abiItem.inputs.length !== args.length)
continue;
const matched = args.every((arg, index) => {
const abiParameter = 'inputs' in abiItem && abiItem.inputs[index];
if (!abiParameter)
return false;
return isArgOfType(arg, abiParameter);
});
if (matched) {
if (matchedAbiItem &&
'inputs' in matchedAbiItem &&
matchedAbiItem.inputs) {
const ambiguousTypes = getAmbiguousTypes(abiItem.inputs, matchedAbiItem.inputs, args);
if (ambiguousTypes)
throw new abi_js_1.AbiItemAmbiguityError({
abiItem,
type: ambiguousTypes[0],
}, {
abiItem: matchedAbiItem,
type: ambiguousTypes[1],
});
}
matchedAbiItem = abiItem;
}
}
if (matchedAbiItem)
return matchedAbiItem;
return abiItems[0];
}
function isArgOfType(arg, abiParameter) {
const argType = typeof arg;
const abiParameterType = abiParameter.type;
switch (abiParameterType) {
case 'address':
return (0, isAddress_js_1.isAddress)(arg, { strict: false });
case 'bool':
return argType === 'boolean';
case 'function':
return argType === 'string';
case 'string':
return argType === 'string';
default: {
if (abiParameterType === 'tuple' && 'components' in abiParameter)
return Object.values(abiParameter.components).every((component, index) => {
return isArgOfType(Object.values(arg)[index], component);
});
if (/^u?int(8|16|24|32|40|48|56|64|72|80|88|96|104|112|120|128|136|144|152|160|168|176|184|192|200|208|216|224|232|240|248|256)?$/.test(abiParameterType))
return argType === 'number' || argType === 'bigint';
if (/^bytes([1-9]|1[0-9]|2[0-9]|3[0-2])?$/.test(abiParameterType))
return argType === 'string' || arg instanceof Uint8Array;
if (/[a-z]+[1-9]{0,3}(\[[0-9]{0,}\])+$/.test(abiParameterType)) {
return (Array.isArray(arg) &&
arg.every((x) => isArgOfType(x, {
...abiParameter,
type: abiParameterType.replace(/(\[[0-9]{0,}\])$/, ''),
})));
}
return false;
}
}
}
function getAmbiguousTypes(sourceParameters, targetParameters, args) {
for (const parameterIndex in sourceParameters) {
const sourceParameter = sourceParameters[parameterIndex];
const targetParameter = targetParameters[parameterIndex];
if (sourceParameter.type === 'tuple' &&
targetParameter.type === 'tuple' &&
'components' in sourceParameter &&
'components' in targetParameter)
return getAmbiguousTypes(sourceParameter.components, targetParameter.components, args[parameterIndex]);
const types = [sourceParameter.type, targetParameter.type];
const ambiguous = (() => {
if (types.includes('address') && types.includes('bytes20'))
return true;
if (types.includes('address') && types.includes('string'))
return (0, isAddress_js_1.isAddress)(args[parameterIndex], { strict: false });
if (types.includes('address') && types.includes('bytes'))
return (0, isAddress_js_1.isAddress)(args[parameterIndex], { strict: false });
return false;
})();
if (ambiguous)
return types;
}
return;
}
//# sourceMappingURL=getAbiItem.js.map