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

11
node_modules/ox/core/internal/abi.ts generated vendored Normal file
View File

@@ -0,0 +1,11 @@
import type * as Abi from '../Abi.js'
/** @internal */
export function isSignatures(
value: Abi.Abi | readonly string[],
): value is readonly string[] {
for (const item of value) {
if (typeof item !== 'string') return false
}
return true
}

32
node_modules/ox/core/internal/abiConstructor.ts generated vendored Normal file
View File

@@ -0,0 +1,32 @@
import type * as AbiItem_internal from './abiItem.js'
import type { TypeErrorMessage } from './types.js'
/** @internal */
export type IsSignature<signature extends string> =
| (AbiItem_internal.IsConstructorSignature<signature> extends true
? true
: never)
| (AbiItem_internal.IsStructSignature<signature> extends true
? true
: never) extends infer condition
? [condition] extends [never]
? false
: true
: false
/** @internal */
export type Signature<
signature extends string,
key extends string | unknown = unknown,
> = IsSignature<signature> extends true
? signature
: string extends signature // if exactly `string` (not narrowed), then pass through as valid
? signature
: TypeErrorMessage<`Signature "${signature}" is invalid${key extends string
? ` at position ${key}`
: ''}.`>
/** @internal */
export type Signatures<signatures extends readonly string[]> = {
[key in keyof signatures]: Signature<signatures[key], key>
}

30
node_modules/ox/core/internal/abiError.ts generated vendored Normal file
View File

@@ -0,0 +1,30 @@
import type * as AbiItem_internal from './abiItem.js'
import type { TypeErrorMessage } from './types.js'
/** @internal */
export type IsSignature<signature extends string> =
| (AbiItem_internal.IsErrorSignature<signature> extends true ? true : never)
| (AbiItem_internal.IsStructSignature<signature> extends true
? true
: never) extends infer condition
? [condition] extends [never]
? false
: true
: false
/** @internal */
export type Signature<
signature extends string,
key extends string | unknown = unknown,
> = IsSignature<signature> extends true
? signature
: string extends signature // if exactly `string` (not narrowed), then pass through as valid
? signature
: TypeErrorMessage<`Signature "${signature}" is invalid${key extends string
? ` at position ${key}`
: ''}.`>
/** @internal */
export type Signatures<signatures extends readonly string[]> = {
[key in keyof signatures]: Signature<signatures[key], key>
}

154
node_modules/ox/core/internal/abiEvent.ts generated vendored Normal file
View File

@@ -0,0 +1,154 @@
import type * as abitype from 'abitype'
import type * as Filter from '../Filter.js'
import type * as Hex from '../Hex.js'
import type * as AbiItem_internal from './abiItem.js'
import type {
Compute,
Filter as Filter_internal,
MaybeRequired,
TypeErrorMessage,
UnionToIntersection,
} from './types.js'
/** @internal */
export type EventParameterOptions = {
EnableUnion?: boolean
IndexedOnly?: boolean
Required?: boolean
}
/** @internal */
export type DefaultEventParameterOptions = {
EnableUnion: true
IndexedOnly: true
Required: false
}
/** @internal */
export type IsSignature<signature extends string> =
| (AbiItem_internal.IsEventSignature<signature> extends true ? true : never)
| (AbiItem_internal.IsStructSignature<signature> extends true
? true
: never) extends infer condition
? [condition] extends [never]
? false
: true
: false
/** @internal */
export type Signature<
signature extends string,
key extends string | unknown = unknown,
> = IsSignature<signature> extends true
? signature
: string extends signature // if exactly `string` (not narrowed), then pass through as valid
? signature
: TypeErrorMessage<`Signature "${signature}" is invalid${key extends string
? ` at position ${key}`
: ''}.`>
/** @internal */
export type Signatures<signatures extends readonly string[]> = {
[key in keyof signatures]: Signature<signatures[key], key>
}
/** @internal */
export type ParametersToPrimitiveTypes<
abiParameters extends readonly abitype.AbiParameter[],
options extends EventParameterOptions = DefaultEventParameterOptions,
// Remove non-indexed parameters based on `Options['IndexedOnly']`
> = abiParameters extends readonly []
? readonly []
: Filter_internal<
abiParameters,
options['IndexedOnly'] extends true ? { indexed: true } : object
> extends infer Filtered extends readonly abitype.AbiParameter[]
? Filtered extends readonly []
? readonly []
: HasNamedAbiParameter<Filtered> extends true
? // All tuple parameters are named so return as object
UnionToIntersection<
{
[index in keyof Filtered]: Filtered[index] extends {
name: infer name extends string
}
? {
[key in name]?:
| ParameterToPrimitiveType<Filtered[index], options>
| undefined
}
: {
[key in index]?:
| ParameterToPrimitiveType<Filtered[index], options>
| undefined
}
}[number]
> extends infer Mapped
? Compute<
MaybeRequired<
Mapped,
options['Required'] extends boolean
? options['Required']
: false
>
>
: never
: // Has unnamed tuple parameters so return as array
| readonly [
...{
[K in keyof Filtered]: ParameterToPrimitiveType<
Filtered[K],
options
>
},
]
// Distribute over tuple to represent optional parameters
| (options['Required'] extends true
? never
: // Distribute over tuple to represent optional parameters
Filtered extends readonly [
...infer Head extends readonly abitype.AbiParameter[],
infer _,
]
? ParametersToPrimitiveTypes<
readonly [
...{ [K in keyof Head]: Omit<Head[K], 'name'> },
],
options
>
: never)
: never
/** @internal */
export type ParameterToPrimitiveType<
abiParameter extends abitype.AbiParameter,
//
options extends EventParameterOptions = DefaultEventParameterOptions,
_type = abitype.AbiParameterToPrimitiveType<abiParameter>,
> = options['EnableUnion'] extends true ? TopicType<_type> : _type
/** @internal */
export type TopicType<
primitiveType = Hex.Hex,
topic extends Filter.Topic = Filter.Topic,
> = topic extends Hex.Hex
? primitiveType
: topic extends readonly Hex.Hex[]
? primitiveType[]
: topic extends null
? null
: never
/** @internal */
export type HasNamedAbiParameter<
abiParameters extends readonly abitype.AbiParameter[],
> = abiParameters extends readonly [
infer Head extends abitype.AbiParameter,
...infer Tail extends readonly abitype.AbiParameter[],
]
? Head extends { name: string }
? Head['name'] extends ''
? HasNamedAbiParameter<Tail>
: true
: HasNamedAbiParameter<Tail>
: false

32
node_modules/ox/core/internal/abiFunction.ts generated vendored Normal file
View File

@@ -0,0 +1,32 @@
import type * as AbiItem_internal from './abiItem.js'
import type { TypeErrorMessage } from './types.js'
/** @internal */
export type IsSignature<signature extends string> =
| (AbiItem_internal.IsFunctionSignature<signature> extends true
? true
: never)
| (AbiItem_internal.IsStructSignature<signature> extends true
? true
: never) extends infer condition
? [condition] extends [never]
? false
: true
: false
/** @internal */
export type Signature<
signature extends string,
key extends string | unknown = unknown,
> = IsSignature<signature> extends true
? signature
: string extends signature // if exactly `string` (not narrowed), then pass through as valid
? signature
: TypeErrorMessage<`Signature "${signature}" is invalid${key extends string
? ` at position ${key}`
: ''}.`>
/** @internal */
export type Signatures<signatures extends readonly string[]> = {
[key in keyof signatures]: Signature<signatures[key], key>
}

593
node_modules/ox/core/internal/abiItem.ts generated vendored Normal file
View File

