UNPKG

ox

Version:

Ethereum Standard Library

227 lines 8.48 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.InvalidTypeError = exports.InvalidArrayError = exports.LengthMismatchError = exports.BytesSizeMismatchError = exports.ArrayLengthMismatchError = exports.ZeroDataError = exports.DataSizeTooSmallError = void 0; exports.decode = decode; exports.encode = encode; exports.encodePacked = encodePacked; exports.format = format; exports.from = from; const abitype = require("abitype"); const Address = require("./Address.js"); const Bytes = require("./Bytes.js"); const Errors = require("./Errors.js"); const Hex = require("./Hex.js"); const Solidity = require("./Solidity.js"); const internal = require("./internal/abiParameters.js"); const Cursor = require("./internal/cursor.js"); function decode(parameters, data, options = {}) { const { as = 'Array', checksumAddress = false } = options; const bytes = typeof data === 'string' ? Bytes.fromHex(data) : data; const cursor = Cursor.create(bytes); if (Bytes.size(bytes) === 0 && parameters.length > 0) throw new ZeroDataError(); if (Bytes.size(bytes) && Bytes.size(bytes) < 32) throw new DataSizeTooSmallError({ data: typeof data === 'string' ? data : Hex.fromBytes(data), parameters: parameters, size: Bytes.size(bytes), }); let consumed = 0; const values = as === 'Array' ? [] : {}; for (let i = 0; i < parameters.length; ++i) { const param = parameters[i]; cursor.setPosition(consumed); const [data, consumed_] = internal.decodeParameter(cursor, param, { checksumAddress, staticPosition: 0, }); consumed += consumed_; if (as === 'Array') values.push(data); else values[param.name ?? i] = data; } return values; } function encode(parameters, values, options) { const { checksumAddress = false } = options ?? {}; if (parameters.length !== values.length) throw new LengthMismatchError({ expectedLength: parameters.length, givenLength: values.length, }); const preparedParameters = internal.prepareParameters({ checksumAddress, parameters: parameters, values: values, }); const data = internal.encode(preparedParameters); if (data.length === 0) return '0x'; return data; } function encodePacked(types, values) { if (types.length !== values.length) throw new LengthMismatchError({ expectedLength: types.length, givenLength: values.length, }); const data = []; for (let i = 0; i < types.length; i++) { const type = types[i]; const value = values[i]; data.push(encodePacked.encode(type, value)); } return Hex.concat(...data); } (function (encodePacked) { function encode(type, value, isArray = false) { if (type === 'address') { const address = value; Address.assert(address); return Hex.padLeft(address.toLowerCase(), isArray ? 32 : 0); } if (type === 'string') return Hex.fromString(value); if (type === 'bytes') return value; if (type === 'bool') return Hex.padLeft(Hex.fromBoolean(value), isArray ? 32 : 1); const intMatch = type.match(Solidity.integerRegex); if (intMatch) { const [_type, baseType, bits = '256'] = intMatch; const size = Number.parseInt(bits) / 8; return Hex.fromNumber(value, { size: isArray ? 32 : size, signed: baseType === 'int', }); } const bytesMatch = type.match(Solidity.bytesRegex); if (bytesMatch) { const [_type, size] = bytesMatch; if (Number.parseInt(size) !== (value.length - 2) / 2) throw new BytesSizeMismatchError({ expectedSize: Number.parseInt(size), value: value, }); return Hex.padRight(value, isArray ? 32 : 0); } const arrayMatch = type.match(Solidity.arrayRegex); if (arrayMatch && Array.isArray(value)) { const [_type, childType] = arrayMatch; const data = []; for (let i = 0; i < value.length; i++) { data.push(encode(childType, value[i], true)); } if (data.length === 0) return '0x'; return Hex.concat(...data); } throw new InvalidTypeError(type); } encodePacked.encode = encode; })(encodePacked || (exports.encodePacked = encodePacked = {})); function format(parameters) { return abitype.formatAbiParameters(parameters); } function from(parameters) { if (Array.isArray(parameters) && typeof parameters[0] === 'string') return abitype.parseAbiParameters(parameters); if (typeof parameters === 'string') return abitype.parseAbiParameters(parameters); return parameters; } class DataSizeTooSmallError extends Errors.BaseError { constructor({ data, parameters, size, }) { super(`Data size of ${size} bytes is too small for given parameters.`, { metaMessages: [ `Params: (${abitype.formatAbiParameters(parameters)})`, `Data: ${data} (${size} bytes)`, ], }); Object.defineProperty(this, "name", { enumerable: true, configurable: true, writable: true, value: 'AbiParameters.DataSizeTooSmallError' }); } } exports.DataSizeTooSmallError = DataSizeTooSmallError; class ZeroDataError extends Errors.BaseError { constructor() { super('Cannot decode zero data ("0x") with ABI parameters.'); Object.defineProperty(this, "name", { enumerable: true, configurable: true, writable: true, value: 'AbiParameters.ZeroDataError' }); } } exports.ZeroDataError = ZeroDataError; class ArrayLengthMismatchError extends Errors.BaseError { constructor({ expectedLength, givenLength, type, }) { super(`Array length mismatch for type \`${type}\`. Expected: \`${expectedLength}\`. Given: \`${givenLength}\`.`); Object.defineProperty(this, "name", { enumerable: true, configurable: true, writable: true, value: 'AbiParameters.ArrayLengthMismatchError' }); } } exports.ArrayLengthMismatchError = ArrayLengthMismatchError; class BytesSizeMismatchError extends Errors.BaseError { constructor({ expectedSize, value, }) { super(`Size of bytes "${value}" (bytes${Hex.size(value)}) does not match expected size (bytes${expectedSize}).`); Object.defineProperty(this, "name", { enumerable: true, configurable: true, writable: true, value: 'AbiParameters.BytesSizeMismatchError' }); } } exports.BytesSizeMismatchError = BytesSizeMismatchError; class LengthMismatchError extends Errors.BaseError { constructor({ expectedLength, givenLength, }) { super([ 'ABI encoding parameters/values length mismatch.', `Expected length (parameters): ${expectedLength}`, `Given length (values): ${givenLength}`, ].join('\n')); Object.defineProperty(this, "name", { enumerable: true, configurable: true, writable: true, value: 'AbiParameters.LengthMismatchError' }); } } exports.LengthMismatchError = LengthMismatchError; class InvalidArrayError extends Errors.BaseError { constructor(value) { super(`Value \`${value}\` is not a valid array.`); Object.defineProperty(this, "name", { enumerable: true, configurable: true, writable: true, value: 'AbiParameters.InvalidArrayError' }); } } exports.InvalidArrayError = InvalidArrayError; class InvalidTypeError extends Errors.BaseError { constructor(type) { super(`Type \`${type}\` is not a valid ABI Type.`); Object.defineProperty(this, "name", { enumerable: true, configurable: true, writable: true, value: 'AbiParameters.InvalidTypeError' }); } } exports.InvalidTypeError = InvalidTypeError; //# sourceMappingURL=AbiParameters.js.map