PHP WebShell
Текущая директория: /usr/lib/node_modules/bitgo/node_modules/ox/_esm/core
Просмотр файла: AbiItem.js
import * as abitype from 'abitype';
import * as Errors from './Errors.js';
import * as Hash from './Hash.js';
import * as Hex from './Hex.js';
import * as internal from './internal/abiItem.js';
/**
* Formats an {@link ox#AbiItem.AbiItem} into a **Human Readable ABI Item**.
*
* @example
* ```ts twoslash
* import { AbiItem } from 'ox'
*
* const formatted = AbiItem.format({
* type: 'function',
* name: 'approve',
* stateMutability: 'nonpayable',
* inputs: [
* {
* name: 'spender',
* type: 'address',
* },
* {
* name: 'amount',
* type: 'uint256',
* },
* ],
* outputs: [{ type: 'bool' }],
* })
*
* formatted
* // ^?
*
*
* ```
*
* @param abiItem - The ABI Item to format.
* @returns The formatted ABI Item .
*/
export function format(abiItem) {
return abitype.formatAbiItem(abiItem);
}
/**
* Parses an arbitrary **JSON ABI Item** or **Human Readable ABI Item** into a typed {@link ox#AbiItem.AbiItem}.
*
* @example
* ### JSON ABIs
*
* ```ts twoslash
* import { AbiItem } from 'ox'
*
* const abiItem = AbiItem.from({
* type: 'function',
* name: 'approve',
* stateMutability: 'nonpayable',
* inputs: [
* {
* name: 'spender',
* type: 'address',
* },
* {
* name: 'amount',
* type: 'uint256',
* },
* ],
* outputs: [{ type: 'bool' }],
* })
*
* abiItem
* //^?
*
*
*
*
*
*
*
*
*
*
*
*
* ```
*
* @example
* ### Human Readable ABIs
*
* A Human Readable ABI can be parsed into a typed ABI object:
*
* ```ts twoslash
* import { AbiItem } from 'ox'
*
* const abiItem = AbiItem.from(
* 'function approve(address spender, uint256 amount) returns (bool)' // [!code hl]
* )
*
* abiItem
* //^?
*
*
*
*
*
*
*
*
*
*
*
*
*
* ```
*
* @example
* It is possible to specify `struct`s along with your definitions:
*
* ```ts twoslash
* import { AbiItem } from 'ox'
*
* const abiItem = AbiItem.from([
* 'struct Foo { address spender; uint256 amount; }', // [!code hl]
* 'function approve(Foo foo) returns (bool)',
* ])
*
* abiItem
* //^?
*
*
*
*
*
*
*
*
*
*
*
*
* ```
*
*
*
* @param abiItem - The ABI Item to parse.
* @returns The typed ABI Item.
*/
export function from(abiItem, options = {}) {
const { prepare = true } = options;
const item = (() => {
if (Array.isArray(abiItem))
return abitype.parseAbiItem(abiItem);
if (typeof abiItem === 'string')
return abitype.parseAbiItem(abiItem);
return abiItem;
})();
return {
...item,
...(prepare ? { hash: getSignatureHash(item) } : {}),
};
}
/**
* Extracts an {@link ox#AbiItem.AbiItem} from an {@link ox#Abi.Abi} given a name and optional arguments.
*
* @example
* ABI Items can be extracted by their name using the `name` option:
*
* ```ts twoslash
* import { Abi, AbiItem } from 'ox'
*
* const abi = Abi.from([
* 'function foo()',
* 'event Transfer(address owner, address to, uint256 tokenId)',
* 'function bar(string a) returns (uint256 x)',
* ])
*
* const item = AbiItem.fromAbi(abi, 'Transfer') // [!code focus]
* // ^?
*
*
*
*
*
*
* ```
*
* @example
* ### Extracting by Selector
*
* ABI Items can be extract by their selector when {@link ox#Hex.Hex} is provided to `name`.
*
* ```ts twoslash
* import { Abi, AbiItem } from 'ox'
*
* const abi = Abi.from([
* 'function foo()',
* 'event Transfer(address owner, address to, uint256 tokenId)',
* 'function bar(string a) returns (uint256 x)',
* ])
* const item = AbiItem.fromAbi(abi, '0x095ea7b3') // [!code focus]
* // ^?
*
*
*
*
*
*
*
*
*
*
*
*
*
* ```
*
* :::note
*
* Extracting via a hex selector is useful when extracting an ABI Item from an `eth_call` RPC response,
* a Transaction `input`, or from Event Log `topics`.
*
* :::
*
* @param abi - The ABI to extract from.
* @param name - The name (or selector) of the ABI item to extract.
* @param options - Extraction options.
* @returns The ABI item.
*/
export function fromAbi(abi, name, options) {
const { args = [], prepare = true } = (options ??
{});
const isSelector = Hex.validate(name, { strict: false });
const abiItems = abi.filter((abiItem) => {
if (isSelector) {
if (abiItem.type === 'function' || abiItem.type === 'error')
return getSelector(abiItem) === Hex.slice(name, 0, 4);
if (abiItem.type === 'event')
return getSignatureHash(abiItem) === name;
return false;
}
return 'name' in abiItem && abiItem.name === name;
});
if (abiItems.length === 0)
throw new NotFoundError({ name: name });
if (abiItems.length === 1)
return {
...abiItems[0],
...(prepare ? { hash: getSignatureHash(abiItems[0]) } : {}),
};
let matchedAbiItem;
for (const abiItem of abiItems) {
if (!('inputs' in abiItem))
continue;
if (!args || args.length === 0) {
if (!abiItem.inputs || abiItem.inputs.length === 0)
return {
...abiItem,
...(prepare ? { hash: getSignatureHash(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 internal.isArgOfType(arg, abiParameter);
});
if (matched) {
// Check for ambiguity against already matched parameters (e.g. `address` vs `bytes20`).
if (matchedAbiItem &&
'inputs' in matchedAbiItem &&
matchedAbiItem.inputs) {
const ambiguousTypes = internal.getAmbiguousTypes(abiItem.inputs, matchedAbiItem.inputs, args);
if (ambiguousTypes)
throw new AmbiguityError({
abiItem,
type: ambiguousTypes[0],
}, {
abiItem: matchedAbiItem,
type: ambiguousTypes[1],
});
}
matchedAbiItem = abiItem;
}
}
const abiItem = (() => {
if (matchedAbiItem)
return matchedAbiItem;
const [abiItem, ...overloads] = abiItems;
return { ...abiItem, overloads };
})();
if (!abiItem)
throw new NotFoundError({ name: name });
return {
...abiItem,
...(prepare ? { hash: getSignatureHash(abiItem) } : {}),
};
}
/**
* Computes the [4-byte selector](https://solidity-by-example.org/function-selector/) for an {@link ox#AbiItem.AbiItem}.
*
* Useful for computing function selectors for calldata.
*
* @example
* ```ts twoslash
* import { AbiItem } from 'ox'
*
* const selector = AbiItem.getSelector('function ownerOf(uint256 tokenId)')
* // @log: '0x6352211e'
* ```
*
* @example
* ```ts twoslash
* import { AbiItem } from 'ox'
*
* const selector = AbiItem.getSelector({
* inputs: [{ type: 'uint256' }],
* name: 'ownerOf',
* outputs: [],
* stateMutability: 'view',
* type: 'function'
* })
* // @log: '0x6352211e'
* ```
*
* @param abiItem - The ABI item to compute the selector for. Can be a signature or an ABI item for an error, event, function, etc.
* @returns The first 4 bytes of the {@link ox#Hash.(keccak256:function)} hash of the function signature.
*/
export function getSelector(abiItem) {
return Hex.slice(getSignatureHash(abiItem), 0, 4);
}
/**
* Computes the stringified signature for a given {@link ox#AbiItem.AbiItem}.
*
* @example
* ```ts twoslash
* import { AbiItem } from 'ox'
*
* const signature = AbiItem.getSignature('function ownerOf(uint256 tokenId)')
* // @log: 'ownerOf(uint256)'
* ```
*
* @example
* ```ts twoslash
* import { AbiItem } from 'ox'
*
* const signature = AbiItem.getSignature({
* name: 'ownerOf',
* type: 'function',
* inputs: [{ name: 'tokenId', type: 'uint256' }],
* outputs: [],
* stateMutability: 'view',
* })
* // @log: 'ownerOf(uint256)'
* ```
*
* @param abiItem - The ABI Item to compute the signature for.
* @returns The stringified signature of the ABI Item.
*/
export function getSignature(abiItem) {
const signature = (() => {
if (typeof abiItem === 'string')
return abiItem;
return abitype.formatAbiItem(abiItem);
})();
return internal.normalizeSignature(signature);
}
/**
* Computes the signature hash for an {@link ox#AbiItem.AbiItem}.
*
* Useful for computing Event Topic values.
*
* @example
* ```ts twoslash
* import { AbiItem } from 'ox'
*
* const hash = AbiItem.getSignatureHash('event Transfer(address indexed from, address indexed to, uint256 amount)')
* // @log: '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'
* ```
*
* @example
* ```ts twoslash
* import { AbiItem } from 'ox'
*
* const hash = AbiItem.getSignatureHash({
* name: 'Transfer',
* type: 'event',
* inputs: [
* { name: 'from', type: 'address', indexed: true },
* { name: 'to', type: 'address', indexed: true },
* { name: 'amount', type: 'uint256', indexed: false },
* ],
* })
* // @log: '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'
* ```
*
* @param abiItem - The ABI Item to compute the signature hash for.
* @returns The {@link ox#Hash.(keccak256:function)} hash of the ABI item's signature.
*/
export function getSignatureHash(abiItem) {
if (typeof abiItem !== 'string' && 'hash' in abiItem && abiItem.hash)
return abiItem.hash;
return Hash.keccak256(Hex.fromString(getSignature(abiItem)));
}
/**
* Throws when ambiguous types are found on overloaded ABI items.
*
* @example
* ```ts twoslash
* import { Abi, AbiFunction } from 'ox'
*
* const foo = Abi.from(['function foo(address)', 'function foo(bytes20)'])
* AbiFunction.fromAbi(foo, 'foo', {
* args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'],
* })
* // @error: AbiItem.AmbiguityError: Found ambiguous types in overloaded ABI Items.
* // @error: `bytes20` in `foo(bytes20)`, and
* // @error: `address` in `foo(address)`
* // @error: These types encode differently and cannot be distinguished at runtime.
* // @error: Remove one of the ambiguous items in the ABI.
* ```
*
* ### Solution
*
* Remove one of the ambiguous types from the ABI.
*
* ```ts twoslash
* import { Abi, AbiFunction } from 'ox'
*
* const foo = Abi.from([
* 'function foo(address)',
* 'function foo(bytes20)' // [!code --]
* ])
* AbiFunction.fromAbi(foo, 'foo', {
* args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'],
* })
* // @error: AbiItem.AmbiguityError: Found ambiguous types in overloaded ABI Items.
* // @error: `bytes20` in `foo(bytes20)`, and
* // @error: `address` in `foo(address)`
* // @error: These types encode differently and cannot be distinguished at runtime.
* // @error: Remove one of the ambiguous items in the ABI.
* ```
*/
export class AmbiguityError extends Errors.BaseError {
constructor(x, y) {
super('Found ambiguous types in overloaded ABI Items.', {
metaMessages: [
// TODO: abitype to add support for signature-formatted ABI items.
`\`${x.type}\` in \`${internal.normalizeSignature(abitype.formatAbiItem(x.abiItem))}\`, and`,
`\`${y.type}\` in \`${internal.normalizeSignature(abitype.formatAbiItem(y.abiItem))}\``,
'',
'These types encode differently and cannot be distinguished at runtime.',
'Remove one of the ambiguous items in the ABI.',
],
});
Object.defineProperty(this, "name", {
enumerable: true,
configurable: true,
writable: true,
value: 'AbiItem.AmbiguityError'
});
}
}
/**
* Throws when an ABI item is not found in the ABI.
*
* @example
* ```ts twoslash
* // @noErrors
* import { Abi, AbiFunction } from 'ox'
*
* const foo = Abi.from([
* 'function foo(address)',
* 'function bar(uint)'
* ])
* AbiFunction.fromAbi(foo, 'baz')
* // @error: AbiItem.NotFoundError: ABI function with name "baz" not found.
* ```
*
* ### Solution
*
* Ensure the ABI item exists on the ABI.
*
* ```ts twoslash
* // @noErrors
* import { Abi, AbiFunction } from 'ox'
*
* const foo = Abi.from([
* 'function foo(address)',
* 'function bar(uint)',
* 'function baz(bool)' // [!code ++]
* ])
* AbiFunction.fromAbi(foo, 'baz')
* ```
*/
export class NotFoundError extends Errors.BaseError {
constructor({ name, data, type = 'item', }) {
const selector = (() => {
if (name)
return ` with name "${name}"`;
if (data)
return ` with data "${data}"`;
return '';
})();
super(`ABI ${type}${selector} not found.`);
Object.defineProperty(this, "name", {
enumerable: true,
configurable: true,
writable: true,
value: 'AbiItem.NotFoundError'
});
}
}
/**
* Throws when the selector size is invalid.
*
* @example
* ```ts twoslash
* import { Abi, AbiFunction } from 'ox'
*
* const foo = Abi.from([
* 'function foo(address)',
* 'function bar(uint)'
* ])
* AbiFunction.fromAbi(foo, '0xaaa')
* // @error: AbiItem.InvalidSelectorSizeError: Selector size is invalid. Expected 4 bytes. Received 2 bytes ("0xaaa").
* ```
*
* ### Solution
*
* Ensure the selector size is 4 bytes.
*
* ```ts twoslash
* // @noErrors
* import { Abi, AbiFunction } from 'ox'
*
* const foo = Abi.from([
* 'function foo(address)',
* 'function bar(uint)'
* ])
* AbiFunction.fromAbi(foo, '0x7af82b1a')
* ```
*/
export class InvalidSelectorSizeError extends Errors.BaseError {
constructor({ data }) {
super(`Selector size is invalid. Expected 4 bytes. Received ${Hex.size(data)} bytes ("${data}").`);
Object.defineProperty(this, "name", {
enumerable: true,
configurable: true,
writable: true,
value: 'AbiItem.InvalidSelectorSizeError'
});
}
}
//# sourceMappingURL=AbiItem.js.mapВыполнить команду
Для локальной разработки. Не используйте в интернете!