@@ -0,0 +1,593 @@
import type * as abitype from 'abitype'
import type * as Abi from '../Abi.js'
import type * as AbiItem from '../AbiItem.js'
import type * as AbiParameters from '../AbiParameters.js'
import * as Address from '../Address.js'
import * as Errors from '../Errors.js'
import type {
Compute,
IsNever,
IsUnion,
TypeErrorMessage,
UnionToTuple,
} from './types.js'
/** @internal */
export type ExtractArgs<
abi extends Abi.Abi | readonly unknown[] = Abi.Abi,
name extends AbiItem.Name<abi> = AbiItem.Name<abi>,
> = abitype.AbiParametersToPrimitiveTypes<
AbiItem.FromAbi<abi extends Abi.Abi ? abi : Abi.Abi, name>['inputs'],
'inputs'
> extends infer args
? [args] extends [never]
? readonly unknown[]
: args
: readonly unknown[]
/** @internal */
export type ExtractForArgs<
abi extends Abi.Abi,
name extends AbiItem.Name<abi>,
args extends ExtractArgs<abi, name>,
> = IsUnion<name> extends true
? {
[key in keyof abi]: abi[key] extends { name: name } ? abi[key] : never
}[number]
: AbiItem.FromAbi<abi, name> extends infer abiItem extends AbiItem.AbiItem & {
inputs: readonly abitype.AbiParameter[]
}
? IsUnion<abiItem> extends true // narrow overloads using `args` by converting to tuple and filtering out overloads that don't match
? UnionToTuple<abiItem> extends infer abiItems extends
readonly (AbiItem.AbiItem & {
inputs: readonly abitype.AbiParameter[]
})[]
? IsNever<TupleToUnion<abiItems, abi, name, args>> extends true
? Compute<
abiItems[0] & {
readonly overloads: UnionToTuple<
Exclude<abiItems[number], abiItems[0]>
>
}
>
: TupleToUnion<abiItems, abi, name, args> // convert back to union (removes `never` tuple entries: `['foo', never, 'bar'][number]` => `'foo' | 'bar'`)
: never
: abiItem
: never
/** @internal */
export type TupleToUnion<
abiItems extends readonly {
inputs: readonly abitype.AbiParameter[]
}[],
abi extends Abi.Abi,
name extends AbiItem.Name<abi>,
args extends ExtractArgs<abi, name>,
> = {
[k in keyof abiItems]: (
readonly [] extends args
? readonly [] // fallback to `readonly []` if `args` has no value (e.g. `args` property not provided)
: args
) extends abitype.AbiParametersToPrimitiveTypes<
abiItems[k]['inputs'],
'inputs'
>
? abiItems[k]
: never
}[number]
/** @internal */
export type ErrorSignature<
name extends string = string,
parameters extends string = string,
> = `error ${name}(${parameters})`
/** @internal */
export type IsErrorSignature<signature extends string> =
signature extends ErrorSignature<infer name> ? IsName<name> : false
/** @internal */
export type EventSignature<
name extends string = string,
parameters extends string = string,
> = `event ${name}(${parameters})`
/** @internal */
export type IsEventSignature<signature extends string> =
signature extends EventSignature<infer name> ? IsName<name> : false
/** @internal */
export type FunctionSignature<
name extends string = string,
tail extends string = string,
> = `function ${name}(${tail}`
export type IsFunctionSignature<signature> =
signature extends FunctionSignature<infer name>
? IsName<name> extends true
? signature extends ValidFunctionSignatures
? true
: // Check that `Parameters` is not absorbing other types (e.g. `returns`)
signature extends `function ${string}(${infer parameters})`
? parameters extends InvalidFunctionParameters
? false
: true
: false
: false
: false
/** @internal */
export type Scope = 'public' | 'external' // `internal` or `private` functions wouldn't make it to ABI so can ignore
/** @internal */
export type Returns = `returns (${string})` | `returns(${string})`
// Almost all valid function signatures, except `function ${string}(${infer parameters})` since `parameters` can absorb returns
/** @internal */
export type ValidFunctionSignatures =
| `function ${string}()`
// basic
| `function ${string}() ${Returns}`
| `function ${string}() ${abitype.AbiStateMutability}`
| `function ${string}() ${Scope}`
// combinations
| `function ${string}() ${abitype.AbiStateMutability} ${Returns}`
| `function ${string}() ${Scope} ${Returns}`
| `function ${string}() ${Scope} ${abitype.AbiStateMutability}`
| `function ${string}() ${Scope} ${abitype.AbiStateMutability} ${Returns}`
// Parameters
| `function ${string}(${string}) ${Returns}`
| `function ${string}(${string}) ${abitype.AbiStateMutability}`
| `function ${string}(${string}) ${Scope}`
| `function ${string}(${string}) ${abitype.AbiStateMutability} ${Returns}`
| `function ${string}(${string}) ${Scope} ${Returns}`
| `function ${string}(${string}) ${Scope} ${abitype.AbiStateMutability}`
| `function ${string}(${string}) ${Scope} ${abitype.AbiStateMutability} ${Returns}`
/** @internal */
export type StructSignature<
name extends string = string,
properties extends string = string,
> = `struct ${name} {${properties}}`
/** @internal */
export type IsStructSignature<signature extends string> =
signature extends StructSignature<infer name> ? IsName<name> : false
/** @internal */
export type ConstructorSignature<tail extends string = string> =
`constructor(${tail}`
/** @internal */
export type IsConstructorSignature<signature> =
signature extends ConstructorSignature
? signature extends ValidConstructorSignatures
? true
: false
: false
/** @internal */
export type ValidConstructorSignatures =
| `constructor(${string})`
| `constructor(${string}) payable`
/** @internal */
export type FallbackSignature<abiStateMutability extends '' | ' payable' = ''> =
`fallback() external${abiStateMutability}`
/** @internal */
export type ReceiveSignature = 'receive() external payable'
// TODO: Maybe use this for signature validation one day
// https://twitter.com/devanshj__/status/1610423724708343808
/** @internal */
export type IsSignature<type extends string> =
| (IsErrorSignature<type> extends true ? true : never)
| (IsEventSignature<type> extends true ? true : never)
| (IsFunctionSignature<type> extends true ? true : never)
| (IsStructSignature<type> extends true ? true : never)
| (IsConstructorSignature<type> extends true ? true : never)
| (type extends FallbackSignature ? true : never)
| (type extends ReceiveSignature ? true : never) extends infer condition
? [condition] extends [never]
? false
: true
: false
/** @internal */
export type Signature<
string1 extends string,
string2 extends string | unknown = unknown,
> = IsSignature<string1> extends true
? string1
: string extends string1 // if exactly `string` (not narrowed), then pass through as valid
? string1
: TypeErrorMessage<`Signature "${string1}" is invalid${string2 extends string
? ` at position ${string2}`
: ''}.`>
/** @internal */
export type Signatures<signatures extends readonly string[]> = {
[key in keyof signatures]: Signature<signatures[key], key>
}
/** @internal */
export type IsName<name extends string> = name extends ''
? false
: ValidateName<name> extends name
? true
: false
/** @internal */
export type ValidateName<
name extends string,
checkCharacters extends boolean = false,
> = name extends `${string}${' '}${string}`
? TypeErrorMessage<`Identifier "${name}" cannot contain whitespace.`>
: IsSolidityKeyword<name> extends true
? TypeErrorMessage<`"${name}" is a protected Solidity keyword.`>
: name extends `${number}`
? TypeErrorMessage<`Identifier "${name}" cannot be a number string.`>
: name extends `${number}${string}`
? TypeErrorMessage<`Identifier "${name}" cannot start with a number.`>
: checkCharacters extends true
? IsValidCharacter<name> extends true
? name
: TypeErrorMessage<`"${name}" contains invalid character.`>
: name
/** @internal */
export type IsSolidityKeyword<type extends string> =
type extends SolidityKeywords ? true : false
/** @internal */
export type SolidityKeywords =
| 'after'
| 'alias'
| 'anonymous'
| 'apply'
| 'auto'
| 'byte'
| 'calldata'
| 'case'
| 'catch'
| 'constant'
| 'copyof'
| 'default'
| 'defined'
| 'error'
| 'event'
| 'external'
| 'false'
| 'final'
| 'function'
| 'immutable'
| 'implements'
| 'in'
| 'indexed'
| 'inline'
| 'internal'
| 'let'
| 'mapping'
| 'match'
| 'memory'
| 'mutable'
| 'null'
| 'of'
| 'override'
| 'partial'
| 'private'
| 'promise'
| 'public'
| 'pure'
| 'reference'
| 'relocatable'
| 'return'
| 'returns'
| 'sizeof'
| 'static'
| 'storage'
| 'struct'
| 'super'
| 'supports'
| 'switch'
| 'this'
| 'true'
| 'try'
| 'typedef'
| 'typeof'
| 'var'
| 'view'
| 'virtual'
| `address${`[${string}]` | ''}`
| `bool${`[${string}]` | ''}`
| `string${`[${string}]` | ''}`
| `tuple${`[${string}]` | ''}`
| `bytes${number | ''}${`[${string}]` | ''}`
| `${'u' | ''}int${number | ''}${`[${string}]` | ''}`
/** @internal */
export type IsValidCharacter<character extends string> =
character extends `${ValidCharacters}${infer tail}`
? tail extends ''
? true
: IsValidCharacter<tail>
: false
// biome-ignore format: no formatting
/** @internal */
export type ValidCharacters =
// uppercase letters
| 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z'
// lowercase letters
| 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z'
// numbers
| '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
// special characters
| '_' | '$'
// Template string inference can absorb `returns`:
// type Result = `function foo(string) return s (uint256)` extends `function ${string}(${infer Parameters})` ? Parameters : never
// // ^? type Result = "string ) return s (uint256"
// So we need to validate against `returns` keyword with all combinations of whitespace
/** @internal */
export type InvalidFunctionParameters =
| `${string}${MangledReturns} (${string}`
| `${string}) ${MangledReturns}${string}`
| `${string})${string}${MangledReturns}${string}(${string}`
// r_e_t_u_r_n_s
/** @internal */
export type MangledReturns =
// Single
| `r${string}eturns`
| `re${string}turns`
| `ret${string}urns`
| `retu${string}rns`
| `retur${string}ns`
| `return${string}s`
// Double
// `r_e*`
| `r${string}e${string}turns`
| `r${string}et${string}urns`
| `r${string}etu${string}rns`
| `r${string}etur${string}ns`
| `r${string}eturn${string}s`
// `re_t*`
| `re${string}t${string}urns`
| `re${string}tu${string}rns`
| `re${string}tur${string}ns`
| `re${string}turn${string}s`
// `ret_u*`
| `ret${string}u${string}rns`
| `ret${string}ur${string}ns`
| `ret${string}urn${string}s`
// `retu_r*`
| `retu${string}r${string}ns`
| `retu${string}rn${string}s`
// `retur_n*`
| `retur${string}n${string}s`
// Triple
// `r_e_t*`
| `r${string}e${string}t${string}urns`
| `r${string}e${string}tu${string}rns`
| `r${string}e${string}tur${string}ns`
| `r${string}e${string}turn${string}s`
// `re_t_u*`
| `re${string}t${string}u${string}rns`
| `re${string}t${string}ur${string}ns`
| `re${string}t${string}urn${string}s`
// `ret_u_r*`
| `ret${string}u${string}r${string}ns`
| `ret${string}u${string}rn${string}s`
// `retu_r_n*`
| `retu${string}r${string}n${string}s`
// Quadruple
// `r_e_t_u*`
| `r${string}e${string}t${string}u${string}rns`
| `r${string}e${string}t${string}ur${string}ns`
| `r${string}e${string}t${string}urn${string}s`
// `re_t_u_r*`
| `re${string}t${string}u${string}r${string}ns`
| `re${string}t${string}u${string}rn${string}s`
// `ret_u_r_n*`
| `ret${string}u${string}r${string}n${string}s`
// Quintuple
// `r_e_t_u_r*`
| `r${string}e${string}t${string}u${string}r${string}ns`
| `r${string}e${string}t${string}u${string}rn${string}s`
// `re_t_u_r_n*`
| `re${string}t${string}u${string}r${string}n${string}s`
// Sextuple
// `r_e_t_u_r_n_s`
| `r${string}e${string}t${string}u${string}r${string}n${string}s`
/** @internal */
export type Widen<type> =
| ([unknown] extends [type] ? unknown : never)
| (type extends Function ? type : never)
| (type extends abitype.ResolvedRegister['bigIntType'] ? bigint : never)
| (type extends boolean ? boolean : never)
| (type extends abitype.ResolvedRegister['intType'] ? number : never)
| (type extends string
? type extends abitype.ResolvedRegister['addressType']
? abitype.ResolvedRegister['addressType']
: type extends abitype.ResolvedRegister['bytesType']['inputs']
? abitype.ResolvedRegister['bytesType']
: string
: never)
| (type extends readonly [] ? readonly [] : never)
| (type extends Record<string, unknown>
? { [K in keyof type]: Widen<type[K]> }
: never)
| (type extends { length: number }
? {
[K in keyof type]: Widen<type[K]>
} extends infer Val extends readonly unknown[]
? readonly [...Val]
: never
: never)
/** @internal */
export function normalizeSignature(signature: string): string {
let active = true
let current = ''
let level = 0
let result = ''
let valid = false
for (let i = 0; i < signature.length; i++) {
const char = signature[i]!
// If the character is a separator, we want to reactivate.
if (['(', ')', ','].includes(char)) active = true
// If the character is a "level" token, we want to increment/decrement.
if (char === '(') level++
if (char === ')') level--
// If we aren't active, we don't want to mutate the result.
if (!active) continue
// If level === 0, we are at the definition level.
if (level === 0) {
if (char === ' ' && ['event', 'function', 'error', ''].includes(result))
result = ''
else {
result += char
// If we are at the end of the definition, we must be finished.
if (char === ')') {
valid = true
break
}
}
continue
}
// Ignore spaces
if (char === ' ') {
// If the previous character is a separator, and the current section isn't empty, we want to deactivate.
if (signature[i - 1] !== ',' && current !== ',' && current !== ',(') {
current = ''
active = false
}
continue
}
result += char
current += char
}
if (!valid) throw new Errors.BaseError('Unable to normalize signature.')
return result
}
/** @internal */
export declare namespace normalizeSignature {
export type ErrorType = Errors.BaseError | Errors.GlobalErrorType
}
/** @internal */
export function isArgOfType(
arg: unknown,
abiParameter: AbiParameters.Parameter,
): boolean {
const argType = typeof arg
const abiParameterType = abiParameter.type
switch (abiParameterType) {
case 'address':
return Address.validate(arg as Address.Address, { strict: false })
case 'bool':
return argType === 'boolean'
case 'function':
return argType === 'string'
case 'string':
return argType === 'string'
default: {
if (abiParameterType === 'tuple' && 'components' in abiParameter)
return Object.values(abiParameter.components).every(
(component, index) => {
return isArgOfType(
Object.values(arg as unknown[] | Record<string, unknown>)[index],
component as AbiParameters.Parameter,
)
},
)
// `(u)int<M>`: (un)signed integer type of `M` bits, `0 < M <= 256`, `M % 8 == 0`
// https://regexr.com/6v8hp
if (
/^u?int(8|16|24|32|40|48|56|64|72|80|88|96|104|112|120|128|136|144|152|160|168|176|184|192|200|208|216|224|232|240|248|256)?$/.test(
abiParameterType,
)
)
return argType === 'number' || argType === 'bigint'
// `bytes<M>`: binary type of `M` bytes, `0 < M <= 32`
// https://regexr.com/6va55
if (/^bytes([1-9]|1[0-9]|2[0-9]|3[0-2])?$/.test(abiParameterType))
return argType === 'string' || arg instanceof Uint8Array
// fixed-length (`<type>[M]`) and dynamic (`<type>[]`) arrays
// https://regexr.com/6va6i
if (/[a-z]+[1-9]{0,3}(\[[0-9]{0,}\])+$/.test(abiParameterType)) {
return (
Array.isArray(arg) &&
arg.every((x: unknown) =>
isArgOfType(x, {
...abiParameter,
// Pop off `[]` or `[M]` from end of type
type: abiParameterType.replace(/(\[[0-9]{0,}\])$/, ''),
} as AbiParameters.Parameter),
)
)
}
return false
}
}
}
/** @internal */
export function getAmbiguousTypes(
sourceParameters: readonly AbiParameters.Parameter[],
targetParameters: readonly AbiParameters.Parameter[],
args: ExtractArgs,
): AbiParameters.Parameter['type'][] | undefined {
for (const parameterIndex in sourceParameters) {
const sourceParameter = sourceParameters[parameterIndex]!
const targetParameter = targetParameters[parameterIndex]!
if (
sourceParameter.type === 'tuple' &&
targetParameter.type === 'tuple' &&
'components' in sourceParameter &&
'components' in targetParameter
)
return getAmbiguousTypes(
sourceParameter.components,
targetParameter.components,
(args as any)[parameterIndex],
)
const types = [sourceParameter.type, targetParameter.type]
const ambiguous = (() => {
if (types.includes('address') && types.includes('bytes20')) return true
if (types.includes('address') && types.includes('string'))
return Address.validate(args[parameterIndex] as Address.Address, {
strict: false,
})
if (types.includes('address') && types.includes('bytes'))
return Address.validate(args[parameterIndex] as Address.Address, {
strict: false,
})
return false
})()
if (ambiguous) return types
}
return
}

811
node_modules/ox/core/internal/abiParameters.ts generated vendored Normal file
View File

