@metamask-previews/transaction-controller 39.0.0-preview-e23a91fa → 39.0.0-preview-913113cf

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 (64) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/TransactionController.cjs +104 -219
  3. package/dist/TransactionController.cjs.map +1 -1
  4. package/dist/TransactionController.d.cts +34 -52
  5. package/dist/TransactionController.d.cts.map +1 -1
  6. package/dist/TransactionController.d.mts +34 -52
  7. package/dist/TransactionController.d.mts.map +1 -1
  8. package/dist/TransactionController.mjs +105 -220
  9. package/dist/TransactionController.mjs.map +1 -1
  10. package/dist/helpers/EtherscanRemoteTransactionSource.cjs +1 -0
  11. package/dist/helpers/EtherscanRemoteTransactionSource.cjs.map +1 -1
  12. package/dist/helpers/EtherscanRemoteTransactionSource.d.cts.map +1 -1
  13. package/dist/helpers/EtherscanRemoteTransactionSource.d.mts.map +1 -1
  14. package/dist/helpers/EtherscanRemoteTransactionSource.mjs +1 -0
  15. package/dist/helpers/EtherscanRemoteTransactionSource.mjs.map +1 -1
  16. package/dist/helpers/GasFeePoller.cjs +4 -4
  17. package/dist/helpers/GasFeePoller.cjs.map +1 -1
  18. package/dist/helpers/GasFeePoller.d.cts +1 -1
  19. package/dist/helpers/GasFeePoller.d.cts.map +1 -1
  20. package/dist/helpers/GasFeePoller.d.mts +1 -1
  21. package/dist/helpers/GasFeePoller.d.mts.map +1 -1
  22. package/dist/helpers/GasFeePoller.mjs +4 -4
  23. package/dist/helpers/GasFeePoller.mjs.map +1 -1
  24. package/dist/helpers/IncomingTransactionHelper.cjs +12 -5
  25. package/dist/helpers/IncomingTransactionHelper.cjs.map +1 -1
  26. package/dist/helpers/IncomingTransactionHelper.d.cts.map +1 -1
  27. package/dist/helpers/IncomingTransactionHelper.d.mts.map +1 -1
  28. package/dist/helpers/IncomingTransactionHelper.mjs +13 -6
  29. package/dist/helpers/IncomingTransactionHelper.mjs.map +1 -1
  30. package/dist/helpers/MethodDataHelper.cjs +78 -0
  31. package/dist/helpers/MethodDataHelper.cjs.map +1 -0
  32. package/dist/helpers/MethodDataHelper.d.cts +14 -0
  33. package/dist/helpers/MethodDataHelper.d.cts.map +1 -0
  34. package/dist/helpers/MethodDataHelper.d.mts +14 -0
  35. package/dist/helpers/MethodDataHelper.d.mts.map +1 -0
  36. package/dist/helpers/MethodDataHelper.mjs +71 -0
  37. package/dist/helpers/MethodDataHelper.mjs.map +1 -0
  38. package/dist/helpers/MultichainTrackingHelper.cjs +87 -104
  39. package/dist/helpers/MultichainTrackingHelper.cjs.map +1 -1
  40. package/dist/helpers/MultichainTrackingHelper.d.cts +16 -22
  41. package/dist/helpers/MultichainTrackingHelper.d.cts.map +1 -1
  42. package/dist/helpers/MultichainTrackingHelper.d.mts +16 -22
  43. package/dist/helpers/MultichainTrackingHelper.d.mts.map +1 -1
  44. package/dist/helpers/MultichainTrackingHelper.mjs +88 -109
  45. package/dist/helpers/MultichainTrackingHelper.mjs.map +1 -1
  46. package/dist/helpers/PendingTransactionTracker.cjs +24 -22
  47. package/dist/helpers/PendingTransactionTracker.cjs.map +1 -1
  48. package/dist/helpers/PendingTransactionTracker.d.cts.map +1 -1
  49. package/dist/helpers/PendingTransactionTracker.d.mts.map +1 -1
  50. package/dist/helpers/PendingTransactionTracker.mjs +24 -22
  51. package/dist/helpers/PendingTransactionTracker.mjs.map +1 -1
  52. package/dist/types.cjs.map +1 -1
  53. package/dist/types.d.cts +1 -1
  54. package/dist/types.d.cts.map +1 -1
  55. package/dist/types.d.mts +1 -1
  56. package/dist/types.d.mts.map +1 -1
  57. package/dist/types.mjs.map +1 -1
  58. package/dist/utils/etherscan.cjs +2 -1
  59. package/dist/utils/etherscan.cjs.map +1 -1
  60. package/dist/utils/etherscan.d.cts.map +1 -1
  61. package/dist/utils/etherscan.d.mts.map +1 -1
  62. package/dist/utils/etherscan.mjs +3 -2
  63. package/dist/utils/etherscan.mjs.map +1 -1
  64. package/package.json +1 -1
@@ -138,6 +138,7 @@ _EtherscanRemoteTransactionSource_apiKeysByChainId = new WeakMap(), _EtherscanRe
138
138
  chainId: currentChainId,
139
139
  hash: txMeta.hash,
140
140
  id: (0, uuid_1.v1)({ msecs: time }),
141
+ networkClientId: 'incoming',
141
142
  status: types_1.TransactionStatus.confirmed,
142
143
  time,
