ox
Version:
Ethereum Standard Library
91 lines • 3.2 kB
JavaScript
import * as AbiItem from './AbiItem.js';
import * as AbiParameters from './AbiParameters.js';
import * as Errors from './Errors.js';
import * as Hex from './Hex.js';
import * as formatAbiItem from './internal/human-readable/formatAbiItem.js';
// eslint-disable-next-line jsdoc-js/require-jsdoc
export function decode(...parameters) {
const [abiConstructor, options] = (() => {
if (Array.isArray(parameters[0])) {
const [abi, options] = parameters;
if (options.data === options.bytecode)
return [undefined, options];
return [fromAbi(abi), options];
}
return parameters;
})();
if (!abiConstructor)
return undefined;
const { bytecode } = options;
if (abiConstructor.inputs?.length === 0)
return undefined;
if (!options.data.startsWith(bytecode))
throw new BytecodeMismatchError({
bytecode,
data: options.data,
});
const data = ('0x' + options.data.slice(bytecode.length));
return AbiParameters.decode(abiConstructor.inputs, data, {
checksumAddress: options.checksumAddress,
});
}
// eslint-disable-next-line jsdoc-js/require-jsdoc
export function encode(...parameters) {
const [abiConstructor, options] = (() => {
const options = parameters[1];
if (!options.args || options.args.length === 0)
return [undefined, options];
if (Array.isArray(parameters[0])) {
const [abi] = parameters;
return [fromAbi(abi), options];
}
return parameters;
})();
const { bytecode, args } = options;
if (!abiConstructor)
return bytecode;
return Hex.concat(bytecode, abiConstructor.inputs?.length && args?.length
? AbiParameters.encode(abiConstructor.inputs, args)
: '0x');
}
/** @internal */
export function format(abiConstructor) {
return formatAbiItem.formatAbiItem(abiConstructor);
}
/** @internal */
export function from(abiConstructor) {
return AbiItem.from(abiConstructor);
}
/** @internal */
export function fromAbi(abi) {
const item = abi.find((item) => item.type === 'constructor');
if (!item)
throw new AbiItem.NotFoundError({ name: 'constructor' });
return item;
}
/**
* Throws when the provided `data` does not begin with the provided `bytecode`.
*
* @example
* ```ts twoslash
* import { AbiConstructor } from 'ox'
*
* AbiConstructor.decode(
* AbiConstructor.from('constructor(address)'),
* { bytecode: '0x6080...', data: '0xdeadbeef' }
* )
* // @error: AbiConstructor.BytecodeMismatchError: Provided `data` does not start with the provided `bytecode`.
* ```
*/
export class BytecodeMismatchError extends Errors.BaseError {
name = 'AbiConstructor.BytecodeMismatchError';
constructor({ bytecode, data }) {
super('Provided `data` does not start with the provided `bytecode`.', {
metaMessages: [
`Bytecode: ${bytecode.slice(0, 18)}${bytecode.length > 18 ? '...' : ''}`,
`Data: ${data.slice(0, 18)}${data.length > 18 ? '...' : ''}`,
],
});
}
}
//# sourceMappingURL=AbiConstructor.js.map