FRE-600: Fix code review blockers

- Consolidated duplicate UndoManagers to single instance
- Fixed connection promise to only resolve on 'connected' status
- Fixed WebSocketProvider import (WebsocketProvider)
- Added proper doc.destroy() cleanup
- Renamed isPresenceInitialized property to avoid conflict

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
2026-04-25 00:08:01 -04:00
parent 65b552bb08
commit 7c684a42cc
48450 changed files with 5679671 additions and 383 deletions

227
node_modules/viem/utils/encoding/fromBytes.ts generated vendored Normal file
View File

@@ -0,0 +1,227 @@
import { InvalidBytesBooleanError } from '../../errors/encoding.js'
import type { ErrorType } from '../../errors/utils.js'
import type { ByteArray, Hex } from '../../types/misc.js'
import { type TrimErrorType, trim } from '../data/trim.js'
import {
type AssertSizeErrorType,
assertSize,
type HexToBigIntErrorType,
type HexToNumberErrorType,
hexToBigInt,
hexToNumber,
} from './fromHex.js'
import { type BytesToHexErrorType, bytesToHex } from './toHex.js'
export type FromBytesParameters<
to extends 'string' | 'hex' | 'bigint' | 'number' | 'boolean',
> =
| to
| {
/** Size of the bytes. */
size?: number | undefined
/** Type to convert to. */
to: to
}
export type FromBytesReturnType<to> = to extends 'string'
? string
: to extends 'hex'
? Hex
: to extends 'bigint'
? bigint
: to extends 'number'
? number
: to extends 'boolean'
? boolean
: never
export type FromBytesErrorType =
| BytesToHexErrorType
| BytesToBigIntErrorType
| BytesToBoolErrorType
| BytesToNumberErrorType
| BytesToStringErrorType
| ErrorType
/**
* Decodes a byte array into a UTF-8 string, hex value, number, bigint or boolean.
*
* - Docs: https://viem.sh/docs/utilities/fromBytes
* - Example: https://viem.sh/docs/utilities/fromBytes#usage
*
* @param bytes Byte array to decode.
* @param toOrOpts Type to convert to or options.
* @returns Decoded value.
*
* @example
* import { fromBytes } from 'viem'
* const data = fromBytes(new Uint8Array([1, 164]), 'number')
* // 420
*
* @example
* import { fromBytes } from 'viem'
* const data = fromBytes(
* new Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33]),
* 'string'
* )
* // 'Hello world'
*/
export function fromBytes<
to extends 'string' | 'hex' | 'bigint' | 'number' | 'boolean',
>(
bytes: ByteArray,
toOrOpts: FromBytesParameters<to>,
): FromBytesReturnType<to> {
const opts = typeof toOrOpts === 'string' ? { to: toOrOpts } : toOrOpts
const to = opts.to
if (to === 'number')
return bytesToNumber(bytes, opts) as FromBytesReturnType<to>
if (to === 'bigint')
return bytesToBigInt(bytes, opts) as FromBytesReturnType<to>
if (to === 'boolean')
return bytesToBool(bytes, opts) as FromBytesReturnType<to>
if (to === 'string')
return bytesToString(bytes, opts) as FromBytesReturnType<to>
return bytesToHex(bytes, opts) as FromBytesReturnType<to>
}
export type BytesToBigIntOpts = {
/** Whether or not the number of a signed representation. */
signed?: boolean | undefined
/** Size of the bytes. */
size?: number | undefined
}
export type BytesToBigIntErrorType =
| BytesToHexErrorType
| HexToBigIntErrorType
| ErrorType
/**
* Decodes a byte array into a bigint.
*
* - Docs: https://viem.sh/docs/utilities/fromBytes#bytestobigint
*
* @param bytes Byte array to decode.
* @param opts Options.
* @returns BigInt value.
*
* @example
* import { bytesToBigInt } from 'viem'
* const data = bytesToBigInt(new Uint8Array([1, 164]))
* // 420n
*/
export function bytesToBigInt(
bytes: ByteArray,
opts: BytesToBigIntOpts = {},
): bigint {
if (typeof opts.size !== 'undefined') assertSize(bytes, { size: opts.size })
const hex = bytesToHex(bytes, opts)
return hexToBigInt(hex, opts)
}
export type BytesToBoolOpts = {
/** Size of the bytes. */
size?: number | undefined
}
export type BytesToBoolErrorType =
| AssertSizeErrorType
| TrimErrorType
| ErrorType
/**
* Decodes a byte array into a boolean.
*
* - Docs: https://viem.sh/docs/utilities/fromBytes#bytestobool
*
* @param bytes Byte array to decode.
* @param opts Options.
* @returns Boolean value.
*
* @example
* import { bytesToBool } from 'viem'
* const data = bytesToBool(new Uint8Array([1]))
* // true
*/
export function bytesToBool(
bytes_: ByteArray,
opts: BytesToBoolOpts = {},
): boolean {
let bytes = bytes_
if (typeof opts.size !== 'undefined') {
assertSize(bytes, { size: opts.size })
bytes = trim(bytes)
}
if (bytes.length > 1 || bytes[0] > 1)
throw new InvalidBytesBooleanError(bytes)
return Boolean(bytes[0])
}
export type BytesToNumberOpts = BytesToBigIntOpts
export type BytesToNumberErrorType =
| BytesToHexErrorType
| HexToNumberErrorType
| ErrorType
/**
* Decodes a byte array into a number.
*
* - Docs: https://viem.sh/docs/utilities/fromBytes#bytestonumber
*
* @param bytes Byte array to decode.
* @param opts Options.
* @returns Number value.
*
* @example
* import { bytesToNumber } from 'viem'
* const data = bytesToNumber(new Uint8Array([1, 164]))
* // 420
*/
export function bytesToNumber(
bytes: ByteArray,
opts: BytesToNumberOpts = {},
): number {
if (typeof opts.size !== 'undefined') assertSize(bytes, { size: opts.size })
const hex = bytesToHex(bytes, opts)
return hexToNumber(hex, opts)
}
export type BytesToStringOpts = {
/** Size of the bytes. */
size?: number | undefined
}
export type BytesToStringErrorType =
| AssertSizeErrorType
| TrimErrorType
| ErrorType
/**
* Decodes a byte array into a UTF-8 string.
*
* - Docs: https://viem.sh/docs/utilities/fromBytes#bytestostring
*
* @param bytes Byte array to decode.
* @param opts Options.
* @returns String value.
*
* @example
* import { bytesToString } from 'viem'
* const data = bytesToString(new Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33]))
* // 'Hello world'
*/
export function bytesToString(
bytes_: ByteArray,
opts: BytesToStringOpts = {},
): string {
let bytes = bytes_
if (typeof opts.size !== 'undefined') {
assertSize(bytes, { size: opts.size })
bytes = trim(bytes, { dir: 'right' })
}
return new TextDecoder().decode(bytes)
}

