@toruslabs/ethereum-controllers 5.11.0 → 6.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/dist/ethereumControllers.cjs.js +80 -431
  2. package/dist/ethereumControllers.esm.js +30 -349
  3. package/dist/ethereumControllers.umd.min.js +1 -1
  4. package/dist/ethereumControllers.umd.min.js.LICENSE.txt +7 -2
  5. package/dist/lib.cjs/Account/AccountTrackerController.js +160 -0
  6. package/dist/lib.cjs/Block/PollingBlockTracker.js +85 -0
  7. package/dist/lib.cjs/Currency/CurrencyController.js +111 -0
  8. package/dist/lib.cjs/Gas/GasFeeController.js +214 -0
  9. package/dist/lib.cjs/Gas/gasUtil.js +148 -0
  10. package/dist/lib.cjs/Keyring/KeyringController.js +93 -0
  11. package/dist/lib.cjs/Message/AbstractMessageController.js +107 -0
  12. package/dist/lib.cjs/Message/AddChainController.js +78 -0
  13. package/dist/lib.cjs/Message/MessageController.js +77 -0
  14. package/dist/lib.cjs/Message/PersonalMessageController.js +77 -0
  15. package/dist/lib.cjs/Message/SwitchChainController.js +78 -0
  16. package/dist/lib.cjs/Message/TypedMessageController.js +81 -0
  17. package/dist/lib.cjs/Message/utils.js +112 -0
  18. package/dist/lib.cjs/Network/NetworkController.js +201 -0
  19. package/dist/lib.cjs/Network/cacheIdentifier.js +112 -0
  20. package/dist/lib.cjs/Network/createEthereumMiddleware.js +302 -0
  21. package/dist/lib.cjs/Network/createJsonRpcClient.js +64 -0
  22. package/dist/lib.cjs/Nfts/NftHandler.js +180 -0
  23. package/dist/lib.cjs/Nfts/NftsController.js +213 -0
  24. package/dist/lib.cjs/Preferences/PreferencesController.js +476 -0
  25. package/dist/lib.cjs/Tokens/TokenHandler.js +51 -0
  26. package/dist/lib.cjs/Tokens/TokenRatesController.js +112 -0
  27. package/dist/lib.cjs/Tokens/TokensController.js +259 -0
  28. package/dist/lib.cjs/Transaction/NonceTracker.js +150 -0
  29. package/dist/lib.cjs/Transaction/PendingTransactionTracker.js +222 -0
  30. package/dist/lib.cjs/Transaction/TransactionController.js +515 -0
  31. package/dist/lib.cjs/Transaction/TransactionGasUtil.js +81 -0
  32. package/dist/lib.cjs/Transaction/TransactionStateHistoryHelper.js +42 -0
  33. package/dist/lib.cjs/Transaction/TransactionStateManager.js +296 -0
  34. package/dist/lib.cjs/Transaction/TransactionUtils.js +341 -0
  35. package/dist/lib.cjs/index.js +171 -0
  36. package/dist/lib.cjs/utils/abis.js +510 -0
  37. package/dist/lib.cjs/utils/constants.js +362 -0
  38. package/dist/lib.cjs/utils/contractAddresses.js +16 -0
  39. package/dist/lib.cjs/utils/conversionUtils.js +232 -0
  40. package/dist/lib.cjs/utils/helpers.js +244 -0
  41. package/dist/lib.cjs/utils/lodashUtils.js +25 -0
  42. package/dist/lib.esm/Account/AccountTrackerController.js +158 -0
  43. package/dist/lib.esm/Block/PollingBlockTracker.js +83 -0
  44. package/dist/lib.esm/Currency/CurrencyController.js +109 -0
  45. package/dist/lib.esm/Gas/GasFeeController.js +212 -0
  46. package/dist/lib.esm/Gas/gasUtil.js +141 -0
  47. package/dist/lib.esm/Keyring/KeyringController.js +91 -0
  48. package/dist/lib.esm/Message/AbstractMessageController.js +105 -0
  49. package/dist/lib.esm/Message/AddChainController.js +76 -0
  50. package/dist/lib.esm/Message/MessageController.js +75 -0
  51. package/dist/lib.esm/Message/PersonalMessageController.js +75 -0
  52. package/dist/lib.esm/Message/SwitchChainController.js +76 -0
  53. package/dist/lib.esm/Message/TypedMessageController.js +79 -0
  54. package/dist/lib.esm/Message/utils.js +105 -0
  55. package/dist/lib.esm/Network/NetworkController.js +199 -0
  56. package/dist/lib.esm/Network/cacheIdentifier.js +107 -0
  57. package/dist/lib.esm/Network/createEthereumMiddleware.js +289 -0
  58. package/dist/lib.esm/Network/createJsonRpcClient.js +60 -0
  59. package/dist/lib.esm/Nfts/NftHandler.js +178 -0
  60. package/dist/lib.esm/Nfts/NftsController.js +211 -0
  61. package/dist/lib.esm/Preferences/PreferencesController.js +474 -0
  62. package/dist/lib.esm/Tokens/TokenHandler.js +49 -0
  63. package/dist/lib.esm/Tokens/TokenRatesController.js +109 -0
  64. package/dist/lib.esm/Tokens/TokensController.js +257 -0
  65. package/dist/lib.esm/Transaction/NonceTracker.js +148 -0
  66. package/dist/lib.esm/Transaction/PendingTransactionTracker.js +220 -0
  67. package/dist/lib.esm/Transaction/TransactionController.js +513 -0
  68. package/dist/lib.esm/Transaction/TransactionGasUtil.js +79 -0
  69. package/dist/lib.esm/Transaction/TransactionStateHistoryHelper.js +38 -0
  70. package/dist/lib.esm/Transaction/TransactionStateManager.js +294 -0
  71. package/dist/lib.esm/Transaction/TransactionUtils.js +326 -0
  72. package/dist/lib.esm/index.js +33 -0
  73. package/dist/lib.esm/utils/abis.js +505 -0
  74. package/dist/lib.esm/utils/constants.js +323 -0
  75. package/dist/lib.esm/utils/contractAddresses.js +14 -0
  76. package/dist/lib.esm/utils/conversionUtils.js +218 -0
  77. package/dist/lib.esm/utils/helpers.js +227 -0
  78. package/dist/lib.esm/utils/lodashUtils.js +21 -0
  79. package/dist/types/Account/AccountTrackerController.d.ts +5 -5
  80. package/dist/types/Block/PollingBlockTracker.d.ts +1 -2
  81. package/dist/types/Currency/CurrencyController.d.ts +1 -1
  82. package/dist/types/Gas/GasFeeController.d.ts +3 -3
  83. package/dist/types/Gas/gasUtil.d.ts +1 -1
  84. package/dist/types/Keyring/KeyringController.d.ts +3 -5
  85. package/dist/types/Message/AbstractMessageController.d.ts +5 -6
  86. package/dist/types/Message/AddChainController.d.ts +4 -4
  87. package/dist/types/Message/MessageController.d.ts +4 -4
  88. package/dist/types/Message/PersonalMessageController.d.ts +4 -4
  89. package/dist/types/Message/SwitchChainController.d.ts +4 -4
  90. package/dist/types/Message/TypedMessageController.d.ts +6 -7
  91. package/dist/types/Message/utils.d.ts +2 -7
  92. package/dist/types/Network/NetworkController.d.ts +4 -4
  93. package/dist/types/Network/cacheIdentifier.d.ts +1 -1
  94. package/dist/types/Network/createEthereumMiddleware.d.ts +2 -18
  95. package/dist/types/Network/createJsonRpcClient.d.ts +2 -2
  96. package/dist/types/Nfts/NftsController.d.ts +2 -2
  97. package/dist/types/Preferences/PreferencesController.d.ts +4 -4
  98. package/dist/types/Tokens/TokensController.d.ts +3 -3
  99. package/dist/types/Transaction/NonceTracker.d.ts +5 -5
  100. package/dist/types/Transaction/PendingTransactionTracker.d.ts +5 -5
  101. package/dist/types/Transaction/TransactionController.d.ts +12 -12
  102. package/dist/types/Transaction/TransactionGasUtil.d.ts +4 -4
  103. package/dist/types/Transaction/TransactionStateManager.d.ts +3 -3
  104. package/dist/types/Transaction/TransactionUtils.d.ts +1 -1
  105. package/dist/types/index.d.ts +12 -14
  106. package/dist/types/utils/constants.d.ts +1 -5
  107. package/dist/types/utils/helpers.d.ts +4 -4
  108. package/dist/types/utils/interfaces.d.ts +43 -23
  109. package/package.json +10 -9
  110. package/dist/types/Message/DecryptMessageController.d.ts +0 -20
  111. package/dist/types/Message/EncryptionPublicKeyController.d.ts +0 -20
