diff --git a/src.ts/providers/abstract-provider.ts b/src.ts/providers/abstract-provider.ts index 2a6089761..f764fe551 100644 --- a/src.ts/providers/abstract-provider.ts +++ b/src.ts/providers/abstract-provider.ts @@ -384,8 +384,8 @@ export class AbstractProvider implements Provider { return (this.#plugins.get(name)) || null; } - set disableCcipRead(value: boolean) { this.#disableCcipRead = !!value; } get disableCcipRead(): boolean { return this.#disableCcipRead; } + set disableCcipRead(value: boolean) { this.#disableCcipRead = !!value; } // Shares multiple identical requests made during the same 250ms async #perform(req: PerformActionRequest): Promise { @@ -467,7 +467,7 @@ export class AbstractProvider implements Provider { } _wrapBlockWithTransactions(value: BlockParams, network: Network): Block { - return new Block(formatBlock(value), this); + return new Block(formatBlockWithTransactions(value), this); } _wrapLog(value: LogParams, network: Network): Log { @@ -1034,7 +1034,8 @@ export class AbstractProvider implements Provider { this.#timers.delete(timerId); } - _setTimeout(_func: () => void, timeout: number = 0): number { + _setTimeout(_func: () => void, timeout?: number): number { + if (timeout == null) { timeout = 0; } const timerId = this.#nextTimer++; const func = () => { this.#timers.delete(timerId); @@ -1330,7 +1331,7 @@ function bytesPad(value: Uint8Array): Uint8Array { return result; } -const empty = new Uint8Array([ ]); +const empty: Uint8Array = new Uint8Array([ ]); // ABI Encodes a series of (bytes, bytes, ...) function encodeBytes(datas: Array): string { diff --git a/src.ts/providers/community.ts b/src.ts/providers/community.ts index dddd1a21a..4a1da4df0 100644 --- a/src.ts/providers/community.ts +++ b/src.ts/providers/community.ts @@ -5,7 +5,7 @@ export interface CommunityResourcable { // Show the throttle message only once const shown: Set = new Set(); -export function showThrottleMessage(service: string) { +export function showThrottleMessage(service: string): void { if (shown.has(service)) { return; } shown.add(service); diff --git a/src.ts/providers/ens-resolver.ts b/src.ts/providers/ens-resolver.ts index de7df6bbe..667f8f527 100644 --- a/src.ts/providers/ens-resolver.ts +++ b/src.ts/providers/ens-resolver.ts @@ -190,7 +190,8 @@ export class EnsResolver { return await this.#supports2544; } - async _fetch(selector: string, parameters: BytesLike = "0x"): Promise { + async _fetch(selector: string, parameters?: BytesLike): Promise { + if (parameters == null) { parameters = "0x"; } // e.g. keccak256("addr(bytes32,uint256)") const addrData = concat([ selector, namehash(this.name), parameters ]); @@ -226,7 +227,8 @@ export class EnsResolver { return null; } - async getAddress(coinType: number = 60): Promise { + async getAddress(coinType?: number): Promise { + if (coinType == null) { coinType = 60; } if (coinType === 60) { try { // keccak256("addr(bytes32)") diff --git a/src.ts/providers/format.ts b/src.ts/providers/format.ts index 896b5a5f1..5fedc92b0 100644 --- a/src.ts/providers/format.ts +++ b/src.ts/providers/format.ts @@ -1,4 +1,6 @@ - +/** + * @_ignore + */ import { getAddress, getCreateAddress } from "../address/index.js"; import { Signature } from "../crypto/index.js" import { accessListify } from "../transaction/index.js"; @@ -7,6 +9,11 @@ import { assert, assertArgument } from "../utils/index.js"; +import type { + BlockParams, LogParams, + TransactionReceiptParams, TransactionResponseParams, + TransactionResponse +} from "./provider.js"; const BN_0 = BigInt(0); @@ -83,7 +90,7 @@ export function formatUint256(value: any): string { return zeroPadValue(value, 32); } -export const formatLog = object({ +const _formatLog = object({ address: getAddress, blockHash: formatHash, blockNumber: getNumber, @@ -97,7 +104,11 @@ export const formatLog = object({ index: [ "logIndex" ] }); -function _formatBlock(txFunc: FormatFunc): FormatFunc { +export function formatLog(value: any): LogParams { + return _formatLog(value); +} + +function _formatBlockWith(txFunc: FormatFunc): FormatFunc { return object({ hash: allowNull(formatHash), parentHash: formatHash, @@ -119,11 +130,19 @@ function _formatBlock(txFunc: FormatFunc): FormatFunc { }); } -export const formatBlock = _formatBlock(formatHash); +const _formatBlock = _formatBlockWith(formatHash); -export const formatBlockWithTransactions = _formatBlock(formatTransactionResponse); +export function formatBlock(value: any): BlockParams { + return _formatBlock(value); +} -export const formatReceiptLog = object({ +const _formatBlockWithTransactions = _formatBlockWith(formatTransactionResponse); + +export function formatBlockWithTransactions(value: any): BlockParams { + return _formatBlockWithTransactions(value); +} + +const _formatReceiptLog = object({ transactionIndex: getNumber, blockNumber: getNumber, transactionHash: formatHash, @@ -136,7 +155,11 @@ export const formatReceiptLog = object({ index: [ "logIndex" ] }); -export const formatTransactionReceipt = object({ +export function formatReceiptLog(value: any): LogParams { + return _formatReceiptLog(value); +} + +const _formatTransactionReceipt = object({ to: allowNull(getAddress, null), from: allowNull(getAddress, null), contractAddress: allowNull(getAddress, null), @@ -160,7 +183,11 @@ export const formatTransactionReceipt = object({ index: [ "transactionIndex" ], }); -export function formatTransactionResponse(value: any) { +export function formatTransactionReceipt(value: any): TransactionReceiptParams { + return _formatTransactionReceipt(value); +} + +export function formatTransactionResponse(value: any): TransactionResponseParams { // Some clients (TestRPC) do strange things like return 0x0 for the // 0 address; correct this to be a real address diff --git a/src.ts/providers/index.ts b/src.ts/providers/index.ts index 6e25db4bf..74712936e 100644 --- a/src.ts/providers/index.ts +++ b/src.ts/providers/index.ts @@ -1,8 +1,11 @@ +/** + * About providers. + * + * @_section: api/providers:Providers [providers] + */ -///// - export { AbstractProvider, UnmanagedSubscriber } from "./abstract-provider.js"; @@ -49,13 +52,14 @@ export { JsonRpcApiProvider, JsonRpcProvider, JsonRpcSigner } from "./provider-j export { BrowserProvider } from "./provider-browser.js"; -export { AlchemyProvider } from "./provider-alchemy.js"; -export { AnkrProvider } from "./provider-ankr.js"; -export { CloudflareProvider } from "./provider-cloudflare.js"; -export { BaseEtherscanProvider, EtherscanPlugin } from "./provider-etherscan-base.js"; -export { EtherscanProvider } from "./provider-etherscan.js"; -export { InfuraProvider } from "./provider-infura.js"; -//export { PocketProvider } from "./provider-pocket.js"; +export { + AlchemyProvider, + AnkrProvider, + CloudflareProvider, + BaseEtherscanProvider, EtherscanPlugin, EtherscanProvider, + InfuraProvider +// PocketProvider +} from "./thirdparty.js"; import { IpcSocketProvider } from "./provider-ipcsocket.js"; /*-browser*/ export { IpcSocketProvider }; @@ -88,8 +92,10 @@ export type { GasCostParameters } from "./plugins-network.js"; export type { BlockTag, + BlockParams, LogParams, TransactionReceiptParams, TransactionResponseParams, TransactionRequest, PreparedTransactionRequest, - EventFilter, Filter, FilterByBlockHash, OrphanFilter, ProviderEvent, TopicFilter, + EventFilter, Filter, FilterByBlockHash, OrphanFilter, ProviderEvent, + TopicFilter, Provider, } from "./provider.js"; diff --git a/src.ts/providers/network.ts b/src.ts/providers/network.ts index 1ec9486e4..93d670403 100644 --- a/src.ts/providers/network.ts +++ b/src.ts/providers/network.ts @@ -1,7 +1,11 @@ +/** + * About networks + * + * @_subsection: api/providers:Networks + */ + import { accessListify } from "../transaction/index.js"; -import { - getStore, getBigInt, setStore, assertArgument -} from "../utils/index.js"; +import { getBigInt, assertArgument } from "../utils/index.js"; import { EnsPlugin, GasCostPlugin } from "./plugins-network.js"; //import { EtherscanPlugin } from "./provider-etherscan-base.js"; @@ -88,43 +92,41 @@ const Networks: Map Network> = new Map(); // @TODO: Add a _ethersNetworkObj variable to better detect network ovjects export class Network { - #props: { - name: string, - chainId: bigint, + #name: string; + #chainId: bigint; - plugins: Map - }; + #plugins: Map; - constructor(name: string, _chainId: BigNumberish) { - const chainId = getBigInt(_chainId); - const plugins = new Map(); - this.#props = { name, chainId, plugins }; + constructor(name: string, chainId: BigNumberish) { + this.#name = name; + this.#chainId = getBigInt(chainId); + this.#plugins = new Map(); } toJSON(): any { return { name: this.name, chainId: this.chainId }; } - get name(): string { return getStore(this.#props, "name"); } - set name(value: string) { setStore(this.#props, "name", value); } + get name(): string { return this.#name; } + set name(value: string) { this.#name = value; } - get chainId(): bigint { return getStore(this.#props, "chainId"); } - set chainId(value: BigNumberish) { setStore(this.#props, "chainId", getBigInt(value, "chainId")); } + get chainId(): bigint { return this.#chainId; } + set chainId(value: BigNumberish) { this.#chainId = getBigInt(value, "chainId"); } get plugins(): Array { - return Array.from(this.#props.plugins.values()); + return Array.from(this.#plugins.values()); } attachPlugin(plugin: NetworkPlugin): this { - if (this.#props.plugins.get(plugin.name)) { + if (this.#plugins.get(plugin.name)) { throw new Error(`cannot replace existing plugin: ${ plugin.name } `); } - this.#props.plugins.set(plugin.name, plugin.clone()); + this.#plugins.set(plugin.name, plugin.clone()); return this; } getPlugin(name: string): null | T { - return (this.#props.plugins.get(name)) || null; + return (this.#plugins.get(name)) || null; } // Gets a list of Plugins which match basename, ignoring any fragment @@ -139,16 +141,7 @@ export class Network { }); return clone; } -/* - freeze(): Frozen { - Object.freeze(this.#props); - return this; - } - isFrozen(): boolean { - return Object.isFrozen(this.#props); - } -*/ computeIntrinsicGas(tx: TransactionLike): number { const costs = this.getPlugin("org.ethers.gas-cost") || (new GasCostPlugin()); diff --git a/src.ts/providers/plugins-network.ts b/src.ts/providers/plugins-network.ts index 5d13c8012..5bcb52bbc 100644 --- a/src.ts/providers/plugins-network.ts +++ b/src.ts/providers/plugins-network.ts @@ -45,7 +45,8 @@ export class GasCostPlugin extends NetworkPlugin implements GasCostParameters { readonly txAccessListStorageKey!: number; readonly txAccessListAddress!: number; - constructor(effectiveBlock: number = 0, costs?: GasCostParameters) { + constructor(effectiveBlock?: number, costs?: GasCostParameters) { + if (effectiveBlock == null) { effectiveBlock = 0; } super(`org.ethers.network-plugins.gas-cost#${ (effectiveBlock || 0) }`); const props: Record = { effectiveBlock }; diff --git a/src.ts/providers/provider-alchemy.ts b/src.ts/providers/provider-alchemy.ts index f50dce7f7..fc5f5ad4a 100644 --- a/src.ts/providers/provider-alchemy.ts +++ b/src.ts/providers/provider-alchemy.ts @@ -39,10 +39,14 @@ function getHost(name: string): string { assertArgument(false, "unsupported network", "network", name); } +/** + * The AlchemyProvider is backed by the [[alchemyapu]] API. + */ export class AlchemyProvider extends JsonRpcProvider implements CommunityResourcable { readonly apiKey!: string; - constructor(_network: Networkish = "mainnet", apiKey?: null | string) { + constructor(_network?: Networkish, apiKey?: null | string) { + if (_network == null) { _network = "mainnet"; } const network = Network.from(_network); if (apiKey == null) { apiKey = defaultApiKey; } diff --git a/src.ts/providers/provider-ankr.ts b/src.ts/providers/provider-ankr.ts index 0456096e5..252bf623b 100644 --- a/src.ts/providers/provider-ankr.ts +++ b/src.ts/providers/provider-ankr.ts @@ -17,10 +17,6 @@ function getHost(name: string): string { switch (name) { case "mainnet": return "rpc.ankr.com/eth"; - case "ropsten": - return "rpc.ankr.com/eth_ropsten"; - case "rinkeby": - return "rpc.ankr.com/eth_rinkeby"; case "goerli": return "rpc.ankr.com/eth_goerli"; case "matic": @@ -36,7 +32,8 @@ function getHost(name: string): string { export class AnkrProvider extends JsonRpcProvider implements CommunityResourcable { readonly apiKey!: string; - constructor(_network: Networkish = "mainnet", apiKey?: null | string) { + constructor(_network?: Networkish, apiKey?: null | string) { + if (_network == null) { _network = "mainnet"; } const network = Network.from(_network); if (apiKey == null) { apiKey = defaultApiKey; } diff --git a/src.ts/providers/provider-browser.ts b/src.ts/providers/provider-browser.ts index 856147403..f474df3d8 100644 --- a/src.ts/providers/provider-browser.ts +++ b/src.ts/providers/provider-browser.ts @@ -13,7 +13,7 @@ export interface Eip1193Provider { request(request: { method: string, params?: Array | Record }): Promise; }; -export type DebugEventJsonRpcApiProvider = { +export type DebugEventBrowserProvider = { action: "sendEip1193Payload", payload: { method: string, params: Array } } | { diff --git a/src.ts/providers/provider-cloudflare.ts b/src.ts/providers/provider-cloudflare.ts index 2f814a04b..0d760a7f8 100644 --- a/src.ts/providers/provider-cloudflare.ts +++ b/src.ts/providers/provider-cloudflare.ts @@ -7,7 +7,8 @@ import type { Networkish } from "./network.js"; export class CloudflareProvider extends JsonRpcProvider { - constructor(_network: Networkish = "mainnet") { + constructor(_network?: Networkish) { + if (_network == null) { _network = "mainnet"; } const network = Network.from(_network); assertArgument(network.name === "mainnet", "unsupported network", "network", _network); super("https:/\/cloudflare-eth.com/", network, { staticNetwork: network }); diff --git a/src.ts/providers/provider-etherscan-base.ts b/src.ts/providers/provider-etherscan-base.ts index 41494d1ff..42f09500f 100644 --- a/src.ts/providers/provider-etherscan-base.ts +++ b/src.ts/providers/provider-etherscan-base.ts @@ -1,4 +1,4 @@ -import { getBuiltinCallException } from "../abi/index.js"; +import { AbiCoder } from "../abi/index.js"; import { accessListify } from "../transaction/index.js"; import { defineProperties, @@ -257,7 +257,7 @@ export class BaseEtherscanProvider extends AbstractProvider { _checkError(req: PerformActionRequest, error: Error, transaction: any): never { if (req.method === "call" || req.method === "estimateGas") { if (error.message.match(/execution reverted/i)) { - const e = getBuiltinCallException(req.method, req.transaction, (error).data); + const e = AbiCoder.getBuiltinCallException(req.method, req.transaction, (error).data); e.info = { request: req, error } throw e; } diff --git a/src.ts/providers/provider-infura.ts b/src.ts/providers/provider-infura.ts index f82543382..f6772f68b 100644 --- a/src.ts/providers/provider-infura.ts +++ b/src.ts/providers/provider-infura.ts @@ -44,8 +44,8 @@ export class InfuraWebSocketProvider extends WebSocketProvider implements Commun readonly projectId!: string; readonly projectSecret!: null | string; - constructor(network?: Networkish, apiKey?: any) { - const provider = new InfuraProvider(network, apiKey); + constructor(network?: Networkish, projectId?: string) { + const provider = new InfuraProvider(network, projectId); const req = provider._getConnection(); assert(!req.credentials, "INFURA WebSocket project secrets unsupported", @@ -69,7 +69,8 @@ export class InfuraProvider extends JsonRpcProvider implements CommunityResourca readonly projectId!: string; readonly projectSecret!: null | string; - constructor(_network: Networkish = "mainnet", projectId?: null | string, projectSecret?: null | string) { + constructor(_network?: Networkish, projectId?: null | string, projectSecret?: null | string) { + if (_network == null) { _network = "mainnet"; } const network = Network.from(_network); if (projectId == null) { projectId = defaultProjectId; } if (projectSecret == null) { projectSecret = null; } @@ -91,8 +92,8 @@ export class InfuraProvider extends JsonRpcProvider implements CommunityResourca return (this.projectId === defaultProjectId); } - static getWebSocketProvider(network?: Networkish, apiKey?: any): InfuraWebSocketProvider { - return new InfuraWebSocketProvider(network, apiKey); + static getWebSocketProvider(network?: Networkish, projectId?: string): InfuraWebSocketProvider { + return new InfuraWebSocketProvider(network, projectId); } static getRequest(network: Network, projectId?: null | string, projectSecret?: null | string): FetchRequest { @@ -112,5 +113,4 @@ export class InfuraProvider extends JsonRpcProvider implements CommunityResourca return request; } - } diff --git a/src.ts/providers/provider-ipcsocket.ts b/src.ts/providers/provider-ipcsocket.ts index 0a825a613..2e5abd1e9 100644 --- a/src.ts/providers/provider-ipcsocket.ts +++ b/src.ts/providers/provider-ipcsocket.ts @@ -66,40 +66,3 @@ export class IpcSocketProvider extends SocketProvider { this.socket.write(message); } } -/* - -import { defineProperties } from "@ethersproject/properties"; - -import { SocketLike, SocketProvider } from "./provider-socket.js"; - -import type { Socket } from "net"; - -export class SocketWrapper implements SocketLike { - #socket: Socket; - - constructor(path: string) { - this.#socket = connect(path); - } - - send(data: string): void { - this.#socket.write(data, () => { }); - } - - addEventListener(event: string, listener: (data: string) => void): void { - //this.#socket.on(event, (value: ) => { - //}); - } - - close(): void { - } -} - -export class IpcProvider extends SocketProvider { - readonly path!: string; - - constructor(path: string) { - super(new SocketWrapper(path)); - defineProperties(this, { path }); - } -} -*/ diff --git a/src.ts/providers/provider-jsonrpc.ts b/src.ts/providers/provider-jsonrpc.ts index 25e39f234..320c7b5fd 100644 --- a/src.ts/providers/provider-jsonrpc.ts +++ b/src.ts/providers/provider-jsonrpc.ts @@ -3,7 +3,7 @@ // https://playground.open-rpc.org/?schemaUrl=https://raw.githubusercontent.com/ethereum/eth1.0-apis/assembled-spec/openrpc.json&uiSchema%5BappBar%5D%5Bui:splitView%5D=true&uiSchema%5BappBar%5D%5Bui:input%5D=false&uiSchema%5BappBar%5D%5Bui:examplesDropdown%5D=false -import { getBuiltinCallException } from "../abi/index.js"; +import { AbiCoder } from "../abi/index.js"; import { getAddress, resolveAddress } from "../address/index.js"; import { TypedDataEncoder } from "../hash/index.js"; import { accessListify } from "../transaction/index.js"; @@ -528,7 +528,8 @@ export class JsonRpcApiProvider extends AbstractProvider { return super._perform(req); } - /** Sub-classes may override this; it detects the *actual* network that + /** + * Sub-classes may override this; it detects the *actual* network that * we are **currently** connected to. * * Keep in mind that [[send]] may only be used once [[ready]], otherwise the @@ -783,7 +784,7 @@ export class JsonRpcApiProvider extends AbstractProvider { if (method === "eth_call" || method === "eth_estimateGas") { const result = spelunkData(error); - const e = getBuiltinCallException( + const e = AbiCoder.getBuiltinCallException( (method === "eth_call") ? "call": "estimateGas", ((payload).params[0]), (result ? result.data: null) @@ -961,7 +962,8 @@ export class JsonRpcApiProvider extends AbstractProvider { * * Throws if the account doesn't exist. */ - async getSigner(address: number | string = 0): Promise { + async getSigner(address?: number | string): Promise { + if (address == null) { address = 0; } const accountsPromise = this.send("eth_accounts", [ ]); diff --git a/src.ts/providers/signer.ts b/src.ts/providers/signer.ts index 1ded72afd..7444434be 100644 --- a/src.ts/providers/signer.ts +++ b/src.ts/providers/signer.ts @@ -73,7 +73,6 @@ export interface Signer extends Addressable, ContractRunner, NameResolver { * node to populate the nonce and fee data. * * @param tx - The call to prepare - * @returns The fully prepared {@link TransactionLike} */ populateTransaction(tx: TransactionRequest): Promise>; diff --git a/src.ts/providers/thirdparty.ts b/src.ts/providers/thirdparty.ts new file mode 100644 index 000000000..ad500715f --- /dev/null +++ b/src.ts/providers/thirdparty.ts @@ -0,0 +1,15 @@ +/** + * About thirdparty... + * + * @_section: api/providers/third-party:Third Party Providers [third-party] + */ + +/** + * + */ +export { AlchemyProvider } from "./provider-alchemy.js"; +export { AnkrProvider } from "./provider-ankr.js"; +export { CloudflareProvider } from "./provider-cloudflare.js"; +export { BaseEtherscanProvider, EtherscanPlugin } from "./provider-etherscan-base.js"; +export { EtherscanProvider } from "./provider-etherscan.js"; +export { InfuraProvider } from "./provider-infura.js";