@@ -0,0 +1,811 @@
import type {
AbiParameter,
AbiParameterKind,
AbiParameterToPrimitiveType,
AbiParametersToPrimitiveTypes,
} from 'abitype'
import * as AbiParameters from '../AbiParameters.js'
import * as Address from '../Address.js'
import * as Bytes from '../Bytes.js'
import * as Errors from '../Errors.js'
import * as Hex from '../Hex.js'
import { integerRegex } from '../Solidity.js'
import type * as Cursor from './cursor.js'
import type { Compute, IsNarrowable, UnionToIntersection } from './types.js'
/** @internal */
export type ParameterToPrimitiveType<
abiParameter extends AbiParameter | { name: string; type: unknown },
abiParameterKind extends AbiParameterKind = AbiParameterKind,
> = AbiParameterToPrimitiveType<abiParameter, abiParameterKind>
/** @internal */
export type PreparedParameter = { dynamic: boolean; encoded: Hex.Hex }
/** @internal */
export type ToObject<
parameters extends readonly AbiParameter[],
kind extends AbiParameterKind = AbiParameterKind,
> = IsNarrowable<parameters, AbiParameters.AbiParameters> extends true
? Compute<
UnionToIntersection<
{
[index in keyof parameters]: parameters[index] extends {
name: infer name extends string
}
? {
[key in name]: AbiParameterToPrimitiveType<
parameters[index],
kind
>
}
: {
[key in index]: AbiParameterToPrimitiveType<
parameters[index],
kind
>
}
}[number]
>
>
: unknown
/** @internal */
export type ToPrimitiveTypes<
abiParameters extends readonly AbiParameter[],
abiParameterKind extends AbiParameterKind = AbiParameterKind,
> = AbiParametersToPrimitiveTypes<abiParameters, abiParameterKind>
/** @internal */
export type Tuple = ParameterToPrimitiveType<TupleAbiParameter>
/** @internal */
export function decodeParameter(
cursor: Cursor.Cursor,
param: AbiParameters.Parameter,
options: { checksumAddress?: boolean | undefined; staticPosition: number },
) {
const { checksumAddress, staticPosition } = options
const arrayComponents = getArrayComponents(param.type)
if (arrayComponents) {
const [length, type] = arrayComponents
return decodeArray(
cursor,
{ ...param, type },
{ checksumAddress, length, staticPosition },
)
}
if (param.type === 'tuple')
return decodeTuple(cursor, param as TupleAbiParameter, {
checksumAddress,
staticPosition,
})
if (param.type === 'address')
return decodeAddress(cursor, { checksum: checksumAddress })
if (param.type === 'bool') return decodeBool(cursor)
if (param.type.startsWith('bytes'))
return decodeBytes(cursor, param, { staticPosition })
if (param.type.startsWith('uint') || param.type.startsWith('int'))
return decodeNumber(cursor, param)
if (param.type === 'string') return decodeString(cursor, { staticPosition })
throw new AbiParameters.InvalidTypeError(param.type)
}
export declare namespace decodeParameter {
type ErrorType =
| decodeArray.ErrorType
| decodeTuple.ErrorType
| decodeAddress.ErrorType
| decodeBool.ErrorType
| decodeBytes.ErrorType
| decodeNumber.ErrorType
| decodeString.ErrorType
| AbiParameters.InvalidTypeError
| Errors.GlobalErrorType
}
const sizeOfLength = 32
const sizeOfOffset = 32
/** @internal */
export function decodeAddress(
cursor: Cursor.Cursor,
options: { checksum?: boolean | undefined } = {},
) {
const { checksum = false } = options
const value = cursor.readBytes(32)
const wrap = (address: Hex.Hex) =>
checksum ? Address.checksum(address) : address
return [wrap(Hex.fromBytes(Bytes.slice(value, -20))), 32]
}
export declare namespace decodeAddress {
type ErrorType =
| Hex.fromBytes.ErrorType
| Bytes.slice.ErrorType
| Errors.GlobalErrorType
}
/** @internal */
export function decodeArray(
cursor: Cursor.Cursor,
param: AbiParameters.Parameter,
options: {
checksumAddress?: boolean | undefined
length: number | null
staticPosition: number
},
) {
const { checksumAddress, length, staticPosition } = options
// If the length of the array is not known in advance (dynamic array),
// this means we will need to wonder off to the pointer and decode.
if (!length) {
// Dealing with a dynamic type, so get the offset of the array data.
const offset = Bytes.toNumber(cursor.readBytes(sizeOfOffset))
// Start is the static position of current slot + offset.
const start = staticPosition + offset
const startOfData = start + sizeOfLength
// Get the length of the array from the offset.
cursor.setPosition(start)
const length = Bytes.toNumber(cursor.readBytes(sizeOfLength))
// Check if the array has any dynamic children.
const dynamicChild = hasDynamicChild(param)
let consumed = 0
const value: unknown[] = []
for (let i = 0; i < length; ++i) {
// If any of the children is dynamic, then all elements will be offset pointer, thus size of one slot (32 bytes).
// Otherwise, elements will be the size of their encoding (consumed bytes).
cursor.setPosition(startOfData + (dynamicChild ? i * 32 : consumed))
const [data, consumed_] = decodeParameter(cursor, param, {
checksumAddress,
staticPosition: startOfData,
})
consumed += consumed_
value.push(data)
}
// As we have gone wondering, restore to the original position + next slot.
cursor.setPosition(staticPosition + 32)
return [value, 32]
}
// If the length of the array is known in advance,
// and the length of an element deeply nested in the array is not known,
// we need to decode the offset of the array data.
if (hasDynamicChild(param)) {
// Dealing with dynamic types, so get the offset of the array data.
const offset = Bytes.toNumber(cursor.readBytes(sizeOfOffset))
// Start is the static position of current slot + offset.
const start = staticPosition + offset
const value: unknown[] = []
for (let i = 0; i < length; ++i) {
// Move cursor along to the next slot (next offset pointer).
cursor.setPosition(start + i * 32)
const [data] = decodeParameter(cursor, param, {
checksumAddress,
staticPosition: start,
})
value.push(data)
}
// As we have gone wondering, restore to the original position + next slot.
cursor.setPosition(staticPosition + 32)
return [value, 32]
}
// If the length of the array is known in advance and the array is deeply static,
// then we can just decode each element in sequence.
let consumed = 0
const value: unknown[] = []
for (let i = 0; i < length; ++i) {
const [data, consumed_] = decodeParameter(cursor, param, {
checksumAddress,
staticPosition: staticPosition + consumed,
})
consumed += consumed_
value.push(data)
}
return [value, consumed]
}
export declare namespace decodeArray {
type ErrorType = Bytes.toNumber.ErrorType | Errors.GlobalErrorType
}
/** @internal */
export function decodeBool(cursor: Cursor.Cursor) {
return [Bytes.toBoolean(cursor.readBytes(32), { size: 32 }), 32]
}
export declare namespace decodeBool {
type ErrorType = Bytes.toBoolean.ErrorType | Errors.GlobalErrorType
}
/** @internal */
export function decodeBytes(
cursor: Cursor.Cursor,
param: AbiParameters.Parameter,
{ staticPosition }: { staticPosition: number },
) {
const [_, size] = param.type.split('bytes')
if (!size) {
// Dealing with dynamic types, so get the offset of the bytes data.
const offset = Bytes.toNumber(cursor.readBytes(32))
// Set position of the cursor to start of bytes data.
cursor.setPosition(staticPosition + offset)
const length = Bytes.toNumber(cursor.readBytes(32))
// If there is no length, we have zero data.
if (length === 0) {
// As we have gone wondering, restore to the original position + next slot.
cursor.setPosition(staticPosition + 32)
return ['0x', 32]
}
const data = cursor.readBytes(length)
// As we have gone wondering, restore to the original position + next slot.
cursor.setPosition(staticPosition + 32)
return [Hex.fromBytes(data), 32]
}
const value = Hex.fromBytes(cursor.readBytes(Number.parseInt(size), 32))
return [value, 32]
}
export declare namespace decodeBytes {
type ErrorType =
| Hex.fromBytes.ErrorType
| Bytes.toNumber.ErrorType
| Errors.GlobalErrorType
}
/** @internal */
export function decodeNumber(
cursor: Cursor.Cursor,
param: AbiParameters.Parameter,
) {
const signed = param.type.startsWith('int')
const size = Number.parseInt(param.type.split('int')[1] || '256')
const value = cursor.readBytes(32)
return [
size > 48
? Bytes.toBigInt(value, { signed })
: Bytes.toNumber(value, { signed }),
32,
]
}
export declare namespace decodeNumber {
type ErrorType =
| Bytes.toNumber.ErrorType
| Bytes.toBigInt.ErrorType
| Errors.GlobalErrorType
}
/** @internal */
export type TupleAbiParameter = AbiParameters.Parameter & {
components: readonly AbiParameters.Parameter[]
}
/** @internal */
export function decodeTuple(
cursor: Cursor.Cursor,
param: TupleAbiParameter,
options: { checksumAddress?: boolean | undefined; staticPosition: number },
) {
const { checksumAddress, staticPosition } = options
// Tuples can have unnamed components (i.e. they are arrays), so we must
// determine whether the tuple is named or unnamed. In the case of a named
// tuple, the value will be an object where each property is the name of the
// component. In the case of an unnamed tuple, the value will be an array.
const hasUnnamedChild =
param.components.length === 0 || param.components.some(({ name }) => !name)
// Initialize the value to an object or an array, depending on whether the
// tuple is named or unnamed.
const value: any = hasUnnamedChild ? [] : {}
let consumed = 0
// If the tuple has a dynamic child, we must first decode the offset to the
// tuple data.
if (hasDynamicChild(param)) {
// Dealing with dynamic types, so get the offset of the tuple data.
const offset = Bytes.toNumber(cursor.readBytes(sizeOfOffset))
// Start is the static position of referencing slot + offset.
const start = staticPosition + offset
for (let i = 0; i < param.components.length; ++i) {
const component = param.components[i]!
cursor.setPosition(start + consumed)
const [data, consumed_] = decodeParameter(cursor, component, {
checksumAddress,
staticPosition: start,
})
consumed += consumed_
value[hasUnnamedChild ? i : component?.name!] = data
}
// As we have gone wondering, restore to the original position + next slot.
cursor.setPosition(staticPosition + 32)
return [value, 32]
}
// If the tuple has static children, we can just decode each component
// in sequence.
for (let i = 0; i < param.components.length; ++i) {
const component = param.components[i]!
const [data, consumed_] = decodeParameter(cursor, component, {
checksumAddress,
staticPosition,
})
value[hasUnnamedChild ? i : component?.name!] = data
consumed += consumed_
}
return [value, consumed]
}
export declare namespace decodeTuple {
type ErrorType = Bytes.toNumber.ErrorType | Errors.GlobalErrorType
}
/** @internal */
export function decodeString(
cursor: Cursor.Cursor,
{ staticPosition }: { staticPosition: number },
) {
// Get offset to start of string data.
const offset = Bytes.toNumber(cursor.readBytes(32))
// Start is the static position of current slot + offset.
const start = staticPosition + offset
cursor.setPosition(start)
const length = Bytes.toNumber(cursor.readBytes(32))
// If there is no length, we have zero data (empty string).
if (length === 0) {
cursor.setPosition(staticPosition + 32)
return ['', 32]
}
const data = cursor.readBytes(length, 32)
const value = Bytes.toString(Bytes.trimLeft(data))
// As we have gone wondering, restore to the original position + next slot.
cursor.setPosition(staticPosition + 32)
return [value, 32]
}
export declare namespace decodeString {
type ErrorType =
| Bytes.toNumber.ErrorType
| Bytes.toString.ErrorType
| Bytes.trimLeft.ErrorType
| Errors.GlobalErrorType
}
/** @internal */
export function prepareParameters<
const parameters extends AbiParameters.AbiParameters,
>({
checksumAddress,
parameters,
values,
}: {
checksumAddress?: boolean | undefined
parameters: parameters
values: parameters extends AbiParameters.AbiParameters
? ToPrimitiveTypes<parameters>
: never
}) {
const preparedParameters: PreparedParameter[] = []
for (let i = 0; i < parameters.length; i++) {
preparedParameters.push(
prepareParameter({
checksumAddress,
parameter: parameters[i]!,
value: values[i],
}),
)
}
return preparedParameters
}
/** @internal */
export declare namespace prepareParameters {
type ErrorType = prepareParameter.ErrorType | Errors.GlobalErrorType
}
/** @internal */
export function prepareParameter<
const parameter extends AbiParameters.Parameter,
>({
checksumAddress = false,
parameter: parameter_,
value,
}: {
parameter: parameter
value: parameter extends AbiParameters.Parameter
? ParameterToPrimitiveType<parameter>
: never
checksumAddress?: boolean | undefined
}): PreparedParameter {
const parameter = parameter_ as AbiParameters.Parameter
const arrayComponents = getArrayComponents(parameter.type)
if (arrayComponents) {
const [length, type] = arrayComponents
return encodeArray(value, {
checksumAddress,
length,
parameter: {
...parameter,
type,
},
})
}
if (parameter.type === 'tuple') {
return encodeTuple(value as unknown as Tuple, {
checksumAddress,
parameter: parameter as TupleAbiParameter,
})
}
if (parameter.type === 'address') {
return encodeAddress(value as unknown as Hex.Hex, {
checksum: checksumAddress,
})
}
if (parameter.type === 'bool') {
return encodeBoolean(value as unknown as boolean)
}
if (parameter.type.startsWith('uint') || parameter.type.startsWith('int')) {
const signed = parameter.type.startsWith('int')
const [, , size = '256'] = integerRegex.exec(parameter.type) ?? []
return encodeNumber(value as unknown as number, {
signed,
size: Number(size),
})
}
if (parameter.type.startsWith('bytes')) {
return encodeBytes(value as unknown as Hex.Hex, { type: parameter.type })
}
if (parameter.type === 'string') {
return encodeString(value as unknown as string)
}
throw new AbiParameters.InvalidTypeError(parameter.type)
}
/** @internal */
export declare namespace prepareParameter {
type ErrorType =
| encodeArray.ErrorType
| encodeTuple.ErrorType
| encodeAddress.ErrorType
| encodeBoolean.ErrorType
| encodeBytes.ErrorType
| encodeString.ErrorType
| AbiParameters.InvalidTypeError
| Errors.GlobalErrorType
}
/** @internal */
export function encode(preparedParameters: PreparedParameter[]): Hex.Hex {
// 1. Compute the size of the static part of the parameters.
let staticSize = 0
for (let i = 0; i < preparedParameters.length; i++) {
const { dynamic, encoded } = preparedParameters[i]!
if (dynamic) staticSize += 32
else staticSize += Hex.size(encoded)
}
// 2. Split the parameters into static and dynamic parts.
const staticParameters: Hex.Hex[] = []
const dynamicParameters: Hex.Hex[] = []
let dynamicSize = 0
for (let i = 0; i < preparedParameters.length; i++) {
const { dynamic, encoded } = preparedParameters[i]!
if (dynamic) {
staticParameters.push(
Hex.fromNumber(staticSize + dynamicSize, { size: 32 }),
)
dynamicParameters.push(encoded)
dynamicSize += Hex.size(encoded)
} else {
staticParameters.push(encoded)
}
}
// 3. Concatenate static and dynamic parts.
return Hex.concat(...staticParameters, ...dynamicParameters)
}
/** @internal */
export declare namespace encode {
type ErrorType =
| Hex.concat.ErrorType
| Hex.fromNumber.ErrorType
| Hex.size.ErrorType
| Errors.GlobalErrorType
}
/** @internal */
export function encodeAddress(
value: Hex.Hex,
options: { checksum: boolean },
): PreparedParameter {
const { checksum = false } = options
Address.assert(value, { strict: checksum })
return {
dynamic: false,
encoded: Hex.padLeft(value.toLowerCase() as Hex.Hex),
}
}
/** @internal */
export declare namespace encodeAddress {
type ErrorType =
| Address.assert.ErrorType
| Hex.padLeft.ErrorType
| Errors.GlobalErrorType
}
/** @internal */
export function encodeArray<const parameter extends AbiParameters.Parameter>(
value: ParameterToPrimitiveType<parameter>,
options: {
checksumAddress?: boolean | undefined
length: number | null
parameter: parameter
},
): PreparedParameter {
const { checksumAddress, length, parameter } = options
const dynamic = length === null
if (!Array.isArray(value)) throw new AbiParameters.InvalidArrayError(value)
if (!dynamic && value.length !== length)
throw new AbiParameters.ArrayLengthMismatchError({
expectedLength: length!,
givenLength: value.length,
type: `${parameter.type}[${length}]`,
})
let dynamicChild = false
const preparedParameters: PreparedParameter[] = []
for (let i = 0; i < value.length; i++) {
const preparedParam = prepareParameter({
checksumAddress,
parameter,
value: value[i],
})
if (preparedParam.dynamic) dynamicChild = true
preparedParameters.push(preparedParam)
}
if (dynamic || dynamicChild) {
const data = encode(preparedParameters)
if (dynamic) {
const length = Hex.fromNumber(preparedParameters.length, { size: 32 })
return {
dynamic: true,
encoded:
preparedParameters.length > 0 ? Hex.concat(length, data) : length,
}
}
if (dynamicChild) return { dynamic: true, encoded: data }
}
return {
dynamic: false,
encoded: Hex.concat(...preparedParameters.map(({ encoded }) => encoded)),
}
}
/** @internal */
export declare namespace encodeArray {
type ErrorType =
| AbiParameters.InvalidArrayError
| AbiParameters.ArrayLengthMismatchError
| Hex.concat.ErrorType
| Hex.fromNumber.ErrorType
| Errors.GlobalErrorType
}
/** @internal */
export function encodeBytes(
value: Hex.Hex,
{ type }: { type: string },
): PreparedParameter {
const [, parametersize] = type.split('bytes')
const bytesSize = Hex.size(value)
if (!parametersize) {
let value_ = value
// If the size is not divisible by 32 bytes, pad the end
// with empty bytes to the ceiling 32 bytes.
if (bytesSize % 32 !== 0)
value_ = Hex.padRight(value_, Math.ceil((value.length - 2) / 2 / 32) * 32)
return {
dynamic: true,
encoded: Hex.concat(
Hex.padLeft(Hex.fromNumber(bytesSize, { size: 32 })),
value_,
),
}
}
if (bytesSize !== Number.parseInt(parametersize))
throw new AbiParameters.BytesSizeMismatchError({
expectedSize: Number.parseInt(parametersize),
value,
})
return { dynamic: false, encoded: Hex.padRight(value) }
}
/** @internal */
export declare namespace encodeBytes {
type ErrorType =
| Hex.padLeft.ErrorType
| Hex.padRight.ErrorType
| Hex.fromNumber.ErrorType
| Hex.slice.ErrorType
| Errors.GlobalErrorType
}
/** @internal */
export function encodeBoolean(value: boolean): PreparedParameter {
if (typeof value !== 'boolean')
throw new Errors.BaseError(
`Invalid boolean value: "${value}" (type: ${typeof value}). Expected: \`true\` or \`false\`.`,
)
return { dynamic: false, encoded: Hex.padLeft(Hex.fromBoolean(value)) }
}
/** @internal */
export declare namespace encodeBoolean {
type ErrorType =
| Hex.padLeft.ErrorType
| Hex.fromBoolean.ErrorType
| Errors.GlobalErrorType
}
/** @internal */
export function encodeNumber(
value: number,
{ signed, size }: { signed: boolean; size: number },
): PreparedParameter {
if (typeof size === 'number') {
const max = 2n ** (BigInt(size) - (signed ? 1n : 0n)) - 1n
const min = signed ? -max - 1n : 0n
if (value > max || value < min)
throw new Hex.IntegerOutOfRangeError({
max: max.toString(),
min: min.toString(),
signed,
size: size / 8,
value: value.toString(),
})
}
return {
dynamic: false,
encoded: Hex.fromNumber(value, {
size: 32,
signed,
}),
}
}
/** @internal */
export declare namespace encodeNumber {
type ErrorType = Hex.fromNumber.ErrorType | Errors.GlobalErrorType
}
/** @internal */
export function encodeString(value: string): PreparedParameter {
const hexValue = Hex.fromString(value)
const partsLength = Math.ceil(Hex.size(hexValue) / 32)
const parts: Hex.Hex[] = []
for (let i = 0; i < partsLength; i++) {
parts.push(Hex.padRight(Hex.slice(hexValue, i * 32, (i + 1) * 32)))
}
return {
dynamic: true,
encoded: Hex.concat(
Hex.padRight(Hex.fromNumber(Hex.size(hexValue), { size: 32 })),
...parts,
),
}
}
/** @internal */
export declare namespace encodeString {
type ErrorType =
| Hex.fromNumber.ErrorType
| Hex.padRight.ErrorType
| Hex.slice.ErrorType
| Hex.size.ErrorType
| Errors.GlobalErrorType
}
/** @internal */
export function encodeTuple<
const parameter extends AbiParameters.Parameter & {
components: readonly AbiParameters.Parameter[]
},
>(
value: ParameterToPrimitiveType<parameter>,
options: {
checksumAddress?: boolean | undefined
parameter: parameter
},
): PreparedParameter {
const { checksumAddress, parameter } = options
let dynamic = false
const preparedParameters: PreparedParameter[] = []
for (let i = 0; i < parameter.components.length; i++) {
const param_ = parameter.components[i]!
const index = Array.isArray(value) ? i : param_.name
const preparedParam = prepareParameter({
checksumAddress,
parameter: param_,
value: (value as any)[index!] as readonly unknown[],
})
preparedParameters.push(preparedParam)
if (preparedParam.dynamic) dynamic = true
}
return {
dynamic,
encoded: dynamic
? encode(preparedParameters)
: Hex.concat(...preparedParameters.map(({ encoded }) => encoded)),
}
}
/** @internal */
export declare namespace encodeTuple {
type ErrorType = Hex.concat.ErrorType | Errors.GlobalErrorType
}
/** @internal */
export function getArrayComponents(
type: string,
): [length: number | null, innerType: string] | undefined {
const matches = type.match(/^(.*)\[(\d+)?\]$/)
return matches
? // Return `null` if the array is dynamic.
[matches[2]! ? Number(matches[2]!) : null, matches[1]!]
: undefined
}
/** @internal */
export function hasDynamicChild(param: AbiParameters.Parameter) {
const { type } = param
if (type === 'string') return true
if (type === 'bytes') return true
if (type.endsWith('[]')) return true
if (type === 'tuple') return (param as any).components?.some(hasDynamicChild)
const arrayComponents = getArrayComponents(param.type)
if (
arrayComponents &&
hasDynamicChild({
...param,
type: arrayComponents[1],
} as AbiParameters.Parameter)
)
return true
return false
}

