UNPKG

ox

Version:

Ethereum Standard Library

301 lines 10.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SizeExceedsPaddingSizeError = exports.SliceOffsetOutOfBoundsError = exports.SizeOverflowError = exports.InvalidLengthError = exports.InvalidHexValueError = exports.InvalidHexTypeError = exports.InvalidHexBooleanError = exports.IntegerOutOfRangeError = void 0; exports.assert = assert; exports.concat = concat; exports.from = from; exports.fromBoolean = fromBoolean; exports.fromBytes = fromBytes; exports.fromNumber = fromNumber; exports.fromString = fromString; exports.isEqual = isEqual; exports.padLeft = padLeft; exports.padRight = padRight; exports.random = random; exports.slice = slice; exports.size = size; exports.trimLeft = trimLeft; exports.trimRight = trimRight; exports.toBigInt = toBigInt; exports.toBoolean = toBoolean; exports.toBytes = toBytes; exports.toNumber = toNumber; exports.toString = toString; exports.validate = validate; const utils_1 = require("@noble/curves/abstract/utils"); const Bytes = require("./Bytes.js"); const Errors = require("./Errors.js"); const Json = require("./Json.js"); const internal_bytes = require("./internal/bytes.js"); const internal = require("./internal/hex.js"); const encoder = new TextEncoder(); const hexes = Array.from({ length: 256 }, (_v, i) => i.toString(16).padStart(2, '0')); function assert(value, options = {}) { const { strict = false } = options; if (!value) throw new InvalidHexTypeError(value); if (typeof value !== 'string') throw new InvalidHexTypeError(value); if (strict) { if (!/^0x[0-9a-fA-F]*$/.test(value)) throw new InvalidHexValueError(value); } if (!value.startsWith('0x')) throw new InvalidHexValueError(value); } function concat(...values) { return `0x${values.reduce((acc, x) => acc + x.replace('0x', ''), '')}`; } function from(value) { if (value instanceof Uint8Array) return fromBytes(value); if (Array.isArray(value)) return fromBytes(new Uint8Array(value)); return value; } function fromBoolean(value, options = {}) { const hex = `0x${Number(value)}`; if (typeof options.size === 'number') { internal.assertSize(hex, options.size); return padLeft(hex, options.size); } return hex; } function fromBytes(value, options = {}) { let string = ''; for (let i = 0; i < value.length; i++) string += hexes[value[i]]; const hex = `0x${string}`; if (typeof options.size === 'number') { internal.assertSize(hex, options.size); return padRight(hex, options.size); } return hex; } function fromNumber(value, options = {}) { const { signed, size } = options; const value_ = BigInt(value); let maxValue; if (size) { if (signed) maxValue = (1n << (BigInt(size) * 8n - 1n)) - 1n; else maxValue = 2n ** (BigInt(size) * 8n) - 1n; } else if (typeof value === 'number') { maxValue = BigInt(Number.MAX_SAFE_INTEGER); } const minValue = typeof maxValue === 'bigint' && signed ? -maxValue - 1n : 0; if ((maxValue && value_ > maxValue) || value_ < minValue) { const suffix = typeof value === 'bigint' ? 'n' : ''; throw new IntegerOutOfRangeError({ max: maxValue ? `${maxValue}${suffix}` : undefined, min: `${minValue}${suffix}`, signed, size, value: `${value}${suffix}`, }); } const stringValue = (signed && value_ < 0 ? (1n << BigInt(size * 8)) + BigInt(value_) : value_).toString(16); const hex = `0x${stringValue}`; if (size) return padLeft(hex, size); return hex; } function fromString(value, options = {}) { return fromBytes(encoder.encode(value), options); } function isEqual(hexA, hexB) { return (0, utils_1.equalBytes)(Bytes.fromHex(hexA), Bytes.fromHex(hexB)); } function padLeft(value, size) { return internal.pad(value, { dir: 'left', size }); } function padRight(value, size) { return internal.pad(value, { dir: 'right', size }); } function random(length) { return fromBytes(Bytes.random(length)); } function slice(value, start, end, options = {}) { const { strict } = options; internal.assertStartOffset(value, start); const value_ = `0x${value .replace('0x', '') .slice((start ?? 0) * 2, (end ?? value.length) * 2)}`; if (strict) internal.assertEndOffset(value_, start, end); return value_; } function size(value) { return Math.ceil((value.length - 2) / 2); } function trimLeft(value) { return internal.trim(value, { dir: 'left' }); } function trimRight(value) { return internal.trim(value, { dir: 'right' }); } function toBigInt(hex, options = {}) { const { signed } = options; if (options.size) internal.assertSize(hex, options.size); const value = BigInt(hex); if (!signed) return value; const size = (hex.length - 2) / 2; const max_unsigned = (1n << (BigInt(size) * 8n)) - 1n; const max_signed = max_unsigned >> 1n; if (value <= max_signed) return value; return value - max_unsigned - 1n; } function toBoolean(hex, options = {}) { if (options.size) internal.assertSize(hex, options.size); const hex_ = trimLeft(hex); if (hex_ === '0x') return false; if (hex_ === '0x1') return true; throw new InvalidHexBooleanError(hex); } function toBytes(hex, options = {}) { return Bytes.fromHex(hex, options); } function toNumber(hex, options = {}) { const { signed, size } = options; if (!signed && !size) return Number(hex); return Number(toBigInt(hex, options)); } function toString(hex, options = {}) { const { size } = options; let bytes = Bytes.fromHex(hex); if (size) { internal_bytes.assertSize(bytes, size); bytes = Bytes.trimRight(bytes); } return new TextDecoder().decode(bytes); } function validate(value, options = {}) { const { strict = false } = options; try { assert(value, { strict }); return true; } catch { return false; } } class IntegerOutOfRangeError extends Errors.BaseError { constructor({ max, min, signed, size, value, }) { super(`Number \`${value}\` is not in safe${size ? ` ${size * 8}-bit` : ''}${signed ? ' signed' : ' unsigned'} integer range ${max ? `(\`${min}\` to \`${max}\`)` : `(above \`${min}\`)`}`); Object.defineProperty(this, "name", { enumerable: true, configurable: true, writable: true, value: 'Hex.IntegerOutOfRangeError' }); } } exports.IntegerOutOfRangeError = IntegerOutOfRangeError; class InvalidHexBooleanError extends Errors.BaseError { constructor(hex) { super(`Hex value \`"${hex}"\` is not a valid boolean.`, { metaMessages: [ 'The hex value must be `"0x0"` (false) or `"0x1"` (true).', ], }); Object.defineProperty(this, "name", { enumerable: true, configurable: true, writable: true, value: 'Hex.InvalidHexBooleanError' }); } } exports.InvalidHexBooleanError = InvalidHexBooleanError; class InvalidHexTypeError extends Errors.BaseError { constructor(value) { super(`Value \`${typeof value === 'object' ? Json.stringify(value) : value}\` of type \`${typeof value}\` is an invalid hex type.`, { metaMessages: ['Hex types must be represented as `"0x${string}"`.'], }); Object.defineProperty(this, "name", { enumerable: true, configurable: true, writable: true, value: 'Hex.InvalidHexTypeError' }); } } exports.InvalidHexTypeError = InvalidHexTypeError; class InvalidHexValueError extends Errors.BaseError { constructor(value) { super(`Value \`${value}\` is an invalid hex value.`, { metaMessages: [ 'Hex values must start with `"0x"` and contain only hexadecimal characters (0-9, a-f, A-F).', ], }); Object.defineProperty(this, "name", { enumerable: true, configurable: true, writable: true, value: 'Hex.InvalidHexValueError' }); } } exports.InvalidHexValueError = InvalidHexValueError; class InvalidLengthError extends Errors.BaseError { constructor(value) { super(`Hex value \`"${value}"\` is an odd length (${value.length - 2} nibbles).`, { metaMessages: ['It must be an even length.'], }); Object.defineProperty(this, "name", { enumerable: true, configurable: true, writable: true, value: 'Hex.InvalidLengthError' }); } } exports.InvalidLengthError = InvalidLengthError; class SizeOverflowError extends Errors.BaseError { constructor({ givenSize, maxSize }) { super(`Size cannot exceed \`${maxSize}\` bytes. Given size: \`${givenSize}\` bytes.`); Object.defineProperty(this, "name", { enumerable: true, configurable: true, writable: true, value: 'Hex.SizeOverflowError' }); } } exports.SizeOverflowError = SizeOverflowError; class SliceOffsetOutOfBoundsError extends Errors.BaseError { constructor({ offset, position, size, }) { super(`Slice ${position === 'start' ? 'starting' : 'ending'} at offset \`${offset}\` is out-of-bounds (size: \`${size}\`).`); Object.defineProperty(this, "name", { enumerable: true, configurable: true, writable: true, value: 'Hex.SliceOffsetOutOfBoundsError' }); } } exports.SliceOffsetOutOfBoundsError = SliceOffsetOutOfBoundsError; class SizeExceedsPaddingSizeError extends Errors.BaseError { constructor({ size, targetSize, type, }) { super(`${type.charAt(0).toUpperCase()}${type .slice(1) .toLowerCase()} size (\`${size}\`) exceeds padding size (\`${targetSize}\`).`); Object.defineProperty(this, "name", { enumerable: true, configurable: true, writable: true, value: 'Hex.SizeExceedsPaddingSizeError' }); } } exports.SizeExceedsPaddingSizeError = SizeExceedsPaddingSizeError; //# sourceMappingURL=Hex.js.map