UNPKG

ox

Version:

Ethereum Standard Library

257 lines 8.98 kB
import { EventEmitter } from 'eventemitter3'; import * as Errors from './Errors.js'; import * as RpcResponse from './RpcResponse.js'; export class ProviderRpcError extends Error { name = 'ProviderRpcError'; code; details; constructor(code, message) { super(message); this.code = code; this.details = message; } } /** The user rejected the request. */ export class UserRejectedRequestError extends ProviderRpcError { static code = 4001; code = 4001; name = 'Provider.UserRejectedRequestError'; constructor({ message = 'The user rejected the request.', } = {}) { super(4001, message); } } /** The requested method and/or account has not been authorized by the user. */ export class UnauthorizedError extends ProviderRpcError { static code = 4100; code = 4100; name = 'Provider.UnauthorizedError'; constructor({ message = 'The requested method and/or account has not been authorized by the user.', } = {}) { super(4100, message); } } /** The provider does not support the requested method. */ export class UnsupportedMethodError extends ProviderRpcError { static code = 4200; code = 4200; name = 'Provider.UnsupportedMethodError'; constructor({ message = 'The provider does not support the requested method.', } = {}) { super(4200, message); } } /** The provider is disconnected from all chains. */ export class DisconnectedError extends ProviderRpcError { static code = 4900; code = 4900; name = 'Provider.DisconnectedError'; constructor({ message = 'The provider is disconnected from all chains.', } = {}) { super(4900, message); } } /** The provider is not connected to the requested chain. */ export class ChainDisconnectedError extends ProviderRpcError { static code = 4901; code = 4901; name = 'Provider.ChainDisconnectedError'; constructor({ message = 'The provider is not connected to the requested chain.', } = {}) { super(4901, message); } } /** An error occurred when attempting to switch chain. */ export class SwitchChainError extends ProviderRpcError { static code = 4902; code = 4902; name = 'Provider.SwitchChainError'; constructor({ message = 'An error occurred when attempting to switch chain.', } = {}) { super(4902, message); } } /** This Wallet does not support a capability that was not marked as optional. */ export class UnsupportedNonOptionalCapabilityError extends ProviderRpcError { static code = 5700; code = 5700; name = 'Provider.UnsupportedNonOptionalCapabilityError'; constructor({ message = 'This Wallet does not support a capability that was not marked as optional.', } = {}) { super(5700, message); } } /** This Wallet does not support the requested chain ID. */ export class UnsupportedChainIdError extends ProviderRpcError { static code = 5710; code = 5710; name = 'Provider.UnsupportedChainIdError'; constructor({ message = 'This Wallet does not support the requested chain ID.', } = {}) { super(5710, message); } } /** There is already a bundle submitted with this ID. */ export class DuplicateIdError extends ProviderRpcError { static code = 5720; code = 5720; name = 'Provider.DuplicateIdError'; constructor({ message = 'There is already a bundle submitted with this ID.', } = {}) { super(5720, message); } } /** This bundle id is unknown / has not been submitted. */ export class UnknownBundleIdError extends ProviderRpcError { static code = 5730; code = 5730; name = 'Provider.UnknownBundleIdError'; constructor({ message = 'This bundle id is unknown / has not been submitted.', } = {}) { super(5730, message); } } /** The call bundle is too large for the Wallet to process. */ export class BundleTooLargeError extends ProviderRpcError { static code = 5740; code = 5740; name = 'Provider.BundleTooLargeError'; constructor({ message = 'The call bundle is too large for the Wallet to process.', } = {}) { super(5740, message); } } /** The Wallet can support atomicity after an upgrade, but the user rejected the upgrade. */ export class AtomicReadyWalletRejectedUpgradeError extends ProviderRpcError { static code = 5750; code = 5750; name = 'Provider.AtomicReadyWalletRejectedUpgradeError'; constructor({ message = 'The Wallet can support atomicity after an upgrade, but the user rejected the upgrade.', } = {}) { super(5750, message); } } /** The wallet does not support atomic execution but the request requires it. */ export class AtomicityNotSupportedError extends ProviderRpcError { static code = 5760; code = 5760; name = 'Provider.AtomicityNotSupportedError'; constructor({ message = 'The wallet does not support atomic execution but the request requires it.', } = {}) { super(5760, message); } } /** * 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 function createEmitter() { const emitter = new EventEmitter(); return { get eventNames() { return emitter.eventNames.bind(emitter); }, get listenerCount() { return emitter.listenerCount.bind(emitter); }, get listeners() { return emitter.listeners.bind(emitter); }, addListener: emitter.addListener.bind(emitter), emit: emitter.emit.bind(emitter), off: emitter.off.bind(emitter), on: emitter.on.bind(emitter), once: emitter.once.bind(emitter), removeAllListeners: emitter.removeAllListeners.bind(emitter), removeListener: emitter.removeListener.bind(emitter), }; } // eslint-disable-next-line jsdoc-js/require-jsdoc export function from(provider, _options = {}) { if (!provider) throw new IsUndefinedError(); const wrapped = Object.create(Object.getPrototypeOf(provider)); Object.defineProperties(wrapped, Object.getOwnPropertyDescriptors(provider)); wrapped.request = async (args) => { try { return await provider.request(args); } catch (error) { throw parseError(error); } }; return wrapped; } /** * 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 function parseError(error) { const error_ = RpcResponse.parseError(error); if (error_ instanceof RpcResponse.InternalError) { if (!error_.data) return error_; const { code } = error_.data; const Constructor = providerErrorCodeMap[code]; if (Constructor) return new Constructor(error_); } return error_; } /** @internal */ const providerErrorCodeMap = { [DisconnectedError.code]: DisconnectedError, [ChainDisconnectedError.code]: ChainDisconnectedError, [UserRejectedRequestError.code]: UserRejectedRequestError, [UnauthorizedError.code]: UnauthorizedError, [UnsupportedMethodError.code]: UnsupportedMethodError, [SwitchChainError.code]: SwitchChainError, [AtomicReadyWalletRejectedUpgradeError.code]: AtomicReadyWalletRejectedUpgradeError, [AtomicityNotSupportedError.code]: AtomicityNotSupportedError, [BundleTooLargeError.code]: BundleTooLargeError, [UnknownBundleIdError.code]: UnknownBundleIdError, [DuplicateIdError.code]: DuplicateIdError, [UnsupportedChainIdError.code]: UnsupportedChainIdError, [UnsupportedNonOptionalCapabilityError.code]: UnsupportedNonOptionalCapabilityError, }; /** Thrown when the provider is undefined. */ export class IsUndefinedError extends Errors.BaseError { name = 'Provider.IsUndefinedError'; constructor() { super('`provider` is undefined.'); } } //# sourceMappingURL=Provider.js.map