103
node_modules/ox/core/internal/base58.ts generated vendored Normal file
View File

@@ -0,0 +1,103 @@
import * as Bytes from '../Bytes.js'
import type * as Errors from '../Errors.js'
import * as Hex from '../Hex.js'
/** @internal */
export const integerToAlphabet =
'123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
/** @internal */
export const alphabetToInteger = /* __PURE__ */ Object.freeze<
Record<string, bigint>
>({
1: 0n,
2: 1n,
3: 2n,
4: 3n,
5: 4n,
6: 5n,
7: 6n,
8: 7n,
9: 8n,
A: 9n,
B: 10n,
C: 11n,
D: 12n,
E: 13n,
F: 14n,
G: 15n,
H: 16n,
J: 17n,
K: 18n,
L: 19n,
M: 20n,
N: 21n,
P: 22n,
Q: 23n,
R: 24n,
S: 25n,
T: 26n,
U: 27n,
V: 28n,
W: 29n,
X: 30n,
Y: 31n,
Z: 32n,
a: 33n,
b: 34n,
c: 35n,
d: 36n,
e: 37n,
f: 38n,
g: 39n,
h: 40n,
i: 41n,
j: 42n,
k: 43n,
m: 44n,
n: 45n,
o: 46n,
p: 47n,
q: 48n,
r: 49n,
s: 50n,
t: 51n,
u: 52n,
v: 53n,
w: 54n,
x: 55n,
y: 56n,
z: 57n,
})
/** @internal */
export function from(value: Hex.Hex | Bytes.Bytes) {
let bytes = Bytes.from(value)
let integer = (() => {
let hex = value
if (value instanceof Uint8Array) hex = Hex.fromBytes(bytes)
return BigInt(hex as string)
})()
let result = ''
while (integer > 0n) {
const remainder = Number(integer % 58n)
integer = integer / 58n
result = integerToAlphabet[remainder] + result
}
while (bytes.length > 1 && bytes[0] === 0) {
result = '1' + result
bytes = bytes.slice(1)
}
return result
}
/** @internal */
export declare namespace from {
type ErrorType = Errors.GlobalErrorType
}
/** @internal */

152
node_modules/ox/core/internal/bytes.ts generated vendored Normal file
View File

@@ -0,0 +1,152 @@
import * as Bytes from '../Bytes.js'
import type * as Errors from '../Errors.js'
/** @internal */
export function assertSize(bytes: Bytes.Bytes, size_: number): void {
if (Bytes.size(bytes) > size_)
throw new Bytes.SizeOverflowError({
givenSize: Bytes.size(bytes),
maxSize: size_,
})
}
/** @internal */
export declare namespace assertSize {
type ErrorType =
| Bytes.size.ErrorType
| Bytes.SizeOverflowError
| Errors.GlobalErrorType
}
/** @internal */
export function assertStartOffset(
value: Bytes.Bytes,
start?: number | undefined,
) {
if (typeof start === 'number' && start > 0 && start > Bytes.size(value) - 1)
throw new Bytes.SliceOffsetOutOfBoundsError({
offset: start,
position: 'start',
size: Bytes.size(value),
})
}
export declare namespace assertStartOffset {
export type ErrorType =
| Bytes.SliceOffsetOutOfBoundsError
| Bytes.size.ErrorType
| Errors.GlobalErrorType
}
/** @internal */
export function assertEndOffset(
value: Bytes.Bytes,
start?: number | undefined,
end?: number | undefined,
) {
if (
typeof start === 'number' &&
typeof end === 'number' &&
Bytes.size(value) !== end - start
) {
throw new Bytes.SliceOffsetOutOfBoundsError({
offset: end,
position: 'end',
size: Bytes.size(value),
})
}
}
/** @internal */
export declare namespace assertEndOffset {
type ErrorType =
| Bytes.SliceOffsetOutOfBoundsError
| Bytes.size.ErrorType
| Errors.GlobalErrorType
}
/** @internal */
export const charCodeMap = {
zero: 48,
nine: 57,
A: 65,
F: 70,
a: 97,
f: 102,
} as const
/** @internal */
export 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
}
/** @internal */
export function pad(bytes: Bytes.Bytes, options: pad.Options = {}) {
const { dir, size = 32 } = options
if (size === 0) return bytes
if (bytes.length > size)
throw new Bytes.SizeExceedsPaddingSizeError({
size: bytes.length,
targetSize: size,
type: 'Bytes',
})
const paddedBytes = new Uint8Array(size)
for (let i = 0; i < size; i++) {
const padEnd = dir === 'right'
paddedBytes[padEnd ? i : size - i - 1] =
bytes[padEnd ? i : bytes.length - i - 1]!
}
return paddedBytes
}
/** @internal */
export declare namespace pad {
type Options = {
dir?: 'left' | 'right' | undefined
size?: number | undefined
}
type ReturnType = Bytes.Bytes
type ErrorType = Bytes.SizeExceedsPaddingSizeError | Errors.GlobalErrorType
}
/** @internal */
export function trim(
value: Bytes.Bytes,
options: trim.Options = {},
): trim.ReturnType {
const { dir = 'left' } = options
let data = value
let sliceLength = 0
for (let i = 0; i < data.length - 1; i++) {
if (data[dir === 'left' ? i : data.length - i - 1]!.toString() === '0')
sliceLength++
else break
}
data =
dir === 'left'
? data.slice(sliceLength)
: data.slice(0, data.length - sliceLength)
return data as trim.ReturnType
}
/** @internal */
export declare namespace trim {
type Options = {
dir?: 'left' | 'right' | undefined
}
type ReturnType = Bytes.Bytes
type ErrorType = Errors.GlobalErrorType
}

252
node_modules/ox/core/internal/cursor.ts generated vendored Normal file
View File

@@ -0,0 +1,252 @@
import type { Bytes } from '../Bytes.js'
import * as Errors from '../Errors.js'
/** @internal */
export type Cursor = {
bytes: Bytes
dataView: DataView
position: number
positionReadCount: Map<number, number>
recursiveReadCount: number
recursiveReadLimit: number
remaining: number
assertReadLimit(position?: number): void
assertPosition(position: number): void
decrementPosition(offset: number): void
getReadCount(position?: number): number
incrementPosition(offset: number): void
inspectByte(position?: number): Bytes[number]
inspectBytes(length: number, position?: number): Bytes
inspectUint8(position?: number): number
inspectUint16(position?: number): number
inspectUint24(position?: number): number
inspectUint32(position?: number): number
pushByte(byte: Bytes[number]): void
pushBytes(bytes: Bytes): void
pushUint8(value: number): void
pushUint16(value: number): void
pushUint24(value: number): void
pushUint32(value: number): void
readByte(): Bytes[number]
readBytes(length: number, size?: number): Bytes
readUint8(): number
readUint16(): number
readUint24(): number
readUint32(): number
setPosition(position: number): () => void
_touch(): void
}
const staticCursor: Cursor = /*#__PURE__*/ {
bytes: new Uint8Array(),
dataView: new DataView(new ArrayBuffer(0)),
position: 0,
positionReadCount: new Map(),
recursiveReadCount: 0,
recursiveReadLimit: Number.POSITIVE_INFINITY,
assertReadLimit() {
if (this.recursiveReadCount >= this.recursiveReadLimit)
throw new RecursiveReadLimitExceededError({
count: this.recursiveReadCount + 1,
limit: this.recursiveReadLimit,
})
},
assertPosition(position) {
if (position < 0 || position > this.bytes.length - 1)
throw new PositionOutOfBoundsError({
length: this.bytes.length,
position,
})
},
decrementPosition(offset) {
if (offset < 0) throw new NegativeOffsetError({ offset })
const position = this.position - offset
this.assertPosition(position)
this.position = position
},
getReadCount(position) {
return this.positionReadCount.get(position || this.position) || 0
},
incrementPosition(offset) {
if (offset < 0) throw new NegativeOffsetError({ offset })
const position = this.position + offset
this.assertPosition(position)
this.position = position
},
inspectByte(position_) {
const position = position_ ?? this.position
this.assertPosition(position)
return this.bytes[position]!
},
inspectBytes(length, position_) {
const position = position_ ?? this.position
this.assertPosition(position + length - 1)
return this.bytes.subarray(position, position + length)
},
inspectUint8(position_) {
const position = position_ ?? this.position
this.assertPosition(position)
return this.bytes[position]!
},
inspectUint16(position_) {
const position = position_ ?? this.position
this.assertPosition(position + 1)
return this.dataView.getUint16(position)
},
inspectUint24(position_) {
const position = position_ ?? this.position
this.assertPosition(position + 2)
return (
(this.dataView.getUint16(position) << 8) +
this.dataView.getUint8(position + 2)
)
},
inspectUint32(position_) {
const position = position_ ?? this.position
this.assertPosition(position + 3)
return this.dataView.getUint32(position)
},
pushByte(byte: Bytes[number]) {
this.assertPosition(this.position)
this.bytes[this.position] = byte
this.position++
},
pushBytes(bytes: Bytes) {
this.assertPosition(this.position + bytes.length - 1)
this.bytes.set(bytes, this.position)
this.position += bytes.length
},
pushUint8(value: number) {
this.assertPosition(this.position)
this.bytes[this.position] = value
this.position++
},
pushUint16(value: number) {
this.assertPosition(this.position + 1)
this.dataView.setUint16(this.position, value)
this.position += 2
},
pushUint24(value: number) {
this.assertPosition(this.position + 2)
this.dataView.setUint16(this.position, value >> 8)
this.dataView.setUint8(this.position + 2, value & ~4294967040)
this.position += 3
},
pushUint32(value: number) {
this.assertPosition(this.position + 3)
this.dataView.setUint32(this.position, value)
this.position += 4
},
readByte() {
this.assertReadLimit()
this._touch()
const value = this.inspectByte()
this.position++
return value
},
readBytes(length, size) {
this.assertReadLimit()
this._touch()
const value = this.inspectBytes(length)
this.position += size ?? length
return value
},
readUint8() {
this.assertReadLimit()
this._touch()
const value = this.inspectUint8()
this.position += 1
return value
},
readUint16() {
this.assertReadLimit()
this._touch()
const value = this.inspectUint16()
this.position += 2
return value
},
readUint24() {
this.assertReadLimit()
this._touch()
const value = this.inspectUint24()
this.position += 3
return value
},
readUint32() {
this.assertReadLimit()
this._touch()
const value = this.inspectUint32()
this.position += 4
return value
},
get remaining() {
return this.bytes.length - this.position
},
setPosition(position) {
const oldPosition = this.position
this.assertPosition(position)
this.position = position
return () => (this.position = oldPosition)
},
_touch() {
if (this.recursiveReadLimit === Number.POSITIVE_INFINITY) return
const count = this.getReadCount()
this.positionReadCount.set(this.position, count + 1)
if (count > 0) this.recursiveReadCount++
},
}
/** @internal */
export function create(
bytes: Bytes,
{ recursiveReadLimit = 8_192 }: create.Config = {},
): Cursor {
const cursor: Cursor = Object.create(staticCursor)
cursor.bytes = bytes
cursor.dataView = new DataView(
bytes.buffer,
bytes.byteOffset,
bytes.byteLength,
)
cursor.positionReadCount = new Map()
cursor.recursiveReadLimit = recursiveReadLimit
return cursor
}
/** @internal */
export declare namespace create {
type Config = { recursiveReadLimit?: number | undefined }
type ErrorType = Errors.GlobalErrorType
}
/** @internal */
export class NegativeOffsetError extends Errors.BaseError {
override readonly name = 'Cursor.NegativeOffsetError'
constructor({ offset }: { offset: number }) {
super(`Offset \`${offset}\` cannot be negative.`)
}
}
/** @internal */
export class PositionOutOfBoundsError extends Errors.BaseError {
override readonly name = 'Cursor.PositionOutOfBoundsError'
constructor({ length, position }: { length: number; position: number }) {
super(
`Position \`${position}\` is out of bounds (\`0 < position < ${length}\`).`,
)
}
}
/** @internal */
export class RecursiveReadLimitExceededError extends Errors.BaseError {
override readonly name = 'Cursor.RecursiveReadLimitExceededError'
constructor({ count, limit }: { count: number; limit: number }) {
super(
`Recursive read limit of \`${limit}\` exceeded (recursive read count: \`${count}\`).`,
)
}
}

