UNPKG

ox

Version:

Ethereum Standard Library

402 lines 17.1 kB
import { EventEmitter } from 'eventemitter3'; import type * as Address from './Address.js'; import * as Errors from './Errors.js'; import type * as RpcSchema_internal from './internal/rpcSchema.js'; import type { Compute, IsNarrowable, IsNever } from './internal/types.js'; import * as RpcResponse from './RpcResponse.js'; import type * as RpcSchema from './RpcSchema.js'; /** Options for a {@link ox#Provider.Provider}. */ export type Options = { /** * RPC Schema to use for the Provider's `request` function. * See {@link ox#RpcSchema.(from:function)} for more. * * @default `RpcSchema.Generic` */ schema?: RpcSchema.Schema | undefined; }; /** Root type for an EIP-1193 Provider. */ export type Provider<options extends Options | undefined = undefined, eventMap extends boolean | Record<string, unknown> = false, _schema extends RpcSchema.Generic = options extends { schema: infer schema extends RpcSchema.Schema; } ? RpcSchema.ToGeneric<schema> : RpcSchema.Default> = Compute<{ request: RequestFn<_schema>; } & ((eventMap extends true ? Emitter<EventMap> : never) | (eventMap extends false ? Partial<Emitter<EventMap>> : never) | (eventMap extends Record<string, unknown> ? Emitter<eventMap> : never))>; /** Type for an EIP-1193 Provider's event emitter. */ export type Emitter<eventMap extends Record<string, unknown> | undefined = undefined> = Compute<EventEmitter<EventMap<eventMap>>>; /** EIP-1193 Provider's `request` function. */ export type RequestFn<schema extends RpcSchema.Generic = RpcSchema.Generic> = <methodName extends RpcSchema.MethodNameGeneric>(parameters: RpcSchema_internal.ExtractRequestOpaque<schema, methodName>) => Promise<RpcSchema.ExtractReturnType<schema, methodName>>; export type ConnectInfo = { chainId: string; }; export type Message = { type: string; data: unknown; }; export declare class ProviderRpcError extends Error { name: string; code: number; details: string; constructor(code: number, message: string); } export type EventMap<eventMap extends Record<string, unknown> | undefined = undefined> = { accountsChanged: (accounts: readonly Address.Address[]) => void; chainChanged: (chainId: string) => void; connect: (connectInfo: ConnectInfo) => void; disconnect: (error: ProviderRpcError) => void; message: (message: Message) => void; } & (eventMap extends Record<string, unknown> ? eventMap : {}); /** The user rejected the request. */ export declare class UserRejectedRequestError extends ProviderRpcError { static readonly code = 4001; readonly code = 4001; readonly name = "Provider.UserRejectedRequestError"; constructor({ message, }?: { message?: string | undefined; }); } /** The requested method and/or account has not been authorized by the user. */ export declare class UnauthorizedError extends ProviderRpcError { static readonly code = 4100; readonly code = 4100; readonly name = "Provider.UnauthorizedError"; constructor({ message, }?: { message?: string | undefined; }); } /** The provider does not support the requested method. */ export declare class UnsupportedMethodError extends ProviderRpcError { static readonly code = 4200; readonly code = 4200; readonly name = "Provider.UnsupportedMethodError"; constructor({ message, }?: { message?: string | undefined; }); } /** The provider is disconnected from all chains. */ export declare class DisconnectedError extends ProviderRpcError { static readonly code = 4900; readonly code = 4900; readonly name = "Provider.DisconnectedError"; constructor({ message, }?: { message?: string | undefined; }); } /** The provider is not connected to the requested chain. */ export declare class ChainDisconnectedError extends ProviderRpcError { static readonly code = 4901; readonly code = 4901; readonly name = "Provider.ChainDisconnectedError"; constructor({ message, }?: { message?: string | undefined; }); } /** An error occurred when attempting to switch chain. */ export declare class SwitchChainError extends ProviderRpcError { static readonly code = 4902; readonly code = 4902; readonly name = "Provider.SwitchChainError"; constructor({ message, }?: { message?: string | undefined; }); } /** This Wallet does not support a capability that was not marked as optional. */ export declare class UnsupportedNonOptionalCapabilityError extends ProviderRpcError { static readonly code = 5700; readonly code = 5700; readonly name = "Provider.UnsupportedNonOptionalCapabilityError"; constructor({ message, }?: { message?: string | undefined; }); } /** This Wallet does not support the requested chain ID. */ export declare class UnsupportedChainIdError extends ProviderRpcError { static readonly code = 5710; readonly code = 5710; readonly name = "Provider.UnsupportedChainIdError"; constructor({ message, }?: { message?: string | undefined; }); } /** There is already a bundle submitted with this ID. */ export declare class DuplicateIdError extends ProviderRpcError { static readonly code = 5720; readonly code = 5720; readonly name = "Provider.DuplicateIdError"; constructor({ message, }?: { message?: string | undefined; }); } /** This bundle id is unknown / has not been submitted. */ export declare class UnknownBundleIdError extends ProviderRpcError { static readonly code = 5730; readonly code = 5730; readonly name = "Provider.UnknownBundleIdError"; constructor({ message, }?: { message?: string | undefined; }); } /** The call bundle is too large for the Wallet to process. */ export declare class BundleTooLargeError extends ProviderRpcError { static readonly code = 5740; readonly code = 5740; readonly name = "Provider.BundleTooLargeError"; constructor({ message, }?: { message?: string | undefined; }); } /** The Wallet can support atomicity after an upgrade, but the user rejected the upgrade. */ export declare class AtomicReadyWalletRejectedUpgradeError extends ProviderRpcError { static readonly code = 5750; readonly code = 5750; readonly name = "Provider.AtomicReadyWalletRejectedUpgradeError"; constructor({ message, }?: { message?: string | undefined; }); } /** The wallet does not support atomic execution but the request requires it. */ export declare class AtomicityNotSupportedError extends ProviderRpcError { static readonly code = 5760; readonly code = 5760; readonly name = "Provider.AtomicityNotSupportedError"; constructor({ message, }?: { message?: string | undefined; }); } /** * Creates an EIP-1193 flavored event emitter to be injected onto a Provider. * * @example * ```ts twoslash * // @noErrors * import { Provider, RpcRequest, RpcResponse } from 'ox' // [!code focus] * * // 1. Instantiate a Provider Emitter. // [!code focus] * const emitter = Provider.createEmitter() // [!code focus] * * const store = RpcRequest.createStore() * * const provider = Provider.from({ * // 2. Pass the Emitter to the Provider. // [!code focus] * ...emitter, // [!code focus] * async request(args) { * return await fetch('https://1.rpc.thirdweb.com', { * body: JSON.stringify(store.prepare(args)), * method: 'POST', * headers: { * 'Content-Type': 'application/json' * } * }) * .then((res) => res.json()) * .then(RpcResponse.parse) * } * }) * * // 3. Emit Provider Events. // [!code focus] * emitter.emit('accountsChanged', ['0x...']) // [!code focus] * ``` * * @returns An event emitter. */ export declare function createEmitter<eventMap extends Record<string, unknown> = Record<string, unknown>>(): Emitter<eventMap>; export declare namespace createEmitter { type ErrorType = Errors.GlobalErrorType; } /** * Instantiates an [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193) {@link ox#Provider.Provider} * from an arbitrary [EIP-1193 Provider](https://eips.ethereum.org/EIPS/eip-1193) interface. * * @example * ### Instantiating with RPC Transport * * Ox's {@link ox#RpcTransport} is EIP-1193 compliant, and can be used to instantiate an EIP-1193 Provider. This means you can use any HTTP RPC endpoint as an EIP-1193 Provider. * * ```ts twoslash * import { Provider, RpcTransport } from 'ox' * * const transport = RpcTransport.fromHttp( * 'https://1.rpc.thirdweb.com' * ) * const provider = Provider.from(transport) * ``` * * @example * ### Instantiating with External Providers * * The example below demonstrates how we can instantiate a typed EIP-1193 Provider from an * external EIP-1193 Provider like `window.ethereum`. * * ```ts twoslash * import 'ox/window' * import { Provider } from 'ox' * * const provider = Provider.from(window.ethereum) * * const blockNumber = await provider.request({ * method: 'eth_blockNumber' * }) * ``` * * :::tip * * There are also libraries that distribute EIP-1193 Provider objects that you can use with `Provider.from`: * * - [`@walletconnect/ethereum-provider`](https://www.npmjs.com/package/\@walletconnect/ethereum-provider) * * - [`@coinbase/wallet-sdk`](https://www.npmjs.com/package/\@coinbase/wallet-sdk) * * - [`@metamask/detect-provider`](https://www.npmjs.com/package/\@metamask/detect-provider) * * - [`@safe-global/safe-apps-provider`](https://github.com/safe-global/safe-apps-sdk/tree/main/packages/safe-apps-provider) * * - [`mipd`](https://github.com/wevm/mipd): EIP-6963 Multi Injected Providers * * ::: * * @example * ### Instantiating a Custom Provider * * The example below demonstrates how we can instantiate a typed EIP-1193 Provider from a * HTTP `fetch` JSON-RPC request. You can use this pattern to integrate with any asynchronous JSON-RPC * transport, including WebSockets and IPC. * * ```ts twoslash * // @noErrors * import { Provider, RpcRequest, RpcResponse } from 'ox' * * const store = RpcRequest.createStore() * * const provider = Provider.from({ * async request(args) { * return await fetch('https://1.rpc.thirdweb.com', { * body: JSON.stringify(store.prepare(args)), * method: 'POST', * headers: { * 'Content-Type': 'application/json' * } * }) * .then((res) => res.json()) * .then(RpcResponse.parse) * } * }) * * const blockNumber = await provider.request({ * method: 'eth_blockNumber' * }) * ``` * * @example * ### Type-safe Custom Schemas * * It is possible to define your own type-safe schema by using the {@link ox#RpcSchema.(from:function)} type. * * ```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' }) * // ^| * ``` * * @example * ### Instantiating a Provider with Events * * The example below demonstrates how to instantiate a Provider with your own EIP-1193 flavored event emitter. * * This example is useful for Wallets that distribute an EIP-1193 Provider (e.g. webpage injection via `window.ethereum`). * * ```ts twoslash * // @noErrors * import { Provider, RpcRequest, RpcResponse } from 'ox' * * // 1. Instantiate a Provider Emitter. * const emitter = Provider.createEmitter() // [!code ++] * * const store = RpcRequest.createStore() * * const provider = Provider.from({ * // 2. Pass the Emitter to the Provider. * ...emitter, // [!code ++] * async request(args) { * return await fetch('https://1.rpc.thirdweb.com', { * body: JSON.stringify(store.prepare(args)), * method: 'POST', * headers: { * 'Content-Type': 'application/json' * } * }) * .then((res) => res.json()) * .then(RpcResponse.parse) * } * }) * * // 3. Emit Provider Events. * emitter.emit('accountsChanged', ['0x...']) // [!code ++] * ``` * * @param provider - The EIP-1193 provider to convert. * @returns An typed EIP-1193 Provider. */ export declare function from<options extends Options | undefined, provider extends from.Value<options> | undefined = undefined>(provider: provider | from.Value<options> | undefined, options?: options | Options): from.ReturnType<options, provider>; export declare namespace from { type Value<options extends Options | undefined = undefined> = Partial<Emitter<any>> & { request: (parameters: options extends { schema: infer schema extends RpcSchema.Schema; } ? RpcSchema.ToGeneric<schema>['Request'] : RpcSchema.Generic['Request']) => unknown; }; type ReturnType<options extends Options | undefined = Options | undefined, provider extends from.Value<options> | undefined = from.Value<options> | undefined> = Omit<provider, 'request'> & { request: RequestFn<options extends { schema: infer schema extends RpcSchema.Schema; } ? RpcSchema.ToGeneric<schema> : RpcSchema.Default>; }; type ErrorType = IsUndefinedError | Errors.GlobalErrorType; } /** * Parses an error into a Provider error instance. * * @example * ```ts twoslash * import { Provider } from 'ox' * * const error = Provider.parseError({ * code: 4200, * message: 'foo' * }) * * error * // ^? * ``` * * @param error - The error object to parse. * @returns An error instance. */ export declare function parseError<const error extends RpcResponse.ErrorObject | Error | unknown>(error: error | Error | RpcResponse.ErrorObject): parseError.ReturnType<error>; export declare namespace parseError { type ReturnType<errorObject extends RpcResponse.ErrorObject | unknown, error = errorObject extends RpcResponse.ErrorObject ? (errorObject['code'] extends DisconnectedError['code'] ? DisconnectedError : never) | (IsNarrowable<errorObject['code'], number> extends false ? DisconnectedError : never) | (errorObject['code'] extends ChainDisconnectedError['code'] ? ChainDisconnectedError : never) | (IsNarrowable<errorObject['code'], number> extends false ? ChainDisconnectedError : never) | (errorObject['code'] extends UserRejectedRequestError['code'] ? UserRejectedRequestError : never) | (IsNarrowable<errorObject['code'], number> extends false ? UserRejectedRequestError : never) | (errorObject['code'] extends UnauthorizedError['code'] ? UnauthorizedError : never) | (IsNarrowable<errorObject['code'], number> extends false ? UnauthorizedError : never) | (errorObject['code'] extends UnsupportedMethodError['code'] ? UnsupportedMethodError : never) | (IsNarrowable<errorObject['code'], number> extends false ? UnsupportedMethodError : never) | (errorObject['code'] extends SwitchChainError['code'] ? SwitchChainError : never) | (IsNarrowable<errorObject['code'], number> extends false ? SwitchChainError : never) | (errorObject['code'] extends AtomicReadyWalletRejectedUpgradeError['code'] ? AtomicReadyWalletRejectedUpgradeError : never) | (IsNarrowable<errorObject['code'], number> extends false ? AtomicReadyWalletRejectedUpgradeError : never) | (errorObject['code'] extends AtomicityNotSupportedError['code'] ? AtomicityNotSupportedError : never) | (IsNarrowable<errorObject['code'], number> extends false ? AtomicityNotSupportedError : never) | (errorObject['code'] extends BundleTooLargeError['code'] ? BundleTooLargeError : never) | (IsNarrowable<errorObject['code'], number> extends false ? BundleTooLargeError : never) | (errorObject['code'] extends UnknownBundleIdError['code'] ? UnknownBundleIdError : never) | (IsNarrowable<errorObject['code'], number> extends false ? UnknownBundleIdError : never) | (errorObject['code'] extends DuplicateIdError['code'] ? DuplicateIdError : never) | (IsNarrowable<errorObject['code'], number> extends false ? DuplicateIdError : never) | (errorObject['code'] extends UnsupportedChainIdError['code'] ? UnsupportedChainIdError : never) | (IsNarrowable<errorObject['code'], number> extends false ? UnsupportedChainIdError : never) | (errorObject['code'] extends UnsupportedNonOptionalCapabilityError['code'] ? UnsupportedNonOptionalCapabilityError : never) | (IsNarrowable<errorObject['code'], number> extends false ? UnsupportedNonOptionalCapabilityError : never) : RpcResponse.parseError.ReturnType<RpcResponse.ErrorObject>> = IsNever<error> extends true ? RpcResponse.parseError.ReturnType<errorObject> : error; } /** Thrown when the provider is undefined. */ export declare class IsUndefinedError extends Errors.BaseError { readonly name = "Provider.IsUndefinedError"; constructor(); } //# sourceMappingURL=Provider.d.ts.map