docs: added more jsdocs for providers

This commit is contained in:
Richard Moore 2022-11-30 13:44:47 -05:00
parent 421c5443b3
commit f5281a0342
22 changed files with 632 additions and 141 deletions

@ -1,3 +1,9 @@
/**
* About Subclassing the Provider...
*
* @_section: api/providers/abstract-provider: Subclassing Provider [abstract-provider]
*/
// @TODO
// Event coalescence
// When we register an event with an async value (e.g. address is a Signer
@ -36,9 +42,14 @@ import type { Listener } from "../utils/index.js";
import type { Networkish } from "./network.js";
//import type { MaxPriorityFeePlugin } from "./plugins-network.js";
import type {
BlockParams, BlockTag, EventFilter, Filter, FilterByBlockHash, LogParams, OrphanFilter,
BlockParams, LogParams, TransactionReceiptParams,
TransactionResponseParams
} from "./formatting.js";
import type {
BlockTag, EventFilter, Filter, FilterByBlockHash, OrphanFilter,
PreparedTransactionRequest, Provider, ProviderEvent,
TransactionReceiptParams, TransactionRequest, TransactionResponseParams
TransactionRequest
} from "./provider.js";

@ -1,3 +1,8 @@
/**
* About Abstract Signer and subclassing
*
* @_section: api/providers/abstract-signer: Subclassing Signer [abstract-signer]
*/
import { Transaction } from "../transaction/index.js";
import {
defineProperties, getBigInt, resolveProperties,

@ -1,4 +1,10 @@
/**
* There are many awesome community services that provide Ethereum
* nodes both for developers just starting out and for large-scale
* communities.
*
* @_section: api/providers/thirdparty: Community Providers [thirdparty]
*/
export interface CommunityResourcable {
isCommunityResource(): boolean;
}

@ -12,6 +12,9 @@ import {
import type {
BlockParams, LogParams,
TransactionReceiptParams, TransactionResponseParams,
} from "./formatting.js";
import type {
TransactionResponse
} from "./provider.js";

@ -0,0 +1,195 @@
/**
* About provider formatting?
*
* @_section: api/providers/formatting:Formatting [provider-formatting]
*/
import type { Signature } from "../crypto/index.js";
import type { AccessList, AccessListish } from "../transaction/index.js";
import type { BigNumberish } from "../utils/index.js";
import type { AddressLike } from "../address/index.js";
import type { BlockTag } from "./provider.js";
export interface TransactionRequest {
type?: null | number;
to?: null | AddressLike;
from?: null | AddressLike;
nonce?: null | number;
gasLimit?: null | BigNumberish;
gasPrice?: null | BigNumberish;
maxPriorityFeePerGas?: null | BigNumberish;
maxFeePerGas?: null | BigNumberish;
data?: null | string;
value?: null | BigNumberish;
chainId?: null | BigNumberish;
accessList?: null | AccessListish;
customData?: any;
// Only meaningful when used for call
blockTag?: BlockTag;
enableCcipRead?: boolean;
// Todo?
//gasMultiplier?: number;
};
export interface PreparedTransactionRequest {
type?: number;
to?: AddressLike;
from?: AddressLike;
nonce?: number;
gasLimit?: bigint;
gasPrice?: bigint;
maxPriorityFeePerGas?: bigint;
maxFeePerGas?: bigint;
data?: string;
value?: bigint;
chainId?: bigint;
accessList?: AccessList;
customData?: any;
blockTag?: BlockTag;
enableCcipRead?: boolean;
}
//////////////////////
// Block
export interface BlockParams<T extends string | TransactionResponseParams> {
hash?: null | string;
number: number;
timestamp: number;
parentHash: string;
nonce: string;
difficulty: bigint;
gasLimit: bigint;
gasUsed: bigint;
miner: string;
extraData: string;
baseFeePerGas: null | bigint;
transactions: ReadonlyArray<T>;
};
//////////////////////
// Log
export interface LogParams {
transactionHash: string;
blockHash: string;
blockNumber: number;
removed: boolean;
address: string;
data: string;
topics: ReadonlyArray<string>;
index: number;
transactionIndex: number;
}
//////////////////////
// Transaction Receipt
export interface TransactionReceiptParams {
to: null | string;
from: string;
contractAddress: null | string;
hash: string;
index: number;
blockHash: string;
blockNumber: number;
logsBloom: string;
logs: ReadonlyArray<LogParams>;
gasUsed: bigint;
cumulativeGasUsed: bigint;
gasPrice?: null | bigint;
effectiveGasPrice?: null | bigint;
type: number;
//byzantium: boolean;
status: null | number;
root: null | string;
}
/*
export interface LegacyTransactionReceipt {
byzantium: false;
status: null;
root: string;
}
export interface ByzantiumTransactionReceipt {
byzantium: true;
status: number;
root: null;
}
*/
//////////////////////
// Transaction Response
export interface TransactionResponseParams {
blockNumber: null | number;
blockHash: null | string;
hash: string;
index: number;
type: number;
to: null | string;
from: string;
nonce: number;
gasLimit: bigint;
gasPrice: bigint;
maxPriorityFeePerGas: null | bigint;
maxFeePerGas: null | bigint;
data: string;
value: bigint;
chainId: bigint;
signature: Signature;
accessList: null | AccessList;
};

@ -52,14 +52,12 @@ export { JsonRpcApiProvider, JsonRpcProvider, JsonRpcSigner } from "./provider-j
export { BrowserProvider } from "./provider-browser.js";
export {
AlchemyProvider,
AnkrProvider,
CloudflareProvider,
BaseEtherscanProvider, EtherscanPlugin, EtherscanProvider,
InfuraProvider
// PocketProvider
} from "./thirdparty.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, InfuraWebSocketProvider } from "./provider-infura.js";
import { IpcSocketProvider } from "./provider-ipcsocket.js"; /*-browser*/
export { IpcSocketProvider };
@ -90,9 +88,13 @@ export type { Networkish } from "./network.js";
export type { GasCostParameters } from "./plugins-network.js";
export type {
BlockParams, LogParams, TransactionReceiptParams,
TransactionResponseParams,
} from "./formatting.js";
export type {
BlockTag,
BlockParams, LogParams, TransactionReceiptParams, TransactionResponseParams,
TransactionRequest, PreparedTransactionRequest,
EventFilter, Filter, FilterByBlockHash, OrphanFilter, ProviderEvent,
TopicFilter,

@ -1,7 +1,7 @@
/**
* About networks
*
* @_subsection: api/providers:Networks
* @_subsection: api/providers:Networks [networks]
*/
import { accessListify } from "../transaction/index.js";

@ -2,7 +2,12 @@ import { defineProperties } from "../utils/properties.js";
import { assertArgument } from "../utils/index.js";
import type { FeeData, Provider } from "./provider.js";
import type { BlockParams, TransactionResponseParams } from "./formatting.js";
import type {
Block, FeeData, Provider, TransactionResponse
} from "./provider.js";
const EnsAddress = "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e";
@ -138,8 +143,6 @@ export class FeeDataNetworkPlugin extends NetworkPlugin {
}
}
import type { Block, BlockParams, TransactionResponse, TransactionResponseParams } from "./provider.js";
export class CustomBlockNetworkPlugin extends NetworkPlugin {
readonly #blockFunc: (provider: Provider, block: BlockParams<string>) => Block<string>;
readonly #blockWithTxsFunc: (provider: Provider, block: BlockParams<TransactionResponseParams>) => Block<TransactionResponse>;

@ -41,6 +41,8 @@ function getHost(name: string): string {
/**
* The AlchemyProvider is backed by the [[alchemyapu]] API.
*
* @_docloc: api/providers/thirdparty
*/
export class AlchemyProvider extends JsonRpcProvider implements CommunityResourcable {
readonly apiKey!: string;

@ -29,6 +29,11 @@ function getHost(name: string): string {
}
/**
* About Ankr...
*
* @_docloc: api/providers/thirdparty
*/
export class AnkrProvider extends JsonRpcProvider implements CommunityResourcable {
readonly apiKey!: string;

@ -5,7 +5,11 @@ import { JsonRpcProvider } from "./provider-jsonrpc.js";
import type { Networkish } from "./network.js";
/**
* Aboud Cloudflare...
*
* @_docloc: api/providers/thirdparty
*/
export class CloudflareProvider extends JsonRpcProvider {
constructor(_network?: Networkish) {
if (_network == null) { _network = "mainnet"; }

@ -20,6 +20,11 @@ import type { TransactionRequest } from "./provider.js";
const THROTTLE = 2000;
/**
* Aboud Etherscan Debug...
*
* @_docloc: api/providers/thirdparty:Etherscan
*/
export type DebugEventEtherscanProvider = {
action: "sendRequest",
id: number,
@ -37,6 +42,11 @@ export type DebugEventEtherscanProvider = {
const EtherscanPluginId = "org.ethers.plugins.Etherscan";
/**
* Aboud Cloudflare...
*
* @_docloc: api/providers/thirdparty:Etherscan
*/
export class EtherscanPlugin extends NetworkPlugin {
readonly baseUrl!: string;
readonly communityApiKey!: string;
@ -54,6 +64,11 @@ export class EtherscanPlugin extends NetworkPlugin {
let nextId = 1;
/**
* Aboud Etherscan...
*
* @_docloc: api/providers/thirdparty:Etherscan
*/
export class BaseEtherscanProvider extends AbstractProvider {
readonly network!: Network;
readonly apiKey!: string;

@ -1,3 +1,9 @@
/**
* Aboud Etherscan...
*
* @_subsection api/providers/thirdparty:Etherscan [etherscan]
*/
import { BaseEtherscanProvider } from "./provider-etherscan-base.js";
import { Contract } from "../contract/index.js";
@ -5,6 +11,9 @@ function isPromise<T = any>(value: any): value is Promise<T> {
return (value && typeof(value.then) === "function");
}
/**
* Aboud EtherscanProvider...
*/
export class EtherscanProvider extends BaseEtherscanProvider {
async getContract(_address: string): Promise<null | Contract> {
let address = this._getAddress(_address);

@ -1,3 +1,8 @@
/**
* About INFURA
*
* @_subsection: api/providers/thirdparty:INFURA [infura]
*/
import {
defineProperties, FetchRequest, assert, assertArgument
} from "../utils/index.js";
@ -40,6 +45,9 @@ function getHost(name: string): string {
assertArgument(false, "unsupported network", "network", name);
}
/**
* INFURA...
*/
export class InfuraWebSocketProvider extends WebSocketProvider implements CommunityResourcable {
readonly projectId!: string;
readonly projectSecret!: null | string;
@ -65,6 +73,9 @@ export class InfuraWebSocketProvider extends WebSocketProvider implements Commun
}
}
/**
* Aboud Cloudflare...
*/
export class InfuraProvider extends JsonRpcProvider implements CommunityResourcable {
readonly projectId!: string;
readonly projectSecret!: null | string;

@ -1,3 +1,9 @@
/**
* About JSON-RPC...
*
* @_section: api/providers/jsonrpc:JSON-RPC Provider [about-jsonrpcProvider]
*/
// @TODO:
// - Add the batching API
@ -98,6 +104,10 @@ export type JsonRpcError = {
}
};
/**
* When subscribing to the ``"debug"`` event, the [[Listener]] will
* receive this object as the first parameter.
*/
export type DebugEventJsonRpcApiProvider = {
action: "sendRpcPayload",
payload: JsonRpcPayload | Array<JsonRpcPayload>
@ -114,16 +124,13 @@ export type DebugEventJsonRpcApiProvider = {
* is targetted towards sub-classes, which often will not expose
* any of these options to their consumers.
*
* _property: options.polling? => boolean
* If true, the polling strategy is used immediately for events.
* Otherwise, an attempt to use filters is made and on failure
* polling is used for that and all future events. (default: ``false``)
* **``polling``** - use the polling strategy is used immediately
* for events; otherwise, attempt to use filters and fall back onto
* polling (default: ``false``)
*
* _property: options.staticNetwork => [[Network]]
* If this is set, then there are no requests made for the chainId.
* (default: ``null``)
* **``staticNetwork``** - do not request chain ID on requests to
* validate the underlying chain has not changed (default: ``null``)
*
* _warning:
* This should **ONLY** be used if it is **certain** that the network
* cannot change, such as when using INFURA (since the URL dictates the
* network). If the network is assumed static and it does change, this
@ -131,21 +138,15 @@ export type DebugEventJsonRpcApiProvider = {
* with MetaMask, since the used can select a new network from the
* drop-down at any time.
*
* _property: option.batchStallTime? => number
* The amount of time (in ms) to wait, allowing requests to be batched,
* before making the request. If ``0``, then batching will only occur
* within the same event loop. If the batchSize is ``1``, then this is
* ignored. (default: ``10``)
* **``batchStallTime``** - how long (ms) to aggregate requests into a
* single batch. ``0`` indicates batching will only encompass the current
* event loop. If ``batchMaxCount = 1``, this is ignored. (default: ``10``)
*
* _property: options.batchMaxSize? => number
* The target maximum size (in bytes) to allow a payload within a single
* batch. At least one request will be made per request, which may
* violate this constraint if it is set too small or a large request is
* present. (default: 1Mb)
* **``batchMaxSize``** - target maximum size (bytes) to allow per batch
* request (default: 1Mb)
*
* _property: options.bstchMaxCount? => number
* The maximum number of payloads to allow in a single batch. Set this to
* ``1`` to disable batching entirely. (default: ``100``)
* **``batchMaxCount``** - maximum number of requests to allow in a batch.
* If ``batchMaxCount = 1``, then batching is disabled. (default: ``100``)
*/
export type JsonRpcApiProviderOptions = {
polling?: boolean;
@ -348,7 +349,7 @@ type Payload = { payload: JsonRpcPayload, resolve: ResolveFunc, reject: RejectFu
* - a sub-class MUST override _send
* - a sub-class MUST call the `_start()` method once connected
*/
export class JsonRpcApiProvider extends AbstractProvider {
export abstract class JsonRpcApiProvider extends AbstractProvider {
#options: Required<JsonRpcApiProviderOptions>;
@ -487,11 +488,14 @@ export class JsonRpcApiProvider extends AbstractProvider {
*
* Sub-classes **MUST** override this.
*/
_send(payload: JsonRpcPayload | Array<JsonRpcPayload>): Promise<Array<JsonRpcResult | JsonRpcError>> {
abstract _send(payload: JsonRpcPayload | Array<JsonRpcPayload>): Promise<Array<JsonRpcResult | JsonRpcError>>;
/*
{
assert(false, "sub-classes must override _send", "UNSUPPORTED_OPERATION", {
operation: "jsonRpcApiProvider._send"
});
}
*/
/**
@ -991,7 +995,7 @@ export class JsonRpcApiProvider extends AbstractProvider {
}
}
export class JsonRpcApiPollingProvider extends JsonRpcApiProvider {
export abstract class JsonRpcApiPollingProvider extends JsonRpcApiProvider {
#pollingInterval: number;
constructor(network?: Networkish, options?: JsonRpcApiProviderOptions) {
super(network, options);

@ -1,12 +1,12 @@
/**
* SocketProvider
*
* Generic long-lived socket provider.
*
* Sub-classing notes
* - a sub-class MUST call the `_start()` method once connected
* - a sub-class MUST override the `_write(string)` method
* - a sub-class MUST call `_processMessage(string)` for each message
*
* @_subsection: api/providers/abstract-provider
*/
import { UnmanagedSubscriber } from "./abstract-provider.js";
@ -130,6 +130,10 @@ export class SocketEventSubscriber extends SocketSubscriber {
}
}
/**
* SocketProvider...
*
*/
export class SocketProvider extends JsonRpcApiProvider {
#callbacks: Map<number, { payload: JsonRpcPayload, resolve: (r: any) => void, reject: (e: Error) => void }>;

@ -18,6 +18,11 @@ const BN_0 = BigInt(0);
export type BlockTag = number | string;
import {
BlockParams, LogParams, TransactionReceiptParams,
TransactionResponseParams
} from "./formatting.js";
// -----------------------
function getValue<T>(value: undefined | null | T): null | T {
@ -31,11 +36,46 @@ function toJson(value: null | bigint): null | string {
}
// @TODO? <T extends FeeData = { }> implements Required<T>
/**
* A **FeeData** wraps all the fee-related values associated with
* the network.
*/
export class FeeData {
/**
* The gas price for legacy networks.
*/
readonly gasPrice!: null | bigint;
/**
* The maximum fee to pay per gas.
*
* The base fee per gas is defined by the network and based on
* congestion, increasing the cost during times of heavy load
* and lowering when less busy.
*
* The actual fee per gas will be the base fee for the block
* and the priority fee, up to the max fee per gas.
*
* This will be ``null`` on legacy networks (i.e. [pre-EIP-1559](link-eip-1559))
*/
readonly maxFeePerGas!: null | bigint;
/**
* The additional amout to pay per gas to encourage a validator
* to include the transaction.
*
* The purpose of this is to compensate the validator for the
* adjusted risk for including a given transaction.
*
* This will be ``null`` on legacy networks (i.e. [pre-EIP-1559](link-eip-1559))
*/
readonly maxPriorityFeePerGas!: null | bigint;
/**
* Creates a new FeeData for %%gasPrice%%, %%maxFeePerGas%% and
* %%maxPriorityFeePerGas%%.
*/
constructor(gasPrice?: null | bigint, maxFeePerGas?: null | bigint, maxPriorityFeePerGas?: null | bigint) {
defineProperties<FeeData>(this, {
gasPrice: getValue(gasPrice),
@ -44,6 +84,9 @@ export class FeeData {
});
}
/**
* Returns a JSON-friendly value.
*/
toJSON(): any {
const {
gasPrice, maxFeePerGas, maxPriorityFeePerGas
@ -175,7 +218,7 @@ export async function resolveTransactionRequest(tx: TransactionRequest, provider
//////////////////////
// Block
/*
export interface BlockParams<T extends string | TransactionResponseParams> {
hash?: null | string;
@ -197,6 +240,7 @@ export interface BlockParams<T extends string | TransactionResponseParams> {
transactions: ReadonlyArray<T>;
};
*/
export interface MinedBlock<T extends string | TransactionResponse = string> extends Block<T> {
readonly number: number;
@ -206,28 +250,97 @@ export interface MinedBlock<T extends string | TransactionResponse = string> ext
readonly miner: string;
}
/**
* A **Block** represents the data associated with a full block on
* Ethereum.
*/
export class Block<T extends string | TransactionResponse> implements BlockParams<T>, Iterable<T> {
/**
* The provider connected to the block used to fetch additional details
* if necessary.
*/
readonly provider!: Provider;
/**
* The block number, sometimes called the block height. This is a
* sequential number that is one higher than the parent block.
*/
readonly number!: number;
/**
* The block hash.
*/
readonly hash!: null | string;
/**
* The timestamp for this block, which is the number of seconds since
* epoch that this block was included.
*/
readonly timestamp!: number;
/**
* The block hash of the parent block.
*/
readonly parentHash!: string;
/**
* The nonce.
*
* On legacy networks, this is the random number inserted which
* permitted the difficulty target to be reached.
*/
readonly nonce!: string;
/**
* The difficulty target.
*
* On legacy networks, this is the proof-of-work target required
* for a block to meet the protocol rules to be included.
*
* On modern networks, this is a random number arrived at using
* randao. @TODO: Find links?
*/
readonly difficulty!: bigint;
/**
* The total gas limit for this block.
*/
readonly gasLimit!: bigint;
/**
* The total gas used in this block.
*/
readonly gasUsed!: bigint;
/**
* The miner coinbase address, wihch receives any subsidies for
* including this block.
*/
readonly miner!: string;
/**
* Any extra data the validator wished to include.
*/
readonly extraData!: string;
/**
* The base fee per gas that all transactions in this block were
* charged.
*
* This adjusts after each block, depending on how congested the network
* is.
*/
readonly baseFeePerGas!: null | bigint;
readonly #transactions: ReadonlyArray<T>;
/**
* Create a new **Block** object.
*
* This should generally not be necessary as the unless implementing a
* low-level library.
*/
constructor(block: BlockParams<T>, provider: Provider) {
this.#transactions = Object.freeze(block.transactions.map((tx) => {
@ -259,12 +372,14 @@ export class Block<T extends string | TransactionResponse> implements BlockParam
});
}
/**
* Returns the list of transactions.
*/
get transactions(): ReadonlyArray<T> { return this.#transactions; }
//connect(provider: Provider): Block<T> {
// return new Block(this, provider);
//}
/**
* Returns a JSON-friendly value.
*/
toJSON(): any {
const {
baseFeePerGas, difficulty, extraData, gasLimit, gasUsed, hash,
@ -297,13 +412,23 @@ export class Block<T extends string | TransactionResponse> implements BlockParam
};
}
/**
* The number of transactions in this block.
*/
get length(): number { return this.transactions.length; }
/**
* The [date](link-js-data) this block was included at.
*/
get date(): null | Date {
if (this.timestamp == null) { return null; }
return new Date(this.timestamp * 1000);
}
// @TODO: Don't have 2 block types?
// just populate this with all the values? simplifies provider
/**
* Get the transaction at %%indexe%% within this block.
*/
async getTransaction(index: number): Promise<TransactionResponse> {
const tx = this.transactions[index];
if (tx == null) { throw new Error("no such tx"); }
@ -314,7 +439,17 @@ export class Block<T extends string | TransactionResponse> implements BlockParam
}
}
/**
* Has this block been mined.
*
* If true, the block has been typed-gaurded that all mined
* properties are non-null.
*/
isMined(): this is MinedBlock<T> { return !!this.hash; }
/**
*
*/
isLondon(): this is (Block<T> & { baseFeePerGas: bigint }) {
return !!this.baseFeePerGas;
}
@ -328,6 +463,7 @@ export class Block<T extends string | TransactionResponse> implements BlockParam
//////////////////////
// Log
/*
export interface LogParams {
transactionHash: string;
blockHash: string;
@ -343,7 +479,7 @@ export interface LogParams {
index: number;
transactionIndex: number;
}
*/
export class Log implements LogParams {
readonly provider: Provider;
@ -420,7 +556,7 @@ export class Log implements LogParams {
//////////////////////
// Transaction Receipt
/*
export interface TransactionReceiptParams {
to: null | string;
from: string;
@ -445,7 +581,7 @@ export interface TransactionReceiptParams {
status: null | number;
root: null | string;
}
*/
/*
export interface LegacyTransactionReceipt {
byzantium: false;
@ -595,7 +731,7 @@ export class TransactionReceipt implements TransactionReceiptParams, Iterable<Lo
//////////////////////
// Transaction Response
/*
export interface TransactionResponseParams {
blockNumber: null | number;
blockHash: null | string;
@ -625,7 +761,7 @@ export interface TransactionResponseParams {
accessList: null | AccessList;
};
*/
export interface MinedTransactionResponse extends TransactionResponse {
blockNumber: number;
blockHash: string;
@ -1028,7 +1164,35 @@ export type ProviderEvent = string | Array<string | Array<string>> | EventFilter
//////////////////////
// Provider
/**
* A **Provider** is the primary method to interact with the read-only
* content on Ethereum.
*
* It allows access to details about accounts, blocks and transactions
* and the ability to query event logs and simulate contract execution.
*
* Account data includes the [balance](getBalance),
* [transaction count](getTransactionCount), [code](getCode) and
* [state trie storage](getStorage).
*
* Simulating execution can be used to [call](call),
* [estimate gas](estimateGas) and
* [get transaction results](getTransactionResult).
*
* The [[broadcastTransaction]] is the only method which allows updating
* the blockchain, but it is usually accessed by a [[Signer]], since a
* private key must be used to sign the transaction before it can be
* broadcast.
*/
export interface Provider extends ContractRunner, EventEmitterable<ProviderEvent>, NameResolver {
/**
* The provider iteself.
*
* This is part of the necessary API for executing a contract, as
* it provides a common property on any [[ContractRunner]] that
* can be used to access the read-only portion of the runner.
*/
provider: this;
@ -1055,11 +1219,9 @@ export interface Provider extends ContractRunner, EventEmitterable<ProviderEvent
// Account
/**
* Get the account balance (in wei) of %%address%%. If %%blockTag%% is specified and
* the node supports archive access, the balance is as of that [[BlockTag]].
*
* @param {Address | Addressable} address - The account to lookup the balance of
* @param blockTag - The block tag to use for historic archive access. [default: ``"latest"``]
* Get the account balance (in wei) of %%address%%. If %%blockTag%%
* is specified and the node supports archive access for that
* %%blockTag%%, the balance is as of that [[BlockTag]].
*
* @note On nodes without archive access enabled, the %%blockTag%% may be
* **silently ignored** by the node, which may cause issues if relied on.
@ -1067,12 +1229,11 @@ export interface Provider extends ContractRunner, EventEmitterable<ProviderEvent
getBalance(address: AddressLike, blockTag?: BlockTag): Promise<bigint>;
/**
* Get the number of transactions ever sent for %%address%%, which is used as
* the ``nonce`` when sending a transaction. If %%blockTag%% is specified and
* the node supports archive access, the transaction count is as of that [[BlockTag]].
*
* @param {Address | Addressable} address - The account to lookup the transaction count of
* @param blockTag - The block tag to use for historic archive access. [default: ``"latest"``]
* Get the number of transactions ever sent for %%address%%, which
* is used as the ``nonce`` when sending a transaction. If
* %%blockTag%% is specified and the node supports archive access
* for that %%blockTag%%, the transaction count is as of that
* [[BlockTag]].
*
* @note On nodes without archive access enabled, the %%blockTag%% may be
* **silently ignored** by the node, which may cause issues if relied on.
@ -1080,10 +1241,7 @@ export interface Provider extends ContractRunner, EventEmitterable<ProviderEvent
getTransactionCount(address: AddressLike, blockTag?: BlockTag): Promise<number>;
/**
* Get the bytecode for //address//.
*
* @param {Address | Addressable} address - The account to lookup the bytecode of
* @param blockTag - The block tag to use for historic archive access. [default: ``"latest"``]
* Get the bytecode for %%address%%.
*
* @note On nodes without archive access enabled, the %%blockTag%% may be
* **silently ignored** by the node, which may cause issues if relied on.
@ -1091,11 +1249,7 @@ export interface Provider extends ContractRunner, EventEmitterable<ProviderEvent
getCode(address: AddressLike, blockTag?: BlockTag): Promise<string>
/**
* Get the storage slot value for a given //address// and slot //position//.
*
* @param {Address | Addressable} address - The account to lookup the storage of
* @param position - The storage slot to fetch the value of
* @param blockTag - The block tag to use for historic archive access. [default: ``"latest"``]
* Get the storage slot value for %%address%% at slot %%position%%.
*
* @note On nodes without archive access enabled, the %%blockTag%% may be
* **silently ignored** by the node, which may cause issues if relied on.
@ -1108,24 +1262,19 @@ export interface Provider extends ContractRunner, EventEmitterable<ProviderEvent
/**
* Estimates the amount of gas required to executre %%tx%%.
*
* @param tx - The transaction to estimate the gas requirement for
*/
estimateGas(tx: TransactionRequest): Promise<bigint>;
// If call fails, throws CALL_EXCEPTION { data: string, error, errorString?, panicReason? }
/**
* Uses call to simulate execution of %%tx%%.
*
* @param tx - The transaction to simulate
* Simulate the execution of %%tx%%. If the call reverts, it will
* throw a [[CallExceptionError]] which includes the revert data.
*/
call(tx: TransactionRequest): Promise<string>
/**
* Broadcasts the %%signedTx%% to the network, adding it to the memory pool
* of any node for which the transaction meets the rebroadcast requirements.
*
* @param signedTx - The transaction to broadcast
* Broadcasts the %%signedTx%% to the network, adding it to the
* memory pool of any node for which the transaction meets the
* rebroadcast requirements.
*/
broadcastTransaction(signedTx: string): Promise<TransactionResponse>;
@ -1133,25 +1282,83 @@ export interface Provider extends ContractRunner, EventEmitterable<ProviderEvent
////////////////////
// Queries
/**
* Resolves to the block for %%blockHashOrBlockTag%%.
*/
getBlock(blockHashOrBlockTag: BlockTag | string): Promise<null | Block<string>>;
/**
* Resolves to the block for %%blockHashOrBlockTag%%, including each
* full transaction.
*
* If a block is unknonw, this resolved to ``null``.
*/
getBlockWithTransactions(blockHashOrBlockTag: BlockTag | string): Promise<null | Block<TransactionResponse>>
/**
* Resolves to the transaction for %%hash%%.
*
* If the transaction is unknown or on pruning nodes which
* discard old transactions this resolves to ``null``.
*/
getTransaction(hash: string): Promise<null | TransactionResponse>;
/**
* Resolves to the transaction receipt for %%hash%%, if mined.
*
* If the transaction has not been mined, is unknown or on
* pruning nodes which discard old transactions this resolves to
* ``null``.
*/
getTransactionReceipt(hash: string): Promise<null | TransactionReceipt>;
/**
* Resolves to the result returned by the executions of %%hash%%.
*
* This is only supported on nodes with archive access and with
* the necessary debug APIs enabled.
*/
getTransactionResult(hash: string): Promise<null | string>;
////////////////////
// Bloom-filter Queries
/**
* Resolves to the list of Logs that match %%filter%%
*/
getLogs(filter: Filter | FilterByBlockHash): Promise<Array<Log>>;
////////////////////
// ENS
resolveName(name: string): Promise<null | string>;
/**
* Resolves to the address configured for the %%ensName%% or
* ``null`` if unconfigured.
*/
resolveName(ensName: string): Promise<null | string>;
/**
* Resolves to the ENS name associated for the %%address%% or
* ``null`` if the //primary name// is not configured.
*
* Users must perform additional steps to configure a //primary name//,
* which is not currently common.
*/
lookupAddress(address: string): Promise<null | string>;
/**
* Waits until the transaction %%hash%% is mined and has %%confirms%%
* confirmations.
*/
waitForTransaction(hash: string, confirms?: number, timeout?: number): Promise<null | TransactionReceipt>;
/**
* Resolves to the block at %%blockTag%% once it has been mined.
*
* This can be useful for waiting some number of blocks by using
* the ``currentBlockNumber + N``.
*/
waitForBlock(blockTag?: BlockTag): Promise<Block<string>>;
}

@ -6,12 +6,23 @@ import type { Subscriber } from "./abstract-provider.js";
//#TODO: Temp
import type { Provider } from "./provider.js";
/**
* @TODO
*
* @_docloc: api/providers/abstract-provider
*/
export interface ConnectionRpcProvider extends Provider {
//send(method: string, params: Array<any>): Promise<any>;
_subscribe(param: Array<any>, processFunc: (result: any) => void): number;
_unsubscribe(filterId: number): void;
}
/**
* @TODO
*
* @_docloc: api/providers/abstract-provider
*/
export class BlockConnectionSubscriber implements Subscriber {
#provider: ConnectionRpcProvider;
#blockNumber: number;

@ -10,6 +10,16 @@ function copy(obj: any): any {
return JSON.parse(JSON.stringify(obj));
}
/**
* Some backends support subscribing to events using a Filter ID.
*
* When subscribing with this technique, the node issues a unique
* //Filter ID//. At this point the node dedicates resources to
* the filter, so that periodic calls to follow up on the //Filter ID//
* will receive any events since the last call.
*
* @_docloc: api/providers/abstract-provider
*/
export class FilterIdSubscriber implements Subscriber {
#provider: JsonRpcApiProvider;
@ -90,6 +100,11 @@ export class FilterIdSubscriber implements Subscriber {
resume(): void { this.start(); }
}
/**
* A **FilterIdSubscriber** for receiving contract events.
*
* @_docloc: api/providers/abstract-provider
*/
export class FilterIdEventSubscriber extends FilterIdSubscriber {
#event: EventFilter;
@ -114,6 +129,11 @@ export class FilterIdEventSubscriber extends FilterIdSubscriber {
}
}
/**
* A **FilterIdSubscriber** for receiving pending transactions events.
*
* @_docloc: api/providers/abstract-provider
*/
export class FilterIdPendingSubscriber extends FilterIdSubscriber {
async _subscribe(provider: JsonRpcApiProvider): Promise<string> {
return await provider.send("eth_newPendingTransactionFilter", [ ]);

@ -1,41 +0,0 @@
/*
import { Subscriber } from "./abstract-provider.js";
export class HotSwapSubscriber implements Subscriber {
#target?: Subscriber;
_switchSubscriber(subscriber: Subscriber): void {
this.#target = subscriber;
}
start(): void {
if (this.#target) { return this.#target.start(); }
return super.start();
}
stop(): void {
if (this.#target) { return this.#target.stop(); }
return super.stop();
}
pause(dropWhilePaused?: boolean): void {
if (this.#target) { return this.#target.pause(dropWhilePaused); }
return super.pause(dropWhilePaused);
}
resume(): void {
if (this.#target) { return this.#target.resume(); }
return super.resume();
}
set pollingInterval(value: number) {
if (this.#target) { return this.#target.pollingInterval = value; }
return super.pollingInterval = value;
}
get pollingInterval(): number {
if (this.#target) { return this.#target.pollingInterval; }
return super.pollingInterval;
}
}
*/

@ -7,6 +7,11 @@ function copy(obj: any): any {
return JSON.parse(JSON.stringify(obj));
}
/**
* @TODO
*
* @_docloc: api/providers/abstract-provider
*/
export function getPollingSubscriber(provider: AbstractProvider, event: ProviderEvent): Subscriber {
if (event === "block") { return new PollingBlockSubscriber(provider); }
if (isHexString(event, 32)) { return new PollingTransactionSubscriber(provider, event); }
@ -18,6 +23,11 @@ export function getPollingSubscriber(provider: AbstractProvider, event: Provider
// @TODO: refactor this
/**
* @TODO
*
* @_docloc: api/providers/abstract-provider
*/
export class PollingBlockSubscriber implements Subscriber{
#provider: AbstractProvider;
#poller: null | number;
@ -81,6 +91,11 @@ export class PollingBlockSubscriber implements Subscriber{
}
}
/**
* @TODO
*
* @_docloc: api/providers/abstract-provider
*/
export class OnBlockSubscriber implements Subscriber {
#provider: AbstractProvider;
#poll: (b: number) => void;
@ -109,6 +124,11 @@ export class OnBlockSubscriber implements Subscriber {
resume(): void { this.start(); }
}
/**
* @TODO
*
* @_docloc: api/providers/abstract-provider
*/
export class PollingOrphanSubscriber extends OnBlockSubscriber {
#filter: OrphanFilter;
@ -123,6 +143,11 @@ export class PollingOrphanSubscriber extends OnBlockSubscriber {
}
}
/**
* @TODO
*
* @_docloc: api/providers/abstract-provider
*/
export class PollingTransactionSubscriber extends OnBlockSubscriber {
#hash: string;
@ -137,6 +162,11 @@ export class PollingTransactionSubscriber extends OnBlockSubscriber {
}
}
/**
* @TODO
*
* @_docloc: api/providers/abstract-provider
*/
export class PollingEventSubscriber implements Subscriber {
#provider: AbstractProvider;
#filter: EventFilter;

@ -1,15 +0,0 @@
/**
* 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";