64
node_modules/ox/core/internal/ens.ts generated vendored Normal file
View File

@@ -0,0 +1,64 @@
import { Bytes } from '../../index.js'
import * as Ens from '../Ens.js'
import type * as Errors from '../Errors.js'
import * as Hex from '../Hex.js'
/**
* @internal
* Encodes a [DNS packet](https://docs.ens.domains/resolution/names#dns) into a ByteArray containing a UDP payload.
*/
export function packetToBytes(packet: string): Bytes.Bytes {
// strip leading and trailing `.`
const value = packet.replace(/^\.|\.$/gm, '')
if (value.length === 0) return new Uint8Array(1)
const bytes = new Uint8Array(Bytes.fromString(value).byteLength + 2)
let offset = 0
const list = value.split('.')
for (let i = 0; i < list.length; i++) {
let encoded = Bytes.fromString(list[i]!)
// if the length is > 255, make the encoded label value a labelhash
// this is compatible with the universal resolver
if (encoded.byteLength > 255)
encoded = Bytes.fromString(wrapLabelhash(Ens.labelhash(list[i]!)))
bytes[offset] = encoded.length
bytes.set(encoded, offset + 1)
offset += encoded.length + 1
}
if (bytes.byteLength !== offset + 1) return bytes.slice(0, offset + 1)
return bytes
}
export declare namespace packetToBytes {
type ErrorType =
| wrapLabelhash.ErrorType
| Ens.labelhash.ErrorType
| Bytes.fromString.ErrorType
| Errors.GlobalErrorType
}
/** @internal */
export function wrapLabelhash(hash: Hex.Hex): `[${string}]` {
return `[${hash.slice(2)}]`
}
export declare namespace wrapLabelhash {
type ErrorType = Errors.GlobalErrorType
}
/** @internal */
export function unwrapLabelhash(label: string): Hex.Hex | null {
if (label.length !== 66) return null
if (label.indexOf('[') !== 0) return null
if (label.indexOf(']') !== 65) return null
const hash = `0x${label.slice(1, 65)}`
if (!Hex.validate(hash, { strict: true })) return null
return hash
}
export declare namespace unwrapLabelhash {
type ErrorType = Hex.validate.ErrorType | Errors.GlobalErrorType
}

6
node_modules/ox/core/internal/entropy.ts generated vendored Normal file
View File

@@ -0,0 +1,6 @@
export let extraEntropy = false
/** @internal */
export function setExtraEntropy(entropy: boolean) {
extraEntropy = entropy
}

26
node_modules/ox/core/internal/errors.ts generated vendored Normal file
View File

@@ -0,0 +1,26 @@
import { version } from '../version.js'
/** @internal */
export function getUrl(url: string) {
return url
}
/** @internal */
export function getVersion() {
return version
}
/** @internal */
export function prettyPrint(args: unknown) {
if (!args) return ''
const entries = Object.entries(args)
.map(([key, value]) => {
if (value === undefined || value === false) return null
return [key, value]
})
.filter(Boolean) as [string, string][]
const maxLength = entries.reduce((acc, [key]) => Math.max(acc, key.length), 0)
return entries
.map(([key, value]) => ` ${`${key}:`.padEnd(maxLength + 1)} ${value}`)
.join('\n')
}

25
node_modules/ox/core/internal/hdKey.ts generated vendored Normal file
View File

@@ -0,0 +1,25 @@
import type { HDKey } from '@scure/bip32'
import type * as Errors from '../Errors.js'
import type * as HdKey from '../HdKey.js'
import * as Hex from '../Hex.js'
import * as Secp256k1 from '../Secp256k1.js'
/** @internal */
export function fromScure(key: HDKey): HdKey.HdKey {
return {
derive: (path) => fromScure(key.derive(path)),
depth: key.depth,
identifier: Hex.fromBytes(key.identifier!),
index: key.index,
privateKey: Hex.fromBytes(key.privateKey!),
privateExtendedKey: key.privateExtendedKey,
publicKey: Secp256k1.getPublicKey({ privateKey: key.privateKey! }),
publicExtendedKey: key.publicExtendedKey,
versions: key.versions,
}
}
/** @internal */
export declare namespace fromScure {
type ErrorType = Errors.GlobalErrorType
}

124
node_modules/ox/core/internal/hex.ts generated vendored Normal file
View File

@@ -0,0 +1,124 @@
import type * as Errors from '../Errors.js'
import * as Hex from '../Hex.js'
/** @internal */
export function assertSize(hex: Hex.Hex, size_: number): void {
if (Hex.size(hex) > size_)
throw new Hex.SizeOverflowError({
givenSize: Hex.size(hex),
maxSize: size_,
})
}
/** @internal */
export declare namespace assertSize {
type ErrorType =
| Hex.size.ErrorType
| Hex.SizeOverflowError
| Errors.GlobalErrorType
}
/** @internal */
export function assertStartOffset(value: Hex.Hex, start?: number | undefined) {
if (typeof start === 'number' && start > 0 && start > Hex.size(value) - 1)
throw new Hex.SliceOffsetOutOfBoundsError({
offset: start,
position: 'start',
size: Hex.size(value),
})
}
export declare namespace assertStartOffset {
type ErrorType =
| Hex.SliceOffsetOutOfBoundsError
| Hex.size.ErrorType
| Errors.GlobalErrorType
}
/** @internal */
export function assertEndOffset(
value: Hex.Hex,
start?: number | undefined,
end?: number | undefined,
) {
if (
typeof start === 'number' &&
typeof end === 'number' &&
Hex.size(value) !== end - start
) {
throw new Hex.SliceOffsetOutOfBoundsError({
offset: end,
position: 'end',
size: Hex.size(value),
})
}
}
export declare namespace assertEndOffset {
type ErrorType =
| Hex.SliceOffsetOutOfBoundsError
| Hex.size.ErrorType
| Errors.GlobalErrorType
}
/** @internal */
export function pad(hex_: Hex.Hex, options: pad.Options = {}) {
const { dir, size = 32 } = options
if (size === 0) return hex_
const hex = hex_.replace('0x', '')
if (hex.length > size * 2)
throw new Hex.SizeExceedsPaddingSizeError({
size: Math.ceil(hex.length / 2),
targetSize: size,
type: 'Hex',
})
return `0x${hex[dir === 'right' ? 'padEnd' : 'padStart'](size * 2, '0')}` as Hex.Hex
}
/** @internal */
export declare namespace pad {
type Options = {
dir?: 'left' | 'right' | undefined
size?: number | undefined
}
type ErrorType = Hex.SizeExceedsPaddingSizeError | Errors.GlobalErrorType
}
/** @internal */
export function trim(
value: Hex.Hex,
options: trim.Options = {},
): trim.ReturnType {
const { dir = 'left' } = options
let data = value.replace('0x', '')
let sliceLength = 0
for (let i = 0; i < data.length - 1; i++) {
if (data[dir === 'left' ? i : data.length - i - 1]!.toString() === '0')
sliceLength++
else break
}
data =
dir === 'left'
? data.slice(sliceLength)
: data.slice(0, data.length - sliceLength)
if (data === '0') return '0x'
if (dir === 'right' && data.length % 2 === 1) return `0x${data}0`
return `0x${data}` as trim.ReturnType
}
/** @internal */
export declare namespace trim {
type Options = {
dir?: 'left' | 'right' | undefined
}
type ReturnType = Hex.Hex
type ErrorType = Errors.GlobalErrorType
}

34
node_modules/ox/core/internal/lru.ts generated vendored Normal file
View File

@@ -0,0 +1,34 @@
/**
* @internal
*
* Map with a LRU (Least recently used) policy.
* @see https://en.wikipedia.org/wiki/Cache_replacement_policies#LRU
*/
export class LruMap<value = unknown> extends Map<string, value> {
maxSize: number
constructor(size: number) {
super()
this.maxSize = size
}
override get(key: string) {
const value = super.get(key)
if (super.has(key) && value !== undefined) {
this.delete(key)
super.set(key, value)
}
return value
}
override set(key: string, value: value) {
super.set(key, value)
if (this.maxSize && this.size > this.maxSize) {
const firstKey = this.keys().next().value
if (firstKey) this.delete(firstKey)
}
return this
}
}

10
node_modules/ox/core/internal/mnemonic/wordlists.ts generated vendored Normal file
View File

@@ -0,0 +1,10 @@
export { wordlist as czech } from '@scure/bip39/wordlists/czech'
export { wordlist as english } from '@scure/bip39/wordlists/english'
export { wordlist as french } from '@scure/bip39/wordlists/french'
export { wordlist as italian } from '@scure/bip39/wordlists/italian'
export { wordlist as japanese } from '@scure/bip39/wordlists/japanese'
export { wordlist as korean } from '@scure/bip39/wordlists/korean'
export { wordlist as portuguese } from '@scure/bip39/wordlists/portuguese'
export { wordlist as simplifiedChinese } from '@scure/bip39/wordlists/simplified-chinese'
export { wordlist as spanish } from '@scure/bip39/wordlists/spanish'
export { wordlist as traditionalChinese } from '@scure/bip39/wordlists/traditional-chinese'

63
node_modules/ox/core/internal/promise.ts generated vendored Normal file
View File

@@ -0,0 +1,63 @@
import * as Errors from '../Errors.js'
/** @internal */
export function withTimeout<data>(
fn: withTimeout.Fn<data>,
options: withTimeout.Options,
): Promise<data> {
const { errorInstance = new TimeoutError(), timeout, signal } = options
return new Promise((resolve, reject) => {
;(async () => {
let timeoutId: any
try {
const controller = new AbortController()
if (timeout > 0)
timeoutId = setTimeout(() => {
if (signal) {
controller.abort()
} else {
reject(errorInstance)
}
}, timeout) as any
resolve(await fn({ signal: controller.signal }))
} catch (err) {
if ((err as Error)?.name === 'AbortError') reject(errorInstance)
reject(err)
} finally {
clearTimeout(timeoutId)
}
})()
})
}
/** @internal */
export declare namespace withTimeout {
type Fn<data> = ({
signal,
}: { signal: AbortController['signal'] | null }) => Promise<data>
type Options = {
// The error instance to throw when the timeout is reached.
errorInstance?: Error | undefined
// The timeout (in ms).
timeout: number
// Whether or not the timeout should use an abort signal.
signal?: boolean | undefined
}
type ErrorType = TimeoutError | Errors.GlobalErrorType
}
/** @internal */
/**
* Thrown when an operation times out.
* @internal
*/
export class TimeoutError extends Errors.BaseError {
override readonly name = 'Promise.TimeoutError'
constructor() {
super('Operation timed out.')
}
}

15
node_modules/ox/core/internal/register.ts generated vendored Normal file
View File

@@ -0,0 +1,15 @@
import type * as RpcSchema from '../RpcSchema.js'
// biome-ignore lint/suspicious/noEmptyInterface:
export interface Register {}
export type ResolvedRegister = {
RpcSchema: Register extends { RpcSchema: infer schema }
? schema
: DefaultRegister['RpcSchema']
}
/** @internal */
export type DefaultRegister = {
RpcSchema: RpcSchema.Eth | RpcSchema.Wallet
}

20
node_modules/ox/core/internal/rpcSchema.ts generated vendored Normal file
View File

@@ -0,0 +1,20 @@
import type { Generic, MethodNameGeneric } from '../RpcSchema.js'
import type { Compute, IsNarrowable } from './types.js'
/** @internal */
export type ExtractRequestOpaque<
schema extends Generic,
methodName extends MethodNameGeneric<schema> = MethodNameGeneric<schema>,
> = Compute<
Omit<
{
method: methodName | schema['Request']['method']
params?: unknown
} & (methodName extends schema['Request']['method']
? IsNarrowable<schema, Generic> extends true
? Extract<schema, { Request: { method: methodName } }>['Request']
: {}
: {}),
''
>
>

802
node_modules/ox/core/internal/rpcSchemas/eth.ts generated vendored Normal file
View File

