@metamask-previews/transaction-controller 43.0.0-preview-77c9cd86 → 43.0.0-preview-bd04b248

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/CHANGELOG.md +5 -5
  2. package/dist/TransactionController.cjs +27 -3
  3. package/dist/TransactionController.cjs.map +1 -1
  4. package/dist/TransactionController.d.cts +6 -0
  5. package/dist/TransactionController.d.cts.map +1 -1
  6. package/dist/TransactionController.d.mts +6 -0
  7. package/dist/TransactionController.d.mts.map +1 -1
  8. package/dist/TransactionController.mjs +25 -1
  9. package/dist/TransactionController.mjs.map +1 -1
  10. package/dist/helpers/MethodDataHelper.cjs +22 -24
  11. package/dist/helpers/MethodDataHelper.cjs.map +1 -1
  12. package/dist/helpers/MethodDataHelper.d.cts +3 -2
  13. package/dist/helpers/MethodDataHelper.d.cts.map +1 -1
  14. package/dist/helpers/MethodDataHelper.d.mts +3 -2
  15. package/dist/helpers/MethodDataHelper.d.mts.map +1 -1
  16. package/dist/helpers/MethodDataHelper.mjs +22 -24
  17. package/dist/helpers/MethodDataHelper.mjs.map +1 -1
  18. package/dist/{utils/resimulate.cjs → helpers/ResimulateHelper.cjs} +99 -4
  19. package/dist/helpers/ResimulateHelper.cjs.map +1 -0
  20. package/dist/{utils/resimulate.d.cts → helpers/ResimulateHelper.d.cts} +13 -1
  21. package/dist/helpers/ResimulateHelper.d.cts.map +1 -0
  22. package/dist/{utils/resimulate.d.mts → helpers/ResimulateHelper.d.mts} +13 -1
  23. package/dist/helpers/ResimulateHelper.d.mts.map +1 -0
  24. package/dist/{utils/resimulate.mjs → helpers/ResimulateHelper.mjs} +99 -5
  25. package/dist/helpers/ResimulateHelper.mjs.map +1 -0
  26. package/dist/types.cjs.map +1 -1
  27. package/dist/types.d.cts +4 -0
  28. package/dist/types.d.cts.map +1 -1
  29. package/dist/types.d.mts +4 -0
  30. package/dist/types.d.mts.map +1 -1
  31. package/dist/types.mjs.map +1 -1
  32. package/package.json +2 -1
  33. package/dist/utils/resimulate.cjs.map +0 -1
  34. package/dist/utils/resimulate.d.cts.map +0 -1
  35. package/dist/utils/resimulate.d.mts.map +0 -1
  36. package/dist/utils/resimulate.mjs.map +0 -1
@@ -13,26 +13,28 @@ 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 _MethodDataHelper_instances, _MethodDataHelper_getState, _MethodDataHelper_interfaceByNetworkClientId, _MethodDataHelper_mutex, _MethodDataHelper_interfaceLookup;
16
+ var _MethodDataHelper_instances, _MethodDataHelper_getProvider, _MethodDataHelper_getState, _MethodDataHelper_methodRegistryByNetworkClientId, _MethodDataHelper_mutex, _MethodDataHelper_registryLookup;
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.MethodDataHelper = void 0;
19
- const abi_1 = require("@ethersproject/abi");
20
19
  const utils_1 = require("@metamask/utils");
21
20
  const async_mutex_1 = require("async-mutex");
21
+ const eth_method_registry_1 = require("eth-method-registry");
22
22
  // This package purposefully relies on Node's EventEmitter module.
23
23
  // eslint-disable-next-line import-x/no-nodejs-modules
24
24
  const events_1 = __importDefault(require("events"));
25
25
  const logger_1 = require("../logger.cjs");
26
26
  const log = (0, utils_1.createModuleLogger)(logger_1.projectLogger, 'method-data');