267
node_modules/viem/utils/encoding/fromHex.ts generated vendored Normal file
View File

@@ -0,0 +1,267 @@
import {
IntegerOutOfRangeError,
type IntegerOutOfRangeErrorType,
InvalidHexBooleanError,
type InvalidHexBooleanErrorType,
SizeOverflowError,
type SizeOverflowErrorType,
} from '../../errors/encoding.js'
import type { ErrorType } from '../../errors/utils.js'
import type { ByteArray, Hex } from '../../types/misc.js'
import { type SizeErrorType, size as size_ } from '../data/size.js'
import { type TrimErrorType, trim } from '../data/trim.js'
import { type HexToBytesErrorType, hexToBytes } from './toBytes.js'
export type AssertSizeErrorType =
| SizeOverflowErrorType
| SizeErrorType
| ErrorType
export function assertSize(
hexOrBytes: Hex | ByteArray,
{ size }: { size: number },
): void {
if (size_(hexOrBytes) > size)
throw new SizeOverflowError({
givenSize: size_(hexOrBytes),
maxSize: size,
})
}
export type FromHexParameters<
to extends 'string' | 'bigint' | 'number' | 'bytes' | 'boolean',
> =
| to
| {
/** Size (in bytes) of the hex value. */
size?: number | undefined
/** Type to convert to. */
to: to
}
export type FromHexReturnType<to> = to extends 'string'
? string
: to extends 'bigint'
? bigint
: to extends 'number'
? number
: to extends 'bytes'
? ByteArray
: to extends 'boolean'
? boolean
: never
export type FromHexErrorType =
| HexToNumberErrorType
| HexToBigIntErrorType
| HexToBoolErrorType
| HexToStringErrorType
| HexToBytesErrorType
| ErrorType
/**
* Decodes a hex string into a string, number, bigint, boolean, or byte array.
*
* - Docs: https://viem.sh/docs/utilities/fromHex
* - Example: https://viem.sh/docs/utilities/fromHex#usage
*
* @param hex Hex string to decode.
* @param toOrOpts Type to convert to or options.
* @returns Decoded value.
*
* @example
* import { fromHex } from 'viem'
* const data = fromHex('0x1a4', 'number')
* // 420
*
* @example
* import { fromHex } from 'viem'
* const data = fromHex('0x48656c6c6f20576f726c6421', 'string')
* // 'Hello world'
*
* @example
* import { fromHex } from 'viem'
* const data = fromHex('0x48656c6c6f20576f726c64210000000000000000000000000000000000000000', {
* size: 32,
* to: 'string'
* })
* // 'Hello world'
*/
export function fromHex<
to extends 'string' | 'bigint' | 'number' | 'bytes' | 'boolean',
>(hex: Hex, toOrOpts: FromHexParameters<to>): FromHexReturnType<to> {
const opts = typeof toOrOpts === 'string' ? { to: toOrOpts } : toOrOpts
const to = opts.to
if (to === 'number') return hexToNumber(hex, opts) as FromHexReturnType<to>
if (to === 'bigint') return hexToBigInt(hex, opts) as FromHexReturnType<to>
if (to === 'string') return hexToString(hex, opts) as FromHexReturnType<to>
if (to === 'boolean') return hexToBool(hex, opts) as FromHexReturnType<to>
return hexToBytes(hex, opts) as FromHexReturnType<to>
}
export type HexToBigIntOpts = {
/** Whether or not the number of a signed representation. */
signed?: boolean | undefined
/** Size (in bytes) of the hex value. */
size?: number | undefined
}
export type HexToBigIntErrorType = AssertSizeErrorType | ErrorType
/**
* Decodes a hex value into a bigint.
*
* - Docs: https://viem.sh/docs/utilities/fromHex#hextobigint
*
* @param hex Hex value to decode.
* @param opts Options.
* @returns BigInt value.
*
* @example
* import { hexToBigInt } from 'viem'
* const data = hexToBigInt('0x1a4', { signed: true })
* // 420n
*
* @example
* import { hexToBigInt } from 'viem'
* const data = hexToBigInt('0x00000000000000000000000000000000000000000000000000000000000001a4', { size: 32 })
* // 420n
*/
export function hexToBigInt(hex: Hex, opts: HexToBigIntOpts = {}): bigint {
const { signed } = opts
if (opts.size) assertSize(hex, { size: opts.size })
const value = BigInt(hex)
if (!signed) return value
const size = (hex.length - 2) / 2
const max = (1n << (BigInt(size) * 8n - 1n)) - 1n
if (value <= max) return value
return value - BigInt(`0x${'f'.padStart(size * 2, 'f')}`) - 1n
}
export type HexToBoolOpts = {
/** Size (in bytes) of the hex value. */
size?: number | undefined
}
export type HexToBoolErrorType =
| AssertSizeErrorType
| InvalidHexBooleanErrorType
| TrimErrorType
| ErrorType
/**
* Decodes a hex value into a boolean.
*
* - Docs: https://viem.sh/docs/utilities/fromHex#hextobool
*
* @param hex Hex value to decode.
* @param opts Options.
* @returns Boolean value.
*
* @example
* import { hexToBool } from 'viem'
* const data = hexToBool('0x01')
* // true
*
* @example
* import { hexToBool } from 'viem'
* const data = hexToBool('0x0000000000000000000000000000000000000000000000000000000000000001', { size: 32 })
* // true
*/
export function hexToBool(hex_: Hex, opts: HexToBoolOpts = {}): boolean {
let hex = hex_
if (opts.size) {
assertSize(hex, { size: opts.size })
hex = trim(hex)
}
if (trim(hex) === '0x00') return false
if (trim(hex) === '0x01') return true
throw new InvalidHexBooleanError(hex)
}
export type HexToNumberOpts = HexToBigIntOpts
export type HexToNumberErrorType =
| HexToBigIntErrorType
| IntegerOutOfRangeErrorType
| ErrorType
/**
* Decodes a hex string into a number.
*
* - Docs: https://viem.sh/docs/utilities/fromHex#hextonumber
*
* @param hex Hex value to decode.
* @param opts Options.
* @returns Number value.
*
* @example
* import { hexToNumber } from 'viem'
* const data = hexToNumber('0x1a4')
* // 420
*
* @example
* import { hexToNumber } from 'viem'
* const data = hexToBigInt('0x00000000000000000000000000000000000000000000000000000000000001a4', { size: 32 })
* // 420
*/
export function hexToNumber(hex: Hex, opts: HexToNumberOpts = {}): number {
const value = hexToBigInt(hex, opts)
const number = Number(value)
if (!Number.isSafeInteger(number))
throw new IntegerOutOfRangeError({
max: `${Number.MAX_SAFE_INTEGER}`,
min: `${Number.MIN_SAFE_INTEGER}`,
signed: opts.signed,
size: opts.size,
value: `${value}n`,
})
return number
}
export type HexToStringOpts = {
/** Size (in bytes) of the hex value. */
size?: number | undefined
}
export type HexToStringErrorType =
| AssertSizeErrorType
| HexToBytesErrorType
| TrimErrorType
| ErrorType
/**
* Decodes a hex value into a UTF-8 string.
*
* - Docs: https://viem.sh/docs/utilities/fromHex#hextostring
*
* @param hex Hex value to decode.
* @param opts Options.
* @returns String value.
*
* @example
* import { hexToString } from 'viem'
* const data = hexToString('0x48656c6c6f20576f726c6421')
* // 'Hello world!'
*
* @example
* import { hexToString } from 'viem'
* const data = hexToString('0x48656c6c6f20576f726c64210000000000000000000000000000000000000000', {
* size: 32,
* })
* // 'Hello world'
*/
export function hexToString(hex: Hex, opts: HexToStringOpts = {}): string {
let bytes = hexToBytes(hex)
if (opts.size) {
assertSize(bytes, { size: opts.size })
bytes = trim(bytes, { dir: 'right' })
}
return new TextDecoder().decode(bytes)
}