@@ -0,0 +1,802 @@
import type * as AccountProof from '../../AccountProof.js'
import type * as Address from '../../Address.js'
import type * as Block from '../../Block.js'
import type * as BlockOverrides from '../../BlockOverrides.js'
import type * as Fee from '../../Fee.js'
import type * as Filter from '../../Filter.js'
import type * as Hex from '../../Hex.js'
import type * as Log from '../../Log.js'
import type * as RpcSchema from '../../RpcSchema.js'
import type * as StateOverrides from '../../StateOverrides.js'
import type * as Transaction from '../../Transaction.js'
import type * as TransactionReceipt from '../../TransactionReceipt.js'
import type * as TransactionRequest from '../../TransactionRequest.js'
/**
* Union of all JSON-RPC Methods for the `eth_` namespace.
*
* @example
* ```ts twoslash
* import { RpcSchema } from 'ox'
*
* type Schema = RpcSchema.Eth
* // ^?
*
*
*
*
*
*
*
*
*
*
*
*
*
* ```
*/
export type Eth = RpcSchema.From<
/**
* Returns a list of addresses owned by this client
*
* @example
* ```
* request({ method: 'eth_accounts' })
* // => ['0x0fB69...']
* ```
*/
| {
Request: {
method: 'eth_accounts'
params?: undefined
}
ReturnType: readonly Address.Address[]
}
/**
* Returns the base fee per blob gas in wei.
*
* @example
* ```
* request({ method: 'eth_blobBaseFee' })
* // '0x09184e72a000'
* ```
*/
| {
Request: {
method: 'eth_blobBaseFee'
params?: undefined
}
ReturnType: Hex.Hex
}
/**
* Returns the number of the most recent block seen by this client
*
* @example
* ```
* request({ method: 'eth_blockNumber' })
* // '0x1b4'
* ```
*/
| {
Request: {
method: 'eth_blockNumber'
params?: undefined
}
ReturnType: Hex.Hex
}
/**
* Executes a new message call immediately without submitting a transaction to the network
*
* ```
* request({ method: 'eth_call', params: [{ to: '0x...', data: '0x...' }] })
* // '0x...'
* ```
*/
| {
Request: {
method: 'eth_call'
params:
| [transaction: TransactionRequest.Rpc]
| [
transaction: TransactionRequest.Rpc,
block:
| Block.Number<Hex.Hex>
| Block.Tag
| Block.Hash
| Block.Identifier,
]
| [
transaction: TransactionRequest.Rpc,
block:
| Block.Number<Hex.Hex>
| Block.Tag
| Block.Hash
| Block.Identifier,
stateOverrides: StateOverrides.Rpc,
]
}
ReturnType: Hex.Hex
}
/**
* Returns the chain ID associated with the current network
*
* @example
* ```
* request({ method: 'eth_chainId' })
* // => '0x1'
* ```
*/
| {
Request: {
method: 'eth_chainId'
params?: undefined
}
ReturnType: Hex.Hex
}
/**
* Returns the client coinbase address.
*
* @example
* ```
* request({ method: 'eth_coinbase' })
* // '0x...'
* ```
*/
| {
Request: {
method: 'eth_coinbase'
params?: undefined
}
ReturnType: Address.Address
}
/**
* Estimates the gas necessary to complete a transaction without submitting it to the network
*
* @example
* ```
* request({
* method: 'eth_estimateGas',
* params: [{ from: '0x...', to: '0x...', value: '0x...' }]
* })
* // '0x5208'
* ```
*/
| {
Request: {
method: 'eth_estimateGas'
params:
| [transaction: TransactionRequest.Rpc]
| [
transaction: TransactionRequest.Rpc,
block:
| Block.Number<Hex.Hex>
| Block.Tag
| Block.Hash
| Block.Identifier,
]
| [
transaction: TransactionRequest.Rpc,
block:
| Block.Number<Hex.Hex>
| Block.Tag
| Block.Hash
| Block.Identifier,
stateOverrides: StateOverrides.Rpc,
]
}
ReturnType: Hex.Hex
}
/**
* Returns a collection of historical gas information
*
* ```
* request({
* method: 'eth_feeHistory',
* params: ['4', 'latest', ['25', '75']]
* })
* // {
* // oldestBlock: '0x1',
* // baseFeePerGas: ['0x1', '0x2', '0x3', '0x4'],
* // gasUsedRatio: ['0x1', '0x2', '0x3', '0x4'],
* // reward: [['0x1', '0x2'], ['0x3', '0x4'], ['0x5', '0x6'], ['0x7', '0x8']]
* // }
* ```
* */
| {
Request: {
method: 'eth_feeHistory'
params: [
/** Number of blocks in the requested range. Between 1 and 1024 blocks can be requested in a single query. Less than requested may be returned if not all blocks are available. */
blockCount: Hex.Hex,
/** Highest number block of the requested range. */
newestBlock: Block.Number<Hex.Hex> | Block.Tag,
/** A monotonically increasing list of percentile values to sample from each block's effective priority fees per gas in ascending order, weighted by gas used. */
rewardPercentiles: number[] | undefined,
]
}
ReturnType: Fee.FeeHistoryRpc
}
/**
* Returns the current price of gas expressed in wei
*
* ```
* request({ method: 'eth_gasPrice' })
* // '0x09184e72a000'
* ```
*/
| {
Request: {
method: 'eth_gasPrice'
params?: undefined
}
ReturnType: Hex.Hex
}
/**
* Returns the balance of an address in wei
*
* @example
* ```
* request({ method: 'eth_getBalance', params: ['0x...', 'latest'] })
* // => '0x12a05...'
* ```
*/
| {
Request: {
method: 'eth_getBalance'
params: [
address: Address.Address,
block:
| Block.Number<Hex.Hex>
| Block.Tag
| Block.Hash
| Block.Identifier,
]
}
ReturnType: Hex.Hex
}
/**
* Returns information about a block specified by hash
*
* ```
* request({ method: 'eth_getBlockByHash', params: ['0x...', true] })
* // {
* // number: '0x1b4',
* // hash: '0x...',
* // parentHash: '0x...',
* // ...
* // }
* ```
*/
| {
Request: {
method: 'eth_getBlockByHash'
params: [
/** hash of a block */
hash: Hex.Hex,
/** true will pull full transaction objects, false will pull transaction hashes */
includeTransactionObjects: boolean,
]
}
ReturnType: Block.Rpc | null
}
/**
* Returns information about a block specified by number
*
* @example
* ```
* request({ method: 'eth_getBlockByNumber', params: ['0x1b4', true] })
* // {
* // number: '0x1b4',
* // hash: '0x...',
* // parentHash: '0x...',
* // ...
* // }
* ```
*/
| {
Request: {
method: 'eth_getBlockByNumber'
params: [
/** block number, or one of "latest", "safe", "finalized", "earliest" or "pending" */
block: Block.Number<Hex.Hex> | Block.Tag,
/** true will pull full transaction objects, false will pull transaction hashes */
includeTransactionObjects: boolean,
]
}
ReturnType: Block.Rpc | null
}
/**
* Returns the number of transactions in a block specified by block hash
*
* ```
* request({ method: 'eth_getBlockTransactionCountByHash', params: ['0x...'] })
* // '0x1'
* ```
*/
| {
Request: {
method: 'eth_getBlockTransactionCountByHash'
params: [hash: Hex.Hex]
}
ReturnType: Hex.Hex
}
/**
* Returns the number of transactions in a block specified by block number
*
* ```
* request({ method: 'eth_getBlockTransactionCountByNumber', params: ['0x1b4'] })
* // '0x1'
* ```
*/
| {
Request: {
method: 'eth_getBlockTransactionCountByNumber'
params: [block: Block.Number<Hex.Hex> | Block.Tag]
}
ReturnType: Hex.Hex
}
/**
* Returns the contract code stored at a given address
*
* @example
* ```
* request({ method: 'eth_getCode', params: ['0x...', 'latest'] })
* // '0x...'
* ```
*/
| {
Request: {
method: 'eth_getCode'
params: [
address: Address.Address,
block:
| Block.Number<Hex.Hex>
| Block.Tag
| Block.Hash
| Block.Identifier,
]
}
ReturnType: Hex.Hex
}
/**
* Returns a list of all logs based on filter ID since the last log retrieval
*
* @example
* ```
* request({ method: 'eth_getFilterChanges', params: ['0x...'] })
* // => [{ ... }| { ... }]
* ```
*/
| {
Request: {
method: 'eth_getFilterChanges'
params: [filterId: Hex.Hex]
}
ReturnType: readonly Log.Rpc[] | readonly Hex.Hex[]
}
/**
* Returns a list of all logs based on filter ID
*
* @example
* ```
* request({ method: 'eth_getFilterLogs', params: ['0x...'] })
* // => [{ ... }| { ... }]
* ```
*/
| {
Request: {
method: 'eth_getFilterLogs'
params: [filterId: Hex.Hex]
}
ReturnType: readonly Log.Rpc[]
}
/**
* Returns a list of all logs based on a filter object
*
* @example
* ```
* request({ method: 'eth_getLogs', params: [{ fromBlock: '0x...', toBlock: '0x...', address: '0x...', topics: ['0x...'] }] })
* // => [{ ... }| { ... }]
* ```
*/
| {
Request: {
method: 'eth_getLogs'
params: [filter: Filter.Rpc]
}
ReturnType: readonly Log.Rpc[]
}
/**
* Returns the account and storage values of the specified account including the Merkle-proof.
*
* @example
* ```
* request({ method: 'eth_getProof', params: ['0x...', ['0x...'], 'latest'] })
* // {
* // ...
* // }
* ```
*/
| {
Request: {
method: 'eth_getProof'
params: [
/** Address of the account. */
address: Address.Address,
/** An array of storage-keys that should be proofed and included. */
storageKeys: Hex.Hex[],
/** Block identifier to pull the proof from. */
block:
| Block.Number<Hex.Hex>
| Block.Tag
| Block.Hash
| Block.Identifier,
]
}
ReturnType: AccountProof.Rpc
}
/**
* Returns the value from a storage position at an address
*
* @example
* ```
* request({ method: 'eth_getStorageAt', params: ['0x...', '0x...', 'latest'] })
* // '0x...'
* ```
*/
| {
Request: {
method: 'eth_getStorageAt'
params: [
address: Address.Address,
index: Hex.Hex,
block:
| Block.Number<Hex.Hex>
| Block.Tag
| Block.Hash
| Block.Identifier,
]
}
ReturnType: Hex.Hex
}
/**
* Returns information about a transaction specified by block hash and transaction index
*
* @example
* ```
* request({ method: 'eth_getTransactionByBlockHashAndIndex', params: ['0x...', '0x...'] })
* // { ... }
* ```
*/
| {
Request: {
method: 'eth_getTransactionByBlockHashAndIndex'
params: [hash: Hex.Hex, index: Hex.Hex]
}
ReturnType: Transaction.Rpc | null
}
/**
* Returns information about a transaction specified by block number and transaction index
*
* @example
* ```
* request({ method: 'eth_getTransactionByBlockNumberAndIndex', params: ['0x...', '0x...'] })
* // { ... }
* ```
*/
| {
Request: {
method: 'eth_getTransactionByBlockNumberAndIndex'
params: [block: Block.Number<Hex.Hex> | Block.Tag, index: Hex.Hex]
}
ReturnType: Transaction.Rpc | null
}
/**
* Returns information about a transaction specified by hash
*
* @example
* ```
* request({ method: 'eth_getTransactionByHash', params: ['0x...'] })
* // { ... }
* ```
*/
| {
Request: {
method: 'eth_getTransactionByHash'
params: [hash: Hex.Hex]
}
ReturnType: Transaction.Rpc | null
}
/**
* Returns the number of transactions sent from an address
*
* @example
* ```
* request({ method: 'eth_getTransactionCount', params: ['0x...', 'latest'] })
* // '0x1'
* ```
*/
| {
Request: {
method: 'eth_getTransactionCount'
params: [
address: Address.Address,
block:
| Block.Number<Hex.Hex>
| Block.Tag
| Block.Hash
| Block.Identifier,
]
}
ReturnType: Hex.Hex
}
/**
* Returns the receipt of a transaction specified by hash
*
* @example
* ```
* request({ method: 'eth_getTransactionReceipt', params: ['0x...'] })
* // { ... }
* ```
*/
| {
Request: {
method: 'eth_getTransactionReceipt'
params: [hash: Hex.Hex]
}
ReturnType: TransactionReceipt.Rpc | null
}
/**
* Returns the number of uncles in a block specified by block hash
*
* @example
* ```
* request({ method: 'eth_getUncleCountByBlockHash', params: ['0x...'] })
* // => '0x1'
* ```
*/
| {
Request: {
method: 'eth_getUncleCountByBlockHash'
params: [hash: Hex.Hex]
}
ReturnType: Hex.Hex
}
/**
* Returns the number of uncles in a block specified by block number
*
* @example
* ```
* request({ method: 'eth_getUncleCountByBlockNumber', params: ['0x...'] })
* // '0x1'
* ```
*/
| {
Request: {
method: 'eth_getUncleCountByBlockNumber'
params: [block: Block.Number<Hex.Hex> | Block.Tag]
}
ReturnType: Hex.Hex
}
/**
* Returns the current maxPriorityFeePerGas in wei.
*
* @example
* ```
* request({ method: 'eth_maxPriorityFeePerGas' })
* // => '0x5f5e100'
* ```
*/
| {
Request: {
method: 'eth_maxPriorityFeePerGas'
params?: undefined
}
ReturnType: Hex.Hex
}
/**
* Creates a filter to listen for new blocks that can be used with `eth_getFilterChanges`
*
* @example
* ```
* request({ method: 'eth_newBlockFilter' })
* // => '0x1'
* ```
*/
| {
Request: {
method: 'eth_newBlockFilter'
params?: undefined
}
ReturnType: Hex.Hex
}
/**
* Creates a filter to listen for specific state changes that can then be used with `eth_getFilterChanges`
*
* @example
* ```
* request({ method: 'eth_newFilter', params: [{ fromBlock: '0x...', toBlock: '0x...', address: '0x...', topics: ['0x...'] }] })
* // => '0x1'
* ```
*/
| {
Request: {
method: 'eth_newFilter'
params: [filter: Filter.Rpc]
}
ReturnType: Hex.Hex
}
/**
* Creates a filter to listen for new pending transactions that can be used with `eth_getFilterChanges`
*
* @example
* ```
* request({ method: 'eth_newPendingTransactionFilter' })
* // '0x1'
* ```
*/
| {
Request: {
method: 'eth_newPendingTransactionFilter'
params?: undefined
}
ReturnType: Hex.Hex
}
/**
* Returns the current Ethereum protocol version
*
* @example
* ```
* request({ method: 'eth_protocolVersion' })
* // '54'
* ```
*/
| {
Request: {
method: 'eth_protocolVersion'
params?: undefined
}
ReturnType: string
}
/**
* Requests that the user provides an Ethereum address to be identified by. Typically causes a browser extension popup to appear.
*
* @example
* ```
* request({ method: 'eth_requestAccounts' })
* // => ['0x...', '0x...']
* ```
*/
| {
Request: {
method: 'eth_requestAccounts'
params?: undefined
}
ReturnType: readonly Address.Address[]
}
/**
* Sends a **signed** transaction to the network
*
* @example
* ```
* request({ method: 'eth_sendRawTransaction', params: ['0x...'] })
* // => '0x...'
* ```
*/
| {
Request: {
method: 'eth_sendRawTransaction'
params: [serializedTransaction: Hex.Hex]
}
ReturnType: Hex.Hex
}
/**
* Creates, signs, and sends a new transaction to the network
*
* @example
* ```
* request({ method: 'eth_sendTransaction', params: [{ from: '0x...', to: '0x...', value: '0x...' }] })
* // '0x...'
* ```
*/
| {
Request: {
method: 'eth_sendTransaction'
params: [transaction: TransactionRequest.Rpc]
}
ReturnType: Hex.Hex
}
| {
Request: {
method: 'eth_simulateV1'
params: [
{
blockStateCalls: readonly {
blockOverrides?: BlockOverrides.Rpc | undefined
calls?: readonly TransactionRequest.Rpc[] | undefined
stateOverrides?: StateOverrides.Rpc | undefined
}[]
returnFullTransactions?: boolean | undefined
traceTransfers?: boolean | undefined
validation?: boolean | undefined
},
block:
| Block.Number<Hex.Hex>
| Block.Tag
| Block.Hash
| Block.Identifier,
]
}
ReturnType: readonly (Block.Rpc & {
calls?:
| readonly {
error?:
| {
data?: Hex.Hex | undefined
code: number
message: string
}
| undefined
logs?: readonly Log.Rpc[] | undefined
gasUsed: Hex.Hex
returnData: Hex.Hex
status: Hex.Hex
}[]
| undefined
})[]
}
/**
* Signs a transaction that can be submitted to the network at a later time using with `eth_sendRawTransaction`
*
* @example
* ```
* request({ method: 'eth_signTransaction', params: [{ from: '0x...', to: '0x...', value: '0x...' }] })
* // '0x...'
* ```
*/
| {
Request: {
method: 'eth_signTransaction'
params: [request: TransactionRequest.Rpc]
}
ReturnType: Hex.Hex
}
/**
* Calculates an Ethereum-specific signature in the form of `keccak256("\x19Ethereum Signed Message:\n" + len(message) + message))`
*
* @example
* ```
* request({ method: 'eth_signTypedData_v4', params: [{ from: '0x...', data: [{ type: 'string', name: 'message', value: 'hello world' }] }] })
* // '0x...'
* ```
*/
| {
Request: {
method: 'eth_signTypedData_v4'
params: [
/** Address to use for signing */
address: Address.Address,
/** Message to sign containing type information, a domain separator, and data */
message: string,
]
}
ReturnType: Hex.Hex
}
/**
* Destroys a filter based on filter ID
*
* @example
* ```
* request({ method: 'eth_uninstallFilter', params: ['0x1'] })
* // true
* ```
*/
| {
Request: {
method: 'eth_uninstallFilter'
params: [filterId: Hex.Hex]
}
ReturnType: boolean
}
>