27
27
  class MethodDataHelper {
28
- constructor({ getState }) {
28
+ constructor({ getProvider, getState, }) {
29
29
  _MethodDataHelper_instances.add(this);
30
+ _MethodDataHelper_getProvider.set(this, void 0);
30
31
  _MethodDataHelper_getState.set(this, void 0);
31
- _MethodDataHelper_interfaceByNetworkClientId.set(this, void 0);
32
+ _MethodDataHelper_methodRegistryByNetworkClientId.set(this, void 0);
32
33
  _MethodDataHelper_mutex.set(this, new async_mutex_1.Mutex());
33
34
  this.hub = new events_1.default();
35
+ __classPrivateFieldSet(this, _MethodDataHelper_getProvider, getProvider, "f");
34
36
  __classPrivateFieldSet(this, _MethodDataHelper_getState, getState, "f");
35
- __classPrivateFieldSet(this, _MethodDataHelper_interfaceByNetworkClientId, new Map(), "f");
37
+ __classPrivateFieldSet(this, _MethodDataHelper_methodRegistryByNetworkClientId, new Map(), "f");
36
38
  }
37
39
  async lookup(fourBytePrefix, networkClientId) {
38
40
  log('lookup', fourBytePrefix, networkClientId);
@@ -43,13 +45,15 @@ class MethodDataHelper {
43
45
  log('Cached', cachedResult);
44
46
  return cachedResult;
45
47
  }
46
- let iface = __classPrivateFieldGet(this, _MethodDataHelper_interfaceByNetworkClientId, "f").get(networkClientId);
47
- if (!iface) {
48
- iface = new abi_1.Interface([]);
49
- __classPrivateFieldGet(this, _MethodDataHelper_interfaceByNetworkClientId, "f").set(networkClientId, iface);
50
- log('Created interface', networkClientId);
48
+ let registry = __classPrivateFieldGet(this, _MethodDataHelper_methodRegistryByNetworkClientId, "f").get(networkClientId);
49
+ if (!registry) {
50
+ const provider = __classPrivateFieldGet(this, _MethodDataHelper_getProvider, "f").call(this, networkClientId);
51
+ // @ts-expect-error Type in eth-method-registry is inappropriate and should be changed
52
+ registry = new eth_method_registry_1.MethodRegistry({ provider });
53
+ __classPrivateFieldGet(this, _MethodDataHelper_methodRegistryByNetworkClientId, "f").set(networkClientId, registry);
54
+ log('Created registry', networkClientId);
51
55
  }
52
- const methodData = await __classPrivateFieldGet(this, _MethodDataHelper_instances, "m", _MethodDataHelper_interfaceLookup).call(this, fourBytePrefix, iface);
56
+ const methodData = await __classPrivateFieldGet(this, _MethodDataHelper_instances, "m", _MethodDataHelper_registryLookup).call(this, fourBytePrefix, registry);
53
57
  log('Result', methodData);
54
58
  this.hub.emit('update', { fourBytePrefix, methodData });
55
59
  return methodData;
@@ -60,23 +64,17 @@ class MethodDataHelper {
60
64
  }
61
65
  }
62
66
  exports.MethodDataHelper = MethodDataHelper;
63
- _MethodDataHelper_getState = new WeakMap(), _MethodDataHelper_interfaceByNetworkClientId = new WeakMap(), _MethodDataHelper_mutex = new WeakMap(), _MethodDataHelper_instances = new WeakSet(), _MethodDataHelper_interfaceLookup = async function _MethodDataHelper_interfaceLookup(fourBytePrefix, iface) {
64
- try {
65
- const functionFragment = iface.getFunction(fourBytePrefix);
66
- return {
67
- registryMethod: functionFragment.format(),
68
- parsedRegistryMethod: {
69
- name: functionFragment.name,
70
- args: functionFragment.inputs.map(({ type }) => ({ type })),
71
- },
72
- };
73
- }
74
- catch {
75
- log('No method found or invalid signature', fourBytePrefix);
67
+ _MethodDataHelper_getProvider = new WeakMap(), _MethodDataHelper_getState = new WeakMap(), _MethodDataHelper_methodRegistryByNetworkClientId = new WeakMap(), _MethodDataHelper_mutex = new WeakMap(), _MethodDataHelper_instances = new WeakSet(), _MethodDataHelper_registryLookup = async function _MethodDataHelper_registryLookup(fourBytePrefix, methodRegistry) {
68
+ const registryMethod = await methodRegistry.lookup(fourBytePrefix);
69
+ if (!registryMethod) {
70
+ log('No method found', fourBytePrefix);
76
71
  return {
77
72
  registryMethod: '',
78
73
  parsedRegistryMethod: { name: undefined, args: undefined },
79
74
  };
80
75
  }
76
+ log('Parsing', registryMethod);
77
+ const parsedRegistryMethod = methodRegistry.parse(registryMethod);
78
+ return { registryMethod, parsedRegistryMethod };
81
79
  };
82
80
  //# sourceMappingURL=MethodDataHelper.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"MethodDataHelper.cjs","sourceRoot":"","sources":["../../src/helpers/MethodDataHelper.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,4CAA+C;AAE/C,2CAAqD;AACrD,6CAAoC;AACpC,kEAAkE;AAClE,sDAAsD;AACtD,oDAAkC;AAElC,0CAA0C;AAG1C,MAAM,GAAG,GAAG,IAAA,0BAAkB,EAAC,sBAAa,EAAE,aAAa,CAAC,CAAC;AAE7D,MAAa,gBAAgB;IAS3B,YAAY,EAAE,QAAQ,EAAkD;;QANxE,6CAA4C;QAE5C,+DAA6D;QAE7D,kCAAS,IAAI,mBAAK,EAAE,EAAC;QAGnB,IAAI,CAAC,GAAG,GAAG,IAAI,gBAAY,EAAE,CAAC;QAE9B,uBAAA,IAAI,8BAAa,QAAQ,MAAA,CAAC;QAC1B,uBAAA,IAAI,gDAA+B,IAAI,GAAG,EAAE,MAAA,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,MAAM,CACV,cAAsB,EACtB,eAAgC;QAEhC,GAAG,CAAC,QAAQ,EAAE,cAAc,EAAE,eAAe,CAAC,CAAC;QAE/C,MAAM,WAAW,GAAG,MAAM,uBAAA,IAAI,+BAAO,CAAC,OAAO,EAAE,CAAC;QAEhD,IAAI;YACF,MAAM,YAAY,GAAG,uBAAA,IAAI,kCAAU,MAAd,IAAI,CAAY,CAAC,cAAc,CAAC,CAAC;YAEtD,IAAI,YAAY,EAAE;gBAChB,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;gBAC5B,OAAO,YAAY,CAAC;aACrB;YAED,IAAI,KAAK,GAAG,uBAAA,IAAI,oDAA4B,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAElE,IAAI,CAAC,KAAK,EAAE;gBACV,KAAK,GAAG,IAAI,eAAS,CAAC,EAAE,CAAC,CAAC;gBAC1B,uBAAA,IAAI,oDAA4B,CAAC,GAAG,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;gBAC7D,GAAG,CAAC,mBAAmB,EAAE,eAAe,CAAC,CAAC;aAC3C;YAED,MAAM,UAAU,GAAG,MAAM,uBAAA,IAAI,sEAAiB,MAArB,IAAI,EAAkB,cAAc,EAAE,KAAK,CAAC,CAAC;YAEtE,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YAE1B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,cAAc,EAAE,UAAU,EAAE,CAAC,CAAC;YAExD,OAAO,UAAU,CAAC;SACnB;gBAAS;YACR,WAAW,EAAE,CAAC;SACf;IACH,CAAC;CAuBF;AAzED,4CAyEC;oOArBC,KAAK,4CACH,cAAsB,EACtB,KAAgB;IAEhB,IAAI;QACF,MAAM,gBAAgB,GAAG,KAAK,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC;QAC3D,OAAO;YACL,cAAc,EAAE,gBAAgB,CAAC,MAAM,EAAE;YACzC,oBAAoB,EAAE;gBACpB,IAAI,EAAE,gBAAgB,CAAC,IAAI;gBAC3B,IAAI,EAAE,gBAAgB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;aAC5D;SACF,CAAC;KACH;IAAC,MAAM;QACN,GAAG,CAAC,sCAAsC,EAAE,cAAc,CAAC,CAAC;QAC5D,OAAO;YACL,cAAc,EAAE,EAAE;YAClB,oBAAoB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;SAC3D,CAAC;KACH;AACH,CAAC","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport type { NetworkClientId } from '@metamask/network-controller';\nimport { createModuleLogger } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\n// This package purposefully relies on Node's EventEmitter module.\n// eslint-disable-next-line import-x/no-nodejs-modules\nimport EventEmitter from 'events';\n\nimport { projectLogger } from '../logger';\nimport type { MethodData } from '../TransactionController';\n\nconst log = createModuleLogger(projectLogger, 'method-data');\n\nexport class MethodDataHelper {\n hub: EventEmitter;\n\n #getState: () => Record<string, MethodData>;\n\n #interfaceByNetworkClientId: Map<NetworkClientId, Interface>;\n\n #mutex = new Mutex();\n\n constructor({ getState }: { getState: () => Record<string, MethodData> }) {\n this.hub = new EventEmitter();\n\n this.#getState = getState;\n this.#interfaceByNetworkClientId = new Map();\n }\n\n async lookup(\n fourBytePrefix: string,\n networkClientId: NetworkClientId,\n ): Promise<MethodData> {\n log('lookup', fourBytePrefix, networkClientId);\n\n const releaseLock = await this.#mutex.acquire();\n\n try {\n const cachedResult = this.#getState()[fourBytePrefix];\n\n if (cachedResult) {\n log('Cached', cachedResult);\n return cachedResult;\n }\n\n let iface = this.#interfaceByNetworkClientId.get(networkClientId);\n\n if (!iface) {\n iface = new Interface([]);\n this.#interfaceByNetworkClientId.set(networkClientId, iface);\n log('Created interface', networkClientId);\n }\n\n const methodData = await this.#interfaceLookup(fourBytePrefix, iface);\n\n log('Result', methodData);\n\n this.hub.emit('update', { fourBytePrefix, methodData });\n\n return methodData;\n } finally {\n releaseLock();\n }\n }\n\n async #interfaceLookup(\n fourBytePrefix: string,\n iface: Interface,\n ): Promise<MethodData> {\n try {\n const functionFragment = iface.getFunction(fourBytePrefix);\n return {\n registryMethod: functionFragment.format(),\n parsedRegistryMethod: {\n name: functionFragment.name,\n args: functionFragment.inputs.map(({ type }) => ({ type })),\n },\n };\n } catch {\n log('No method found or invalid signature', fourBytePrefix);\n return {\n registryMethod: '',\n parsedRegistryMethod: { name: undefined, args: undefined },\n };\n }\n }\n}\n"]}
1
+ {"version":3,"file":"MethodDataHelper.cjs","sourceRoot":"","sources":["../../src/helpers/MethodDataHelper.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AACA,2CAAqD;AACrD,6CAAoC;AACpC,6DAAqD;AACrD,kEAAkE;AAClE,sDAAsD;AACtD,oDAAkC;AAElC,0CAA0C;AAG1C,MAAM,GAAG,GAAG,IAAA,0BAAkB,EAAC,sBAAa,EAAE,aAAa,CAAC,CAAC;AAE7D,MAAa,gBAAgB;IAW3B,YAAY,EACV,WAAW,EACX,QAAQ,GAIT;;QAdD,gDAA6D;QAE7D,6CAA4C;QAE5C,oEAAuE;QAEvE,kCAAS,IAAI,mBAAK,EAAE,EAAC;QASnB,IAAI,CAAC,GAAG,GAAG,IAAI,gBAAY,EAAE,CAAC;QAE9B,uBAAA,IAAI,iCAAgB,WAAW,MAAA,CAAC;QAChC,uBAAA,IAAI,8BAAa,QAAQ,MAAA,CAAC;QAC1B,uBAAA,IAAI,qDAAoC,IAAI,GAAG,EAAE,MAAA,CAAC;IACpD,CAAC;IAED,KAAK,CAAC,MAAM,CACV,cAAsB,EACtB,eAAgC;QAEhC,GAAG,CAAC,QAAQ,EAAE,cAAc,EAAE,eAAe,CAAC,CAAC;QAE/C,MAAM,WAAW,GAAG,MAAM,uBAAA,IAAI,+BAAO,CAAC,OAAO,EAAE,CAAC;QAEhD,IAAI;YACF,MAAM,YAAY,GAAG,uBAAA,IAAI,kCAAU,MAAd,IAAI,CAAY,CAAC,cAAc,CAAC,CAAC;YAEtD,IAAI,YAAY,EAAE;gBAChB,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;gBAC5B,OAAO,YAAY,CAAC;aACrB;YAED,IAAI,QAAQ,GAAG,uBAAA,IAAI,yDAAiC,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAE1E,IAAI,CAAC,QAAQ,EAAE;gBACb,MAAM,QAAQ,GAAG,uBAAA,IAAI,qCAAa,MAAjB,IAAI,EAAc,eAAe,CAAC,CAAC;gBAEpD,sFAAsF;gBACtF,QAAQ,GAAG,IAAI,oCAAc,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;gBAE5C,uBAAA,IAAI,yDAAiC,CAAC,GAAG,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;gBAErE,GAAG,CAAC,kBAAkB,EAAE,eAAe,CAAC,CAAC;aAC1C;YAED,MAAM,UAAU,GAAG,MAAM,uBAAA,IAAI,qEAAgB,MAApB,IAAI,EAAiB,cAAc,EAAE,QAAQ,CAAC,CAAC;YAExE,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YAE1B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,cAAc,EAAE,UAAU,EAAE,CAAC,CAAC;YAExD,OAAO,UAAU,CAAC;SACnB;gBAAS;YACR,WAAW,EAAE,CAAC;SACf;IACH,CAAC;CAuBF;AAvFD,4CAuFC;uRArBC,KAAK,2CACH,cAAsB,EACtB,cAA8B;IAE9B,MAAM,cAAc,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IAEnE,IAAI,CAAC,cAAc,EAAE;QACnB,GAAG,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAC;QAEvC,OAAO;YACL,cAAc,EAAE,EAAE;YAClB,oBAAoB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;SAC3D,CAAC;KACH;IAED,GAAG,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IAE/B,MAAM,oBAAoB,GAAG,cAAc,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAElE,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,CAAC;AAClD,CAAC","sourcesContent":["import type { NetworkClientId, Provider } from '@metamask/network-controller';\nimport { createModuleLogger } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\nimport { MethodRegistry } from 'eth-method-registry';\n// This package purposefully relies on Node's EventEmitter module.\n// eslint-disable-next-line import-x/no-nodejs-modules\nimport EventEmitter from 'events';\n\nimport { projectLogger } from '../logger';\nimport type { MethodData } from '../TransactionController';\n\nconst log = createModuleLogger(projectLogger, 'method-data');\n\nexport class MethodDataHelper {\n hub: EventEmitter;\n\n #getProvider: (networkClientId: NetworkClientId) => Provider;\n\n #getState: () => Record<string, MethodData>;\n\n #methodRegistryByNetworkClientId: Map<NetworkClientId, MethodRegistry>;\n\n #mutex = new Mutex();\n\n constructor({\n getProvider,\n getState,\n }: {\n getProvider: (networkClientId: NetworkClientId) => Provider;\n getState: () => Record<string, MethodData>;\n }) {\n this.hub = new EventEmitter();\n\n this.#getProvider = getProvider;\n this.#getState = getState;\n this.#methodRegistryByNetworkClientId = new Map();\n }\n\n async lookup(\n fourBytePrefix: string,\n networkClientId: NetworkClientId,\n ): Promise<MethodData> {\n log('lookup', fourBytePrefix, networkClientId);\n\n const releaseLock = await this.#mutex.acquire();\n\n try {\n const cachedResult = this.#getState()[fourBytePrefix];\n\n if (cachedResult) {\n log('Cached', cachedResult);\n return cachedResult;\n }\n\n let registry = this.#methodRegistryByNetworkClientId.get(networkClientId);\n\n if (!registry) {\n const provider = this.#getProvider(networkClientId);\n\n // @ts-expect-error Type in eth-method-registry is inappropriate and should be changed\n registry = new MethodRegistry({ provider });\n\n this.#methodRegistryByNetworkClientId.set(networkClientId, registry);\n\n log('Created registry', networkClientId);\n }\n\n const methodData = await this.#registryLookup(fourBytePrefix, registry);\n\n log('Result', methodData);\n\n this.hub.emit('update', { fourBytePrefix, methodData });\n\n return methodData;\n } finally {\n releaseLock();\n }\n }\n\n async #registryLookup(\n fourBytePrefix: string,\n methodRegistry: MethodRegistry,\n ): Promise<MethodData> {\n const registryMethod = await methodRegistry.lookup(fourBytePrefix);\n\n if (!registryMethod) {\n log('No method found', fourBytePrefix);\n\n return {\n registryMethod: '',\n parsedRegistryMethod: { name: undefined, args: undefined },\n };\n }\n\n log('Parsing', registryMethod);\n\n const parsedRegistryMethod = methodRegistry.parse(registryMethod);\n\n return { registryMethod, parsedRegistryMethod };\n }\n}\n"]}
@@ -1,11 +1,12 @@
1
1
  /// <reference types="node" />
2
- import type { NetworkClientId } from "@metamask/network-controller";
2
+ import type { NetworkClientId, Provider } from "@metamask/network-controller";
3
3
  import EventEmitter from "events";
4
4
  import type { MethodData } from "../TransactionController.cjs";
5
5
  export declare class MethodDataHelper {
6
6
  #private;
7
7
  hub: EventEmitter;
8
- constructor({ getState }: {
8
+ constructor({ getProvider, getState, }: {
9
+ getProvider: (networkClientId: NetworkClientId) => Provider;
9
10
  getState: () => Record<string, MethodData>;
10
11
  });
11
12
  lookup(fourBytePrefix: string, networkClientId: NetworkClientId): Promise<MethodData>;
@@ -1 +1 @@
1
- {"version":3,"file":"MethodDataHelper.d.cts","sourceRoot":"","sources":["../../src/helpers/MethodDataHelper.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,EAAE,eAAe,EAAE,qCAAqC;AAKpE,OAAO,YAAY,eAAe;AAGlC,OAAO,KAAK,EAAE,UAAU,EAAE,qCAAiC;AAI3D,qBAAa,gBAAgB;;IAC3B,GAAG,EAAE,YAAY,CAAC;gBAQN,EAAE,QAAQ,EAAE,EAAE;QAAE,QAAQ,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;KAAE;IAOlE,MAAM,CACV,cAAc,EAAE,MAAM,EACtB,eAAe,EAAE,eAAe,GAC/B,OAAO,CAAC,UAAU,CAAC;CAsDvB"}
1
+ {"version":3,"file":"MethodDataHelper.d.cts","sourceRoot":"","sources":["../../src/helpers/MethodDataHelper.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,qCAAqC;AAM9E,OAAO,YAAY,eAAe;AAGlC,OAAO,KAAK,EAAE,UAAU,EAAE,qCAAiC;AAI3D,qBAAa,gBAAgB;;IAC3B,GAAG,EAAE,YAAY,CAAC;gBAUN,EACV,WAAW,EACX,QAAQ,GACT,EAAE;QACD,WAAW,EAAE,CAAC,eAAe,EAAE,eAAe,KAAK,QAAQ,CAAC;QAC5D,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;CA2DvB"}
@@ -1,11 +1,12 @@
1
1
  /// <reference types="node" />
2
- import type { NetworkClientId } from "@metamask/network-controller";
2
+ import type { NetworkClientId, Provider } from "@metamask/network-controller";
3
3
  import EventEmitter from "events";
4
4
  import type { MethodData } from "../TransactionController.mjs";
5
5
  export declare class MethodDataHelper {
6
6
  #private;
7
7
  hub: EventEmitter;
8
- constructor({ getState }: {
8
+ constructor({ getProvider, getState, }: {
9
+ getProvider: (networkClientId: NetworkClientId) => Provider;
9
10
  getState: () => Record<string, MethodData>;
10
11
  });
11
12
  lookup(fourBytePrefix: string, networkClientId: NetworkClientId): Promise<MethodData>;
@@ -1 +1 @@
1
- {"version":3,"file":"MethodDataHelper.d.mts","sourceRoot":"","sources":["../../src/helpers/MethodDataHelper.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,EAAE,eAAe,EAAE,qCAAqC;AAKpE,OAAO,YAAY,eAAe;AAGlC,OAAO,KAAK,EAAE,UAAU,EAAE,qCAAiC;AAI3D,qBAAa,gBAAgB;;IAC3B,GAAG,EAAE,YAAY,CAAC;gBAQN,EAAE,QAAQ,EAAE,EAAE;QAAE,QAAQ,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;KAAE;IAOlE,MAAM,CACV,cAAc,EAAE,MAAM,EACtB,eAAe,EAAE,eAAe,GAC/B,OAAO,CAAC,UAAU,CAAC;CAsDvB"}
1
+ {"version":3,"file":"MethodDataHelper.d.mts","sourceRoot":"","sources":["../../src/helpers/MethodDataHelper.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,qCAAqC;AAM9E,OAAO,YAAY,eAAe;AAGlC,OAAO,KAAK,EAAE,UAAU,EAAE,qCAAiC;AAI3D,qBAAa,gBAAgB;;IAC3B,GAAG,EAAE,YAAY,CAAC;gBAUN,EACV,WAAW,EACX,QAAQ,GACT,EAAE;QACD,WAAW,EAAE,CAAC,eAAe,EAAE,eAAe,KAAK,QAAQ,CAAC;QAC5D,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;CA2DvB"}
@@ -9,24 +9,26 @@ 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 _MethodDataHelper_instances, _MethodDataHelper_getState, _MethodDataHelper_interfaceByNetworkClientId, _MethodDataHelper_mutex, _MethodDataHelper_interfaceLookup;
13
- import { Interface } from "@ethersproject/abi";
12
+ var _MethodDataHelper_instances, _MethodDataHelper_getProvider, _MethodDataHelper_getState, _MethodDataHelper_methodRegistryByNetworkClientId, _MethodDataHelper_mutex, _MethodDataHelper_registryLookup;
14
13
  import { createModuleLogger } from "@metamask/utils";
15
14
  import { Mutex } from "async-mutex";
15
+ import { MethodRegistry } from "eth-method-registry";
16
16
  // This package purposefully relies on Node's EventEmitter module.
17
17
  // eslint-disable-next-line import-x/no-nodejs-modules
18
18
  import EventEmitter from "events";
19
19
  import { projectLogger } from "../logger.mjs";
20
20
  const log = createModuleLogger(projectLogger, 'method-data');
21
21
  export class MethodDataHelper {
22
- constructor({ getState }) {
22
+ constructor({ getProvider, getState, }) {
23
23
  _MethodDataHelper_instances.add(this);
24
+ _MethodDataHelper_getProvider.set(this, void 0);
24
25
  _MethodDataHelper_getState.set(this, void 0);
25
- _MethodDataHelper_interfaceByNetworkClientId.set(this, void 0);
26
+ _MethodDataHelper_methodRegistryByNetworkClientId.set(this, void 0);
26
27
  _MethodDataHelper_mutex.set(this, new Mutex());
27
28
  this.hub = new EventEmitter();
29
+ __classPrivateFieldSet(this, _MethodDataHelper_getProvider, getProvider, "f");
28
30
  __classPrivateFieldSet(this, _MethodDataHelper_getState, getState, "f");
29
- __classPrivateFieldSet(this, _MethodDataHelper_interfaceByNetworkClientId, new Map(), "f");
31
+ __classPrivateFieldSet(this, _MethodDataHelper_methodRegistryByNetworkClientId, new Map(), "f");
30
32
  }
31
33
  async lookup(fourBytePrefix, networkClientId) {
32
34
  log('lookup', fourBytePrefix, networkClientId);
@@ -37,13 +39,15 @@ export class MethodDataHelper {
37
39
  log('Cached', cachedResult);
38
40
  return cachedResult;
39
41
  }
40
- let iface = __classPrivateFieldGet(this, _MethodDataHelper_interfaceByNetworkClientId, "f").get(networkClientId);
41
- if (!iface) {
42
- iface = new Interface([]);
43
- __classPrivateFieldGet(this, _MethodDataHelper_interfaceByNetworkClientId, "f").set(networkClientId, iface);
44
- log('Created interface', networkClientId);
42
+ let registry = __classPrivateFieldGet(this, _MethodDataHelper_methodRegistryByNetworkClientId, "f").get(networkClientId);
43
+ if (!registry) {
44
+ const provider = __classPrivateFieldGet(this, _MethodDataHelper_getProvider, "f").call(this, networkClientId);
45
+ // @ts-expect-error Type in eth-method-registry is inappropriate and should be changed
46
+ registry = new MethodRegistry({ provider });
47
+ __classPrivateFieldGet(this, _MethodDataHelper_methodRegistryByNetworkClientId, "f").set(networkClientId, registry);
48
+ log('Created registry', networkClientId);
45
49
  }
46
- const methodData = await __classPrivateFieldGet(this, _MethodDataHelper_instances, "m", _MethodDataHelper_interfaceLookup).call(this, fourBytePrefix, iface);
50
+ const methodData = await __classPrivateFieldGet(this, _MethodDataHelper_instances, "m", _MethodDataHelper_registryLookup).call(this, fourBytePrefix, registry);
47
51
  log('Result', methodData);
48
52
  this.hub.emit('update', { fourBytePrefix, methodData });
49
53
  return methodData;
@@ -53,23 +57,17 @@ export class MethodDataHelper {
53
57
  }
54
58
  }
55
59
  }
56
- _MethodDataHelper_getState = new WeakMap(), _MethodDataHelper_interfaceByNetworkClientId = new WeakMap(), _MethodDataHelper_mutex = new WeakMap(), _MethodDataHelper_instances = new WeakSet(), _MethodDataHelper_interfaceLookup = async function _MethodDataHelper_interfaceLookup(fourBytePrefix, iface) {
57
- try {
58
- const functionFragment = iface.getFunction(fourBytePrefix);
59
- return {
60
- registryMethod: functionFragment.format(),
61
- parsedRegistryMethod: {
62
- name: functionFragment.name,
63
- args: functionFragment.inputs.map(({ type }) => ({ type })),
64
- },
65
- };
66
- }
67
- catch {
68
- log('No method found or invalid signature', fourBytePrefix);
60
+ _MethodDataHelper_getProvider = new WeakMap(), _MethodDataHelper_getState = new WeakMap(), _MethodDataHelper_methodRegistryByNetworkClientId = new WeakMap(), _MethodDataHelper_mutex = new WeakMap(), _MethodDataHelper_instances = new WeakSet(), _MethodDataHelper_registryLookup = async function _MethodDataHelper_registryLookup(fourBytePrefix, methodRegistry) {
61
+ const registryMethod = await methodRegistry.lookup(fourBytePrefix);
62
+ if (!registryMethod) {
63
+ log('No method found', fourBytePrefix);
69
64
  return {
70
65
  registryMethod: '',
71
66
  parsedRegistryMethod: { name: undefined, args: undefined },
72
67
  };
73
68
  }
69
+ log('Parsing', registryMethod);
70
+ const parsedRegistryMethod = methodRegistry.parse(registryMethod);
71
+ return { registryMethod, parsedRegistryMethod };
74
72
  };
75
73
  //# sourceMappingURL=MethodDataHelper.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"MethodDataHelper.mjs","sourceRoot":"","sources":["../../src/helpers/MethodDataHelper.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,SAAS,EAAE,2BAA2B;AAE/C,OAAO,EAAE,kBAAkB,EAAE,wBAAwB;AACrD,OAAO,EAAE,KAAK,EAAE,oBAAoB;AACpC,kEAAkE;AAClE,sDAAsD;AACtD,OAAO,YAAY,eAAe;AAElC,OAAO,EAAE,aAAa,EAAE,sBAAkB;AAG1C,MAAM,GAAG,GAAG,kBAAkB,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;AAE7D,MAAM,OAAO,gBAAgB;IAS3B,YAAY,EAAE,QAAQ,EAAkD;;QANxE,6CAA4C;QAE5C,+DAA6D;QAE7D,kCAAS,IAAI,KAAK,EAAE,EAAC;QAGnB,IAAI,CAAC,GAAG,GAAG,IAAI,YAAY,EAAE,CAAC;QAE9B,uBAAA,IAAI,8BAAa,QAAQ,MAAA,CAAC;QAC1B,uBAAA,IAAI,gDAA+B,IAAI,GAAG,EAAE,MAAA,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,MAAM,CACV,cAAsB,EACtB,eAAgC;QAEhC,GAAG,CAAC,QAAQ,EAAE,cAAc,EAAE,eAAe,CAAC,CAAC;QAE/C,MAAM,WAAW,GAAG,MAAM,uBAAA,IAAI,+BAAO,CAAC,OAAO,EAAE,CAAC;QAEhD,IAAI;YACF,MAAM,YAAY,GAAG,uBAAA,IAAI,kCAAU,MAAd,IAAI,CAAY,CAAC,cAAc,CAAC,CAAC;YAEtD,IAAI,YAAY,EAAE;gBAChB,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;gBAC5B,OAAO,YAAY,CAAC;aACrB;YAED,IAAI,KAAK,GAAG,uBAAA,IAAI,oDAA4B,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAElE,IAAI,CAAC,KAAK,EAAE;gBACV,KAAK,GAAG,IAAI,SAAS,CAAC,EAAE,CAAC,CAAC;gBAC1B,uBAAA,IAAI,oDAA4B,CAAC,GAAG,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;gBAC7D,GAAG,CAAC,mBAAmB,EAAE,eAAe,CAAC,CAAC;aAC3C;YAED,MAAM,UAAU,GAAG,MAAM,uBAAA,IAAI,sEAAiB,MAArB,IAAI,EAAkB,cAAc,EAAE,KAAK,CAAC,CAAC;YAEtE,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YAE1B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,cAAc,EAAE,UAAU,EAAE,CAAC,CAAC;YAExD,OAAO,UAAU,CAAC;SACnB;gBAAS;YACR,WAAW,EAAE,CAAC;SACf;IACH,CAAC;CAuBF;oOArBC,KAAK,4CACH,cAAsB,EACtB,KAAgB;IAEhB,IAAI;QACF,MAAM,gBAAgB,GAAG,KAAK,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC;QAC3D,OAAO;YACL,cAAc,EAAE,gBAAgB,CAAC,MAAM,EAAE;YACzC,oBAAoB,EAAE;gBACpB,IAAI,EAAE,gBAAgB,CAAC,IAAI;gBAC3B,IAAI,EAAE,gBAAgB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;aAC5D;SACF,CAAC;KACH;IAAC,MAAM;QACN,GAAG,CAAC,sCAAsC,EAAE,cAAc,CAAC,CAAC;QAC5D,OAAO;YACL,cAAc,EAAE,EAAE;YAClB,oBAAoB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;SAC3D,CAAC;KACH;AACH,CAAC","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport type { NetworkClientId } from '@metamask/network-controller';\nimport { createModuleLogger } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\n// This package purposefully relies on Node's EventEmitter module.\n// eslint-disable-next-line import-x/no-nodejs-modules\nimport EventEmitter from 'events';\n\nimport { projectLogger } from '../logger';\nimport type { MethodData } from '../TransactionController';\n\nconst log = createModuleLogger(projectLogger, 'method-data');\n\nexport class MethodDataHelper {\n hub: EventEmitter;\n\n #getState: () => Record<string, MethodData>;\n\n #interfaceByNetworkClientId: Map<NetworkClientId, Interface>;\n\n #mutex = new Mutex();\n\n constructor({ getState }: { getState: () => Record<string, MethodData> }) {\n this.hub = new EventEmitter();\n\n this.#getState = getState;\n this.#interfaceByNetworkClientId = new Map();\n }\n\n async lookup(\n fourBytePrefix: string,\n networkClientId: NetworkClientId,\n ): Promise<MethodData> {\n log('lookup', fourBytePrefix, networkClientId);\n\n const releaseLock = await this.#mutex.acquire();\n\n try {\n const cachedResult = this.#getState()[fourBytePrefix];\n\n if (cachedResult) {\n log('Cached', cachedResult);\n return cachedResult;\n }\n\n let iface = this.#interfaceByNetworkClientId.get(networkClientId);\n\n if (!iface) {\n iface = new Interface([]);\n this.#interfaceByNetworkClientId.set(networkClientId, iface);\n log('Created interface', networkClientId);\n }\n\n const methodData = await this.#interfaceLookup(fourBytePrefix, iface);\n\n log('Result', methodData);\n\n this.hub.emit('update', { fourBytePrefix, methodData });\n\n return methodData;\n } finally {\n releaseLock();\n }\n }\n\n async #interfaceLookup(\n fourBytePrefix: string,\n iface: Interface,\n ): Promise<MethodData> {\n try {\n const functionFragment = iface.getFunction(fourBytePrefix);\n return {\n registryMethod: functionFragment.format(),\n parsedRegistryMethod: {\n name: functionFragment.name,\n args: functionFragment.inputs.map(({ type }) => ({ type })),\n },\n };\n } catch {\n log('No method found or invalid signature', fourBytePrefix);\n return {\n registryMethod: '',\n parsedRegistryMethod: { name: undefined, args: undefined },\n };\n }\n }\n}\n"]}
1
+ {"version":3,"file":"MethodDataHelper.mjs","sourceRoot":"","sources":["../../src/helpers/MethodDataHelper.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,OAAO,EAAE,kBAAkB,EAAE,wBAAwB;AACrD,OAAO,EAAE,KAAK,EAAE,oBAAoB;AACpC,OAAO,EAAE,cAAc,EAAE,4BAA4B;AACrD,kEAAkE;AAClE,sDAAsD;AACtD,OAAO,YAAY,eAAe;AAElC,OAAO,EAAE,aAAa,EAAE,sBAAkB;AAG1C,MAAM,GAAG,GAAG,kBAAkB,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;AAE7D,MAAM,OAAO,gBAAgB;IAW3B,YAAY,EACV,WAAW,EACX,QAAQ,GAIT;;QAdD,gDAA6D;QAE7D,6CAA4C;QAE5C,oEAAuE;QAEvE,kCAAS,IAAI,KAAK,EAAE,EAAC;QASnB,IAAI,CAAC,GAAG,GAAG,IAAI,YAAY,EAAE,CAAC;QAE9B,uBAAA,IAAI,iCAAgB,WAAW,MAAA,CAAC;QAChC,uBAAA,IAAI,8BAAa,QAAQ,MAAA,CAAC;QAC1B,uBAAA,IAAI,qDAAoC,IAAI,GAAG,EAAE,MAAA,CAAC;IACpD,CAAC;IAED,KAAK,CAAC,MAAM,CACV,cAAsB,EACtB,eAAgC;QAEhC,GAAG,CAAC,QAAQ,EAAE,cAAc,EAAE,eAAe,CAAC,CAAC;QAE/C,MAAM,WAAW,GAAG,MAAM,uBAAA,IAAI,+BAAO,CAAC,OAAO,EAAE,CAAC;QAEhD,IAAI;YACF,MAAM,YAAY,GAAG,uBAAA,IAAI,kCAAU,MAAd,IAAI,CAAY,CAAC,cAAc,CAAC,CAAC;YAEtD,IAAI,YAAY,EAAE;gBAChB,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;gBAC5B,OAAO,YAAY,CAAC;aACrB;YAED,IAAI,QAAQ,GAAG,uBAAA,IAAI,yDAAiC,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAE1E,IAAI,CAAC,QAAQ,EAAE;gBACb,MAAM,QAAQ,GAAG,uBAAA,IAAI,qCAAa,MAAjB,IAAI,EAAc,eAAe,CAAC,CAAC;gBAEpD,sFAAsF;gBACtF,QAAQ,GAAG,IAAI,cAAc,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;gBAE5C,uBAAA,IAAI,yDAAiC,CAAC,GAAG,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;gBAErE,GAAG,CAAC,kBAAkB,EAAE,eAAe,CAAC,CAAC;aAC1C;YAED,MAAM,UAAU,GAAG,MAAM,uBAAA,IAAI,qEAAgB,MAApB,IAAI,EAAiB,cAAc,EAAE,QAAQ,CAAC,CAAC;YAExE,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YAE1B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,cAAc,EAAE,UAAU,EAAE,CAAC,CAAC;YAExD,OAAO,UAAU,CAAC;SACnB;gBAAS;YACR,WAAW,EAAE,CAAC;SACf;IACH,CAAC;CAuBF;uRArBC,KAAK,2CACH,cAAsB,EACtB,cAA8B;IAE9B,MAAM,cAAc,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IAEnE,IAAI,CAAC,cAAc,EAAE;QACnB,GAAG,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAC;QAEvC,OAAO;YACL,cAAc,EAAE,EAAE;YAClB,oBAAoB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;SAC3D,CAAC;KACH;IAED,GAAG,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IAE/B,MAAM,oBAAoB,GAAG,cAAc,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAElE,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,CAAC;AAClD,CAAC","sourcesContent":["import type { NetworkClientId, Provider } from '@metamask/network-controller';\nimport { createModuleLogger } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\nimport { MethodRegistry } from 'eth-method-registry';\n// This package purposefully relies on Node's EventEmitter module.\n// eslint-disable-next-line import-x/no-nodejs-modules\nimport EventEmitter from 'events';\n\nimport { projectLogger } from '../logger';\nimport type { MethodData } from '../TransactionController';\n\nconst log = createModuleLogger(projectLogger, 'method-data');\n\nexport class MethodDataHelper {\n hub: EventEmitter;\n\n #getProvider: (networkClientId: NetworkClientId) => Provider;\n\n #getState: () => Record<string, MethodData>;\n\n #methodRegistryByNetworkClientId: Map<NetworkClientId, MethodRegistry>;\n\n #mutex = new Mutex();\n\n constructor({\n getProvider,\n getState,\n }: {\n getProvider: (networkClientId: NetworkClientId) => Provider;\n getState: () => Record<string, MethodData>;\n }) {\n this.hub = new EventEmitter();\n\n this.#getProvider = getProvider;\n this.#getState = getState;\n this.#methodRegistryByNetworkClientId = new Map();\n }\n\n async lookup(\n fourBytePrefix: string,\n networkClientId: NetworkClientId,\n ): Promise<MethodData> {\n log('lookup', fourBytePrefix, networkClientId);\n\n const releaseLock = await this.#mutex.acquire();\n\n try {\n const cachedResult = this.#getState()[fourBytePrefix];\n\n if (cachedResult) {\n log('Cached', cachedResult);\n return cachedResult;\n }\n\n let registry = this.#methodRegistryByNetworkClientId.get(networkClientId);\n\n if (!registry) {\n const provider = this.#getProvider(networkClientId);\n\n // @ts-expect-error Type in eth-method-registry is inappropriate and should be changed\n registry = new MethodRegistry({ provider });\n\n this.#methodRegistryByNetworkClientId.set(networkClientId, registry);\n\n log('Created registry', networkClientId);\n }\n\n const methodData = await this.#registryLookup(fourBytePrefix, registry);\n\n log('Result', methodData);\n\n this.hub.emit('update', { fourBytePrefix, methodData });\n\n return methodData;\n } finally {\n releaseLock();\n }\n }\n\n async #registryLookup(\n fourBytePrefix: string,\n methodRegistry: MethodRegistry,\n ): Promise<MethodData> {\n const registryMethod = await methodRegistry.lookup(fourBytePrefix);\n\n if (!registryMethod) {\n log('No method found', fourBytePrefix);\n\n return {\n registryMethod: '',\n parsedRegistryMethod: { name: undefined, args: undefined },\n };\n }\n\n log('Parsing', registryMethod);\n\n const parsedRegistryMethod = methodRegistry.parse(registryMethod);\n\n return { registryMethod, parsedRegistryMethod };\n }\n}\n"]}
@@ -1,18 +1,107 @@
1
1
  "use strict";
2
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
3
+ if (kind === "m") throw new TypeError("Private method is not writable");
4
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
5
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
7
+ };
8
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
9
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
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
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
+ };
13
+ var _ResimulateHelper_instances, _ResimulateHelper_activeResimulations, _ResimulateHelper_intervalIds, _ResimulateHelper_getTransactions, _ResimulateHelper_updateSimulationData, _ResimulateHelper_start, _ResimulateHelper_stop, _ResimulateHelper_removeListener, _ResimulateHelper_getUnapprovedTransactions;
2
14
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.hasSimulationDataChanged = exports.shouldResimulate = exports.BLOCK_TIME_ADDITIONAL_SECONDS = exports.VALUE_COMPARISON_PERCENT_THRESHOLD = exports.BLOCKAID_RESULT_TYPE_MALICIOUS = exports.RESIMULATE_PARAMS = void 0;
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;
4
16
  const utils_1 = require("@metamask/utils");
5
17
  const bn_js_1 = require("bn.js");
6
18
  const lodash_1 = require("lodash");
7
19
  const logger_1 = require("../logger.cjs");
8
- const utils_2 = require("./utils.cjs");
9
- const log = (0, utils_1.createModuleLogger)(logger_1.projectLogger, 'resimulate');
20
+ const types_1 = require("../types.cjs");
21
+ const utils_2 = require("../utils/utils.cjs");
22
+ const log = (0, logger_1.createModuleLogger)(logger_1.projectLogger, 'resimulate-helper');
10
23
  exports.RESIMULATE_PARAMS = ['to', 'value', 'data'];
11
24
  exports.BLOCKAID_RESULT_TYPE_MALICIOUS = 'Malicious';
12
25
  exports.VALUE_COMPARISON_PERCENT_THRESHOLD = 5;
13
26
  exports.BLOCK_TIME_ADDITIONAL_SECONDS = 60;
27
+ exports.RESIMULATE_INTERVAL_MS = 3000;
28
+ class ResimulateHelper {
29
+ constructor({ getTransactions, updateSimulationData, onStateChange, }) {
30
+ _ResimulateHelper_instances.add(this);
31
+ // Map of transactionId <=> isActive
32
+ _ResimulateHelper_activeResimulations.set(this, new Map());
33
+ // Map of transactionId <=> intervalId
34
+ _ResimulateHelper_intervalIds.set(this, new Map());
35
+ _ResimulateHelper_getTransactions.set(this, void 0);
36
+ _ResimulateHelper_updateSimulationData.set(this, void 0);
37
+ __classPrivateFieldSet(this, _ResimulateHelper_getTransactions, getTransactions, "f");
38
+ __classPrivateFieldSet(this, _ResimulateHelper_updateSimulationData, updateSimulationData, "f");
39
+ onStateChange(() => {
40
+ const unapprovedTransactions = __classPrivateFieldGet(this, _ResimulateHelper_instances, "m", _ResimulateHelper_getUnapprovedTransactions).call(this);
41
+ const unapprovedTransactionIds = new Set(unapprovedTransactions.map((tx) => tx.id));
42
+ // Start or stop resimulation based on the current isFocused state
43
+ unapprovedTransactions.forEach((transactionMeta) => {
44
+ if (transactionMeta.isFocused) {
45
+ __classPrivateFieldGet(this, _ResimulateHelper_instances, "m", _ResimulateHelper_start).call(this, transactionMeta);
46
+ }
47
+ else {
48
+ __classPrivateFieldGet(this, _ResimulateHelper_instances, "m", _ResimulateHelper_stop).call(this, transactionMeta);
49
+ }
50
+ });
51
+ // Force stop any running active resimulation that are no longer unapproved transactions list
52
+ __classPrivateFieldGet(this, _ResimulateHelper_activeResimulations, "f").forEach((isActive, transactionId) => {
53
+ if (isActive && !unapprovedTransactionIds.has(transactionId)) {
54
+ __classPrivateFieldGet(this, _ResimulateHelper_instances, "m", _ResimulateHelper_stop).call(this, {
55
+ id: transactionId,
56
+ // Forcing this to false to ensure the resimulation is stopped
57
+ isFocused: false,
58
+ });
59
+ }
60
+ });
61
+ });
62
+ }
63
+ }
64
+ exports.ResimulateHelper = ResimulateHelper;
65
+ _ResimulateHelper_activeResimulations = new WeakMap(), _ResimulateHelper_intervalIds = new WeakMap(), _ResimulateHelper_getTransactions = new WeakMap(), _ResimulateHelper_updateSimulationData = new WeakMap(), _ResimulateHelper_instances = new WeakSet(), _ResimulateHelper_start = function _ResimulateHelper_start(transactionMeta) {
66
+ const { id: transactionId } = transactionMeta;
67
+ const isActive = __classPrivateFieldGet(this, _ResimulateHelper_activeResimulations, "f").get(transactionId);
68
+ if (!transactionMeta.isFocused || isActive) {
69
+ return;
70
+ }
71
+ const listener = async () => {
72
+ try {
73
+ __classPrivateFieldGet(this, _ResimulateHelper_updateSimulationData, "f").call(this, transactionMeta);
74
+ }
75
+ catch (error) {
76
+ /* istanbul ignore next */
77
+ log('Error during transaction resimulation', error);
78
+ }
79
+ };
80
+ const intervalId = setInterval(listener, exports.RESIMULATE_INTERVAL_MS);
81
+ __classPrivateFieldGet(this, _ResimulateHelper_intervalIds, "f").set(transactionId, intervalId);
82
+ __classPrivateFieldGet(this, _ResimulateHelper_activeResimulations, "f").set(transactionId, true);
83
+ log(`Started resimulating transaction ${transactionId} every 3 seconds`);
84
+ }, _ResimulateHelper_stop = function _ResimulateHelper_stop(transactionMeta) {
85
+ const { id: transactionId } = transactionMeta;
86
+ const isActive = __classPrivateFieldGet(this, _ResimulateHelper_activeResimulations, "f").get(transactionId);
87
+ if (transactionMeta.isFocused || !isActive) {
88
+ return;
89
+ }
90
+ __classPrivateFieldGet(this, _ResimulateHelper_instances, "m", _ResimulateHelper_removeListener).call(this, transactionId);
91
+ log(`Stopped resimulating transaction ${transactionId} every 3 seconds`);
92
+ }, _ResimulateHelper_removeListener = function _ResimulateHelper_removeListener(id) {
93
+ const intervalId = __classPrivateFieldGet(this, _ResimulateHelper_intervalIds, "f").get(id);
94
+ if (intervalId) {
95
+ clearInterval(intervalId);
96
+ __classPrivateFieldGet(this, _ResimulateHelper_intervalIds, "f").delete(id);
97
+ }
98
+ __classPrivateFieldGet(this, _ResimulateHelper_activeResimulations, "f").delete(id);
99
+ }, _ResimulateHelper_getUnapprovedTransactions = function _ResimulateHelper_getUnapprovedTransactions() {
100
+ return __classPrivateFieldGet(this, _ResimulateHelper_getTransactions, "f").call(this).filter((tx) => tx.status === types_1.TransactionStatus.unapproved);
101
+ };
14
102
  /**
15
103
  * Determine if a transaction should be resimulated.
104
+ *
16
105
  * @param originalTransactionMeta - The original transaction metadata.
17
106
  * @param newTransactionMeta - The new transaction metadata.
18
107
  * @returns Whether the transaction should be resimulated.
@@ -45,6 +134,7 @@ function shouldResimulate(originalTransactionMeta, newTransactionMeta) {
45
134
  exports.shouldResimulate = shouldResimulate;
46
135
  /**
47
136
  * Determine if the simulation data has changed.
137
+ *
48
138
  * @param originalSimulationData - The original simulation data.
49
139
  * @param newSimulationData - The new simulation data.
50
140
  * @returns Whether the simulation data has changed.
@@ -84,6 +174,7 @@ function hasSimulationDataChanged(originalSimulationData, newSimulationData) {
84
174
  exports.hasSimulationDataChanged = hasSimulationDataChanged;
85
175
  /**
86
176
  * Determine if the transaction parameters have been updated.
177
+ *
87
178
  * @param originalTransactionMeta - The original transaction metadata.
88
179
  * @param newTransactionMeta - The new transaction metadata.
89
180
  * @returns Whether the transaction parameters have been updated.
@@ -106,6 +197,7 @@ function isParametersUpdated(originalTransactionMeta, newTransactionMeta) {
106
197
  }
107
198
  /**
108
199
  * Determine if a transaction has a new security alert.
200
+ *
109
201
  * @param originalTransactionMeta - The original transaction metadata.
110
202
  * @param newTransactionMeta - The new transaction metadata.
111
203
  * @returns Whether the transaction has a new security alert.
@@ -125,6 +217,7 @@ function hasNewSecurityAlert(originalTransactionMeta, newTransactionMeta) {
125
217
  }
126
218
  /**
127
219
  * Determine if a transaction has a value and simulation native balance mismatch.
220
+ *
128
221
  * @param originalTransactionMeta - The original transaction metadata.
129
222
  * @param newTransactionMeta - The new transaction metadata.
130
223
  * @returns Whether the transaction has a value and simulation native balance mismatch.
@@ -142,6 +235,7 @@ function hasValueAndNativeBalanceMismatch(originalTransactionMeta, newTransactio
142
235
  }
143
236
  /**
144
237
  * Determine if a balance change has been updated.
238
+ *
145
239
  * @param originalBalanceChange - The original balance change.
146
240
  * @param newBalanceChange - The new balance change.
147
241
  * @returns Whether the balance change has been updated.
@@ -151,6 +245,7 @@ function isBalanceChangeUpdated(originalBalanceChange, newBalanceChange) {
151
245
  }
152
246
  /**
153
247
  * Determine if the percentage change between two values is within a threshold.
248
+ *
154
249
  * @param originalValue - The original value.
155
250
  * @param newValue - The new value.
156
251
  * @param originalNegative - Whether the original value is negative.
@@ -169,4 +264,4 @@ function percentageChangeWithinThreshold(originalValue, newValue, originalNegati
169
264
  return ((0, utils_2.getPercentageChange)(originalValueBN, newValueBN) <=
170
265
  exports.VALUE_COMPARISON_PERCENT_THRESHOLD);
171
266
  }
172
- //# sourceMappingURL=resimulate.cjs.map
267
+ //# sourceMappingURL=ResimulateHelper.cjs.map
@@ -0,0 +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 onStateChange: (listener: () => void) => void;\n updateSimulationData: (transactionMeta: TransactionMeta) => void;\n};\n\nexport class ResimulateHelper {\n // Map of transactionId <=> isActive\n readonly #activeResimulations: Map<string, boolean> = new Map();\n\n // Map of transactionId <=> intervalId\n readonly #intervalIds: Map<string, NodeJS.Timeout> = new Map();\n\n readonly #getTransactions: () => TransactionMeta[];\n\n readonly #updateSimulationData: (transactionMeta: TransactionMeta) => void;\n\n constructor({\n getTransactions,\n updateSimulationData,\n onStateChange,\n }: ResimulateHelperOptions) {\n this.#getTransactions = getTransactions;\n this.#updateSimulationData = updateSimulationData;\n\n onStateChange(() => {\n const unapprovedTransactions = this.#getUnapprovedTransactions();\n const unapprovedTransactionIds = new Set(\n unapprovedTransactions.map((tx) => tx.id),\n );\n\n // Start or stop resimulation based on the current isFocused state\n unapprovedTransactions.forEach((transactionMeta) => {\n if (transactionMeta.isFocused) {\n this.#start(transactionMeta);\n } else {\n this.#stop(transactionMeta);\n }\n });\n\n // Force stop any running active resimulation that are no longer unapproved transactions list\n this.#activeResimulations.forEach((isActive, transactionId) => {\n if (isActive && !unapprovedTransactionIds.has(transactionId)) {\n this.#stop({\n id: transactionId,\n // Forcing this to false to ensure the resimulation is stopped\n isFocused: false,\n } as unknown as TransactionMeta);\n }\n });\n });\n }\n\n #start(transactionMeta: TransactionMeta) {\n const { id: transactionId } = transactionMeta;\n const isActive = this.#activeResimulations.get(transactionId);\n if (!transactionMeta.isFocused || isActive) {\n return;\n }\n\n const listener = async () => {\n try {\n this.#updateSimulationData(transactionMeta);\n } catch (error) {\n /* istanbul ignore next */\n log('Error during transaction resimulation', error);\n }\n };\n\n const intervalId = setInterval(listener, RESIMULATE_INTERVAL_MS);\n\n this.#intervalIds.set(transactionId, intervalId);\n this.#activeResimulations.set(transactionId, true);\n log(`Started resimulating transaction ${transactionId} every 3 seconds`);\n }\n\n #stop(transactionMeta: TransactionMeta) {\n const { id: transactionId } = transactionMeta;\n const isActive = this.#activeResimulations.get(transactionId);\n if (transactionMeta.isFocused || !isActive) {\n return;\n }\n\n this.#removeListener(transactionId);\n log(`Stopped resimulating transaction ${transactionId} every 3 seconds`);\n }\n\n #removeListener(id: string) {\n const intervalId = this.#intervalIds.get(id);\n if (intervalId) {\n clearInterval(intervalId);\n this.#intervalIds.delete(id);\n }\n this.#activeResimulations.delete(id);\n }\n\n #getUnapprovedTransactions() {\n return this.#getTransactions().filter(\n (tx) => tx.status === TransactionStatus.unapproved,\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) {\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"]}
@@ -3,12 +3,23 @@ export declare const RESIMULATE_PARAMS: readonly ["to", "value", "data"];
3
3
  export declare const BLOCKAID_RESULT_TYPE_MALICIOUS = "Malicious";
4
4
  export declare const VALUE_COMPARISON_PERCENT_THRESHOLD = 5;
5
5
  export declare const BLOCK_TIME_ADDITIONAL_SECONDS = 60;
6
+ export declare const RESIMULATE_INTERVAL_MS = 3000;
6
7
  export type ResimulateResponse = {
7
8
  blockTime?: number;
8
9
  resimulate: boolean;
9
10
  };
11
+ export type ResimulateHelperOptions = {
12
+ getTransactions: () => TransactionMeta[];
13
+ onStateChange: (listener: () => void) => void;
14
+ updateSimulationData: (transactionMeta: TransactionMeta) => void;
15
+ };
16
+ export declare class ResimulateHelper {
17
+ #private;
18
+ constructor({ getTransactions, updateSimulationData, onStateChange, }: ResimulateHelperOptions);
19
+ }
10
20
  /**
11
21
  * Determine if a transaction should be resimulated.
22
+ *
12
23
  * @param originalTransactionMeta - The original transaction metadata.
13
24
  * @param newTransactionMeta - The new transaction metadata.
14
25
  * @returns Whether the transaction should be resimulated.
@@ -19,9 +30,10 @@ export declare function shouldResimulate(originalTransactionMeta: TransactionMet
19
30
  };
20
31
  /**
21
32
  * Determine if the simulation data has changed.
33
+ *
22
34
  * @param originalSimulationData - The original simulation data.
23
35
  * @param newSimulationData - The new simulation data.
24
36
  * @returns Whether the simulation data has changed.
25
37
  */
26
38
  export declare function hasSimulationDataChanged(originalSimulationData: SimulationData, newSimulationData: SimulationData): boolean;
27
- //# sourceMappingURL=resimulate.d.cts.map
39
+ //# sourceMappingURL=ResimulateHelper.d.cts.map
@@ -0,0 +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,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IAC9C,oBAAoB,EAAE,CAAC,eAAe,EAAE,eAAe,KAAK,IAAI,CAAC;CAClE,CAAC;AAEF,qBAAa,gBAAgB;;gBAWf,EACV,eAAe,EACf,oBAAoB,EACpB,aAAa,GACd,EAAE,uBAAuB;CAgF3B;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,uBAAuB,EAAE,eAAe,EACxC,kBAAkB,EAAE,eAAe;;;EA2CpC;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,sBAAsB,EAAE,cAAc,EACtC,iBAAiB,EAAE,cAAc,GAChC,OAAO,CAmDT"}
@@ -3,12 +3,23 @@ export declare const RESIMULATE_PARAMS: readonly ["to", "value", "data"];
3
3
  export declare const BLOCKAID_RESULT_TYPE_MALICIOUS = "Malicious";
4
4
  export declare const VALUE_COMPARISON_PERCENT_THRESHOLD = 5;
5
5
  export declare const BLOCK_TIME_ADDITIONAL_SECONDS = 60;
6
+ export declare const RESIMULATE_INTERVAL_MS = 3000;
6
7
  export type ResimulateResponse = {
7
8
  blockTime?: number;
8
9
  resimulate: boolean;
9
10
  };
11
+ export type ResimulateHelperOptions = {
12
+ getTransactions: () => TransactionMeta[];
13
+ onStateChange: (listener: () => void) => void;
14
+ updateSimulationData: (transactionMeta: TransactionMeta) => void;
15
+ };
16
+ export declare class ResimulateHelper {
17
+ #private;
18
+ constructor({ getTransactions, updateSimulationData, onStateChange, }: ResimulateHelperOptions);
19
+ }
10
20
  /**
11
21
  * Determine if a transaction should be resimulated.
22
+ *
12
23
  * @param originalTransactionMeta - The original transaction metadata.
13
24
  * @param newTransactionMeta - The new transaction metadata.
14
25
  * @returns Whether the transaction should be resimulated.
@@ -19,9 +30,10 @@ export declare function shouldResimulate(originalTransactionMeta: TransactionMet
19
30
  };
20
31
  /**
21
32
  * Determine if the simulation data has changed.
33
+ *
22
34
  * @param originalSimulationData - The original simulation data.
23
35
  * @param newSimulationData - The new simulation data.
24
36
  * @returns Whether the simulation data has changed.
25
37
  */
26
38
  export declare function hasSimulationDataChanged(originalSimulationData: SimulationData, newSimulationData: SimulationData): boolean;
27
- //# sourceMappingURL=resimulate.d.mts.map
39
+ //# sourceMappingURL=ResimulateHelper.d.mts.map
@@ -0,0 +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,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IAC9C,oBAAoB,EAAE,CAAC,eAAe,EAAE,eAAe,KAAK,IAAI,CAAC;CAClE,CAAC;AAEF,qBAAa,gBAAgB;;gBAWf,EACV,eAAe,EACf,oBAAoB,EACpB,aAAa,GACd,EAAE,uBAAuB;CAgF3B;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,uBAAuB,EAAE,eAAe,EACxC,kBAAkB,EAAE,eAAe;;;EA2CpC;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,sBAAsB,EAAE,cAAc,EACtC,iBAAiB,EAAE,cAAc,GAChC,OAAO,CAmDT"}