2019-08-25 02:39:20 -04:00
|
|
|
"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
|
2019-08-25 02:39:20 -04:00
|
|
|
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;
|
2019-08-25 02:39:20 -04:00
|
|
|
ethers.utils.defineReadOnly(this, "signer", signer);
|
|
|
|
}
|
2020-04-03 22:13:06 -04:00
|
|
|
get provider() {
|
|
|
|
return this.signer.provider;
|
|
|
|
}
|
2019-08-25 02:39:20 -04:00
|
|
|
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-08-25 02:39:20 -04:00
|
|
|
}
|
2019-11-20 18:57:38 +09:00
|
|
|
const deltaCount = this._deltaCount;
|
|
|
|
return this._initialPromise.then((initial) => (initial + deltaCount));
|
2019-08-25 02:39:20 -04:00
|
|
|
}
|
|
|
|
return this.signer.getTransactionCount(blockTag);
|
|
|
|
}
|
|
|
|
setTransactionCount(transactionCount) {
|
2019-11-20 18:57:38 +09:00
|
|
|
this._initialPromise = Promise.resolve(transactionCount).then((nonce) => {
|
2019-08-25 02:39:20 -04:00
|
|
|
return ethers.BigNumber.from(nonce).toNumber();
|
|
|
|
});
|
2019-11-20 18:57:38 +09:00
|
|
|
this._deltaCount = 0;
|
2019-08-25 02:39:20 -04:00
|
|
|
}
|
|
|
|
incrementTransactionCount(count) {
|
2019-11-20 18:57:38 +09:00
|
|
|
this._deltaCount += (count ? count : 1);
|
2019-08-25 02:39:20 -04:00
|
|
|
}
|
|
|
|
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-08-25 02:39:20 -04:00
|
|
|
}
|
2019-11-20 18:57:38 +09:00
|
|
|
else {
|
|
|
|
this.setTransactionCount(transaction.nonce);
|
|
|
|
}
|
|
|
|
return this.signer.sendTransaction(transaction).then((tx) => {
|
|
|
|
return tx;
|
|
|
|
});
|
2019-08-25 02:39:20 -04:00
|
|
|
}
|
|
|
|
}
|