ox
Version:
Ethereum Standard Library
257 lines • 8.98 kB
JavaScript
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