ox
Version:
357 lines (339 loc) • 7.36 kB
text/typescript
import type { ResolvedRegister } from './internal/register.js'
import type { Compute, IsNarrowable } from './internal/types.js'
export type { Eth } from './internal/rpcSchemas/eth.js'
export type { Wallet } from './internal/rpcSchemas/wallet.js'
/**
* Instantiates a statically typed Schema. This is a runtime-noop function, and is purposed
* to be used as a type-level tag to be used with {@link ox#Provider.(from:function)} or
* {@link ox#RpcTransport.(fromHttp:function)}.
*
* @example
* ### Using with `Provider.from`
*
* ```ts twoslash
* // @noErrors
* import 'ox/window'
* import { Provider, RpcSchema } from 'ox'
*
* const schema = RpcSchema.from<
* | RpcSchema.Default
* | {
* Request: {
* method: 'abe_foo',
* params: [id: number],
* }
* ReturnType: string
* }
* | {
* Request: {
* method: 'abe_bar',
* params: [id: string],
* }
* ReturnType: string
* }
* >()
*
* const provider = Provider.from(window.ethereum, { schema })
*
* const blockNumber = await provider.request({ method: 'e' })
* // ^|
*
*
*
*
*
* ```
*/
export function from<schema extends Generic>(): schema {
return null as never
}
/**
* Extracts a schema item from a {@link ox#RpcSchema.Generic} or {@link ox#RpcSchema.MethodNameGeneric}.
*
* @example
* ```ts twoslash
* import { RpcSchema } from 'ox'
*
* type Item = RpcSchema.ExtractItem<RpcSchema.Eth, 'eth_getBlockByNumber'>
* // ^?
*
*
*
*
*
*
*
*
*
*
*
*
*
* ```
*/
export type ExtractItem<
schema extends Generic,
methodName extends MethodNameGeneric<schema> = MethodNameGeneric<schema>,
> = Compute<{
Request: ExtractRequest<schema, methodName>
ReturnType: ExtractReturnType<schema, methodName>
}>
/**
* Extracts request from a {@link ox#RpcSchema.Generic} or {@link ox#RpcSchema.MethodNameGeneric}.
*
* @example
* ```ts twoslash
* import { RpcSchema } from 'ox'
*
* type Request = RpcSchema.ExtractRequest<RpcSchema.Eth, 'eth_getBlockByNumber'>
* // ^?
*
*
*
*
*
*
*
*
*
*
*
* ```
*/
export type ExtractRequest<
schema extends Generic,
methodName extends MethodNameGeneric<schema> = MethodNameGeneric<schema>,
> = Extract<schema['Request'], { method: methodName }>
/**
* Type-safe union of all JSON-RPC Method Names.
*
* @example
* ```ts twoslash
* import { RpcSchema } from 'ox'
*
* type MethodName = RpcSchema.ExtractMethodName<RpcSchema.Default>
* // ^?
*
*
*
*
*
*
*
*
* ```
*/
export type ExtractMethodName<schema extends Generic> =
schema['Request']['method']
/**
* Extracts parameters from a {@link ox#RpcSchema.Generic} or {@link ox#RpcSchema.MethodNameGeneric}.
*
* @example
* ```ts twoslash
* import { RpcSchema } from 'ox'
*
* type Eth_GetBlockByNumber = RpcSchema.ExtractParams<RpcSchema.Eth, 'eth_getBlockByNumber'>
* // ^?
*
*
*
*
*
* ```
*/
export type ExtractParams<
schema extends Generic,
methodName extends MethodNameGeneric<schema> = MethodNameGeneric<schema>,
> = ExtractRequest<schema, methodName>['params']
/**
* Extracts return type from a {@link ox#RpcSchema.Generic} or {@link ox#RpcSchema.MethodNameGeneric}.
*
* @example
* ```ts twoslash
* import { RpcSchema } from 'ox'
*
* type ReturnType = RpcSchema.ExtractReturnType<RpcSchema.Eth, 'eth_getBlockByNumber'>
* // ^?
*
*
*
*
*
*
*
*
*
*
*
* ```
*/
export type ExtractReturnType<
schema extends Generic,
methodName extends MethodNameGeneric<schema> = MethodNameGeneric<schema>,
> = methodName extends schema['Request']['method']
? IsNarrowable<schema, Generic> extends true
? Extract<schema, { Request: { method: methodName } }>['ReturnType']
: unknown
: unknown
/**
* Type to define a custom type-safe JSON-RPC Schema.
*
* @example
* ```ts twoslash
* import { RpcSchema, RpcRequest } from 'ox'
*
* type Schema = RpcSchema.From<{
* Request: {
* method: 'eth_foobar',
* params: [id: number],
* }
* ReturnType: string
* }>
* ```
*/
export type From<schema extends Generic> = schema
/**
* Generic type to define a JSON-RPC Method.
*
* @example
* ```ts twoslash
* import { RpcSchema } from 'ox'
*
* type Schema = RpcSchema.Generic
* // ^?
*
*
*
*
*
*
* ```
*/
export type Generic<name extends string = string, params = unknown> = {
Request: {
method: name
params?: params | undefined
}
ReturnType?: unknown
}
/**
* Type-safe union of all JSON-RPC Methods.
*
* @example
* ```ts twoslash
* import { RpcSchema } from 'ox'
*
* type Schema = RpcSchema.Default
* // ^?
*
*
*
*
*
*
*
*
*
*
*
*
*
* ```
*/
export type Default = ResolvedRegister['RpcSchema']
/**
* Generic type to define a JSON-RPC Method Name.
*
* @example
* ```ts twoslash
* import { RpcSchema } from 'ox'
*
* type Name = RpcSchema.MethodNameGeneric
* // ^?
*
*
*
*
*
* ```
*/
export type MethodNameGeneric<schema extends Generic = Generic> =
| schema['Request']['method']
| (string & {})
/**
* Converts an Ox {@link ox#RpcSchema.Generic} (union of `{ Request, ReturnType }`) to
* a [Viem-compatible RPC schema](https://viem.sh) (tuple of `{ Method, Parameters, ReturnType }`).
*
* @example
* ```ts twoslash
* import { RpcSchema } from 'ox'
*
* type ViemSchema = RpcSchema.ToViem<
* | {
* Request: { method: 'eth_blockNumber'; params?: undefined }
* ReturnType: `0x${string}`
* }
* | {
* Request: { method: 'eth_chainId'; params?: undefined }
* ReturnType: `0x${string}`
* }
* >
* ```
*/
export type ToViem<schema extends Generic> = UnionToTuple<
schema extends schema
? {
Method: schema['Request']['method']
Parameters: schema['Request']['params']
ReturnType: schema extends { ReturnType: infer r } ? r : unknown
}
: never
>
/**
* Converts a [Viem-compatible RPC schema](https://viem.sh) (tuple of `{ Method, Parameters, ReturnType }`)
* to an Ox {@link ox#RpcSchema.Generic} (union of `{ Request, ReturnType }`).
*
* @example
* ```ts twoslash
* import { RpcSchema } from 'ox'
*
* type OxSchema = RpcSchema.FromViem<[
* { Method: 'eth_blockNumber'; Parameters?: undefined; ReturnType: `0x${string}` },
* { Method: 'eth_chainId'; Parameters?: undefined; ReturnType: `0x${string}` },
* ]>
* ```
*/
export type FromViem<schema extends readonly ViemSchemaItem[]> = {
[k in keyof schema]: schema[k] extends ViemSchemaItem
? {
Request: {
method: schema[k]['Method']
params: schema[k]['Parameters']
}
ReturnType: schema[k]['ReturnType']
}
: never
}[number]
/** @internal */
type ViemSchemaItem = {
Method: string
Parameters?: unknown
ReturnType?: unknown
}
// --- Union-to-tuple helpers (order is not guaranteed, but stable) ---
/** @internal */
type UnionToIntersection<union> = (
union extends unknown
? (arg: () => union) => void
: never
) extends (arg: infer intersection) => void
? intersection
: never
/** @internal */
type UnionLast<union> = UnionToIntersection<union> extends () => infer last
? last
: never
/** @internal */
type UnionToTuple<union, last = UnionLast<union>> = [union] extends [never]
? []
: [...UnionToTuple<Exclude<union, last>>, last]