102
node_modules/viem/utils/encoding/fromRlp.ts generated vendored Normal file
View File

@@ -0,0 +1,102 @@
import { BaseError, type BaseErrorType } from '../../errors/base.js'
import {
InvalidHexValueError,
type InvalidHexValueErrorType,
} from '../../errors/encoding.js'
import type { ErrorType } from '../../errors/utils.js'
import type { ByteArray, Hex } from '../../types/misc.js'
import {
type CreateCursorErrorType,
type Cursor,
createCursor,
} from '../cursor.js'
import { type HexToBytesErrorType, hexToBytes } from './toBytes.js'
import { type BytesToHexErrorType, bytesToHex } from './toHex.js'
import type { RecursiveArray } from './toRlp.js'
type To = 'hex' | 'bytes'
export type FromRlpReturnType<to extends To> =
| (to extends 'bytes' ? RecursiveArray<ByteArray> : never)
| (to extends 'hex' ? RecursiveArray<Hex> : never)
export type FromRlpErrorType =
| CreateCursorErrorType
| FromRlpCursorErrorType
| HexToBytesErrorType
| InvalidHexValueErrorType
| ErrorType
export function fromRlp<to extends To = 'hex'>(
value: ByteArray | Hex,
to: to | To | undefined = 'hex',
): FromRlpReturnType<to> {
const bytes = (() => {
if (typeof value === 'string') {
if (value.length > 3 && value.length % 2 !== 0)
throw new InvalidHexValueError(value)
return hexToBytes(value)
}
return value
})()
const cursor = createCursor(bytes, {
recursiveReadLimit: Number.POSITIVE_INFINITY,
})
const result = fromRlpCursor(cursor, to)
return result as FromRlpReturnType<to>
}
type FromRlpCursorErrorType =
| BytesToHexErrorType
| ReadLengthErrorType
| ReadListErrorType
| ErrorType
function fromRlpCursor<to extends To = 'hex'>(
cursor: Cursor,
to: to | To | undefined = 'hex',
): FromRlpReturnType<to> {
if (cursor.bytes.length === 0)
return (
to === 'hex' ? bytesToHex(cursor.bytes) : cursor.bytes
) as FromRlpReturnType<to>
const prefix = cursor.readByte()
if (prefix < 0x80) cursor.decrementPosition(1)
// bytes
if (prefix < 0xc0) {
const length = readLength(cursor, prefix, 0x80)
const bytes = cursor.readBytes(length)
return (to === 'hex' ? bytesToHex(bytes) : bytes) as FromRlpReturnType<to>
}
// list
const length = readLength(cursor, prefix, 0xc0)
return readList(cursor, length, to) as {} as FromRlpReturnType<to>
}
type ReadLengthErrorType = BaseErrorType | ErrorType
function readLength(cursor: Cursor, prefix: number, offset: number) {
if (offset === 0x80 && prefix < 0x80) return 1
if (prefix <= offset + 55) return prefix - offset
if (prefix === offset + 55 + 1) return cursor.readUint8()
if (prefix === offset + 55 + 2) return cursor.readUint16()
if (prefix === offset + 55 + 3) return cursor.readUint24()
if (prefix === offset + 55 + 4) return cursor.readUint32()
throw new BaseError('Invalid RLP prefix')
}
type ReadListErrorType = ErrorType
function readList<to extends To>(cursor: Cursor, length: number, to: to | To) {
const position = cursor.position
const value: FromRlpReturnType<to>[] = []
while (cursor.position - position < length)
value.push(fromRlpCursor(cursor, to))
return value
}