@@ -0,0 +1,222 @@
1
+ 'use strict';
2
+
3
+ var _defineProperty = require('@babel/runtime/helpers/defineProperty');
4
+ var baseControllers = require('@toruslabs/base-controllers');
5
+ var auth = require('@web3auth/auth');
6
+ var log = require('loglevel');
7
+ var constants = require('../utils/constants.js');
8
+
9
+ class PendingTransactionTracker extends auth.SafeEventEmitter {
10
+ constructor({
11
+ provider,
12
+ nonceTracker,
13
+ approveTransaction,
14
+ publishTransaction,
15
+ getPendingTransactions,
16
+ getConfirmedTransactions
17
+ }) {
18
+ super();
19
+ _defineProperty(this, "DROPPED_BUFFER_COUNT", 3);
20
+ _defineProperty(this, "nonceTracker", void 0);
21
+ _defineProperty(this, "provider", void 0);
22
+ _defineProperty(this, "approveTransaction", void 0);
23
+ _defineProperty(this, "droppedBlocksBufferByHash", void 0);
24
+ _defineProperty(this, "getConfirmedTransactions", void 0);
25
+ _defineProperty(this, "getPendingTransactions", void 0);
26
+ _defineProperty(this, "publishTransaction", void 0);
27
+ this.provider = provider;
28
+ this.nonceTracker = nonceTracker;
29
+ this.approveTransaction = approveTransaction;
30
+ this.publishTransaction = publishTransaction;
31
+ this.getPendingTransactions = getPendingTransactions;
32
+ this.getConfirmedTransactions = getConfirmedTransactions;
33
+ this.droppedBlocksBufferByHash = new Map();
34
+ }
35
+
36
+ /**
37
+ checks the network for signed txs and releases the nonce global lock if it is
38
+ */
39
+ async updatePendingTxs() {
40
+ // in order to keep the nonceTracker accurate we block it while updating pending transactions
41
+ const nonceGlobalLock = await this.nonceTracker.getGlobalLock();
42
+ try {
43
+ const pendingTxs = this.getPendingTransactions();
44
+ await Promise.all(pendingTxs.map(txMeta => this._checkPendingTx(txMeta)));
45
+ } catch (error) {
46
+ log.error("PendingTransactionTracker - Error updating pending transactions");
47
+ log.error(error);
48
+ }
49
+ nonceGlobalLock.releaseLock();
50
+ }
51
+ async resubmitPendingTxs(block) {
52
+ const pending = this.getPendingTransactions();
53
+ // only try resubmitting if their are transactions to resubmit
54
+ if (pending.length === 0) return;
55
+ // Keep this as a for loop because we want to wait for each item to be submitted
56
+ for (const txMeta of pending) {
57
+ try {
58
+ await this._resubmitTx(txMeta, block.idempotencyKey);
59
+ } catch (error) {
60
+ var _value;
61
+ /*
62
+ Dont marked as failed if the error is a "known" transaction warning
63
+ "there is already a transaction with the same sender-nonce
64
+ but higher/same gas price"
65
+ Also don't mark as failed if it has ever been broadcast successfully.
66
+ A successful broadcast means it may still be mined.
67
+ */
68
+ const errorMessage = ((_value = error.value) === null || _value === void 0 || (_value = _value.message) === null || _value === void 0 ? void 0 : _value.toLowerCase()) || error.message.toLowerCase();
69
+ const isKnownTx =
70
+ // geth
71
+ errorMessage.includes("replacement transaction underpriced") || errorMessage.includes("known transaction") ||
72
+ // parity
73
+ errorMessage.includes("gas price too low to replace") || errorMessage.includes("transaction with the same hash was already imported") ||
74
+ // other
75
+ errorMessage.includes("gateway timeout") || errorMessage.includes("nonce too low");
76
+ // ignore resubmit warnings, return early
77
+ if (isKnownTx) return;
78
+ // encountered real error - transition to error state
79
+ txMeta.warning = {
80
+ error: errorMessage,
81
+ message: "There was an error when resubmitting this transaction."
82
+ };
83
+ this.emit(baseControllers.TX_EVENTS.TX_WARNING, {
84
+ txMeta,
85
+ txId: txMeta.id
86
+ });
87
+ }
88
+ }
89
+ }
90
+ async _resubmitTx(txMeta, latestBlockNumber) {
91
+ if (!txMeta.firstRetryBlockNumber) {
92
+ this.emit(baseControllers.TX_EVENTS.TX_BLOCK_UPDATE, {
93
+ txMeta,
94
+ latestBlockNumber,
95
+ txId: txMeta.id
96
+ });
97
+ }
98
+ const firstRetryBlockNumber = txMeta.firstRetryBlockNumber || latestBlockNumber;
99
+ const txBlockDistance = Number.parseInt(latestBlockNumber, 16) - Number.parseInt(firstRetryBlockNumber, 16);
100
+ const retryCount = txMeta.retryCount || 0;
101
+
102
+ // Exponential backoff to limit retries at publishing (capped at last 15 mins)
103
+ if (txBlockDistance <= Math.min(50, 2 ** retryCount)) return undefined;
104
+
105
+ // Only auto-submit already-signed txs:
106
+ if (!("rawTransaction" in txMeta)) return this.approveTransaction(txMeta.id);
107
+ const {
108
+ rawTransaction
109
+ } = txMeta;
110
+ const txHash = await this.publishTransaction(rawTransaction);
111
+
112
+ // Increment successful tries:
113
+ this.emit(baseControllers.TX_EVENTS.TX_RETRY, {
114
+ txMeta,
115
+ txId: txMeta.id
116
+ });
117
+ return txHash;
118
+ }
119
+ async _checkPendingTx(foundTx) {
120
+ const txMeta = foundTx;
121
+ const txHash = txMeta.transactionHash;
122
+ const txId = txMeta.id;
123
+
124
+ // Only check submitted txs
125
+ if (txMeta.status !== baseControllers.TransactionStatus.submitted) return;
126
+
127
+ // extra check in case there was an uncaught error during the
128
+ // signature and submission process
129
+ if (!txHash) {
130
+ const noTxHashError = new Error("We had an error while submitting this transaction, please try again.");
131
+ noTxHashError.name = "NoTxHashError";
132
+ this.emit(baseControllers.TX_EVENTS.TX_FAILED, {
133
+ txId,
134
+ error: noTxHashError
135
+ });
136
+ return;
137
+ }
138
+
139
+ // If another tx with the same nonce is mined, set as failed.
140
+ if (this._checkIfNonceIsTaken(txMeta)) {
141
+ this.emit(baseControllers.TX_EVENTS.TX_DROPPED, {
142
+ txId
143
+ });
144
+ return;
145
+ }
146
+ try {
147
+ const transactionReceipt = await this.provider.request({
148
+ method: constants.METHOD_TYPES.ETH_GET_TRANSACTION_RECEIPT,
149
+ params: [txHash]
150
+ });
151
+ if (transactionReceipt !== null && transactionReceipt !== void 0 && transactionReceipt.blockNumber) {
152
+ const {
153
+ baseFeePerGas,
154
+ timestamp
155
+ } = await this.provider.request({
156
+ method: constants.METHOD_TYPES.ETH_GET_BLOCK_BY_HASH,
157
+ params: [transactionReceipt.blockHash, false]
158
+ });
159
+ this.emit(baseControllers.TX_EVENTS.TX_CONFIRMED, {
160
+ txId,
161
+ txReceipt: transactionReceipt,
162
+ baseFeePerGas,
163
+ blockTimestamp: timestamp
164
+ });
165
+ return;
166
+ }
167
+ } catch (error) {
168
+ log.error("error while loading tx", error);
169
+ txMeta.warning = {
170
+ error: error.message,
171
+ message: "There was a problem loading this transaction."
172
+ };
173
+ this.emit(baseControllers.TX_EVENTS.TX_WARNING, {
174
+ txMeta,
175
+ txId
176
+ });
177
+ }
178
+ if (await this._checkIfTxWasDropped(txMeta)) {
179
+ this.emit(baseControllers.TX_EVENTS.TX_DROPPED, {
180
+ txId
181
+ });
182
+ }
183
+ }
184
+ async _checkIfTxWasDropped(txMeta) {
185
+ const {
186
+ transactionHash: txHash,
187
+ transaction: {
188
+ nonce,
189
+ from
190
+ }
191
+ } = txMeta;
192
+ const networkNextNonce = await this.provider.request({
193
+ method: constants.METHOD_TYPES.ETH_GET_TRANSACTION_COUNT,
194
+ params: [from, "latest"]
195
+ });
196
+ if (Number.parseInt(nonce, 16) >= Number.parseInt(networkNextNonce, 16)) {
197
+ return false;
198
+ }
199
+ if (!this.droppedBlocksBufferByHash.has(txHash)) {
200
+ this.droppedBlocksBufferByHash.set(txHash, 0);
201
+ }
202
+ const currentBlockBuffer = this.droppedBlocksBufferByHash.get(txHash);
203
+ if (currentBlockBuffer < this.DROPPED_BUFFER_COUNT) {
204
+ this.droppedBlocksBufferByHash.set(txHash, currentBlockBuffer + 1);
205
+ return false;
206
+ }
207
+ this.droppedBlocksBufferByHash.delete(txHash);
208
+ return true;
209
+ }
210
+ _checkIfNonceIsTaken(txMeta) {
211
+ const address = txMeta.transaction.from;
212
+ const completed = this.getConfirmedTransactions(address);
213
+ return completed.some(otherMeta => {
214
+ if (otherMeta.id === txMeta.id) {
215
+ return false;
216
+ }
217
+ return otherMeta.transaction.nonce === txMeta.transaction.nonce;
218
+ });
219
+ }
220
+ }
221
+
222
+ exports.PendingTransactionTracker = PendingTransactionTracker;