ethers.js/packages/experimental/lib.esm/nonce-manager.js

63 lines
2.1 KiB
JavaScript
Raw Normal View History

"use strict";
import { ethers } from "ethers";
import { version } from "./_version";
const logger = new ethers.utils.Logger(version);
2019-11-20 18:57:38 +09:00
// @TODO: Keep a per-NonceManager pool of sent but unmined transactions for
// rebroadcasting, in case we overrun the transaction pool
export class NonceManager extends ethers.Signer {
constructor(signer) {
logger.checkNew(new.target, NonceManager);
super();
2019-11-20 18:57:38 +09:00
this._deltaCount = 0;
ethers.utils.defineReadOnly(this, "signer", signer);
}
2020-04-03 22:13:06 -04:00
get provider() {
return this.signer.provider;
}
connect(provider) {
return new NonceManager(this.signer.connect(provider));
}
getAddress() {
return this.signer.getAddress();
}
getTransactionCount(blockTag) {
if (blockTag === "pending") {
2019-11-20 18:57:38 +09:00
if (!this._initialPromise) {
this._initialPromise = this.signer.getTransactionCount("pending");
}
2019-11-20 18:57:38 +09:00
const deltaCount = this._deltaCount;
return this._initialPromise.then((initial) => (initial + deltaCount));
}
return this.signer.getTransactionCount(blockTag);
}
setTransactionCount(transactionCount) {
2019-11-20 18:57:38 +09:00
this._initialPromise = Promise.resolve(transactionCount).then((nonce) => {
return ethers.BigNumber.from(nonce).toNumber();
});
2019-11-20 18:57:38 +09:00
this._deltaCount = 0;
}
incrementTransactionCount(count) {
2019-11-20 18:57:38 +09:00
this._deltaCount += (count ? count : 1);
}
signMessage(message) {
return this.signer.signMessage(message);
;
}
signTransaction(transaction) {
return this.signer.signTransaction(transaction);
}
sendTransaction(transaction) {
if (transaction.nonce == null) {
transaction = ethers.utils.shallowCopy(transaction);
2019-11-20 18:57:38 +09:00
transaction.nonce = this.getTransactionCount("pending");
this.incrementTransactionCount();
}
2019-11-20 18:57:38 +09:00
else {
this.setTransactionCount(transaction.nonce);
}
return this.signer.sendTransaction(transaction).then((tx) => {
return tx;
});
}
}