248
node_modules/viem/utils/encoding/toBytes.ts generated vendored Normal file
View File

@@ -0,0 +1,248 @@
import { BaseError } from '../../errors/base.js'
import type { ErrorType } from '../../errors/utils.js'
import type { ByteArray, Hex } from '../../types/misc.js'
import { type IsHexErrorType, isHex } from '../data/isHex.js'
import { type PadErrorType, pad } from '../data/pad.js'
import { type AssertSizeErrorType, assertSize } from './fromHex.js'
import {
type NumberToHexErrorType,
type NumberToHexOpts,
numberToHex,
} from './toHex.js'
const encoder = /*#__PURE__*/ new TextEncoder()
export type ToBytesParameters = {
/** Size of the output bytes. */
size?: number | undefined
}
export type ToBytesErrorType =
| NumberToBytesErrorType
| BoolToBytesErrorType
| HexToBytesErrorType
| StringToBytesErrorType
| IsHexErrorType
| ErrorType
/**
* Encodes a UTF-8 string, hex value, bigint, number or boolean to a byte array.
*
* - Docs: https://viem.sh/docs/utilities/toBytes
* - Example: https://viem.sh/docs/utilities/toBytes#usage
*
* @param value Value to encode.
* @param opts Options.
* @returns Byte array value.
*
* @example
* import { toBytes } from 'viem'
* const data = toBytes('Hello world')
* // Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33])
*
* @example
* import { toBytes } from 'viem'
* const data = toBytes(420)
* // Uint8Array([1, 164])
*
* @example
* import { toBytes } from 'viem'
* const data = toBytes(420, { size: 4 })
* // Uint8Array([0, 0, 1, 164])
*/
export function toBytes(
value: string | bigint | number | boolean | Hex,
opts: ToBytesParameters = {},
): ByteArray {
if (typeof value === 'number' || typeof value === 'bigint')
return numberToBytes(value, opts)
if (typeof value === 'boolean') return boolToBytes(value, opts)
if (isHex(value)) return hexToBytes(value, opts)
return stringToBytes(value, opts)
}
export type BoolToBytesOpts = {
/** Size of the output bytes. */
size?: number | undefined
}
export type BoolToBytesErrorType =
| AssertSizeErrorType
| PadErrorType
| ErrorType
/**
* Encodes a boolean into a byte array.
*
* - Docs: https://viem.sh/docs/utilities/toBytes#booltobytes
*
* @param value Boolean value to encode.
* @param opts Options.
* @returns Byte array value.
*
* @example
* import { boolToBytes } from 'viem'
* const data = boolToBytes(true)
* // Uint8Array([1])
*
* @example
* import { boolToBytes } from 'viem'
* const data = boolToBytes(true, { size: 32 })
* // Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1])
*/
export function boolToBytes(value: boolean, opts: BoolToBytesOpts = {}) {
const bytes = new Uint8Array(1)
bytes[0] = Number(value)
if (typeof opts.size === 'number') {
assertSize(bytes, { size: opts.size })
return pad(bytes, { size: opts.size })
}
return bytes
}
// We use very optimized technique to convert hex string to byte array
const charCodeMap = {
zero: 48,
nine: 57,
A: 65,
F: 70,
a: 97,
f: 102,
} as const
function charCodeToBase16(char: number) {
if (char >= charCodeMap.zero && char <= charCodeMap.nine)
return char - charCodeMap.zero
if (char >= charCodeMap.A && char <= charCodeMap.F)
return char - (charCodeMap.A - 10)
if (char >= charCodeMap.a && char <= charCodeMap.f)
return char - (charCodeMap.a - 10)
return undefined
}
export type HexToBytesOpts = {
/** Size of the output bytes. */
size?: number | undefined
}
export type HexToBytesErrorType = AssertSizeErrorType | PadErrorType | ErrorType
/**
* Encodes a hex string into a byte array.
*
* - Docs: https://viem.sh/docs/utilities/toBytes#hextobytes
*
* @param hex Hex string to encode.
* @param opts Options.
* @returns Byte array value.
*
* @example
* import { hexToBytes } from 'viem'
* const data = hexToBytes('0x48656c6c6f20776f726c6421')
* // Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33])
*
* @example
* import { hexToBytes } from 'viem'
* const data = hexToBytes('0x48656c6c6f20776f726c6421', { size: 32 })
* // Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
*/
export function hexToBytes(hex_: Hex, opts: HexToBytesOpts = {}): ByteArray {
let hex = hex_
if (opts.size) {
assertSize(hex, { size: opts.size })
hex = pad(hex, { dir: 'right', size: opts.size })
}
let hexString = hex.slice(2) as string
if (hexString.length % 2) hexString = `0${hexString}`
const length = hexString.length / 2
const bytes = new Uint8Array(length)
for (let index = 0, j = 0; index < length; index++) {
const nibbleLeft = charCodeToBase16(hexString.charCodeAt(j++))
const nibbleRight = charCodeToBase16(hexString.charCodeAt(j++))
if (nibbleLeft === undefined || nibbleRight === undefined) {
throw new BaseError(
`Invalid byte sequence ("${hexString[j - 2]}${
hexString[j - 1]
}" in "${hexString}").`,
)
}
bytes[index] = nibbleLeft * 16 + nibbleRight
}
return bytes
}
export type NumberToBytesErrorType =
| NumberToHexErrorType
| HexToBytesErrorType
| ErrorType
/**
* Encodes a number into a byte array.
*
* - Docs: https://viem.sh/docs/utilities/toBytes#numbertobytes
*
* @param value Number to encode.
* @param opts Options.
* @returns Byte array value.
*
* @example
* import { numberToBytes } from 'viem'
* const data = numberToBytes(420)
* // Uint8Array([1, 164])
*
* @example
* import { numberToBytes } from 'viem'
* const data = numberToBytes(420, { size: 4 })
* // Uint8Array([0, 0, 1, 164])
*/
export function numberToBytes(
value: bigint | number,
opts?: NumberToHexOpts | undefined,
) {
const hex = numberToHex(value, opts)
return hexToBytes(hex)
}
export type StringToBytesOpts = {
/** Size of the output bytes. */
size?: number | undefined
}
export type StringToBytesErrorType =
| AssertSizeErrorType
| PadErrorType
| ErrorType
/**
* Encodes a UTF-8 string into a byte array.
*
* - Docs: https://viem.sh/docs/utilities/toBytes#stringtobytes
*
* @param value String to encode.
* @param opts Options.
* @returns Byte array value.
*
* @example
* import { stringToBytes } from 'viem'
* const data = stringToBytes('Hello world!')
* // Uint8Array([72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33])
*
* @example
* import { stringToBytes } from 'viem'
* const data = stringToBytes('Hello world!', { size: 32 })
* // Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
*/
export function stringToBytes(
value: string,
opts: StringToBytesOpts = {},
): ByteArray {
const bytes = encoder.encode(value)
if (typeof opts.size === 'number') {
assertSize(bytes, { size: opts.size })
return pad(bytes, { dir: 'right', size: opts.size })
}
return bytes
}

