admin: updated dist files

This commit is contained in:
Richard Moore 2023-06-06 22:42:28 -04:00
parent 374fbaebcd
commit 11956aee34
60 changed files with 368 additions and 98 deletions

@ -3,6 +3,15 @@ Change Log
This change log is maintained by `src.ts/_admin/update-changelog.ts` but may also be manually updated. This change log is maintained by `src.ts/_admin/update-changelog.ts` but may also be manually updated.
ethers/v6.5.0 (2023-06-06 22:41)
--------------------------------
- Fix CJS browser bundling ([#4033](https://github.com/ethers-io/ethers.js/issues/4033); [38ee319](https://github.com/ethers-io/ethers.js/commit/38ee3195b0192d8180899fd61308e03fa3a0eb32)).
- Fixed type guard for non-Typed instances ([#4087](https://github.com/ethers-io/ethers.js/issues/4087); [20c3d1b](https://github.com/ethers-io/ethers.js/commit/20c3d1b109743e33ab60a75d69bf7ede73b15ce2)).
- Add confirmations to TransactionResponse ([#4094](https://github.com/ethers-io/ethers.js/issues/4094); [bb8685b](https://github.com/ethers-io/ethers.js/commit/bb8685b112ce1c689c740d4dbcb358c16fb9b22d)).
- Fix stray promises when a node returns invalid results ([#4118](https://github.com/ethers-io/ethers.js/issues/4118); [3c1bad2](https://github.com/ethers-io/ethers.js/commit/3c1bad2fb7ad4a6ff90ff11f3e382fd18e41c800)).
- Added support to detect and stop providers spinning on intitial network detection ([#4015](https://github.com/ethers-io/ethers.js/issues/4015); [f37a52d](https://github.com/ethers-io/ethers.js/commit/f37a52da28ac130b7f4de52901618320994ea87a)).
ethers/v6.4.2 (2023-06-05 22:41) ethers/v6.4.2 (2023-06-05 22:41)
-------------------------------- --------------------------------

85
dist/ethers.js vendored

@ -3,7 +3,7 @@ const __$G = (typeof globalThis !== 'undefined' ? globalThis: typeof window !==
/** /**
* The current version of Ethers. * The current version of Ethers.
*/ */
const version = "6.4.2"; const version = "6.5.0";
/** /**
* Property helper functions. * Property helper functions.
@ -7107,7 +7107,10 @@ class Typed {
* Returns true only if %%value%% is a [[Typed]] instance. * Returns true only if %%value%% is a [[Typed]] instance.
*/ */
static isTyped(value) { static isTyped(value) {
return (value && value._typedSymbol === _typedSymbol); return (value
&& typeof (value) === "object"
&& "_typedSymbol" in value
&& value._typedSymbol === _typedSymbol);
} }
/** /**
* If the value is a [[Typed]] instance, validates the underlying value * If the value is a [[Typed]] instance, validates the underlying value
@ -13523,6 +13526,24 @@ class TransactionResponse {
async getTransaction() { async getTransaction() {
return this.provider.getTransaction(this.hash); return this.provider.getTransaction(this.hash);
} }
/**
* Resolve to the number of confirmations this transaction has.
*/
async confirmations() {
if (this.blockNumber == null) {
const { tx, blockNumber } = await resolveProperties({
tx: this.getTransaction(),
blockNumber: this.provider.getBlockNumber()
});
// Not mined yet...
if (tx == null || tx.blockNumber == null) {
return 0;
}
return blockNumber - tx.blockNumber + 1;
}
const blockNumber = await this.provider.getBlockNumber();
return blockNumber - this.blockNumber + 1;
}
/** /**
* Resolves once this transaction has been mined and has * Resolves once this transaction has been mined and has
* %%confirms%% blocks including it (default: ``1``) with an * %%confirms%% blocks including it (default: ``1``) with an
@ -15373,7 +15394,7 @@ class EnsResolver {
return null; return null;
} }
// Optimization since the eth node cannot change and does // Optimization since the eth node cannot change and does
// not have a wildcar resolver // not have a wildcard resolver
if (name !== "eth" && currentName === "eth") { if (name !== "eth" && currentName === "eth") {
return null; return null;
} }
@ -16576,6 +16597,7 @@ class AbstractProvider {
#plugins; #plugins;
// null=unpaused, true=paused+dropWhilePaused, false=paused // null=unpaused, true=paused+dropWhilePaused, false=paused
#pausedState; #pausedState;
#destroyed;
#networkPromise; #networkPromise;
#anyNetwork; #anyNetwork;
#performCache; #performCache;
@ -16609,6 +16631,7 @@ class AbstractProvider {
this.#subs = new Map(); this.#subs = new Map();
this.#plugins = new Map(); this.#plugins = new Map();
this.#pausedState = null; this.#pausedState = null;
this.#destroyed = false;
this.#nextTimer = 1; this.#nextTimer = 1;
this.#timers = new Map(); this.#timers = new Map();
this.#disableCcipRead = false; this.#disableCcipRead = false;
@ -17543,9 +17566,19 @@ class AbstractProvider {
async removeListener(event, listener) { async removeListener(event, listener) {
return this.off(event, listener); return this.off(event, listener);
} }
/**
* If this provider has been destroyed using the [[destroy]] method.
*
* Once destroyed, all resources are reclaimed, internal event loops
* and timers are cleaned up and no further requests may be sent to
* the provider.
*/
get destroyed() {
return this.#destroyed;
}
/** /**
* Sub-classes may use this to shutdown any sockets or release their * Sub-classes may use this to shutdown any sockets or release their
* resources. * resources and reject any pending requests.
* *
* Sub-classes **must** call ``super.destroy()``. * Sub-classes **must** call ``super.destroy()``.
*/ */
@ -17556,6 +17589,7 @@ class AbstractProvider {
for (const timerId of this.#timers.keys()) { for (const timerId of this.#timers.keys()) {
this._clearTimeout(timerId); this._clearTimeout(timerId);
} }
this.#destroyed = true;
} }
/** /**
* Whether the provider is currently paused. * Whether the provider is currently paused.
@ -18414,11 +18448,20 @@ class JsonRpcApiProvider extends AbstractProvider {
this.emit("debug", { action: "receiveRpcResult", result }); this.emit("debug", { action: "receiveRpcResult", result });
// Process results in batch order // Process results in batch order
for (const { resolve, reject, payload } of batch) { for (const { resolve, reject, payload } of batch) {
if (this.destroyed) {
reject(makeError("provider destroyed; cancelled request", "UNSUPPORTED_OPERATION", { operation: payload.method }));
continue;
}
// Find the matching result // Find the matching result
const resp = result.filter((r) => (r.id === payload.id))[0]; const resp = result.filter((r) => (r.id === payload.id))[0];
// No result; the node failed us in unexpected ways // No result; the node failed us in unexpected ways
if (resp == null) { if (resp == null) {
return reject(makeError("no response from server", "BAD_DATA", { value: result, info: { payload } })); const error = makeError("missing response for request", "BAD_DATA", {
value: result, info: { payload }
});
this.emit("error", error);
reject(error);
continue;
} }
// The response is an error // The response is an error
if ("error" in resp) { if ("error" in resp) {
@ -18476,13 +18519,6 @@ class JsonRpcApiProvider extends AbstractProvider {
assert$1(this.#network, "network is not available yet", "NETWORK_ERROR"); assert$1(this.#network, "network is not available yet", "NETWORK_ERROR");
return this.#network; return this.#network;
} }
/*
{
assert(false, "sub-classes must override _send", "UNSUPPORTED_OPERATION", {
operation: "jsonRpcApiProvider._send"
});
}
*/
/** /**
* Resolves to the non-normalized value by performing %%req%%. * Resolves to the non-normalized value by performing %%req%%.
* *
@ -18563,12 +18599,13 @@ class JsonRpcApiProvider extends AbstractProvider {
this.#notReady = null; this.#notReady = null;
(async () => { (async () => {
// Bootstrap the network // Bootstrap the network
while (this.#network == null) { while (this.#network == null && !this.destroyed) {
try { try {
this.#network = await this._detectNetwork(); this.#network = await this._detectNetwork();
} }
catch (error) { catch (error) {
console.log("JsonRpcProvider failed to startup; retry in 1s"); console.log("JsonRpcProvider failed to detect network and cannot start up; retry in 1s (perhaps the URL is wrong or the node is not started)");
this.emit("error", makeError("failed to bootstrap network detection", "NETWORK_ERROR", { event: "initial-network-discovery", info: { error } }));
await stall$3(1000); await stall$3(1000);
} }
} }
@ -18820,6 +18857,10 @@ class JsonRpcApiProvider extends AbstractProvider {
*/ */
send(method, params) { send(method, params) {
// @TODO: cache chainId?? purge on switch_networks // @TODO: cache chainId?? purge on switch_networks
// We have been destroyed; no operations are supported anymore
if (this.destroyed) {
return Promise.reject(makeError("provider destroyed; cancelled request", "UNSUPPORTED_OPERATION", { operation: method }));
}
const id = this.#nextId++; const id = this.#nextId++;
const promise = new Promise((resolve, reject) => { const promise = new Promise((resolve, reject) => {
this.#payloads.push({ this.#payloads.push({
@ -18873,6 +18914,20 @@ class JsonRpcApiProvider extends AbstractProvider {
const accounts = await this.send("eth_accounts", []); const accounts = await this.send("eth_accounts", []);
return accounts.map((a) => new JsonRpcSigner(this, a)); return accounts.map((a) => new JsonRpcSigner(this, a));
} }
destroy() {
// Stop processing requests
if (this.#drainTimer) {
clearTimeout(this.#drainTimer);
this.#drainTimer = null;
}
// Cancel all pending requests
for (const { payload, reject } of this.#payloads) {
reject(makeError("provider destroyed; cancelled request", "UNSUPPORTED_OPERATION", { operation: payload.method }));
}
this.#payloads = [];
// Parent clean-up
super.destroy();
}
} }
class JsonRpcApiPollingProvider extends JsonRpcApiProvider { class JsonRpcApiPollingProvider extends JsonRpcApiProvider {
#pollingInterval; #pollingInterval;
@ -22754,7 +22809,7 @@ class HDNodeWallet extends BaseWallet {
return HDNodeWallet.#fromSeed(mnemonic.computeSeed(), mnemonic).derivePath(path); return HDNodeWallet.#fromSeed(mnemonic.computeSeed(), mnemonic).derivePath(path);
} }
/** /**
* Create am HD Node from %%mnemonic%%. * Create an HD Node from %%mnemonic%%.
*/ */
static fromMnemonic(mnemonic, path) { static fromMnemonic(mnemonic, path) {
if (!path) { if (!path) {

2
dist/ethers.js.map vendored

File diff suppressed because one or more lines are too long

2
dist/ethers.min.js vendored

File diff suppressed because one or more lines are too long

85
dist/ethers.umd.js vendored

@ -9,7 +9,7 @@ const __$G = (typeof globalThis !== 'undefined' ? globalThis: typeof window !==
/** /**
* The current version of Ethers. * The current version of Ethers.
*/ */
const version = "6.4.2"; const version = "6.5.0";
/** /**
* Property helper functions. * Property helper functions.
@ -7113,7 +7113,10 @@ const __$G = (typeof globalThis !== 'undefined' ? globalThis: typeof window !==
* Returns true only if %%value%% is a [[Typed]] instance. * Returns true only if %%value%% is a [[Typed]] instance.
*/ */
static isTyped(value) { static isTyped(value) {
return (value && value._typedSymbol === _typedSymbol); return (value
&& typeof (value) === "object"
&& "_typedSymbol" in value
&& value._typedSymbol === _typedSymbol);
} }
/** /**
* If the value is a [[Typed]] instance, validates the underlying value * If the value is a [[Typed]] instance, validates the underlying value
@ -13529,6 +13532,24 @@ const __$G = (typeof globalThis !== 'undefined' ? globalThis: typeof window !==
async getTransaction() { async getTransaction() {
return this.provider.getTransaction(this.hash); return this.provider.getTransaction(this.hash);
} }
/**
* Resolve to the number of confirmations this transaction has.
*/
async confirmations() {
if (this.blockNumber == null) {
const { tx, blockNumber } = await resolveProperties({
tx: this.getTransaction(),
blockNumber: this.provider.getBlockNumber()
});
// Not mined yet...
if (tx == null || tx.blockNumber == null) {
return 0;
}
return blockNumber - tx.blockNumber + 1;
}
const blockNumber = await this.provider.getBlockNumber();
return blockNumber - this.blockNumber + 1;
}
/** /**
* Resolves once this transaction has been mined and has * Resolves once this transaction has been mined and has
* %%confirms%% blocks including it (default: ``1``) with an * %%confirms%% blocks including it (default: ``1``) with an
@ -15379,7 +15400,7 @@ const __$G = (typeof globalThis !== 'undefined' ? globalThis: typeof window !==
return null; return null;
} }
// Optimization since the eth node cannot change and does // Optimization since the eth node cannot change and does
// not have a wildcar resolver // not have a wildcard resolver
if (name !== "eth" && currentName === "eth") { if (name !== "eth" && currentName === "eth") {
return null; return null;
} }
@ -16582,6 +16603,7 @@ const __$G = (typeof globalThis !== 'undefined' ? globalThis: typeof window !==
#plugins; #plugins;
// null=unpaused, true=paused+dropWhilePaused, false=paused // null=unpaused, true=paused+dropWhilePaused, false=paused
#pausedState; #pausedState;
#destroyed;
#networkPromise; #networkPromise;
#anyNetwork; #anyNetwork;
#performCache; #performCache;
@ -16615,6 +16637,7 @@ const __$G = (typeof globalThis !== 'undefined' ? globalThis: typeof window !==
this.#subs = new Map(); this.#subs = new Map();
this.#plugins = new Map(); this.#plugins = new Map();
this.#pausedState = null; this.#pausedState = null;
this.#destroyed = false;
this.#nextTimer = 1; this.#nextTimer = 1;
this.#timers = new Map(); this.#timers = new Map();
this.#disableCcipRead = false; this.#disableCcipRead = false;
@ -17549,9 +17572,19 @@ const __$G = (typeof globalThis !== 'undefined' ? globalThis: typeof window !==
async removeListener(event, listener) { async removeListener(event, listener) {
return this.off(event, listener); return this.off(event, listener);
} }
/**
* If this provider has been destroyed using the [[destroy]] method.
*
* Once destroyed, all resources are reclaimed, internal event loops
* and timers are cleaned up and no further requests may be sent to
* the provider.
*/
get destroyed() {
return this.#destroyed;
}
/** /**
* Sub-classes may use this to shutdown any sockets or release their * Sub-classes may use this to shutdown any sockets or release their
* resources. * resources and reject any pending requests.
* *
* Sub-classes **must** call ``super.destroy()``. * Sub-classes **must** call ``super.destroy()``.
*/ */
@ -17562,6 +17595,7 @@ const __$G = (typeof globalThis !== 'undefined' ? globalThis: typeof window !==
for (const timerId of this.#timers.keys()) { for (const timerId of this.#timers.keys()) {
this._clearTimeout(timerId); this._clearTimeout(timerId);
} }
this.#destroyed = true;
} }
/** /**
* Whether the provider is currently paused. * Whether the provider is currently paused.
@ -18420,11 +18454,20 @@ const __$G = (typeof globalThis !== 'undefined' ? globalThis: typeof window !==
this.emit("debug", { action: "receiveRpcResult", result }); this.emit("debug", { action: "receiveRpcResult", result });
// Process results in batch order // Process results in batch order
for (const { resolve, reject, payload } of batch) { for (const { resolve, reject, payload } of batch) {
if (this.destroyed) {
reject(makeError("provider destroyed; cancelled request", "UNSUPPORTED_OPERATION", { operation: payload.method }));
continue;
}
// Find the matching result // Find the matching result
const resp = result.filter((r) => (r.id === payload.id))[0]; const resp = result.filter((r) => (r.id === payload.id))[0];
// No result; the node failed us in unexpected ways // No result; the node failed us in unexpected ways
if (resp == null) { if (resp == null) {
return reject(makeError("no response from server", "BAD_DATA", { value: result, info: { payload } })); const error = makeError("missing response for request", "BAD_DATA", {
value: result, info: { payload }
});
this.emit("error", error);
reject(error);
continue;
} }
// The response is an error // The response is an error
if ("error" in resp) { if ("error" in resp) {
@ -18482,13 +18525,6 @@ const __$G = (typeof globalThis !== 'undefined' ? globalThis: typeof window !==
assert$1(this.#network, "network is not available yet", "NETWORK_ERROR"); assert$1(this.#network, "network is not available yet", "NETWORK_ERROR");
return this.#network; return this.#network;
} }
/*
{
assert(false, "sub-classes must override _send", "UNSUPPORTED_OPERATION", {
operation: "jsonRpcApiProvider._send"
});
}
*/
/** /**
* Resolves to the non-normalized value by performing %%req%%. * Resolves to the non-normalized value by performing %%req%%.
* *
@ -18569,12 +18605,13 @@ const __$G = (typeof globalThis !== 'undefined' ? globalThis: typeof window !==
this.#notReady = null; this.#notReady = null;
(async () => { (async () => {
// Bootstrap the network // Bootstrap the network
while (this.#network == null) { while (this.#network == null && !this.destroyed) {
try { try {
this.#network = await this._detectNetwork(); this.#network = await this._detectNetwork();
} }
catch (error) { catch (error) {
console.log("JsonRpcProvider failed to startup; retry in 1s"); console.log("JsonRpcProvider failed to detect network and cannot start up; retry in 1s (perhaps the URL is wrong or the node is not started)");
this.emit("error", makeError("failed to bootstrap network detection", "NETWORK_ERROR", { event: "initial-network-discovery", info: { error } }));
await stall$3(1000); await stall$3(1000);
} }
} }
@ -18826,6 +18863,10 @@ const __$G = (typeof globalThis !== 'undefined' ? globalThis: typeof window !==
*/ */
send(method, params) { send(method, params) {
// @TODO: cache chainId?? purge on switch_networks // @TODO: cache chainId?? purge on switch_networks
// We have been destroyed; no operations are supported anymore
if (this.destroyed) {
return Promise.reject(makeError("provider destroyed; cancelled request", "UNSUPPORTED_OPERATION", { operation: method }));
}
const id = this.#nextId++; const id = this.#nextId++;
const promise = new Promise((resolve, reject) => { const promise = new Promise((resolve, reject) => {
this.#payloads.push({ this.#payloads.push({
@ -18879,6 +18920,20 @@ const __$G = (typeof globalThis !== 'undefined' ? globalThis: typeof window !==
const accounts = await this.send("eth_accounts", []); const accounts = await this.send("eth_accounts", []);
return accounts.map((a) => new JsonRpcSigner(this, a)); return accounts.map((a) => new JsonRpcSigner(this, a));
} }
destroy() {
// Stop processing requests
if (this.#drainTimer) {
clearTimeout(this.#drainTimer);
this.#drainTimer = null;
}
// Cancel all pending requests
for (const { payload, reject } of this.#payloads) {
reject(makeError("provider destroyed; cancelled request", "UNSUPPORTED_OPERATION", { operation: payload.method }));
}
this.#payloads = [];
// Parent clean-up
super.destroy();
}
} }
class JsonRpcApiPollingProvider extends JsonRpcApiProvider { class JsonRpcApiPollingProvider extends JsonRpcApiProvider {
#pollingInterval; #pollingInterval;
@ -22760,7 +22815,7 @@ const __$G = (typeof globalThis !== 'undefined' ? globalThis: typeof window !==
return HDNodeWallet.#fromSeed(mnemonic.computeSeed(), mnemonic).derivePath(path); return HDNodeWallet.#fromSeed(mnemonic.computeSeed(), mnemonic).derivePath(path);
} }
/** /**
* Create am HD Node from %%mnemonic%%. * Create an HD Node from %%mnemonic%%.
*/ */
static fromMnemonic(mnemonic, path) { static fromMnemonic(mnemonic, path) {
if (!path) { if (!path) {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -151,7 +151,7 @@ const u64 = {
/** /**
* The current version of Ethers. * The current version of Ethers.
*/ */
const version = "6.4.2"; const version = "6.5.0";
/** /**
* Property helper functions. * Property helper functions.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -5,5 +5,5 @@ exports.version = void 0;
/** /**
* The current version of Ethers. * The current version of Ethers.
*/ */
exports.version = "6.4.2"; exports.version = "6.5.0";
//# sourceMappingURL=_version.js.map //# sourceMappingURL=_version.js.map

File diff suppressed because one or more lines are too long

@ -580,7 +580,10 @@ class Typed {
* Returns true only if %%value%% is a [[Typed]] instance. * Returns true only if %%value%% is a [[Typed]] instance.
*/ */
static isTyped(value) { static isTyped(value) {
return (value && value._typedSymbol === _typedSymbol); return (value
&& typeof (value) === "object"
&& "_typedSymbol" in value
&& value._typedSymbol === _typedSymbol);
} }
/** /**
* If the value is a [[Typed]] instance, validates the underlying value * If the value is a [[Typed]] instance, validates the underlying value

File diff suppressed because one or more lines are too long

@ -1,3 +1,12 @@
{ {
"browser": {
"./crypto/crypto.js": "./crypto/crypto-browser.js",
"./providers/provider-ipcsocket.js": "./providers/provider-ipcsocket-browser.js",
"./providers/ws.js": "./providers/ws-browser.js",
"./utils/base64.js": "./utils/base64-browser.js",
"./utils/geturl.js": "./utils/geturl-browser.js",
"./wordlists/wordlists.js": "./wordlists/wordlists-browser.js"
},
"sideEffects": false,
"type": "commonjs" "type": "commonjs"
} }

@ -392,9 +392,17 @@ export declare class AbstractProvider implements Provider {
removeAllListeners(event?: ProviderEvent): Promise<this>; removeAllListeners(event?: ProviderEvent): Promise<this>;
addListener(event: ProviderEvent, listener: Listener): Promise<this>; addListener(event: ProviderEvent, listener: Listener): Promise<this>;
removeListener(event: ProviderEvent, listener: Listener): Promise<this>; removeListener(event: ProviderEvent, listener: Listener): Promise<this>;
/**
* If this provider has been destroyed using the [[destroy]] method.
*
* Once destroyed, all resources are reclaimed, internal event loops
* and timers are cleaned up and no further requests may be sent to
* the provider.
*/
get destroyed(): boolean;
/** /**
* Sub-classes may use this to shutdown any sockets or release their * Sub-classes may use this to shutdown any sockets or release their
* resources. * resources and reject any pending requests.
* *
* Sub-classes **must** call ``super.destroy()``. * Sub-classes **must** call ``super.destroy()``.
*/ */

File diff suppressed because one or more lines are too long

@ -164,6 +164,7 @@ class AbstractProvider {
#plugins; #plugins;
// null=unpaused, true=paused+dropWhilePaused, false=paused // null=unpaused, true=paused+dropWhilePaused, false=paused
#pausedState; #pausedState;
#destroyed;
#networkPromise; #networkPromise;
#anyNetwork; #anyNetwork;
#performCache; #performCache;
@ -197,6 +198,7 @@ class AbstractProvider {
this.#subs = new Map(); this.#subs = new Map();
this.#plugins = new Map(); this.#plugins = new Map();
this.#pausedState = null; this.#pausedState = null;
this.#destroyed = false;
this.#nextTimer = 1; this.#nextTimer = 1;
this.#timers = new Map(); this.#timers = new Map();
this.#disableCcipRead = false; this.#disableCcipRead = false;
@ -1132,9 +1134,19 @@ class AbstractProvider {
async removeListener(event, listener) { async removeListener(event, listener) {
return this.off(event, listener); return this.off(event, listener);
} }
/**
* If this provider has been destroyed using the [[destroy]] method.
*
* Once destroyed, all resources are reclaimed, internal event loops
* and timers are cleaned up and no further requests may be sent to
* the provider.
*/
get destroyed() {
return this.#destroyed;
}
/** /**
* Sub-classes may use this to shutdown any sockets or release their * Sub-classes may use this to shutdown any sockets or release their
* resources. * resources and reject any pending requests.
* *
* Sub-classes **must** call ``super.destroy()``. * Sub-classes **must** call ``super.destroy()``.
*/ */
@ -1145,6 +1157,7 @@ class AbstractProvider {
for (const timerId of this.#timers.keys()) { for (const timerId of this.#timers.keys()) {
this._clearTimeout(timerId); this._clearTimeout(timerId);
} }
this.#destroyed = true;
} }
/** /**
* Whether the provider is currently paused. * Whether the provider is currently paused.

File diff suppressed because one or more lines are too long

@ -469,7 +469,7 @@ class EnsResolver {
return null; return null;
} }
// Optimization since the eth node cannot change and does // Optimization since the eth node cannot change and does
// not have a wildcar resolver // not have a wildcard resolver
if (name !== "eth" && currentName === "eth") { if (name !== "eth" && currentName === "eth") {
return null; return null;
} }

File diff suppressed because one or more lines are too long

@ -313,6 +313,7 @@ export declare abstract class JsonRpcApiProvider extends AbstractProvider {
*/ */
getSigner(address?: number | string): Promise<JsonRpcSigner>; getSigner(address?: number | string): Promise<JsonRpcSigner>;
listAccounts(): Promise<Array<JsonRpcSigner>>; listAccounts(): Promise<Array<JsonRpcSigner>>;
destroy(): void;
} }
export declare abstract class JsonRpcApiPollingProvider extends JsonRpcApiProvider { export declare abstract class JsonRpcApiPollingProvider extends JsonRpcApiProvider {
#private; #private;

File diff suppressed because one or more lines are too long

@ -246,11 +246,20 @@ class JsonRpcApiProvider extends abstract_provider_js_1.AbstractProvider {
this.emit("debug", { action: "receiveRpcResult", result }); this.emit("debug", { action: "receiveRpcResult", result });
// Process results in batch order // Process results in batch order
for (const { resolve, reject, payload } of batch) { for (const { resolve, reject, payload } of batch) {
if (this.destroyed) {
reject((0, index_js_5.makeError)("provider destroyed; cancelled request", "UNSUPPORTED_OPERATION", { operation: payload.method }));
continue;
}
// Find the matching result // Find the matching result
const resp = result.filter((r) => (r.id === payload.id))[0]; const resp = result.filter((r) => (r.id === payload.id))[0];
// No result; the node failed us in unexpected ways // No result; the node failed us in unexpected ways
if (resp == null) { if (resp == null) {
return reject((0, index_js_5.makeError)("no response from server", "BAD_DATA", { value: result, info: { payload } })); const error = (0, index_js_5.makeError)("missing response for request", "BAD_DATA", {
value: result, info: { payload }
});
this.emit("error", error);
reject(error);
continue;
} }
// The response is an error // The response is an error
if ("error" in resp) { if ("error" in resp) {
@ -308,13 +317,6 @@ class JsonRpcApiProvider extends abstract_provider_js_1.AbstractProvider {
(0, index_js_5.assert)(this.#network, "network is not available yet", "NETWORK_ERROR"); (0, index_js_5.assert)(this.#network, "network is not available yet", "NETWORK_ERROR");
return this.#network; return this.#network;
} }
/*
{
assert(false, "sub-classes must override _send", "UNSUPPORTED_OPERATION", {
operation: "jsonRpcApiProvider._send"
});
}
*/
/** /**
* Resolves to the non-normalized value by performing %%req%%. * Resolves to the non-normalized value by performing %%req%%.
* *
@ -395,12 +397,13 @@ class JsonRpcApiProvider extends abstract_provider_js_1.AbstractProvider {
this.#notReady = null; this.#notReady = null;
(async () => { (async () => {
// Bootstrap the network // Bootstrap the network
while (this.#network == null) { while (this.#network == null && !this.destroyed) {
try { try {
this.#network = await this._detectNetwork(); this.#network = await this._detectNetwork();
} }
catch (error) { catch (error) {
console.log("JsonRpcProvider failed to startup; retry in 1s"); console.log("JsonRpcProvider failed to detect network and cannot start up; retry in 1s (perhaps the URL is wrong or the node is not started)");
this.emit("error", (0, index_js_5.makeError)("failed to bootstrap network detection", "NETWORK_ERROR", { event: "initial-network-discovery", info: { error } }));
await stall(1000); await stall(1000);
} }
} }
@ -652,6 +655,10 @@ class JsonRpcApiProvider extends abstract_provider_js_1.AbstractProvider {
*/ */
send(method, params) { send(method, params) {
// @TODO: cache chainId?? purge on switch_networks // @TODO: cache chainId?? purge on switch_networks
// We have been destroyed; no operations are supported anymore
if (this.destroyed) {
return Promise.reject((0, index_js_5.makeError)("provider destroyed; cancelled request", "UNSUPPORTED_OPERATION", { operation: method }));
}
const id = this.#nextId++; const id = this.#nextId++;
const promise = new Promise((resolve, reject) => { const promise = new Promise((resolve, reject) => {
this.#payloads.push({ this.#payloads.push({
@ -705,6 +712,20 @@ class JsonRpcApiProvider extends abstract_provider_js_1.AbstractProvider {
const accounts = await this.send("eth_accounts", []); const accounts = await this.send("eth_accounts", []);
return accounts.map((a) => new JsonRpcSigner(this, a)); return accounts.map((a) => new JsonRpcSigner(this, a));
} }
destroy() {
// Stop processing requests
if (this.#drainTimer) {
clearTimeout(this.#drainTimer);
this.#drainTimer = null;
}
// Cancel all pending requests
for (const { payload, reject } of this.#payloads) {
reject((0, index_js_5.makeError)("provider destroyed; cancelled request", "UNSUPPORTED_OPERATION", { operation: payload.method }));
}
this.#payloads = [];
// Parent clean-up
super.destroy();
}
} }
exports.JsonRpcApiProvider = JsonRpcApiProvider; exports.JsonRpcApiProvider = JsonRpcApiProvider;
class JsonRpcApiPollingProvider extends JsonRpcApiProvider { class JsonRpcApiPollingProvider extends JsonRpcApiProvider {

File diff suppressed because one or more lines are too long

@ -775,6 +775,10 @@ export declare class TransactionResponse implements TransactionLike<string>, Tra
* and wish to get an up-to-date populated instance. * and wish to get an up-to-date populated instance.
*/ */
getTransaction(): Promise<null | TransactionResponse>; getTransaction(): Promise<null | TransactionResponse>;
/**
* Resolve to the number of confirmations this transaction has.
*/
confirmations(): Promise<number>;
/** /**
* Resolves once this transaction has been mined and has * Resolves once this transaction has been mined and has
* %%confirms%% blocks including it (default: ``1``) with an * %%confirms%% blocks including it (default: ``1``) with an

File diff suppressed because one or more lines are too long

@ -922,6 +922,24 @@ class TransactionResponse {
async getTransaction() { async getTransaction() {
return this.provider.getTransaction(this.hash); return this.provider.getTransaction(this.hash);
} }
/**
* Resolve to the number of confirmations this transaction has.
*/
async confirmations() {
if (this.blockNumber == null) {
const { tx, blockNumber } = await (0, index_js_1.resolveProperties)({
tx: this.getTransaction(),
blockNumber: this.provider.getBlockNumber()
});
// Not mined yet...
if (tx == null || tx.blockNumber == null) {
return 0;
}
return blockNumber - tx.blockNumber + 1;
}
const blockNumber = await this.provider.getBlockNumber();
return blockNumber - this.blockNumber + 1;
}
/** /**
* Resolves once this transaction has been mined and has * Resolves once this transaction has been mined and has
* %%confirms%% blocks including it (default: ``1``) with an * %%confirms%% blocks including it (default: ``1``) with an

File diff suppressed because one or more lines are too long

@ -133,6 +133,9 @@ export interface UnsupportedOperationError extends EthersError<"UNSUPPORTED_OPER
* This Error indicates a proplem connecting to a network. * This Error indicates a proplem connecting to a network.
*/ */
export interface NetworkError extends EthersError<"NETWORK_ERROR"> { export interface NetworkError extends EthersError<"NETWORK_ERROR"> {
/**
* The network event.
*/
event: string; event: string;
} }
/** /**

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -138,7 +138,7 @@ export declare class HDNodeWallet extends BaseWallet {
*/ */
static createRandom(password?: string, path?: string, wordlist?: Wordlist): HDNodeWallet; static createRandom(password?: string, path?: string, wordlist?: Wordlist): HDNodeWallet;
/** /**
* Create am HD Node from %%mnemonic%%. * Create an HD Node from %%mnemonic%%.
*/ */
static fromMnemonic(mnemonic: Mnemonic, path?: string): HDNodeWallet; static fromMnemonic(mnemonic: Mnemonic, path?: string): HDNodeWallet;
/** /**

@ -308,7 +308,7 @@ class HDNodeWallet extends base_wallet_js_1.BaseWallet {
return HDNodeWallet.#fromSeed(mnemonic.computeSeed(), mnemonic).derivePath(path); return HDNodeWallet.#fromSeed(mnemonic.computeSeed(), mnemonic).derivePath(path);
} }
/** /**
* Create am HD Node from %%mnemonic%%. * Create an HD Node from %%mnemonic%%.
*/ */
static fromMnemonic(mnemonic, path) { static fromMnemonic(mnemonic, path) {
if (!path) { if (!path) {

@ -2,5 +2,5 @@
/** /**
* The current version of Ethers. * The current version of Ethers.
*/ */
export const version = "6.4.2"; export const version = "6.5.0";
//# sourceMappingURL=_version.js.map //# sourceMappingURL=_version.js.map

File diff suppressed because one or more lines are too long

@ -577,7 +577,10 @@ export class Typed {
* Returns true only if %%value%% is a [[Typed]] instance. * Returns true only if %%value%% is a [[Typed]] instance.
*/ */
static isTyped(value) { static isTyped(value) {
return (value && value._typedSymbol === _typedSymbol); return (value
&& typeof (value) === "object"
&& "_typedSymbol" in value
&& value._typedSymbol === _typedSymbol);
} }
/** /**
* If the value is a [[Typed]] instance, validates the underlying value * If the value is a [[Typed]] instance, validates the underlying value

File diff suppressed because one or more lines are too long

@ -392,9 +392,17 @@ export declare class AbstractProvider implements Provider {
removeAllListeners(event?: ProviderEvent): Promise<this>; removeAllListeners(event?: ProviderEvent): Promise<this>;
addListener(event: ProviderEvent, listener: Listener): Promise<this>; addListener(event: ProviderEvent, listener: Listener): Promise<this>;
removeListener(event: ProviderEvent, listener: Listener): Promise<this>; removeListener(event: ProviderEvent, listener: Listener): Promise<this>;
/**
* If this provider has been destroyed using the [[destroy]] method.
*
* Once destroyed, all resources are reclaimed, internal event loops
* and timers are cleaned up and no further requests may be sent to
* the provider.
*/
get destroyed(): boolean;
/** /**
* Sub-classes may use this to shutdown any sockets or release their * Sub-classes may use this to shutdown any sockets or release their
* resources. * resources and reject any pending requests.
* *
* Sub-classes **must** call ``super.destroy()``. * Sub-classes **must** call ``super.destroy()``.
*/ */

File diff suppressed because one or more lines are too long

@ -160,6 +160,7 @@ export class AbstractProvider {
#plugins; #plugins;
// null=unpaused, true=paused+dropWhilePaused, false=paused // null=unpaused, true=paused+dropWhilePaused, false=paused
#pausedState; #pausedState;
#destroyed;
#networkPromise; #networkPromise;
#anyNetwork; #anyNetwork;
#performCache; #performCache;
@ -193,6 +194,7 @@ export class AbstractProvider {
this.#subs = new Map(); this.#subs = new Map();
this.#plugins = new Map(); this.#plugins = new Map();
this.#pausedState = null; this.#pausedState = null;
this.#destroyed = false;
this.#nextTimer = 1; this.#nextTimer = 1;
this.#timers = new Map(); this.#timers = new Map();
this.#disableCcipRead = false; this.#disableCcipRead = false;
@ -1128,9 +1130,19 @@ export class AbstractProvider {
async removeListener(event, listener) { async removeListener(event, listener) {
return this.off(event, listener); return this.off(event, listener);
} }
/**
* If this provider has been destroyed using the [[destroy]] method.
*
* Once destroyed, all resources are reclaimed, internal event loops
* and timers are cleaned up and no further requests may be sent to
* the provider.
*/
get destroyed() {
return this.#destroyed;
}
/** /**
* Sub-classes may use this to shutdown any sockets or release their * Sub-classes may use this to shutdown any sockets or release their
* resources. * resources and reject any pending requests.
* *
* Sub-classes **must** call ``super.destroy()``. * Sub-classes **must** call ``super.destroy()``.
*/ */
@ -1141,6 +1153,7 @@ export class AbstractProvider {
for (const timerId of this.#timers.keys()) { for (const timerId of this.#timers.keys()) {
this._clearTimeout(timerId); this._clearTimeout(timerId);
} }
this.#destroyed = true;
} }
/** /**
* Whether the provider is currently paused. * Whether the provider is currently paused.

File diff suppressed because one or more lines are too long

@ -464,7 +464,7 @@ export class EnsResolver {
return null; return null;
} }
// Optimization since the eth node cannot change and does // Optimization since the eth node cannot change and does
// not have a wildcar resolver // not have a wildcard resolver
if (name !== "eth" && currentName === "eth") { if (name !== "eth" && currentName === "eth") {
return null; return null;
} }

File diff suppressed because one or more lines are too long

@ -313,6 +313,7 @@ export declare abstract class JsonRpcApiProvider extends AbstractProvider {
*/ */
getSigner(address?: number | string): Promise<JsonRpcSigner>; getSigner(address?: number | string): Promise<JsonRpcSigner>;
listAccounts(): Promise<Array<JsonRpcSigner>>; listAccounts(): Promise<Array<JsonRpcSigner>>;
destroy(): void;
} }
export declare abstract class JsonRpcApiPollingProvider extends JsonRpcApiProvider { export declare abstract class JsonRpcApiPollingProvider extends JsonRpcApiProvider {
#private; #private;

File diff suppressed because one or more lines are too long

@ -242,11 +242,20 @@ export class JsonRpcApiProvider extends AbstractProvider {
this.emit("debug", { action: "receiveRpcResult", result }); this.emit("debug", { action: "receiveRpcResult", result });
// Process results in batch order // Process results in batch order
for (const { resolve, reject, payload } of batch) { for (const { resolve, reject, payload } of batch) {
if (this.destroyed) {
reject(makeError("provider destroyed; cancelled request", "UNSUPPORTED_OPERATION", { operation: payload.method }));
continue;
}
// Find the matching result // Find the matching result
const resp = result.filter((r) => (r.id === payload.id))[0]; const resp = result.filter((r) => (r.id === payload.id))[0];
// No result; the node failed us in unexpected ways // No result; the node failed us in unexpected ways
if (resp == null) { if (resp == null) {
return reject(makeError("no response from server", "BAD_DATA", { value: result, info: { payload } })); const error = makeError("missing response for request", "BAD_DATA", {
value: result, info: { payload }
});
this.emit("error", error);
reject(error);
continue;
} }
// The response is an error // The response is an error
if ("error" in resp) { if ("error" in resp) {
@ -304,13 +313,6 @@ export class JsonRpcApiProvider extends AbstractProvider {
assert(this.#network, "network is not available yet", "NETWORK_ERROR"); assert(this.#network, "network is not available yet", "NETWORK_ERROR");
return this.#network; return this.#network;
} }
/*
{
assert(false, "sub-classes must override _send", "UNSUPPORTED_OPERATION", {
operation: "jsonRpcApiProvider._send"
});
}
*/
/** /**
* Resolves to the non-normalized value by performing %%req%%. * Resolves to the non-normalized value by performing %%req%%.
* *
@ -391,12 +393,13 @@ export class JsonRpcApiProvider extends AbstractProvider {
this.#notReady = null; this.#notReady = null;
(async () => { (async () => {
// Bootstrap the network // Bootstrap the network
while (this.#network == null) { while (this.#network == null && !this.destroyed) {
try { try {
this.#network = await this._detectNetwork(); this.#network = await this._detectNetwork();
} }
catch (error) { catch (error) {
console.log("JsonRpcProvider failed to startup; retry in 1s"); console.log("JsonRpcProvider failed to detect network and cannot start up; retry in 1s (perhaps the URL is wrong or the node is not started)");
this.emit("error", makeError("failed to bootstrap network detection", "NETWORK_ERROR", { event: "initial-network-discovery", info: { error } }));
await stall(1000); await stall(1000);
} }
} }
@ -648,6 +651,10 @@ export class JsonRpcApiProvider extends AbstractProvider {
*/ */
send(method, params) { send(method, params) {
// @TODO: cache chainId?? purge on switch_networks // @TODO: cache chainId?? purge on switch_networks
// We have been destroyed; no operations are supported anymore
if (this.destroyed) {
return Promise.reject(makeError("provider destroyed; cancelled request", "UNSUPPORTED_OPERATION", { operation: method }));
}
const id = this.#nextId++; const id = this.#nextId++;
const promise = new Promise((resolve, reject) => { const promise = new Promise((resolve, reject) => {
this.#payloads.push({ this.#payloads.push({
@ -701,6 +708,20 @@ export class JsonRpcApiProvider extends AbstractProvider {
const accounts = await this.send("eth_accounts", []); const accounts = await this.send("eth_accounts", []);
return accounts.map((a) => new JsonRpcSigner(this, a)); return accounts.map((a) => new JsonRpcSigner(this, a));
} }
destroy() {
// Stop processing requests
if (this.#drainTimer) {
clearTimeout(this.#drainTimer);
this.#drainTimer = null;
}
// Cancel all pending requests
for (const { payload, reject } of this.#payloads) {
reject(makeError("provider destroyed; cancelled request", "UNSUPPORTED_OPERATION", { operation: payload.method }));
}
this.#payloads = [];
// Parent clean-up
super.destroy();
}
} }
export class JsonRpcApiPollingProvider extends JsonRpcApiProvider { export class JsonRpcApiPollingProvider extends JsonRpcApiProvider {
#pollingInterval; #pollingInterval;

File diff suppressed because one or more lines are too long

@ -775,6 +775,10 @@ export declare class TransactionResponse implements TransactionLike<string>, Tra
* and wish to get an up-to-date populated instance. * and wish to get an up-to-date populated instance.
*/ */
getTransaction(): Promise<null | TransactionResponse>; getTransaction(): Promise<null | TransactionResponse>;
/**
* Resolve to the number of confirmations this transaction has.
*/
confirmations(): Promise<number>;
/** /**
* Resolves once this transaction has been mined and has * Resolves once this transaction has been mined and has
* %%confirms%% blocks including it (default: ``1``) with an * %%confirms%% blocks including it (default: ``1``) with an

File diff suppressed because one or more lines are too long

@ -914,6 +914,24 @@ export class TransactionResponse {
async getTransaction() { async getTransaction() {
return this.provider.getTransaction(this.hash); return this.provider.getTransaction(this.hash);
} }
/**
* Resolve to the number of confirmations this transaction has.
*/
async confirmations() {
if (this.blockNumber == null) {
const { tx, blockNumber } = await resolveProperties({
tx: this.getTransaction(),
blockNumber: this.provider.getBlockNumber()
});
// Not mined yet...
if (tx == null || tx.blockNumber == null) {
return 0;
}
return blockNumber - tx.blockNumber + 1;
}
const blockNumber = await this.provider.getBlockNumber();
return blockNumber - this.blockNumber + 1;
}
/** /**
* Resolves once this transaction has been mined and has * Resolves once this transaction has been mined and has
* %%confirms%% blocks including it (default: ``1``) with an * %%confirms%% blocks including it (default: ``1``) with an

File diff suppressed because one or more lines are too long

@ -133,6 +133,9 @@ export interface UnsupportedOperationError extends EthersError<"UNSUPPORTED_OPER
* This Error indicates a proplem connecting to a network. * This Error indicates a proplem connecting to a network.
*/ */
export interface NetworkError extends EthersError<"NETWORK_ERROR"> { export interface NetworkError extends EthersError<"NETWORK_ERROR"> {
/**
* The network event.
*/
event: string; event: string;
} }
/** /**

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -138,7 +138,7 @@ export declare class HDNodeWallet extends BaseWallet {
*/ */
static createRandom(password?: string, path?: string, wordlist?: Wordlist): HDNodeWallet; static createRandom(password?: string, path?: string, wordlist?: Wordlist): HDNodeWallet;
/** /**
* Create am HD Node from %%mnemonic%%. * Create an HD Node from %%mnemonic%%.
*/ */
static fromMnemonic(mnemonic: Mnemonic, path?: string): HDNodeWallet; static fromMnemonic(mnemonic: Mnemonic, path?: string): HDNodeWallet;
/** /**

@ -305,7 +305,7 @@ export class HDNodeWallet extends BaseWallet {
return HDNodeWallet.#fromSeed(mnemonic.computeSeed(), mnemonic).derivePath(path); return HDNodeWallet.#fromSeed(mnemonic.computeSeed(), mnemonic).derivePath(path);
} }
/** /**
* Create am HD Node from %%mnemonic%%. * Create an HD Node from %%mnemonic%%.
*/ */
static fromMnemonic(mnemonic, path) { static fromMnemonic(mnemonic, path) {
if (!path) { if (!path) {

4
package-lock.json generated

@ -1,12 +1,12 @@
{ {
"name": "ethers", "name": "ethers",
"version": "6.4.1", "version": "6.4.2",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "ethers", "name": "ethers",
"version": "6.4.1", "version": "6.4.2",
"funding": [ "funding": [
{ {
"type": "individual", "type": "individual",

@ -93,7 +93,7 @@
"url": "https://www.buymeacoffee.com/ricmoo" "url": "https://www.buymeacoffee.com/ricmoo"
} }
], ],
"gitHead": "c1357847dcdec93d72f28d890f9271d0289ccefd", "gitHead": "38ee3195b0192d8180899fd61308e03fa3a0eb32",
"homepage": "https://ethers.org", "homepage": "https://ethers.org",
"keywords": [ "keywords": [
"ethereum", "ethereum",
@ -131,5 +131,5 @@
"test-esm": "mocha --reporter ./reporter.cjs ./lib.esm/_tests/test-*.js" "test-esm": "mocha --reporter ./reporter.cjs ./lib.esm/_tests/test-*.js"
}, },
"sideEffects": false, "sideEffects": false,
"version": "6.4.2" "version": "6.5.0"
} }

@ -3,4 +3,4 @@
/** /**
* The current version of Ethers. * The current version of Ethers.
*/ */
export const version: string = "6.4.2"; export const version: string = "6.5.0";