-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
/
Copy pathnonce-manager.ts
74 lines (59 loc) · 2.51 KB
/
nonce-manager.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
"use strict"
import { ethers } from "ethers";
// @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 {
readonly signer: ethers.Signer;
_initialPromise: Promise<number>;
_deltaCount: number;
constructor(signer: ethers.Signer) {
super();
this._deltaCount = 0;
ethers.utils.defineReadOnly(this, "signer", signer);
ethers.utils.defineReadOnly(this, "provider", signer.provider || null);
}
connect(provider: ethers.providers.Provider): NonceManager {
return new NonceManager(this.signer.connect(provider));
}
getAddress(): Promise<string> {
return this.signer.getAddress();
}
getTransactionCount(blockTag?: ethers.providers.BlockTag): Promise<number> {
if (blockTag === "pending") {
if (!this._initialPromise) {
this._initialPromise = this.signer.getTransactionCount("pending");
}
const deltaCount = this._deltaCount;
return this._initialPromise.then((initial) => (initial + deltaCount));
}
return this.signer.getTransactionCount(blockTag);
}
setTransactionCount(transactionCount: ethers.BigNumberish | Promise<ethers.BigNumberish>): void {
this._initialPromise = Promise.resolve(transactionCount).then((nonce) => {
return ethers.BigNumber.from(nonce).toNumber();
});
this._deltaCount = 0;
}
incrementTransactionCount(count?: number): void {
this._deltaCount += ((count == null) ? 1: count);
}
signMessage(message: ethers.Bytes | string): Promise<string> {
return this.signer.signMessage(message);;
}
signTransaction(transaction: ethers.utils.Deferrable<ethers.providers.TransactionRequest>): Promise<string> {
return this.signer.signTransaction(transaction);
}
sendTransaction(transaction: ethers.utils.Deferrable<ethers.providers.TransactionRequest>): Promise<ethers.providers.TransactionResponse> {
if (transaction.nonce == null) {
transaction = ethers.utils.shallowCopy(transaction);
transaction.nonce = this.getTransactionCount("pending");
this.incrementTransactionCount();
} else {
this.setTransactionCount(transaction.nonce);
this._deltaCount++;
}
return this.signer.sendTransaction(transaction).then((tx) => {
return tx;
});
}
}