249
node_modules/viem/utils/encoding/toHex.ts generated vendored Normal file
View File

@@ -0,0 +1,249 @@
import {
IntegerOutOfRangeError,
type IntegerOutOfRangeErrorType,
} from '../../errors/encoding.js'
import type { ErrorType } from '../../errors/utils.js'
import type { ByteArray, Hex } from '../../types/misc.js'
import { type PadErrorType, pad } from '../data/pad.js'
import { type AssertSizeErrorType, assertSize } from './fromHex.js'
const hexes = /*#__PURE__*/ Array.from({ length: 256 }, (_v, i) =>
i.toString(16).padStart(2, '0'),
)
export type ToHexParameters = {
/** The size (in bytes) of the output hex value. */
size?: number | undefined
}
export type ToHexErrorType =
| BoolToHexErrorType
| BytesToHexErrorType
| NumberToHexErrorType
| StringToHexErrorType
| ErrorType
/**
* Encodes a string, number, bigint, or ByteArray into a hex string
*
* - Docs: https://viem.sh/docs/utilities/toHex
* - Example: https://viem.sh/docs/utilities/toHex#usage
*
* @param value Value to encode.
* @param opts Options.
* @returns Hex value.
*
* @example
* import { toHex } from 'viem'
* const data = toHex('Hello world')
* // '0x48656c6c6f20776f726c6421'
*
* @example
* import { toHex } from 'viem'
* const data = toHex(420)
* // '0x1a4'
*
* @example
* import { toHex } from 'viem'
* const data = toHex('Hello world', { size: 32 })
* // '0x48656c6c6f20776f726c64210000000000000000000000000000000000000000'
*/
export function toHex(
value: string | number | bigint | boolean | ByteArray,
opts: ToHexParameters = {},
): Hex {
if (typeof value === 'number' || typeof value === 'bigint')
return numberToHex(value, opts)
if (typeof value === 'string') {
return stringToHex(value, opts)
}
if (typeof value === 'boolean') return boolToHex(value, opts)
return bytesToHex(value, opts)
}
export type BoolToHexOpts = {
/** The size (in bytes) of the output hex value. */
size?: number | undefined
}
export type BoolToHexErrorType = AssertSizeErrorType | PadErrorType | ErrorType
/**
* Encodes a boolean into a hex string
*
* - Docs: https://viem.sh/docs/utilities/toHex#booltohex
*
* @param value Value to encode.
* @param opts Options.
* @returns Hex value.
*
* @example
* import { boolToHex } from 'viem'
* const data = boolToHex(true)
* // '0x1'
*
* @example
* import { boolToHex } from 'viem'
* const data = boolToHex(false)
* // '0x0'
*
* @example
* import { boolToHex } from 'viem'
* const data = boolToHex(true, { size: 32 })
* // '0x0000000000000000000000000000000000000000000000000000000000000001'
*/
export function boolToHex(value: boolean, opts: BoolToHexOpts = {}): Hex {
const hex: Hex = `0x${Number(value)}`
if (typeof opts.size === 'number') {
assertSize(hex, { size: opts.size })
return pad(hex, { size: opts.size })
}
return hex
}
export type BytesToHexOpts = {
/** The size (in bytes) of the output hex value. */
size?: number | undefined
}
export type BytesToHexErrorType = AssertSizeErrorType | PadErrorType | ErrorType
/**
* Encodes a bytes array into a hex string
*
* - Docs: https://viem.sh/docs/utilities/toHex#bytestohex
*
* @param value Value to encode.
* @param opts Options.
* @returns Hex value.
*
* @example
* import { bytesToHex } from 'viem'
* const data = bytesToHex(Uint8Array.from([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33])
* // '0x48656c6c6f20576f726c6421'
*
* @example
* import { bytesToHex } from 'viem'
* const data = bytesToHex(Uint8Array.from([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33]), { size: 32 })
* // '0x48656c6c6f20576f726c64210000000000000000000000000000000000000000'
*/
export function bytesToHex(value: ByteArray, opts: BytesToHexOpts = {}): Hex {
let string = ''
for (let i = 0; i < value.length; i++) {
string += hexes[value[i]]
}
const hex = `0x${string}` as const
if (typeof opts.size === 'number') {
assertSize(hex, { size: opts.size })
return pad(hex, { dir: 'right', size: opts.size })
}
return hex
}
export type NumberToHexOpts =
| {
/** Whether or not the number of a signed representation. */
signed?: boolean | undefined
/** The size (in bytes) of the output hex value. */
size: number
}
| {
signed?: undefined
/** The size (in bytes) of the output hex value. */
size?: number | undefined
}
export type NumberToHexErrorType =
| IntegerOutOfRangeErrorType
| PadErrorType
| ErrorType
/**
* Encodes a number or bigint into a hex string
*
* - Docs: https://viem.sh/docs/utilities/toHex#numbertohex
*
* @param value Value to encode.
* @param opts Options.
* @returns Hex value.
*
* @example
* import { numberToHex } from 'viem'
* const data = numberToHex(420)
* // '0x1a4'
*
* @example
* import { numberToHex } from 'viem'
* const data = numberToHex(420, { size: 32 })
* // '0x00000000000000000000000000000000000000000000000000000000000001a4'
*/
export function numberToHex(
value_: number | bigint,
opts: NumberToHexOpts = {},
): Hex {
const { signed, size } = opts
const value = BigInt(value_)
let maxValue: bigint | number | undefined
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 hex = `0x${(
signed && value < 0 ? (1n << BigInt(size * 8)) + BigInt(value) : value
).toString(16)}` as Hex
if (size) return pad(hex, { size }) as Hex
return hex
}
export type StringToHexOpts = {
/** The size (in bytes) of the output hex value. */
size?: number | undefined
}
export type StringToHexErrorType = BytesToHexErrorType | ErrorType
const encoder = /*#__PURE__*/ new TextEncoder()
/**
* Encodes a UTF-8 string into a hex string
*
* - Docs: https://viem.sh/docs/utilities/toHex#stringtohex
*
* @param value Value to encode.
* @param opts Options.
* @returns Hex value.
*
* @example
* import { stringToHex } from 'viem'
* const data = stringToHex('Hello World!')
* // '0x48656c6c6f20576f726c6421'
*
* @example
* import { stringToHex } from 'viem'
* const data = stringToHex('Hello World!', { size: 32 })
* // '0x48656c6c6f20576f726c64210000000000000000000000000000000000000000'
*/
export function stringToHex(value_: string, opts: StringToHexOpts = {}): Hex {
const value = encoder.encode(value_)
return bytesToHex(value, opts)
}