143
144
  txParams: {
@@ -1 +1 @@
1
- {"version":3,"file":"EtherscanRemoteTransactionSource.cjs","sourceRoot":"","sources":["../../src/helpers/EtherscanRemoteTransactionSource.ts"],"names":[],"mappings":"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","sourcesContent":["import { BNToHex } from '@metamask/controller-utils';\nimport type { Hex } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\nimport BN from 'bn.js';\nimport { v1 as random } from 'uuid';\n\nimport { ETHERSCAN_SUPPORTED_NETWORKS } from '../constants';\nimport { incomingTransactionsLogger as log } from '../logger';\nimport type {\n RemoteTransactionSource,\n RemoteTransactionSourceRequest,\n TransactionMeta,\n} from '../types';\nimport { TransactionStatus, TransactionType } from '../types';\nimport {\n fetchEtherscanTokenTransactions,\n fetchEtherscanTransactions,\n} from '../utils/etherscan';\nimport type {\n EtherscanTokenTransactionMeta,\n EtherscanTransactionMeta,\n EtherscanTransactionMetaBase,\n EtherscanTransactionRequest,\n EtherscanTransactionResponse,\n} from '../utils/etherscan';\n\nconst ETHERSCAN_RATE_LIMIT_INTERVAL = 5000;\n\n/**\n * A RemoteTransactionSource that fetches transaction data from Etherscan.\n */\nexport class EtherscanRemoteTransactionSource\n implements RemoteTransactionSource\n{\n #apiKeysByChainId?: Record<Hex, string>;\n\n #includeTokenTransfers: boolean;\n\n #isTokenRequestPending: boolean;\n\n #mutex = new Mutex();\n\n constructor({\n apiKeysByChainId,\n includeTokenTransfers,\n }: {\n apiKeysByChainId?: Record<Hex, string>;\n includeTokenTransfers?: boolean;\n } = {}) {\n this.#apiKeysByChainId = apiKeysByChainId;\n this.#includeTokenTransfers = includeTokenTransfers ?? true;\n this.#isTokenRequestPending = false;\n }\n\n isSupportedNetwork(chainId: Hex): boolean {\n return Object.keys(ETHERSCAN_SUPPORTED_NETWORKS).includes(chainId);\n }\n\n getLastBlockVariations(): string[] {\n return [this.#isTokenRequestPending ? 'token' : 'normal'];\n }\n\n async fetchTransactions(\n request: RemoteTransactionSourceRequest,\n ): Promise<TransactionMeta[]> {\n const releaseLock = await this.#mutex.acquire();\n const acquiredTime = Date.now();\n const { currentChainId: chainId } = request;\n const apiKey = this.#apiKeysByChainId?.[chainId];\n\n if (apiKey) {\n log('Etherscan API key found for chain', chainId);\n }\n\n const etherscanRequest: EtherscanTransactionRequest = {\n ...request,\n apiKey,\n chainId,\n };\n\n try {\n const transactions = this.#isTokenRequestPending\n ? await this.#fetchTokenTransactions(request, etherscanRequest)\n : await this.#fetchNormalTransactions(request, etherscanRequest);\n\n if (this.#includeTokenTransfers) {\n this.#isTokenRequestPending = !this.#isTokenRequestPending;\n }\n\n return transactions;\n } finally {\n this.#releaseLockAfterInterval(acquiredTime, releaseLock);\n }\n }\n\n #releaseLockAfterInterval(acquireTime: number, releaseLock: () => void) {\n const elapsedTime = Date.now() - acquireTime;\n const remainingTime = Math.max(\n 0,\n ETHERSCAN_RATE_LIMIT_INTERVAL - elapsedTime,\n );\n // Wait for the remaining time if it hasn't been 5 seconds yet\n if (remainingTime > 0) {\n setTimeout(releaseLock, remainingTime);\n } else {\n releaseLock();\n }\n }\n\n #fetchNormalTransactions = async (\n request: RemoteTransactionSourceRequest,\n etherscanRequest: EtherscanTransactionRequest,\n ) => {\n const { currentChainId } = request;\n\n const etherscanTransactions = await fetchEtherscanTransactions(\n etherscanRequest,\n );\n\n return this.#getResponseTransactions(etherscanTransactions).map((tx) =>\n this.#normalizeTransaction(tx, currentChainId),\n );\n };\n\n #fetchTokenTransactions = async (\n request: RemoteTransactionSourceRequest,\n etherscanRequest: EtherscanTransactionRequest,\n ) => {\n const { currentChainId } = request;\n\n const etherscanTransactions = await fetchEtherscanTokenTransactions(\n etherscanRequest,\n );\n\n return this.#getResponseTransactions(etherscanTransactions).map((tx) =>\n this.#normalizeTokenTransaction(tx, currentChainId),\n );\n };\n\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n #getResponseTransactions<T extends EtherscanTransactionMetaBase>(\n response: EtherscanTransactionResponse<T>,\n ): T[] {\n let result = response.result as T[];\n\n if (response.status === '0') {\n result = [];\n\n if (response.result.length) {\n log('Ignored Etherscan request error', {\n message: response.result,\n type: this.#isTokenRequestPending ? 'token' : 'normal',\n });\n }\n }\n\n return result;\n }\n\n #normalizeTransaction(\n txMeta: EtherscanTransactionMeta,\n currentChainId: Hex,\n ): TransactionMeta {\n const base = this.#normalizeTransactionBase(txMeta, currentChainId);\n\n return {\n ...base,\n txParams: {\n ...base.txParams,\n data: txMeta.input,\n },\n ...(txMeta.isError === '0'\n ? { status: TransactionStatus.confirmed }\n : {\n error: new Error('Transaction failed'),\n status: TransactionStatus.failed,\n }),\n };\n }\n\n #normalizeTokenTransaction(\n txMeta: EtherscanTokenTransactionMeta,\n currentChainId: Hex,\n ): TransactionMeta {\n const base = this.#normalizeTransactionBase(txMeta, currentChainId);\n\n return {\n ...base,\n isTransfer: true,\n transferInformation: {\n contractAddress: txMeta.contractAddress,\n decimals: Number(txMeta.tokenDecimal),\n symbol: txMeta.tokenSymbol,\n },\n };\n }\n\n #normalizeTransactionBase(\n txMeta: EtherscanTransactionMetaBase,\n currentChainId: Hex,\n ): TransactionMeta {\n const time = parseInt(txMeta.timeStamp, 10) * 1000;\n\n return {\n blockNumber: txMeta.blockNumber,\n chainId: currentChainId,\n hash: txMeta.hash,\n id: random({ msecs: time }),\n status: TransactionStatus.confirmed,\n time,\n txParams: {\n chainId: currentChainId,\n from: txMeta.from,\n gas: BNToHex(new BN(txMeta.gas)),\n gasPrice: BNToHex(new BN(txMeta.gasPrice)),\n gasUsed: BNToHex(new BN(txMeta.gasUsed)),\n nonce: BNToHex(new BN(txMeta.nonce)),\n to: txMeta.to,\n value: BNToHex(new BN(txMeta.value)),\n },\n type: TransactionType.incoming,\n verifiedOnBlockchain: false,\n };\n }\n}\n"]}
1
+ {"version":3,"file":"EtherscanRemoteTransactionSource.cjs","sourceRoot":"","sources":["../../src/helpers/EtherscanRemoteTransactionSource.ts"],"names":[],"mappings":"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","sourcesContent":["import { BNToHex } from '@metamask/controller-utils';\nimport type { Hex } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\nimport BN from 'bn.js';\nimport { v1 as random } from 'uuid';\n\nimport { ETHERSCAN_SUPPORTED_NETWORKS } from '../constants';\nimport { incomingTransactionsLogger as log } from '../logger';\nimport type {\n RemoteTransactionSource,\n RemoteTransactionSourceRequest,\n TransactionMeta,\n} from '../types';\nimport { TransactionStatus, TransactionType } from '../types';\nimport {\n fetchEtherscanTokenTransactions,\n fetchEtherscanTransactions,\n} from '../utils/etherscan';\nimport type {\n EtherscanTokenTransactionMeta,\n EtherscanTransactionMeta,\n EtherscanTransactionMetaBase,\n EtherscanTransactionRequest,\n EtherscanTransactionResponse,\n} from '../utils/etherscan';\n\nconst ETHERSCAN_RATE_LIMIT_INTERVAL = 5000;\n\n/**\n * A RemoteTransactionSource that fetches transaction data from Etherscan.\n */\nexport class EtherscanRemoteTransactionSource\n implements RemoteTransactionSource\n{\n #apiKeysByChainId?: Record<Hex, string>;\n\n #includeTokenTransfers: boolean;\n\n #isTokenRequestPending: boolean;\n\n #mutex = new Mutex();\n\n constructor({\n apiKeysByChainId,\n includeTokenTransfers,\n }: {\n apiKeysByChainId?: Record<Hex, string>;\n includeTokenTransfers?: boolean;\n } = {}) {\n this.#apiKeysByChainId = apiKeysByChainId;\n this.#includeTokenTransfers = includeTokenTransfers ?? true;\n this.#isTokenRequestPending = false;\n }\n\n isSupportedNetwork(chainId: Hex): boolean {\n return Object.keys(ETHERSCAN_SUPPORTED_NETWORKS).includes(chainId);\n }\n\n getLastBlockVariations(): string[] {\n return [this.#isTokenRequestPending ? 'token' : 'normal'];\n }\n\n async fetchTransactions(\n request: RemoteTransactionSourceRequest,\n ): Promise<TransactionMeta[]> {\n const releaseLock = await this.#mutex.acquire();\n const acquiredTime = Date.now();\n const { currentChainId: chainId } = request;\n const apiKey = this.#apiKeysByChainId?.[chainId];\n\n if (apiKey) {\n log('Etherscan API key found for chain', chainId);\n }\n\n const etherscanRequest: EtherscanTransactionRequest = {\n ...request,\n apiKey,\n chainId,\n };\n\n try {\n const transactions = this.#isTokenRequestPending\n ? await this.#fetchTokenTransactions(request, etherscanRequest)\n : await this.#fetchNormalTransactions(request, etherscanRequest);\n\n if (this.#includeTokenTransfers) {\n this.#isTokenRequestPending = !this.#isTokenRequestPending;\n }\n\n return transactions;\n } finally {\n this.#releaseLockAfterInterval(acquiredTime, releaseLock);\n }\n }\n\n #releaseLockAfterInterval(acquireTime: number, releaseLock: () => void) {\n const elapsedTime = Date.now() - acquireTime;\n const remainingTime = Math.max(\n 0,\n ETHERSCAN_RATE_LIMIT_INTERVAL - elapsedTime,\n );\n // Wait for the remaining time if it hasn't been 5 seconds yet\n if (remainingTime > 0) {\n setTimeout(releaseLock, remainingTime);\n } else {\n releaseLock();\n }\n }\n\n #fetchNormalTransactions = async (\n request: RemoteTransactionSourceRequest,\n etherscanRequest: EtherscanTransactionRequest,\n ) => {\n const { currentChainId } = request;\n\n const etherscanTransactions = await fetchEtherscanTransactions(\n etherscanRequest,\n );\n\n return this.#getResponseTransactions(etherscanTransactions).map((tx) =>\n this.#normalizeTransaction(tx, currentChainId),\n );\n };\n\n #fetchTokenTransactions = async (\n request: RemoteTransactionSourceRequest,\n etherscanRequest: EtherscanTransactionRequest,\n ) => {\n const { currentChainId } = request;\n\n const etherscanTransactions = await fetchEtherscanTokenTransactions(\n etherscanRequest,\n );\n\n return this.#getResponseTransactions(etherscanTransactions).map((tx) =>\n this.#normalizeTokenTransaction(tx, currentChainId),\n );\n };\n\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n #getResponseTransactions<T extends EtherscanTransactionMetaBase>(\n response: EtherscanTransactionResponse<T>,\n ): T[] {\n let result = response.result as T[];\n\n if (response.status === '0') {\n result = [];\n\n if (response.result.length) {\n log('Ignored Etherscan request error', {\n message: response.result,\n type: this.#isTokenRequestPending ? 'token' : 'normal',\n });\n }\n }\n\n return result;\n }\n\n #normalizeTransaction(\n txMeta: EtherscanTransactionMeta,\n currentChainId: Hex,\n ): TransactionMeta {\n const base = this.#normalizeTransactionBase(txMeta, currentChainId);\n\n return {\n ...base,\n txParams: {\n ...base.txParams,\n data: txMeta.input,\n },\n ...(txMeta.isError === '0'\n ? { status: TransactionStatus.confirmed }\n : {\n error: new Error('Transaction failed'),\n status: TransactionStatus.failed,\n }),\n };\n }\n\n #normalizeTokenTransaction(\n txMeta: EtherscanTokenTransactionMeta,\n currentChainId: Hex,\n ): TransactionMeta {\n const base = this.#normalizeTransactionBase(txMeta, currentChainId);\n\n return {\n ...base,\n isTransfer: true,\n transferInformation: {\n contractAddress: txMeta.contractAddress,\n decimals: Number(txMeta.tokenDecimal),\n symbol: txMeta.tokenSymbol,\n },\n };\n }\n\n #normalizeTransactionBase(\n txMeta: EtherscanTransactionMetaBase,\n currentChainId: Hex,\n ): TransactionMeta {\n const time = parseInt(txMeta.timeStamp, 10) * 1000;\n\n return {\n blockNumber: txMeta.blockNumber,\n chainId: currentChainId,\n hash: txMeta.hash,\n id: random({ msecs: time }),\n networkClientId: 'incoming',\n status: TransactionStatus.confirmed,\n time,\n txParams: {\n chainId: currentChainId,\n from: txMeta.from,\n gas: BNToHex(new BN(txMeta.gas)),\n gasPrice: BNToHex(new BN(txMeta.gasPrice)),\n gasUsed: BNToHex(new BN(txMeta.gasUsed)),\n nonce: BNToHex(new BN(txMeta.nonce)),\n to: txMeta.to,\n value: BNToHex(new BN(txMeta.value)),\n },\n type: TransactionType.incoming,\n verifiedOnBlockchain: false,\n };\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"EtherscanRemoteTransactionSource.d.cts","sourceRoot":"","sources":["../../src/helpers/EtherscanRemoteTransactionSource.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAO3C,OAAO,KAAK,EACV,uBAAuB,EACvB,8BAA8B,EAC9B,eAAe,EAChB,qBAAiB;AAgBlB;;GAEG;AACH,qBAAa,gCACX,YAAW,uBAAuB;;gBAUtB,EACV,gBAAgB,EAChB,qBAAqB,GACtB,GAAE;QACD,gBAAgB,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACvC,qBAAqB,CAAC,EAAE,OAAO,CAAC;KAC5B;IAMN,kBAAkB,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO;IAIzC,sBAAsB,IAAI,MAAM,EAAE;IAI5B,iBAAiB,CACrB,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,eAAe,EAAE,CAAC;CAiK9B"}
1
+ {"version":3,"file":"EtherscanRemoteTransactionSource.d.cts","sourceRoot":"","sources":["../../src/helpers/EtherscanRemoteTransactionSource.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAO3C,OAAO,KAAK,EACV,uBAAuB,EACvB,8BAA8B,EAC9B,eAAe,EAChB,qBAAiB;AAgBlB;;GAEG;AACH,qBAAa,gCACX,YAAW,uBAAuB;;gBAUtB,EACV,gBAAgB,EAChB,qBAAqB,GACtB,GAAE;QACD,gBAAgB,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACvC,qBAAqB,CAAC,EAAE,OAAO,CAAC;KAC5B;IAMN,kBAAkB,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO;IAIzC,sBAAsB,IAAI,MAAM,EAAE;IAI5B,iBAAiB,CACrB,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,eAAe,EAAE,CAAC;CAkK9B"}
@@ -1 +1 @@
1
- {"version":3,"file":"EtherscanRemoteTransactionSource.d.mts","sourceRoot":"","sources":["../../src/helpers/EtherscanRemoteTransactionSource.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAO3C,OAAO,KAAK,EACV,uBAAuB,EACvB,8BAA8B,EAC9B,eAAe,EAChB,qBAAiB;AAgBlB;;GAEG;AACH,qBAAa,gCACX,YAAW,uBAAuB;;gBAUtB,EACV,gBAAgB,EAChB,qBAAqB,GACtB,GAAE;QACD,gBAAgB,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACvC,qBAAqB,CAAC,EAAE,OAAO,CAAC;KAC5B;IAMN,kBAAkB,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO;IAIzC,sBAAsB,IAAI,MAAM,EAAE;IAI5B,iBAAiB,CACrB,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,eAAe,EAAE,CAAC;CAiK9B"}
1
+ {"version":3,"file":"EtherscanRemoteTransactionSource.d.mts","sourceRoot":"","sources":["../../src/helpers/EtherscanRemoteTransactionSource.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAO3C,OAAO,KAAK,EACV,uBAAuB,EACvB,8BAA8B,EAC9B,eAAe,EAChB,qBAAiB;AAgBlB;;GAEG;AACH,qBAAa,gCACX,YAAW,uBAAuB;;gBAUtB,EACV,gBAAgB,EAChB,qBAAqB,GACtB,GAAE;QACD,gBAAgB,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACvC,qBAAqB,CAAC,EAAE,OAAO,CAAC;KAC5B;IAMN,kBAAkB,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO;IAIzC,sBAAsB,IAAI,MAAM,EAAE;IAI5B,iBAAiB,CACrB,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,eAAe,EAAE,CAAC;CAkK9B"}
@@ -138,6 +138,7 @@ _EtherscanRemoteTransactionSource_apiKeysByChainId = new WeakMap(), _EtherscanRe
138
138
  chainId: currentChainId,
139
139
  hash: txMeta.hash,
140
140
  id: random({ msecs: time }),
141
+ networkClientId: 'incoming',
141
142
  status: TransactionStatus.confirmed,
142
143
  time,
143
144
  txParams: {
@@ -1 +1 @@
1
- {"version":3,"file":"EtherscanRemoteTransactionSource.mjs","sourceRoot":"","sources":["../../src/helpers/EtherscanRemoteTransactionSource.ts"],"names":[],"mappings":"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","sourcesContent":["import { BNToHex } from '@metamask/controller-utils';\nimport type { Hex } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\nimport BN from 'bn.js';\nimport { v1 as random } from 'uuid';\n\nimport { ETHERSCAN_SUPPORTED_NETWORKS } from '../constants';\nimport { incomingTransactionsLogger as log } from '../logger';\nimport type {\n RemoteTransactionSource,\n RemoteTransactionSourceRequest,\n TransactionMeta,\n} from '../types';\nimport { TransactionStatus, TransactionType } from '../types';\nimport {\n fetchEtherscanTokenTransactions,\n fetchEtherscanTransactions,\n} from '../utils/etherscan';\nimport type {\n EtherscanTokenTransactionMeta,\n EtherscanTransactionMeta,\n EtherscanTransactionMetaBase,\n EtherscanTransactionRequest,\n EtherscanTransactionResponse,\n} from '../utils/etherscan';\n\nconst ETHERSCAN_RATE_LIMIT_INTERVAL = 5000;\n\n/**\n * A RemoteTransactionSource that fetches transaction data from Etherscan.\n */\nexport class EtherscanRemoteTransactionSource\n implements RemoteTransactionSource\n{\n #apiKeysByChainId?: Record<Hex, string>;\n\n #includeTokenTransfers: boolean;\n\n #isTokenRequestPending: boolean;\n\n #mutex = new Mutex();\n\n constructor({\n apiKeysByChainId,\n includeTokenTransfers,\n }: {\n apiKeysByChainId?: Record<Hex, string>;\n includeTokenTransfers?: boolean;\n } = {}) {\n this.#apiKeysByChainId = apiKeysByChainId;\n this.#includeTokenTransfers = includeTokenTransfers ?? true;\n this.#isTokenRequestPending = false;\n }\n\n isSupportedNetwork(chainId: Hex): boolean {\n return Object.keys(ETHERSCAN_SUPPORTED_NETWORKS).includes(chainId);\n }\n\n getLastBlockVariations(): string[] {\n return [this.#isTokenRequestPending ? 'token' : 'normal'];\n }\n\n async fetchTransactions(\n request: RemoteTransactionSourceRequest,\n ): Promise<TransactionMeta[]> {\n const releaseLock = await this.#mutex.acquire();\n const acquiredTime = Date.now();\n const { currentChainId: chainId } = request;\n const apiKey = this.#apiKeysByChainId?.[chainId];\n\n if (apiKey) {\n log('Etherscan API key found for chain', chainId);\n }\n\n const etherscanRequest: EtherscanTransactionRequest = {\n ...request,\n apiKey,\n chainId,\n };\n\n try {\n const transactions = this.#isTokenRequestPending\n ? await this.#fetchTokenTransactions(request, etherscanRequest)\n : await this.#fetchNormalTransactions(request, etherscanRequest);\n\n if (this.#includeTokenTransfers) {\n this.#isTokenRequestPending = !this.#isTokenRequestPending;\n }\n\n return transactions;\n } finally {\n this.#releaseLockAfterInterval(acquiredTime, releaseLock);\n }\n }\n\n #releaseLockAfterInterval(acquireTime: number, releaseLock: () => void) {\n const elapsedTime = Date.now() - acquireTime;\n const remainingTime = Math.max(\n 0,\n ETHERSCAN_RATE_LIMIT_INTERVAL - elapsedTime,\n );\n // Wait for the remaining time if it hasn't been 5 seconds yet\n if (remainingTime > 0) {\n setTimeout(releaseLock, remainingTime);\n } else {\n releaseLock();\n }\n }\n\n #fetchNormalTransactions = async (\n request: RemoteTransactionSourceRequest,\n etherscanRequest: EtherscanTransactionRequest,\n ) => {\n const { currentChainId } = request;\n\n const etherscanTransactions = await fetchEtherscanTransactions(\n etherscanRequest,\n );\n\n return this.#getResponseTransactions(etherscanTransactions).map((tx) =>\n this.#normalizeTransaction(tx, currentChainId),\n );\n };\n\n #fetchTokenTransactions = async (\n request: RemoteTransactionSourceRequest,\n etherscanRequest: EtherscanTransactionRequest,\n ) => {\n const { currentChainId } = request;\n\n const etherscanTransactions = await fetchEtherscanTokenTransactions(\n etherscanRequest,\n );\n\n return this.#getResponseTransactions(etherscanTransactions).map((tx) =>\n this.#normalizeTokenTransaction(tx, currentChainId),\n );\n };\n\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n #getResponseTransactions<T extends EtherscanTransactionMetaBase>(\n response: EtherscanTransactionResponse<T>,\n ): T[] {\n let result = response.result as T[];\n\n if (response.status === '0') {\n result = [];\n\n if (response.result.length) {\n log('Ignored Etherscan request error', {\n message: response.result,\n type: this.#isTokenRequestPending ? 'token' : 'normal',\n });\n }\n }\n\n return result;\n }\n\n #normalizeTransaction(\n txMeta: EtherscanTransactionMeta,\n currentChainId: Hex,\n ): TransactionMeta {\n const base = this.#normalizeTransactionBase(txMeta, currentChainId);\n\n return {\n ...base,\n txParams: {\n ...base.txParams,\n data: txMeta.input,\n },\n ...(txMeta.isError === '0'\n ? { status: TransactionStatus.confirmed }\n : {\n error: new Error('Transaction failed'),\n status: TransactionStatus.failed,\n }),\n };\n }\n\n #normalizeTokenTransaction(\n txMeta: EtherscanTokenTransactionMeta,\n currentChainId: Hex,\n ): TransactionMeta {\n const base = this.#normalizeTransactionBase(txMeta, currentChainId);\n\n return {\n ...base,\n isTransfer: true,\n transferInformation: {\n contractAddress: txMeta.contractAddress,\n decimals: Number(txMeta.tokenDecimal),\n symbol: txMeta.tokenSymbol,\n },\n };\n }\n\n #normalizeTransactionBase(\n txMeta: EtherscanTransactionMetaBase,\n currentChainId: Hex,\n ): TransactionMeta {\n const time = parseInt(txMeta.timeStamp, 10) * 1000;\n\n return {\n blockNumber: txMeta.blockNumber,\n chainId: currentChainId,\n hash: txMeta.hash,\n id: random({ msecs: time }),\n status: TransactionStatus.confirmed,\n time,\n txParams: {\n chainId: currentChainId,\n from: txMeta.from,\n gas: BNToHex(new BN(txMeta.gas)),\n gasPrice: BNToHex(new BN(txMeta.gasPrice)),\n gasUsed: BNToHex(new BN(txMeta.gasUsed)),\n nonce: BNToHex(new BN(txMeta.nonce)),\n to: txMeta.to,\n value: BNToHex(new BN(txMeta.value)),\n },\n type: TransactionType.incoming,\n verifiedOnBlockchain: false,\n };\n }\n}\n"]}
1
+ {"version":3,"file":"EtherscanRemoteTransactionSource.mjs","sourceRoot":"","sources":["../../src/helpers/EtherscanRemoteTransactionSource.ts"],"names":[],"mappings":"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","sourcesContent":["import { BNToHex } from '@metamask/controller-utils';\nimport type { Hex } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\nimport BN from 'bn.js';\nimport { v1 as random } from 'uuid';\n\nimport { ETHERSCAN_SUPPORTED_NETWORKS } from '../constants';\nimport { incomingTransactionsLogger as log } from '../logger';\nimport type {\n RemoteTransactionSource,\n RemoteTransactionSourceRequest,\n TransactionMeta,\n} from '../types';\nimport { TransactionStatus, TransactionType } from '../types';\nimport {\n fetchEtherscanTokenTransactions,\n fetchEtherscanTransactions,\n} from '../utils/etherscan';\nimport type {\n EtherscanTokenTransactionMeta,\n EtherscanTransactionMeta,\n EtherscanTransactionMetaBase,\n EtherscanTransactionRequest,\n EtherscanTransactionResponse,\n} from '../utils/etherscan';\n\nconst ETHERSCAN_RATE_LIMIT_INTERVAL = 5000;\n\n/**\n * A RemoteTransactionSource that fetches transaction data from Etherscan.\n */\nexport class EtherscanRemoteTransactionSource\n implements RemoteTransactionSource\n{\n #apiKeysByChainId?: Record<Hex, string>;\n\n #includeTokenTransfers: boolean;\n\n #isTokenRequestPending: boolean;\n\n #mutex = new Mutex();\n\n constructor({\n apiKeysByChainId,\n includeTokenTransfers,\n }: {\n apiKeysByChainId?: Record<Hex, string>;\n includeTokenTransfers?: boolean;\n } = {}) {\n this.#apiKeysByChainId = apiKeysByChainId;\n this.#includeTokenTransfers = includeTokenTransfers ?? true;\n this.#isTokenRequestPending = false;\n }\n\n isSupportedNetwork(chainId: Hex): boolean {\n return Object.keys(ETHERSCAN_SUPPORTED_NETWORKS).includes(chainId);\n }\n\n getLastBlockVariations(): string[] {\n return [this.#isTokenRequestPending ? 'token' : 'normal'];\n }\n\n async fetchTransactions(\n request: RemoteTransactionSourceRequest,\n ): Promise<TransactionMeta[]> {\n const releaseLock = await this.#mutex.acquire();\n const acquiredTime = Date.now();\n const { currentChainId: chainId } = request;\n const apiKey = this.#apiKeysByChainId?.[chainId];\n\n if (apiKey) {\n log('Etherscan API key found for chain', chainId);\n }\n\n const etherscanRequest: EtherscanTransactionRequest = {\n ...request,\n apiKey,\n chainId,\n };\n\n try {\n const transactions = this.#isTokenRequestPending\n ? await this.#fetchTokenTransactions(request, etherscanRequest)\n : await this.#fetchNormalTransactions(request, etherscanRequest);\n\n if (this.#includeTokenTransfers) {\n this.#isTokenRequestPending = !this.#isTokenRequestPending;\n }\n\n return transactions;\n } finally {\n this.#releaseLockAfterInterval(acquiredTime, releaseLock);\n }\n }\n\n #releaseLockAfterInterval(acquireTime: number, releaseLock: () => void) {\n const elapsedTime = Date.now() - acquireTime;\n const remainingTime = Math.max(\n 0,\n ETHERSCAN_RATE_LIMIT_INTERVAL - elapsedTime,\n );\n // Wait for the remaining time if it hasn't been 5 seconds yet\n if (remainingTime > 0) {\n setTimeout(releaseLock, remainingTime);\n } else {\n releaseLock();\n }\n }\n\n #fetchNormalTransactions = async (\n request: RemoteTransactionSourceRequest,\n etherscanRequest: EtherscanTransactionRequest,\n ) => {\n const { currentChainId } = request;\n\n const etherscanTransactions = await fetchEtherscanTransactions(\n etherscanRequest,\n );\n\n return this.#getResponseTransactions(etherscanTransactions).map((tx) =>\n this.#normalizeTransaction(tx, currentChainId),\n );\n };\n\n #fetchTokenTransactions = async (\n request: RemoteTransactionSourceRequest,\n etherscanRequest: EtherscanTransactionRequest,\n ) => {\n const { currentChainId } = request;\n\n const etherscanTransactions = await fetchEtherscanTokenTransactions(\n etherscanRequest,\n );\n\n return this.#getResponseTransactions(etherscanTransactions).map((tx) =>\n this.#normalizeTokenTransaction(tx, currentChainId),\n );\n };\n\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n #getResponseTransactions<T extends EtherscanTransactionMetaBase>(\n response: EtherscanTransactionResponse<T>,\n ): T[] {\n let result = response.result as T[];\n\n if (response.status === '0') {\n result = [];\n\n if (response.result.length) {\n log('Ignored Etherscan request error', {\n message: response.result,\n type: this.#isTokenRequestPending ? 'token' : 'normal',\n });\n }\n }\n\n return result;\n }\n\n #normalizeTransaction(\n txMeta: EtherscanTransactionMeta,\n currentChainId: Hex,\n ): TransactionMeta {\n const base = this.#normalizeTransactionBase(txMeta, currentChainId);\n\n return {\n ...base,\n txParams: {\n ...base.txParams,\n data: txMeta.input,\n },\n ...(txMeta.isError === '0'\n ? { status: TransactionStatus.confirmed }\n : {\n error: new Error('Transaction failed'),\n status: TransactionStatus.failed,\n }),\n };\n }\n\n #normalizeTokenTransaction(\n txMeta: EtherscanTokenTransactionMeta,\n currentChainId: Hex,\n ): TransactionMeta {\n const base = this.#normalizeTransactionBase(txMeta, currentChainId);\n\n return {\n ...base,\n isTransfer: true,\n transferInformation: {\n contractAddress: txMeta.contractAddress,\n decimals: Number(txMeta.tokenDecimal),\n symbol: txMeta.tokenSymbol,\n },\n };\n }\n\n #normalizeTransactionBase(\n txMeta: EtherscanTransactionMetaBase,\n currentChainId: Hex,\n ): TransactionMeta {\n const time = parseInt(txMeta.timeStamp, 10) * 1000;\n\n return {\n blockNumber: txMeta.blockNumber,\n chainId: currentChainId,\n hash: txMeta.hash,\n id: random({ msecs: time }),\n networkClientId: 'incoming',\n status: TransactionStatus.confirmed,\n time,\n txParams: {\n chainId: currentChainId,\n from: txMeta.from,\n gas: BNToHex(new BN(txMeta.gas)),\n gasPrice: BNToHex(new BN(txMeta.gasPrice)),\n gasUsed: BNToHex(new BN(txMeta.gasUsed)),\n nonce: BNToHex(new BN(txMeta.nonce)),\n to: txMeta.to,\n value: BNToHex(new BN(txMeta.value)),\n },\n type: TransactionType.incoming,\n verifiedOnBlockchain: false,\n };\n }\n}\n"]}
@@ -119,8 +119,8 @@ _GasFeePoller_findNetworkClientIdByChainId = new WeakMap(), _GasFeePoller_gasFee
119
119
  layer1GasFee,
120
120
  });
121
121
  }, _GasFeePoller_updateTransactionGasFeeEstimates = async function _GasFeePoller_updateTransactionGasFeeEstimates(transactionMeta, gasFeeControllerData) {
122
- const { chainId, networkClientId } = transactionMeta;
123
- const ethQuery = new eth_query_1.default(__classPrivateFieldGet(this, _GasFeePoller_getProvider, "f").call(this, chainId, networkClientId));
122
+ const { networkClientId } = transactionMeta;
123
+ const ethQuery = new eth_query_1.default(__classPrivateFieldGet(this, _GasFeePoller_getProvider, "f").call(this, networkClientId));
124
124
  const gasFeeFlow = (0, gas_flow_1.getGasFeeFlow)(transactionMeta, __classPrivateFieldGet(this, _GasFeePoller_gasFeeFlows, "f"));
125
125
  if (gasFeeFlow) {
126
126
  log('Found gas fee flow', gasFeeFlow.constructor.name, transactionMeta.id);
@@ -149,8 +149,8 @@ _GasFeePoller_findNetworkClientIdByChainId = new WeakMap(), _GasFeePoller_gasFee
149
149
  });
150
150
  return { gasFeeEstimates, gasFeeEstimatesLoaded: true };
151
151
  }, _GasFeePoller_updateTransactionLayer1GasFee = async function _GasFeePoller_updateTransactionLayer1GasFee(transactionMeta) {
152
- const { chainId, networkClientId } = transactionMeta;
153
- const provider = __classPrivateFieldGet(this, _GasFeePoller_getProvider, "f").call(this, chainId, networkClientId);
152
+ const { networkClientId } = transactionMeta;
153
+ const provider = __classPrivateFieldGet(this, _GasFeePoller_getProvider, "f").call(this, networkClientId);
154
154
  const layer1GasFee = await (0, layer1_gas_fee_flow_1.getTransactionLayer1GasFee)({
155
155
  layer1GasFeeFlows: __classPrivateFieldGet(this, _GasFeePoller_layer1GasFeeFlows, "f"),
156
156
  provider,
@@ -1 +1 @@
1
- {"version":3,"file":"GasFeePoller.cjs","sourceRoot":"","sources":["../../src/helpers/GasFeePoller.ts"],"names":[],"mappings":"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","sourcesContent":["import EthQuery from '@metamask/eth-query';\nimport type {\n FetchGasFeeEstimateOptions,\n GasFeeState,\n} from '@metamask/gas-fee-controller';\nimport type { NetworkClientId, Provider } from '@metamask/network-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport EventEmitter from 'events';\n\nimport { projectLogger } from '../logger';\nimport type {\n GasFeeEstimates,\n GasFeeFlow,\n GasFeeFlowRequest,\n Layer1GasFeeFlow,\n} from '../types';\nimport { TransactionStatus, type TransactionMeta } from '../types';\nimport { getGasFeeFlow } from '../utils/gas-flow';\nimport { getTransactionLayer1GasFee } from '../utils/layer1-gas-fee-flow';\n\nconst log = createModuleLogger(projectLogger, 'gas-fee-poller');\n\nconst INTERVAL_MILLISECONDS = 10000;\n\n/**\n * Automatically polls and updates suggested gas fees on unapproved transactions.\n */\nexport class GasFeePoller {\n hub: EventEmitter = new EventEmitter();\n\n #findNetworkClientIdByChainId: (chainId: Hex) => NetworkClientId | undefined;\n\n #gasFeeFlows: GasFeeFlow[];\n\n #getGasFeeControllerEstimates: (\n options: FetchGasFeeEstimateOptions,\n ) => Promise<GasFeeState>;\n\n #getProvider: (chainId: Hex, networkClientId?: NetworkClientId) => Provider;\n\n #getTransactions: () => TransactionMeta[];\n\n #layer1GasFeeFlows: Layer1GasFeeFlow[];\n\n #timeout: ReturnType<typeof setTimeout> | undefined;\n\n #running = false;\n\n /**\n * Constructs a new instance of the GasFeePoller.\n * @param options - The options for this instance.\n * @param options.findNetworkClientIdByChainId - Callback to find the network client ID by chain ID.\n * @param options.gasFeeFlows - The gas fee flows to use to obtain suitable gas fees.\n * @param options.getGasFeeControllerEstimates - Callback to obtain the default fee estimates.\n * @param options.getProvider - Callback to obtain a provider instance.\n * @param options.getTransactions - Callback to obtain the transaction data.\n * @param options.layer1GasFeeFlows - The layer 1 gas fee flows to use to obtain suitable layer 1 gas fees.\n * @param options.onStateChange - Callback to register a listener for controller state changes.\n */\n constructor({\n findNetworkClientIdByChainId,\n gasFeeFlows,\n getGasFeeControllerEstimates,\n getProvider,\n getTransactions,\n layer1GasFeeFlows,\n onStateChange,\n }: {\n findNetworkClientIdByChainId: (chainId: Hex) => NetworkClientId | undefined;\n gasFeeFlows: GasFeeFlow[];\n getGasFeeControllerEstimates: (\n options: FetchGasFeeEstimateOptions,\n ) => Promise<GasFeeState>;\n getProvider: (chainId: Hex, networkClientId?: NetworkClientId) => Provider;\n getTransactions: () => TransactionMeta[];\n layer1GasFeeFlows: Layer1GasFeeFlow[];\n onStateChange: (listener: () => void) => void;\n }) {\n this.#findNetworkClientIdByChainId = findNetworkClientIdByChainId;\n this.#gasFeeFlows = gasFeeFlows;\n this.#layer1GasFeeFlows = layer1GasFeeFlows;\n this.#getGasFeeControllerEstimates = getGasFeeControllerEstimates;\n this.#getProvider = getProvider;\n this.#getTransactions = getTransactions;\n\n onStateChange(() => {\n const unapprovedTransactions = this.#getUnapprovedTransactions();\n\n if (unapprovedTransactions.length) {\n this.#start();\n } else {\n this.#stop();\n }\n });\n }\n\n #start() {\n if (this.#running) {\n return;\n }\n\n // Intentionally not awaiting since this starts the timeout chain.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.#onTimeout();\n\n this.#running = true;\n\n log('Started polling');\n }\n\n #stop() {\n if (!this.#running) {\n return;\n }\n\n clearTimeout(this.#timeout);\n\n this.#timeout = undefined;\n this.#running = false;\n\n log('Stopped polling');\n }\n\n async #onTimeout() {\n await this.#updateUnapprovedTransactions();\n\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.#timeout = setTimeout(() => this.#onTimeout(), INTERVAL_MILLISECONDS);\n }\n\n async #updateUnapprovedTransactions() {\n const unapprovedTransactions = this.#getUnapprovedTransactions();\n\n if (!unapprovedTransactions.length) {\n return;\n }\n\n log('Found unapproved transactions', unapprovedTransactions.length);\n\n const gasFeeControllerDataByChainId = await this.#getGasFeeControllerData(\n unapprovedTransactions,\n );\n\n log('Retrieved gas fee controller data', gasFeeControllerDataByChainId);\n\n await Promise.all(\n unapprovedTransactions.flatMap((tx) => {\n const { chainId } = tx;\n\n const gasFeeControllerData = gasFeeControllerDataByChainId.get(\n chainId,\n ) as GasFeeState;\n\n return this.#updateUnapprovedTransaction(tx, gasFeeControllerData);\n }),\n );\n }\n\n async #updateUnapprovedTransaction(\n transactionMeta: TransactionMeta,\n gasFeeControllerData: GasFeeState,\n ) {\n const { id } = transactionMeta;\n\n const [gasFeeEstimatesResponse, layer1GasFee] = await Promise.all([\n this.#updateTransactionGasFeeEstimates(\n transactionMeta,\n gasFeeControllerData,\n ),\n this.#updateTransactionLayer1GasFee(transactionMeta),\n ]);\n\n if (!gasFeeEstimatesResponse && !layer1GasFee) {\n return;\n }\n\n this.hub.emit('transaction-updated', {\n transactionId: id,\n gasFeeEstimates: gasFeeEstimatesResponse?.gasFeeEstimates,\n gasFeeEstimatesLoaded: gasFeeEstimatesResponse?.gasFeeEstimatesLoaded,\n layer1GasFee,\n });\n }\n\n async #updateTransactionGasFeeEstimates(\n transactionMeta: TransactionMeta,\n gasFeeControllerData: GasFeeState,\n ): Promise<\n | { gasFeeEstimates?: GasFeeEstimates; gasFeeEstimatesLoaded: boolean }\n | undefined\n > {\n const { chainId, networkClientId } = transactionMeta;\n\n const ethQuery = new EthQuery(this.#getProvider(chainId, networkClientId));\n const gasFeeFlow = getGasFeeFlow(transactionMeta, this.#gasFeeFlows);\n\n if (gasFeeFlow) {\n log(\n 'Found gas fee flow',\n gasFeeFlow.constructor.name,\n transactionMeta.id,\n );\n }\n\n const request: GasFeeFlowRequest = {\n ethQuery,\n gasFeeControllerData,\n transactionMeta,\n };\n\n let gasFeeEstimates: GasFeeEstimates | undefined;\n\n if (gasFeeFlow) {\n try {\n const response = await gasFeeFlow.getGasFees(request);\n gasFeeEstimates = response.estimates;\n } catch (error) {\n log('Failed to get suggested gas fees', transactionMeta.id, error);\n }\n }\n\n if (!gasFeeEstimates && transactionMeta.gasFeeEstimatesLoaded) {\n return undefined;\n }\n\n log('Updated gas fee estimates', {\n gasFeeEstimates,\n transaction: transactionMeta.id,\n });\n\n return { gasFeeEstimates, gasFeeEstimatesLoaded: true };\n }\n\n async #updateTransactionLayer1GasFee(\n transactionMeta: TransactionMeta,\n ): Promise<Hex | undefined> {\n const { chainId, networkClientId } = transactionMeta;\n const provider = this.#getProvider(chainId, networkClientId);\n\n const layer1GasFee = await getTransactionLayer1GasFee({\n layer1GasFeeFlows: this.#layer1GasFeeFlows,\n provider,\n transactionMeta,\n });\n\n if (layer1GasFee) {\n log('Updated layer 1 gas fee', layer1GasFee, transactionMeta.id);\n }\n\n return layer1GasFee;\n }\n\n #getUnapprovedTransactions() {\n return this.#getTransactions().filter(\n (tx) => tx.status === TransactionStatus.unapproved,\n );\n }\n\n async #getGasFeeControllerData(\n transactions: TransactionMeta[],\n ): Promise<Map<string, GasFeeState>> {\n const networkClientIdsByChainId = new Map<Hex, NetworkClientId>();\n\n for (const transaction of transactions) {\n const { chainId, networkClientId: transactionNetworkClientId } =\n transaction;\n\n if (networkClientIdsByChainId.has(chainId)) {\n continue;\n }\n\n const networkClientId =\n transactionNetworkClientId ??\n (this.#findNetworkClientIdByChainId(chainId) as string);\n\n networkClientIdsByChainId.set(chainId, networkClientId);\n }\n\n log('Extracted network client IDs by chain ID', networkClientIdsByChainId);\n\n const entryPromises = Array.from(networkClientIdsByChainId.entries()).map(\n async ([chainId, networkClientId]) => {\n return [\n chainId,\n await this.#getGasFeeControllerEstimates({ networkClientId }),\n ] as const;\n },\n );\n\n return new Map(await Promise.all(entryPromises));\n }\n}\n"]}
1
+ {"version":3,"file":"GasFeePoller.cjs","sourceRoot":"","sources":["../../src/helpers/GasFeePoller.ts"],"names":[],"mappings":"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","sourcesContent":["import EthQuery from '@metamask/eth-query';\nimport type {\n FetchGasFeeEstimateOptions,\n GasFeeState,\n} from '@metamask/gas-fee-controller';\nimport type { NetworkClientId, Provider } from '@metamask/network-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport EventEmitter from 'events';\n\nimport { projectLogger } from '../logger';\nimport type {\n GasFeeEstimates,\n GasFeeFlow,\n GasFeeFlowRequest,\n Layer1GasFeeFlow,\n} from '../types';\nimport { TransactionStatus, type TransactionMeta } from '../types';\nimport { getGasFeeFlow } from '../utils/gas-flow';\nimport { getTransactionLayer1GasFee } from '../utils/layer1-gas-fee-flow';\n\nconst log = createModuleLogger(projectLogger, 'gas-fee-poller');\n\nconst INTERVAL_MILLISECONDS = 10000;\n\n/**\n * Automatically polls and updates suggested gas fees on unapproved transactions.\n */\nexport class GasFeePoller {\n hub: EventEmitter = new EventEmitter();\n\n #findNetworkClientIdByChainId: (chainId: Hex) => NetworkClientId | undefined;\n\n #gasFeeFlows: GasFeeFlow[];\n\n #getGasFeeControllerEstimates: (\n options: FetchGasFeeEstimateOptions,\n ) => Promise<GasFeeState>;\n\n #getProvider: (networkClientId: NetworkClientId) => Provider;\n\n #getTransactions: () => TransactionMeta[];\n\n #layer1GasFeeFlows: Layer1GasFeeFlow[];\n\n #timeout: ReturnType<typeof setTimeout> | undefined;\n\n #running = false;\n\n /**\n * Constructs a new instance of the GasFeePoller.\n * @param options - The options for this instance.\n * @param options.findNetworkClientIdByChainId - Callback to find the network client ID by chain ID.\n * @param options.gasFeeFlows - The gas fee flows to use to obtain suitable gas fees.\n * @param options.getGasFeeControllerEstimates - Callback to obtain the default fee estimates.\n * @param options.getProvider - Callback to obtain a provider instance.\n * @param options.getTransactions - Callback to obtain the transaction data.\n * @param options.layer1GasFeeFlows - The layer 1 gas fee flows to use to obtain suitable layer 1 gas fees.\n * @param options.onStateChange - Callback to register a listener for controller state changes.\n */\n constructor({\n findNetworkClientIdByChainId,\n gasFeeFlows,\n getGasFeeControllerEstimates,\n getProvider,\n getTransactions,\n layer1GasFeeFlows,\n onStateChange,\n }: {\n findNetworkClientIdByChainId: (chainId: Hex) => NetworkClientId | undefined;\n gasFeeFlows: GasFeeFlow[];\n getGasFeeControllerEstimates: (\n options: FetchGasFeeEstimateOptions,\n ) => Promise<GasFeeState>;\n getProvider: (networkClientId: NetworkClientId) => Provider;\n getTransactions: () => TransactionMeta[];\n layer1GasFeeFlows: Layer1GasFeeFlow[];\n onStateChange: (listener: () => void) => void;\n }) {\n this.#findNetworkClientIdByChainId = findNetworkClientIdByChainId;\n this.#gasFeeFlows = gasFeeFlows;\n this.#layer1GasFeeFlows = layer1GasFeeFlows;\n this.#getGasFeeControllerEstimates = getGasFeeControllerEstimates;\n this.#getProvider = getProvider;\n this.#getTransactions = getTransactions;\n\n onStateChange(() => {\n const unapprovedTransactions = this.#getUnapprovedTransactions();\n\n if (unapprovedTransactions.length) {\n this.#start();\n } else {\n this.#stop();\n }\n });\n }\n\n #start() {\n if (this.#running) {\n return;\n }\n\n // Intentionally not awaiting since this starts the timeout chain.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.#onTimeout();\n\n this.#running = true;\n\n log('Started polling');\n }\n\n #stop() {\n if (!this.#running) {\n return;\n }\n\n clearTimeout(this.#timeout);\n\n this.#timeout = undefined;\n this.#running = false;\n\n log('Stopped polling');\n }\n\n async #onTimeout() {\n await this.#updateUnapprovedTransactions();\n\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.#timeout = setTimeout(() => this.#onTimeout(), INTERVAL_MILLISECONDS);\n }\n\n async #updateUnapprovedTransactions() {\n const unapprovedTransactions = this.#getUnapprovedTransactions();\n\n if (!unapprovedTransactions.length) {\n return;\n }\n\n log('Found unapproved transactions', unapprovedTransactions.length);\n\n const gasFeeControllerDataByChainId = await this.#getGasFeeControllerData(\n unapprovedTransactions,\n );\n\n log('Retrieved gas fee controller data', gasFeeControllerDataByChainId);\n\n await Promise.all(\n unapprovedTransactions.flatMap((tx) => {\n const { chainId } = tx;\n\n const gasFeeControllerData = gasFeeControllerDataByChainId.get(\n chainId,\n ) as GasFeeState;\n\n return this.#updateUnapprovedTransaction(tx, gasFeeControllerData);\n }),\n );\n }\n\n async #updateUnapprovedTransaction(\n transactionMeta: TransactionMeta,\n gasFeeControllerData: GasFeeState,\n ) {\n const { id } = transactionMeta;\n\n const [gasFeeEstimatesResponse, layer1GasFee] = await Promise.all([\n this.#updateTransactionGasFeeEstimates(\n transactionMeta,\n gasFeeControllerData,\n ),\n this.#updateTransactionLayer1GasFee(transactionMeta),\n ]);\n\n if (!gasFeeEstimatesResponse && !layer1GasFee) {\n return;\n }\n\n this.hub.emit('transaction-updated', {\n transactionId: id,\n gasFeeEstimates: gasFeeEstimatesResponse?.gasFeeEstimates,\n gasFeeEstimatesLoaded: gasFeeEstimatesResponse?.gasFeeEstimatesLoaded,\n layer1GasFee,\n });\n }\n\n async #updateTransactionGasFeeEstimates(\n transactionMeta: TransactionMeta,\n gasFeeControllerData: GasFeeState,\n ): Promise<\n | { gasFeeEstimates?: GasFeeEstimates; gasFeeEstimatesLoaded: boolean }\n | undefined\n > {\n const { networkClientId } = transactionMeta;\n\n const ethQuery = new EthQuery(this.#getProvider(networkClientId));\n const gasFeeFlow = getGasFeeFlow(transactionMeta, this.#gasFeeFlows);\n\n if (gasFeeFlow) {\n log(\n 'Found gas fee flow',\n gasFeeFlow.constructor.name,\n transactionMeta.id,\n );\n }\n\n const request: GasFeeFlowRequest = {\n ethQuery,\n gasFeeControllerData,\n transactionMeta,\n };\n\n let gasFeeEstimates: GasFeeEstimates | undefined;\n\n if (gasFeeFlow) {\n try {\n const response = await gasFeeFlow.getGasFees(request);\n gasFeeEstimates = response.estimates;\n } catch (error) {\n log('Failed to get suggested gas fees', transactionMeta.id, error);\n }\n }\n\n if (!gasFeeEstimates && transactionMeta.gasFeeEstimatesLoaded) {\n return undefined;\n }\n\n log('Updated gas fee estimates', {\n gasFeeEstimates,\n transaction: transactionMeta.id,\n });\n\n return { gasFeeEstimates, gasFeeEstimatesLoaded: true };\n }\n\n async #updateTransactionLayer1GasFee(\n transactionMeta: TransactionMeta,\n ): Promise<Hex | undefined> {\n const { networkClientId } = transactionMeta;\n const provider = this.#getProvider(networkClientId);\n\n const layer1GasFee = await getTransactionLayer1GasFee({\n layer1GasFeeFlows: this.#layer1GasFeeFlows,\n provider,\n transactionMeta,\n });\n\n if (layer1GasFee) {\n log('Updated layer 1 gas fee', layer1GasFee, transactionMeta.id);\n }\n\n return layer1GasFee;\n }\n\n #getUnapprovedTransactions() {\n return this.#getTransactions().filter(\n (tx) => tx.status === TransactionStatus.unapproved,\n );\n }\n\n async #getGasFeeControllerData(\n transactions: TransactionMeta[],\n ): Promise<Map<string, GasFeeState>> {\n const networkClientIdsByChainId = new Map<Hex, NetworkClientId>();\n\n for (const transaction of transactions) {\n const { chainId, networkClientId: transactionNetworkClientId } =\n transaction;\n\n if (networkClientIdsByChainId.has(chainId)) {\n continue;\n }\n\n const networkClientId =\n transactionNetworkClientId ??\n (this.#findNetworkClientIdByChainId(chainId) as string);\n\n networkClientIdsByChainId.set(chainId, networkClientId);\n }\n\n log('Extracted network client IDs by chain ID', networkClientIdsByChainId);\n\n const entryPromises = Array.from(networkClientIdsByChainId.entries()).map(\n async ([chainId, networkClientId]) => {\n return [\n chainId,\n await this.#getGasFeeControllerEstimates({ networkClientId }),\n ] as const;\n },\n );\n\n return new Map(await Promise.all(entryPromises));\n }\n}\n"]}
@@ -26,7 +26,7 @@ export declare class GasFeePoller {
26
26
  findNetworkClientIdByChainId: (chainId: Hex) => NetworkClientId | undefined;
27
27
  gasFeeFlows: GasFeeFlow[];
28
28
  getGasFeeControllerEstimates: (options: FetchGasFeeEstimateOptions) => Promise<GasFeeState>;
29
- getProvider: (chainId: Hex, networkClientId?: NetworkClientId) => Provider;
29
+ getProvider: (networkClientId: NetworkClientId) => Provider;
30
30
  getTransactions: () => TransactionMeta[];
31
31
  layer1GasFeeFlows: Layer1GasFeeFlow[];
32
32
  onStateChange: (listener: () => void) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"GasFeePoller.d.cts","sourceRoot":"","sources":["../../src/helpers/GasFeePoller.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,EACV,0BAA0B,EAC1B,WAAW,EACZ,qCAAqC;AACtC,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,qCAAqC;AAC9E,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAE3C,OAAO,YAAY,eAAe;AAGlC,OAAO,KAAK,EAEV,UAAU,EAEV,gBAAgB,EACjB,qBAAiB;AAClB,OAAO,EAAqB,KAAK,eAAe,EAAE,qBAAiB;AAQnE;;GAEG;AACH,qBAAa,YAAY;;IACvB,GAAG,EAAE,YAAY,CAAsB;IAoBvC;;;;;;;;;;OAUG;gBACS,EACV,4BAA4B,EAC5B,WAAW,EACX,4BAA4B,EAC5B,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,aAAa,GACd,EAAE;QACD,4BAA4B,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,eAAe,GAAG,SAAS,CAAC;QAC5E,WAAW,EAAE,UAAU,EAAE,CAAC;QAC1B,4BAA4B,EAAE,CAC5B,OAAO,EAAE,0BAA0B,KAChC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC1B,WAAW,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,eAAe,CAAC,EAAE,eAAe,KAAK,QAAQ,CAAC;QAC3E,eAAe,EAAE,MAAM,eAAe,EAAE,CAAC;QACzC,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;QACtC,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;KAC/C;CAsNF"}
1
+ {"version":3,"file":"GasFeePoller.d.cts","sourceRoot":"","sources":["../../src/helpers/GasFeePoller.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,EACV,0BAA0B,EAC1B,WAAW,EACZ,qCAAqC;AACtC,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,qCAAqC;AAC9E,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAE3C,OAAO,YAAY,eAAe;AAGlC,OAAO,KAAK,EAEV,UAAU,EAEV,gBAAgB,EACjB,qBAAiB;AAClB,OAAO,EAAqB,KAAK,eAAe,EAAE,qBAAiB;AAQnE;;GAEG;AACH,qBAAa,YAAY;;IACvB,GAAG,EAAE,YAAY,CAAsB;IAoBvC;;;;;;;;;;OAUG;gBACS,EACV,4BAA4B,EAC5B,WAAW,EACX,4BAA4B,EAC5B,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,aAAa,GACd,EAAE;QACD,4BAA4B,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,eAAe,GAAG,SAAS,CAAC;QAC5E,WAAW,EAAE,UAAU,EAAE,CAAC;QAC1B,4BAA4B,EAAE,CAC5B,OAAO,EAAE,0BAA0B,KAChC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC1B,WAAW,EAAE,CAAC,eAAe,EAAE,eAAe,KAAK,QAAQ,CAAC;QAC5D,eAAe,EAAE,MAAM,eAAe,EAAE,CAAC;QACzC,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;QACtC,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;KAC/C;CAsNF"}
@@ -26,7 +26,7 @@ export declare class GasFeePoller {
26
26
  findNetworkClientIdByChainId: (chainId: Hex) => NetworkClientId | undefined;
27
27
  gasFeeFlows: GasFeeFlow[];
28
28
  getGasFeeControllerEstimates: (options: FetchGasFeeEstimateOptions) => Promise<GasFeeState>;
29
- getProvider: (chainId: Hex, networkClientId?: NetworkClientId) => Provider;
29
+ getProvider: (networkClientId: NetworkClientId) => Provider;
30
30
  getTransactions: () => TransactionMeta[];
31
31
  layer1GasFeeFlows: Layer1GasFeeFlow[];
32
32
  onStateChange: (listener: () => void) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"GasFeePoller.d.mts","sourceRoot":"","sources":["../../src/helpers/GasFeePoller.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,EACV,0BAA0B,EAC1B,WAAW,EACZ,qCAAqC;AACtC,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,qCAAqC;AAC9E,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAE3C,OAAO,YAAY,eAAe;AAGlC,OAAO,KAAK,EAEV,UAAU,EAEV,gBAAgB,EACjB,qBAAiB;AAClB,OAAO,EAAqB,KAAK,eAAe,EAAE,qBAAiB;AAQnE;;GAEG;AACH,qBAAa,YAAY;;IACvB,GAAG,EAAE,YAAY,CAAsB;IAoBvC;;;;;;;;;;OAUG;gBACS,EACV,4BAA4B,EAC5B,WAAW,EACX,4BAA4B,EAC5B,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,aAAa,GACd,EAAE;QACD,4BAA4B,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,eAAe,GAAG,SAAS,CAAC;QAC5E,WAAW,EAAE,UAAU,EAAE,CAAC;QAC1B,4BAA4B,EAAE,CAC5B,OAAO,EAAE,0BAA0B,KAChC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC1B,WAAW,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,eAAe,CAAC,EAAE,eAAe,KAAK,QAAQ,CAAC;QAC3E,eAAe,EAAE,MAAM,eAAe,EAAE,CAAC;QACzC,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;QACtC,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;KAC/C;CAsNF"}
1
+ {"version":3,"file":"GasFeePoller.d.mts","sourceRoot":"","sources":["../../src/helpers/GasFeePoller.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,EACV,0BAA0B,EAC1B,WAAW,EACZ,qCAAqC;AACtC,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,qCAAqC;AAC9E,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAE3C,OAAO,YAAY,eAAe;AAGlC,OAAO,KAAK,EAEV,UAAU,EAEV,gBAAgB,EACjB,qBAAiB;AAClB,OAAO,EAAqB,KAAK,eAAe,EAAE,qBAAiB;AAQnE;;GAEG;AACH,qBAAa,YAAY;;IACvB,GAAG,EAAE,YAAY,CAAsB;IAoBvC;;;;;;;;;;OAUG;gBACS,EACV,4BAA4B,EAC5B,WAAW,EACX,4BAA4B,EAC5B,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,aAAa,GACd,EAAE;QACD,4BAA4B,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,eAAe,GAAG,SAAS,CAAC;QAC5E,WAAW,EAAE,UAAU,EAAE,CAAC;QAC1B,4BAA4B,EAAE,CAC5B,OAAO,EAAE,0BAA0B,KAChC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC1B,WAAW,EAAE,CAAC,eAAe,EAAE,eAAe,KAAK,QAAQ,CAAC;QAC5D,eAAe,EAAE,MAAM,eAAe,EAAE,CAAC;QACzC,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;QACtC,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;KAC/C;CAsNF"}
@@ -119,8 +119,8 @@ _GasFeePoller_findNetworkClientIdByChainId = new WeakMap(), _GasFeePoller_gasFee
119
119
  layer1GasFee,
120
120
  });
121
121
  }, _GasFeePoller_updateTransactionGasFeeEstimates = async function _GasFeePoller_updateTransactionGasFeeEstimates(transactionMeta, gasFeeControllerData) {
122
- const { chainId, networkClientId } = transactionMeta;
123
- const ethQuery = new EthQuery(__classPrivateFieldGet(this, _GasFeePoller_getProvider, "f").call(this, chainId, networkClientId));
122
+ const { networkClientId } = transactionMeta;
123
+ const ethQuery = new EthQuery(__classPrivateFieldGet(this, _GasFeePoller_getProvider, "f").call(this, networkClientId));
124
124
  const gasFeeFlow = getGasFeeFlow(transactionMeta, __classPrivateFieldGet(this, _GasFeePoller_gasFeeFlows, "f"));
125
125
  if (gasFeeFlow) {
126
126
  log('Found gas fee flow', gasFeeFlow.constructor.name, transactionMeta.id);
@@ -149,8 +149,8 @@ _GasFeePoller_findNetworkClientIdByChainId = new WeakMap(), _GasFeePoller_gasFee
149
149
  });
150
150
  return { gasFeeEstimates, gasFeeEstimatesLoaded: true };
151
151
  }, _GasFeePoller_updateTransactionLayer1GasFee = async function _GasFeePoller_updateTransactionLayer1GasFee(transactionMeta) {
152
- const { chainId, networkClientId } = transactionMeta;
153
- const provider = __classPrivateFieldGet(this, _GasFeePoller_getProvider, "f").call(this, chainId, networkClientId);
152
+ const { networkClientId } = transactionMeta;
153
+ const provider = __classPrivateFieldGet(this, _GasFeePoller_getProvider, "f").call(this, networkClientId);
154
154
  const layer1GasFee = await getTransactionLayer1GasFee({
155
155
  layer1GasFeeFlows: __classPrivateFieldGet(this, _GasFeePoller_layer1GasFeeFlows, "f"),
156
156
  provider,
@@ -1 +1 @@
1
- {"version":3,"file":"GasFeePoller.mjs","sourceRoot":"","sources":["../../src/helpers/GasFeePoller.ts"],"names":[],"mappings":"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","sourcesContent":["import EthQuery from '@metamask/eth-query';\nimport type {\n FetchGasFeeEstimateOptions,\n GasFeeState,\n} from '@metamask/gas-fee-controller';\nimport type { NetworkClientId, Provider } from '@metamask/network-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport EventEmitter from 'events';\n\nimport { projectLogger } from '../logger';\nimport type {\n GasFeeEstimates,\n GasFeeFlow,\n GasFeeFlowRequest,\n Layer1GasFeeFlow,\n} from '../types';\nimport { TransactionStatus, type TransactionMeta } from '../types';\nimport { getGasFeeFlow } from '../utils/gas-flow';\nimport { getTransactionLayer1GasFee } from '../utils/layer1-gas-fee-flow';\n\nconst log = createModuleLogger(projectLogger, 'gas-fee-poller');\n\nconst INTERVAL_MILLISECONDS = 10000;\n\n/**\n * Automatically polls and updates suggested gas fees on unapproved transactions.\n */\nexport class GasFeePoller {\n hub: EventEmitter = new EventEmitter();\n\n #findNetworkClientIdByChainId: (chainId: Hex) => NetworkClientId | undefined;\n\n #gasFeeFlows: GasFeeFlow[];\n\n #getGasFeeControllerEstimates: (\n options: FetchGasFeeEstimateOptions,\n ) => Promise<GasFeeState>;\n\n #getProvider: (chainId: Hex, networkClientId?: NetworkClientId) => Provider;\n\n #getTransactions: () => TransactionMeta[];\n\n #layer1GasFeeFlows: Layer1GasFeeFlow[];\n\n #timeout: ReturnType<typeof setTimeout> | undefined;\n\n #running = false;\n\n /**\n * Constructs a new instance of the GasFeePoller.\n * @param options - The options for this instance.\n * @param options.findNetworkClientIdByChainId - Callback to find the network client ID by chain ID.\n * @param options.gasFeeFlows - The gas fee flows to use to obtain suitable gas fees.\n * @param options.getGasFeeControllerEstimates - Callback to obtain the default fee estimates.\n * @param options.getProvider - Callback to obtain a provider instance.\n * @param options.getTransactions - Callback to obtain the transaction data.\n * @param options.layer1GasFeeFlows - The layer 1 gas fee flows to use to obtain suitable layer 1 gas fees.\n * @param options.onStateChange - Callback to register a listener for controller state changes.\n */\n constructor({\n findNetworkClientIdByChainId,\n gasFeeFlows,\n getGasFeeControllerEstimates,\n getProvider,\n getTransactions,\n layer1GasFeeFlows,\n onStateChange,\n }: {\n findNetworkClientIdByChainId: (chainId: Hex) => NetworkClientId | undefined;\n gasFeeFlows: GasFeeFlow[];\n getGasFeeControllerEstimates: (\n options: FetchGasFeeEstimateOptions,\n ) => Promise<GasFeeState>;\n getProvider: (chainId: Hex, networkClientId?: NetworkClientId) => Provider;\n getTransactions: () => TransactionMeta[];\n layer1GasFeeFlows: Layer1GasFeeFlow[];\n onStateChange: (listener: () => void) => void;\n }) {\n this.#findNetworkClientIdByChainId = findNetworkClientIdByChainId;\n this.#gasFeeFlows = gasFeeFlows;\n this.#layer1GasFeeFlows = layer1GasFeeFlows;\n this.#getGasFeeControllerEstimates = getGasFeeControllerEstimates;\n this.#getProvider = getProvider;\n this.#getTransactions = getTransactions;\n\n onStateChange(() => {\n const unapprovedTransactions = this.#getUnapprovedTransactions();\n\n if (unapprovedTransactions.length) {\n this.#start();\n } else {\n this.#stop();\n }\n });\n }\n\n #start() {\n if (this.#running) {\n return;\n }\n\n // Intentionally not awaiting since this starts the timeout chain.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.#onTimeout();\n\n this.#running = true;\n\n log('Started polling');\n }\n\n #stop() {\n if (!this.#running) {\n return;\n }\n\n clearTimeout(this.#timeout);\n\n this.#timeout = undefined;\n this.#running = false;\n\n log('Stopped polling');\n }\n\n async #onTimeout() {\n await this.#updateUnapprovedTransactions();\n\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.#timeout = setTimeout(() => this.#onTimeout(), INTERVAL_MILLISECONDS);\n }\n\n async #updateUnapprovedTransactions() {\n const unapprovedTransactions = this.#getUnapprovedTransactions();\n\n if (!unapprovedTransactions.length) {\n return;\n }\n\n log('Found unapproved transactions', unapprovedTransactions.length);\n\n const gasFeeControllerDataByChainId = await this.#getGasFeeControllerData(\n unapprovedTransactions,\n );\n\n log('Retrieved gas fee controller data', gasFeeControllerDataByChainId);\n\n await Promise.all(\n unapprovedTransactions.flatMap((tx) => {\n const { chainId } = tx;\n\n const gasFeeControllerData = gasFeeControllerDataByChainId.get(\n chainId,\n ) as GasFeeState;\n\n return this.#updateUnapprovedTransaction(tx, gasFeeControllerData);\n }),\n );\n }\n\n async #updateUnapprovedTransaction(\n transactionMeta: TransactionMeta,\n gasFeeControllerData: GasFeeState,\n ) {\n const { id } = transactionMeta;\n\n const [gasFeeEstimatesResponse, layer1GasFee] = await Promise.all([\n this.#updateTransactionGasFeeEstimates(\n transactionMeta,\n gasFeeControllerData,\n ),\n this.#updateTransactionLayer1GasFee(transactionMeta),\n ]);\n\n if (!gasFeeEstimatesResponse && !layer1GasFee) {\n return;\n }\n\n this.hub.emit('transaction-updated', {\n transactionId: id,\n gasFeeEstimates: gasFeeEstimatesResponse?.gasFeeEstimates,\n gasFeeEstimatesLoaded: gasFeeEstimatesResponse?.gasFeeEstimatesLoaded,\n layer1GasFee,\n });\n }\n\n async #updateTransactionGasFeeEstimates(\n transactionMeta: TransactionMeta,\n gasFeeControllerData: GasFeeState,\n ): Promise<\n | { gasFeeEstimates?: GasFeeEstimates; gasFeeEstimatesLoaded: boolean }\n | undefined\n > {\n const { chainId, networkClientId } = transactionMeta;\n\n const ethQuery = new EthQuery(this.#getProvider(chainId, networkClientId));\n const gasFeeFlow = getGasFeeFlow(transactionMeta, this.#gasFeeFlows);\n\n if (gasFeeFlow) {\n log(\n 'Found gas fee flow',\n gasFeeFlow.constructor.name,\n transactionMeta.id,\n );\n }\n\n const request: GasFeeFlowRequest = {\n ethQuery,\n gasFeeControllerData,\n transactionMeta,\n };\n\n let gasFeeEstimates: GasFeeEstimates | undefined;\n\n if (gasFeeFlow) {\n try {\n const response = await gasFeeFlow.getGasFees(request);\n gasFeeEstimates = response.estimates;\n } catch (error) {\n log('Failed to get suggested gas fees', transactionMeta.id, error);\n }\n }\n\n if (!gasFeeEstimates && transactionMeta.gasFeeEstimatesLoaded) {\n return undefined;\n }\n\n log('Updated gas fee estimates', {\n gasFeeEstimates,\n transaction: transactionMeta.id,\n });\n\n return { gasFeeEstimates, gasFeeEstimatesLoaded: true };\n }\n\n async #updateTransactionLayer1GasFee(\n transactionMeta: TransactionMeta,\n ): Promise<Hex | undefined> {\n const { chainId, networkClientId } = transactionMeta;\n const provider = this.#getProvider(chainId, networkClientId);\n\n const layer1GasFee = await getTransactionLayer1GasFee({\n layer1GasFeeFlows: this.#layer1GasFeeFlows,\n provider,\n transactionMeta,\n });\n\n if (layer1GasFee) {\n log('Updated layer 1 gas fee', layer1GasFee, transactionMeta.id);\n }\n\n return layer1GasFee;\n }\n\n #getUnapprovedTransactions() {\n return this.#getTransactions().filter(\n (tx) => tx.status === TransactionStatus.unapproved,\n );\n }\n\n async #getGasFeeControllerData(\n transactions: TransactionMeta[],\n ): Promise<Map<string, GasFeeState>> {\n const networkClientIdsByChainId = new Map<Hex, NetworkClientId>();\n\n for (const transaction of transactions) {\n const { chainId, networkClientId: transactionNetworkClientId } =\n transaction;\n\n if (networkClientIdsByChainId.has(chainId)) {\n continue;\n }\n\n const networkClientId =\n transactionNetworkClientId ??\n (this.#findNetworkClientIdByChainId(chainId) as string);\n\n networkClientIdsByChainId.set(chainId, networkClientId);\n }\n\n log('Extracted network client IDs by chain ID', networkClientIdsByChainId);\n\n const entryPromises = Array.from(networkClientIdsByChainId.entries()).map(\n async ([chainId, networkClientId]) => {\n return [\n chainId,\n await this.#getGasFeeControllerEstimates({ networkClientId }),\n ] as const;\n },\n );\n\n return new Map(await Promise.all(entryPromises));\n }\n}\n"]}
1
+ {"version":3,"file":"GasFeePoller.mjs","sourceRoot":"","sources":["../../src/helpers/GasFeePoller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,OAAO,SAAQ,4BAA4B;;AAO3C,OAAO,EAAE,kBAAkB,EAAE,wBAAwB;AACrD,OAAO,YAAY,eAAe;AAElC,OAAO,EAAE,aAAa,EAAE,sBAAkB;AAO1C,OAAO,EAAE,iBAAiB,EAAwB,qBAAiB;AACnE,OAAO,EAAE,aAAa,EAAE,8BAA0B;AAClD,OAAO,EAAE,0BAA0B,EAAE,yCAAqC;AAE1E,MAAM,GAAG,GAAG,kBAAkB,CAAC,aAAa,EAAE,gBAAgB,CAAC,CAAC;AAEhE,MAAM,qBAAqB,GAAG,KAAK,CAAC;AAEpC;;GAEG;AACH,MAAM,OAAO,YAAY;IAqBvB;;;;;;;;;;OAUG;IACH,YAAY,EACV,4BAA4B,EAC5B,WAAW,EACX,4BAA4B,EAC5B,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,aAAa,GAWd;;QAjDD,QAAG,GAAiB,IAAI,YAAY,EAAE,CAAC;QAEvC,6DAA6E;QAE7E,4CAA2B;QAE3B,6DAE0B;QAE1B,4CAA6D;QAE7D,gDAA0C;QAE1C,kDAAuC;QAEvC,wCAAoD;QAEpD,gCAAW,KAAK,EAAC;QAgCf,uBAAA,IAAI,8CAAiC,4BAA4B,MAAA,CAAC;QAClE,uBAAA,IAAI,6BAAgB,WAAW,MAAA,CAAC;QAChC,uBAAA,IAAI,mCAAsB,iBAAiB,MAAA,CAAC;QAC5C,uBAAA,IAAI,8CAAiC,4BAA4B,MAAA,CAAC;QAClE,uBAAA,IAAI,6BAAgB,WAAW,MAAA,CAAC;QAChC,uBAAA,IAAI,iCAAoB,eAAe,MAAA,CAAC;QAExC,aAAa,CAAC,GAAG,EAAE;YACjB,MAAM,sBAAsB,GAAG,uBAAA,IAAI,wEAA2B,MAA/B,IAAI,CAA6B,CAAC;YAEjE,IAAI,sBAAsB,CAAC,MAAM,EAAE;gBACjC,uBAAA,IAAI,oDAAO,MAAX,IAAI,CAAS,CAAC;aACf;iBAAM;gBACL,uBAAA,IAAI,mDAAM,MAAV,IAAI,CAAQ,CAAC;aACd;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CAqMF;;IAlMG,IAAI,uBAAA,IAAI,6BAAS,EAAE;QACjB,OAAO;KACR;IAED,kEAAkE;IAClE,mEAAmE;IACnE,uBAAA,IAAI,wDAAW,MAAf,IAAI,CAAa,CAAC;IAElB,uBAAA,IAAI,yBAAY,IAAI,MAAA,CAAC;IAErB,GAAG,CAAC,iBAAiB,CAAC,CAAC;AACzB,CAAC;IAGC,IAAI,CAAC,uBAAA,IAAI,6BAAS,EAAE;QAClB,OAAO;KACR;IAED,YAAY,CAAC,uBAAA,IAAI,6BAAS,CAAC,CAAC;IAE5B,uBAAA,IAAI,yBAAY,SAAS,MAAA,CAAC;IAC1B,uBAAA,IAAI,yBAAY,KAAK,MAAA,CAAC;IAEtB,GAAG,CAAC,iBAAiB,CAAC,CAAC;AACzB,CAAC,4BAED,KAAK;IACH,MAAM,uBAAA,IAAI,2EAA8B,MAAlC,IAAI,CAAgC,CAAC;IAE3C,kEAAkE;IAClE,uBAAA,IAAI,yBAAY,UAAU,CAAC,GAAG,EAAE,CAAC,uBAAA,IAAI,wDAAW,MAAf,IAAI,CAAa,EAAE,qBAAqB,CAAC,MAAA,CAAC;AAC7E,CAAC,+CAED,KAAK;IACH,MAAM,sBAAsB,GAAG,uBAAA,IAAI,wEAA2B,MAA/B,IAAI,CAA6B,CAAC;IAEjE,IAAI,CAAC,sBAAsB,CAAC,MAAM,EAAE;QAClC,OAAO;KACR;IAED,GAAG,CAAC,+BAA+B,EAAE,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAEpE,MAAM,6BAA6B,GAAG,MAAM,uBAAA,IAAI,sEAAyB,MAA7B,IAAI,EAC9C,sBAAsB,CACvB,CAAC;IAEF,GAAG,CAAC,mCAAmC,EAAE,6BAA6B,CAAC,CAAC;IAExE,MAAM,OAAO,CAAC,GAAG,CACf,sBAAsB,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE;QACpC,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;QAEvB,MAAM,oBAAoB,GAAG,6BAA6B,CAAC,GAAG,CAC5D,OAAO,CACO,CAAC;QAEjB,OAAO,uBAAA,IAAI,0EAA6B,MAAjC,IAAI,EAA8B,EAAE,EAAE,oBAAoB,CAAC,CAAC;IACrE,CAAC,CAAC,CACH,CAAC;AACJ,CAAC,8CAED,KAAK,oDACH,eAAgC,EAChC,oBAAiC;IAEjC,MAAM,EAAE,EAAE,EAAE,GAAG,eAAe,CAAC;IAE/B,MAAM,CAAC,uBAAuB,EAAE,YAAY,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAChE,uBAAA,IAAI,+EAAkC,MAAtC,IAAI,EACF,eAAe,EACf,oBAAoB,CACrB;QACD,uBAAA,IAAI,4EAA+B,MAAnC,IAAI,EAAgC,eAAe,CAAC;KACrD,CAAC,CAAC;IAEH,IAAI,CAAC,uBAAuB,IAAI,CAAC,YAAY,EAAE;QAC7C,OAAO;KACR;IAED,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,qBAAqB,EAAE;QACnC,aAAa,EAAE,EAAE;QACjB,eAAe,EAAE,uBAAuB,EAAE,eAAe;QACzD,qBAAqB,EAAE,uBAAuB,EAAE,qBAAqB;QACrE,YAAY;KACb,CAAC,CAAC;AACL,CAAC,mDAED,KAAK,yDACH,eAAgC,EAChC,oBAAiC;IAKjC,MAAM,EAAE,eAAe,EAAE,GAAG,eAAe,CAAC;IAE5C,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,uBAAA,IAAI,iCAAa,MAAjB,IAAI,EAAc,eAAe,CAAC,CAAC,CAAC;IAClE,MAAM,UAAU,GAAG,aAAa,CAAC,eAAe,EAAE,uBAAA,IAAI,iCAAa,CAAC,CAAC;IAErE,IAAI,UAAU,EAAE;QACd,GAAG,CACD,oBAAoB,EACpB,UAAU,CAAC,WAAW,CAAC,IAAI,EAC3B,eAAe,CAAC,EAAE,CACnB,CAAC;KACH;IAED,MAAM,OAAO,GAAsB;QACjC,QAAQ;QACR,oBAAoB;QACpB,eAAe;KAChB,CAAC;IAEF,IAAI,eAA4C,CAAC;IAEjD,IAAI,UAAU,EAAE;QACd,IAAI;YACF,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YACtD,eAAe,GAAG,QAAQ,CAAC,SAAS,CAAC;SACtC;QAAC,OAAO,KAAK,EAAE;YACd,GAAG,CAAC,kCAAkC,EAAE,eAAe,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;SACpE;KACF;IAED,IAAI,CAAC,eAAe,IAAI,eAAe,CAAC,qBAAqB,EAAE;QAC7D,OAAO,SAAS,CAAC;KAClB;IAED,GAAG,CAAC,2BAA2B,EAAE;QAC/B,eAAe;QACf,WAAW,EAAE,eAAe,CAAC,EAAE;KAChC,CAAC,CAAC;IAEH,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,IAAI,EAAE,CAAC;AAC1D,CAAC,gDAED,KAAK,sDACH,eAAgC;IAEhC,MAAM,EAAE,eAAe,EAAE,GAAG,eAAe,CAAC;IAC5C,MAAM,QAAQ,GAAG,uBAAA,IAAI,iCAAa,MAAjB,IAAI,EAAc,eAAe,CAAC,CAAC;IAEpD,MAAM,YAAY,GAAG,MAAM,0BAA0B,CAAC;QACpD,iBAAiB,EAAE,uBAAA,IAAI,uCAAmB;QAC1C,QAAQ;QACR,eAAe;KAChB,CAAC,CAAC;IAEH,IAAI,YAAY,EAAE;QAChB,GAAG,CAAC,yBAAyB,EAAE,YAAY,EAAE,eAAe,CAAC,EAAE,CAAC,CAAC;KAClE;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;IAGC,OAAO,uBAAA,IAAI,qCAAiB,MAArB,IAAI,CAAmB,CAAC,MAAM,CACnC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,KAAK,iBAAiB,CAAC,UAAU,CACnD,CAAC;AACJ,CAAC,0CAED,KAAK,gDACH,YAA+B;IAE/B,MAAM,yBAAyB,GAAG,IAAI,GAAG,EAAwB,CAAC;IAElE,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE;QACtC,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,0BAA0B,EAAE,GAC5D,WAAW,CAAC;QAEd,IAAI,yBAAyB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;YAC1C,SAAS;SACV;QAED,MAAM,eAAe,GACnB,0BAA0B;YACzB,uBAAA,IAAI,kDAA8B,MAAlC,IAAI,EAA+B,OAAO,CAAY,CAAC;QAE1D,yBAAyB,CAAC,GAAG,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;KACzD;IAED,GAAG,CAAC,0CAA0C,EAAE,yBAAyB,CAAC,CAAC;IAE3E,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CACvE,KAAK,EAAE,CAAC,OAAO,EAAE,eAAe,CAAC,EAAE,EAAE;QACnC,OAAO;YACL,OAAO;YACP,MAAM,uBAAA,IAAI,kDAA8B,MAAlC,IAAI,EAA+B,EAAE,eAAe,EAAE,CAAC;SACrD,CAAC;IACb,CAAC,CACF,CAAC;IAEF,OAAO,IAAI,GAAG,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC;AACnD,CAAC","sourcesContent":["import EthQuery from '@metamask/eth-query';\nimport type {\n FetchGasFeeEstimateOptions,\n GasFeeState,\n} from '@metamask/gas-fee-controller';\nimport type { NetworkClientId, Provider } from '@metamask/network-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport EventEmitter from 'events';\n\nimport { projectLogger } from '../logger';\nimport type {\n GasFeeEstimates,\n GasFeeFlow,\n GasFeeFlowRequest,\n Layer1GasFeeFlow,\n} from '../types';\nimport { TransactionStatus, type TransactionMeta } from '../types';\nimport { getGasFeeFlow } from '../utils/gas-flow';\nimport { getTransactionLayer1GasFee } from '../utils/layer1-gas-fee-flow';\n\nconst log = createModuleLogger(projectLogger, 'gas-fee-poller');\n\nconst INTERVAL_MILLISECONDS = 10000;\n\n/**\n * Automatically polls and updates suggested gas fees on unapproved transactions.\n */\nexport class GasFeePoller {\n hub: EventEmitter = new EventEmitter();\n\n #findNetworkClientIdByChainId: (chainId: Hex) => NetworkClientId | undefined;\n\n #gasFeeFlows: GasFeeFlow[];\n\n #getGasFeeControllerEstimates: (\n options: FetchGasFeeEstimateOptions,\n ) => Promise<GasFeeState>;\n\n #getProvider: (networkClientId: NetworkClientId) => Provider;\n\n #getTransactions: () => TransactionMeta[];\n\n #layer1GasFeeFlows: Layer1GasFeeFlow[];\n\n #timeout: ReturnType<typeof setTimeout> | undefined;\n\n #running = false;\n\n /**\n * Constructs a new instance of the GasFeePoller.\n * @param options - The options for this instance.\n * @param options.findNetworkClientIdByChainId - Callback to find the network client ID by chain ID.\n * @param options.gasFeeFlows - The gas fee flows to use to obtain suitable gas fees.\n * @param options.getGasFeeControllerEstimates - Callback to obtain the default fee estimates.\n * @param options.getProvider - Callback to obtain a provider instance.\n * @param options.getTransactions - Callback to obtain the transaction data.\n * @param options.layer1GasFeeFlows - The layer 1 gas fee flows to use to obtain suitable layer 1 gas fees.\n * @param options.onStateChange - Callback to register a listener for controller state changes.\n */\n constructor({\n findNetworkClientIdByChainId,\n gasFeeFlows,\n getGasFeeControllerEstimates,\n getProvider,\n getTransactions,\n layer1GasFeeFlows,\n onStateChange,\n }: {\n findNetworkClientIdByChainId: (chainId: Hex) => NetworkClientId | undefined;\n gasFeeFlows: GasFeeFlow[];\n getGasFeeControllerEstimates: (\n options: FetchGasFeeEstimateOptions,\n ) => Promise<GasFeeState>;\n getProvider: (networkClientId: NetworkClientId) => Provider;\n getTransactions: () => TransactionMeta[];\n layer1GasFeeFlows: Layer1GasFeeFlow[];\n onStateChange: (listener: () => void) => void;\n }) {\n this.#findNetworkClientIdByChainId = findNetworkClientIdByChainId;\n this.#gasFeeFlows = gasFeeFlows;\n this.#layer1GasFeeFlows = layer1GasFeeFlows;\n this.#getGasFeeControllerEstimates = getGasFeeControllerEstimates;\n this.#getProvider = getProvider;\n this.#getTransactions = getTransactions;\n\n onStateChange(() => {\n const unapprovedTransactions = this.#getUnapprovedTransactions();\n\n if (unapprovedTransactions.length) {\n this.#start();\n } else {\n this.#stop();\n }\n });\n }\n\n #start() {\n if (this.#running) {\n return;\n }\n\n // Intentionally not awaiting since this starts the timeout chain.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.#onTimeout();\n\n this.#running = true;\n\n log('Started polling');\n }\n\n #stop() {\n if (!this.#running) {\n return;\n }\n\n clearTimeout(this.#timeout);\n\n this.#timeout = undefined;\n this.#running = false;\n\n log('Stopped polling');\n }\n\n async #onTimeout() {\n await this.#updateUnapprovedTransactions();\n\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.#timeout = setTimeout(() => this.#onTimeout(), INTERVAL_MILLISECONDS);\n }\n\n async #updateUnapprovedTransactions() {\n const unapprovedTransactions = this.#getUnapprovedTransactions();\n\n if (!unapprovedTransactions.length) {\n return;\n }\n\n log('Found unapproved transactions', unapprovedTransactions.length);\n\n const gasFeeControllerDataByChainId = await this.#getGasFeeControllerData(\n unapprovedTransactions,\n );\n\n log('Retrieved gas fee controller data', gasFeeControllerDataByChainId);\n\n await Promise.all(\n unapprovedTransactions.flatMap((tx) => {\n const { chainId } = tx;\n\n const gasFeeControllerData = gasFeeControllerDataByChainId.get(\n chainId,\n ) as GasFeeState;\n\n return this.#updateUnapprovedTransaction(tx, gasFeeControllerData);\n }),\n );\n }\n\n async #updateUnapprovedTransaction(\n transactionMeta: TransactionMeta,\n gasFeeControllerData: GasFeeState,\n ) {\n const { id } = transactionMeta;\n\n const [gasFeeEstimatesResponse, layer1GasFee] = await Promise.all([\n this.#updateTransactionGasFeeEstimates(\n transactionMeta,\n gasFeeControllerData,\n ),\n this.#updateTransactionLayer1GasFee(transactionMeta),\n ]);\n\n if (!gasFeeEstimatesResponse && !layer1GasFee) {\n return;\n }\n\n this.hub.emit('transaction-updated', {\n transactionId: id,\n gasFeeEstimates: gasFeeEstimatesResponse?.gasFeeEstimates,\n gasFeeEstimatesLoaded: gasFeeEstimatesResponse?.gasFeeEstimatesLoaded,\n layer1GasFee,\n });\n }\n\n async #updateTransactionGasFeeEstimates(\n transactionMeta: TransactionMeta,\n gasFeeControllerData: GasFeeState,\n ): Promise<\n | { gasFeeEstimates?: GasFeeEstimates; gasFeeEstimatesLoaded: boolean }\n | undefined\n > {\n const { networkClientId } = transactionMeta;\n\n const ethQuery = new EthQuery(this.#getProvider(networkClientId));\n const gasFeeFlow = getGasFeeFlow(transactionMeta, this.#gasFeeFlows);\n\n if (gasFeeFlow) {\n log(\n 'Found gas fee flow',\n gasFeeFlow.constructor.name,\n transactionMeta.id,\n );\n }\n\n const request: GasFeeFlowRequest = {\n ethQuery,\n gasFeeControllerData,\n transactionMeta,\n };\n\n let gasFeeEstimates: GasFeeEstimates | undefined;\n\n if (gasFeeFlow) {\n try {\n const response = await gasFeeFlow.getGasFees(request);\n gasFeeEstimates = response.estimates;\n } catch (error) {\n log('Failed to get suggested gas fees', transactionMeta.id, error);\n }\n }\n\n if (!gasFeeEstimates && transactionMeta.gasFeeEstimatesLoaded) {\n return undefined;\n }\n\n log('Updated gas fee estimates', {\n gasFeeEstimates,\n transaction: transactionMeta.id,\n });\n\n return { gasFeeEstimates, gasFeeEstimatesLoaded: true };\n }\n\n async #updateTransactionLayer1GasFee(\n transactionMeta: TransactionMeta,\n ): Promise<Hex | undefined> {\n const { networkClientId } = transactionMeta;\n const provider = this.#getProvider(networkClientId);\n\n const layer1GasFee = await getTransactionLayer1GasFee({\n layer1GasFeeFlows: this.#layer1GasFeeFlows,\n provider,\n transactionMeta,\n });\n\n if (layer1GasFee) {\n log('Updated layer 1 gas fee', layer1GasFee, transactionMeta.id);\n }\n\n return layer1GasFee;\n }\n\n #getUnapprovedTransactions() {\n return this.#getTransactions().filter(\n (tx) => tx.status === TransactionStatus.unapproved,\n );\n }\n\n async #getGasFeeControllerData(\n transactions: TransactionMeta[],\n ): Promise<Map<string, GasFeeState>> {\n const networkClientIdsByChainId = new Map<Hex, NetworkClientId>();\n\n for (const transaction of transactions) {\n const { chainId, networkClientId: transactionNetworkClientId } =\n transaction;\n\n if (networkClientIdsByChainId.has(chainId)) {\n continue;\n }\n\n const networkClientId =\n transactionNetworkClientId ??\n (this.#findNetworkClientIdByChainId(chainId) as string);\n\n networkClientIdsByChainId.set(chainId, networkClientId);\n }\n\n log('Extracted network client IDs by chain ID', networkClientIdsByChainId);\n\n const entryPromises = Array.from(networkClientIdsByChainId.entries()).map(\n async ([chainId, networkClientId]) => {\n return [\n chainId,\n await this.#getGasFeeControllerEstimates({ networkClientId }),\n ] as const;\n },\n );\n\n return new Map(await Promise.all(entryPromises));\n }\n}\n"]}
@@ -13,7 +13,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
13
13
  var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  return (mod && mod.__esModule) ? mod : { "default": mod };
15
15
  };
16
- var _IncomingTransactionHelper_instances, _IncomingTransactionHelper_blockTracker, _IncomingTransactionHelper_getCurrentAccount, _IncomingTransactionHelper_getLastFetchedBlockNumbers, _IncomingTransactionHelper_getLocalTransactions, _IncomingTransactionHelper_getChainId, _IncomingTransactionHelper_isEnabled, _IncomingTransactionHelper_isRunning, _IncomingTransactionHelper_mutex, _IncomingTransactionHelper_onLatestBlock, _IncomingTransactionHelper_queryEntireHistory, _IncomingTransactionHelper_remoteTransactionSource, _IncomingTransactionHelper_transactionLimit, _IncomingTransactionHelper_updateTransactions, _IncomingTransactionHelper_sortTransactionsByTime, _IncomingTransactionHelper_getNewTransactions, _IncomingTransactionHelper_getUpdatedTransactions, _IncomingTransactionHelper_isTransactionOutdated, _IncomingTransactionHelper_getLastFetchedBlockNumberDec, _IncomingTransactionHelper_getFromBlock, _IncomingTransactionHelper_updateLastFetchedBlockNumber, _IncomingTransactionHelper_getBlockNumberKey, _IncomingTransactionHelper_canStart;
16
+ var _IncomingTransactionHelper_instances, _IncomingTransactionHelper_blockTracker, _IncomingTransactionHelper_getCurrentAccount, _IncomingTransactionHelper_getLastFetchedBlockNumbers, _IncomingTransactionHelper_getLocalTransactions, _IncomingTransactionHelper_getChainId, _IncomingTransactionHelper_isEnabled, _IncomingTransactionHelper_isRunning, _IncomingTransactionHelper_log, _IncomingTransactionHelper_mutex, _IncomingTransactionHelper_onLatestBlock, _IncomingTransactionHelper_queryEntireHistory, _IncomingTransactionHelper_remoteTransactionSource, _IncomingTransactionHelper_transactionLimit, _IncomingTransactionHelper_updateTransactions, _IncomingTransactionHelper_sortTransactionsByTime, _IncomingTransactionHelper_getNewTransactions, _IncomingTransactionHelper_getUpdatedTransactions, _IncomingTransactionHelper_isTransactionOutdated, _IncomingTransactionHelper_getLastFetchedBlockNumberDec, _IncomingTransactionHelper_getFromBlock, _IncomingTransactionHelper_updateLastFetchedBlockNumber, _IncomingTransactionHelper_getBlockNumberKey, _IncomingTransactionHelper_canStart;
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.IncomingTransactionHelper = void 0;
19
19
  const async_mutex_1 = require("async-mutex");
@@ -36,6 +36,7 @@ class IncomingTransactionHelper {
36
36
  _IncomingTransactionHelper_getChainId.set(this, void 0);
37
37
  _IncomingTransactionHelper_isEnabled.set(this, void 0);
38
38
  _IncomingTransactionHelper_isRunning.set(this, void 0);
39
+ _IncomingTransactionHelper_log.set(this, void 0);
39
40
  _IncomingTransactionHelper_mutex.set(this, new async_mutex_1.Mutex());
40
41
  _IncomingTransactionHelper_onLatestBlock.set(this, void 0);
41
42
  _IncomingTransactionHelper_queryEntireHistory.set(this, void 0);
@@ -50,6 +51,7 @@ class IncomingTransactionHelper {
50
51
  __classPrivateFieldSet(this, _IncomingTransactionHelper_getChainId, getChainId, "f");
51
52
  __classPrivateFieldSet(this, _IncomingTransactionHelper_isEnabled, isEnabled ?? (() => true), "f");
52
53
  __classPrivateFieldSet(this, _IncomingTransactionHelper_isRunning, false, "f");
54
+ __classPrivateFieldSet(this, _IncomingTransactionHelper_log, (0, logger_1.createModuleLogger)(logger_1.incomingTransactionsLogger, getChainId()), "f");
53
55
  __classPrivateFieldSet(this, _IncomingTransactionHelper_queryEntireHistory, queryEntireHistory ?? true, "f");
54
56
  __classPrivateFieldSet(this, _IncomingTransactionHelper_remoteTransactionSource, remoteTransactionSource, "f");
55
57
  __classPrivateFieldSet(this, _IncomingTransactionHelper_transactionLimit, transactionLimit, "f");
@@ -72,20 +74,25 @@ class IncomingTransactionHelper {
72
74
  if (!__classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_canStart).call(this)) {
73
75
  return;
74
76
  }
77
+ __classPrivateFieldGet(this, _IncomingTransactionHelper_log, "f").call(this, 'Starting polling');
75
78
  // TODO: Either fix this lint violation or explain why it's necessary to ignore.
76
79
  // eslint-disable-next-line @typescript-eslint/no-misused-promises
77
80
  __classPrivateFieldGet(this, _IncomingTransactionHelper_blockTracker, "f").addListener('latest', __classPrivateFieldGet(this, _IncomingTransactionHelper_onLatestBlock, "f"));
78
81
  __classPrivateFieldSet(this, _IncomingTransactionHelper_isRunning, true, "f");
79
82
  }
80
83
  stop() {
84
+ if (!__classPrivateFieldGet(this, _IncomingTransactionHelper_isRunning, "f")) {
85
+ return;
86
+ }
81
87
  // TODO: Either fix this lint violation or explain why it's necessary to ignore.
82
88
  // eslint-disable-next-line @typescript-eslint/no-misused-promises
83
89
  __classPrivateFieldGet(this, _IncomingTransactionHelper_blockTracker, "f").removeListener('latest', __classPrivateFieldGet(this, _IncomingTransactionHelper_onLatestBlock, "f"));
84
90
  __classPrivateFieldSet(this, _IncomingTransactionHelper_isRunning, false, "f");
91
+ __classPrivateFieldGet(this, _IncomingTransactionHelper_log, "f").call(this, 'Stopped polling');
85
92
  }
86
93
  async update(latestBlockNumberHex) {
87
94
  const releaseLock = await __classPrivateFieldGet(this, _IncomingTransactionHelper_mutex, "f").acquire();
88
- (0, logger_1.incomingTransactionsLogger)('Checking for incoming transactions');
95
+ __classPrivateFieldGet(this, _IncomingTransactionHelper_log, "f").call(this, 'Checking');
89
96
  try {
90
97
  if (!__classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_canStart).call(this)) {
91
98
  return;
@@ -108,7 +115,7 @@ class IncomingTransactionHelper {
108
115
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
109
116
  }
110
117
  catch (error) {
111
- (0, logger_1.incomingTransactionsLogger)('Error while fetching remote transactions', error);
118
+ __classPrivateFieldGet(this, _IncomingTransactionHelper_log, "f").call(this, 'Error while fetching remote transactions', error);
112
119
  return;
113
120
  }
114
121
  if (!__classPrivateFieldGet(this, _IncomingTransactionHelper_updateTransactions, "f")) {
@@ -123,7 +130,7 @@ class IncomingTransactionHelper {
123
130
  if (newTransactions.length > 0 || updatedTransactions.length > 0) {
124
131
  __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_sortTransactionsByTime).call(this, newTransactions);
125
132
  __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_sortTransactionsByTime).call(this, updatedTransactions);
126
- (0, logger_1.incomingTransactionsLogger)('Found incoming transactions', {
133
+ __classPrivateFieldGet(this, _IncomingTransactionHelper_log, "f").call(this, 'Found incoming transactions', {
127
134
  new: newTransactions,
128
135
  updated: updatedTransactions,
129
136
  });
@@ -140,7 +147,7 @@ class IncomingTransactionHelper {
140
147
  }
141
148
  }
142
149
  exports.IncomingTransactionHelper = IncomingTransactionHelper;
143
- _IncomingTransactionHelper_blockTracker = new WeakMap(), _IncomingTransactionHelper_getCurrentAccount = new WeakMap(), _IncomingTransactionHelper_getLastFetchedBlockNumbers = new WeakMap(), _IncomingTransactionHelper_getLocalTransactions = new WeakMap(), _IncomingTransactionHelper_getChainId = new WeakMap(), _IncomingTransactionHelper_isEnabled = new WeakMap(), _IncomingTransactionHelper_isRunning = new WeakMap(), _IncomingTransactionHelper_mutex = new WeakMap(), _IncomingTransactionHelper_onLatestBlock = new WeakMap(), _IncomingTransactionHelper_queryEntireHistory = new WeakMap(), _IncomingTransactionHelper_remoteTransactionSource = new WeakMap(), _IncomingTransactionHelper_transactionLimit = new WeakMap(), _IncomingTransactionHelper_updateTransactions = new WeakMap(), _IncomingTransactionHelper_instances = new WeakSet(), _IncomingTransactionHelper_sortTransactionsByTime = function _IncomingTransactionHelper_sortTransactionsByTime(transactions) {
150
+ _IncomingTransactionHelper_blockTracker = new WeakMap(), _IncomingTransactionHelper_getCurrentAccount = new WeakMap(), _IncomingTransactionHelper_getLastFetchedBlockNumbers = new WeakMap(), _IncomingTransactionHelper_getLocalTransactions = new WeakMap(), _IncomingTransactionHelper_getChainId = new WeakMap(), _IncomingTransactionHelper_isEnabled = new WeakMap(), _IncomingTransactionHelper_isRunning = new WeakMap(), _IncomingTransactionHelper_log = new WeakMap(), _IncomingTransactionHelper_mutex = new WeakMap(), _IncomingTransactionHelper_onLatestBlock = new WeakMap(), _IncomingTransactionHelper_queryEntireHistory = new WeakMap(), _IncomingTransactionHelper_remoteTransactionSource = new WeakMap(), _IncomingTransactionHelper_transactionLimit = new WeakMap(), _IncomingTransactionHelper_updateTransactions = new WeakMap(), _IncomingTransactionHelper_instances = new WeakSet(), _IncomingTransactionHelper_sortTransactionsByTime = function _IncomingTransactionHelper_sortTransactionsByTime(transactions) {
144
151
  transactions.sort((a, b) => (a.time < b.time ? -1 : 1));
145
152
  }, _IncomingTransactionHelper_getNewTransactions = function _IncomingTransactionHelper_getNewTransactions(remoteTxs, localTxs) {
146
153
  return remoteTxs.filter((tx) => !localTxs.some(({ hash }) => hash === tx.hash));
@@ -1 +1 @@
1
- {"version":3,"file":"IncomingTransactionHelper.cjs","sourceRoot":"","sources":["../../src/helpers/IncomingTransactionHelper.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AccountsController } from '@metamask/accounts-controller';\nimport type { BlockTracker } from '@metamask/network-controller';\nimport type { Hex } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\nimport EventEmitter from 'events';\n\nimport { incomingTransactionsLogger as log } from '../logger';\nimport type { RemoteTransactionSource, TransactionMeta } from '../types';\n\nconst RECENT_HISTORY_BLOCK_RANGE = 10;\n\n// TODO: Replace `any` with type\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst UPDATE_CHECKS: ((txMeta: TransactionMeta) => any)[] = [\n (txMeta) => txMeta.status,\n (txMeta) => txMeta.txParams.gasUsed,\n];\n\n/**\n * Configuration options for the IncomingTransactionHelper\n *\n * @property includeTokenTransfers - Whether or not to include ERC20 token transfers.\n * @property isEnabled - Whether or not incoming transaction retrieval is enabled.\n * @property queryEntireHistory - Whether to initially query the entire transaction history or only recent blocks.\n * @property updateTransactions - Whether to update local transactions using remote transaction data.\n */\nexport type IncomingTransactionOptions = {\n includeTokenTransfers?: boolean;\n isEnabled?: () => boolean;\n queryEntireHistory?: boolean;\n updateTransactions?: boolean;\n};\n\nexport class IncomingTransactionHelper {\n hub: EventEmitter;\n\n #blockTracker: BlockTracker;\n\n #getCurrentAccount: () => ReturnType<\n AccountsController['getSelectedAccount']\n >;\n\n #getLastFetchedBlockNumbers: () => Record<string, number>;\n\n #getLocalTransactions: () => TransactionMeta[];\n\n #getChainId: () => Hex;\n\n #isEnabled: () => boolean;\n\n #isRunning: boolean;\n\n #mutex = new Mutex();\n\n #onLatestBlock: (blockNumberHex: Hex) => Promise<void>;\n\n #queryEntireHistory: boolean;\n\n #remoteTransactionSource: RemoteTransactionSource;\n\n #transactionLimit?: number;\n\n #updateTransactions: boolean;\n\n constructor({\n blockTracker,\n getCurrentAccount,\n getLastFetchedBlockNumbers,\n getLocalTransactions,\n getChainId,\n isEnabled,\n queryEntireHistory,\n remoteTransactionSource,\n transactionLimit,\n updateTransactions,\n }: {\n blockTracker: BlockTracker;\n getCurrentAccount: () => ReturnType<\n AccountsController['getSelectedAccount']\n >;\n getLastFetchedBlockNumbers: () => Record<string, number>;\n getLocalTransactions?: () => TransactionMeta[];\n getChainId: () => Hex;\n isEnabled?: () => boolean;\n queryEntireHistory?: boolean;\n remoteTransactionSource: RemoteTransactionSource;\n transactionLimit?: number;\n updateTransactions?: boolean;\n }) {\n this.hub = new EventEmitter();\n\n this.#blockTracker = blockTracker;\n this.#getCurrentAccount = getCurrentAccount;\n this.#getLastFetchedBlockNumbers = getLastFetchedBlockNumbers;\n this.#getLocalTransactions = getLocalTransactions || (() => []);\n this.#getChainId = getChainId;\n this.#isEnabled = isEnabled ?? (() => true);\n this.#isRunning = false;\n this.#queryEntireHistory = queryEntireHistory ?? true;\n this.#remoteTransactionSource = remoteTransactionSource;\n this.#transactionLimit = transactionLimit;\n this.#updateTransactions = updateTransactions ?? false;\n\n // Using a property instead of a method to provide a listener reference\n // with the correct scope that we can remove later if stopped.\n this.#onLatestBlock = async (blockNumberHex: Hex) => {\n try {\n await this.update(blockNumberHex);\n } catch (error) {\n console.error('Error while checking incoming transactions', error);\n }\n };\n }\n\n start() {\n if (this.#isRunning) {\n return;\n }\n\n if (!this.#canStart()) {\n return;\n }\n\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.#blockTracker.addListener('latest', this.#onLatestBlock);\n this.#isRunning = true;\n }\n\n stop() {\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.#blockTracker.removeListener('latest', this.#onLatestBlock);\n this.#isRunning = false;\n }\n\n async update(latestBlockNumberHex?: Hex): Promise<void> {\n const releaseLock = await this.#mutex.acquire();\n\n log('Checking for incoming transactions');\n\n try {\n if (!this.#canStart()) {\n return;\n }\n\n const latestBlockNumber = parseInt(\n latestBlockNumberHex || (await this.#blockTracker.getLatestBlock()),\n 16,\n );\n\n const additionalLastFetchedKeys =\n this.#remoteTransactionSource.getLastBlockVariations?.() ?? [];\n\n const fromBlock = this.#getFromBlock(latestBlockNumber);\n const account = this.#getCurrentAccount();\n const currentChainId = this.#getChainId();\n\n let remoteTransactions = [];\n\n try {\n remoteTransactions =\n await this.#remoteTransactionSource.fetchTransactions({\n address: account.address,\n currentChainId,\n fromBlock,\n limit: this.#transactionLimit,\n });\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n log('Error while fetching remote transactions', error);\n return;\n }\n if (!this.#updateTransactions) {\n const address = account.address.toLowerCase();\n remoteTransactions = remoteTransactions.filter(\n (tx) => tx.txParams.to?.toLowerCase() === address,\n );\n }\n\n const localTransactions = !this.#updateTransactions\n ? []\n : this.#getLocalTransactions();\n\n const newTransactions = this.#getNewTransactions(\n remoteTransactions,\n localTransactions,\n );\n\n const updatedTransactions = this.#getUpdatedTransactions(\n remoteTransactions,\n localTransactions,\n );\n\n if (newTransactions.length > 0 || updatedTransactions.length > 0) {\n this.#sortTransactionsByTime(newTransactions);\n this.#sortTransactionsByTime(updatedTransactions);\n\n log('Found incoming transactions', {\n new: newTransactions,\n updated: updatedTransactions,\n });\n\n this.hub.emit('transactions', {\n added: newTransactions,\n updated: updatedTransactions,\n });\n }\n this.#updateLastFetchedBlockNumber(\n remoteTransactions,\n additionalLastFetchedKeys,\n );\n } finally {\n releaseLock();\n }\n }\n\n #sortTransactionsByTime(transactions: TransactionMeta[]) {\n transactions.sort((a, b) => (a.time < b.time ? -1 : 1));\n }\n\n #getNewTransactions(\n remoteTxs: TransactionMeta[],\n localTxs: TransactionMeta[],\n ): TransactionMeta[] {\n return remoteTxs.filter(\n (tx) => !localTxs.some(({ hash }) => hash === tx.hash),\n );\n }\n\n #getUpdatedTransactions(\n remoteTxs: TransactionMeta[],\n localTxs: TransactionMeta[],\n ): TransactionMeta[] {\n return remoteTxs.filter((remoteTx) =>\n localTxs.some(\n (localTx) =>\n remoteTx.hash === localTx.hash &&\n this.#isTransactionOutdated(remoteTx, localTx),\n ),\n );\n }\n\n #isTransactionOutdated(\n remoteTx: TransactionMeta,\n localTx: TransactionMeta,\n ): boolean {\n return UPDATE_CHECKS.some(\n (getValue) => getValue(remoteTx) !== getValue(localTx),\n );\n }\n\n #getLastFetchedBlockNumberDec(): number {\n const additionalLastFetchedKeys =\n this.#remoteTransactionSource.getLastBlockVariations?.() ?? [];\n const lastFetchedKey = this.#getBlockNumberKey(additionalLastFetchedKeys);\n const lastFetchedBlockNumbers = this.#getLastFetchedBlockNumbers();\n return lastFetchedBlockNumbers[lastFetchedKey];\n }\n\n #getFromBlock(latestBlockNumber: number): number | undefined {\n const lastFetchedBlockNumber = this.#getLastFetchedBlockNumberDec();\n\n if (lastFetchedBlockNumber) {\n return lastFetchedBlockNumber + 1;\n }\n\n return this.#queryEntireHistory\n ? undefined\n : latestBlockNumber - RECENT_HISTORY_BLOCK_RANGE;\n }\n\n #updateLastFetchedBlockNumber(\n remoteTxs: TransactionMeta[],\n additionalKeys: string[],\n ) {\n let lastFetchedBlockNumber = -1;\n\n for (const tx of remoteTxs) {\n const currentBlockNumberValue = tx.blockNumber\n ? parseInt(tx.blockNumber, 10)\n : -1;\n\n lastFetchedBlockNumber = Math.max(\n lastFetchedBlockNumber,\n currentBlockNumberValue,\n );\n }\n\n if (lastFetchedBlockNumber === -1) {\n return;\n }\n\n const lastFetchedKey = this.#getBlockNumberKey(additionalKeys);\n const lastFetchedBlockNumbers = this.#getLastFetchedBlockNumbers();\n const previousValue = lastFetchedBlockNumbers[lastFetchedKey];\n\n if (previousValue >= lastFetchedBlockNumber) {\n return;\n }\n\n this.hub.emit('updatedLastFetchedBlockNumbers', {\n lastFetchedBlockNumbers: {\n ...lastFetchedBlockNumbers,\n [lastFetchedKey]: lastFetchedBlockNumber,\n },\n blockNumber: lastFetchedBlockNumber,\n });\n }\n\n #getBlockNumberKey(additionalKeys: string[]): string {\n const currentChainId = this.#getChainId();\n const currentAccount = this.#getCurrentAccount()?.address.toLowerCase();\n\n return [currentChainId, currentAccount, ...additionalKeys].join('#');\n }\n\n #canStart(): boolean {\n const isEnabled = this.#isEnabled();\n const currentChainId = this.#getChainId();\n\n const isSupportedNetwork =\n this.#remoteTransactionSource.isSupportedNetwork(currentChainId);\n\n return isEnabled && isSupportedNetwork;\n }\n}\n"]}
1
+ {"version":3,"file":"IncomingTransactionHelper.cjs","sourceRoot":"","sources":["../../src/helpers/IncomingTransactionHelper.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AccountsController } from '@metamask/accounts-controller';\nimport type { BlockTracker } from '@metamask/network-controller';\nimport type { Hex } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\nimport EventEmitter from 'events';\n\nimport {\n createModuleLogger,\n incomingTransactionsLogger as log,\n} from '../logger';\nimport type { RemoteTransactionSource, TransactionMeta } from '../types';\n\nconst RECENT_HISTORY_BLOCK_RANGE = 10;\n\n// TODO: Replace `any` with type\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst UPDATE_CHECKS: ((txMeta: TransactionMeta) => any)[] = [\n (txMeta) => txMeta.status,\n (txMeta) => txMeta.txParams.gasUsed,\n];\n\n/**\n * Configuration options for the IncomingTransactionHelper\n *\n * @property includeTokenTransfers - Whether or not to include ERC20 token transfers.\n * @property isEnabled - Whether or not incoming transaction retrieval is enabled.\n * @property queryEntireHistory - Whether to initially query the entire transaction history or only recent blocks.\n * @property updateTransactions - Whether to update local transactions using remote transaction data.\n */\nexport type IncomingTransactionOptions = {\n includeTokenTransfers?: boolean;\n isEnabled?: () => boolean;\n queryEntireHistory?: boolean;\n updateTransactions?: boolean;\n};\n\nexport class IncomingTransactionHelper {\n hub: EventEmitter;\n\n #blockTracker: BlockTracker;\n\n #getCurrentAccount: () => ReturnType<\n AccountsController['getSelectedAccount']\n >;\n\n #getLastFetchedBlockNumbers: () => Record<string, number>;\n\n #getLocalTransactions: () => TransactionMeta[];\n\n #getChainId: () => Hex;\n\n #isEnabled: () => boolean;\n\n #isRunning: boolean;\n\n #log: debug.Debugger;\n\n #mutex = new Mutex();\n\n #onLatestBlock: (blockNumberHex: Hex) => Promise<void>;\n\n #queryEntireHistory: boolean;\n\n #remoteTransactionSource: RemoteTransactionSource;\n\n #transactionLimit?: number;\n\n #updateTransactions: boolean;\n\n constructor({\n blockTracker,\n getCurrentAccount,\n getLastFetchedBlockNumbers,\n getLocalTransactions,\n getChainId,\n isEnabled,\n queryEntireHistory,\n remoteTransactionSource,\n transactionLimit,\n updateTransactions,\n }: {\n blockTracker: BlockTracker;\n getCurrentAccount: () => ReturnType<\n AccountsController['getSelectedAccount']\n >;\n getLastFetchedBlockNumbers: () => Record<string, number>;\n getLocalTransactions?: () => TransactionMeta[];\n getChainId: () => Hex;\n isEnabled?: () => boolean;\n queryEntireHistory?: boolean;\n remoteTransactionSource: RemoteTransactionSource;\n transactionLimit?: number;\n updateTransactions?: boolean;\n }) {\n this.hub = new EventEmitter();\n\n this.#blockTracker = blockTracker;\n this.#getCurrentAccount = getCurrentAccount;\n this.#getLastFetchedBlockNumbers = getLastFetchedBlockNumbers;\n this.#getLocalTransactions = getLocalTransactions || (() => []);\n this.#getChainId = getChainId;\n this.#isEnabled = isEnabled ?? (() => true);\n this.#isRunning = false;\n this.#log = createModuleLogger(log, getChainId());\n this.#queryEntireHistory = queryEntireHistory ?? true;\n this.#remoteTransactionSource = remoteTransactionSource;\n this.#transactionLimit = transactionLimit;\n this.#updateTransactions = updateTransactions ?? false;\n\n // Using a property instead of a method to provide a listener reference\n // with the correct scope that we can remove later if stopped.\n this.#onLatestBlock = async (blockNumberHex: Hex) => {\n try {\n await this.update(blockNumberHex);\n } catch (error) {\n console.error('Error while checking incoming transactions', error);\n }\n };\n }\n\n start() {\n if (this.#isRunning) {\n return;\n }\n\n if (!this.#canStart()) {\n return;\n }\n\n this.#log('Starting polling');\n\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.#blockTracker.addListener('latest', this.#onLatestBlock);\n this.#isRunning = true;\n }\n\n stop() {\n if (!this.#isRunning) {\n return;\n }\n\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.#blockTracker.removeListener('latest', this.#onLatestBlock);\n this.#isRunning = false;\n\n this.#log('Stopped polling');\n }\n\n async update(latestBlockNumberHex?: Hex): Promise<void> {\n const releaseLock = await this.#mutex.acquire();\n\n this.#log('Checking');\n\n try {\n if (!this.#canStart()) {\n return;\n }\n\n const latestBlockNumber = parseInt(\n latestBlockNumberHex || (await this.#blockTracker.getLatestBlock()),\n 16,\n );\n\n const additionalLastFetchedKeys =\n this.#remoteTransactionSource.getLastBlockVariations?.() ?? [];\n\n const fromBlock = this.#getFromBlock(latestBlockNumber);\n const account = this.#getCurrentAccount();\n const currentChainId = this.#getChainId();\n\n let remoteTransactions = [];\n\n try {\n remoteTransactions =\n await this.#remoteTransactionSource.fetchTransactions({\n address: account.address,\n currentChainId,\n fromBlock,\n limit: this.#transactionLimit,\n });\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n this.#log('Error while fetching remote transactions', error);\n return;\n }\n if (!this.#updateTransactions) {\n const address = account.address.toLowerCase();\n remoteTransactions = remoteTransactions.filter(\n (tx) => tx.txParams.to?.toLowerCase() === address,\n );\n }\n\n const localTransactions = !this.#updateTransactions\n ? []\n : this.#getLocalTransactions();\n\n const newTransactions = this.#getNewTransactions(\n remoteTransactions,\n localTransactions,\n );\n\n const updatedTransactions = this.#getUpdatedTransactions(\n remoteTransactions,\n localTransactions,\n );\n\n if (newTransactions.length > 0 || updatedTransactions.length > 0) {\n this.#sortTransactionsByTime(newTransactions);\n this.#sortTransactionsByTime(updatedTransactions);\n\n this.#log('Found incoming transactions', {\n new: newTransactions,\n updated: updatedTransactions,\n });\n\n this.hub.emit('transactions', {\n added: newTransactions,\n updated: updatedTransactions,\n });\n }\n this.#updateLastFetchedBlockNumber(\n remoteTransactions,\n additionalLastFetchedKeys,\n );\n } finally {\n releaseLock();\n }\n }\n\n #sortTransactionsByTime(transactions: TransactionMeta[]) {\n transactions.sort((a, b) => (a.time < b.time ? -1 : 1));\n }\n\n #getNewTransactions(\n remoteTxs: TransactionMeta[],\n localTxs: TransactionMeta[],\n ): TransactionMeta[] {\n return remoteTxs.filter(\n (tx) => !localTxs.some(({ hash }) => hash === tx.hash),\n );\n }\n\n #getUpdatedTransactions(\n remoteTxs: TransactionMeta[],\n localTxs: TransactionMeta[],\n ): TransactionMeta[] {\n return remoteTxs.filter((remoteTx) =>\n localTxs.some(\n (localTx) =>\n remoteTx.hash === localTx.hash &&\n this.#isTransactionOutdated(remoteTx, localTx),\n ),\n );\n }\n\n #isTransactionOutdated(\n remoteTx: TransactionMeta,\n localTx: TransactionMeta,\n ): boolean {\n return UPDATE_CHECKS.some(\n (getValue) => getValue(remoteTx) !== getValue(localTx),\n );\n }\n\n #getLastFetchedBlockNumberDec(): number {\n const additionalLastFetchedKeys =\n this.#remoteTransactionSource.getLastBlockVariations?.() ?? [];\n const lastFetchedKey = this.#getBlockNumberKey(additionalLastFetchedKeys);\n const lastFetchedBlockNumbers = this.#getLastFetchedBlockNumbers();\n return lastFetchedBlockNumbers[lastFetchedKey];\n }\n\n #getFromBlock(latestBlockNumber: number): number | undefined {\n const lastFetchedBlockNumber = this.#getLastFetchedBlockNumberDec();\n\n if (lastFetchedBlockNumber) {\n return lastFetchedBlockNumber + 1;\n }\n\n return this.#queryEntireHistory\n ? undefined\n : latestBlockNumber - RECENT_HISTORY_BLOCK_RANGE;\n }\n\n #updateLastFetchedBlockNumber(\n remoteTxs: TransactionMeta[],\n additionalKeys: string[],\n ) {\n let lastFetchedBlockNumber = -1;\n\n for (const tx of remoteTxs) {\n const currentBlockNumberValue = tx.blockNumber\n ? parseInt(tx.blockNumber, 10)\n : -1;\n\n lastFetchedBlockNumber = Math.max(\n lastFetchedBlockNumber,\n currentBlockNumberValue,\n );\n }\n\n if (lastFetchedBlockNumber === -1) {\n return;\n }\n\n const lastFetchedKey = this.#getBlockNumberKey(additionalKeys);\n const lastFetchedBlockNumbers = this.#getLastFetchedBlockNumbers();\n const previousValue = lastFetchedBlockNumbers[lastFetchedKey];\n\n if (previousValue >= lastFetchedBlockNumber) {\n return;\n }\n\n this.hub.emit('updatedLastFetchedBlockNumbers', {\n lastFetchedBlockNumbers: {\n ...lastFetchedBlockNumbers,\n [lastFetchedKey]: lastFetchedBlockNumber,\n },\n blockNumber: lastFetchedBlockNumber,\n });\n }\n\n #getBlockNumberKey(additionalKeys: string[]): string {\n const currentChainId = this.#getChainId();\n const currentAccount = this.#getCurrentAccount()?.address.toLowerCase();\n\n return [currentChainId, currentAccount, ...additionalKeys].join('#');\n }\n\n #canStart(): boolean {\n const isEnabled = this.#isEnabled();\n const currentChainId = this.#getChainId();\n\n const isSupportedNetwork =\n this.#remoteTransactionSource.isSupportedNetwork(currentChainId);\n\n return isEnabled && isSupportedNetwork;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"IncomingTransactionHelper.d.cts","sourceRoot":"","sources":["../../src/helpers/IncomingTransactionHelper.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,sCAAsC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,qCAAqC;AACjE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAE3C,OAAO,YAAY,eAAe;AAGlC,OAAO,KAAK,EAAE,uBAAuB,EAAE,eAAe,EAAE,qBAAiB;AAWzE;;;;;;;GAOG;AACH,MAAM,MAAM,0BAA0B,GAAG;IACvC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;IAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF,qBAAa,yBAAyB;;IACpC,GAAG,EAAE,YAAY,CAAC;gBA8BN,EACV,YAAY,EACZ,iBAAiB,EACjB,0BAA0B,EAC1B,oBAAoB,EACpB,UAAU,EACV,SAAS,EACT,kBAAkB,EAClB,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,GACnB,EAAE;QACD,YAAY,EAAE,YAAY,CAAC;QAC3B,iBAAiB,EAAE,MAAM,UAAU,CACjC,kBAAkB,CAAC,oBAAoB,CAAC,CACzC,CAAC;QACF,0BAA0B,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACzD,oBAAoB,CAAC,EAAE,MAAM,eAAe,EAAE,CAAC;QAC/C,UAAU,EAAE,MAAM,GAAG,CAAC;QACtB,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;QAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B,uBAAuB,EAAE,uBAAuB,CAAC;QACjD,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;KAC9B;IA0BD,KAAK;IAeL,IAAI;IAOE,MAAM,CAAC,oBAAoB,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;CA+LxD"}
1
+ {"version":3,"file":"IncomingTransactionHelper.d.cts","sourceRoot":"","sources":["../../src/helpers/IncomingTransactionHelper.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,sCAAsC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,qCAAqC;AACjE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAE3C,OAAO,YAAY,eAAe;AAMlC,OAAO,KAAK,EAAE,uBAAuB,EAAE,eAAe,EAAE,qBAAiB;AAWzE;;;;;;;GAOG;AACH,MAAM,MAAM,0BAA0B,GAAG;IACvC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;IAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF,qBAAa,yBAAyB;;IACpC,GAAG,EAAE,YAAY,CAAC;gBAgCN,EACV,YAAY,EACZ,iBAAiB,EACjB,0BAA0B,EAC1B,oBAAoB,EACpB,UAAU,EACV,SAAS,EACT,kBAAkB,EAClB,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,GACnB,EAAE;QACD,YAAY,EAAE,YAAY,CAAC;QAC3B,iBAAiB,EAAE,MAAM,UAAU,CACjC,kBAAkB,CAAC,oBAAoB,CAAC,CACzC,CAAC;QACF,0BAA0B,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACzD,oBAAoB,CAAC,EAAE,MAAM,eAAe,EAAE,CAAC;QAC/C,UAAU,EAAE,MAAM,GAAG,CAAC;QACtB,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;QAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B,uBAAuB,EAAE,uBAAuB,CAAC;QACjD,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;KAC9B;IA2BD,KAAK;IAiBL,IAAI;IAaE,MAAM,CAAC,oBAAoB,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;CA+LxD"}
@@ -1 +1 @@
1
- {"version":3,"file":"IncomingTransactionHelper.d.mts","sourceRoot":"","sources":["../../src/helpers/IncomingTransactionHelper.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,sCAAsC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,qCAAqC;AACjE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAE3C,OAAO,YAAY,eAAe;AAGlC,OAAO,KAAK,EAAE,uBAAuB,EAAE,eAAe,EAAE,qBAAiB;AAWzE;;;;;;;GAOG;AACH,MAAM,MAAM,0BAA0B,GAAG;IACvC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;IAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF,qBAAa,yBAAyB;;IACpC,GAAG,EAAE,YAAY,CAAC;gBA8BN,EACV,YAAY,EACZ,iBAAiB,EACjB,0BAA0B,EAC1B,oBAAoB,EACpB,UAAU,EACV,SAAS,EACT,kBAAkB,EAClB,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,GACnB,EAAE;QACD,YAAY,EAAE,YAAY,CAAC;QAC3B,iBAAiB,EAAE,MAAM,UAAU,CACjC,kBAAkB,CAAC,oBAAoB,CAAC,CACzC,CAAC;QACF,0BAA0B,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACzD,oBAAoB,CAAC,EAAE,MAAM,eAAe,EAAE,CAAC;QAC/C,UAAU,EAAE,MAAM,GAAG,CAAC;QACtB,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;QAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B,uBAAuB,EAAE,uBAAuB,CAAC;QACjD,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;KAC9B;IA0BD,KAAK;IAeL,IAAI;IAOE,MAAM,CAAC,oBAAoB,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;CA+LxD"}
1
+ {"version":3,"file":"IncomingTransactionHelper.d.mts","sourceRoot":"","sources":["../../src/helpers/IncomingTransactionHelper.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,sCAAsC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,qCAAqC;AACjE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAE3C,OAAO,YAAY,eAAe;AAMlC,OAAO,KAAK,EAAE,uBAAuB,EAAE,eAAe,EAAE,qBAAiB;AAWzE;;;;;;;GAOG;AACH,MAAM,MAAM,0BAA0B,GAAG;IACvC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;IAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF,qBAAa,yBAAyB;;IACpC,GAAG,EAAE,YAAY,CAAC;gBAgCN,EACV,YAAY,EACZ,iBAAiB,EACjB,0BAA0B,EAC1B,oBAAoB,EACpB,UAAU,EACV,SAAS,EACT,kBAAkB,EAClB,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,GACnB,EAAE;QACD,YAAY,EAAE,YAAY,CAAC;QAC3B,iBAAiB,EAAE,MAAM,UAAU,CACjC,kBAAkB,CAAC,oBAAoB,CAAC,CACzC,CAAC;QACF,0BAA0B,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACzD,oBAAoB,CAAC,EAAE,MAAM,eAAe,EAAE,CAAC;QAC/C,UAAU,EAAE,MAAM,GAAG,CAAC;QACtB,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;QAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B,uBAAuB,EAAE,uBAAuB,CAAC;QACjD,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;KAC9B;IA2BD,KAAK;IAiBL,IAAI;IAaE,MAAM,CAAC,oBAAoB,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;CA+LxD"}