@metamask/smart-transactions-controller 16.0.1 → 16.2.0
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.
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# Changelog
|
|
2
|
+
|
|
2
3
|
All notable changes to this project will be documented in this file.
|
|
3
4
|
|
|
4
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
@@ -6,26 +7,58 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
6
7
|
|
|
7
8
|
## [Unreleased]
|
|
8
9
|
|
|
10
|
+
## [16.2.0]
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Added multi-chain smart transaction support ([#498](https://github.com/MetaMask/smart-transactions-controller/pull/498))
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- Improve changelog linting to prevent formatting issues ([#502](https://github.com/MetaMask/smart-transactions-controller/pull/502))
|
|
19
|
+
|
|
20
|
+
## [16.1.0]
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- Add Base Sentinel endpoint to STX controller ([#500](https://github.com/MetaMask/smart-transactions-controller/pull/500))
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- Add workflow_dispatch to security-code-scanner ([#499](https://github.com/MetaMask/smart-transactions-controller/pull/499))
|
|
29
|
+
- SmartTransactionsController `state` should persist ([#493](https://github.com/MetaMask/smart-transactions-controller/pull/493))
|
|
30
|
+
After opening your browser smart transactions should be preserved.
|
|
31
|
+
|
|
9
32
|
## [16.0.1]
|
|
33
|
+
|
|
10
34
|
### Fixed
|
|
35
|
+
|
|
11
36
|
- Extend definition of when a regular tx is marked as failed based on a smart transaction status, clean up unsupported statuses ([#485](https://github.com/MetaMask/smart-transactions-controller/pull/485))
|
|
12
37
|
|
|
13
38
|
## [16.0.0]
|
|
39
|
+
|
|
14
40
|
### Changed
|
|
41
|
+
|
|
15
42
|
- **BREAKING** Update `@metamask/transaction-controller` peer dependency from `^38.0.0` to `^42.0.0` ([#482](https://github.com/MetaMask/smart-transactions-controller/pull/482))
|
|
16
43
|
|
|
17
44
|
### Removed
|
|
45
|
+
|
|
18
46
|
- **BREAKING** Remove exports for `AllowedActions` and `AllowedEvents` types ([#482](https://github.com/MetaMask/smart-transactions-controller/pull/482))
|
|
19
47
|
|
|
20
48
|
## [15.1.0]
|
|
49
|
+
|
|
21
50
|
### Changed
|
|
51
|
+
|
|
22
52
|
- Update constants.ts to add a BSC url for smart transactions ([#483](https://github.com/MetaMask/smart-transactions-controller/pull/483))
|
|
23
53
|
|
|
24
54
|
### Removed
|
|
55
|
+
|
|
25
56
|
- Remove unnecessary `events` dependency ([#473](https://github.com/MetaMask/smart-transactions-controller/pull/473))
|
|
26
57
|
|
|
27
58
|
## [15.0.0]
|
|
59
|
+
|
|
28
60
|
### Changed
|
|
61
|
+
|
|
29
62
|
- **BREAKING**: Recategorize controllers as peer dependencies ([#472](https://github.com/MetaMask/smart-transactions-controller/pull/472))
|
|
30
63
|
- The following packages have been removed as dependencies, and added as peer dependencies:
|
|
31
64
|
- `@metamask/network-controller@^22.0.0`
|
|
@@ -39,7 +72,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
39
72
|
- Bump `@metamask/eth-json-rpc-provider` from `^4.1.0` to `^4.1.6` ([#460](https://github.com/MetaMask/smart-transactions-controller/pull/460))
|
|
40
73
|
|
|
41
74
|
## [14.0.0]
|
|
75
|
+
|
|
42
76
|
### Changed
|
|
77
|
+
|
|
43
78
|
- **BREAKING** Update `@metamask/polling-controller` from `^8.0.0` to `^11.0.0` ([#448](https://github.com/MetaMask/smart-transactions-controller/pull/448))
|
|
44
79
|
- `startPollingByNetworkClientId` has been renamed to `startPolling`, accepting a `SmartTransactionsControllerPollingInput` object instead of a string as argument.
|
|
45
80
|
- Update `@metamask/transaction-controller` from `^34.0.0` to `^37.3.0` ([#446](https://github.com/MetaMask/smart-transactions-controller/pull/446))
|
|
@@ -47,18 +82,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
47
82
|
- Update `@metamask/network-controller` from `^20.0.0` to `^21.1.0` ([#447](https://github.com/MetaMask/smart-transactions-controller/pull/447))
|
|
48
83
|
|
|
49
84
|
## [13.2.0]
|
|
85
|
+
|
|
50
86
|
### Added
|
|
87
|
+
|
|
51
88
|
- Add metrics events for Receive and Request ([#429](https://github.com/MetaMask/smart-transactions-controller/pull/429))
|
|
52
89
|
- Add `ReceiveRequest` variant to `MetaMetricsEvents` enum
|
|
53
90
|
- Add `Navigation` variant to `MetaMetricsEventCategory` enum
|
|
54
91
|
|
|
55
92
|
## [13.1.0]
|
|
93
|
+
|
|
56
94
|
### Changed
|
|
95
|
+
|
|
57
96
|
- Emit a new "smartTransactionConfirmationDone" event ([#424](https://github.com/MetaMask/smart-transactions-controller/pull/424))
|
|
58
97
|
- Use a new API (Sentinel) for a health check ([#411](https://github.com/MetaMask/smart-transactions-controller/pull/411))
|
|
59
98
|
|
|
60
99
|
## [13.0.0]
|
|
100
|
+
|
|
61
101
|
### Changed
|
|
102
|
+
|
|
62
103
|
- **BREAKING:** Updated `SmartTransactionsController` to inherit from `StaticIntervalPollingController` instead of `StaticIntervalPollingControllerV1` ([#397](https://github.com/MetaMask/smart-transactions-controller/pull/397)).
|
|
63
104
|
- The constructor for `SmartTransactionsController` now accepts a single options object instead of three separate arguments, with configuration options merged into this object.
|
|
64
105
|
- `SmartTransactionsController` now requires a `messenger` option (with the corresponding type `SmartTransactionsControllerMessenger` now available).
|
|
@@ -70,75 +111,105 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
70
111
|
- Added and exported the following types: `SmartTransactionsControllerMessenger`, `SmartTransactionsControllerState`, `SmartTransactionsControllerGetStateAction`, `SmartTransactionsControllerActions`, `SmartTransactionsControllerStateChangeEvent`, `SmartTransactionsControllerSmartTransactionEvent`, and `SmartTransactionsControllerEvents`.
|
|
71
112
|
|
|
72
113
|
## [12.0.1]
|
|
114
|
+
|
|
73
115
|
### Changed
|
|
116
|
+
|
|
74
117
|
- Remove logic for ensuring uniqueness of smart transactions ([#404](https://github.com/MetaMask/smart-transactions-controller/pull/404))
|
|
75
118
|
- This issue has been resolved in production.
|
|
76
119
|
|
|
77
120
|
### Fixed
|
|
121
|
+
|
|
78
122
|
- Fix issue where this.ethQuery is sometimes unexpectedly undefined ([#405](https://github.com/MetaMask/smart-transactions-controller/pull/405))
|
|
79
123
|
|
|
80
124
|
## [12.0.0]
|
|
125
|
+
|
|
81
126
|
### Changed
|
|
127
|
+
|
|
82
128
|
- Upgrade @metamask/network-controller from 19.0.0 to 20.0.0 ([#395](https://github.com/MetaMask/smart-transactions-controller/pull/395))
|
|
83
129
|
- **BREAKING**: Removed providerConfig from state and provider object from constructor parameters. Instead provider object will be used from selected network client. ([#395](https://github.com/MetaMask/smart-transactions-controller/pull/395))
|
|
84
130
|
|
|
85
131
|
## [11.0.0]
|
|
132
|
+
|
|
86
133
|
### Changed
|
|
134
|
+
|
|
87
135
|
- adapt to eip-1193 provider changes ([#384](https://github.com/MetaMask/smart-transactions-controller/pull/384))
|
|
88
136
|
- **BREAKING**: Save new event props to a newly created smart transaction, use both `properties` and `sensitiveProperties` for events. ([#386](https://github.com/MetaMask/smart-transactions-controller/pull/386))([#390](https://github.com/MetaMask/smart-transactions-controller/pull/390))
|
|
89
137
|
|
|
90
138
|
## [10.2.0]
|
|
139
|
+
|
|
91
140
|
### Changed
|
|
141
|
+
|
|
92
142
|
- Update metrics, so events work even for non-swaps transactions ([#374](https://github.com/MetaMask/smart-transactions-controller/pull/374))
|
|
93
143
|
- Update @metamask/transaction-controller from 32.0.0 to 34.0.0 ([#371](https://github.com/MetaMask/smart-transactions-controller/pull/371))
|
|
94
144
|
- Update braces from 3.0.2 to 3.0.3 and remove the `--immutable-cache` flag in a build file ([#367](https://github.com/MetaMask/smart-transactions-controller/pull/367))
|
|
95
145
|
|
|
96
146
|
## [10.1.6]
|
|
147
|
+
|
|
97
148
|
### Changed
|
|
149
|
+
|
|
98
150
|
- Update @metamask/transaction-controller from 29.1.0 to 32.0.0 ([#348](https://github.com/MetaMask/smart-transactions-controller/pull/348))
|
|
99
151
|
|
|
100
152
|
## [10.1.5]
|
|
153
|
+
|
|
101
154
|
### Changed
|
|
155
|
+
|
|
102
156
|
- Update @metamask/polling-controller from 6.0.2 to 8.0.0 ([#352](https://github.com/MetaMask/smart-transactions-controller/pull/352))
|
|
103
157
|
|
|
104
158
|
## [10.1.4]
|
|
159
|
+
|
|
105
160
|
### Changed
|
|
161
|
+
|
|
106
162
|
- Update @metamask/network-controller from 18.1.1 to 19.0.0 ([#349](https://github.com/MetaMask/smart-transactions-controller/pull/349))
|
|
107
163
|
- Update @metamask/base-controller from 5.0.2 to 6.0.0 ([#351](https://github.com/MetaMask/smart-transactions-controller/pull/351))
|
|
108
164
|
|
|
109
165
|
## [10.1.3]
|
|
166
|
+
|
|
110
167
|
### Changed
|
|
168
|
+
|
|
111
169
|
- Update jest from v26 to v29, ts-jest from v26 to v29 and nock from v13 to v14 ([#325](https://github.com/MetaMask/smart-transactions-controller/pull/325))
|
|
112
170
|
|
|
113
171
|
## [10.1.2]
|
|
172
|
+
|
|
114
173
|
### Fixed
|
|
174
|
+
|
|
115
175
|
- fix: Improve state management to ensure unique smart transactions in a rare edge case. This will be removed in a future version once we have confirmed this is resolved. ([#353](https://github.com/MetaMask/smart-transactions-controller/pull/353))
|
|
116
176
|
- Bring release instructions in README up to date ([#354](https://github.com/MetaMask/smart-transactions-controller/pull/354))
|
|
117
177
|
|
|
118
178
|
## [10.1.1]
|
|
179
|
+
|
|
119
180
|
### Fixed
|
|
181
|
+
|
|
120
182
|
- Call the "poll" function only once on a network switch ([#348](https://github.com/MetaMask/smart-transactions-controller/pull/348))
|
|
121
183
|
- Update `@metamask/transaction-controller` from `^29.1.0` to `^30.0.0` ([#342](https://github.com/MetaMask/smart-transactions-controller/pull/342))
|
|
122
184
|
|
|
123
185
|
## [10.1.0]
|
|
186
|
+
|
|
124
187
|
### Changed
|
|
188
|
+
|
|
125
189
|
- Update `@metamask/transaction-controller` from `^28.1.0` to `^29.1.0` ([#339](https://github.com/MetaMask/smart-transactions-controller/pull/339))
|
|
126
190
|
|
|
127
191
|
## [10.0.1]
|
|
192
|
+
|
|
128
193
|
### Fixed
|
|
194
|
+
|
|
129
195
|
- Emit an event with an updated Smart Transaction before confirmation ([#333](https://github.com/MetaMask/smart-transactions-controller/pull/333))
|
|
130
196
|
|
|
131
197
|
## [10.0.0]
|
|
198
|
+
|
|
132
199
|
### Fixed
|
|
200
|
+
|
|
133
201
|
- **BREAKING**: Flip the behavior of the `wipeSmartTransactions` method's `ignoreNetwork` option ([#323](https://github.com/MetaMask/smart-transactions-controller/pull/323))
|
|
134
202
|
- Passing `false` will now wipe transactions for the globally selected chain, and passing `true` will now wipe transactions from each chain stored in state, instead of the other way around
|
|
135
203
|
|
|
136
204
|
## [9.0.0]
|
|
205
|
+
|
|
137
206
|
### Added
|
|
207
|
+
|
|
138
208
|
- Add Sepolia support ([#316](https://github.com/MetaMask/smart-transactions-controller/pull/316))
|
|
139
209
|
- Add function `wipeSmartTransactions` to clear all state for a given address (needs to be supplied in all-lowercase) ([#316](https://github.com/MetaMask/smart-transactions-controller/pull/316))
|
|
140
210
|
|
|
141
211
|
### Changed
|
|
212
|
+
|
|
142
213
|
- Update `@metamask/base-controller` from `^4.1.1` to `^5.0.1` ([#296](https://github.com/MetaMask/smart-transactions-controller/pull/296))
|
|
143
214
|
- Update `@metamask/controller-utils` from `^8.0.3` to `^9.1.0` ([#318](https://github.com/MetaMask/smart-transactions-controller/pull/318))
|
|
144
215
|
- Update `@metamask/network-controller` from `^17.2.0` to `^18.1.0` ([#310](https://github.com/MetaMask/smart-transactions-controller/pull/310))
|
|
@@ -146,21 +217,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
146
217
|
- Update `@metamask/transaction-controller` from `^25.1.0` to `^28.1.0` ([#319](https://github.com/MetaMask/smart-transactions-controller/pull/319))
|
|
147
218
|
|
|
148
219
|
### Removed
|
|
220
|
+
|
|
149
221
|
- **BREAKING**: Remove Goerli support ([#316](https://github.com/MetaMask/smart-transactions-controller/pull/316))
|
|
150
222
|
|
|
151
223
|
## [8.1.0]
|
|
224
|
+
|
|
152
225
|
### Changed
|
|
226
|
+
|
|
153
227
|
- Update a URL for transaction-api from `https://transaction.metaswap.codefi.network` to `https://transaction.api.cx.metamask.io`, since we shouldn't be using `codefi.network` anymore ([#314](https://github.com/MetaMask/smart-transactions-controller/pull/314))
|
|
154
228
|
- Add a new function called `getSmartTransactionByMinedTxHash`, which can be used to get a smart transaction by its `minedHash` prop ([#314](https://github.com/MetaMask/smart-transactions-controller/pull/314))
|
|
155
229
|
- Add new props on the `SmartTransactionsStatus` type, so they can be used e.g. as event props ([#314](https://github.com/MetaMask/smart-transactions-controller/pull/314))
|
|
156
230
|
|
|
157
231
|
## [8.0.0]
|
|
232
|
+
|
|
158
233
|
### Changed
|
|
234
|
+
|
|
159
235
|
- **BREAKING:** The constructor now requires a `getTransactions` option, which can be used to get a list of existing transactions ([#301](https://github.com/MetaMask/smart-transactions-controller/pull/301))
|
|
160
236
|
- Ensure that a transaction does not get re-confirmed if it is already confirmed or submitted. MetaMask Swaps are confirmed from this controller, other transaction types are most of the time confirmed from the TransactionController. ([#301](https://github.com/MetaMask/smart-transactions-controller/pull/301))
|
|
161
237
|
|
|
162
238
|
## [7.0.0]
|
|
239
|
+
|
|
163
240
|
### Added
|
|
241
|
+
|
|
164
242
|
- **BREAKING:** Track fees and liveness for multiple chains by adding `feesByChainId` and `livenessByChainId` properties to SmartTransactionsControllerState ([#237](https://github.com/MetaMask/smart-transactions-controller/pull/237))
|
|
165
243
|
- In particular, clients should prefer accessing `feesByChainId` and `livenessByChainId` instead of `fees` and `liveness`, which will be removed in a future major version.
|
|
166
244
|
- `SmartTransactionsController` now inherits from `StaticIntervalPollingControllerV1` ([#237](https://github.com/MetaMask/smart-transactions-controller/pull/237), [#265](https://github.com/MetaMask/smart-transactions-controller/pull/265))
|
|
@@ -188,6 +266,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
188
266
|
- This occurs after transactions are submitted, after they are confirmed, after statuses are updated, and also explicitly via `updateSmartTransaction`.
|
|
189
267
|
|
|
190
268
|
### Changed
|
|
269
|
+
|
|
191
270
|
- **BREAKING**: Bump `@metamask/network-controller` from `^15.0.0` to `^17.0.0` ([#238](https://github.com/MetaMask/smart-transactions-controller/pull/238) [#241](https://github.com/MetaMask/smart-transactions-controller/pull/241))
|
|
192
271
|
- This is breaking because the type of the `messenger` has backward-incompatible changes. See the changelog for `@metamask/base-controller@4.0.0` for more.
|
|
193
272
|
- **BREAKING**: The set of supported chains (configurable via `supportedChainIds`) now defaults to including Goerli instead of Rinkeby ([#237](https://github.com/MetaMask/smart-transactions-controller/pull/237))
|
|
@@ -207,9 +286,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
207
286
|
- Deprecate `time` property on `SmartTransaction` type in favor of `creationTime` ([#298](https://github.com/MetaMask/smart-transactions-controller/pull/298))
|
|
208
287
|
|
|
209
288
|
### Removed
|
|
289
|
+
|
|
210
290
|
- **BREAKING:** Remove property `ethersProvider` from `SmartTransactionsController` ([#237](https://github.com/MetaMask/smart-transactions-controller/pull/237))
|
|
211
291
|
|
|
212
292
|
### Fixed
|
|
293
|
+
|
|
213
294
|
- Fix `getFees` so that it does not blow away an existing `nonce` on the trade transaction ([#271](https://github.com/MetaMask/smart-transactions-controller/pull/271))
|
|
214
295
|
- Fix `submitSignedTransactions` so that it sets a `nonce` on the resulting transaction if it doesn't have one ([#271](https://github.com/MetaMask/smart-transactions-controller/pull/271))
|
|
215
296
|
- Fix updating a smart transaction to no longer throw when no smart transactions have been previously saved under the current chain ([#271](https://github.com/MetaMask/smart-transactions-controller/pull/271))
|
|
@@ -220,49 +301,66 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
220
301
|
- This change may cause errors to be thrown immediately following a network switch until a future NetworkController state update or polling iteration.
|
|
221
302
|
|
|
222
303
|
## [6.2.2]
|
|
304
|
+
|
|
223
305
|
### Fixed
|
|
306
|
+
|
|
224
307
|
- Revert "Parameterize SmartTransactionsController state by ChainId for MultiChain + Integrate PollingController Mixin ([#235](https://github.com/MetaMask/smart-transactions-controller/pull/235))
|
|
225
308
|
|
|
226
309
|
## [6.2.1] [DEPRECATED]
|
|
310
|
+
|
|
227
311
|
### Fixed
|
|
312
|
+
|
|
228
313
|
- Fix a typo in a URL for submitting transactions ([#230](https://github.com/MetaMask/smart-transactions-controller/pull/230))
|
|
229
314
|
|
|
230
315
|
## [6.2.0] [DEPRECATED]
|
|
316
|
+
|
|
231
317
|
### Added
|
|
318
|
+
|
|
232
319
|
- Pass current version of this package to API when submitting transactions ([#227](https://github.com/MetaMask/smart-transactions-controller/pull/227))
|
|
233
320
|
|
|
234
321
|
## [6.1.0] [DEPRECATED]
|
|
322
|
+
|
|
235
323
|
### Added
|
|
324
|
+
|
|
236
325
|
- Add a new "userOptInV2" prop ([#222](https://github.com/MetaMask/smart-transactions-controller/pull/222))
|
|
237
326
|
|
|
238
327
|
### Changed
|
|
328
|
+
|
|
239
329
|
- Bump @metamask/network-controller from 15.0.0 to 15.1.0 ([#219](https://github.com/MetaMask/smart-transactions-controller/pull/219))
|
|
240
330
|
|
|
241
331
|
## [6.0.0] [DEPRECATED]
|
|
332
|
+
|
|
242
333
|
### Added
|
|
334
|
+
|
|
243
335
|
- **BREAKING:** `getNetworkClientById` is now required argument in constructor options object ([#210](https://github.com/MetaMask/smart-transactions-controller/pull/210))
|
|
244
336
|
- Integrate `PollingController` mixin and `_executePoll` method used for concurrent multichain polling ([#210](https://github.com/MetaMask/smart-transactions-controller/pull/210))
|
|
245
337
|
- Consumers can now call `startPollingByNetworkClientId` with a networkClientId to start polling for a specific chain and `stopPollingByPollingToken` with the returned pollingToken to stop polling for that chain.
|
|
246
338
|
|
|
247
339
|
### Changed
|
|
340
|
+
|
|
248
341
|
- **BREAKING**: Bump `@metamask/network-controller` from ^13.0.1 to ^15.0.0 ([#211](https://github.com/MetaMask/smart-transactions-controller/pull/211))
|
|
249
342
|
- **BREAKING**: Replace `@ethersproject/providers` with `@metamask/eth-query` ([#210](https://github.com/MetaMask/smart-transactions-controller/pull/210))
|
|
250
343
|
- Remove `@ethersproject/bignumber` ([#210](https://github.com/MetaMask/smart-transactions-controller/pull/210))
|
|
251
344
|
- Add optional options object containing a `networkClientId` argument to the `updateSmartTransaction` method ([#210](https://github.com/MetaMask/smart-transactions-controller/pull/210))
|
|
252
345
|
|
|
253
346
|
## [5.0.0]
|
|
347
|
+
|
|
254
348
|
### Changed
|
|
349
|
+
|
|
255
350
|
- Bump dependency on `@metamask/network-controller` to ^13.0.0 ([#191](https://github.com/MetaMask/smart-transactions-controller/pull/191))
|
|
256
351
|
- Bump dependency on `@metamask/base-controller` to ^3.2.1 ([#191](https://github.com/MetaMask/smart-transactions-controller/pull/191))
|
|
257
352
|
- Bump dependency on `@metamask/controller-utils` to ^5.0.0 ([#191](https://github.com/MetaMask/smart-transactions-controller/pull/191))
|
|
258
353
|
|
|
259
354
|
### Removed
|
|
355
|
+
|
|
260
356
|
- **BREAKING:** Remove `metamaskNetworkId` from smart transaction state ([#191](https://github.com/MetaMask/smart-transactions-controller/pull/191))
|
|
261
357
|
- To migrate, remove references to `TransactionMeta.metamaskNetworkId` and `TransactionMeta.history.metamaskNetworkId`
|
|
262
358
|
- Remove `getNetwork` from constructor options ([#191](https://github.com/MetaMask/smart-transactions-controller/pull/191))
|
|
263
359
|
|
|
264
360
|
## [4.0.0]
|
|
361
|
+
|
|
265
362
|
### Changed
|
|
363
|
+
|
|
266
364
|
- **BREAKING**: Bump minimum Node.js version to v16 ([#161](https://github.com/MetaMask/smart-transactions-controller/pull/161))
|
|
267
365
|
- **BREAKING:** Remove `isomorphic-fetch` ([#131](https://github.com/MetaMask/smart-transactions-controller/pull/131))
|
|
268
366
|
- Projects lacking `fetch` will now have to supply their own polyfill.
|
|
@@ -270,23 +368,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
270
368
|
- Move `@types/lodash` to devDependencies ([#141](https://github.com/MetaMask/smart-transactions-controller/pull/141))
|
|
271
369
|
|
|
272
370
|
## [3.1.0]
|
|
371
|
+
|
|
273
372
|
### Changed
|
|
373
|
+
|
|
274
374
|
- Replace use of full `@metamask/controllers` repo with packages from `@metamask/core-monorepo` ([#110](https://github.com/MetaMask/smart-transactions-controller/pull/110), [#112](https://github.com/MetaMask/smart-transactions-controller/pull/112), [#113](https://github.com/MetaMask/smart-transactions-controller/pull/113))
|
|
275
375
|
|
|
276
376
|
## [3.0.0]
|
|
377
|
+
|
|
277
378
|
### Changed
|
|
379
|
+
|
|
278
380
|
- **BREAKING:** Bump required Node version to v14 ([#90](https://github.com/MetaMask/smart-transactions-controller/pull/90))
|
|
279
381
|
- `@metamask/controllers@32.0.2` ([#104](https://github.com/MetaMask/smart-transactions-controller/pull/104))
|
|
280
382
|
|
|
281
383
|
### Fixed
|
|
384
|
+
|
|
282
385
|
- Ensure the nonce lock is always released ([#108](https://github.com/MetaMask/smart-transactions-controller/pull/108))
|
|
283
386
|
|
|
284
387
|
## [2.3.2]
|
|
388
|
+
|
|
285
389
|
### Changed
|
|
390
|
+
|
|
286
391
|
- Replace `ethers` with submodules (@ethersproject/bignumber,@ethersproject/bytes, @ethersproject/providers,) - no functional change ([#95](https://github.com/MetaMask/smart-transactions-controller/pull/95))
|
|
287
392
|
|
|
288
393
|
## [2.3.1]
|
|
394
|
+
|
|
289
395
|
### Changed
|
|
396
|
+
|
|
290
397
|
- Remove unnecessary event props ([#93](https://github.com/MetaMask/smart-transactions-controller/pull/93))
|
|
291
398
|
- Update `is-release` filter ([#91](https://github.com/MetaMask/smart-transactions-controller/pull/91))
|
|
292
399
|
- update is-release filter ([#89](https://github.com/MetaMask/smart-transactions-controller/pull/89))
|
|
@@ -294,57 +401,79 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
294
401
|
- add config for MetaMask/action-npm-publish ([#85](https://github.com/MetaMask/smart-transactions-controller/pull/85))
|
|
295
402
|
|
|
296
403
|
## [2.3.0]
|
|
404
|
+
|
|
297
405
|
### Added
|
|
406
|
+
|
|
298
407
|
- Add the "clearFees" function ([#84](https://github.com/MetaMask/smart-transactions-controller/pull/84))
|
|
299
408
|
|
|
300
409
|
## [2.2.0]
|
|
410
|
+
|
|
301
411
|
### Changed
|
|
412
|
+
|
|
302
413
|
- chore(deps): bump @metamask/controllers from 30.0.0 to 30.1.0 ([#81](https://github.com/MetaMask/smart-transactions-controller/pull/81))
|
|
303
414
|
- chore(deps-dev): bump @metamask/eslint-config-nodejs from 8.0.0 to 9.0.0 ([#80](https://github.com/MetaMask/smart-transactions-controller/pull/80))
|
|
304
415
|
- chore(deps-dev): bump @metamask/auto-changelog from 2.6.0 to 2.6.1 ([#79](https://github.com/MetaMask/smart-transactions-controller/pull/79))
|
|
305
416
|
- Return all error props in an error response ([#82](https://github.com/MetaMask/smart-transactions-controller/pull/82))
|
|
306
417
|
|
|
307
418
|
## [2.1.0]
|
|
419
|
+
|
|
308
420
|
### Added
|
|
421
|
+
|
|
309
422
|
- chore(deps): bump @metamask/controllers from 29.0.1 to 30.0.0 ([#75](https://github.com/MetaMask/smart-transactions-controller/pull/75))
|
|
310
423
|
- chore(deps-dev): bump @metamask/auto-changelog from 2.5.0 to 2.6.0 ([#71](https://github.com/MetaMask/smart-transactions-controller/pull/71))
|
|
311
424
|
- Return a pending status for a cancelled tx that hasn't been settled yet ([#74](https://github.com/MetaMask/smart-transactions-controller/pull/74))
|
|
312
425
|
|
|
313
426
|
## [2.0.1]
|
|
427
|
+
|
|
314
428
|
### Changed
|
|
429
|
+
|
|
315
430
|
- Previous version deprecated due to missing build files. No code changes made.
|
|
316
431
|
|
|
317
432
|
## [2.0.0] [DEPRECATED]
|
|
433
|
+
|
|
318
434
|
### Added
|
|
435
|
+
|
|
319
436
|
- "estimateGas" -> "getFees", support a new cancellation reason, refactoring ([#69](https://github.com/MetaMask/smart-transactions-controller/pull/69))
|
|
320
437
|
- chore(deps): bump @metamask/controllers from 28.0.0 to 29.0.1 ([#68](https://github.com/MetaMask/smart-transactions-controller/pull/68))
|
|
321
438
|
- If mined status is not mined and cancel reason not set, then show the cancel link, refactoring ([#66](https://github.com/MetaMask/smart-transactions-controller/pull/66))
|
|
322
439
|
- chore(deps): bump @metamask/controllers from 27.1.1 to 28.0.0 ([#65](https://github.com/MetaMask/smart-transactions-controller/pull/65))
|
|
323
440
|
|
|
324
441
|
## [1.10.0]
|
|
442
|
+
|
|
325
443
|
### Added
|
|
444
|
+
|
|
326
445
|
- Handle the "cancelled" status, lower status polling interval from 10s to 5s, don't mark a tx as cancelled immediately, track uuid ([#63](https://github.com/MetaMask/smart-transactions-controller/pull/63))
|
|
327
446
|
- chore(deps): bump @metamask/controllers from 25.1.0 to 27.1.1 ([#62](https://github.com/MetaMask/smart-transactions-controller/pull/62))
|
|
328
447
|
- Add tracking of the "current_stx_enabled" param ([#58](https://github.com/MetaMask/smart-transactions-controller/pull/58))
|
|
329
448
|
|
|
330
449
|
## [1.9.1]
|
|
450
|
+
|
|
331
451
|
### Added
|
|
452
|
+
|
|
332
453
|
- Use the "confirmExternalTransaction" fn directly ([#56](https://github.com/MetaMask/smart-transactions-controller/pull/56))
|
|
333
454
|
|
|
334
455
|
## [1.9.0]
|
|
456
|
+
|
|
335
457
|
### Added
|
|
458
|
+
|
|
336
459
|
- Only accept the "getNonceLock" fn and not the whole "nonceTracker" ([#54](https://github.com/MetaMask/smart-transactions-controller/pull/54))
|
|
337
460
|
|
|
338
461
|
## [1.8.0]
|
|
462
|
+
|
|
339
463
|
### Added
|
|
464
|
+
|
|
340
465
|
- Do not update an STX which doesn't exist anymore, add UTs ([#52](https://github.com/MetaMask/smart-transactions-controller/pull/52))
|
|
341
466
|
|
|
342
467
|
## [1.7.0]
|
|
468
|
+
|
|
343
469
|
### Added
|
|
470
|
+
|
|
344
471
|
- Fix UTs, change threshold ([#49](https://github.com/MetaMask/smart-transactions-controller/pull/49))
|
|
345
472
|
|
|
346
473
|
## [1.6.0]
|
|
474
|
+
|
|
347
475
|
### Added
|
|
476
|
+
|
|
348
477
|
- Change cancellable interval to be 1 minute ([#47](https://github.com/MetaMask/smart-transactions-controller/pull/47))
|
|
349
478
|
- Estimate approval transaction along with swaps transaction ([#46](https://github.com/MetaMask/smart-transactions-controller/pull/46))
|
|
350
479
|
- chore(deps): bump @metamask/controllers from 20.1.0 to 25.1.0 ([#44](https://github.com/MetaMask/smart-transactions-controller/pull/44))
|
|
@@ -352,11 +481,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
352
481
|
- Add method for estimateGas ([#43](https://github.com/MetaMask/smart-transactions-controller/pull/43))
|
|
353
482
|
|
|
354
483
|
## [1.5.0]
|
|
484
|
+
|
|
355
485
|
### Added
|
|
486
|
+
|
|
356
487
|
- Add "fees" and "liveness" into the smartTransactionsState, update version ([#41](https://github.com/MetaMask/smart-transactions-controller/pull/41))
|
|
357
488
|
|
|
358
489
|
## [1.4.0]
|
|
490
|
+
|
|
359
491
|
### Added
|
|
492
|
+
|
|
360
493
|
- Add isomorphic-fetch to stx controller ([#38](https://github.com/MetaMask/smart-transactions-controller/pull/38))
|
|
361
494
|
- feat: create new handleFetch with custom error handling ([#35](https://github.com/MetaMask/smart-transactions-controller/pull/35))
|
|
362
495
|
- Unblock submit if ethers errors ([#30](https://github.com/MetaMask/smart-transactions-controller/pull/30))
|
|
@@ -367,18 +500,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
367
500
|
- Switch license with MetaMask license ([#25](https://github.com/MetaMask/smart-transactions-controller/pull/25))
|
|
368
501
|
|
|
369
502
|
## [1.3.0]
|
|
503
|
+
|
|
370
504
|
### Added
|
|
505
|
+
|
|
371
506
|
- Use the production version of the Transaction APIs repo ([#37](https://github.com/MetaMask/smart-transactions-controller/pull/37))
|
|
372
507
|
|
|
373
508
|
## [1.2.0]
|
|
509
|
+
|
|
374
510
|
### Added
|
|
511
|
+
|
|
375
512
|
- Add more unit tests for SmartTransactionsController ([#23](https://github.com/MetaMask/smart-transactions-controller/pull/23))
|
|
376
513
|
- chore(deps): bump @metamask/controllers from 16.0.0 to 19.0.0 ([#18](https://github.com/MetaMask/smart-transactions-controller/pull/18))
|
|
377
514
|
- Add cancelled status to stx after successful cancel request ([#21](https://github.com/MetaMask/smart-transactions-controller/pull/21))
|
|
378
515
|
- 1.1.0 ([#22](https://github.com/MetaMask/smart-transactions-controller/pull/22))
|
|
379
516
|
|
|
380
517
|
## [1.1.0]
|
|
518
|
+
|
|
381
519
|
### Added
|
|
520
|
+
|
|
382
521
|
- Tracking of STX status changes ([#20](https://github.com/MetaMask/smart-transactions-controller/pull/20))
|
|
383
522
|
- Remove cancelled transaction when new trx with same nonce submitted ([#19](https://github.com/MetaMask/smart-transactions-controller/pull/19))
|
|
384
523
|
- chore: modify polling and clean up tests ([#17](https://github.com/MetaMask/smart-transactions-controller/pull/17))
|
|
@@ -387,7 +526,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
387
526
|
- Smart Transactions List ([#13](https://github.com/MetaMask/smart-transactions-controller/pull/13))
|
|
388
527
|
|
|
389
528
|
## [1.0.0]
|
|
529
|
+
|
|
390
530
|
### Added
|
|
531
|
+
|
|
391
532
|
- Adds nonce to a tx, adds `yarn build:link` support, updates functions for API calls, refactoring ([#8](https://github.com/MetaMask/smart-transactions-controller/pull/8))
|
|
392
533
|
- Add many unit tests, support for the batch_status API, refactoring ([#6](https://github.com/MetaMask/smart-transactions-controller/pull/6))
|
|
393
534
|
- Bump @metamask/controllers from 15.1.0 to 16.0.0
|
|
@@ -396,7 +537,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
396
537
|
- Add initial SmartTransactionsController ([#1](https://github.com/MetaMask/smart-transactions-controller/pull/1))
|
|
397
538
|
- Initial commit
|
|
398
539
|
|
|
399
|
-
[Unreleased]: https://github.com/MetaMask/smart-transactions-controller/compare/v16.0
|
|
540
|
+
[Unreleased]: https://github.com/MetaMask/smart-transactions-controller/compare/v16.2.0...HEAD
|
|
541
|
+
[16.2.0]: https://github.com/MetaMask/smart-transactions-controller/compare/v16.1.0...v16.2.0
|
|
542
|
+
[16.1.0]: https://github.com/MetaMask/smart-transactions-controller/compare/v16.0.1...v16.1.0
|
|
400
543
|
[16.0.1]: https://github.com/MetaMask/smart-transactions-controller/compare/v16.0.0...v16.0.1
|
|
401
544
|
[16.0.0]: https://github.com/MetaMask/smart-transactions-controller/compare/v15.1.0...v16.0.0
|
|
402
545
|
[15.1.0]: https://github.com/MetaMask/smart-transactions-controller/compare/v15.0.0...v15.1.0
|
|
@@ -79,7 +79,7 @@ declare type SmartTransactionsControllerOptions = {
|
|
|
79
79
|
updateTransaction: (transaction: TransactionMeta, note: string) => void;
|
|
80
80
|
};
|
|
81
81
|
export declare type SmartTransactionsControllerPollingInput = {
|
|
82
|
-
|
|
82
|
+
chainIds: Hex[];
|
|
83
83
|
};
|
|
84
84
|
declare const SmartTransactionsController_base: (abstract new (...args: any[]) => {
|
|
85
85
|
readonly "__#787890@#intervalIds": Record<string, NodeJS.Timeout>;
|
|
@@ -100,23 +100,25 @@ export default class SmartTransactionsController extends SmartTransactionsContro
|
|
|
100
100
|
#private;
|
|
101
101
|
timeoutHandle?: NodeJS.Timeout;
|
|
102
102
|
constructor({ interval, clientId, chainId: InitialChainId, supportedChainIds, getNonceLock, confirmExternalTransaction, trackMetaMetricsEvent, state, messenger, getTransactions, getMetaMetricsProps, getFeatureFlags, updateTransaction, }: SmartTransactionsControllerOptions);
|
|
103
|
-
_executePoll({
|
|
103
|
+
_executePoll({ chainIds, }: SmartTransactionsControllerPollingInput): Promise<void>;
|
|
104
104
|
checkPoll({ smartTransactionsState: { smartTransactions }, }: SmartTransactionsControllerState): void;
|
|
105
105
|
initializeSmartTransactionsForChainId(): void;
|
|
106
106
|
poll(interval?: number): Promise<void>;
|
|
107
107
|
stop(): Promise<void>;
|
|
108
108
|
setOptInState(optInState: boolean | null): void;
|
|
109
109
|
trackStxStatusChange(smartTransaction: SmartTransaction, prevSmartTransaction?: SmartTransaction): void;
|
|
110
|
-
isNewSmartTransaction(smartTransactionUuid: string): boolean;
|
|
110
|
+
isNewSmartTransaction(smartTransactionUuid: string, chainId?: Hex): boolean;
|
|
111
111
|
updateSmartTransaction(smartTransaction: SmartTransaction, { networkClientId }?: {
|
|
112
112
|
networkClientId?: NetworkClientId;
|
|
113
113
|
}): void;
|
|
114
|
-
updateSmartTransactions({
|
|
115
|
-
|
|
114
|
+
updateSmartTransactions({ chainIds, }?: {
|
|
115
|
+
chainIds: Hex[];
|
|
116
116
|
}): Promise<void>;
|
|
117
|
-
fetchSmartTransactionsStatus(
|
|
117
|
+
fetchSmartTransactionsStatus(transactions: {
|
|
118
|
+
uuid: string;
|
|
118
119
|
networkClientId?: NetworkClientId;
|
|
119
|
-
|
|
120
|
+
chainId: Hex;
|
|
121
|
+
}[]): Promise<Record<string, SmartTransactionsStatus>>;
|
|
120
122
|
clearFees(): Fees;
|
|
121
123
|
getFees(tradeTx: UnsignedTransaction, approvalTx?: UnsignedTransaction, { networkClientId }?: {
|
|
122
124
|
networkClientId?: NetworkClientId;
|
|
@@ -13,7 +13,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
13
13
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
14
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
15
|
};
|
|
16
|
-
var _SmartTransactionsController_instances, _SmartTransactionsController_interval, _SmartTransactionsController_clientId, _SmartTransactionsController_chainId, _SmartTransactionsController_supportedChainIds, _SmartTransactionsController_getNonceLock, _SmartTransactionsController_ethQuery, _SmartTransactionsController_confirmExternalTransaction, _SmartTransactionsController_getRegularTransactions, _SmartTransactionsController_trackMetaMetricsEvent, _SmartTransactionsController_getMetaMetricsProps, _SmartTransactionsController_getFeatureFlags, _SmartTransactionsController_updateTransaction, _SmartTransactionsController_fetch, _SmartTransactionsController_updateSmartTransaction, _SmartTransactionsController_addMetaMetricsPropsToNewSmartTransaction, _SmartTransactionsController_createOrUpdateSmartTransaction, _SmartTransactionsController_doesTransactionNeedConfirmation, _SmartTransactionsController_confirmSmartTransaction, _SmartTransactionsController_addNonceToTransaction, _SmartTransactionsController_getChainId, _SmartTransactionsController_getEthQuery, _SmartTransactionsController_getCurrentSmartTransactions, _SmartTransactionsController_wipeSmartTransactionsPerChainId;
|
|
16
|
+
var _SmartTransactionsController_instances, _SmartTransactionsController_interval, _SmartTransactionsController_clientId, _SmartTransactionsController_chainId, _SmartTransactionsController_supportedChainIds, _SmartTransactionsController_getNonceLock, _SmartTransactionsController_ethQuery, _SmartTransactionsController_confirmExternalTransaction, _SmartTransactionsController_getRegularTransactions, _SmartTransactionsController_trackMetaMetricsEvent, _SmartTransactionsController_getMetaMetricsProps, _SmartTransactionsController_getFeatureFlags, _SmartTransactionsController_updateTransaction, _SmartTransactionsController_fetch, _SmartTransactionsController_updateSmartTransaction, _SmartTransactionsController_addMetaMetricsPropsToNewSmartTransaction, _SmartTransactionsController_createOrUpdateSmartTransaction, _SmartTransactionsController_doesTransactionNeedConfirmation, _SmartTransactionsController_confirmSmartTransaction, _SmartTransactionsController_addNonceToTransaction, _SmartTransactionsController_getChainId, _SmartTransactionsController_getChainIds, _SmartTransactionsController_getNetworkClientId, _SmartTransactionsController_getEthQuery, _SmartTransactionsController_getCurrentSmartTransactions, _SmartTransactionsController_wipeSmartTransactionsPerChainId;
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
exports.getDefaultSmartTransactionsControllerState = exports.DEFAULT_INTERVAL = void 0;
|
|
19
19
|
const bytes_1 = require("@ethersproject/bytes");
|
|
@@ -35,7 +35,7 @@ const ETH_QUERY_ERROR_MSG = '`ethQuery` is not defined on SmartTransactionsContr
|
|
|
35
35
|
const controllerName = 'SmartTransactionsController';
|
|
36
36
|
const controllerMetadata = {
|
|
37
37
|
smartTransactionsState: {
|
|
38
|
-
persist:
|
|
38
|
+
persist: true,
|
|
39
39
|
anonymous: true,
|
|
40
40
|
},
|
|
41
41
|
};
|
|
@@ -117,20 +117,20 @@ class SmartTransactionsController extends (0, polling_controller_1.StaticInterva
|
|
|
117
117
|
});
|
|
118
118
|
this.messagingSystem.subscribe(`${controllerName}:stateChange`, (currentState) => this.checkPoll(currentState));
|
|
119
119
|
}
|
|
120
|
-
async _executePoll({
|
|
120
|
+
async _executePoll({ chainIds, }) {
|
|
121
121
|
// if this is going to be truly UI driven polling we shouldn't really reach here
|
|
122
122
|
// with a networkClientId that is not supported, but for now I'll add a check in case
|
|
123
123
|
// wondering if we should add some kind of predicate to the polling controller to check whether
|
|
124
124
|
// we should poll or not
|
|
125
|
-
const
|
|
126
|
-
if (
|
|
125
|
+
const filteredChainIds = (chainIds !== null && chainIds !== void 0 ? chainIds : []).filter((chainId) => __classPrivateFieldGet(this, _SmartTransactionsController_supportedChainIds, "f").includes(chainId));
|
|
126
|
+
if (filteredChainIds.length === 0) {
|
|
127
127
|
return Promise.resolve();
|
|
128
128
|
}
|
|
129
|
-
return this.updateSmartTransactions({
|
|
129
|
+
return this.updateSmartTransactions({ chainIds: filteredChainIds });
|
|
130
130
|
}
|
|
131
131
|
checkPoll({ smartTransactionsState: { smartTransactions }, }) {
|
|
132
|
-
const
|
|
133
|
-
const pendingTransactions =
|
|
132
|
+
const smartTransactionsForAllChains = Object.values(smartTransactions).flat();
|
|
133
|
+
const pendingTransactions = smartTransactionsForAllChains === null || smartTransactionsForAllChains === void 0 ? void 0 : smartTransactionsForAllChains.filter(utils_1.isSmartTransactionPending);
|
|
134
134
|
if (!this.timeoutHandle && (pendingTransactions === null || pendingTransactions === void 0 ? void 0 : pendingTransactions.length) > 0) {
|
|
135
135
|
this.poll();
|
|
136
136
|
}
|
|
@@ -182,9 +182,9 @@ class SmartTransactionsController extends (0, polling_controller_1.StaticInterva
|
|
|
182
182
|
sensitiveProperties: (0, utils_1.getSmartTransactionMetricsSensitiveProperties)(updatedSmartTransaction),
|
|
183
183
|
});
|
|
184
184
|
}
|
|
185
|
-
isNewSmartTransaction(smartTransactionUuid) {
|
|
185
|
+
isNewSmartTransaction(smartTransactionUuid, chainId) {
|
|
186
186
|
const { smartTransactionsState: { smartTransactions }, } = this.state;
|
|
187
|
-
const currentSmartTransactions = smartTransactions[__classPrivateFieldGet(this, _SmartTransactionsController_chainId, "f")];
|
|
187
|
+
const currentSmartTransactions = smartTransactions[chainId !== null && chainId !== void 0 ? chainId : __classPrivateFieldGet(this, _SmartTransactionsController_chainId, "f")];
|
|
188
188
|
const currentIndex = currentSmartTransactions === null || currentSmartTransactions === void 0 ? void 0 : currentSmartTransactions.findIndex((stx) => stx.uuid === smartTransactionUuid);
|
|
189
189
|
return currentIndex === -1 || currentIndex === undefined;
|
|
190
190
|
}
|
|
@@ -201,35 +201,62 @@ class SmartTransactionsController extends (0, polling_controller_1.StaticInterva
|
|
|
201
201
|
ethQuery,
|
|
202
202
|
});
|
|
203
203
|
}
|
|
204
|
-
async updateSmartTransactions({
|
|
204
|
+
async updateSmartTransactions({ chainIds, } = {
|
|
205
|
+
chainIds: __classPrivateFieldGet(this, _SmartTransactionsController_instances, "m", _SmartTransactionsController_getChainIds).call(this),
|
|
206
|
+
}) {
|
|
205
207
|
const { smartTransactionsState: { smartTransactions }, } = this.state;
|
|
206
|
-
|
|
207
|
-
const
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
208
|
+
// Iterate over each chain group directly
|
|
209
|
+
for (const [chainId, transactions] of Object.entries(smartTransactions)) {
|
|
210
|
+
if (chainIds && !chainIds.includes(chainId)) {
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
// Filter pending transactions and map them to the desired shape
|
|
214
|
+
const pendingTransactions = transactions
|
|
215
|
+
.filter(utils_1.isSmartTransactionPending)
|
|
216
|
+
.map((pendingSmartTransaction) => {
|
|
217
|
+
// Use the transaction's chainId (from the key) to derive a networkClientId
|
|
218
|
+
const networkClientIdToUse = __classPrivateFieldGet(this, _SmartTransactionsController_instances, "m", _SmartTransactionsController_getNetworkClientId).call(this, {
|
|
219
|
+
chainId: chainId,
|
|
220
|
+
});
|
|
221
|
+
return {
|
|
222
|
+
uuid: pendingSmartTransaction.uuid,
|
|
223
|
+
networkClientId: networkClientIdToUse,
|
|
224
|
+
chainId: pendingSmartTransaction.chainId, // same as the key, but explicit on the transaction
|
|
225
|
+
};
|
|
214
226
|
});
|
|
227
|
+
if (pendingTransactions.length > 0) {
|
|
228
|
+
// Since each group is per chain, all transactions share the same chainId.
|
|
229
|
+
await this.fetchSmartTransactionsStatus(pendingTransactions);
|
|
230
|
+
}
|
|
215
231
|
}
|
|
216
232
|
}
|
|
217
233
|
// ! Ask backend API to accept list of uuids as params
|
|
218
|
-
async fetchSmartTransactionsStatus(
|
|
219
|
-
|
|
220
|
-
|
|
234
|
+
async fetchSmartTransactionsStatus(transactions) {
|
|
235
|
+
// Since transactions come from the same chain group, take the chainId from the first one.
|
|
236
|
+
const { chainId } = transactions[0];
|
|
237
|
+
// Build query parameters with all UUIDs
|
|
238
|
+
const uuids = transactions.map((tx) => tx.uuid);
|
|
239
|
+
const params = new URLSearchParams({ uuids: uuids.join(',') });
|
|
240
|
+
// Get the ethQuery for the first transaction's networkClientId
|
|
241
|
+
const ethQuery = __classPrivateFieldGet(this, _SmartTransactionsController_instances, "m", _SmartTransactionsController_getEthQuery).call(this, {
|
|
242
|
+
networkClientId: transactions[0].networkClientId,
|
|
221
243
|
});
|
|
222
|
-
|
|
223
|
-
const ethQuery = __classPrivateFieldGet(this, _SmartTransactionsController_instances, "m", _SmartTransactionsController_getEthQuery).call(this, { networkClientId });
|
|
244
|
+
// Construct the URL and fetch the data
|
|
224
245
|
const url = `${(0, utils_1.getAPIRequestURL)(types_1.APIType.BATCH_STATUS, chainId)}?${params.toString()}`;
|
|
225
246
|
const data = (await __classPrivateFieldGet(this, _SmartTransactionsController_instances, "m", _SmartTransactionsController_fetch).call(this, url));
|
|
247
|
+
// Process each returned status
|
|
226
248
|
for (const [uuid, stxStatus] of Object.entries(data)) {
|
|
249
|
+
const matchingTx = transactions.find((tx) => tx.uuid === uuid);
|
|
250
|
+
if (!matchingTx) {
|
|
251
|
+
console.error(`No matching transaction found for uuid: ${uuid}`);
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
227
254
|
const smartTransaction = {
|
|
228
255
|
statusMetadata: stxStatus,
|
|
229
256
|
status: (0, utils_1.calculateStatus)(stxStatus),
|
|
230
257
|
cancellable: (0, utils_1.isSmartTransactionCancellable)(stxStatus),
|
|
231
258
|
uuid,
|
|
232
|
-
networkClientId,
|
|
259
|
+
networkClientId: matchingTx.networkClientId,
|
|
233
260
|
};
|
|
234
261
|
await __classPrivateFieldGet(this, _SmartTransactionsController_instances, "m", _SmartTransactionsController_createOrUpdateSmartTransaction).call(this, smartTransaction, {
|
|
235
262
|
chainId,
|
|
@@ -469,7 +496,7 @@ async function _SmartTransactionsController_fetch(request, options) {
|
|
|
469
496
|
const { smartTransactionsState: { smartTransactions }, } = this.state;
|
|
470
497
|
const currentSmartTransactions = (_a = smartTransactions[chainId]) !== null && _a !== void 0 ? _a : [];
|
|
471
498
|
const currentIndex = currentSmartTransactions === null || currentSmartTransactions === void 0 ? void 0 : currentSmartTransactions.findIndex((stx) => stx.uuid === smartTransaction.uuid);
|
|
472
|
-
const isNewSmartTransaction = this.isNewSmartTransaction(smartTransaction.uuid);
|
|
499
|
+
const isNewSmartTransaction = this.isNewSmartTransaction(smartTransaction.uuid, chainId);
|
|
473
500
|
if (__classPrivateFieldGet(this, _SmartTransactionsController_ethQuery, "f") === undefined) {
|
|
474
501
|
throw new Error(ETH_QUERY_ERROR_MSG);
|
|
475
502
|
}
|
|
@@ -496,7 +523,7 @@ async function _SmartTransactionsController_fetch(request, options) {
|
|
|
496
523
|
.concat(historifiedSmartTransaction)
|
|
497
524
|
: currentSmartTransactions.concat(historifiedSmartTransaction);
|
|
498
525
|
this.update((state) => {
|
|
499
|
-
state.smartTransactionsState.smartTransactions[
|
|
526
|
+
state.smartTransactionsState.smartTransactions[chainId] =
|
|
500
527
|
nextSmartTransactions;
|
|
501
528
|
});
|
|
502
529
|
return;
|
|
@@ -610,6 +637,12 @@ async function _SmartTransactionsController_fetch(request, options) {
|
|
|
610
637
|
return this.messagingSystem.call('NetworkController:getNetworkClientById', networkClientId).configuration.chainId;
|
|
611
638
|
}
|
|
612
639
|
return __classPrivateFieldGet(this, _SmartTransactionsController_chainId, "f");
|
|
640
|
+
}, _SmartTransactionsController_getChainIds = function _SmartTransactionsController_getChainIds() {
|
|
641
|
+
const { networkConfigurationsByChainId } = this.messagingSystem.call('NetworkController:getState');
|
|
642
|
+
return Object.keys(networkConfigurationsByChainId).filter((chainId) => __classPrivateFieldGet(this, _SmartTransactionsController_supportedChainIds, "f").includes(chainId));
|
|
643
|
+
}, _SmartTransactionsController_getNetworkClientId = function _SmartTransactionsController_getNetworkClientId({ chainId }) {
|
|
644
|
+
const { networkConfigurationsByChainId } = this.messagingSystem.call('NetworkController:getState');
|
|
645
|
+
return networkConfigurationsByChainId[chainId].rpcEndpoints[networkConfigurationsByChainId[chainId].defaultRpcEndpointIndex].networkClientId;
|
|
613
646
|
}, _SmartTransactionsController_getEthQuery = function _SmartTransactionsController_getEthQuery({ networkClientId, } = {}) {
|
|
614
647
|
if (networkClientId) {
|
|
615
648
|
const { provider } = this.messagingSystem.call('NetworkController:getNetworkClientById', networkClientId);
|
|
@@ -621,11 +654,12 @@ async function _SmartTransactionsController_fetch(request, options) {
|
|
|
621
654
|
return __classPrivateFieldGet(this, _SmartTransactionsController_ethQuery, "f");
|
|
622
655
|
}, _SmartTransactionsController_getCurrentSmartTransactions = function _SmartTransactionsController_getCurrentSmartTransactions() {
|
|
623
656
|
const { smartTransactionsState: { smartTransactions }, } = this.state;
|
|
624
|
-
const
|
|
625
|
-
if (!
|
|
657
|
+
const smartTransactionsForAllChains = Object.values(smartTransactions).flat();
|
|
658
|
+
if (!smartTransactionsForAllChains ||
|
|
659
|
+
smartTransactionsForAllChains.length === 0) {
|
|
626
660
|
return [];
|
|
627
661
|
}
|
|
628
|
-
return
|
|
662
|
+
return smartTransactionsForAllChains;
|
|
629
663
|
}, _SmartTransactionsController_wipeSmartTransactionsPerChainId = function _SmartTransactionsController_wipeSmartTransactionsPerChainId({ chainId, addressLowerCase, }) {
|
|
630
664
|
const { smartTransactionsState: { smartTransactions }, } = this.state;
|
|
631
665
|
const smartTransactionsForSelectedChain = smartTransactions === null || smartTransactions === void 0 ? void 0 : smartTransactions[chainId];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SmartTransactionsController.js","sourceRoot":"","sources":["../src/SmartTransactionsController.ts"],"names":[],"mappings":"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","sourcesContent":["import { hexlify } from '@ethersproject/bytes';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport {\n query,\n safelyExecute,\n ChainId,\n isSafeDynamicKey,\n} from '@metamask/controller-utils';\nimport EthQuery from '@metamask/eth-query';\nimport type {\n NetworkClientId,\n NetworkControllerGetNetworkClientByIdAction,\n NetworkControllerGetStateAction,\n NetworkControllerStateChangeEvent,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type {\n TransactionController,\n TransactionMeta,\n TransactionParams,\n} from '@metamask/transaction-controller';\nimport { TransactionStatus } from '@metamask/transaction-controller';\nimport { BigNumber } from 'bignumber.js';\nimport cloneDeep from 'lodash/cloneDeep';\n\nimport { MetaMetricsEventCategory, MetaMetricsEventName } from './constants';\nimport type {\n Fees,\n Hex,\n IndividualTxFees,\n SignedCanceledTransaction,\n SignedTransaction,\n SmartTransaction,\n SmartTransactionsStatus,\n UnsignedTransaction,\n GetTransactionsOptions,\n MetaMetricsProps,\n FeatureFlags,\n ClientId,\n} from './types';\nimport { APIType, SmartTransactionStatuses } from './types';\nimport {\n calculateStatus,\n generateHistoryEntry,\n getAPIRequestURL,\n handleFetch,\n incrementNonceInHex,\n isSmartTransactionCancellable,\n isSmartTransactionPending,\n replayHistory,\n snapshotFromTxMeta,\n getTxHash,\n getSmartTransactionMetricsProperties,\n getSmartTransactionMetricsSensitiveProperties,\n shouldMarkRegularTransactionAsFailed,\n markRegularTransactionAsFailed,\n} from './utils';\n\nconst SECOND = 1000;\nexport const DEFAULT_INTERVAL = SECOND * 5;\nconst ETH_QUERY_ERROR_MSG =\n '`ethQuery` is not defined on SmartTransactionsController';\n\n/**\n * The name of the {@link SmartTransactionsController}\n */\nconst controllerName = 'SmartTransactionsController';\n\nconst controllerMetadata = {\n smartTransactionsState: {\n persist: false,\n anonymous: true,\n },\n};\n\ntype FeeEstimates = {\n approvalTxFees: IndividualTxFees | null;\n tradeTxFees: IndividualTxFees | null;\n};\n\nexport type SmartTransactionsControllerState = {\n smartTransactionsState: {\n smartTransactions: Record<Hex, SmartTransaction[]>;\n userOptIn: boolean | null;\n userOptInV2: boolean | null;\n liveness: boolean | null;\n fees: FeeEstimates;\n feesByChainId: Record<Hex, FeeEstimates>;\n livenessByChainId: Record<Hex, boolean>;\n };\n};\n\n/**\n * Get the default {@link SmartTransactionsController} state.\n *\n * @returns The default {@link SmartTransactionsController} state.\n */\nexport function getDefaultSmartTransactionsControllerState(): SmartTransactionsControllerState {\n return {\n smartTransactionsState: {\n smartTransactions: {},\n userOptIn: null,\n userOptInV2: null,\n fees: {\n approvalTxFees: null,\n tradeTxFees: null,\n },\n liveness: true,\n livenessByChainId: {\n [ChainId.mainnet]: true,\n [ChainId.sepolia]: true,\n },\n feesByChainId: {\n [ChainId.mainnet]: {\n approvalTxFees: null,\n tradeTxFees: null,\n },\n [ChainId.sepolia]: {\n approvalTxFees: null,\n tradeTxFees: null,\n },\n },\n },\n };\n}\n\nexport type SmartTransactionsControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n SmartTransactionsControllerState\n >;\n\n/**\n * The actions that can be performed using the {@link SmartTransactionsController}.\n */\nexport type SmartTransactionsControllerActions =\n SmartTransactionsControllerGetStateAction;\n\ntype AllowedActions =\n | NetworkControllerGetNetworkClientByIdAction\n | NetworkControllerGetStateAction;\n\nexport type SmartTransactionsControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n SmartTransactionsControllerState\n >;\n\nexport type SmartTransactionsControllerSmartTransactionEvent = {\n type: 'SmartTransactionsController:smartTransaction';\n payload: [SmartTransaction];\n};\n\nexport type SmartTransactionsControllerSmartTransactionConfirmationDoneEvent = {\n type: 'SmartTransactionsController:smartTransactionConfirmationDone';\n payload: [SmartTransaction];\n};\n\n/**\n * The events that {@link SmartTransactionsController} can emit.\n */\nexport type SmartTransactionsControllerEvents =\n | SmartTransactionsControllerStateChangeEvent\n | SmartTransactionsControllerSmartTransactionEvent\n | SmartTransactionsControllerSmartTransactionConfirmationDoneEvent;\n\ntype AllowedEvents = NetworkControllerStateChangeEvent;\n\n/**\n * The messenger of the {@link SmartTransactionsController}.\n */\nexport type SmartTransactionsControllerMessenger =\n RestrictedControllerMessenger<\n typeof controllerName,\n SmartTransactionsControllerActions | AllowedActions,\n SmartTransactionsControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n >;\n\ntype SmartTransactionsControllerOptions = {\n interval?: number;\n clientId: ClientId;\n chainId?: Hex;\n supportedChainIds?: Hex[];\n getNonceLock: TransactionController['getNonceLock'];\n confirmExternalTransaction: TransactionController['confirmExternalTransaction'];\n trackMetaMetricsEvent: (\n event: {\n event: MetaMetricsEventName;\n category: MetaMetricsEventCategory;\n properties?: ReturnType<typeof getSmartTransactionMetricsProperties>;\n sensitiveProperties?: ReturnType<\n typeof getSmartTransactionMetricsSensitiveProperties\n >;\n },\n options?: { metaMetricsId?: string } & Record<string, boolean>,\n ) => void;\n state?: Partial<SmartTransactionsControllerState>;\n messenger: SmartTransactionsControllerMessenger;\n getTransactions: (options?: GetTransactionsOptions) => TransactionMeta[];\n getMetaMetricsProps: () => Promise<MetaMetricsProps>;\n getFeatureFlags: () => FeatureFlags;\n updateTransaction: (transaction: TransactionMeta, note: string) => void;\n};\n\nexport type SmartTransactionsControllerPollingInput = {\n networkClientId: string;\n};\n\nexport default class SmartTransactionsController extends StaticIntervalPollingController<SmartTransactionsControllerPollingInput>()<\n typeof controllerName,\n SmartTransactionsControllerState,\n SmartTransactionsControllerMessenger\n> {\n #interval: number;\n\n #clientId: ClientId;\n\n #chainId: Hex;\n\n #supportedChainIds: Hex[];\n\n timeoutHandle?: NodeJS.Timeout;\n\n readonly #getNonceLock: SmartTransactionsControllerOptions['getNonceLock'];\n\n #ethQuery: EthQuery | undefined;\n\n #confirmExternalTransaction: SmartTransactionsControllerOptions['confirmExternalTransaction'];\n\n #getRegularTransactions: (\n options?: GetTransactionsOptions,\n ) => TransactionMeta[];\n\n readonly #trackMetaMetricsEvent: SmartTransactionsControllerOptions['trackMetaMetricsEvent'];\n\n readonly #getMetaMetricsProps: () => Promise<MetaMetricsProps>;\n\n #getFeatureFlags: SmartTransactionsControllerOptions['getFeatureFlags'];\n\n #updateTransaction: SmartTransactionsControllerOptions['updateTransaction'];\n\n /* istanbul ignore next */\n async #fetch(request: string, options?: RequestInit) {\n const fetchOptions = {\n ...options,\n headers: {\n 'Content-Type': 'application/json',\n ...(this.#clientId && { 'X-Client-Id': this.#clientId }),\n },\n };\n\n return handleFetch(request, fetchOptions);\n }\n\n constructor({\n interval = DEFAULT_INTERVAL,\n clientId,\n chainId: InitialChainId = ChainId.mainnet,\n supportedChainIds = [ChainId.mainnet, ChainId.sepolia],\n getNonceLock,\n confirmExternalTransaction,\n trackMetaMetricsEvent,\n state = {},\n messenger,\n getTransactions,\n getMetaMetricsProps,\n getFeatureFlags,\n updateTransaction,\n }: SmartTransactionsControllerOptions) {\n super({\n name: controllerName,\n metadata: controllerMetadata,\n messenger,\n state: {\n ...getDefaultSmartTransactionsControllerState(),\n ...state,\n },\n });\n this.#interval = interval;\n this.#clientId = clientId;\n this.#chainId = InitialChainId;\n this.#supportedChainIds = supportedChainIds;\n this.setIntervalLength(interval);\n this.#getNonceLock = getNonceLock;\n this.#ethQuery = undefined;\n this.#confirmExternalTransaction = confirmExternalTransaction;\n this.#getRegularTransactions = getTransactions;\n this.#trackMetaMetricsEvent = trackMetaMetricsEvent;\n this.#getMetaMetricsProps = getMetaMetricsProps;\n this.#getFeatureFlags = getFeatureFlags;\n this.#updateTransaction = updateTransaction;\n\n this.initializeSmartTransactionsForChainId();\n\n this.messagingSystem.subscribe(\n 'NetworkController:stateChange',\n ({ selectedNetworkClientId }) => {\n const {\n configuration: { chainId },\n provider,\n } = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n this.#chainId = chainId;\n this.#ethQuery = new EthQuery(provider);\n this.initializeSmartTransactionsForChainId();\n this.checkPoll(this.state);\n },\n );\n\n this.messagingSystem.subscribe(\n `${controllerName}:stateChange`,\n (currentState) => this.checkPoll(currentState),\n );\n }\n\n async _executePoll({\n networkClientId,\n }: SmartTransactionsControllerPollingInput): Promise<void> {\n // if this is going to be truly UI driven polling we shouldn't really reach here\n // with a networkClientId that is not supported, but for now I'll add a check in case\n // wondering if we should add some kind of predicate to the polling controller to check whether\n // we should poll or not\n const chainId = this.#getChainId({ networkClientId });\n if (!this.#supportedChainIds.includes(chainId)) {\n return Promise.resolve();\n }\n return this.updateSmartTransactions({ networkClientId });\n }\n\n checkPoll({\n smartTransactionsState: { smartTransactions },\n }: SmartTransactionsControllerState) {\n const currentSmartTransactions = smartTransactions[this.#chainId];\n const pendingTransactions = currentSmartTransactions?.filter(\n isSmartTransactionPending,\n );\n if (!this.timeoutHandle && pendingTransactions?.length > 0) {\n this.poll();\n } else if (this.timeoutHandle && pendingTransactions?.length === 0) {\n this.stop();\n }\n }\n\n initializeSmartTransactionsForChainId() {\n if (this.#supportedChainIds.includes(this.#chainId)) {\n this.update((state) => {\n state.smartTransactionsState.smartTransactions[this.#chainId] =\n state.smartTransactionsState.smartTransactions[this.#chainId] ?? [];\n });\n }\n }\n\n async poll(interval?: number): Promise<void> {\n if (interval) {\n this.#interval = interval;\n }\n\n this.timeoutHandle && clearInterval(this.timeoutHandle);\n\n if (!this.#supportedChainIds.includes(this.#chainId)) {\n return;\n }\n\n this.timeoutHandle = setInterval(() => {\n safelyExecute(async () => this.updateSmartTransactions());\n }, this.#interval);\n await safelyExecute(async () => this.updateSmartTransactions());\n }\n\n async stop() {\n this.timeoutHandle && clearInterval(this.timeoutHandle);\n this.timeoutHandle = undefined;\n }\n\n setOptInState(optInState: boolean | null): void {\n this.update((state) => {\n state.smartTransactionsState.userOptInV2 = optInState;\n });\n }\n\n trackStxStatusChange(\n smartTransaction: SmartTransaction,\n prevSmartTransaction?: SmartTransaction,\n ) {\n let updatedSmartTransaction = cloneDeep(smartTransaction);\n updatedSmartTransaction = {\n ...cloneDeep(prevSmartTransaction),\n ...updatedSmartTransaction,\n };\n\n if (updatedSmartTransaction.status === prevSmartTransaction?.status) {\n return; // If status hasn't changed, don't track it again.\n }\n\n this.#trackMetaMetricsEvent({\n event: MetaMetricsEventName.StxStatusUpdated,\n category: MetaMetricsEventCategory.Transactions,\n properties: getSmartTransactionMetricsProperties(updatedSmartTransaction),\n sensitiveProperties: getSmartTransactionMetricsSensitiveProperties(\n updatedSmartTransaction,\n ),\n });\n }\n\n isNewSmartTransaction(smartTransactionUuid: string): boolean {\n const {\n smartTransactionsState: { smartTransactions },\n } = this.state;\n const currentSmartTransactions = smartTransactions[this.#chainId];\n const currentIndex = currentSmartTransactions?.findIndex(\n (stx) => stx.uuid === smartTransactionUuid,\n );\n return currentIndex === -1 || currentIndex === undefined;\n }\n\n updateSmartTransaction(\n smartTransaction: SmartTransaction,\n { networkClientId }: { networkClientId?: NetworkClientId } = {},\n ) {\n let ethQuery = this.#ethQuery;\n let chainId = this.#chainId;\n if (networkClientId) {\n const { configuration, provider } = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n chainId = configuration.chainId;\n ethQuery = new EthQuery(provider);\n }\n\n this.#createOrUpdateSmartTransaction(smartTransaction, {\n chainId,\n ethQuery,\n });\n }\n\n #updateSmartTransaction(\n smartTransaction: SmartTransaction,\n {\n chainId = this.#chainId,\n }: {\n chainId: Hex;\n },\n ) {\n const {\n smartTransactionsState: { smartTransactions },\n } = this.state;\n const currentSmartTransactions = smartTransactions[chainId] ?? [];\n const currentIndex = currentSmartTransactions?.findIndex(\n (stx) => stx.uuid === smartTransaction.uuid,\n );\n\n if (currentIndex === -1) {\n return; // Smart transaction not found, don't update anything.\n }\n\n if (!isSafeDynamicKey(chainId)) {\n return;\n }\n\n this.update((state) => {\n state.smartTransactionsState.smartTransactions[chainId][currentIndex] = {\n ...state.smartTransactionsState.smartTransactions[chainId][\n currentIndex\n ],\n ...smartTransaction,\n };\n });\n }\n\n async #addMetaMetricsPropsToNewSmartTransaction(\n smartTransaction: SmartTransaction,\n ) {\n const metaMetricsProps = await this.#getMetaMetricsProps();\n smartTransaction.accountHardwareType =\n metaMetricsProps?.accountHardwareType;\n smartTransaction.accountType = metaMetricsProps?.accountType;\n smartTransaction.deviceModel = metaMetricsProps?.deviceModel;\n }\n\n async #createOrUpdateSmartTransaction(\n smartTransaction: SmartTransaction,\n {\n chainId = this.#chainId,\n ethQuery = this.#ethQuery,\n }: {\n chainId: Hex;\n ethQuery: EthQuery | undefined;\n },\n ): Promise<void> {\n const {\n smartTransactionsState: { smartTransactions },\n } = this.state;\n const currentSmartTransactions = smartTransactions[chainId] ?? [];\n const currentIndex = currentSmartTransactions?.findIndex(\n (stx) => stx.uuid === smartTransaction.uuid,\n );\n const isNewSmartTransaction = this.isNewSmartTransaction(\n smartTransaction.uuid,\n );\n if (this.#ethQuery === undefined) {\n throw new Error(ETH_QUERY_ERROR_MSG);\n }\n\n if (isNewSmartTransaction) {\n await this.#addMetaMetricsPropsToNewSmartTransaction(smartTransaction);\n }\n\n this.trackStxStatusChange(\n smartTransaction,\n isNewSmartTransaction\n ? undefined\n : currentSmartTransactions[currentIndex],\n );\n\n if (isNewSmartTransaction) {\n // add smart transaction\n const cancelledNonceIndex = currentSmartTransactions?.findIndex(\n (stx: SmartTransaction) =>\n stx.txParams?.nonce === smartTransaction.txParams?.nonce &&\n stx.status?.startsWith('cancelled'),\n );\n const snapshot = cloneDeep(smartTransaction);\n const history = [snapshot];\n const historifiedSmartTransaction = { ...smartTransaction, history };\n const nextSmartTransactions =\n cancelledNonceIndex > -1\n ? currentSmartTransactions\n .slice(0, cancelledNonceIndex)\n .concat(currentSmartTransactions.slice(cancelledNonceIndex + 1))\n .concat(historifiedSmartTransaction)\n : currentSmartTransactions.concat(historifiedSmartTransaction);\n\n this.update((state) => {\n state.smartTransactionsState.smartTransactions[this.#chainId] =\n nextSmartTransactions;\n });\n return;\n }\n\n const currentSmartTransaction = currentSmartTransactions[currentIndex];\n const nextSmartTransaction = {\n ...currentSmartTransaction,\n ...smartTransaction,\n };\n\n // We have to emit this event here, because then a txHash is returned to the TransactionController once it's available\n // and the #doesTransactionNeedConfirmation function will work properly, since it will find the txHash in the regular transactions list.\n this.messagingSystem.publish(\n `SmartTransactionsController:smartTransaction`,\n nextSmartTransaction,\n );\n\n if (\n shouldMarkRegularTransactionAsFailed({\n smartTransaction: nextSmartTransaction,\n clientId: this.#clientId,\n getFeatureFlags: this.#getFeatureFlags,\n })\n ) {\n markRegularTransactionAsFailed({\n smartTransaction: nextSmartTransaction,\n getRegularTransactions: this.#getRegularTransactions,\n updateTransaction: this.#updateTransaction,\n });\n }\n\n if (\n (smartTransaction.status === SmartTransactionStatuses.SUCCESS ||\n smartTransaction.status === SmartTransactionStatuses.REVERTED) &&\n !smartTransaction.confirmed\n ) {\n await this.#confirmSmartTransaction(nextSmartTransaction, {\n chainId,\n ethQuery,\n });\n } else {\n this.#updateSmartTransaction(smartTransaction, {\n chainId,\n });\n }\n }\n\n async updateSmartTransactions({\n networkClientId,\n }: {\n networkClientId?: NetworkClientId;\n } = {}): Promise<void> {\n const {\n smartTransactionsState: { smartTransactions },\n } = this.state;\n const chainId = this.#getChainId({ networkClientId });\n const smartTransactionsForChainId = smartTransactions[chainId];\n\n const transactionsToUpdate: string[] = smartTransactionsForChainId\n .filter(isSmartTransactionPending)\n .map((smartTransaction) => smartTransaction.uuid);\n\n if (transactionsToUpdate.length > 0) {\n this.fetchSmartTransactionsStatus(transactionsToUpdate, {\n networkClientId,\n });\n }\n }\n\n #doesTransactionNeedConfirmation(txHash: string | undefined): boolean {\n if (!txHash) {\n return true;\n }\n const transactions = this.#getRegularTransactions();\n const foundTransaction = transactions?.find((tx) => {\n return tx.hash?.toLowerCase() === txHash.toLowerCase();\n });\n if (!foundTransaction) {\n return true;\n }\n // If a found transaction is either confirmed or submitted, it doesn't need confirmation from the STX controller.\n // When it's in the submitted state, the TransactionController checks its status and confirms it,\n // so no need to confirm it again here.\n return ![TransactionStatus.confirmed, TransactionStatus.submitted].includes(\n foundTransaction.status,\n );\n }\n\n async #confirmSmartTransaction(\n smartTransaction: SmartTransaction,\n {\n chainId = this.#chainId,\n ethQuery = this.#ethQuery,\n }: {\n chainId: Hex;\n ethQuery: EthQuery | undefined;\n },\n ) {\n if (ethQuery === undefined) {\n throw new Error(ETH_QUERY_ERROR_MSG);\n }\n const txHash = smartTransaction.statusMetadata?.minedHash;\n try {\n const transactionReceipt: {\n maxFeePerGas?: string;\n maxPriorityFeePerGas?: string;\n blockNumber: string;\n } | null = await query(ethQuery, 'getTransactionReceipt', [txHash]);\n const transaction: {\n maxFeePerGas?: string;\n maxPriorityFeePerGas?: string;\n } | null = await query(ethQuery, 'getTransactionByHash', [txHash]);\n\n const maxFeePerGas = transaction?.maxFeePerGas;\n const maxPriorityFeePerGas = transaction?.maxPriorityFeePerGas;\n if (transactionReceipt?.blockNumber) {\n const blockData: { baseFeePerGas?: Hex } | null = await query(\n ethQuery,\n 'getBlockByNumber',\n [transactionReceipt?.blockNumber, false],\n );\n const baseFeePerGas = blockData?.baseFeePerGas;\n const updatedTxParams = {\n ...smartTransaction.txParams,\n maxFeePerGas,\n maxPriorityFeePerGas,\n };\n // call confirmExternalTransaction\n const originalTxMeta = {\n ...smartTransaction,\n id: smartTransaction.uuid,\n status: TransactionStatus.confirmed,\n hash: txHash,\n txParams: updatedTxParams,\n };\n // create txMeta snapshot for history\n const snapshot = snapshotFromTxMeta(originalTxMeta);\n // recover previous tx state obj\n const previousState = replayHistory(originalTxMeta.history);\n // generate history entry and add to history\n const entry = generateHistoryEntry(\n previousState,\n snapshot,\n 'txStateManager: setting status to confirmed',\n );\n const txMeta =\n entry.length > 0\n ? {\n ...originalTxMeta,\n history: originalTxMeta.history.concat(entry),\n }\n : originalTxMeta;\n\n if (this.#doesTransactionNeedConfirmation(txHash)) {\n this.#confirmExternalTransaction(\n // TODO: Replace 'as' assertion with correct typing for `txMeta`\n txMeta as TransactionMeta,\n transactionReceipt,\n // TODO: Replace 'as' assertion with correct typing for `baseFeePerGas`\n baseFeePerGas as Hex,\n );\n }\n this.#trackMetaMetricsEvent({\n event: MetaMetricsEventName.StxConfirmed,\n category: MetaMetricsEventCategory.Transactions,\n properties: getSmartTransactionMetricsProperties(smartTransaction),\n sensitiveProperties:\n getSmartTransactionMetricsSensitiveProperties(smartTransaction),\n });\n this.#updateSmartTransaction(\n { ...smartTransaction, confirmed: true },\n {\n chainId,\n },\n );\n }\n } catch (error) {\n this.#trackMetaMetricsEvent({\n event: MetaMetricsEventName.StxConfirmationFailed,\n category: MetaMetricsEventCategory.Transactions,\n });\n console.error('confirm error', error);\n } finally {\n this.messagingSystem.publish(\n `SmartTransactionsController:smartTransactionConfirmationDone`,\n smartTransaction,\n );\n }\n }\n\n // ! Ask backend API to accept list of uuids as params\n async fetchSmartTransactionsStatus(\n uuids: string[],\n { networkClientId }: { networkClientId?: NetworkClientId } = {},\n ): Promise<Record<string, SmartTransactionsStatus>> {\n const params = new URLSearchParams({\n uuids: uuids.join(','),\n });\n const chainId = this.#getChainId({ networkClientId });\n const ethQuery = this.#getEthQuery({ networkClientId });\n const url = `${getAPIRequestURL(\n APIType.BATCH_STATUS,\n chainId,\n )}?${params.toString()}`;\n\n const data = (await this.#fetch(url)) as Record<\n string,\n SmartTransactionsStatus\n >;\n\n for (const [uuid, stxStatus] of Object.entries(data)) {\n const smartTransaction: SmartTransaction = {\n statusMetadata: stxStatus,\n status: calculateStatus(stxStatus),\n cancellable: isSmartTransactionCancellable(stxStatus),\n uuid,\n networkClientId,\n };\n await this.#createOrUpdateSmartTransaction(smartTransaction, {\n chainId,\n ethQuery,\n });\n }\n\n return data;\n }\n\n async #addNonceToTransaction(\n transaction: UnsignedTransaction,\n networkClientId: NetworkClientId,\n ): Promise<UnsignedTransaction> {\n const nonceLock = await this.#getNonceLock(\n transaction.from,\n networkClientId,\n );\n const nonce = nonceLock.nextNonce;\n nonceLock.releaseLock();\n return {\n ...transaction,\n nonce: `0x${nonce.toString(16)}`,\n };\n }\n\n clearFees(): Fees {\n const fees = {\n approvalTxFees: null,\n tradeTxFees: null,\n };\n this.update((state) => {\n state.smartTransactionsState.fees = fees;\n });\n\n return fees;\n }\n\n async getFees(\n tradeTx: UnsignedTransaction,\n approvalTx?: UnsignedTransaction,\n { networkClientId }: { networkClientId?: NetworkClientId } = {},\n ): Promise<Fees> {\n const selectedNetworkClientId =\n networkClientId ??\n this.messagingSystem.call('NetworkController:getState')\n .selectedNetworkClientId;\n const chainId = this.#getChainId({\n networkClientId: selectedNetworkClientId,\n });\n const transactions = [];\n let unsignedTradeTransactionWithNonce;\n if (approvalTx) {\n const unsignedApprovalTransactionWithNonce =\n await this.#addNonceToTransaction(approvalTx, selectedNetworkClientId);\n transactions.push(unsignedApprovalTransactionWithNonce);\n unsignedTradeTransactionWithNonce = {\n ...tradeTx,\n // If there is an approval tx, the trade tx's nonce is increased by 1.\n nonce: incrementNonceInHex(unsignedApprovalTransactionWithNonce.nonce),\n };\n } else if (tradeTx.nonce) {\n unsignedTradeTransactionWithNonce = tradeTx;\n } else {\n unsignedTradeTransactionWithNonce = await this.#addNonceToTransaction(\n tradeTx,\n selectedNetworkClientId,\n );\n }\n transactions.push(unsignedTradeTransactionWithNonce);\n const data = await this.#fetch(\n getAPIRequestURL(APIType.GET_FEES, chainId),\n {\n method: 'POST',\n body: JSON.stringify({\n txs: transactions,\n }),\n },\n );\n let approvalTxFees: IndividualTxFees | null;\n let tradeTxFees: IndividualTxFees | null;\n if (approvalTx) {\n approvalTxFees = data?.txs[0];\n tradeTxFees = data?.txs[1];\n } else {\n approvalTxFees = null;\n tradeTxFees = data?.txs[0];\n }\n\n this.update((state) => {\n if (chainId === this.#chainId) {\n state.smartTransactionsState.fees = {\n approvalTxFees,\n tradeTxFees,\n };\n }\n state.smartTransactionsState.feesByChainId[chainId] = {\n approvalTxFees,\n tradeTxFees,\n };\n });\n\n return {\n approvalTxFees,\n tradeTxFees,\n };\n }\n\n // * After this successful call client must add a nonce representative to\n // * transaction controller external transactions list\n async submitSignedTransactions({\n transactionMeta,\n txParams,\n signedTransactions,\n signedCanceledTransactions,\n networkClientId,\n }: {\n signedTransactions: SignedTransaction[];\n signedCanceledTransactions: SignedCanceledTransaction[];\n transactionMeta?: TransactionMeta;\n txParams?: TransactionParams;\n networkClientId?: NetworkClientId;\n }) {\n const selectedNetworkClientId =\n networkClientId ??\n this.messagingSystem.call('NetworkController:getState')\n .selectedNetworkClientId;\n const chainId = this.#getChainId({\n networkClientId: selectedNetworkClientId,\n });\n const ethQuery = this.#getEthQuery({\n networkClientId: selectedNetworkClientId,\n });\n const data = await this.#fetch(\n getAPIRequestURL(APIType.SUBMIT_TRANSACTIONS, chainId),\n {\n method: 'POST',\n body: JSON.stringify({\n rawTxs: signedTransactions,\n rawCancelTxs: signedCanceledTransactions,\n }),\n },\n );\n const time = Date.now();\n let preTxBalance;\n try {\n const preTxBalanceBN = await query(ethQuery, 'getBalance', [\n txParams?.from,\n ]);\n preTxBalance = new BigNumber(preTxBalanceBN).toString(16);\n } catch (error) {\n console.error('provider error', error);\n }\n\n const requiresNonce = txParams && !txParams.nonce;\n let nonce;\n let nonceLock;\n let nonceDetails = {};\n\n if (requiresNonce) {\n nonceLock = await this.#getNonceLock(\n txParams.from,\n selectedNetworkClientId,\n );\n nonce = hexlify(nonceLock.nextNonce);\n nonceDetails = nonceLock.nonceDetails;\n txParams.nonce ??= nonce;\n }\n const submitTransactionResponse = {\n ...data,\n txHash: getTxHash(signedTransactions[0]),\n };\n\n try {\n await this.#createOrUpdateSmartTransaction(\n {\n chainId,\n nonceDetails,\n preTxBalance,\n status: SmartTransactionStatuses.PENDING,\n time,\n txParams,\n uuid: submitTransactionResponse.uuid,\n txHash: submitTransactionResponse.txHash,\n cancellable: true,\n type: transactionMeta?.type ?? 'swap',\n transactionId: transactionMeta?.id,\n networkClientId: selectedNetworkClientId,\n },\n { chainId, ethQuery },\n );\n } finally {\n nonceLock?.releaseLock();\n }\n\n return submitTransactionResponse;\n }\n\n #getChainId({\n networkClientId,\n }: { networkClientId?: NetworkClientId } = {}): Hex {\n if (networkClientId) {\n return this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n ).configuration.chainId;\n }\n\n return this.#chainId;\n }\n\n #getEthQuery({\n networkClientId,\n }: {\n networkClientId?: NetworkClientId;\n } = {}): EthQuery {\n if (networkClientId) {\n const { provider } = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n return new EthQuery(provider);\n }\n\n if (this.#ethQuery === undefined) {\n throw new Error(ETH_QUERY_ERROR_MSG);\n }\n\n return this.#ethQuery;\n }\n\n // TODO: This should return if the cancellation was on chain or not (for nonce management)\n // After this successful call client must update nonce representative\n // in transaction controller external transactions list\n async cancelSmartTransaction(\n uuid: string,\n {\n networkClientId,\n }: {\n networkClientId?: NetworkClientId;\n } = {},\n ): Promise<void> {\n const chainId = this.#getChainId({ networkClientId });\n await this.#fetch(getAPIRequestURL(APIType.CANCEL, chainId), {\n method: 'POST',\n body: JSON.stringify({ uuid }),\n });\n }\n\n async fetchLiveness({\n networkClientId,\n }: {\n networkClientId?: NetworkClientId;\n } = {}): Promise<boolean> {\n const chainId = this.#getChainId({ networkClientId });\n let liveness = false;\n try {\n const response = await this.#fetch(\n getAPIRequestURL(APIType.LIVENESS, chainId),\n );\n liveness = Boolean(response.smartTransactions);\n } catch (error) {\n console.log('\"fetchLiveness\" API call failed');\n }\n\n this.update((state) => {\n if (chainId === this.#chainId) {\n state.smartTransactionsState.liveness = liveness;\n }\n state.smartTransactionsState.livenessByChainId[chainId] = liveness;\n });\n\n return liveness;\n }\n\n async setStatusRefreshInterval(interval: number): Promise<void> {\n if (interval !== this.#interval) {\n this.#interval = interval;\n }\n }\n\n #getCurrentSmartTransactions(): SmartTransaction[] {\n const {\n smartTransactionsState: { smartTransactions },\n } = this.state;\n const currentSmartTransactions = smartTransactions?.[this.#chainId];\n if (!currentSmartTransactions || currentSmartTransactions.length === 0) {\n return [];\n }\n return currentSmartTransactions;\n }\n\n getTransactions({\n addressFrom,\n status,\n }: {\n addressFrom: string;\n status: SmartTransactionStatuses;\n }): SmartTransaction[] {\n const currentSmartTransactions = this.#getCurrentSmartTransactions();\n return currentSmartTransactions.filter((stx) => {\n return stx.status === status && stx.txParams?.from === addressFrom;\n });\n }\n\n getSmartTransactionByMinedTxHash(\n txHash: string | undefined,\n ): SmartTransaction | undefined {\n if (!txHash) {\n return undefined;\n }\n const currentSmartTransactions = this.#getCurrentSmartTransactions();\n return currentSmartTransactions.find((smartTransaction) => {\n return (\n smartTransaction.statusMetadata?.minedHash?.toLowerCase() ===\n txHash.toLowerCase()\n );\n });\n }\n\n wipeSmartTransactions({\n address,\n ignoreNetwork,\n }: {\n address: string;\n ignoreNetwork?: boolean;\n }): void {\n if (!address) {\n return;\n }\n const addressLowerCase = address.toLowerCase();\n if (ignoreNetwork) {\n const {\n smartTransactionsState: { smartTransactions },\n } = this.state;\n (Object.keys(smartTransactions) as Hex[]).forEach((chainId) => {\n this.#wipeSmartTransactionsPerChainId({\n chainId,\n addressLowerCase,\n });\n });\n } else {\n this.#wipeSmartTransactionsPerChainId({\n chainId: this.#chainId,\n addressLowerCase,\n });\n }\n }\n\n #wipeSmartTransactionsPerChainId({\n chainId,\n addressLowerCase,\n }: {\n chainId: Hex;\n addressLowerCase: string;\n }): void {\n const {\n smartTransactionsState: { smartTransactions },\n } = this.state;\n const smartTransactionsForSelectedChain: SmartTransaction[] =\n smartTransactions?.[chainId];\n if (\n !smartTransactionsForSelectedChain ||\n smartTransactionsForSelectedChain.length === 0\n ) {\n return;\n }\n const newSmartTransactionsForSelectedChain =\n smartTransactionsForSelectedChain.filter(\n (smartTransaction: SmartTransaction) =>\n smartTransaction.txParams?.from !== addressLowerCase,\n );\n this.update((state) => {\n state.smartTransactionsState.smartTransactions[chainId] =\n newSmartTransactionsForSelectedChain;\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SmartTransactionsController.js","sourceRoot":"","sources":["../src/SmartTransactionsController.ts"],"names":[],"mappings":"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","sourcesContent":["import { hexlify } from '@ethersproject/bytes';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport {\n query,\n safelyExecute,\n ChainId,\n isSafeDynamicKey,\n} from '@metamask/controller-utils';\nimport EthQuery from '@metamask/eth-query';\nimport type {\n NetworkClientId,\n NetworkControllerGetNetworkClientByIdAction,\n NetworkControllerGetStateAction,\n NetworkControllerStateChangeEvent,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type {\n TransactionController,\n TransactionMeta,\n TransactionParams,\n} from '@metamask/transaction-controller';\nimport { TransactionStatus } from '@metamask/transaction-controller';\nimport { BigNumber } from 'bignumber.js';\nimport cloneDeep from 'lodash/cloneDeep';\n\nimport { MetaMetricsEventCategory, MetaMetricsEventName } from './constants';\nimport type {\n Fees,\n Hex,\n IndividualTxFees,\n SignedCanceledTransaction,\n SignedTransaction,\n SmartTransaction,\n SmartTransactionsStatus,\n UnsignedTransaction,\n GetTransactionsOptions,\n MetaMetricsProps,\n FeatureFlags,\n ClientId,\n} from './types';\nimport { APIType, SmartTransactionStatuses } from './types';\nimport {\n calculateStatus,\n generateHistoryEntry,\n getAPIRequestURL,\n handleFetch,\n incrementNonceInHex,\n isSmartTransactionCancellable,\n isSmartTransactionPending,\n replayHistory,\n snapshotFromTxMeta,\n getTxHash,\n getSmartTransactionMetricsProperties,\n getSmartTransactionMetricsSensitiveProperties,\n shouldMarkRegularTransactionAsFailed,\n markRegularTransactionAsFailed,\n} from './utils';\n\nconst SECOND = 1000;\nexport const DEFAULT_INTERVAL = SECOND * 5;\nconst ETH_QUERY_ERROR_MSG =\n '`ethQuery` is not defined on SmartTransactionsController';\n\n/**\n * The name of the {@link SmartTransactionsController}\n */\nconst controllerName = 'SmartTransactionsController';\n\nconst controllerMetadata = {\n smartTransactionsState: {\n persist: true,\n anonymous: true,\n },\n};\n\ntype FeeEstimates = {\n approvalTxFees: IndividualTxFees | null;\n tradeTxFees: IndividualTxFees | null;\n};\n\nexport type SmartTransactionsControllerState = {\n smartTransactionsState: {\n smartTransactions: Record<Hex, SmartTransaction[]>;\n userOptIn: boolean | null;\n userOptInV2: boolean | null;\n liveness: boolean | null;\n fees: FeeEstimates;\n feesByChainId: Record<Hex, FeeEstimates>;\n livenessByChainId: Record<Hex, boolean>;\n };\n};\n\n/**\n * Get the default {@link SmartTransactionsController} state.\n *\n * @returns The default {@link SmartTransactionsController} state.\n */\nexport function getDefaultSmartTransactionsControllerState(): SmartTransactionsControllerState {\n return {\n smartTransactionsState: {\n smartTransactions: {},\n userOptIn: null,\n userOptInV2: null,\n fees: {\n approvalTxFees: null,\n tradeTxFees: null,\n },\n liveness: true,\n livenessByChainId: {\n [ChainId.mainnet]: true,\n [ChainId.sepolia]: true,\n },\n feesByChainId: {\n [ChainId.mainnet]: {\n approvalTxFees: null,\n tradeTxFees: null,\n },\n [ChainId.sepolia]: {\n approvalTxFees: null,\n tradeTxFees: null,\n },\n },\n },\n };\n}\n\nexport type SmartTransactionsControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n SmartTransactionsControllerState\n >;\n\n/**\n * The actions that can be performed using the {@link SmartTransactionsController}.\n */\nexport type SmartTransactionsControllerActions =\n SmartTransactionsControllerGetStateAction;\n\ntype AllowedActions =\n | NetworkControllerGetNetworkClientByIdAction\n | NetworkControllerGetStateAction;\n\nexport type SmartTransactionsControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n SmartTransactionsControllerState\n >;\n\nexport type SmartTransactionsControllerSmartTransactionEvent = {\n type: 'SmartTransactionsController:smartTransaction';\n payload: [SmartTransaction];\n};\n\nexport type SmartTransactionsControllerSmartTransactionConfirmationDoneEvent = {\n type: 'SmartTransactionsController:smartTransactionConfirmationDone';\n payload: [SmartTransaction];\n};\n\n/**\n * The events that {@link SmartTransactionsController} can emit.\n */\nexport type SmartTransactionsControllerEvents =\n | SmartTransactionsControllerStateChangeEvent\n | SmartTransactionsControllerSmartTransactionEvent\n | SmartTransactionsControllerSmartTransactionConfirmationDoneEvent;\n\ntype AllowedEvents = NetworkControllerStateChangeEvent;\n\n/**\n * The messenger of the {@link SmartTransactionsController}.\n */\nexport type SmartTransactionsControllerMessenger =\n RestrictedControllerMessenger<\n typeof controllerName,\n SmartTransactionsControllerActions | AllowedActions,\n SmartTransactionsControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n >;\n\ntype SmartTransactionsControllerOptions = {\n interval?: number;\n clientId: ClientId;\n chainId?: Hex;\n supportedChainIds?: Hex[];\n getNonceLock: TransactionController['getNonceLock'];\n confirmExternalTransaction: TransactionController['confirmExternalTransaction'];\n trackMetaMetricsEvent: (\n event: {\n event: MetaMetricsEventName;\n category: MetaMetricsEventCategory;\n properties?: ReturnType<typeof getSmartTransactionMetricsProperties>;\n sensitiveProperties?: ReturnType<\n typeof getSmartTransactionMetricsSensitiveProperties\n >;\n },\n options?: { metaMetricsId?: string } & Record<string, boolean>,\n ) => void;\n state?: Partial<SmartTransactionsControllerState>;\n messenger: SmartTransactionsControllerMessenger;\n getTransactions: (options?: GetTransactionsOptions) => TransactionMeta[];\n getMetaMetricsProps: () => Promise<MetaMetricsProps>;\n getFeatureFlags: () => FeatureFlags;\n updateTransaction: (transaction: TransactionMeta, note: string) => void;\n};\n\nexport type SmartTransactionsControllerPollingInput = {\n chainIds: Hex[];\n};\n\nexport default class SmartTransactionsController extends StaticIntervalPollingController<SmartTransactionsControllerPollingInput>()<\n typeof controllerName,\n SmartTransactionsControllerState,\n SmartTransactionsControllerMessenger\n> {\n #interval: number;\n\n #clientId: ClientId;\n\n #chainId: Hex;\n\n #supportedChainIds: Hex[];\n\n timeoutHandle?: NodeJS.Timeout;\n\n readonly #getNonceLock: SmartTransactionsControllerOptions['getNonceLock'];\n\n #ethQuery: EthQuery | undefined;\n\n #confirmExternalTransaction: SmartTransactionsControllerOptions['confirmExternalTransaction'];\n\n #getRegularTransactions: (\n options?: GetTransactionsOptions,\n ) => TransactionMeta[];\n\n readonly #trackMetaMetricsEvent: SmartTransactionsControllerOptions['trackMetaMetricsEvent'];\n\n readonly #getMetaMetricsProps: () => Promise<MetaMetricsProps>;\n\n #getFeatureFlags: SmartTransactionsControllerOptions['getFeatureFlags'];\n\n #updateTransaction: SmartTransactionsControllerOptions['updateTransaction'];\n\n /* istanbul ignore next */\n async #fetch(request: string, options?: RequestInit) {\n const fetchOptions = {\n ...options,\n headers: {\n 'Content-Type': 'application/json',\n ...(this.#clientId && { 'X-Client-Id': this.#clientId }),\n },\n };\n\n return handleFetch(request, fetchOptions);\n }\n\n constructor({\n interval = DEFAULT_INTERVAL,\n clientId,\n chainId: InitialChainId = ChainId.mainnet,\n supportedChainIds = [ChainId.mainnet, ChainId.sepolia],\n getNonceLock,\n confirmExternalTransaction,\n trackMetaMetricsEvent,\n state = {},\n messenger,\n getTransactions,\n getMetaMetricsProps,\n getFeatureFlags,\n updateTransaction,\n }: SmartTransactionsControllerOptions) {\n super({\n name: controllerName,\n metadata: controllerMetadata,\n messenger,\n state: {\n ...getDefaultSmartTransactionsControllerState(),\n ...state,\n },\n });\n this.#interval = interval;\n this.#clientId = clientId;\n this.#chainId = InitialChainId;\n this.#supportedChainIds = supportedChainIds;\n this.setIntervalLength(interval);\n this.#getNonceLock = getNonceLock;\n this.#ethQuery = undefined;\n this.#confirmExternalTransaction = confirmExternalTransaction;\n this.#getRegularTransactions = getTransactions;\n this.#trackMetaMetricsEvent = trackMetaMetricsEvent;\n this.#getMetaMetricsProps = getMetaMetricsProps;\n this.#getFeatureFlags = getFeatureFlags;\n this.#updateTransaction = updateTransaction;\n\n this.initializeSmartTransactionsForChainId();\n\n this.messagingSystem.subscribe(\n 'NetworkController:stateChange',\n ({ selectedNetworkClientId }) => {\n const {\n configuration: { chainId },\n provider,\n } = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n this.#chainId = chainId;\n this.#ethQuery = new EthQuery(provider);\n this.initializeSmartTransactionsForChainId();\n this.checkPoll(this.state);\n },\n );\n\n this.messagingSystem.subscribe(\n `${controllerName}:stateChange`,\n (currentState) => this.checkPoll(currentState),\n );\n }\n\n async _executePoll({\n chainIds,\n }: SmartTransactionsControllerPollingInput): Promise<void> {\n // if this is going to be truly UI driven polling we shouldn't really reach here\n // with a networkClientId that is not supported, but for now I'll add a check in case\n // wondering if we should add some kind of predicate to the polling controller to check whether\n // we should poll or not\n const filteredChainIds = (chainIds ?? []).filter((chainId) =>\n this.#supportedChainIds.includes(chainId),\n );\n\n if (filteredChainIds.length === 0) {\n return Promise.resolve();\n }\n return this.updateSmartTransactions({ chainIds: filteredChainIds });\n }\n\n checkPoll({\n smartTransactionsState: { smartTransactions },\n }: SmartTransactionsControllerState) {\n const smartTransactionsForAllChains =\n Object.values(smartTransactions).flat();\n\n const pendingTransactions = smartTransactionsForAllChains?.filter(\n isSmartTransactionPending,\n );\n if (!this.timeoutHandle && pendingTransactions?.length > 0) {\n this.poll();\n } else if (this.timeoutHandle && pendingTransactions?.length === 0) {\n this.stop();\n }\n }\n\n initializeSmartTransactionsForChainId() {\n if (this.#supportedChainIds.includes(this.#chainId)) {\n this.update((state) => {\n state.smartTransactionsState.smartTransactions[this.#chainId] =\n state.smartTransactionsState.smartTransactions[this.#chainId] ?? [];\n });\n }\n }\n\n async poll(interval?: number): Promise<void> {\n if (interval) {\n this.#interval = interval;\n }\n\n this.timeoutHandle && clearInterval(this.timeoutHandle);\n\n if (!this.#supportedChainIds.includes(this.#chainId)) {\n return;\n }\n\n this.timeoutHandle = setInterval(() => {\n safelyExecute(async () => this.updateSmartTransactions());\n }, this.#interval);\n await safelyExecute(async () => this.updateSmartTransactions());\n }\n\n async stop() {\n this.timeoutHandle && clearInterval(this.timeoutHandle);\n this.timeoutHandle = undefined;\n }\n\n setOptInState(optInState: boolean | null): void {\n this.update((state) => {\n state.smartTransactionsState.userOptInV2 = optInState;\n });\n }\n\n trackStxStatusChange(\n smartTransaction: SmartTransaction,\n prevSmartTransaction?: SmartTransaction,\n ) {\n let updatedSmartTransaction = cloneDeep(smartTransaction);\n updatedSmartTransaction = {\n ...cloneDeep(prevSmartTransaction),\n ...updatedSmartTransaction,\n };\n\n if (updatedSmartTransaction.status === prevSmartTransaction?.status) {\n return; // If status hasn't changed, don't track it again.\n }\n\n this.#trackMetaMetricsEvent({\n event: MetaMetricsEventName.StxStatusUpdated,\n category: MetaMetricsEventCategory.Transactions,\n properties: getSmartTransactionMetricsProperties(updatedSmartTransaction),\n sensitiveProperties: getSmartTransactionMetricsSensitiveProperties(\n updatedSmartTransaction,\n ),\n });\n }\n\n isNewSmartTransaction(smartTransactionUuid: string, chainId?: Hex): boolean {\n const {\n smartTransactionsState: { smartTransactions },\n } = this.state;\n const currentSmartTransactions =\n smartTransactions[chainId ?? this.#chainId];\n const currentIndex = currentSmartTransactions?.findIndex(\n (stx) => stx.uuid === smartTransactionUuid,\n );\n return currentIndex === -1 || currentIndex === undefined;\n }\n\n updateSmartTransaction(\n smartTransaction: SmartTransaction,\n { networkClientId }: { networkClientId?: NetworkClientId } = {},\n ) {\n let ethQuery = this.#ethQuery;\n let chainId = this.#chainId;\n if (networkClientId) {\n const { configuration, provider } = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n chainId = configuration.chainId;\n ethQuery = new EthQuery(provider);\n }\n\n this.#createOrUpdateSmartTransaction(smartTransaction, {\n chainId,\n ethQuery,\n });\n }\n\n #updateSmartTransaction(\n smartTransaction: SmartTransaction,\n {\n chainId = this.#chainId,\n }: {\n chainId: Hex;\n },\n ) {\n const {\n smartTransactionsState: { smartTransactions },\n } = this.state;\n const currentSmartTransactions = smartTransactions[chainId] ?? [];\n const currentIndex = currentSmartTransactions?.findIndex(\n (stx) => stx.uuid === smartTransaction.uuid,\n );\n\n if (currentIndex === -1) {\n return; // Smart transaction not found, don't update anything.\n }\n\n if (!isSafeDynamicKey(chainId)) {\n return;\n }\n\n this.update((state) => {\n state.smartTransactionsState.smartTransactions[chainId][currentIndex] = {\n ...state.smartTransactionsState.smartTransactions[chainId][\n currentIndex\n ],\n ...smartTransaction,\n };\n });\n }\n\n async #addMetaMetricsPropsToNewSmartTransaction(\n smartTransaction: SmartTransaction,\n ) {\n const metaMetricsProps = await this.#getMetaMetricsProps();\n smartTransaction.accountHardwareType =\n metaMetricsProps?.accountHardwareType;\n smartTransaction.accountType = metaMetricsProps?.accountType;\n smartTransaction.deviceModel = metaMetricsProps?.deviceModel;\n }\n\n async #createOrUpdateSmartTransaction(\n smartTransaction: SmartTransaction,\n {\n chainId = this.#chainId,\n ethQuery = this.#ethQuery,\n }: {\n chainId: Hex;\n ethQuery: EthQuery | undefined;\n },\n ): Promise<void> {\n const {\n smartTransactionsState: { smartTransactions },\n } = this.state;\n const currentSmartTransactions = smartTransactions[chainId] ?? [];\n const currentIndex = currentSmartTransactions?.findIndex(\n (stx) => stx.uuid === smartTransaction.uuid,\n );\n const isNewSmartTransaction = this.isNewSmartTransaction(\n smartTransaction.uuid,\n chainId,\n );\n if (this.#ethQuery === undefined) {\n throw new Error(ETH_QUERY_ERROR_MSG);\n }\n\n if (isNewSmartTransaction) {\n await this.#addMetaMetricsPropsToNewSmartTransaction(smartTransaction);\n }\n\n this.trackStxStatusChange(\n smartTransaction,\n isNewSmartTransaction\n ? undefined\n : currentSmartTransactions[currentIndex],\n );\n\n if (isNewSmartTransaction) {\n // add smart transaction\n const cancelledNonceIndex = currentSmartTransactions?.findIndex(\n (stx: SmartTransaction) =>\n stx.txParams?.nonce === smartTransaction.txParams?.nonce &&\n stx.status?.startsWith('cancelled'),\n );\n const snapshot = cloneDeep(smartTransaction);\n const history = [snapshot];\n const historifiedSmartTransaction = { ...smartTransaction, history };\n const nextSmartTransactions =\n cancelledNonceIndex > -1\n ? currentSmartTransactions\n .slice(0, cancelledNonceIndex)\n .concat(currentSmartTransactions.slice(cancelledNonceIndex + 1))\n .concat(historifiedSmartTransaction)\n : currentSmartTransactions.concat(historifiedSmartTransaction);\n\n this.update((state) => {\n state.smartTransactionsState.smartTransactions[chainId] =\n nextSmartTransactions;\n });\n return;\n }\n\n const currentSmartTransaction = currentSmartTransactions[currentIndex];\n const nextSmartTransaction = {\n ...currentSmartTransaction,\n ...smartTransaction,\n };\n\n // We have to emit this event here, because then a txHash is returned to the TransactionController once it's available\n // and the #doesTransactionNeedConfirmation function will work properly, since it will find the txHash in the regular transactions list.\n this.messagingSystem.publish(\n `SmartTransactionsController:smartTransaction`,\n nextSmartTransaction,\n );\n\n if (\n shouldMarkRegularTransactionAsFailed({\n smartTransaction: nextSmartTransaction,\n clientId: this.#clientId,\n getFeatureFlags: this.#getFeatureFlags,\n })\n ) {\n markRegularTransactionAsFailed({\n smartTransaction: nextSmartTransaction,\n getRegularTransactions: this.#getRegularTransactions,\n updateTransaction: this.#updateTransaction,\n });\n }\n\n if (\n (smartTransaction.status === SmartTransactionStatuses.SUCCESS ||\n smartTransaction.status === SmartTransactionStatuses.REVERTED) &&\n !smartTransaction.confirmed\n ) {\n await this.#confirmSmartTransaction(nextSmartTransaction, {\n chainId,\n ethQuery,\n });\n } else {\n this.#updateSmartTransaction(smartTransaction, {\n chainId,\n });\n }\n }\n\n async updateSmartTransactions(\n {\n chainIds,\n }: {\n chainIds: Hex[];\n } = {\n chainIds: this.#getChainIds(),\n },\n ): Promise<void> {\n const {\n smartTransactionsState: { smartTransactions },\n } = this.state;\n\n // Iterate over each chain group directly\n for (const [chainId, transactions] of Object.entries(smartTransactions)) {\n if (chainIds && !chainIds.includes(chainId as Hex)) {\n continue;\n }\n // Filter pending transactions and map them to the desired shape\n const pendingTransactions = transactions\n .filter(isSmartTransactionPending)\n .map((pendingSmartTransaction) => {\n // Use the transaction's chainId (from the key) to derive a networkClientId\n const networkClientIdToUse = this.#getNetworkClientId({\n chainId: chainId as Hex,\n });\n return {\n uuid: pendingSmartTransaction.uuid,\n networkClientId: networkClientIdToUse,\n chainId: pendingSmartTransaction.chainId as Hex, // same as the key, but explicit on the transaction\n };\n });\n\n if (pendingTransactions.length > 0) {\n // Since each group is per chain, all transactions share the same chainId.\n await this.fetchSmartTransactionsStatus(pendingTransactions);\n }\n }\n }\n\n #doesTransactionNeedConfirmation(txHash: string | undefined): boolean {\n if (!txHash) {\n return true;\n }\n const transactions = this.#getRegularTransactions();\n const foundTransaction = transactions?.find((tx) => {\n return tx.hash?.toLowerCase() === txHash.toLowerCase();\n });\n if (!foundTransaction) {\n return true;\n }\n // If a found transaction is either confirmed or submitted, it doesn't need confirmation from the STX controller.\n // When it's in the submitted state, the TransactionController checks its status and confirms it,\n // so no need to confirm it again here.\n return ![TransactionStatus.confirmed, TransactionStatus.submitted].includes(\n foundTransaction.status,\n );\n }\n\n async #confirmSmartTransaction(\n smartTransaction: SmartTransaction,\n {\n chainId = this.#chainId,\n ethQuery = this.#ethQuery,\n }: {\n chainId: Hex;\n ethQuery: EthQuery | undefined;\n },\n ) {\n if (ethQuery === undefined) {\n throw new Error(ETH_QUERY_ERROR_MSG);\n }\n const txHash = smartTransaction.statusMetadata?.minedHash;\n try {\n const transactionReceipt: {\n maxFeePerGas?: string;\n maxPriorityFeePerGas?: string;\n blockNumber: string;\n } | null = await query(ethQuery, 'getTransactionReceipt', [txHash]);\n const transaction: {\n maxFeePerGas?: string;\n maxPriorityFeePerGas?: string;\n } | null = await query(ethQuery, 'getTransactionByHash', [txHash]);\n\n const maxFeePerGas = transaction?.maxFeePerGas;\n const maxPriorityFeePerGas = transaction?.maxPriorityFeePerGas;\n if (transactionReceipt?.blockNumber) {\n const blockData: { baseFeePerGas?: Hex } | null = await query(\n ethQuery,\n 'getBlockByNumber',\n [transactionReceipt?.blockNumber, false],\n );\n const baseFeePerGas = blockData?.baseFeePerGas;\n const updatedTxParams = {\n ...smartTransaction.txParams,\n maxFeePerGas,\n maxPriorityFeePerGas,\n };\n // call confirmExternalTransaction\n const originalTxMeta = {\n ...smartTransaction,\n id: smartTransaction.uuid,\n status: TransactionStatus.confirmed,\n hash: txHash,\n txParams: updatedTxParams,\n };\n // create txMeta snapshot for history\n const snapshot = snapshotFromTxMeta(originalTxMeta);\n // recover previous tx state obj\n const previousState = replayHistory(originalTxMeta.history);\n // generate history entry and add to history\n const entry = generateHistoryEntry(\n previousState,\n snapshot,\n 'txStateManager: setting status to confirmed',\n );\n const txMeta =\n entry.length > 0\n ? {\n ...originalTxMeta,\n history: originalTxMeta.history.concat(entry),\n }\n : originalTxMeta;\n\n if (this.#doesTransactionNeedConfirmation(txHash)) {\n this.#confirmExternalTransaction(\n // TODO: Replace 'as' assertion with correct typing for `txMeta`\n txMeta as TransactionMeta,\n transactionReceipt,\n // TODO: Replace 'as' assertion with correct typing for `baseFeePerGas`\n baseFeePerGas as Hex,\n );\n }\n this.#trackMetaMetricsEvent({\n event: MetaMetricsEventName.StxConfirmed,\n category: MetaMetricsEventCategory.Transactions,\n properties: getSmartTransactionMetricsProperties(smartTransaction),\n sensitiveProperties:\n getSmartTransactionMetricsSensitiveProperties(smartTransaction),\n });\n this.#updateSmartTransaction(\n { ...smartTransaction, confirmed: true },\n {\n chainId,\n },\n );\n }\n } catch (error) {\n this.#trackMetaMetricsEvent({\n event: MetaMetricsEventName.StxConfirmationFailed,\n category: MetaMetricsEventCategory.Transactions,\n });\n console.error('confirm error', error);\n } finally {\n this.messagingSystem.publish(\n `SmartTransactionsController:smartTransactionConfirmationDone`,\n smartTransaction,\n );\n }\n }\n\n // ! Ask backend API to accept list of uuids as params\n async fetchSmartTransactionsStatus(\n transactions: {\n uuid: string;\n networkClientId?: NetworkClientId;\n chainId: Hex;\n }[],\n ): Promise<Record<string, SmartTransactionsStatus>> {\n // Since transactions come from the same chain group, take the chainId from the first one.\n const { chainId } = transactions[0];\n\n // Build query parameters with all UUIDs\n const uuids = transactions.map((tx) => tx.uuid);\n const params = new URLSearchParams({ uuids: uuids.join(',') });\n\n // Get the ethQuery for the first transaction's networkClientId\n const ethQuery = this.#getEthQuery({\n networkClientId: transactions[0].networkClientId,\n });\n\n // Construct the URL and fetch the data\n const url = `${getAPIRequestURL(\n APIType.BATCH_STATUS,\n chainId,\n )}?${params.toString()}`;\n const data = (await this.#fetch(url)) as Record<\n string,\n SmartTransactionsStatus\n >;\n\n // Process each returned status\n for (const [uuid, stxStatus] of Object.entries(data)) {\n const matchingTx = transactions.find((tx) => tx.uuid === uuid);\n if (!matchingTx) {\n console.error(`No matching transaction found for uuid: ${uuid}`);\n continue;\n }\n\n const smartTransaction: SmartTransaction = {\n statusMetadata: stxStatus,\n status: calculateStatus(stxStatus),\n cancellable: isSmartTransactionCancellable(stxStatus),\n uuid,\n networkClientId: matchingTx.networkClientId,\n };\n\n await this.#createOrUpdateSmartTransaction(smartTransaction, {\n chainId,\n ethQuery,\n });\n }\n\n return data;\n }\n\n async #addNonceToTransaction(\n transaction: UnsignedTransaction,\n networkClientId: NetworkClientId,\n ): Promise<UnsignedTransaction> {\n const nonceLock = await this.#getNonceLock(\n transaction.from,\n networkClientId,\n );\n const nonce = nonceLock.nextNonce;\n nonceLock.releaseLock();\n return {\n ...transaction,\n nonce: `0x${nonce.toString(16)}`,\n };\n }\n\n clearFees(): Fees {\n const fees = {\n approvalTxFees: null,\n tradeTxFees: null,\n };\n this.update((state) => {\n state.smartTransactionsState.fees = fees;\n });\n\n return fees;\n }\n\n async getFees(\n tradeTx: UnsignedTransaction,\n approvalTx?: UnsignedTransaction,\n { networkClientId }: { networkClientId?: NetworkClientId } = {},\n ): Promise<Fees> {\n const selectedNetworkClientId =\n networkClientId ??\n this.messagingSystem.call('NetworkController:getState')\n .selectedNetworkClientId;\n const chainId = this.#getChainId({\n networkClientId: selectedNetworkClientId,\n });\n const transactions = [];\n let unsignedTradeTransactionWithNonce;\n if (approvalTx) {\n const unsignedApprovalTransactionWithNonce =\n await this.#addNonceToTransaction(approvalTx, selectedNetworkClientId);\n transactions.push(unsignedApprovalTransactionWithNonce);\n unsignedTradeTransactionWithNonce = {\n ...tradeTx,\n // If there is an approval tx, the trade tx's nonce is increased by 1.\n nonce: incrementNonceInHex(unsignedApprovalTransactionWithNonce.nonce),\n };\n } else if (tradeTx.nonce) {\n unsignedTradeTransactionWithNonce = tradeTx;\n } else {\n unsignedTradeTransactionWithNonce = await this.#addNonceToTransaction(\n tradeTx,\n selectedNetworkClientId,\n );\n }\n transactions.push(unsignedTradeTransactionWithNonce);\n const data = await this.#fetch(\n getAPIRequestURL(APIType.GET_FEES, chainId),\n {\n method: 'POST',\n body: JSON.stringify({\n txs: transactions,\n }),\n },\n );\n let approvalTxFees: IndividualTxFees | null;\n let tradeTxFees: IndividualTxFees | null;\n if (approvalTx) {\n approvalTxFees = data?.txs[0];\n tradeTxFees = data?.txs[1];\n } else {\n approvalTxFees = null;\n tradeTxFees = data?.txs[0];\n }\n\n this.update((state) => {\n if (chainId === this.#chainId) {\n state.smartTransactionsState.fees = {\n approvalTxFees,\n tradeTxFees,\n };\n }\n state.smartTransactionsState.feesByChainId[chainId] = {\n approvalTxFees,\n tradeTxFees,\n };\n });\n\n return {\n approvalTxFees,\n tradeTxFees,\n };\n }\n\n // * After this successful call client must add a nonce representative to\n // * transaction controller external transactions list\n async submitSignedTransactions({\n transactionMeta,\n txParams,\n signedTransactions,\n signedCanceledTransactions,\n networkClientId,\n }: {\n signedTransactions: SignedTransaction[];\n signedCanceledTransactions: SignedCanceledTransaction[];\n transactionMeta?: TransactionMeta;\n txParams?: TransactionParams;\n networkClientId?: NetworkClientId;\n }) {\n const selectedNetworkClientId =\n networkClientId ??\n this.messagingSystem.call('NetworkController:getState')\n .selectedNetworkClientId;\n const chainId = this.#getChainId({\n networkClientId: selectedNetworkClientId,\n });\n const ethQuery = this.#getEthQuery({\n networkClientId: selectedNetworkClientId,\n });\n const data = await this.#fetch(\n getAPIRequestURL(APIType.SUBMIT_TRANSACTIONS, chainId),\n {\n method: 'POST',\n body: JSON.stringify({\n rawTxs: signedTransactions,\n rawCancelTxs: signedCanceledTransactions,\n }),\n },\n );\n const time = Date.now();\n let preTxBalance;\n try {\n const preTxBalanceBN = await query(ethQuery, 'getBalance', [\n txParams?.from,\n ]);\n preTxBalance = new BigNumber(preTxBalanceBN).toString(16);\n } catch (error) {\n console.error('provider error', error);\n }\n\n const requiresNonce = txParams && !txParams.nonce;\n let nonce;\n let nonceLock;\n let nonceDetails = {};\n\n if (requiresNonce) {\n nonceLock = await this.#getNonceLock(\n txParams.from,\n selectedNetworkClientId,\n );\n nonce = hexlify(nonceLock.nextNonce);\n nonceDetails = nonceLock.nonceDetails;\n txParams.nonce ??= nonce;\n }\n const submitTransactionResponse = {\n ...data,\n txHash: getTxHash(signedTransactions[0]),\n };\n\n try {\n await this.#createOrUpdateSmartTransaction(\n {\n chainId,\n nonceDetails,\n preTxBalance,\n status: SmartTransactionStatuses.PENDING,\n time,\n txParams,\n uuid: submitTransactionResponse.uuid,\n txHash: submitTransactionResponse.txHash,\n cancellable: true,\n type: transactionMeta?.type ?? 'swap',\n transactionId: transactionMeta?.id,\n networkClientId: selectedNetworkClientId,\n },\n { chainId, ethQuery },\n );\n } finally {\n nonceLock?.releaseLock();\n }\n\n return submitTransactionResponse;\n }\n\n #getChainId({\n networkClientId,\n }: { networkClientId?: NetworkClientId } = {}): Hex {\n if (networkClientId) {\n return this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n ).configuration.chainId;\n }\n\n return this.#chainId;\n }\n\n #getChainIds(): Hex[] {\n const { networkConfigurationsByChainId } = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n return Object.keys(networkConfigurationsByChainId).filter(\n (chainId): chainId is Hex =>\n this.#supportedChainIds.includes(chainId as Hex),\n );\n }\n\n #getNetworkClientId({ chainId }: { chainId: string }): string {\n const { networkConfigurationsByChainId } = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n return networkConfigurationsByChainId[chainId as Hex].rpcEndpoints[\n networkConfigurationsByChainId[chainId as Hex].defaultRpcEndpointIndex\n ].networkClientId;\n }\n\n #getEthQuery({\n networkClientId,\n }: {\n networkClientId?: NetworkClientId;\n } = {}): EthQuery {\n if (networkClientId) {\n const { provider } = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n return new EthQuery(provider);\n }\n\n if (this.#ethQuery === undefined) {\n throw new Error(ETH_QUERY_ERROR_MSG);\n }\n\n return this.#ethQuery;\n }\n\n // TODO: This should return if the cancellation was on chain or not (for nonce management)\n // After this successful call client must update nonce representative\n // in transaction controller external transactions list\n async cancelSmartTransaction(\n uuid: string,\n {\n networkClientId,\n }: {\n networkClientId?: NetworkClientId;\n } = {},\n ): Promise<void> {\n const chainId = this.#getChainId({ networkClientId });\n await this.#fetch(getAPIRequestURL(APIType.CANCEL, chainId), {\n method: 'POST',\n body: JSON.stringify({ uuid }),\n });\n }\n\n async fetchLiveness({\n networkClientId,\n }: {\n networkClientId?: NetworkClientId;\n } = {}): Promise<boolean> {\n const chainId = this.#getChainId({ networkClientId });\n let liveness = false;\n try {\n const response = await this.#fetch(\n getAPIRequestURL(APIType.LIVENESS, chainId),\n );\n liveness = Boolean(response.smartTransactions);\n } catch (error) {\n console.log('\"fetchLiveness\" API call failed');\n }\n\n this.update((state) => {\n if (chainId === this.#chainId) {\n state.smartTransactionsState.liveness = liveness;\n }\n state.smartTransactionsState.livenessByChainId[chainId] = liveness;\n });\n\n return liveness;\n }\n\n async setStatusRefreshInterval(interval: number): Promise<void> {\n if (interval !== this.#interval) {\n this.#interval = interval;\n }\n }\n\n #getCurrentSmartTransactions(): SmartTransaction[] {\n const {\n smartTransactionsState: { smartTransactions },\n } = this.state;\n const smartTransactionsForAllChains =\n Object.values(smartTransactions).flat();\n if (\n !smartTransactionsForAllChains ||\n smartTransactionsForAllChains.length === 0\n ) {\n return [];\n }\n return smartTransactionsForAllChains;\n }\n\n getTransactions({\n addressFrom,\n status,\n }: {\n addressFrom: string;\n status: SmartTransactionStatuses;\n }): SmartTransaction[] {\n const currentSmartTransactions = this.#getCurrentSmartTransactions();\n return currentSmartTransactions.filter((stx) => {\n return stx.status === status && stx.txParams?.from === addressFrom;\n });\n }\n\n getSmartTransactionByMinedTxHash(\n txHash: string | undefined,\n ): SmartTransaction | undefined {\n if (!txHash) {\n return undefined;\n }\n const currentSmartTransactions = this.#getCurrentSmartTransactions();\n return currentSmartTransactions.find((smartTransaction) => {\n return (\n smartTransaction.statusMetadata?.minedHash?.toLowerCase() ===\n txHash.toLowerCase()\n );\n });\n }\n\n wipeSmartTransactions({\n address,\n ignoreNetwork,\n }: {\n address: string;\n ignoreNetwork?: boolean;\n }): void {\n if (!address) {\n return;\n }\n const addressLowerCase = address.toLowerCase();\n if (ignoreNetwork) {\n const {\n smartTransactionsState: { smartTransactions },\n } = this.state;\n (Object.keys(smartTransactions) as Hex[]).forEach((chainId) => {\n this.#wipeSmartTransactionsPerChainId({\n chainId,\n addressLowerCase,\n });\n });\n } else {\n this.#wipeSmartTransactionsPerChainId({\n chainId: this.#chainId,\n addressLowerCase,\n });\n }\n }\n\n #wipeSmartTransactionsPerChainId({\n chainId,\n addressLowerCase,\n }: {\n chainId: Hex;\n addressLowerCase: string;\n }): void {\n const {\n smartTransactionsState: { smartTransactions },\n } = this.state;\n const smartTransactionsForSelectedChain: SmartTransaction[] =\n smartTransactions?.[chainId];\n if (\n !smartTransactionsForSelectedChain ||\n smartTransactionsForSelectedChain.length === 0\n ) {\n return;\n }\n const newSmartTransactionsForSelectedChain =\n smartTransactionsForSelectedChain.filter(\n (smartTransaction: SmartTransaction) =>\n smartTransaction.txParams?.from !== addressLowerCase,\n );\n this.update((state) => {\n state.smartTransactionsState.smartTransactions[chainId] =\n newSmartTransactionsForSelectedChain;\n });\n }\n}\n"]}
|
package/dist/constants.js
CHANGED
|
@@ -6,6 +6,7 @@ exports.API_BASE_URL = 'https://transaction.api.cx.metamask.io';
|
|
|
6
6
|
exports.SENTINEL_API_BASE_URL_MAP = {
|
|
7
7
|
1: 'https://tx-sentinel-ethereum-mainnet.api.cx.metamask.io',
|
|
8
8
|
56: 'https://tx-sentinel-bsc-mainnet.api.cx.metamask.io',
|
|
9
|
+
8453: 'https://tx-sentinel-base-mainnet.api.cx.metamask.io',
|
|
9
10
|
11155111: 'https://tx-sentinel-ethereum-sepolia.api.cx.metamask.io',
|
|
10
11
|
};
|
|
11
12
|
var MetaMetricsEventName;
|
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,YAAY,GAAG,wCAAwC,CAAC;AAMrE,6BAA6B;AAChB,QAAA,yBAAyB,GAA0B;IAC9D,CAAC,EAAE,yDAAyD;IAC5D,EAAE,EAAE,oDAAoD;IACxD,QAAQ,EAAE,yDAAyD;CACpE,CAAC;AAEF,IAAY,oBAKX;AALD,WAAY,oBAAoB;IAC9B,+DAAuC,CAAA;IACvC,sDAA8B,CAAA;IAC9B,yEAAiD,CAAA;IACjD,0DAAkC,CAAA;AACpC,CAAC,EALW,oBAAoB,GAApB,4BAAoB,KAApB,4BAAoB,QAK/B;AAED,IAAY,wBAGX;AAHD,WAAY,wBAAwB;IAClC,yDAA6B,CAAA;IAC7B,qDAAyB,CAAA;AAC3B,CAAC,EAHW,wBAAwB,GAAxB,gCAAwB,KAAxB,gCAAwB,QAGnC","sourcesContent":["export const API_BASE_URL = 'https://transaction.api.cx.metamask.io';\n\ntype SentinelApiBaseUrlMap = {\n [key: number]: string;\n};\n\n// The map with types applied\nexport const SENTINEL_API_BASE_URL_MAP: SentinelApiBaseUrlMap = {\n 1: 'https://tx-sentinel-ethereum-mainnet.api.cx.metamask.io',\n 56: 'https://tx-sentinel-bsc-mainnet.api.cx.metamask.io',\n 11155111: 'https://tx-sentinel-ethereum-sepolia.api.cx.metamask.io',\n};\n\nexport enum MetaMetricsEventName {\n StxStatusUpdated = 'STX Status Updated',\n StxConfirmed = 'STX Confirmed',\n StxConfirmationFailed = 'STX Confirmation Failed',\n ReceiveRequest = 'Receive Request',\n}\n\nexport enum MetaMetricsEventCategory {\n Transactions = 'Transactions',\n Navigation = 'Navigation',\n}\n"]}
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,YAAY,GAAG,wCAAwC,CAAC;AAMrE,6BAA6B;AAChB,QAAA,yBAAyB,GAA0B;IAC9D,CAAC,EAAE,yDAAyD;IAC5D,EAAE,EAAE,oDAAoD;IACxD,IAAI,EAAE,qDAAqD;IAC3D,QAAQ,EAAE,yDAAyD;CACpE,CAAC;AAEF,IAAY,oBAKX;AALD,WAAY,oBAAoB;IAC9B,+DAAuC,CAAA;IACvC,sDAA8B,CAAA;IAC9B,yEAAiD,CAAA;IACjD,0DAAkC,CAAA;AACpC,CAAC,EALW,oBAAoB,GAApB,4BAAoB,KAApB,4BAAoB,QAK/B;AAED,IAAY,wBAGX;AAHD,WAAY,wBAAwB;IAClC,yDAA6B,CAAA;IAC7B,qDAAyB,CAAA;AAC3B,CAAC,EAHW,wBAAwB,GAAxB,gCAAwB,KAAxB,gCAAwB,QAGnC","sourcesContent":["export const API_BASE_URL = 'https://transaction.api.cx.metamask.io';\n\ntype SentinelApiBaseUrlMap = {\n [key: number]: string;\n};\n\n// The map with types applied\nexport const SENTINEL_API_BASE_URL_MAP: SentinelApiBaseUrlMap = {\n 1: 'https://tx-sentinel-ethereum-mainnet.api.cx.metamask.io',\n 56: 'https://tx-sentinel-bsc-mainnet.api.cx.metamask.io',\n 8453: 'https://tx-sentinel-base-mainnet.api.cx.metamask.io',\n 11155111: 'https://tx-sentinel-ethereum-sepolia.api.cx.metamask.io',\n};\n\nexport enum MetaMetricsEventName {\n StxStatusUpdated = 'STX Status Updated',\n StxConfirmed = 'STX Confirmed',\n StxConfirmationFailed = 'STX Confirmation Failed',\n ReceiveRequest = 'Receive Request',\n}\n\nexport enum MetaMetricsEventCategory {\n Transactions = 'Transactions',\n Navigation = 'Navigation',\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamask/smart-transactions-controller",
|
|
3
|
-
"version": "16.0
|
|
3
|
+
"version": "16.2.0",
|
|
4
4
|
"description": "Improves success rates for swaps by trialing transactions privately and finding minimum fees",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -16,10 +16,11 @@
|
|
|
16
16
|
"build": "tsc --project tsconfig.build.json",
|
|
17
17
|
"build:clean": "rm -rf dist && yarn build",
|
|
18
18
|
"build:link": "yarn build && cd dist && yarn link && rm -rf node_modules && cd ..",
|
|
19
|
-
"lint": "yarn lint:eslint && yarn lint:misc --check",
|
|
19
|
+
"lint": "yarn lint:eslint && yarn lint:misc --check && yarn lint:changelog",
|
|
20
|
+
"lint:changelog": "auto-changelog validate --prettier",
|
|
20
21
|
"lint:eslint": "eslint . --cache --ext js,ts",
|
|
21
|
-
"lint:fix": "yarn lint:eslint --fix && yarn lint:misc --write",
|
|
22
|
-
"lint:misc": "prettier '**/*.json' '**/*.md' '
|
|
22
|
+
"lint:fix": "yarn lint:eslint --fix && yarn lint:misc --write && yarn lint:changelog",
|
|
23
|
+
"lint:misc": "prettier '**/*.json' '**/*.md' '**/*.yml' '!.yarnrc.yml' --ignore-path .gitignore --no-error-on-unmatched-pattern",
|
|
23
24
|
"prepack": "./scripts/prepack.sh",
|
|
24
25
|
"test": "jest",
|
|
25
26
|
"test:watch": "jest --watchAll"
|