135
node_modules/viem/utils/encoding/toRlp.ts generated vendored Normal file
View File

@@ -0,0 +1,135 @@
import { BaseError } from '../../errors/base.js'
import type { ErrorType } from '../../errors/utils.js'
import type { ByteArray, Hex } from '../../types/misc.js'
import {
type CreateCursorErrorType,
type Cursor,
createCursor,
} from '../cursor.js'
import { type HexToBytesErrorType, hexToBytes } from './toBytes.js'
import { type BytesToHexErrorType, bytesToHex } from './toHex.js'
export type RecursiveArray<T> = T | readonly RecursiveArray<T>[]
type To = 'hex' | 'bytes'
type Encodable = {
length: number
encode(cursor: Cursor): void
}
export type ToRlpReturnType<to extends To> =
| (to extends 'bytes' ? ByteArray : never)
| (to extends 'hex' ? Hex : never)
export type ToRlpErrorType =
| CreateCursorErrorType
| BytesToHexErrorType
| HexToBytesErrorType
| ErrorType
export function toRlp<to extends To = 'hex'>(
bytes: RecursiveArray<ByteArray> | RecursiveArray<Hex>,
to: to | To | undefined = 'hex',
): ToRlpReturnType<to> {
const encodable = getEncodable(bytes)
const cursor = createCursor(new Uint8Array(encodable.length))
encodable.encode(cursor)
if (to === 'hex') return bytesToHex(cursor.bytes) as ToRlpReturnType<to>
return cursor.bytes as ToRlpReturnType<to>
}
export type BytesToRlpErrorType = ToRlpErrorType | ErrorType
export function bytesToRlp<to extends To = 'bytes'>(
bytes: RecursiveArray<ByteArray>,
to: to | To | undefined = 'bytes',
): ToRlpReturnType<to> {
return toRlp(bytes, to)
}
export type HexToRlpErrorType = ToRlpErrorType | ErrorType
export function hexToRlp<to extends To = 'hex'>(
hex: RecursiveArray<Hex>,
to: to | To | undefined = 'hex',
): ToRlpReturnType<to> {
return toRlp(hex, to)
}
function getEncodable(
bytes: RecursiveArray<ByteArray> | RecursiveArray<Hex>,
): Encodable {
if (Array.isArray(bytes))
return getEncodableList(bytes.map((x) => getEncodable(x)))
return getEncodableBytes(bytes as any)
}
function getEncodableList(list: Encodable[]): Encodable {
const bodyLength = list.reduce((acc, x) => acc + x.length, 0)
const sizeOfBodyLength = getSizeOfLength(bodyLength)
const length = (() => {
if (bodyLength <= 55) return 1 + bodyLength
return 1 + sizeOfBodyLength + bodyLength
})()
return {
length,
encode(cursor: Cursor) {
if (bodyLength <= 55) {
cursor.pushByte(0xc0 + bodyLength)
} else {
cursor.pushByte(0xc0 + 55 + sizeOfBodyLength)
if (sizeOfBodyLength === 1) cursor.pushUint8(bodyLength)
else if (sizeOfBodyLength === 2) cursor.pushUint16(bodyLength)
else if (sizeOfBodyLength === 3) cursor.pushUint24(bodyLength)
else cursor.pushUint32(bodyLength)
}
for (const { encode } of list) {
encode(cursor)
}
},
}
}
function getEncodableBytes(bytesOrHex: ByteArray | Hex): Encodable {
const bytes =
typeof bytesOrHex === 'string' ? hexToBytes(bytesOrHex) : bytesOrHex
const sizeOfBytesLength = getSizeOfLength(bytes.length)
const length = (() => {
if (bytes.length === 1 && bytes[0] < 0x80) return 1
if (bytes.length <= 55) return 1 + bytes.length
return 1 + sizeOfBytesLength + bytes.length
})()
return {
length,
encode(cursor: Cursor) {
if (bytes.length === 1 && bytes[0] < 0x80) {
cursor.pushBytes(bytes)
} else if (bytes.length <= 55) {
cursor.pushByte(0x80 + bytes.length)
cursor.pushBytes(bytes)
} else {
cursor.pushByte(0x80 + 55 + sizeOfBytesLength)
if (sizeOfBytesLength === 1) cursor.pushUint8(bytes.length)
else if (sizeOfBytesLength === 2) cursor.pushUint16(bytes.length)
else if (sizeOfBytesLength === 3) cursor.pushUint24(bytes.length)
else cursor.pushUint32(bytes.length)
cursor.pushBytes(bytes)
}
},
}
}
function getSizeOfLength(length: number) {
if (length < 2 ** 8) return 1
if (length < 2 ** 16) return 2
if (length < 2 ** 24) return 3
if (length < 2 ** 32) return 4
throw new BaseError('Length is too large.')
}