428
node_modules/ox/core/internal/rpcSchemas/wallet.ts generated vendored Normal file
View File

@@ -0,0 +1,428 @@
import type * as Address from '../../Address.js'
import type * as Hex from '../../Hex.js'
import type * as RpcSchema from '../../RpcSchema.js'
import type * as TransactionRequest from '../../TransactionRequest.js'
import type { Compute } from '../types.js'
/**
* Union of all JSON-RPC Methods for the `wallet_` namespace.
*
* @example
* ```ts twoslash
* import { RpcSchema } from 'ox'
*
* type Schema = RpcSchema.Wallet
* // ^?
*
*
*
*
*
*
*
*
*
*
*
* ```
*/
export type Wallet = RpcSchema.From<
/**
* Requests that the user provides an Ethereum address to be identified by.
*
* @see {@link https://eips.ethereum.org/EIPS/eip-1102}
*/
| {
Request: {
method: 'eth_requestAccounts'
params?: undefined
}
ReturnType: readonly Address.Address[]
}
/**
* Sends a **signed** transaction to the network
*
* @example
* ```
* request({ method: 'eth_sendRawTransaction', params: ['0x...'] })
* // => '0x...'
* ```
*/
| {
Request: {
method: 'eth_sendRawTransaction'
params: [serializedTransaction: Hex.Hex]
}
ReturnType: Hex.Hex
}
/**
* Creates, signs, and sends a new transaction to the network
*
* @example
* ```
* request({ method: 'eth_sendTransaction', params: [{ from: '0x...', to: '0x...', value: '0x...' }] })
* // '0x...'
* ```
*/
| {
Request: {
method: 'eth_sendTransaction'
params: [transaction: TransactionRequest.Rpc]
}
ReturnType: Hex.Hex
}
/**
* Signs a transaction that can be submitted to the network at a later time using with `eth_sendRawTransaction`
*
* @example
* ```
* request({ method: 'eth_signTransaction', params: [{ from: '0x...', to: '0x...', value: '0x...' }] })
* // '0x...'
* ```
*/
| {
Request: {
method: 'eth_signTransaction'
params: [request: TransactionRequest.Rpc]
}
ReturnType: Hex.Hex
}
/**
* Calculates an Ethereum-specific signature in the form of `keccak256("\x19Ethereum Signed Message:\n" + len(message) + message))`
*
* @example
* ```
* request({ method: 'eth_signTypedData_v4', params: [{ from: '0x...', data: [{ type: 'string', name: 'message', value: 'hello world' }] }] })
* // '0x...'
* ```
*/
| {
Request: {
method: 'eth_signTypedData_v4'
params: [
/** Address to use for signing */
address: Address.Address,
/** Message to sign containing type information, a domain separator, and data */
message: string,
]
}
ReturnType: Hex.Hex
}
/**
* Calculates an Ethereum-specific signature in the form of `keccak256("\x19Ethereum Signed Message:\n" + len(message) + message))`
*
* @see {@link https://eips.ethereum.org/EIPS/eip-1474}
*/
| {
Request: {
method: 'personal_sign'
params: [
/** Data to sign */
data: Hex.Hex,
/** Address to use for signing */
address: Address.Address,
]
}
ReturnType: Hex.Hex
}
/**
* Add an Ethereum chain to the wallet.
*
* @see {@link https://eips.ethereum.org/EIPS/eip-3085}
*/
| {
Request: {
method: 'wallet_addEthereumChain'
params: [chain: Compute<WalletAddEthereumChainParameters>]
}
ReturnType: null
}
/**
* Returns the status of a call batch that was sent via `wallet_sendCalls`.
*
* @see {@link https://eips.ethereum.org/EIPS/eip-5792}
*/
| {
Request: {
method: 'wallet_getCallsStatus'
params?: [string]
}
ReturnType: Compute<WalletGetCallsStatusReturnType>
}
/**
* Gets the connected wallet's capabilities.
*
* @see {@link https://eips.ethereum.org/EIPS/eip-5792}
*/
| {
Request: {
method: 'wallet_getCapabilities'
params?: [Address.Address]
}
ReturnType: Compute<WalletCapabilitiesMap>
}
/**
* Gets the wallets current permissions.
*
* @see {@link https://eips.ethereum.org/EIPS/eip-2255}
*/
| {
Request: {
method: 'wallet_getPermissions'
params?: undefined
}
ReturnType: readonly Compute<WalletPermission>[]
}
/**
* Requests permissions from a wallet.
*
* @see {@link https://eips.ethereum.org/EIPS/eip-7715}
*/
| {
Request: {
method: 'wallet_grantPermissions'
params?: [WalletGrantPermissionsParameters]
}
ReturnType: Compute<WalletGrantPermissionsReturnType>
}
/**
* Requests the given permissions from the user.
*
* @see {@link https://eips.ethereum.org/EIPS/eip-2255}
*/
| {
Request: {
method: 'wallet_requestPermissions'
params: [permissions: { eth_accounts: Record<string, any> }]
}
ReturnType: readonly Compute<WalletPermission>[]
}
/**
* Revokes the given permissions from the user.
*
* @see {@link https://github.com/MetaMask/metamask-improvement-proposals/blob/main/MIPs/mip-2.md}
*/
| {
Request: {
method: 'wallet_revokePermissions'
params: [permissions: { eth_accounts: Record<string, any> }]
}
ReturnType: null
}
/**
* Requests the connected wallet to send a batch of calls.
*
* @see {@link https://eips.ethereum.org/EIPS/eip-5792}
*/
| {
Request: {
method: 'wallet_sendCalls'
params: Compute<WalletSendCallsParameters>
}
ReturnType: string
}
/**
* Requests for the wallet to show information about a call batch
* that was sent via `wallet_sendCalls`.
*
* @see {@link https://eips.ethereum.org/EIPS/eip-5792}
*/
| {
Request: {
method: 'wallet_showCallsStatus'
params: [string]
}
ReturnType: undefined
}
/**
* Switch the wallet to the given Ethereum chain.
*
* @see {@link https://eips.ethereum.org/EIPS/eip-3326}
*/
| {
Request: {
method: 'wallet_switchEthereumChain'
params: [chain: { chainId: string }]
}
ReturnType: null
}
/**
* Requests that the user tracks the token in their wallet. Returns a boolean indicating if the token was successfully added.
*
* @see {@link https://eips.ethereum.org/EIPS/eip-747}
*/
| {
Request: {
method: 'wallet_watchAsset'
params: [Compute<WalletWatchAssetParameters>]
}
ReturnType: boolean
}
>
/**
* Parameters for `wallet_addEthereumChain`. [See more](https://eips.ethereum.org/EIPS/eip-3085).
* @internal
*/
type WalletAddEthereumChainParameters = {
/** A 0x-prefixed hexadecimal string */
chainId: string
/** The chain name. */
chainName: string
/** Native currency for the chain. */
nativeCurrency?:
| {
name: string
symbol: string
decimals: number
}
| undefined
rpcUrls: readonly string[]
blockExplorerUrls?: readonly string[] | undefined
iconUrls?: readonly string[] | undefined
}
/**
* Capabilities of a wallet. [See more](https://eips.ethereum.org/EIPS/eip-5792#wallet_getcapabilities).
* @internal
*/
type WalletCapabilities = {
[capability: string]: any
}
/**
* Capabilities of a wallet, mapped to chain IDs. [See more](https://eips.ethereum.org/EIPS/eip-5792#wallet_getcapabilities).
* @internal
*/
type WalletCapabilitiesMap = {
[chainId: Hex.Hex]: WalletCapabilities
}
/**
* Return type for `wallet_getCallsStatus`. [See more](https://eips.ethereum.org/EIPS/eip-5792#wallet_getcallsstatus).
* @internal
*/
type WalletGetCallsStatusReturnType = {
status: 'PENDING' | 'CONFIRMED'
receipts?:
| readonly {
logs: {
address: Hex.Hex
data: Hex.Hex
topics: readonly Hex.Hex[]
}[]
status: Hex.Hex
blockHash: Hex.Hex
blockNumber: Hex.Hex
gasUsed: Hex.Hex
transactionHash: Hex.Hex
}[]
| undefined
}
/**
* Caveat for a wallet permission. [See more](https://eips.ethereum.org/EIPS/eip-2255).
* @internal
*/
type WalletPermissionCaveat = {
type: string
value: any
}
/**
* A wallet permission. [See more](https://eips.ethereum.org/EIPS/eip-2255).
* @internal
*/
type WalletPermission = {
caveats: readonly WalletPermissionCaveat[]
date: number
id: string
invoker: `http://${string}` | `https://${string}`
parentCapability: 'eth_accounts' | string
}
/**
* Parameters for `wallet_grantPermissions`. [See more](https://eips.ethereum.org/EIPS/eip-7715).
* @internal
*/
type WalletGrantPermissionsParameters = {
signer?:
| {
type: string
data?: unknown | undefined
}
| undefined
permissions: readonly {
data: unknown
policies: readonly {
data: unknown
type: string
}[]
required?: boolean | undefined
type: string
}[]
expiry: number
}
/**
* Return type for `wallet_grantPermissions`. [See more](https://eips.ethereum.org/EIPS/eip-7715).
* @internal
*/
type WalletGrantPermissionsReturnType = {
expiry: number
factory?: `0x${string}` | undefined
factoryData?: string | undefined
grantedPermissions: readonly {
data: unknown
policies: readonly {
data: unknown
type: string
}[]
required?: boolean | undefined
type: string
}[]
permissionsContext: string
signerData?:
| {
userOpBuilder?: `0x${string}` | undefined
submitToAddress?: `0x${string}` | undefined
}
| undefined
}
/**
* Parameters for `wallet_sendCalls`. [See more](https://eips.ethereum.org/EIPS/eip-5792).
* @internal
*/
type WalletSendCallsParameters = [
{
calls: readonly {
to?: Address.Address | undefined
data?: Hex.Hex | undefined
value?: Hex.Hex | undefined
}[]
capabilities?: WalletCapabilities | undefined
chainId?: Hex.Hex | undefined
from: Address.Address
version: string
},
]
/**
* Parameters for `wallet_watchAsset`. [See more](https://eips.ethereum.org/EIPS/eip-747).
* @internal
*/
type WalletWatchAssetParameters = {
/** Token type. */
type: 'ERC20'
options: {
/** The address of the token contract */
address: string
/** A ticker symbol or shorthand, up to 11 characters */
symbol: string
/** The number of token decimals */
decimals: number
/** A string url of the token logo */
image?: string | undefined
}
}

69
node_modules/ox/core/internal/rpcTransport.ts generated vendored Normal file
View File

@@ -0,0 +1,69 @@
import type * as Errors from '../Errors.js'
import * as RpcRequest from '../RpcRequest.js'
import * as RpcResponse from '../RpcResponse.js'
import type * as RpcSchema from '../RpcSchema.js'
import type * as RpcTransport from '../RpcTransport.js'
import type { Compute } from './types.js'
/** @internal */
export type Options<
raw extends boolean | undefined = undefined,
options extends Record<string, unknown> = {},
schema extends RpcSchema.Generic = RpcSchema.Default,
> = {
/**
* Enables raw mode responses will return an object with `result` and `error` properties instead of returning the `result` directly and throwing errors.
*
* - `true`: a JSON-RPC response object will be returned with `result` and `error` properties.
* - `false`: the JSON-RPC response object's `result` property will be returned directly, and JSON-RPC Errors will be thrown.
*
* @default false
*/
raw?: raw | boolean | undefined
/**
* RPC Schema to use for the Transport's `request` function.
* See {@link ox#RpcSchema.(from:function)} for more.
*
* @default `RpcSchema.Default`
*/
schema?: schema | RpcSchema.Default | undefined
} & options
/** @internal */
export function create<
options extends Record<string, unknown> = {},
schema extends RpcSchema.Generic = RpcSchema.Default,
raw extends boolean = false,
>(
transport: create.Transport<options>,
options_root?: Options<raw, options, schema>,
): RpcTransport.RpcTransport<raw, options, schema> {
const requestStore = RpcRequest.createStore()
return {
request: async ({ method, params }, options: any = {}) => {
const body = requestStore.prepare({ method, params } as never)
const data = await transport.request(body as never, options as never)
return RpcResponse.parse(data, {
raw: options.raw ?? options_root?.raw,
}) as never
},
}
}
/** @internal */
export declare namespace create {
type Transport<options extends Record<string, unknown> = {}> = {
request: (
body: Compute<Omit<RpcRequest.RpcRequest, '_returnType'>>,
options: options,
) => Promise<RpcResponse.RpcResponse>
}
type ErrorType =
| RpcRequest.createStore.ErrorType
| RpcResponse.parse.ErrorType
| Errors.GlobalErrorType
}

414
node_modules/ox/core/internal/types.ts generated vendored Normal file
View File

