@metamask/transaction-controller 68.1.1 → 68.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -1
- package/dist/helpers/GasFeePoller.d.cts +2 -0
- package/dist/helpers/GasFeePoller.d.cts.map +1 -1
- package/dist/helpers/GasFeePoller.d.mts +2 -0
- package/dist/helpers/GasFeePoller.d.mts.map +1 -1
- package/dist/helpers/MethodDataHelper.d.cts +2 -0
- package/dist/helpers/MethodDataHelper.d.cts.map +1 -1
- package/dist/helpers/MethodDataHelper.d.mts +2 -0
- package/dist/helpers/MethodDataHelper.d.mts.map +1 -1
- package/dist/helpers/PendingTransactionTracker.d.cts +2 -0
- package/dist/helpers/PendingTransactionTracker.d.cts.map +1 -1
- package/dist/helpers/PendingTransactionTracker.d.mts +2 -0
- package/dist/helpers/PendingTransactionTracker.d.mts.map +1 -1
- package/dist/helpers/ResimulateHelper.cjs +18 -10
- package/dist/helpers/ResimulateHelper.cjs.map +1 -1
- package/dist/helpers/ResimulateHelper.d.cts.map +1 -1
- package/dist/helpers/ResimulateHelper.d.mts.map +1 -1
- package/dist/helpers/ResimulateHelper.mjs +18 -10
- package/dist/helpers/ResimulateHelper.mjs.map +1 -1
- package/dist/utils/batch.cjs +6 -2
- package/dist/utils/batch.cjs.map +1 -1
- package/dist/utils/batch.d.cts.map +1 -1
- package/dist/utils/batch.d.mts.map +1 -1
- package/dist/utils/batch.mjs +6 -2
- package/dist/utils/batch.mjs.map +1 -1
- package/dist/utils/feature-flags.cjs +2 -1
- package/dist/utils/feature-flags.cjs.map +1 -1
- package/dist/utils/feature-flags.d.cts +8 -0
- package/dist/utils/feature-flags.d.cts.map +1 -1
- package/dist/utils/feature-flags.d.mts +8 -0
- package/dist/utils/feature-flags.d.mts.map +1 -1
- package/dist/utils/feature-flags.mjs +2 -1
- package/dist/utils/feature-flags.mjs.map +1 -1
- package/dist/utils/gas.cjs +11 -2
- package/dist/utils/gas.cjs.map +1 -1
- package/dist/utils/gas.d.cts.map +1 -1
- package/dist/utils/gas.d.mts.map +1 -1
- package/dist/utils/gas.mjs +11 -2
- package/dist/utils/gas.mjs.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [68.2.1]
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Bump `@metamask/core-backend` from `^6.3.3` to `^6.4.0` ([#9312](https://github.com/MetaMask/core/pull/9312))
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- Resimulate the latest transaction data instead of stale data captured when resimulation started, fixing flickering simulation results after a transaction is updated ([#9287](https://github.com/MetaMask/core/pull/9287))
|
|
19
|
+
|
|
20
|
+
## [68.2.0]
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- Add optional `maxGasLimit` to the `gasEstimateFallback` feature flag config, clamping the fixed or percentage-derived gas estimate fallback to a chain's per-transaction gas cap so it can never exceed the limit the RPC will accept ([#9191](https://github.com/MetaMask/core/pull/9191))
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- Bump `@metamask/accounts-controller` from `^39.0.2` to `^39.0.3` ([#9231](https://github.com/MetaMask/core/pull/9231))
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- Add explicit error when submitting a batch that requires EIP-7702 but the account or chain does not support it ([#9240](https://github.com/MetaMask/core/pull/9240))
|
|
33
|
+
|
|
10
34
|
## [68.1.1]
|
|
11
35
|
|
|
12
36
|
### Changed
|
|
@@ -2521,7 +2545,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
2521
2545
|
|
|
2522
2546
|
All changes listed after this point were applied to this package following the monorepo conversion.
|
|
2523
2547
|
|
|
2524
|
-
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@68.
|
|
2548
|
+
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@68.2.1...HEAD
|
|
2549
|
+
[68.2.1]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@68.2.0...@metamask/transaction-controller@68.2.1
|
|
2550
|
+
[68.2.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@68.1.1...@metamask/transaction-controller@68.2.0
|
|
2525
2551
|
[68.1.1]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@68.1.0...@metamask/transaction-controller@68.1.1
|
|
2526
2552
|
[68.1.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@68.0.1...@metamask/transaction-controller@68.1.0
|
|
2527
2553
|
[68.0.1]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@68.0.0...@metamask/transaction-controller@68.0.1
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node/events" />
|
|
3
|
+
/// <reference types="npm-which/node_modules/@types/node/events" />
|
|
2
4
|
import type { FetchGasFeeEstimateOptions, GasFeeState } from "@metamask/gas-fee-controller";
|
|
3
5
|
import type { Hex } from "@metamask/utils";
|
|
4
6
|
import EventEmitter from "events";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GasFeePoller.d.cts","sourceRoot":"","sources":["../../src/helpers/GasFeePoller.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"GasFeePoller.d.cts","sourceRoot":"","sources":["../../src/helpers/GasFeePoller.ts"],"names":[],"mappings":";;;AAAA,OAAO,KAAK,EACV,0BAA0B,EAC1B,WAAW,EACZ,qCAAqC;AAEtC,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAI3C,OAAO,YAAY,eAAe;AAIlC,OAAO,KAAK,EAAE,8BAA8B,EAAE,qCAAiC;AAC/E,OAAO,KAAK,EACV,eAAe,EACf,UAAU,EAEV,gBAAgB,EAChB,eAAe,EAEf,oBAAoB,EACrB,qBAAiB;AAClB,OAAO,EACL,mBAAmB,EAIpB,qBAAiB;AASlB;;GAEG;AACH,qBAAa,YAAY;;IACvB,GAAG,EAAE,YAAY,CAAsB;IAoBvC;;;;;;;;;;;OAWG;gBACS,EACV,WAAW,EACX,4BAA4B,EAC5B,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EACjB,SAAS,EACT,aAAa,GACd,EAAE;QACD,WAAW,EAAE,UAAU,EAAE,CAAC;QAC1B,4BAA4B,EAAE,CAC5B,OAAO,EAAE,0BAA0B,KAChC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC1B,eAAe,EAAE,MAAM,eAAe,EAAE,CAAC;QACzC,qBAAqB,EAAE,MAAM,oBAAoB,EAAE,CAAC;QACpD,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;QACtC,SAAS,EAAE,8BAA8B,CAAC;QAC1C,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;KAC/C;CA6SF;AAED;;;;;;;;;GASG;AACH,wBAAgB,8BAA8B,CAAC,EAC7C,eAAe,EACf,qBAAqB,EACrB,8BAA8B,EAC9B,YAAY,EACZ,MAAM,GACP,EAAE;IACD,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,8BAA8B,EAAE,CAAC,eAAe,EAAE,eAAe,KAAK,OAAO,CAAC;IAC9E,YAAY,CAAC,EAAE,GAAG,CAAC;IACnB,MAAM,EAAE,eAAe,CAAC;CACzB,GAAG,IAAI,CAiCP;AAED;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAAC,EAC5C,MAAM,EACN,YAAY,GACb,EAAE;IACD,MAAM,EAAE,eAAe,CAAC;IACxB,YAAY,EAAE,mBAAmB,CAAC;CACnC,GAAG,IAAI,CAgBP"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node/events" />
|
|
3
|
+
/// <reference types="npm-which/node_modules/@types/node/events" />
|
|
2
4
|
import type { FetchGasFeeEstimateOptions, GasFeeState } from "@metamask/gas-fee-controller";
|
|
3
5
|
import type { Hex } from "@metamask/utils";
|
|
4
6
|
import EventEmitter from "events";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GasFeePoller.d.mts","sourceRoot":"","sources":["../../src/helpers/GasFeePoller.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"GasFeePoller.d.mts","sourceRoot":"","sources":["../../src/helpers/GasFeePoller.ts"],"names":[],"mappings":";;;AAAA,OAAO,KAAK,EACV,0BAA0B,EAC1B,WAAW,EACZ,qCAAqC;AAEtC,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAI3C,OAAO,YAAY,eAAe;AAIlC,OAAO,KAAK,EAAE,8BAA8B,EAAE,qCAAiC;AAC/E,OAAO,KAAK,EACV,eAAe,EACf,UAAU,EAEV,gBAAgB,EAChB,eAAe,EAEf,oBAAoB,EACrB,qBAAiB;AAClB,OAAO,EACL,mBAAmB,EAIpB,qBAAiB;AASlB;;GAEG;AACH,qBAAa,YAAY;;IACvB,GAAG,EAAE,YAAY,CAAsB;IAoBvC;;;;;;;;;;;OAWG;gBACS,EACV,WAAW,EACX,4BAA4B,EAC5B,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EACjB,SAAS,EACT,aAAa,GACd,EAAE;QACD,WAAW,EAAE,UAAU,EAAE,CAAC;QAC1B,4BAA4B,EAAE,CAC5B,OAAO,EAAE,0BAA0B,KAChC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC1B,eAAe,EAAE,MAAM,eAAe,EAAE,CAAC;QACzC,qBAAqB,EAAE,MAAM,oBAAoB,EAAE,CAAC;QACpD,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;QACtC,SAAS,EAAE,8BAA8B,CAAC;QAC1C,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;KAC/C;CA6SF;AAED;;;;;;;;;GASG;AACH,wBAAgB,8BAA8B,CAAC,EAC7C,eAAe,EACf,qBAAqB,EACrB,8BAA8B,EAC9B,YAAY,EACZ,MAAM,GACP,EAAE;IACD,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,8BAA8B,EAAE,CAAC,eAAe,EAAE,eAAe,KAAK,OAAO,CAAC;IAC9E,YAAY,CAAC,EAAE,GAAG,CAAC;IACnB,MAAM,EAAE,eAAe,CAAC;CACzB,GAAG,IAAI,CAiCP;AAED;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAAC,EAC5C,MAAM,EACN,YAAY,GACb,EAAE;IACD,MAAM,EAAE,eAAe,CAAC;IACxB,YAAY,EAAE,mBAAmB,CAAC;CACnC,GAAG,IAAI,CAgBP"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node/events" />
|
|
3
|
+
/// <reference types="npm-which/node_modules/@types/node/events" />
|
|
2
4
|
import type { NetworkClientId } from "@metamask/network-controller";
|
|
3
5
|
import EventEmitter from "events";
|
|
4
6
|
import type { MethodData, TransactionControllerMessenger } from "../TransactionController.cjs";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MethodDataHelper.d.cts","sourceRoot":"","sources":["../../src/helpers/MethodDataHelper.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MethodDataHelper.d.cts","sourceRoot":"","sources":["../../src/helpers/MethodDataHelper.ts"],"names":[],"mappings":";;;AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,qCAAqC;AAMpE,OAAO,YAAY,eAAe;AAGlC,OAAO,KAAK,EACV,UAAU,EACV,8BAA8B,EAC/B,qCAAiC;AAKlC,qBAAa,gBAAgB;;IAC3B,GAAG,EAAE,YAAY,CAAC;gBAaN,EACV,SAAS,EACT,QAAQ,GACT,EAAE;QACD,SAAS,EAAE,8BAA8B,CAAC;QAC1C,QAAQ,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;KAC5C;IAQK,MAAM,CACV,cAAc,EAAE,MAAM,EACtB,eAAe,EAAE,eAAe,GAC/B,OAAO,CAAC,UAAU,CAAC;CA8DvB"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node/events" />
|
|
3
|
+
/// <reference types="npm-which/node_modules/@types/node/events" />
|
|
2
4
|
import type { NetworkClientId } from "@metamask/network-controller";
|
|
3
5
|
import EventEmitter from "events";
|
|
4
6
|
import type { MethodData, TransactionControllerMessenger } from "../TransactionController.mjs";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MethodDataHelper.d.mts","sourceRoot":"","sources":["../../src/helpers/MethodDataHelper.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MethodDataHelper.d.mts","sourceRoot":"","sources":["../../src/helpers/MethodDataHelper.ts"],"names":[],"mappings":";;;AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,qCAAqC;AAMpE,OAAO,YAAY,eAAe;AAGlC,OAAO,KAAK,EACV,UAAU,EACV,8BAA8B,EAC/B,qCAAiC;AAKlC,qBAAa,gBAAgB;;IAC3B,GAAG,EAAE,YAAY,CAAC;gBAaN,EACV,SAAS,EACT,QAAQ,GACT,EAAE;QACD,SAAS,EAAE,8BAA8B,CAAC;QAC1C,QAAQ,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;KAC5C;IAQK,MAAM,CACV,cAAc,EAAE,MAAM,EACtB,eAAe,EAAE,eAAe,GAC/B,OAAO,CAAC,UAAU,CAAC;CA8DvB"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node/events" />
|
|
3
|
+
/// <reference types="npm-which/node_modules/@types/node/events" />
|
|
2
4
|
import type { BlockTracker, NetworkClientId } from "@metamask/network-controller";
|
|
3
5
|
import EventEmitter from "events";
|
|
4
6
|
import type { TransactionControllerMessenger } from "../TransactionController.cjs";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PendingTransactionTracker.d.cts","sourceRoot":"","sources":["../../src/helpers/PendingTransactionTracker.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PendingTransactionTracker.d.cts","sourceRoot":"","sources":["../../src/helpers/PendingTransactionTracker.ts"],"names":[],"mappings":";;;AAAA,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EAChB,qCAAqC;AAItC,OAAO,YAAY,eAAe;AAIlC,OAAO,KAAK,EAAE,8BAA8B,EAAE,qCAAiC;AAC/E,OAAO,KAAK,EAAE,eAAe,EAAsB,qBAAiB;AA0BpE,KAAK,MAAM,GAAG;IACZ,uBAAuB,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACnD,qBAAqB,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACjD,oBAAoB,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAC9D,qBAAqB,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;CAChE,CAAC;AAKF,MAAM,WAAW,qCAAsC,SAAQ,YAAY;IACzE,EAAE,CAAC,SAAS,SAAS,MAAM,MAAM,EAC/B,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,KAAK,IAAI,GAC7C,IAAI,CAAC;IAER,IAAI,CAAC,SAAS,SAAS,MAAM,MAAM,EACjC,SAAS,EAAE,SAAS,EACpB,GAAG,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,GACzB,OAAO,CAAC;CACZ;AAED,qBAAa,yBAAyB;;IACpC,GAAG,EAAE,qCAAqC,CAAC;gBAkC/B,EACV,YAAY,EACZ,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,KAAK,EACL,SAAS,EACT,eAAe,GAChB,EAAE;QACD,YAAY,EAAE,YAAY,CAAC;QAC3B,aAAa,EAAE,MAAM,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;QACzC,eAAe,EAAE,MAAM,eAAe,EAAE,CAAC;QACzC,KAAK,CAAC,EAAE;YACN,6BAA6B,CAAC,EAAE,CAC9B,eAAe,EAAE,eAAe,KAC7B,OAAO,CAAC,OAAO,CAAC,CAAC;SACvB,CAAC;QACF,gBAAgB,EAAE,CAAC,eAAe,EAAE,eAAe,KAAK,OAAO,CAAC;QAChE,SAAS,EAAE,8BAA8B,CAAC;QAC1C,eAAe,EAAE,eAAe,CAAC;KAClC;IAgCD,0BAA0B,QAAO,IAAI,CAQnC;IAEF;;;;;;;;;;OAUG;IACH,oBAAoB,CAAC,eAAe,EAAE,eAAe,GAAG,IAAI;IAK5D;;;;OAIG;IACG,qBAAqB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BnE,IAAI,IAAI,IAAI;CA+bb"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node/events" />
|
|
3
|
+
/// <reference types="npm-which/node_modules/@types/node/events" />
|
|
2
4
|
import type { BlockTracker, NetworkClientId } from "@metamask/network-controller";
|
|
3
5
|
import EventEmitter from "events";
|
|
4
6
|
import type { TransactionControllerMessenger } from "../TransactionController.mjs";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PendingTransactionTracker.d.mts","sourceRoot":"","sources":["../../src/helpers/PendingTransactionTracker.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PendingTransactionTracker.d.mts","sourceRoot":"","sources":["../../src/helpers/PendingTransactionTracker.ts"],"names":[],"mappings":";;;AAAA,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EAChB,qCAAqC;AAItC,OAAO,YAAY,eAAe;AAIlC,OAAO,KAAK,EAAE,8BAA8B,EAAE,qCAAiC;AAC/E,OAAO,KAAK,EAAE,eAAe,EAAsB,qBAAiB;AA0BpE,KAAK,MAAM,GAAG;IACZ,uBAAuB,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACnD,qBAAqB,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACjD,oBAAoB,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAC9D,qBAAqB,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;CAChE,CAAC;AAKF,MAAM,WAAW,qCAAsC,SAAQ,YAAY;IACzE,EAAE,CAAC,SAAS,SAAS,MAAM,MAAM,EAC/B,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,KAAK,IAAI,GAC7C,IAAI,CAAC;IAER,IAAI,CAAC,SAAS,SAAS,MAAM,MAAM,EACjC,SAAS,EAAE,SAAS,EACpB,GAAG,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,GACzB,OAAO,CAAC;CACZ;AAED,qBAAa,yBAAyB;;IACpC,GAAG,EAAE,qCAAqC,CAAC;gBAkC/B,EACV,YAAY,EACZ,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,KAAK,EACL,SAAS,EACT,eAAe,GAChB,EAAE;QACD,YAAY,EAAE,YAAY,CAAC;QAC3B,aAAa,EAAE,MAAM,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;QACzC,eAAe,EAAE,MAAM,eAAe,EAAE,CAAC;QACzC,KAAK,CAAC,EAAE;YACN,6BAA6B,CAAC,EAAE,CAC9B,eAAe,EAAE,eAAe,KAC7B,OAAO,CAAC,OAAO,CAAC,CAAC;SACvB,CAAC;QACF,gBAAgB,EAAE,CAAC,eAAe,EAAE,eAAe,KAAK,OAAO,CAAC;QAChE,SAAS,EAAE,8BAA8B,CAAC;QAC1C,eAAe,EAAE,eAAe,CAAC;KAClC;IAgCD,0BAA0B,QAAO,IAAI,CAQnC;IAEF;;;;;;;;;;OAUG;IACH,oBAAoB,CAAC,eAAe,EAAE,eAAe,GAAG,IAAI;IAK5D;;;;OAIG;IACG,qBAAqB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BnE,IAAI,IAAI,IAAI;CA+bb"}
|
|
@@ -10,7 +10,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
10
10
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
11
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
12
|
};
|
|
13
|
-
var _ResimulateHelper_instances, _ResimulateHelper_timeoutIds, _ResimulateHelper_getTransactions, _ResimulateHelper_simulateTransaction, _ResimulateHelper_onTransactionsUpdate, _ResimulateHelper_start, _ResimulateHelper_queueUpdate, _ResimulateHelper_stop, _ResimulateHelper_removeListener;
|
|
13
|
+
var _ResimulateHelper_instances, _ResimulateHelper_timeoutIds, _ResimulateHelper_getTransactions, _ResimulateHelper_simulateTransaction, _ResimulateHelper_onTransactionsUpdate, _ResimulateHelper_getResimulatableTransactions, _ResimulateHelper_start, _ResimulateHelper_queueUpdate, _ResimulateHelper_stop, _ResimulateHelper_removeListener;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.hasSimulationDataChanged = exports.shouldResimulate = exports.ResimulateHelper = exports.RESIMULATE_INTERVAL_MS = exports.BLOCK_TIME_ADDITIONAL_SECONDS = exports.VALUE_COMPARISON_PERCENT_THRESHOLD = exports.BLOCKAID_RESULT_TYPE_MALICIOUS = exports.RESIMULATE_PARAMS = void 0;
|
|
16
16
|
const utils_1 = require("@metamask/utils");
|
|
@@ -39,28 +39,36 @@ class ResimulateHelper {
|
|
|
39
39
|
}
|
|
40
40
|
exports.ResimulateHelper = ResimulateHelper;
|
|
41
41
|
_ResimulateHelper_timeoutIds = new WeakMap(), _ResimulateHelper_getTransactions = new WeakMap(), _ResimulateHelper_simulateTransaction = new WeakMap(), _ResimulateHelper_instances = new WeakSet(), _ResimulateHelper_onTransactionsUpdate = function _ResimulateHelper_onTransactionsUpdate() {
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
// Combine unapproved transaction IDs and currently active resimulations
|
|
42
|
+
const resimulatableTransactionIds = new Set(__classPrivateFieldGet(this, _ResimulateHelper_instances, "m", _ResimulateHelper_getResimulatableTransactions).call(this).map((tx) => tx.id));
|
|
43
|
+
// Combine resimulatable transaction IDs and currently active resimulations
|
|
45
44
|
const allTransactionIds = new Set([
|
|
46
|
-
...
|
|
45
|
+
...resimulatableTransactionIds,
|
|
47
46
|
...__classPrivateFieldGet(this, _ResimulateHelper_timeoutIds, "f").keys(),
|
|
48
47
|
]);
|
|
49
48
|
allTransactionIds.forEach((transactionId) => {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
__classPrivateFieldGet(this, _ResimulateHelper_instances, "m", _ResimulateHelper_start).call(this, transactionMeta);
|
|
49
|
+
if (resimulatableTransactionIds.has(transactionId)) {
|
|
50
|
+
__classPrivateFieldGet(this, _ResimulateHelper_instances, "m", _ResimulateHelper_start).call(this, transactionId);
|
|
53
51
|
}
|
|
54
52
|
else {
|
|
55
53
|
__classPrivateFieldGet(this, _ResimulateHelper_instances, "m", _ResimulateHelper_stop).call(this, transactionId);
|
|
56
54
|
}
|
|
57
55
|
});
|
|
58
|
-
},
|
|
59
|
-
|
|
56
|
+
}, _ResimulateHelper_getResimulatableTransactions = function _ResimulateHelper_getResimulatableTransactions() {
|
|
57
|
+
return __classPrivateFieldGet(this, _ResimulateHelper_getTransactions, "f").call(this).filter((tx) => tx.status === types_1.TransactionStatus.unapproved && tx.isActive);
|
|
58
|
+
}, _ResimulateHelper_start = function _ResimulateHelper_start(transactionId) {
|
|
60
59
|
if (__classPrivateFieldGet(this, _ResimulateHelper_timeoutIds, "f").has(transactionId)) {
|
|
61
60
|
return;
|
|
62
61
|
}
|
|
63
62
|
const listener = () => {
|
|
63
|
+
// Read the latest transaction on each tick rather than capturing it in
|
|
64
|
+
// the closure. Otherwise an update to the transaction (e.g. editing a
|
|
65
|
+
// batch approval amount) would keep resimulating the stale data, as
|
|
66
|
+
// `#start` returns early when a timer already exists for the id.
|
|
67
|
+
const transactionMeta = __classPrivateFieldGet(this, _ResimulateHelper_instances, "m", _ResimulateHelper_getResimulatableTransactions).call(this).find((tx) => tx.id === transactionId);
|
|
68
|
+
if (!transactionMeta) {
|
|
69
|
+
__classPrivateFieldGet(this, _ResimulateHelper_instances, "m", _ResimulateHelper_stop).call(this, transactionId);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
64
72
|
__classPrivateFieldGet(this, _ResimulateHelper_simulateTransaction, "f").call(this, transactionMeta)
|
|
65
73
|
.catch((error) => {
|
|
66
74
|
/* istanbul ignore next */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ResimulateHelper.cjs","sourceRoot":"","sources":["../../src/helpers/ResimulateHelper.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Hex } from '@metamask/utils';\nimport { remove0x } from '@metamask/utils';\nimport { BN } from 'bn.js';\nimport { isEqual } from 'lodash';\n\nimport { createModuleLogger, projectLogger } from '../logger';\nimport { TransactionStatus } from '../types';\nimport type {\n SimulationBalanceChange,\n SimulationData,\n TransactionMeta,\n TransactionParams,\n} from '../types';\nimport { getPercentageChange } from '../utils/utils';\n\nconst log = createModuleLogger(projectLogger, 'resimulate-helper');\n\nexport const RESIMULATE_PARAMS = ['to', 'value', 'data'] as const;\nexport const BLOCKAID_RESULT_TYPE_MALICIOUS = 'Malicious';\nexport const VALUE_COMPARISON_PERCENT_THRESHOLD = 5;\nexport const BLOCK_TIME_ADDITIONAL_SECONDS = 60;\nexport const RESIMULATE_INTERVAL_MS = 3000;\n\nexport type ResimulateResponse = {\n blockTime?: number;\n resimulate: boolean;\n};\n\nexport type ResimulateHelperOptions = {\n getTransactions: () => TransactionMeta[];\n onTransactionsUpdate: (listener: () => void) => void;\n simulateTransaction: (transactionMeta: TransactionMeta) => Promise<void>;\n};\n\nexport class ResimulateHelper {\n // Map of transactionId <=> timeoutId\n readonly #timeoutIds: Map<string, NodeJS.Timeout> = new Map();\n\n readonly #getTransactions: () => TransactionMeta[];\n\n readonly #simulateTransaction: (\n transactionMeta: TransactionMeta,\n ) => Promise<void>;\n\n constructor({\n getTransactions,\n simulateTransaction,\n onTransactionsUpdate,\n }: ResimulateHelperOptions) {\n this.#getTransactions = getTransactions;\n this.#simulateTransaction = simulateTransaction;\n\n onTransactionsUpdate(this.#onTransactionsUpdate.bind(this));\n }\n\n #onTransactionsUpdate(): void {\n const unapprovedTransactions = this.#getTransactions().filter(\n (tx) => tx.status === TransactionStatus.unapproved,\n );\n\n const unapprovedTransactionIds = new Set(\n unapprovedTransactions.map((tx) => tx.id),\n );\n\n // Combine unapproved transaction IDs and currently active resimulations\n const allTransactionIds = new Set([\n ...unapprovedTransactionIds,\n ...this.#timeoutIds.keys(),\n ]);\n\n allTransactionIds.forEach((transactionId) => {\n const transactionMeta = unapprovedTransactions.find(\n (tx) => tx.id === transactionId,\n ) as TransactionMeta;\n\n if (transactionMeta?.isActive) {\n this.#start(transactionMeta);\n } else {\n this.#stop(transactionId);\n }\n });\n }\n\n #start(transactionMeta: TransactionMeta): void {\n const { id: transactionId } = transactionMeta;\n if (this.#timeoutIds.has(transactionId)) {\n return;\n }\n\n const listener = (): void => {\n this.#simulateTransaction(transactionMeta)\n .catch((error) => {\n /* istanbul ignore next */\n log('Error during transaction resimulation', error);\n })\n .finally(() => {\n // Schedule the next execution\n if (this.#timeoutIds.has(transactionId)) {\n this.#queueUpdate(transactionId, listener);\n }\n });\n };\n\n // Start the first execution\n this.#queueUpdate(transactionId, listener);\n log(\n `Started resimulating transaction ${transactionId} every ${RESIMULATE_INTERVAL_MS} milliseconds`,\n );\n }\n\n #queueUpdate(transactionId: string, listener: () => void): void {\n const timeoutId = setTimeout(listener, RESIMULATE_INTERVAL_MS);\n this.#timeoutIds.set(transactionId, timeoutId);\n }\n\n #stop(transactionId: string): void {\n if (!this.#timeoutIds.has(transactionId)) {\n return;\n }\n\n this.#removeListener(transactionId);\n log(\n `Stopped resimulating transaction ${transactionId} every ${RESIMULATE_INTERVAL_MS} milliseconds`,\n );\n }\n\n #removeListener(id: string): void {\n const timeoutId = this.#timeoutIds.get(id);\n if (timeoutId) {\n clearTimeout(timeoutId);\n this.#timeoutIds.delete(id);\n }\n }\n}\n\n/**\n * Determine if a transaction should be resimulated.\n *\n * @param originalTransactionMeta - The original transaction metadata.\n * @param newTransactionMeta - The new transaction metadata.\n * @returns Whether the transaction should be resimulated.\n */\nexport function shouldResimulate(\n originalTransactionMeta: TransactionMeta,\n newTransactionMeta: TransactionMeta,\n): ResimulateResponse {\n const { id: transactionId } = newTransactionMeta;\n\n const parametersUpdated = isParametersUpdated(\n originalTransactionMeta,\n newTransactionMeta,\n );\n\n const securityAlert = hasNewSecurityAlert(\n originalTransactionMeta,\n newTransactionMeta,\n );\n\n const valueAndNativeBalanceMismatch = hasValueAndNativeBalanceMismatch(\n originalTransactionMeta,\n newTransactionMeta,\n );\n\n const resimulate =\n parametersUpdated || securityAlert || valueAndNativeBalanceMismatch;\n\n let blockTime: number | undefined;\n\n if (securityAlert || valueAndNativeBalanceMismatch) {\n const nowSeconds = Math.floor(Date.now() / 1000);\n blockTime = nowSeconds + BLOCK_TIME_ADDITIONAL_SECONDS;\n }\n\n if (resimulate) {\n log('Transaction should be resimulated', {\n transactionId,\n blockTime,\n parametersUpdated,\n securityAlert,\n valueAndNativeBalanceMismatch,\n });\n }\n\n return {\n blockTime,\n resimulate,\n };\n}\n\n/**\n * Determine if the simulation data has changed.\n *\n * @param originalSimulationData - The original simulation data.\n * @param newSimulationData - The new simulation data.\n * @returns Whether the simulation data has changed.\n */\nexport function hasSimulationDataChanged(\n originalSimulationData: SimulationData,\n newSimulationData: SimulationData,\n): boolean {\n if (isEqual(originalSimulationData, newSimulationData)) {\n return false;\n }\n\n if (\n isBalanceChangeUpdated(\n originalSimulationData?.nativeBalanceChange,\n newSimulationData?.nativeBalanceChange,\n )\n ) {\n log('Simulation data native balance changed');\n return true;\n }\n\n if (\n originalSimulationData.tokenBalanceChanges.length !==\n newSimulationData.tokenBalanceChanges.length\n ) {\n return true;\n }\n\n for (const originalTokenBalanceChange of originalSimulationData.tokenBalanceChanges) {\n const newTokenBalanceChange = newSimulationData.tokenBalanceChanges.find(\n ({ address, id }) =>\n address === originalTokenBalanceChange.address &&\n id === originalTokenBalanceChange.id,\n );\n\n if (!newTokenBalanceChange) {\n log('Missing new token balance', {\n address: originalTokenBalanceChange.address,\n id: originalTokenBalanceChange.id,\n });\n\n return true;\n }\n\n if (\n isBalanceChangeUpdated(originalTokenBalanceChange, newTokenBalanceChange)\n ) {\n log('Simulation data token balance changed', {\n originalTokenBalanceChange,\n newTokenBalanceChange,\n });\n\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Determine if the transaction parameters have been updated.\n *\n * @param originalTransactionMeta - The original transaction metadata.\n * @param newTransactionMeta - The new transaction metadata.\n * @returns Whether the transaction parameters have been updated.\n */\nfunction isParametersUpdated(\n originalTransactionMeta: TransactionMeta,\n newTransactionMeta: TransactionMeta,\n): boolean {\n const { id: transactionId, txParams: newParams } = newTransactionMeta;\n const { txParams: originalParams } = originalTransactionMeta;\n\n if (!originalParams || isEqual(originalParams, newParams)) {\n return false;\n }\n\n const params = Object.keys(newParams) as (keyof TransactionParams)[];\n\n const updatedProperties = params.filter(\n (param) => newParams[param] !== originalParams[param],\n );\n\n log('Transaction parameters updated', {\n transactionId,\n updatedProperties,\n originalParams,\n newParams,\n });\n\n return RESIMULATE_PARAMS.some((param) => updatedProperties.includes(param));\n}\n\n/**\n * Determine if a transaction has a new security alert.\n *\n * @param originalTransactionMeta - The original transaction metadata.\n * @param newTransactionMeta - The new transaction metadata.\n * @returns Whether the transaction has a new security alert.\n */\nfunction hasNewSecurityAlert(\n originalTransactionMeta: TransactionMeta,\n newTransactionMeta: TransactionMeta,\n): boolean {\n const { securityAlertResponse: originalSecurityAlertResponse } =\n originalTransactionMeta;\n\n const { id: transactionId, securityAlertResponse: newSecurityAlertResponse } =\n newTransactionMeta;\n\n if (isEqual(originalSecurityAlertResponse, newSecurityAlertResponse)) {\n return false;\n }\n\n log('Security alert updated', {\n transactionId,\n originalSecurityAlertResponse,\n newSecurityAlertResponse,\n });\n\n return (\n newSecurityAlertResponse?.result_type === BLOCKAID_RESULT_TYPE_MALICIOUS\n );\n}\n\n/**\n * Determine if a transaction has a value and simulation native balance mismatch.\n *\n * @param originalTransactionMeta - The original transaction metadata.\n * @param newTransactionMeta - The new transaction metadata.\n * @returns Whether the transaction has a value and simulation native balance mismatch.\n */\nfunction hasValueAndNativeBalanceMismatch(\n originalTransactionMeta: TransactionMeta,\n newTransactionMeta: TransactionMeta,\n): boolean {\n const { simulationData: originalSimulationData } = originalTransactionMeta;\n\n const { simulationData: newSimulationData, txParams: newTxParams } =\n newTransactionMeta;\n\n if (\n !newSimulationData ||\n isEqual(originalSimulationData, newSimulationData)\n ) {\n return false;\n }\n\n const newValue = newTxParams?.value ?? '0x0';\n\n const newNativeBalanceDifference =\n newSimulationData?.nativeBalanceChange?.difference ?? '0x0';\n\n return !percentageChangeWithinThreshold(\n newValue as Hex,\n newNativeBalanceDifference,\n false,\n newSimulationData?.nativeBalanceChange?.isDecrease === false,\n );\n}\n\n/**\n * Determine if a balance change has been updated.\n *\n * @param originalBalanceChange - The original balance change.\n * @param newBalanceChange - The new balance change.\n * @returns Whether the balance change has been updated.\n */\nfunction isBalanceChangeUpdated(\n originalBalanceChange?: SimulationBalanceChange,\n newBalanceChange?: SimulationBalanceChange,\n): boolean {\n return !percentageChangeWithinThreshold(\n originalBalanceChange?.difference ?? '0x0',\n newBalanceChange?.difference ?? '0x0',\n originalBalanceChange?.isDecrease === false,\n newBalanceChange?.isDecrease === false,\n );\n}\n\n/**\n * Determine if the percentage change between two values is within a threshold.\n *\n * @param originalValue - The original value.\n * @param newValue - The new value.\n * @param originalNegative - Whether the original value is negative.\n * @param newNegative - Whether the new value is negative.\n * @returns Whether the percentage change between the two values is within a threshold.\n */\nfunction percentageChangeWithinThreshold(\n originalValue: Hex,\n newValue: Hex,\n originalNegative?: boolean,\n newNegative?: boolean,\n): boolean {\n let originalValueBN = new BN(remove0x(originalValue), 'hex');\n let newValueBN = new BN(remove0x(newValue), 'hex');\n\n if (originalNegative) {\n originalValueBN = originalValueBN.neg();\n }\n\n if (newNegative) {\n newValueBN = newValueBN.neg();\n }\n\n return (\n getPercentageChange(originalValueBN, newValueBN) <=\n VALUE_COMPARISON_PERCENT_THRESHOLD\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ResimulateHelper.cjs","sourceRoot":"","sources":["../../src/helpers/ResimulateHelper.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AACA,2CAA2C;AAC3C,iCAA2B;AAC3B,mCAAiC;AAEjC,0CAA8D;AAC9D,wCAA6C;AAO7C,8CAAqD;AAErD,MAAM,GAAG,GAAG,IAAA,2BAAkB,EAAC,sBAAa,EAAE,mBAAmB,CAAC,CAAC;AAEtD,QAAA,iBAAiB,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAU,CAAC;AACrD,QAAA,8BAA8B,GAAG,WAAW,CAAC;AAC7C,QAAA,kCAAkC,GAAG,CAAC,CAAC;AACvC,QAAA,6BAA6B,GAAG,EAAE,CAAC;AACnC,QAAA,sBAAsB,GAAG,IAAI,CAAC;AAa3C,MAAa,gBAAgB;IAU3B,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,oBAAoB,GACI;;QAb1B,qCAAqC;QAC5B,uCAA2C,IAAI,GAAG,EAAE,EAAC;QAErD,oDAA0C;QAE1C,wDAEU;QAOjB,uBAAA,IAAI,qCAAoB,eAAe,MAAA,CAAC;QACxC,uBAAA,IAAI,yCAAwB,mBAAmB,MAAA,CAAC;QAEhD,oBAAoB,CAAC,uBAAA,IAAI,2EAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9D,CAAC;CA0FF;AA7GD,4CA6GC;;IAvFG,MAAM,2BAA2B,GAAG,IAAI,GAAG,CACzC,uBAAA,IAAI,mFAA8B,MAAlC,IAAI,CAAgC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CACxD,CAAC;IAEF,2EAA2E;IAC3E,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;QAChC,GAAG,2BAA2B;QAC9B,GAAG,uBAAA,IAAI,oCAAY,CAAC,IAAI,EAAE;KAC3B,CAAC,CAAC;IAEH,iBAAiB,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,EAAE;QAC1C,IAAI,2BAA2B,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;YACnD,uBAAA,IAAI,4DAAO,MAAX,IAAI,EAAQ,aAAa,CAAC,CAAC;QAC7B,CAAC;aAAM,CAAC;YACN,uBAAA,IAAI,2DAAM,MAAV,IAAI,EAAO,aAAa,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;IAGC,OAAO,uBAAA,IAAI,yCAAiB,MAArB,IAAI,CAAmB,CAAC,MAAM,CACnC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,KAAK,yBAAiB,CAAC,UAAU,IAAI,EAAE,CAAC,QAAQ,CAClE,CAAC;AACJ,CAAC,6DAEM,aAAqB;IAC1B,IAAI,uBAAA,IAAI,oCAAY,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;QACxC,OAAO;IACT,CAAC;IAED,MAAM,QAAQ,GAAG,GAAS,EAAE;QAC1B,uEAAuE;QACvE,sEAAsE;QACtE,oEAAoE;QACpE,iEAAiE;QACjE,MAAM,eAAe,GAAG,uBAAA,IAAI,mFAA8B,MAAlC,IAAI,CAAgC,CAAC,IAAI,CAC/D,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,aAAa,CAChC,CAAC;QAEF,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,uBAAA,IAAI,2DAAM,MAAV,IAAI,EAAO,aAAa,CAAC,CAAC;YAC1B,OAAO;QACT,CAAC;QAED,uBAAA,IAAI,6CAAqB,MAAzB,IAAI,EAAsB,eAAe,CAAC;aACvC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YACf,0BAA0B;YAC1B,GAAG,CAAC,uCAAuC,EAAE,KAAK,CAAC,CAAC;QACtD,CAAC,CAAC;aACD,OAAO,CAAC,GAAG,EAAE;YACZ,8BAA8B;YAC9B,IAAI,uBAAA,IAAI,oCAAY,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;gBACxC,uBAAA,IAAI,kEAAa,MAAjB,IAAI,EAAc,aAAa,EAAE,QAAQ,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC,CAAC,CAAC;IACP,CAAC,CAAC;IAEF,4BAA4B;IAC5B,uBAAA,IAAI,kEAAa,MAAjB,IAAI,EAAc,aAAa,EAAE,QAAQ,CAAC,CAAC;IAC3C,GAAG,CACD,oCAAoC,aAAa,UAAU,8BAAsB,eAAe,CACjG,CAAC;AACJ,CAAC,yEAEY,aAAqB,EAAE,QAAoB;IACtD,MAAM,SAAS,GAAG,UAAU,CAAC,QAAQ,EAAE,8BAAsB,CAAC,CAAC;IAC/D,uBAAA,IAAI,oCAAY,CAAC,GAAG,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;AACjD,CAAC,2DAEK,aAAqB;IACzB,IAAI,CAAC,uBAAA,IAAI,oCAAY,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;QACzC,OAAO;IACT,CAAC;IAED,uBAAA,IAAI,qEAAgB,MAApB,IAAI,EAAiB,aAAa,CAAC,CAAC;IACpC,GAAG,CACD,oCAAoC,aAAa,UAAU,8BAAsB,eAAe,CACjG,CAAC;AACJ,CAAC,+EAEe,EAAU;IACxB,MAAM,SAAS,GAAG,uBAAA,IAAI,oCAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC3C,IAAI,SAAS,EAAE,CAAC;QACd,YAAY,CAAC,SAAS,CAAC,CAAC;QACxB,uBAAA,IAAI,oCAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC;AAGH;;;;;;GAMG;AACH,SAAgB,gBAAgB,CAC9B,uBAAwC,EACxC,kBAAmC;IAEnC,MAAM,EAAE,EAAE,EAAE,aAAa,EAAE,GAAG,kBAAkB,CAAC;IAEjD,MAAM,iBAAiB,GAAG,mBAAmB,CAC3C,uBAAuB,EACvB,kBAAkB,CACnB,CAAC;IAEF,MAAM,aAAa,GAAG,mBAAmB,CACvC,uBAAuB,EACvB,kBAAkB,CACnB,CAAC;IAEF,MAAM,6BAA6B,GAAG,gCAAgC,CACpE,uBAAuB,EACvB,kBAAkB,CACnB,CAAC;IAEF,MAAM,UAAU,GACd,iBAAiB,IAAI,aAAa,IAAI,6BAA6B,CAAC;IAEtE,IAAI,SAA6B,CAAC;IAElC,IAAI,aAAa,IAAI,6BAA6B,EAAE,CAAC;QACnD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QACjD,SAAS,GAAG,UAAU,GAAG,qCAA6B,CAAC;IACzD,CAAC;IAED,IAAI,UAAU,EAAE,CAAC;QACf,GAAG,CAAC,mCAAmC,EAAE;YACvC,aAAa;YACb,SAAS;YACT,iBAAiB;YACjB,aAAa;YACb,6BAA6B;SAC9B,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,SAAS;QACT,UAAU;KACX,CAAC;AACJ,CAAC;AA7CD,4CA6CC;AAED;;;;;;GAMG;AACH,SAAgB,wBAAwB,CACtC,sBAAsC,EACtC,iBAAiC;IAEjC,IAAI,IAAA,gBAAO,EAAC,sBAAsB,EAAE,iBAAiB,CAAC,EAAE,CAAC;QACvD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IACE,sBAAsB,CACpB,sBAAsB,EAAE,mBAAmB,EAC3C,iBAAiB,EAAE,mBAAmB,CACvC,EACD,CAAC;QACD,GAAG,CAAC,wCAAwC,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IACE,sBAAsB,CAAC,mBAAmB,CAAC,MAAM;QACjD,iBAAiB,CAAC,mBAAmB,CAAC,MAAM,EAC5C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,MAAM,0BAA0B,IAAI,sBAAsB,CAAC,mBAAmB,EAAE,CAAC;QACpF,MAAM,qBAAqB,GAAG,iBAAiB,CAAC,mBAAmB,CAAC,IAAI,CACtE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,CAClB,OAAO,KAAK,0BAA0B,CAAC,OAAO;YAC9C,EAAE,KAAK,0BAA0B,CAAC,EAAE,CACvC,CAAC;QAEF,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAC3B,GAAG,CAAC,2BAA2B,EAAE;gBAC/B,OAAO,EAAE,0BAA0B,CAAC,OAAO;gBAC3C,EAAE,EAAE,0BAA0B,CAAC,EAAE;aAClC,CAAC,CAAC;YAEH,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IACE,sBAAsB,CAAC,0BAA0B,EAAE,qBAAqB,CAAC,EACzE,CAAC;YACD,GAAG,CAAC,uCAAuC,EAAE;gBAC3C,0BAA0B;gBAC1B,qBAAqB;aACtB,CAAC,CAAC;YAEH,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAtDD,4DAsDC;AAED;;;;;;GAMG;AACH,SAAS,mBAAmB,CAC1B,uBAAwC,EACxC,kBAAmC;IAEnC,MAAM,EAAE,EAAE,EAAE,aAAa,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,kBAAkB,CAAC;IACtE,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,uBAAuB,CAAC;IAE7D,IAAI,CAAC,cAAc,IAAI,IAAA,gBAAO,EAAC,cAAc,EAAE,SAAS,CAAC,EAAE,CAAC;QAC1D,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAgC,CAAC;IAErE,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,CACrC,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,cAAc,CAAC,KAAK,CAAC,CACtD,CAAC;IAEF,GAAG,CAAC,gCAAgC,EAAE;QACpC,aAAa;QACb,iBAAiB;QACjB,cAAc;QACd,SAAS;KACV,CAAC,CAAC;IAEH,OAAO,yBAAiB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED;;;;;;GAMG;AACH,SAAS,mBAAmB,CAC1B,uBAAwC,EACxC,kBAAmC;IAEnC,MAAM,EAAE,qBAAqB,EAAE,6BAA6B,EAAE,GAC5D,uBAAuB,CAAC;IAE1B,MAAM,EAAE,EAAE,EAAE,aAAa,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,GAC1E,kBAAkB,CAAC;IAErB,IAAI,IAAA,gBAAO,EAAC,6BAA6B,EAAE,wBAAwB,CAAC,EAAE,CAAC;QACrE,OAAO,KAAK,CAAC;IACf,CAAC;IAED,GAAG,CAAC,wBAAwB,EAAE;QAC5B,aAAa;QACb,6BAA6B;QAC7B,wBAAwB;KACzB,CAAC,CAAC;IAEH,OAAO,CACL,wBAAwB,EAAE,WAAW,KAAK,sCAA8B,CACzE,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,gCAAgC,CACvC,uBAAwC,EACxC,kBAAmC;IAEnC,MAAM,EAAE,cAAc,EAAE,sBAAsB,EAAE,GAAG,uBAAuB,CAAC;IAE3E,MAAM,EAAE,cAAc,EAAE,iBAAiB,EAAE,QAAQ,EAAE,WAAW,EAAE,GAChE,kBAAkB,CAAC;IAErB,IACE,CAAC,iBAAiB;QAClB,IAAA,gBAAO,EAAC,sBAAsB,EAAE,iBAAiB,CAAC,EAClD,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,QAAQ,GAAG,WAAW,EAAE,KAAK,IAAI,KAAK,CAAC;IAE7C,MAAM,0BAA0B,GAC9B,iBAAiB,EAAE,mBAAmB,EAAE,UAAU,IAAI,KAAK,CAAC;IAE9D,OAAO,CAAC,+BAA+B,CACrC,QAAe,EACf,0BAA0B,EAC1B,KAAK,EACL,iBAAiB,EAAE,mBAAmB,EAAE,UAAU,KAAK,KAAK,CAC7D,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,sBAAsB,CAC7B,qBAA+C,EAC/C,gBAA0C;IAE1C,OAAO,CAAC,+BAA+B,CACrC,qBAAqB,EAAE,UAAU,IAAI,KAAK,EAC1C,gBAAgB,EAAE,UAAU,IAAI,KAAK,EACrC,qBAAqB,EAAE,UAAU,KAAK,KAAK,EAC3C,gBAAgB,EAAE,UAAU,KAAK,KAAK,CACvC,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,+BAA+B,CACtC,aAAkB,EAClB,QAAa,EACb,gBAA0B,EAC1B,WAAqB;IAErB,IAAI,eAAe,GAAG,IAAI,UAAE,CAAC,IAAA,gBAAQ,EAAC,aAAa,CAAC,EAAE,KAAK,CAAC,CAAC;IAC7D,IAAI,UAAU,GAAG,IAAI,UAAE,CAAC,IAAA,gBAAQ,EAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,CAAC;IAEnD,IAAI,gBAAgB,EAAE,CAAC;QACrB,eAAe,GAAG,eAAe,CAAC,GAAG,EAAE,CAAC;IAC1C,CAAC;IAED,IAAI,WAAW,EAAE,CAAC;QAChB,UAAU,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC;IAChC,CAAC;IAED,OAAO,CACL,IAAA,2BAAmB,EAAC,eAAe,EAAE,UAAU,CAAC;QAChD,0CAAkC,CACnC,CAAC;AACJ,CAAC","sourcesContent":["import type { Hex } from '@metamask/utils';\nimport { remove0x } from '@metamask/utils';\nimport { BN } from 'bn.js';\nimport { isEqual } from 'lodash';\n\nimport { createModuleLogger, projectLogger } from '../logger';\nimport { TransactionStatus } from '../types';\nimport type {\n SimulationBalanceChange,\n SimulationData,\n TransactionMeta,\n TransactionParams,\n} from '../types';\nimport { getPercentageChange } from '../utils/utils';\n\nconst log = createModuleLogger(projectLogger, 'resimulate-helper');\n\nexport const RESIMULATE_PARAMS = ['to', 'value', 'data'] as const;\nexport const BLOCKAID_RESULT_TYPE_MALICIOUS = 'Malicious';\nexport const VALUE_COMPARISON_PERCENT_THRESHOLD = 5;\nexport const BLOCK_TIME_ADDITIONAL_SECONDS = 60;\nexport const RESIMULATE_INTERVAL_MS = 3000;\n\nexport type ResimulateResponse = {\n blockTime?: number;\n resimulate: boolean;\n};\n\nexport type ResimulateHelperOptions = {\n getTransactions: () => TransactionMeta[];\n onTransactionsUpdate: (listener: () => void) => void;\n simulateTransaction: (transactionMeta: TransactionMeta) => Promise<void>;\n};\n\nexport class ResimulateHelper {\n // Map of transactionId <=> timeoutId\n readonly #timeoutIds: Map<string, NodeJS.Timeout> = new Map();\n\n readonly #getTransactions: () => TransactionMeta[];\n\n readonly #simulateTransaction: (\n transactionMeta: TransactionMeta,\n ) => Promise<void>;\n\n constructor({\n getTransactions,\n simulateTransaction,\n onTransactionsUpdate,\n }: ResimulateHelperOptions) {\n this.#getTransactions = getTransactions;\n this.#simulateTransaction = simulateTransaction;\n\n onTransactionsUpdate(this.#onTransactionsUpdate.bind(this));\n }\n\n #onTransactionsUpdate(): void {\n const resimulatableTransactionIds = new Set(\n this.#getResimulatableTransactions().map((tx) => tx.id),\n );\n\n // Combine resimulatable transaction IDs and currently active resimulations\n const allTransactionIds = new Set([\n ...resimulatableTransactionIds,\n ...this.#timeoutIds.keys(),\n ]);\n\n allTransactionIds.forEach((transactionId) => {\n if (resimulatableTransactionIds.has(transactionId)) {\n this.#start(transactionId);\n } else {\n this.#stop(transactionId);\n }\n });\n }\n\n #getResimulatableTransactions(): TransactionMeta[] {\n return this.#getTransactions().filter(\n (tx) => tx.status === TransactionStatus.unapproved && tx.isActive,\n );\n }\n\n #start(transactionId: string): void {\n if (this.#timeoutIds.has(transactionId)) {\n return;\n }\n\n const listener = (): void => {\n // Read the latest transaction on each tick rather than capturing it in\n // the closure. Otherwise an update to the transaction (e.g. editing a\n // batch approval amount) would keep resimulating the stale data, as\n // `#start` returns early when a timer already exists for the id.\n const transactionMeta = this.#getResimulatableTransactions().find(\n (tx) => tx.id === transactionId,\n );\n\n if (!transactionMeta) {\n this.#stop(transactionId);\n return;\n }\n\n this.#simulateTransaction(transactionMeta)\n .catch((error) => {\n /* istanbul ignore next */\n log('Error during transaction resimulation', error);\n })\n .finally(() => {\n // Schedule the next execution\n if (this.#timeoutIds.has(transactionId)) {\n this.#queueUpdate(transactionId, listener);\n }\n });\n };\n\n // Start the first execution\n this.#queueUpdate(transactionId, listener);\n log(\n `Started resimulating transaction ${transactionId} every ${RESIMULATE_INTERVAL_MS} milliseconds`,\n );\n }\n\n #queueUpdate(transactionId: string, listener: () => void): void {\n const timeoutId = setTimeout(listener, RESIMULATE_INTERVAL_MS);\n this.#timeoutIds.set(transactionId, timeoutId);\n }\n\n #stop(transactionId: string): void {\n if (!this.#timeoutIds.has(transactionId)) {\n return;\n }\n\n this.#removeListener(transactionId);\n log(\n `Stopped resimulating transaction ${transactionId} every ${RESIMULATE_INTERVAL_MS} milliseconds`,\n );\n }\n\n #removeListener(id: string): void {\n const timeoutId = this.#timeoutIds.get(id);\n if (timeoutId) {\n clearTimeout(timeoutId);\n this.#timeoutIds.delete(id);\n }\n }\n}\n\n/**\n * Determine if a transaction should be resimulated.\n *\n * @param originalTransactionMeta - The original transaction metadata.\n * @param newTransactionMeta - The new transaction metadata.\n * @returns Whether the transaction should be resimulated.\n */\nexport function shouldResimulate(\n originalTransactionMeta: TransactionMeta,\n newTransactionMeta: TransactionMeta,\n): ResimulateResponse {\n const { id: transactionId } = newTransactionMeta;\n\n const parametersUpdated = isParametersUpdated(\n originalTransactionMeta,\n newTransactionMeta,\n );\n\n const securityAlert = hasNewSecurityAlert(\n originalTransactionMeta,\n newTransactionMeta,\n );\n\n const valueAndNativeBalanceMismatch = hasValueAndNativeBalanceMismatch(\n originalTransactionMeta,\n newTransactionMeta,\n );\n\n const resimulate =\n parametersUpdated || securityAlert || valueAndNativeBalanceMismatch;\n\n let blockTime: number | undefined;\n\n if (securityAlert || valueAndNativeBalanceMismatch) {\n const nowSeconds = Math.floor(Date.now() / 1000);\n blockTime = nowSeconds + BLOCK_TIME_ADDITIONAL_SECONDS;\n }\n\n if (resimulate) {\n log('Transaction should be resimulated', {\n transactionId,\n blockTime,\n parametersUpdated,\n securityAlert,\n valueAndNativeBalanceMismatch,\n });\n }\n\n return {\n blockTime,\n resimulate,\n };\n}\n\n/**\n * Determine if the simulation data has changed.\n *\n * @param originalSimulationData - The original simulation data.\n * @param newSimulationData - The new simulation data.\n * @returns Whether the simulation data has changed.\n */\nexport function hasSimulationDataChanged(\n originalSimulationData: SimulationData,\n newSimulationData: SimulationData,\n): boolean {\n if (isEqual(originalSimulationData, newSimulationData)) {\n return false;\n }\n\n if (\n isBalanceChangeUpdated(\n originalSimulationData?.nativeBalanceChange,\n newSimulationData?.nativeBalanceChange,\n )\n ) {\n log('Simulation data native balance changed');\n return true;\n }\n\n if (\n originalSimulationData.tokenBalanceChanges.length !==\n newSimulationData.tokenBalanceChanges.length\n ) {\n return true;\n }\n\n for (const originalTokenBalanceChange of originalSimulationData.tokenBalanceChanges) {\n const newTokenBalanceChange = newSimulationData.tokenBalanceChanges.find(\n ({ address, id }) =>\n address === originalTokenBalanceChange.address &&\n id === originalTokenBalanceChange.id,\n );\n\n if (!newTokenBalanceChange) {\n log('Missing new token balance', {\n address: originalTokenBalanceChange.address,\n id: originalTokenBalanceChange.id,\n });\n\n return true;\n }\n\n if (\n isBalanceChangeUpdated(originalTokenBalanceChange, newTokenBalanceChange)\n ) {\n log('Simulation data token balance changed', {\n originalTokenBalanceChange,\n newTokenBalanceChange,\n });\n\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Determine if the transaction parameters have been updated.\n *\n * @param originalTransactionMeta - The original transaction metadata.\n * @param newTransactionMeta - The new transaction metadata.\n * @returns Whether the transaction parameters have been updated.\n */\nfunction isParametersUpdated(\n originalTransactionMeta: TransactionMeta,\n newTransactionMeta: TransactionMeta,\n): boolean {\n const { id: transactionId, txParams: newParams } = newTransactionMeta;\n const { txParams: originalParams } = originalTransactionMeta;\n\n if (!originalParams || isEqual(originalParams, newParams)) {\n return false;\n }\n\n const params = Object.keys(newParams) as (keyof TransactionParams)[];\n\n const updatedProperties = params.filter(\n (param) => newParams[param] !== originalParams[param],\n );\n\n log('Transaction parameters updated', {\n transactionId,\n updatedProperties,\n originalParams,\n newParams,\n });\n\n return RESIMULATE_PARAMS.some((param) => updatedProperties.includes(param));\n}\n\n/**\n * Determine if a transaction has a new security alert.\n *\n * @param originalTransactionMeta - The original transaction metadata.\n * @param newTransactionMeta - The new transaction metadata.\n * @returns Whether the transaction has a new security alert.\n */\nfunction hasNewSecurityAlert(\n originalTransactionMeta: TransactionMeta,\n newTransactionMeta: TransactionMeta,\n): boolean {\n const { securityAlertResponse: originalSecurityAlertResponse } =\n originalTransactionMeta;\n\n const { id: transactionId, securityAlertResponse: newSecurityAlertResponse } =\n newTransactionMeta;\n\n if (isEqual(originalSecurityAlertResponse, newSecurityAlertResponse)) {\n return false;\n }\n\n log('Security alert updated', {\n transactionId,\n originalSecurityAlertResponse,\n newSecurityAlertResponse,\n });\n\n return (\n newSecurityAlertResponse?.result_type === BLOCKAID_RESULT_TYPE_MALICIOUS\n );\n}\n\n/**\n * Determine if a transaction has a value and simulation native balance mismatch.\n *\n * @param originalTransactionMeta - The original transaction metadata.\n * @param newTransactionMeta - The new transaction metadata.\n * @returns Whether the transaction has a value and simulation native balance mismatch.\n */\nfunction hasValueAndNativeBalanceMismatch(\n originalTransactionMeta: TransactionMeta,\n newTransactionMeta: TransactionMeta,\n): boolean {\n const { simulationData: originalSimulationData } = originalTransactionMeta;\n\n const { simulationData: newSimulationData, txParams: newTxParams } =\n newTransactionMeta;\n\n if (\n !newSimulationData ||\n isEqual(originalSimulationData, newSimulationData)\n ) {\n return false;\n }\n\n const newValue = newTxParams?.value ?? '0x0';\n\n const newNativeBalanceDifference =\n newSimulationData?.nativeBalanceChange?.difference ?? '0x0';\n\n return !percentageChangeWithinThreshold(\n newValue as Hex,\n newNativeBalanceDifference,\n false,\n newSimulationData?.nativeBalanceChange?.isDecrease === false,\n );\n}\n\n/**\n * Determine if a balance change has been updated.\n *\n * @param originalBalanceChange - The original balance change.\n * @param newBalanceChange - The new balance change.\n * @returns Whether the balance change has been updated.\n */\nfunction isBalanceChangeUpdated(\n originalBalanceChange?: SimulationBalanceChange,\n newBalanceChange?: SimulationBalanceChange,\n): boolean {\n return !percentageChangeWithinThreshold(\n originalBalanceChange?.difference ?? '0x0',\n newBalanceChange?.difference ?? '0x0',\n originalBalanceChange?.isDecrease === false,\n newBalanceChange?.isDecrease === false,\n );\n}\n\n/**\n * Determine if the percentage change between two values is within a threshold.\n *\n * @param originalValue - The original value.\n * @param newValue - The new value.\n * @param originalNegative - Whether the original value is negative.\n * @param newNegative - Whether the new value is negative.\n * @returns Whether the percentage change between the two values is within a threshold.\n */\nfunction percentageChangeWithinThreshold(\n originalValue: Hex,\n newValue: Hex,\n originalNegative?: boolean,\n newNegative?: boolean,\n): boolean {\n let originalValueBN = new BN(remove0x(originalValue), 'hex');\n let newValueBN = new BN(remove0x(newValue), 'hex');\n\n if (originalNegative) {\n originalValueBN = originalValueBN.neg();\n }\n\n if (newNegative) {\n newValueBN = newValueBN.neg();\n }\n\n return (\n getPercentageChange(originalValueBN, newValueBN) <=\n VALUE_COMPARISON_PERCENT_THRESHOLD\n );\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ResimulateHelper.d.cts","sourceRoot":"","sources":["../../src/helpers/ResimulateHelper.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAEV,cAAc,EACd,eAAe,EAEhB,qBAAiB;AAKlB,eAAO,MAAM,iBAAiB,kCAAmC,CAAC;AAClE,eAAO,MAAM,8BAA8B,cAAc,CAAC;AAC1D,eAAO,MAAM,kCAAkC,IAAI,CAAC;AACpD,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAChD,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAE3C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,eAAe,EAAE,MAAM,eAAe,EAAE,CAAC;IACzC,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IACrD,mBAAmB,EAAE,CAAC,eAAe,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1E,CAAC;AAEF,qBAAa,gBAAgB;;gBAUf,EACV,eAAe,EACf,mBAAmB,EACnB,oBAAoB,GACrB,EAAE,uBAAuB;
|
|
1
|
+
{"version":3,"file":"ResimulateHelper.d.cts","sourceRoot":"","sources":["../../src/helpers/ResimulateHelper.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAEV,cAAc,EACd,eAAe,EAEhB,qBAAiB;AAKlB,eAAO,MAAM,iBAAiB,kCAAmC,CAAC;AAClE,eAAO,MAAM,8BAA8B,cAAc,CAAC;AAC1D,eAAO,MAAM,kCAAkC,IAAI,CAAC;AACpD,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAChD,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAE3C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,eAAe,EAAE,MAAM,eAAe,EAAE,CAAC;IACzC,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IACrD,mBAAmB,EAAE,CAAC,eAAe,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1E,CAAC;AAEF,qBAAa,gBAAgB;;gBAUf,EACV,eAAe,EACf,mBAAmB,EACnB,oBAAoB,GACrB,EAAE,uBAAuB;CA+F3B;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,uBAAuB,EAAE,eAAe,EACxC,kBAAkB,EAAE,eAAe,GAClC,kBAAkB,CA0CpB;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,sBAAsB,EAAE,cAAc,EACtC,iBAAiB,EAAE,cAAc,GAChC,OAAO,CAmDT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ResimulateHelper.d.mts","sourceRoot":"","sources":["../../src/helpers/ResimulateHelper.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAEV,cAAc,EACd,eAAe,EAEhB,qBAAiB;AAKlB,eAAO,MAAM,iBAAiB,kCAAmC,CAAC;AAClE,eAAO,MAAM,8BAA8B,cAAc,CAAC;AAC1D,eAAO,MAAM,kCAAkC,IAAI,CAAC;AACpD,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAChD,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAE3C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,eAAe,EAAE,MAAM,eAAe,EAAE,CAAC;IACzC,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IACrD,mBAAmB,EAAE,CAAC,eAAe,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1E,CAAC;AAEF,qBAAa,gBAAgB;;gBAUf,EACV,eAAe,EACf,mBAAmB,EACnB,oBAAoB,GACrB,EAAE,uBAAuB;
|
|
1
|
+
{"version":3,"file":"ResimulateHelper.d.mts","sourceRoot":"","sources":["../../src/helpers/ResimulateHelper.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAEV,cAAc,EACd,eAAe,EAEhB,qBAAiB;AAKlB,eAAO,MAAM,iBAAiB,kCAAmC,CAAC;AAClE,eAAO,MAAM,8BAA8B,cAAc,CAAC;AAC1D,eAAO,MAAM,kCAAkC,IAAI,CAAC;AACpD,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAChD,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAE3C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,eAAe,EAAE,MAAM,eAAe,EAAE,CAAC;IACzC,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IACrD,mBAAmB,EAAE,CAAC,eAAe,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1E,CAAC;AAEF,qBAAa,gBAAgB;;gBAUf,EACV,eAAe,EACf,mBAAmB,EACnB,oBAAoB,GACrB,EAAE,uBAAuB;CA+F3B;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,uBAAuB,EAAE,eAAe,EACxC,kBAAkB,EAAE,eAAe,GAClC,kBAAkB,CA0CpB;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,sBAAsB,EAAE,cAAc,EACtC,iBAAiB,EAAE,cAAc,GAChC,OAAO,CAmDT"}
|
|
@@ -9,7 +9,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
9
9
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
11
|
};
|
|
12
|
-
var _ResimulateHelper_instances, _ResimulateHelper_timeoutIds, _ResimulateHelper_getTransactions, _ResimulateHelper_simulateTransaction, _ResimulateHelper_onTransactionsUpdate, _ResimulateHelper_start, _ResimulateHelper_queueUpdate, _ResimulateHelper_stop, _ResimulateHelper_removeListener;
|
|
12
|
+
var _ResimulateHelper_instances, _ResimulateHelper_timeoutIds, _ResimulateHelper_getTransactions, _ResimulateHelper_simulateTransaction, _ResimulateHelper_onTransactionsUpdate, _ResimulateHelper_getResimulatableTransactions, _ResimulateHelper_start, _ResimulateHelper_queueUpdate, _ResimulateHelper_stop, _ResimulateHelper_removeListener;
|
|
13
13
|
import { remove0x } from "@metamask/utils";
|
|
14
14
|
import { BN } from "bn.js";
|
|
15
15
|
import $lodash from "lodash";
|
|
@@ -36,28 +36,36 @@ export class ResimulateHelper {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
_ResimulateHelper_timeoutIds = new WeakMap(), _ResimulateHelper_getTransactions = new WeakMap(), _ResimulateHelper_simulateTransaction = new WeakMap(), _ResimulateHelper_instances = new WeakSet(), _ResimulateHelper_onTransactionsUpdate = function _ResimulateHelper_onTransactionsUpdate() {
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
// Combine unapproved transaction IDs and currently active resimulations
|
|
39
|
+
const resimulatableTransactionIds = new Set(__classPrivateFieldGet(this, _ResimulateHelper_instances, "m", _ResimulateHelper_getResimulatableTransactions).call(this).map((tx) => tx.id));
|
|
40
|
+
// Combine resimulatable transaction IDs and currently active resimulations
|
|
42
41
|
const allTransactionIds = new Set([
|
|
43
|
-
...
|
|
42
|
+
...resimulatableTransactionIds,
|
|
44
43
|
...__classPrivateFieldGet(this, _ResimulateHelper_timeoutIds, "f").keys(),
|
|
45
44
|
]);
|
|
46
45
|
allTransactionIds.forEach((transactionId) => {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
__classPrivateFieldGet(this, _ResimulateHelper_instances, "m", _ResimulateHelper_start).call(this, transactionMeta);
|
|
46
|
+
if (resimulatableTransactionIds.has(transactionId)) {
|
|
47
|
+
__classPrivateFieldGet(this, _ResimulateHelper_instances, "m", _ResimulateHelper_start).call(this, transactionId);
|
|
50
48
|
}
|
|
51
49
|
else {
|
|
52
50
|
__classPrivateFieldGet(this, _ResimulateHelper_instances, "m", _ResimulateHelper_stop).call(this, transactionId);
|
|
53
51
|
}
|
|
54
52
|
});
|
|
55
|
-
},
|
|
56
|
-
|
|
53
|
+
}, _ResimulateHelper_getResimulatableTransactions = function _ResimulateHelper_getResimulatableTransactions() {
|
|
54
|
+
return __classPrivateFieldGet(this, _ResimulateHelper_getTransactions, "f").call(this).filter((tx) => tx.status === TransactionStatus.unapproved && tx.isActive);
|
|
55
|
+
}, _ResimulateHelper_start = function _ResimulateHelper_start(transactionId) {
|
|
57
56
|
if (__classPrivateFieldGet(this, _ResimulateHelper_timeoutIds, "f").has(transactionId)) {
|
|
58
57
|
return;
|
|
59
58
|
}
|
|
60
59
|
const listener = () => {
|
|
60
|
+
// Read the latest transaction on each tick rather than capturing it in
|
|
61
|
+
// the closure. Otherwise an update to the transaction (e.g. editing a
|
|
62
|
+
// batch approval amount) would keep resimulating the stale data, as
|
|
63
|
+
// `#start` returns early when a timer already exists for the id.
|
|
64
|
+
const transactionMeta = __classPrivateFieldGet(this, _ResimulateHelper_instances, "m", _ResimulateHelper_getResimulatableTransactions).call(this).find((tx) => tx.id === transactionId);
|
|
65
|
+
if (!transactionMeta) {
|
|
66
|
+
__classPrivateFieldGet(this, _ResimulateHelper_instances, "m", _ResimulateHelper_stop).call(this, transactionId);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
61
69
|
__classPrivateFieldGet(this, _ResimulateHelper_simulateTransaction, "f").call(this, transactionMeta)
|
|
62
70
|
.catch((error) => {
|
|
63
71
|
/* istanbul ignore next */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ResimulateHelper.mjs","sourceRoot":"","sources":["../../src/helpers/ResimulateHelper.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Hex } from '@metamask/utils';\nimport { remove0x } from '@metamask/utils';\nimport { BN } from 'bn.js';\nimport { isEqual } from 'lodash';\n\nimport { createModuleLogger, projectLogger } from '../logger';\nimport { TransactionStatus } from '../types';\nimport type {\n SimulationBalanceChange,\n SimulationData,\n TransactionMeta,\n TransactionParams,\n} from '../types';\nimport { getPercentageChange } from '../utils/utils';\n\nconst log = createModuleLogger(projectLogger, 'resimulate-helper');\n\nexport const RESIMULATE_PARAMS = ['to', 'value', 'data'] as const;\nexport const BLOCKAID_RESULT_TYPE_MALICIOUS = 'Malicious';\nexport const VALUE_COMPARISON_PERCENT_THRESHOLD = 5;\nexport const BLOCK_TIME_ADDITIONAL_SECONDS = 60;\nexport const RESIMULATE_INTERVAL_MS = 3000;\n\nexport type ResimulateResponse = {\n blockTime?: number;\n resimulate: boolean;\n};\n\nexport type ResimulateHelperOptions = {\n getTransactions: () => TransactionMeta[];\n onTransactionsUpdate: (listener: () => void) => void;\n simulateTransaction: (transactionMeta: TransactionMeta) => Promise<void>;\n};\n\nexport class ResimulateHelper {\n // Map of transactionId <=> timeoutId\n readonly #timeoutIds: Map<string, NodeJS.Timeout> = new Map();\n\n readonly #getTransactions: () => TransactionMeta[];\n\n readonly #simulateTransaction: (\n transactionMeta: TransactionMeta,\n ) => Promise<void>;\n\n constructor({\n getTransactions,\n simulateTransaction,\n onTransactionsUpdate,\n }: ResimulateHelperOptions) {\n this.#getTransactions = getTransactions;\n this.#simulateTransaction = simulateTransaction;\n\n onTransactionsUpdate(this.#onTransactionsUpdate.bind(this));\n }\n\n #onTransactionsUpdate(): void {\n const unapprovedTransactions = this.#getTransactions().filter(\n (tx) => tx.status === TransactionStatus.unapproved,\n );\n\n const unapprovedTransactionIds = new Set(\n unapprovedTransactions.map((tx) => tx.id),\n );\n\n // Combine unapproved transaction IDs and currently active resimulations\n const allTransactionIds = new Set([\n ...unapprovedTransactionIds,\n ...this.#timeoutIds.keys(),\n ]);\n\n allTransactionIds.forEach((transactionId) => {\n const transactionMeta = unapprovedTransactions.find(\n (tx) => tx.id === transactionId,\n ) as TransactionMeta;\n\n if (transactionMeta?.isActive) {\n this.#start(transactionMeta);\n } else {\n this.#stop(transactionId);\n }\n });\n }\n\n #start(transactionMeta: TransactionMeta): void {\n const { id: transactionId } = transactionMeta;\n if (this.#timeoutIds.has(transactionId)) {\n return;\n }\n\n const listener = (): void => {\n this.#simulateTransaction(transactionMeta)\n .catch((error) => {\n /* istanbul ignore next */\n log('Error during transaction resimulation', error);\n })\n .finally(() => {\n // Schedule the next execution\n if (this.#timeoutIds.has(transactionId)) {\n this.#queueUpdate(transactionId, listener);\n }\n });\n };\n\n // Start the first execution\n this.#queueUpdate(transactionId, listener);\n log(\n `Started resimulating transaction ${transactionId} every ${RESIMULATE_INTERVAL_MS} milliseconds`,\n );\n }\n\n #queueUpdate(transactionId: string, listener: () => void): void {\n const timeoutId = setTimeout(listener, RESIMULATE_INTERVAL_MS);\n this.#timeoutIds.set(transactionId, timeoutId);\n }\n\n #stop(transactionId: string): void {\n if (!this.#timeoutIds.has(transactionId)) {\n return;\n }\n\n this.#removeListener(transactionId);\n log(\n `Stopped resimulating transaction ${transactionId} every ${RESIMULATE_INTERVAL_MS} milliseconds`,\n );\n }\n\n #removeListener(id: string): void {\n const timeoutId = this.#timeoutIds.get(id);\n if (timeoutId) {\n clearTimeout(timeoutId);\n this.#timeoutIds.delete(id);\n }\n }\n}\n\n/**\n * Determine if a transaction should be resimulated.\n *\n * @param originalTransactionMeta - The original transaction metadata.\n * @param newTransactionMeta - The new transaction metadata.\n * @returns Whether the transaction should be resimulated.\n */\nexport function shouldResimulate(\n originalTransactionMeta: TransactionMeta,\n newTransactionMeta: TransactionMeta,\n): ResimulateResponse {\n const { id: transactionId } = newTransactionMeta;\n\n const parametersUpdated = isParametersUpdated(\n originalTransactionMeta,\n newTransactionMeta,\n );\n\n const securityAlert = hasNewSecurityAlert(\n originalTransactionMeta,\n newTransactionMeta,\n );\n\n const valueAndNativeBalanceMismatch = hasValueAndNativeBalanceMismatch(\n originalTransactionMeta,\n newTransactionMeta,\n );\n\n const resimulate =\n parametersUpdated || securityAlert || valueAndNativeBalanceMismatch;\n\n let blockTime: number | undefined;\n\n if (securityAlert || valueAndNativeBalanceMismatch) {\n const nowSeconds = Math.floor(Date.now() / 1000);\n blockTime = nowSeconds + BLOCK_TIME_ADDITIONAL_SECONDS;\n }\n\n if (resimulate) {\n log('Transaction should be resimulated', {\n transactionId,\n blockTime,\n parametersUpdated,\n securityAlert,\n valueAndNativeBalanceMismatch,\n });\n }\n\n return {\n blockTime,\n resimulate,\n };\n}\n\n/**\n * Determine if the simulation data has changed.\n *\n * @param originalSimulationData - The original simulation data.\n * @param newSimulationData - The new simulation data.\n * @returns Whether the simulation data has changed.\n */\nexport function hasSimulationDataChanged(\n originalSimulationData: SimulationData,\n newSimulationData: SimulationData,\n): boolean {\n if (isEqual(originalSimulationData, newSimulationData)) {\n return false;\n }\n\n if (\n isBalanceChangeUpdated(\n originalSimulationData?.nativeBalanceChange,\n newSimulationData?.nativeBalanceChange,\n )\n ) {\n log('Simulation data native balance changed');\n return true;\n }\n\n if (\n originalSimulationData.tokenBalanceChanges.length !==\n newSimulationData.tokenBalanceChanges.length\n ) {\n return true;\n }\n\n for (const originalTokenBalanceChange of originalSimulationData.tokenBalanceChanges) {\n const newTokenBalanceChange = newSimulationData.tokenBalanceChanges.find(\n ({ address, id }) =>\n address === originalTokenBalanceChange.address &&\n id === originalTokenBalanceChange.id,\n );\n\n if (!newTokenBalanceChange) {\n log('Missing new token balance', {\n address: originalTokenBalanceChange.address,\n id: originalTokenBalanceChange.id,\n });\n\n return true;\n }\n\n if (\n isBalanceChangeUpdated(originalTokenBalanceChange, newTokenBalanceChange)\n ) {\n log('Simulation data token balance changed', {\n originalTokenBalanceChange,\n newTokenBalanceChange,\n });\n\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Determine if the transaction parameters have been updated.\n *\n * @param originalTransactionMeta - The original transaction metadata.\n * @param newTransactionMeta - The new transaction metadata.\n * @returns Whether the transaction parameters have been updated.\n */\nfunction isParametersUpdated(\n originalTransactionMeta: TransactionMeta,\n newTransactionMeta: TransactionMeta,\n): boolean {\n const { id: transactionId, txParams: newParams } = newTransactionMeta;\n const { txParams: originalParams } = originalTransactionMeta;\n\n if (!originalParams || isEqual(originalParams, newParams)) {\n return false;\n }\n\n const params = Object.keys(newParams) as (keyof TransactionParams)[];\n\n const updatedProperties = params.filter(\n (param) => newParams[param] !== originalParams[param],\n );\n\n log('Transaction parameters updated', {\n transactionId,\n updatedProperties,\n originalParams,\n newParams,\n });\n\n return RESIMULATE_PARAMS.some((param) => updatedProperties.includes(param));\n}\n\n/**\n * Determine if a transaction has a new security alert.\n *\n * @param originalTransactionMeta - The original transaction metadata.\n * @param newTransactionMeta - The new transaction metadata.\n * @returns Whether the transaction has a new security alert.\n */\nfunction hasNewSecurityAlert(\n originalTransactionMeta: TransactionMeta,\n newTransactionMeta: TransactionMeta,\n): boolean {\n const { securityAlertResponse: originalSecurityAlertResponse } =\n originalTransactionMeta;\n\n const { id: transactionId, securityAlertResponse: newSecurityAlertResponse } =\n newTransactionMeta;\n\n if (isEqual(originalSecurityAlertResponse, newSecurityAlertResponse)) {\n return false;\n }\n\n log('Security alert updated', {\n transactionId,\n originalSecurityAlertResponse,\n newSecurityAlertResponse,\n });\n\n return (\n newSecurityAlertResponse?.result_type === BLOCKAID_RESULT_TYPE_MALICIOUS\n );\n}\n\n/**\n * Determine if a transaction has a value and simulation native balance mismatch.\n *\n * @param originalTransactionMeta - The original transaction metadata.\n * @param newTransactionMeta - The new transaction metadata.\n * @returns Whether the transaction has a value and simulation native balance mismatch.\n */\nfunction hasValueAndNativeBalanceMismatch(\n originalTransactionMeta: TransactionMeta,\n newTransactionMeta: TransactionMeta,\n): boolean {\n const { simulationData: originalSimulationData } = originalTransactionMeta;\n\n const { simulationData: newSimulationData, txParams: newTxParams } =\n newTransactionMeta;\n\n if (\n !newSimulationData ||\n isEqual(originalSimulationData, newSimulationData)\n ) {\n return false;\n }\n\n const newValue = newTxParams?.value ?? '0x0';\n\n const newNativeBalanceDifference =\n newSimulationData?.nativeBalanceChange?.difference ?? '0x0';\n\n return !percentageChangeWithinThreshold(\n newValue as Hex,\n newNativeBalanceDifference,\n false,\n newSimulationData?.nativeBalanceChange?.isDecrease === false,\n );\n}\n\n/**\n * Determine if a balance change has been updated.\n *\n * @param originalBalanceChange - The original balance change.\n * @param newBalanceChange - The new balance change.\n * @returns Whether the balance change has been updated.\n */\nfunction isBalanceChangeUpdated(\n originalBalanceChange?: SimulationBalanceChange,\n newBalanceChange?: SimulationBalanceChange,\n): boolean {\n return !percentageChangeWithinThreshold(\n originalBalanceChange?.difference ?? '0x0',\n newBalanceChange?.difference ?? '0x0',\n originalBalanceChange?.isDecrease === false,\n newBalanceChange?.isDecrease === false,\n );\n}\n\n/**\n * Determine if the percentage change between two values is within a threshold.\n *\n * @param originalValue - The original value.\n * @param newValue - The new value.\n * @param originalNegative - Whether the original value is negative.\n * @param newNegative - Whether the new value is negative.\n * @returns Whether the percentage change between the two values is within a threshold.\n */\nfunction percentageChangeWithinThreshold(\n originalValue: Hex,\n newValue: Hex,\n originalNegative?: boolean,\n newNegative?: boolean,\n): boolean {\n let originalValueBN = new BN(remove0x(originalValue), 'hex');\n let newValueBN = new BN(remove0x(newValue), 'hex');\n\n if (originalNegative) {\n originalValueBN = originalValueBN.neg();\n }\n\n if (newNegative) {\n newValueBN = newValueBN.neg();\n }\n\n return (\n getPercentageChange(originalValueBN, newValueBN) <=\n VALUE_COMPARISON_PERCENT_THRESHOLD\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ResimulateHelper.mjs","sourceRoot":"","sources":["../../src/helpers/ResimulateHelper.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Hex } from '@metamask/utils';\nimport { remove0x } from '@metamask/utils';\nimport { BN } from 'bn.js';\nimport { isEqual } from 'lodash';\n\nimport { createModuleLogger, projectLogger } from '../logger';\nimport { TransactionStatus } from '../types';\nimport type {\n SimulationBalanceChange,\n SimulationData,\n TransactionMeta,\n TransactionParams,\n} from '../types';\nimport { getPercentageChange } from '../utils/utils';\n\nconst log = createModuleLogger(projectLogger, 'resimulate-helper');\n\nexport const RESIMULATE_PARAMS = ['to', 'value', 'data'] as const;\nexport const BLOCKAID_RESULT_TYPE_MALICIOUS = 'Malicious';\nexport const VALUE_COMPARISON_PERCENT_THRESHOLD = 5;\nexport const BLOCK_TIME_ADDITIONAL_SECONDS = 60;\nexport const RESIMULATE_INTERVAL_MS = 3000;\n\nexport type ResimulateResponse = {\n blockTime?: number;\n resimulate: boolean;\n};\n\nexport type ResimulateHelperOptions = {\n getTransactions: () => TransactionMeta[];\n onTransactionsUpdate: (listener: () => void) => void;\n simulateTransaction: (transactionMeta: TransactionMeta) => Promise<void>;\n};\n\nexport class ResimulateHelper {\n // Map of transactionId <=> timeoutId\n readonly #timeoutIds: Map<string, NodeJS.Timeout> = new Map();\n\n readonly #getTransactions: () => TransactionMeta[];\n\n readonly #simulateTransaction: (\n transactionMeta: TransactionMeta,\n ) => Promise<void>;\n\n constructor({\n getTransactions,\n simulateTransaction,\n onTransactionsUpdate,\n }: ResimulateHelperOptions) {\n this.#getTransactions = getTransactions;\n this.#simulateTransaction = simulateTransaction;\n\n onTransactionsUpdate(this.#onTransactionsUpdate.bind(this));\n }\n\n #onTransactionsUpdate(): void {\n const resimulatableTransactionIds = new Set(\n this.#getResimulatableTransactions().map((tx) => tx.id),\n );\n\n // Combine resimulatable transaction IDs and currently active resimulations\n const allTransactionIds = new Set([\n ...resimulatableTransactionIds,\n ...this.#timeoutIds.keys(),\n ]);\n\n allTransactionIds.forEach((transactionId) => {\n if (resimulatableTransactionIds.has(transactionId)) {\n this.#start(transactionId);\n } else {\n this.#stop(transactionId);\n }\n });\n }\n\n #getResimulatableTransactions(): TransactionMeta[] {\n return this.#getTransactions().filter(\n (tx) => tx.status === TransactionStatus.unapproved && tx.isActive,\n );\n }\n\n #start(transactionId: string): void {\n if (this.#timeoutIds.has(transactionId)) {\n return;\n }\n\n const listener = (): void => {\n // Read the latest transaction on each tick rather than capturing it in\n // the closure. Otherwise an update to the transaction (e.g. editing a\n // batch approval amount) would keep resimulating the stale data, as\n // `#start` returns early when a timer already exists for the id.\n const transactionMeta = this.#getResimulatableTransactions().find(\n (tx) => tx.id === transactionId,\n );\n\n if (!transactionMeta) {\n this.#stop(transactionId);\n return;\n }\n\n this.#simulateTransaction(transactionMeta)\n .catch((error) => {\n /* istanbul ignore next */\n log('Error during transaction resimulation', error);\n })\n .finally(() => {\n // Schedule the next execution\n if (this.#timeoutIds.has(transactionId)) {\n this.#queueUpdate(transactionId, listener);\n }\n });\n };\n\n // Start the first execution\n this.#queueUpdate(transactionId, listener);\n log(\n `Started resimulating transaction ${transactionId} every ${RESIMULATE_INTERVAL_MS} milliseconds`,\n );\n }\n\n #queueUpdate(transactionId: string, listener: () => void): void {\n const timeoutId = setTimeout(listener, RESIMULATE_INTERVAL_MS);\n this.#timeoutIds.set(transactionId, timeoutId);\n }\n\n #stop(transactionId: string): void {\n if (!this.#timeoutIds.has(transactionId)) {\n return;\n }\n\n this.#removeListener(transactionId);\n log(\n `Stopped resimulating transaction ${transactionId} every ${RESIMULATE_INTERVAL_MS} milliseconds`,\n );\n }\n\n #removeListener(id: string): void {\n const timeoutId = this.#timeoutIds.get(id);\n if (timeoutId) {\n clearTimeout(timeoutId);\n this.#timeoutIds.delete(id);\n }\n }\n}\n\n/**\n * Determine if a transaction should be resimulated.\n *\n * @param originalTransactionMeta - The original transaction metadata.\n * @param newTransactionMeta - The new transaction metadata.\n * @returns Whether the transaction should be resimulated.\n */\nexport function shouldResimulate(\n originalTransactionMeta: TransactionMeta,\n newTransactionMeta: TransactionMeta,\n): ResimulateResponse {\n const { id: transactionId } = newTransactionMeta;\n\n const parametersUpdated = isParametersUpdated(\n originalTransactionMeta,\n newTransactionMeta,\n );\n\n const securityAlert = hasNewSecurityAlert(\n originalTransactionMeta,\n newTransactionMeta,\n );\n\n const valueAndNativeBalanceMismatch = hasValueAndNativeBalanceMismatch(\n originalTransactionMeta,\n newTransactionMeta,\n );\n\n const resimulate =\n parametersUpdated || securityAlert || valueAndNativeBalanceMismatch;\n\n let blockTime: number | undefined;\n\n if (securityAlert || valueAndNativeBalanceMismatch) {\n const nowSeconds = Math.floor(Date.now() / 1000);\n blockTime = nowSeconds + BLOCK_TIME_ADDITIONAL_SECONDS;\n }\n\n if (resimulate) {\n log('Transaction should be resimulated', {\n transactionId,\n blockTime,\n parametersUpdated,\n securityAlert,\n valueAndNativeBalanceMismatch,\n });\n }\n\n return {\n blockTime,\n resimulate,\n };\n}\n\n/**\n * Determine if the simulation data has changed.\n *\n * @param originalSimulationData - The original simulation data.\n * @param newSimulationData - The new simulation data.\n * @returns Whether the simulation data has changed.\n */\nexport function hasSimulationDataChanged(\n originalSimulationData: SimulationData,\n newSimulationData: SimulationData,\n): boolean {\n if (isEqual(originalSimulationData, newSimulationData)) {\n return false;\n }\n\n if (\n isBalanceChangeUpdated(\n originalSimulationData?.nativeBalanceChange,\n newSimulationData?.nativeBalanceChange,\n )\n ) {\n log('Simulation data native balance changed');\n return true;\n }\n\n if (\n originalSimulationData.tokenBalanceChanges.length !==\n newSimulationData.tokenBalanceChanges.length\n ) {\n return true;\n }\n\n for (const originalTokenBalanceChange of originalSimulationData.tokenBalanceChanges) {\n const newTokenBalanceChange = newSimulationData.tokenBalanceChanges.find(\n ({ address, id }) =>\n address === originalTokenBalanceChange.address &&\n id === originalTokenBalanceChange.id,\n );\n\n if (!newTokenBalanceChange) {\n log('Missing new token balance', {\n address: originalTokenBalanceChange.address,\n id: originalTokenBalanceChange.id,\n });\n\n return true;\n }\n\n if (\n isBalanceChangeUpdated(originalTokenBalanceChange, newTokenBalanceChange)\n ) {\n log('Simulation data token balance changed', {\n originalTokenBalanceChange,\n newTokenBalanceChange,\n });\n\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Determine if the transaction parameters have been updated.\n *\n * @param originalTransactionMeta - The original transaction metadata.\n * @param newTransactionMeta - The new transaction metadata.\n * @returns Whether the transaction parameters have been updated.\n */\nfunction isParametersUpdated(\n originalTransactionMeta: TransactionMeta,\n newTransactionMeta: TransactionMeta,\n): boolean {\n const { id: transactionId, txParams: newParams } = newTransactionMeta;\n const { txParams: originalParams } = originalTransactionMeta;\n\n if (!originalParams || isEqual(originalParams, newParams)) {\n return false;\n }\n\n const params = Object.keys(newParams) as (keyof TransactionParams)[];\n\n const updatedProperties = params.filter(\n (param) => newParams[param] !== originalParams[param],\n );\n\n log('Transaction parameters updated', {\n transactionId,\n updatedProperties,\n originalParams,\n newParams,\n });\n\n return RESIMULATE_PARAMS.some((param) => updatedProperties.includes(param));\n}\n\n/**\n * Determine if a transaction has a new security alert.\n *\n * @param originalTransactionMeta - The original transaction metadata.\n * @param newTransactionMeta - The new transaction metadata.\n * @returns Whether the transaction has a new security alert.\n */\nfunction hasNewSecurityAlert(\n originalTransactionMeta: TransactionMeta,\n newTransactionMeta: TransactionMeta,\n): boolean {\n const { securityAlertResponse: originalSecurityAlertResponse } =\n originalTransactionMeta;\n\n const { id: transactionId, securityAlertResponse: newSecurityAlertResponse } =\n newTransactionMeta;\n\n if (isEqual(originalSecurityAlertResponse, newSecurityAlertResponse)) {\n return false;\n }\n\n log('Security alert updated', {\n transactionId,\n originalSecurityAlertResponse,\n newSecurityAlertResponse,\n });\n\n return (\n newSecurityAlertResponse?.result_type === BLOCKAID_RESULT_TYPE_MALICIOUS\n );\n}\n\n/**\n * Determine if a transaction has a value and simulation native balance mismatch.\n *\n * @param originalTransactionMeta - The original transaction metadata.\n * @param newTransactionMeta - The new transaction metadata.\n * @returns Whether the transaction has a value and simulation native balance mismatch.\n */\nfunction hasValueAndNativeBalanceMismatch(\n originalTransactionMeta: TransactionMeta,\n newTransactionMeta: TransactionMeta,\n): boolean {\n const { simulationData: originalSimulationData } = originalTransactionMeta;\n\n const { simulationData: newSimulationData, txParams: newTxParams } =\n newTransactionMeta;\n\n if (\n !newSimulationData ||\n isEqual(originalSimulationData, newSimulationData)\n ) {\n return false;\n }\n\n const newValue = newTxParams?.value ?? '0x0';\n\n const newNativeBalanceDifference =\n newSimulationData?.nativeBalanceChange?.difference ?? '0x0';\n\n return !percentageChangeWithinThreshold(\n newValue as Hex,\n newNativeBalanceDifference,\n false,\n newSimulationData?.nativeBalanceChange?.isDecrease === false,\n );\n}\n\n/**\n * Determine if a balance change has been updated.\n *\n * @param originalBalanceChange - The original balance change.\n * @param newBalanceChange - The new balance change.\n * @returns Whether the balance change has been updated.\n */\nfunction isBalanceChangeUpdated(\n originalBalanceChange?: SimulationBalanceChange,\n newBalanceChange?: SimulationBalanceChange,\n): boolean {\n return !percentageChangeWithinThreshold(\n originalBalanceChange?.difference ?? '0x0',\n newBalanceChange?.difference ?? '0x0',\n originalBalanceChange?.isDecrease === false,\n newBalanceChange?.isDecrease === false,\n );\n}\n\n/**\n * Determine if the percentage change between two values is within a threshold.\n *\n * @param originalValue - The original value.\n * @param newValue - The new value.\n * @param originalNegative - Whether the original value is negative.\n * @param newNegative - Whether the new value is negative.\n * @returns Whether the percentage change between the two values is within a threshold.\n */\nfunction percentageChangeWithinThreshold(\n originalValue: Hex,\n newValue: Hex,\n originalNegative?: boolean,\n newNegative?: boolean,\n): boolean {\n let originalValueBN = new BN(remove0x(originalValue), 'hex');\n let newValueBN = new BN(remove0x(newValue), 'hex');\n\n if (originalNegative) {\n originalValueBN = originalValueBN.neg();\n }\n\n if (newNegative) {\n newValueBN = newValueBN.neg();\n }\n\n return (\n getPercentageChange(originalValueBN, newValueBN) <=\n VALUE_COMPARISON_PERCENT_THRESHOLD\n );\n}\n"]}
|
package/dist/utils/batch.cjs
CHANGED
|
@@ -28,6 +28,7 @@ exports.ERROR_MESSAGE_NO_UPGRADE_CONTRACT = 'Upgrade contract address not found'
|
|
|
28
28
|
*/
|
|
29
29
|
async function addTransactionBatch(request) {
|
|
30
30
|
const { getInternalAccounts, messenger, request: transactionBatchRequest, } = request;
|
|
31
|
+
const { disableHook, disable7702, disableSequential } = transactionBatchRequest;
|
|
31
32
|
const sizeLimit = (0, feature_flags_1.getBatchSizeLimit)(messenger);
|
|
32
33
|
(0, validation_1.validateBatchRequest)({
|
|
33
34
|
internalAccounts: getInternalAccounts(),
|
|
@@ -37,14 +38,17 @@ async function addTransactionBatch(request) {
|
|
|
37
38
|
});
|
|
38
39
|
log('Adding', transactionBatchRequest);
|
|
39
40
|
const accountCanUse7702 = (0, eip7702_1.doesAccountSupportEIP7702)(messenger, transactionBatchRequest.from);
|
|
40
|
-
if (!
|
|
41
|
+
if (disableHook && disableSequential && !disable7702 && !accountCanUse7702) {
|
|
42
|
+
throw rpc_errors_1.rpcErrors.internal('Account does not support EIP-7702');
|
|
43
|
+
}
|
|
44
|
+
if (!disable7702 && accountCanUse7702) {
|
|
41
45
|
try {
|
|
42
46
|
return await addTransactionBatchWith7702(request);
|
|
43
47
|
}
|
|
44
48
|
catch (error) {
|
|
45
49
|
const isEIP7702NotSupportedError = error instanceof rpc_errors_1.JsonRpcError &&
|
|
46
50
|
error.message === 'Chain does not support EIP-7702';
|
|
47
|
-
if (!isEIP7702NotSupportedError) {
|
|
51
|
+
if (!isEIP7702NotSupportedError || (disableHook && disableSequential)) {
|
|
48
52
|
throw error;
|
|
49
53
|
}
|
|
50
54
|
}
|