@@ -0,0 +1,414 @@
/** Combines members of an intersection into a readable type. */
// https://twitter.com/mattpocockuk/status/1622730173446557697?s=20&t=NdpAcmEFXY01xkqU3KO0Mg
export type Compute<type> = { [key in keyof type]: type[key] } & unknown
declare const symbol: unique symbol
/**
* Creates a branded type of `T` with the brand `U`.
*
* @example
* ```ts
* type Result = Branded<string, 'foo'>
* // ^? type Result = string & { [symbol]: 'foo' }
* ```
*/
export type Branded<T, U> = T & { [symbol]: U }
/**
* Filters out all members of `T` that are not `P`
*
* @example
* ```ts
* type Result = Filter<['a', 'b', 'c'], 'b'>
* // ^? type Result = ['a', 'c']
* ```
*
* @internal
*/
export type Filter<
T extends readonly unknown[],
P,
Acc extends readonly unknown[] = [],
> = T extends readonly [infer F, ...infer Rest extends readonly unknown[]]
? [F] extends [P]
? Filter<Rest, P, [...Acc, F]>
: Filter<Rest, P, Acc>
: readonly [...Acc]
/**
* Checks if `T` can be narrowed further than `U`
*
* @example
* ```ts
* type Result = IsNarrowable<'foo', string>
* // ^? true
* ```
*/
export type IsNarrowable<T, U> = IsNever<
(T extends U ? true : false) & (U extends T ? false : true)
> extends true
? false
: true
/**
* Checks if `T` is `never`
*
* @example
* ```ts
* type Result = IsNever<never>
* // ^? type Result = true
* ```
*/
export type IsNever<T> = [T] extends [never] ? true : false
/**
* Removes `readonly` from all properties of an object.
*
* @internal
*/
export type Mutable<type extends object> = {
-readonly [key in keyof type]: type[key]
}
/**
* Evaluates boolean "or" condition for `T` properties.
*
* * @example
* ```ts
* type Result = Or<[false, true, false]>
* // ^? type Result = true
* ```
*
* @example
* ```ts
* type Result = Or<[false, false, false]>
* // ^? type Result = false
* ```
*
* @internal
*/
export type Or<T extends readonly unknown[]> = T extends readonly [
infer Head,
...infer Tail,
]
? Head extends true
? true
: Or<Tail>
: false
/**
* Checks if `T` is `undefined`
*
* @example
* ```ts
* type Result = IsUndefined<undefined>
* // ^? type Result = true
* ```
*
* @internal
*/
export type IsUndefined<T> = [undefined] extends [T] ? true : false
/**
* Checks if type `T` is the `unknown` type.
*
* @internal
*/
export type IsUnknown<T> = unknown extends T
? [T] extends [null]
? false
: true
: false
/** @internal */
export type MaybePromise<T> = T | Promise<T>
/**
* Makes attributes on the type T required if required is true.
*
* @example
* ```ts
* MaybeRequired<{ a: string, b?: number }, true>
* // { a: string, b: number }
*
* MaybeRequired<{ a: string, b?: number }, false>
* // { a: string, b?: number }
* ```
*
* @internal
*/
export type MaybeRequired<T, required extends boolean> = required extends true
? ExactRequired<T>
: T
/**
* Assigns the properties of U onto T.
*
* @example
* ```ts
* Assign<{ a: string, b: number }, { a: undefined, c: boolean }>
* // { a: undefined, b: number, c: boolean }
* ```
*
* @internal
*/
export type Assign<T, U> = Assign_inner<T, U> & U
/** @internal */
export type Assign_inner<T, U> = {
[K in keyof T as K extends keyof U
? U[K] extends void
? never
: K
: K]: K extends keyof U ? U[K] : T[K]
}
/**
* Constructs a type by excluding `undefined` from `T`.
*
* @example
* ```ts
* NoUndefined<string | undefined>
* // string
* ```
*
* @internal
*/
export type NoUndefined<T> = T extends undefined ? never : T
/**
* Strict version of built-in Omit type
*
* @internal
*/
export type Omit<type, keys extends keyof type> = Pick<
type,
Exclude<keyof type, keys>
>
/**
* Creates a type that is a partial of T, but with the required keys K.
*
* @example
* ```ts
* PartialBy<{ a: string, b: number }, 'a'>
* // { a?: string, b: number }
* ```
*
* @internal
*/
export type PartialBy<T, K extends keyof T> = Omit<T, K> &
ExactPartial<Pick<T, K>>
export type RecursiveArray<T> = T | readonly RecursiveArray<T>[]
/**
* Creates a type that is T with the required keys K.
*
* @example
* ```ts
* RequiredBy<{ a?: string, b: number }, 'a'>
* // { a: string, b: number }
* ```
*
* @internal
*/
export type RequiredBy<T, K extends keyof T> = Omit<T, K> &
ExactRequired<Pick<T, K>>
/**
* Returns truthy if `array` contains `value`.
*
* @example
* ```ts
* Some<[1, 2, 3], 2>
* // true
* ```
*
* @internal
*/
export type Some<
array extends readonly unknown[],
value,
> = array extends readonly [value, ...unknown[]]
? true
: array extends readonly [unknown, ...infer rest]
? Some<rest, value>
: false
/**
* Prints custom error message
*
* @param messages - Error message
* @returns Custom error message
*
* @example
* ```ts
* type Result = TypeErrorMessage<'Custom error message'>
* // ^? type Result = ['Error: Custom error message']
* ```
*/
export type TypeErrorMessage<messages extends string | string[]> =
messages extends string
? [
// Surrounding with array to prevent `messages` from being widened to `string`
`Error: ${messages}`,
]
: {
[key in keyof messages]: messages[key] extends infer message extends
string
? `Error: ${message}`
: never
}
/** @internal */
export type UnionToTuple<
union,
///
last = LastInUnion<union>,
> = [union] extends [never] ? [] : [...UnionToTuple<Exclude<union, last>>, last]
/** @internal */
export type LastInUnion<U> = UnionToIntersection<
U extends unknown ? (x: U) => 0 : never
> extends (x: infer l) => 0
? l
: never
/** @internal */
export type UnionToIntersection<union> = (
union extends unknown
? (arg: union) => 0
: never
) extends (arg: infer i) => 0
? i
: never
/** @internal */
export type IsUnion<
union,
///
union2 = union,
> = union extends union2 ? ([union2] extends [union] ? false : true) : never
/** @internal */
export type MaybePartial<
type,
enabled extends boolean | undefined,
> = enabled extends true ? Compute<ExactPartial<type>> : type
export type ExactPartial<type> = {
[key in keyof type]?: type[key] | undefined
}
/** @internal */
export type ExactRequired<type> = {
[key in keyof type]-?: Exclude<type[key], undefined>
}
export type OneOf<
union extends object,
fallback extends object | undefined = undefined,
///
keys extends KeyofUnion<union> = KeyofUnion<union>,
> = union extends infer item
? Compute<
item & {
[key in Exclude<keys, keyof item>]?: fallback extends object
? key extends keyof fallback
? fallback[key]
: undefined
: undefined
}
>
: never
/** @internal */
export type KeyofUnion<type> = type extends type ? keyof type : never
/** @internal */
export type Undefined<type> = {
[key in keyof type]?: undefined
}
///////////////////////////////////////////////////////////////////////////
// Loose types
/**
* Loose version of {@link Omit}
* @internal
*/
export type LooseOmit<type, keys extends string> = Pick<
type,
Exclude<keyof type, keys>
>
///////////////////////////////////////////////////////////////////////////
// Union types
/** @internal */
export type UnionCompute<type> = type extends object ? Compute<type> : type
/** @internal */
export type UnionLooseOmit<type, keys extends string> = type extends any
? LooseOmit<type, keys>
: never
/**
* Construct a type with the properties of union type T except for those in type K.
* @example
* ```ts
* type Result = UnionOmit<{ a: string, b: number } | { a: string, b: undefined, c: number }, 'a'>
* // { b: number } | { b: undefined, c: number }
* ```
*
* @internal
*/
export type UnionOmit<type, keys extends keyof type> = type extends any
? Omit<type, keys>
: never
/**
* Construct a type with the properties of union type T except for those in type K.
* @example
* ```ts
* type Result = UnionOmit<{ a: string, b: number } | { a: string, b: undefined, c: number }, 'a'>
* // { b: number } | { b: undefined, c: number }
* ```
*
* @internal
*/
export type UnionPick<type, keys extends keyof type> = type extends any
? Pick<type, keys>
: never
/**
* Creates a type that is a partial of T, but with the required keys K.
*
* @example
* ```ts
* PartialBy<{ a: string, b: number } | { a: string, b: undefined, c: number }, 'a'>
* // { a?: string, b: number } | { a?: string, b: undefined, c: number }
* ```
*
* @internal
*/
export type UnionPartialBy<T, K extends keyof T> = T extends any
? PartialBy<T, K>
: never
/**
* Creates a type that is T with the required keys K.
*
* @example
* ```ts
* RequiredBy<{ a?: string, b: number } | { a?: string, c?: number }, 'a'>
* // { a: string, b: number } | { a: string, c?: number }
* ```
*
* @internal
*/
export type UnionRequiredBy<T, K extends keyof T> = T extends any
? RequiredBy<T, K>
: never

15
node_modules/ox/core/internal/uid.ts generated vendored Normal file
View File

@@ -0,0 +1,15 @@
const size = 256
let index = size
let buffer: string
/** @internal */
export function uid(length = 11) {
if (!buffer || index + length > size * 2) {
buffer = ''
index = 0
for (let i = 0; i < size; i++) {
buffer += ((256 + Math.random() * 256) | 0).toString(16).substring(1)
}
}
return buffer.substring(index, index++ + length)
}

239
node_modules/ox/core/internal/webauthn.ts generated vendored Normal file
View File

@@ -0,0 +1,239 @@
import { p256 } from '@noble/curves/p256'
import type * as Errors from '../Errors.js'
import * as Hex from '../Hex.js'
import * as PublicKey from '../PublicKey.js'
import { CredentialCreationFailedError } from '../WebAuthnP256.js'
/** @internal */
export type AttestationConveyancePreference =
| 'direct'
| 'enterprise'
| 'indirect'
| 'none'
/** @internal */
export type AuthenticatorAttachment = 'cross-platform' | 'platform'
/** @internal */
export type AuthenticatorTransport =
| 'ble'
| 'hybrid'
| 'internal'
| 'nfc'
| 'usb'
/** @internal */
export type COSEAlgorithmIdentifier = number
/** @internal */
export type CredentialMediationRequirement =
| 'conditional'
| 'optional'
| 'required'
| 'silent'
/** @internal */
export type PublicKeyCredentialType = 'public-key'
/** @internal */
export type ResidentKeyRequirement = 'discouraged' | 'preferred' | 'required'
/** @internal */
export type UserVerificationRequirement =
| 'discouraged'
| 'preferred'
| 'required'
/** @internal */
export type LargeBlobSupport = {
support: 'required' | 'preferred'
}
/** @internal */
export type BufferSource = ArrayBufferView | ArrayBuffer
/** @internal */
export type PrfExtension = Record<'eval', Record<'first', Uint8Array>>
/** @internal */
export interface AuthenticationExtensionsClientInputs {
appid?: string
credProps?: boolean
hmacCreateSecret?: boolean
minPinLength?: boolean
prf?: PrfExtension
largeBlob?: LargeBlobSupport
}
/** @internal */
export interface AuthenticatorSelectionCriteria {
authenticatorAttachment?: AuthenticatorAttachment
requireResidentKey?: boolean
residentKey?: ResidentKeyRequirement
userVerification?: UserVerificationRequirement
}
/** @internal */
export interface Credential {
readonly id: string
readonly type: string
}
/** @internal */
export interface CredentialCreationOptions {
publicKey?: PublicKeyCredentialCreationOptions
signal?: AbortSignal
}
/** @internal */
export interface CredentialRequestOptions {
mediation?: CredentialMediationRequirement
publicKey?: PublicKeyCredentialRequestOptions
signal?: AbortSignal
}
/** @internal */
export interface PublicKeyCredential extends Credential {
readonly authenticatorAttachment: string | null
readonly rawId: ArrayBuffer
readonly response: AuthenticatorResponse
getClientExtensionResults(): AuthenticationExtensionsClientOutputs
}
/** @internal */
export interface PublicKeyCredentialCreationOptions {
attestation?: AttestationConveyancePreference
authenticatorSelection?: AuthenticatorSelectionCriteria
challenge: BufferSource
excludeCredentials?: PublicKeyCredentialDescriptor[]
extensions?: AuthenticationExtensionsClientInputs
pubKeyCredParams: PublicKeyCredentialParameters[]
rp: PublicKeyCredentialRpEntity
timeout?: number
user: PublicKeyCredentialUserEntity
}
/** @internal */
export interface PublicKeyCredentialDescriptor {
id: BufferSource
transports?: AuthenticatorTransport[]
type: PublicKeyCredentialType
}
/** @internal */
export interface PublicKeyCredentialEntity {
name: string
}
/** @internal */
export interface PublicKeyCredentialParameters {
alg: COSEAlgorithmIdentifier
type: PublicKeyCredentialType
}
/** @internal */
export interface PublicKeyCredentialRequestOptions {
allowCredentials?: PublicKeyCredentialDescriptor[]
challenge: BufferSource
extensions?: AuthenticationExtensionsClientInputs
rpId?: string
timeout?: number
userVerification?: UserVerificationRequirement
}
/** @internal */
export interface PublicKeyCredentialRpEntity extends PublicKeyCredentialEntity {
id?: string
}
/** @internal */
export interface PublicKeyCredentialUserEntity
extends PublicKeyCredentialEntity {
displayName: string
id: BufferSource
}
/**
* Parses an ASN.1 signature into a r and s value.
*
* @internal
*/
export function parseAsn1Signature(bytes: Uint8Array) {
const r_start = bytes[4] === 0 ? 5 : 4
const r_end = r_start + 32
const s_start = bytes[r_end + 2] === 0 ? r_end + 3 : r_end + 2
const r = BigInt(Hex.fromBytes(bytes.slice(r_start, r_end)))
const s = BigInt(Hex.fromBytes(bytes.slice(s_start)))
return {
r,
s: s > p256.CURVE.n / 2n ? p256.CURVE.n - s : s,
}
}
/**
* Parses a public key into x and y coordinates from the public key
* defined on the credential.
*
* @internal
*/
export async function parseCredentialPublicKey(
response: AuthenticatorAttestationResponse,
): Promise<PublicKey.PublicKey> {
try {
const publicKeyBuffer = response.getPublicKey()
if (!publicKeyBuffer) throw new CredentialCreationFailedError()
// Converting `publicKeyBuffer` throws when credential is created by 1Password Firefox Add-on
const publicKeyBytes = new Uint8Array(publicKeyBuffer)
const cryptoKey = await crypto.subtle.importKey(
'spki',
new Uint8Array(publicKeyBytes),
{
name: 'ECDSA',
namedCurve: 'P-256',
hash: 'SHA-256',
},
true,
['verify'],
)
const publicKey = new Uint8Array(
await crypto.subtle.exportKey('raw', cryptoKey),
)
return PublicKey.from(publicKey)
} catch (error) {
// Fallback for 1Password Firefox Add-on restricts access to certain credential properties
// so we need to use `attestationObject` to extract the public key.
// https://github.com/passwordless-id/webauthn/issues/50#issuecomment-2072902094
if ((error as Error).message !== 'Permission denied to access object')
throw error
const data = new Uint8Array(response.attestationObject)
const coordinateLength = 0x20
const cborPrefix = 0x58
const findStart = (key: number) => {
const coordinate = new Uint8Array([key, cborPrefix, coordinateLength])
for (let i = 0; i < data.length - coordinate.length; i++)
if (coordinate.every((byte, j) => data[i + j] === byte))
return i + coordinate.length
throw new CredentialCreationFailedError()
}
const xStart = findStart(0x21)
const yStart = findStart(0x22)
return PublicKey.from(
new Uint8Array([
0x04,
...data.slice(xStart, xStart + coordinateLength),
...data.slice(yStart, yStart + coordinateLength),
]),
)
}
}
export declare namespace parseCredentialPublicKey {
type ErrorType = CredentialCreationFailedError | Errors.GlobalErrorType
}