@metamask/transaction-controller 46.0.0 → 47.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +31 -1
- package/dist/TransactionController.cjs +121 -40
- package/dist/TransactionController.cjs.map +1 -1
- package/dist/TransactionController.d.cts +81 -72
- package/dist/TransactionController.d.cts.map +1 -1
- package/dist/TransactionController.d.mts +81 -72
- package/dist/TransactionController.d.mts.map +1 -1
- package/dist/TransactionController.mjs +122 -41
- package/dist/TransactionController.mjs.map +1 -1
- package/dist/api/accounts-api.cjs +2 -0
- package/dist/api/accounts-api.cjs.map +1 -1
- package/dist/api/accounts-api.d.cts +2 -0
- package/dist/api/accounts-api.d.cts.map +1 -1
- package/dist/api/accounts-api.d.mts +2 -0
- package/dist/api/accounts-api.d.mts.map +1 -1
- package/dist/api/accounts-api.mjs +2 -0
- package/dist/api/accounts-api.mjs.map +1 -1
- package/dist/constants.cjs +20 -1
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +15 -0
- package/dist/constants.d.cts.map +1 -1
- package/dist/constants.d.mts +15 -0
- package/dist/constants.d.mts.map +1 -1
- package/dist/constants.mjs +19 -0
- package/dist/constants.mjs.map +1 -1
- package/dist/gas-flows/LineaGasFeeFlow.cjs +1 -1
- package/dist/gas-flows/LineaGasFeeFlow.cjs.map +1 -1
- package/dist/gas-flows/LineaGasFeeFlow.d.cts.map +1 -1
- package/dist/gas-flows/LineaGasFeeFlow.d.mts.map +1 -1
- package/dist/gas-flows/LineaGasFeeFlow.mjs +1 -1
- package/dist/gas-flows/LineaGasFeeFlow.mjs.map +1 -1
- package/dist/gas-flows/OptimismLayer1GasFeeFlow.cjs +1 -1
- package/dist/gas-flows/OptimismLayer1GasFeeFlow.cjs.map +1 -1
- package/dist/gas-flows/OptimismLayer1GasFeeFlow.d.cts +1 -1
- package/dist/gas-flows/OptimismLayer1GasFeeFlow.d.cts.map +1 -1
- package/dist/gas-flows/OptimismLayer1GasFeeFlow.d.mts +1 -1
- package/dist/gas-flows/OptimismLayer1GasFeeFlow.d.mts.map +1 -1
- package/dist/gas-flows/OptimismLayer1GasFeeFlow.mjs +1 -1
- package/dist/gas-flows/OptimismLayer1GasFeeFlow.mjs.map +1 -1
- package/dist/gas-flows/ScrollLayer1GasFeeFlow.cjs +1 -1
- package/dist/gas-flows/ScrollLayer1GasFeeFlow.cjs.map +1 -1
- package/dist/gas-flows/ScrollLayer1GasFeeFlow.d.cts +1 -1
- package/dist/gas-flows/ScrollLayer1GasFeeFlow.d.cts.map +1 -1
- package/dist/gas-flows/ScrollLayer1GasFeeFlow.d.mts +1 -1
- package/dist/gas-flows/ScrollLayer1GasFeeFlow.d.mts.map +1 -1
- package/dist/gas-flows/ScrollLayer1GasFeeFlow.mjs +1 -1
- package/dist/gas-flows/ScrollLayer1GasFeeFlow.mjs.map +1 -1
- package/dist/helpers/GasFeePoller.cjs +1 -0
- package/dist/helpers/GasFeePoller.cjs.map +1 -1
- package/dist/helpers/GasFeePoller.d.cts +1 -0
- package/dist/helpers/GasFeePoller.d.cts.map +1 -1
- package/dist/helpers/GasFeePoller.d.mts +1 -0
- package/dist/helpers/GasFeePoller.d.mts.map +1 -1
- package/dist/helpers/GasFeePoller.mjs +1 -0
- package/dist/helpers/GasFeePoller.mjs.map +1 -1
- package/dist/helpers/IncomingTransactionHelper.cjs.map +1 -1
- package/dist/helpers/IncomingTransactionHelper.d.cts.map +1 -1
- package/dist/helpers/IncomingTransactionHelper.d.mts.map +1 -1
- package/dist/helpers/IncomingTransactionHelper.mjs.map +1 -1
- package/dist/helpers/MethodDataHelper.cjs.map +1 -1
- package/dist/helpers/MethodDataHelper.d.cts.map +1 -1
- package/dist/helpers/MethodDataHelper.d.mts.map +1 -1
- package/dist/helpers/MethodDataHelper.mjs.map +1 -1
- package/dist/helpers/MultichainTrackingHelper.cjs +1 -21
- package/dist/helpers/MultichainTrackingHelper.cjs.map +1 -1
- package/dist/helpers/MultichainTrackingHelper.d.cts.map +1 -1
- package/dist/helpers/MultichainTrackingHelper.d.mts.map +1 -1
- package/dist/helpers/MultichainTrackingHelper.mjs +1 -21
- package/dist/helpers/MultichainTrackingHelper.mjs.map +1 -1
- package/dist/helpers/PendingTransactionTracker.cjs.map +1 -1
- package/dist/helpers/PendingTransactionTracker.d.cts.map +1 -1
- package/dist/helpers/PendingTransactionTracker.d.mts.map +1 -1
- package/dist/helpers/PendingTransactionTracker.mjs.map +1 -1
- package/dist/helpers/TransactionPoller.cjs +2 -0
- package/dist/helpers/TransactionPoller.cjs.map +1 -1
- package/dist/helpers/TransactionPoller.d.cts +2 -0
- package/dist/helpers/TransactionPoller.d.cts.map +1 -1
- package/dist/helpers/TransactionPoller.d.mts +2 -0
- package/dist/helpers/TransactionPoller.d.mts.map +1 -1
- package/dist/helpers/TransactionPoller.mjs +2 -0
- package/dist/helpers/TransactionPoller.mjs.map +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/types.cjs +5 -0
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +51 -0
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +51 -0
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs +5 -0
- package/dist/types.mjs.map +1 -1
- package/dist/utils/batch.cjs +89 -0
- package/dist/utils/batch.cjs.map +1 -0
- package/dist/utils/batch.d.cts +33 -0
- package/dist/utils/batch.d.cts.map +1 -0
- package/dist/utils/batch.d.mts +33 -0
- package/dist/utils/batch.d.mts.map +1 -0
- package/dist/utils/batch.mjs +84 -0
- package/dist/utils/batch.mjs.map +1 -0
- package/dist/utils/eip7702.cjs +84 -2
- package/dist/utils/eip7702.cjs.map +1 -1
- package/dist/utils/eip7702.d.cts +35 -10
- package/dist/utils/eip7702.d.cts.map +1 -1
- package/dist/utils/eip7702.d.mts +35 -10
- package/dist/utils/eip7702.d.mts.map +1 -1
- package/dist/utils/eip7702.mjs +82 -3
- package/dist/utils/eip7702.mjs.map +1 -1
- package/dist/utils/feature-flags.cjs +53 -0
- package/dist/utils/feature-flags.cjs.map +1 -0
- package/dist/utils/feature-flags.d.cts +39 -0
- package/dist/utils/feature-flags.d.cts.map +1 -0
- package/dist/utils/feature-flags.d.mts +39 -0
- package/dist/utils/feature-flags.d.mts.map +1 -0
- package/dist/utils/feature-flags.mjs +47 -0
- package/dist/utils/feature-flags.mjs.map +1 -0
- package/dist/utils/gas-fees.cjs +48 -3
- package/dist/utils/gas-fees.cjs.map +1 -1
- package/dist/utils/gas-fees.d.cts +11 -0
- package/dist/utils/gas-fees.d.cts.map +1 -1
- package/dist/utils/gas-fees.d.mts +11 -0
- package/dist/utils/gas-fees.d.mts.map +1 -1
- package/dist/utils/gas-fees.mjs +48 -3
- package/dist/utils/gas-fees.mjs.map +1 -1
- package/dist/utils/gas-flow.cjs +4 -0
- package/dist/utils/gas-flow.cjs.map +1 -1
- package/dist/utils/gas-flow.d.cts +1 -0
- package/dist/utils/gas-flow.d.cts.map +1 -1
- package/dist/utils/gas-flow.d.mts +1 -0
- package/dist/utils/gas-flow.d.mts.map +1 -1
- package/dist/utils/gas-flow.mjs +4 -0
- package/dist/utils/gas-flow.mjs.map +1 -1
- package/dist/utils/gas.cjs +50 -1
- package/dist/utils/gas.cjs.map +1 -1
- package/dist/utils/gas.d.cts +22 -0
- package/dist/utils/gas.d.cts.map +1 -1
- package/dist/utils/gas.d.mts +22 -0
- package/dist/utils/gas.d.mts.map +1 -1
- package/dist/utils/gas.mjs +50 -1
- package/dist/utils/gas.mjs.map +1 -1
- package/dist/utils/layer1-gas-fee-flow.cjs +5 -1
- package/dist/utils/layer1-gas-fee-flow.cjs.map +1 -1
- package/dist/utils/layer1-gas-fee-flow.d.cts +4 -1
- package/dist/utils/layer1-gas-fee-flow.d.cts.map +1 -1
- package/dist/utils/layer1-gas-fee-flow.d.mts +4 -1
- package/dist/utils/layer1-gas-fee-flow.d.mts.map +1 -1
- package/dist/utils/layer1-gas-fee-flow.mjs +5 -1
- package/dist/utils/layer1-gas-fee-flow.mjs.map +1 -1
- package/dist/utils/retry.cjs +4 -0
- package/dist/utils/retry.cjs.map +1 -1
- package/dist/utils/retry.d.cts +1 -0
- package/dist/utils/retry.d.cts.map +1 -1
- package/dist/utils/retry.d.mts +1 -0
- package/dist/utils/retry.d.mts.map +1 -1
- package/dist/utils/retry.mjs +4 -0
- package/dist/utils/retry.mjs.map +1 -1
- package/dist/utils/simulation-api.cjs +6 -0
- package/dist/utils/simulation-api.cjs.map +1 -1
- package/dist/utils/simulation-api.d.cts +2 -0
- package/dist/utils/simulation-api.d.cts.map +1 -1
- package/dist/utils/simulation-api.d.mts +2 -0
- package/dist/utils/simulation-api.d.mts.map +1 -1
- package/dist/utils/simulation-api.mjs +6 -0
- package/dist/utils/simulation-api.mjs.map +1 -1
- package/dist/utils/simulation.cjs +19 -5
- package/dist/utils/simulation.cjs.map +1 -1
- package/dist/utils/simulation.d.cts +3 -1
- package/dist/utils/simulation.d.cts.map +1 -1
- package/dist/utils/simulation.d.mts +3 -1
- package/dist/utils/simulation.d.mts.map +1 -1
- package/dist/utils/simulation.mjs +19 -5
- package/dist/utils/simulation.mjs.map +1 -1
- package/dist/utils/swaps.cjs +2 -1
- package/dist/utils/swaps.cjs.map +1 -1
- package/dist/utils/swaps.d.cts +1 -0
- package/dist/utils/swaps.d.cts.map +1 -1
- package/dist/utils/swaps.d.mts +1 -0
- package/dist/utils/swaps.d.mts.map +1 -1
- package/dist/utils/swaps.mjs +2 -1
- package/dist/utils/swaps.mjs.map +1 -1
- package/dist/utils/transaction-type.cjs +3 -1
- package/dist/utils/transaction-type.cjs.map +1 -1
- package/dist/utils/transaction-type.mjs +3 -1
- package/dist/utils/transaction-type.mjs.map +1 -1
- package/dist/utils/validation.cjs +34 -5
- package/dist/utils/validation.cjs.map +1 -1
- package/dist/utils/validation.d.cts +19 -3
- package/dist/utils/validation.d.cts.map +1 -1
- package/dist/utils/validation.d.mts +19 -3
- package/dist/utils/validation.d.mts.map +1 -1
- package/dist/utils/validation.mjs +33 -5
- package/dist/utils/validation.mjs.map +1 -1
- package/package.json +7 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultichainTrackingHelper.mjs","sourceRoot":"","sources":["../../src/helpers/MultichainTrackingHelper.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n NetworkClientId,\n NetworkController,\n NetworkClient,\n BlockTracker,\n Provider,\n NetworkControllerStateChangeEvent,\n} from '@metamask/network-controller';\nimport type { NonceLock, NonceTracker } from '@metamask/nonce-tracker';\nimport type { Hex } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\n\nimport type { PendingTransactionTracker } from './PendingTransactionTracker';\nimport { createModuleLogger, projectLogger } from '../logger';\n\n/**\n * Registry of network clients provided by the NetworkController\n */\ntype NetworkClientRegistry = ReturnType<\n NetworkController['getNetworkClientRegistry']\n>;\n\nconst log = createModuleLogger(projectLogger, 'multichain-tracking');\n\nexport type MultichainTrackingHelperOptions = {\n findNetworkClientIdByChainId: NetworkController['findNetworkClientIdByChainId'];\n getNetworkClientById: NetworkController['getNetworkClientById'];\n getNetworkClientRegistry: NetworkController['getNetworkClientRegistry'];\n\n removePendingTransactionTrackerListeners: (\n pendingTransactionTracker: PendingTransactionTracker,\n ) => void;\n createNonceTracker: (opts: {\n provider: Provider;\n blockTracker: BlockTracker;\n chainId: Hex;\n }) => NonceTracker;\n createPendingTransactionTracker: (opts: {\n provider: Provider;\n blockTracker: BlockTracker;\n chainId: Hex;\n networkClientId: NetworkClientId;\n }) => PendingTransactionTracker;\n onNetworkStateChange: (\n listener: (\n ...payload: NetworkControllerStateChangeEvent['payload']\n ) => void,\n ) => void;\n};\n\nexport class MultichainTrackingHelper {\n readonly #findNetworkClientIdByChainId: NetworkController['findNetworkClientIdByChainId'];\n\n readonly #getNetworkClientById: NetworkController['getNetworkClientById'];\n\n readonly #getNetworkClientRegistry: NetworkController['getNetworkClientRegistry'];\n\n readonly #removePendingTransactionTrackerListeners: (\n pendingTransactionTracker: PendingTransactionTracker,\n ) => void;\n\n readonly #createNonceTracker: (opts: {\n provider: Provider;\n blockTracker: BlockTracker;\n chainId: Hex;\n }) => NonceTracker;\n\n readonly #createPendingTransactionTracker: (opts: {\n provider: Provider;\n blockTracker: BlockTracker;\n chainId: Hex;\n networkClientId: NetworkClientId;\n }) => PendingTransactionTracker;\n\n readonly #nonceMutexesByChainId = new Map<Hex, Map<string, Mutex>>();\n\n readonly #trackingMap: Map<\n NetworkClientId,\n {\n nonceTracker: NonceTracker;\n pendingTransactionTracker: PendingTransactionTracker;\n }\n > = new Map();\n\n constructor({\n findNetworkClientIdByChainId,\n getNetworkClientById,\n getNetworkClientRegistry,\n removePendingTransactionTrackerListeners,\n createNonceTracker,\n createPendingTransactionTracker,\n onNetworkStateChange,\n }: MultichainTrackingHelperOptions) {\n this.#findNetworkClientIdByChainId = findNetworkClientIdByChainId;\n this.#getNetworkClientById = getNetworkClientById;\n this.#getNetworkClientRegistry = getNetworkClientRegistry;\n\n this.#removePendingTransactionTrackerListeners =\n removePendingTransactionTrackerListeners;\n this.#createNonceTracker = createNonceTracker;\n this.#createPendingTransactionTracker = createPendingTransactionTracker;\n\n onNetworkStateChange((_, patches) => {\n const networkClients = this.#getNetworkClientRegistry();\n\n patches.forEach(({ op, path }) => {\n if (op === 'remove' && path[0] === 'networkConfigurations') {\n const networkClientId = path[1] as NetworkClientId;\n delete networkClients[networkClientId];\n }\n });\n\n this.#refreshTrackingMap(networkClients);\n });\n }\n\n initialize() {\n const networkClients = this.#getNetworkClientRegistry();\n\n this.#refreshTrackingMap(networkClients);\n\n log('Initialized');\n }\n\n has(networkClientId: NetworkClientId) {\n return this.#trackingMap.has(networkClientId);\n }\n\n /**\n * Gets the mutex intended to guard the nonceTracker for a particular chainId and key .\n *\n * @param opts - The options object.\n * @param opts.chainId - The hex chainId.\n * @param opts.key - The hex address (or constant) pertaining to the chainId\n * @returns Mutex instance for the given chainId and key pair\n */\n async acquireNonceLockForChainIdKey({\n chainId,\n key = 'global',\n }: {\n chainId: Hex;\n key?: string;\n }): Promise<() => void> {\n let nonceMutexesForChainId = this.#nonceMutexesByChainId.get(chainId);\n if (!nonceMutexesForChainId) {\n nonceMutexesForChainId = new Map<string, Mutex>();\n this.#nonceMutexesByChainId.set(chainId, nonceMutexesForChainId);\n }\n let nonceMutexForKey = nonceMutexesForChainId.get(key);\n if (!nonceMutexForKey) {\n nonceMutexForKey = new Mutex();\n nonceMutexesForChainId.set(key, nonceMutexForKey);\n }\n\n return await nonceMutexForKey.acquire();\n }\n\n /**\n * Gets the next nonce according to the nonce-tracker.\n * Ensure `releaseLock` is called once processing of the `nonce` value is complete.\n *\n * @param address - The hex string address for the transaction.\n * @param networkClientId - The network client ID for the transaction, used to fetch the correct nonce tracker.\n * @returns object with the `nextNonce` `nonceDetails`, and the releaseLock.\n */\n async getNonceLock(\n address: string,\n networkClientId: NetworkClientId,\n ): Promise<NonceLock> {\n const networkClient = this.#getNetworkClientById(networkClientId);\n\n const releaseLockForChainIdKey = await this.acquireNonceLockForChainIdKey({\n chainId: networkClient.configuration.chainId,\n key: address,\n });\n\n const nonceTracker = this.#trackingMap.get(networkClientId)?.nonceTracker;\n\n if (!nonceTracker) {\n throw new Error(\n `Missing nonce tracker for network client ID - ${\n networkClientId as string\n }`,\n );\n }\n\n // Acquires the lock for the chainId + address and the nonceLock from the nonceTracker, then\n // couples them together by replacing the nonceLock's releaseLock method with\n // an anonymous function that calls releases both the original nonceLock and the\n // lock for the chainId.\n try {\n const nonceLock = await nonceTracker.getNonceLock(address);\n\n const releaseLock = () => {\n nonceLock.releaseLock();\n releaseLockForChainIdKey?.();\n };\n\n return {\n ...nonceLock,\n releaseLock,\n };\n } catch (err) {\n releaseLockForChainIdKey?.();\n throw err;\n }\n }\n\n checkForPendingTransactionAndStartPolling = () => {\n for (const [, trackers] of this.#trackingMap) {\n trackers.pendingTransactionTracker.startIfPendingTransactions();\n }\n };\n\n stopAllTracking() {\n for (const [networkClientId] of this.#trackingMap) {\n this.#stopTrackingByNetworkClientId(networkClientId);\n }\n }\n\n getNetworkClient({\n chainId,\n networkClientId: requestNetworkClientId,\n }: {\n chainId?: Hex;\n networkClientId?: NetworkClientId;\n }): NetworkClient & { id: NetworkClientId } {\n if (!requestNetworkClientId && !chainId) {\n throw new Error(\n 'Cannot locate network client without networkClientId or chainId',\n );\n }\n\n let networkClient: NetworkClient | undefined;\n let networkClientId = requestNetworkClientId;\n\n try {\n if (requestNetworkClientId) {\n networkClient = this.#getNetworkClientById(requestNetworkClientId);\n }\n } catch (error) {\n log('No network client found with ID', requestNetworkClientId);\n\n if (!chainId) {\n throw error;\n }\n }\n\n if (!networkClient && chainId) {\n networkClientId = this.#findNetworkClientIdByChainId(chainId);\n networkClient = this.#getNetworkClientById(networkClientId);\n }\n\n return {\n ...(networkClient as NetworkClient),\n id: networkClientId as NetworkClientId,\n };\n }\n\n #refreshTrackingMap = (networkClients: NetworkClientRegistry) => {\n const networkClientIds = Object.keys(networkClients);\n const existingNetworkClientIds = Array.from(this.#trackingMap.keys());\n\n // Remove tracking for NetworkClientIds that no longer exist\n const networkClientIdsToRemove = existingNetworkClientIds.filter(\n (id) => !networkClientIds.includes(id),\n );\n\n networkClientIdsToRemove.forEach((id) => {\n this.#stopTrackingByNetworkClientId(id);\n });\n\n // Start tracking new NetworkClientIds from the registry\n const networkClientIdsToAdd = networkClientIds.filter(\n (id) => !existingNetworkClientIds.includes(id),\n );\n\n networkClientIdsToAdd.forEach((id) => {\n this.#startTrackingByNetworkClientId(id);\n });\n\n if (networkClientIdsToAdd.length) {\n log('Added trackers', networkClientIdsToAdd);\n }\n\n if (networkClientIdsToRemove.length) {\n log('Removed trackers', networkClientIdsToRemove);\n }\n };\n\n #stopTrackingByNetworkClientId(networkClientId: NetworkClientId) {\n const trackers = this.#trackingMap.get(networkClientId);\n if (trackers) {\n trackers.pendingTransactionTracker.stop();\n this.#removePendingTransactionTrackerListeners(\n trackers.pendingTransactionTracker,\n );\n this.#trackingMap.delete(networkClientId);\n }\n }\n\n #startTrackingByNetworkClientId(networkClientId: NetworkClientId) {\n const trackers = this.#trackingMap.get(networkClientId);\n if (trackers) {\n return;\n }\n\n const {\n provider,\n blockTracker,\n configuration: { chainId },\n } = this.#getNetworkClientById(networkClientId);\n\n const nonceTracker = this.#createNonceTracker({\n provider,\n blockTracker,\n chainId,\n });\n\n const pendingTransactionTracker = this.#createPendingTransactionTracker({\n provider,\n blockTracker,\n chainId,\n networkClientId,\n });\n\n this.#trackingMap.set(networkClientId, {\n nonceTracker,\n pendingTransactionTracker,\n });\n }\n\n #getNetworkClient({\n networkClientId,\n chainId,\n }: {\n networkClientId?: NetworkClientId;\n chainId?: Hex;\n } = {}): NetworkClient | undefined {\n let networkClient: NetworkClient | undefined;\n\n if (networkClientId) {\n try {\n networkClient = this.#getNetworkClientById(networkClientId);\n } catch (err) {\n log('failed to get network client by networkClientId');\n }\n }\n if (!networkClient && chainId) {\n try {\n const networkClientIdForChainId =\n this.#findNetworkClientIdByChainId(chainId);\n networkClient = this.#getNetworkClientById(networkClientIdForChainId);\n } catch (err) {\n log('failed to get network client by chainId');\n }\n }\n return networkClient;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"MultichainTrackingHelper.mjs","sourceRoot":"","sources":["../../src/helpers/MultichainTrackingHelper.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n NetworkClientId,\n NetworkController,\n NetworkClient,\n BlockTracker,\n Provider,\n NetworkControllerStateChangeEvent,\n} from '@metamask/network-controller';\nimport type { NonceLock, NonceTracker } from '@metamask/nonce-tracker';\nimport type { Hex } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\n\nimport type { PendingTransactionTracker } from './PendingTransactionTracker';\nimport { createModuleLogger, projectLogger } from '../logger';\n\n/**\n * Registry of network clients provided by the NetworkController\n */\ntype NetworkClientRegistry = ReturnType<\n NetworkController['getNetworkClientRegistry']\n>;\n\nconst log = createModuleLogger(projectLogger, 'multichain-tracking');\n\nexport type MultichainTrackingHelperOptions = {\n findNetworkClientIdByChainId: NetworkController['findNetworkClientIdByChainId'];\n getNetworkClientById: NetworkController['getNetworkClientById'];\n getNetworkClientRegistry: NetworkController['getNetworkClientRegistry'];\n\n removePendingTransactionTrackerListeners: (\n pendingTransactionTracker: PendingTransactionTracker,\n ) => void;\n createNonceTracker: (opts: {\n provider: Provider;\n blockTracker: BlockTracker;\n chainId: Hex;\n }) => NonceTracker;\n createPendingTransactionTracker: (opts: {\n provider: Provider;\n blockTracker: BlockTracker;\n chainId: Hex;\n networkClientId: NetworkClientId;\n }) => PendingTransactionTracker;\n onNetworkStateChange: (\n listener: (\n ...payload: NetworkControllerStateChangeEvent['payload']\n ) => void,\n ) => void;\n};\n\nexport class MultichainTrackingHelper {\n readonly #findNetworkClientIdByChainId: NetworkController['findNetworkClientIdByChainId'];\n\n readonly #getNetworkClientById: NetworkController['getNetworkClientById'];\n\n readonly #getNetworkClientRegistry: NetworkController['getNetworkClientRegistry'];\n\n readonly #removePendingTransactionTrackerListeners: (\n pendingTransactionTracker: PendingTransactionTracker,\n ) => void;\n\n readonly #createNonceTracker: (opts: {\n provider: Provider;\n blockTracker: BlockTracker;\n chainId: Hex;\n }) => NonceTracker;\n\n readonly #createPendingTransactionTracker: (opts: {\n provider: Provider;\n blockTracker: BlockTracker;\n chainId: Hex;\n networkClientId: NetworkClientId;\n }) => PendingTransactionTracker;\n\n readonly #nonceMutexesByChainId = new Map<Hex, Map<string, Mutex>>();\n\n readonly #trackingMap: Map<\n NetworkClientId,\n {\n nonceTracker: NonceTracker;\n pendingTransactionTracker: PendingTransactionTracker;\n }\n > = new Map();\n\n constructor({\n findNetworkClientIdByChainId,\n getNetworkClientById,\n getNetworkClientRegistry,\n removePendingTransactionTrackerListeners,\n createNonceTracker,\n createPendingTransactionTracker,\n onNetworkStateChange,\n }: MultichainTrackingHelperOptions) {\n this.#findNetworkClientIdByChainId = findNetworkClientIdByChainId;\n this.#getNetworkClientById = getNetworkClientById;\n this.#getNetworkClientRegistry = getNetworkClientRegistry;\n\n this.#removePendingTransactionTrackerListeners =\n removePendingTransactionTrackerListeners;\n this.#createNonceTracker = createNonceTracker;\n this.#createPendingTransactionTracker = createPendingTransactionTracker;\n\n onNetworkStateChange((_, patches) => {\n const networkClients = this.#getNetworkClientRegistry();\n\n patches.forEach(({ op, path }) => {\n if (op === 'remove' && path[0] === 'networkConfigurations') {\n const networkClientId = path[1] as NetworkClientId;\n delete networkClients[networkClientId];\n }\n });\n\n this.#refreshTrackingMap(networkClients);\n });\n }\n\n initialize() {\n const networkClients = this.#getNetworkClientRegistry();\n\n this.#refreshTrackingMap(networkClients);\n\n log('Initialized');\n }\n\n has(networkClientId: NetworkClientId) {\n return this.#trackingMap.has(networkClientId);\n }\n\n /**\n * Gets the mutex intended to guard the nonceTracker for a particular chainId and key .\n *\n * @param opts - The options object.\n * @param opts.chainId - The hex chainId.\n * @param opts.key - The hex address (or constant) pertaining to the chainId\n * @returns Mutex instance for the given chainId and key pair\n */\n async acquireNonceLockForChainIdKey({\n chainId,\n key = 'global',\n }: {\n chainId: Hex;\n key?: string;\n }): Promise<() => void> {\n let nonceMutexesForChainId = this.#nonceMutexesByChainId.get(chainId);\n if (!nonceMutexesForChainId) {\n nonceMutexesForChainId = new Map<string, Mutex>();\n this.#nonceMutexesByChainId.set(chainId, nonceMutexesForChainId);\n }\n let nonceMutexForKey = nonceMutexesForChainId.get(key);\n if (!nonceMutexForKey) {\n nonceMutexForKey = new Mutex();\n nonceMutexesForChainId.set(key, nonceMutexForKey);\n }\n\n return await nonceMutexForKey.acquire();\n }\n\n /**\n * Gets the next nonce according to the nonce-tracker.\n * Ensure `releaseLock` is called once processing of the `nonce` value is complete.\n *\n * @param address - The hex string address for the transaction.\n * @param networkClientId - The network client ID for the transaction, used to fetch the correct nonce tracker.\n * @returns object with the `nextNonce` `nonceDetails`, and the releaseLock.\n */\n async getNonceLock(\n address: string,\n networkClientId: NetworkClientId,\n ): Promise<NonceLock> {\n const networkClient = this.#getNetworkClientById(networkClientId);\n\n const releaseLockForChainIdKey = await this.acquireNonceLockForChainIdKey({\n chainId: networkClient.configuration.chainId,\n key: address,\n });\n\n const nonceTracker = this.#trackingMap.get(networkClientId)?.nonceTracker;\n\n if (!nonceTracker) {\n throw new Error(\n `Missing nonce tracker for network client ID - ${\n networkClientId as string\n }`,\n );\n }\n\n // Acquires the lock for the chainId + address and the nonceLock from the nonceTracker, then\n // couples them together by replacing the nonceLock's releaseLock method with\n // an anonymous function that calls releases both the original nonceLock and the\n // lock for the chainId.\n try {\n const nonceLock = await nonceTracker.getNonceLock(address);\n\n const releaseLock = () => {\n nonceLock.releaseLock();\n releaseLockForChainIdKey?.();\n };\n\n return {\n ...nonceLock,\n releaseLock,\n };\n } catch (err) {\n releaseLockForChainIdKey?.();\n throw err;\n }\n }\n\n checkForPendingTransactionAndStartPolling = () => {\n for (const [, trackers] of this.#trackingMap) {\n trackers.pendingTransactionTracker.startIfPendingTransactions();\n }\n };\n\n stopAllTracking() {\n for (const [networkClientId] of this.#trackingMap) {\n this.#stopTrackingByNetworkClientId(networkClientId);\n }\n }\n\n getNetworkClient({\n chainId,\n networkClientId: requestNetworkClientId,\n }: {\n chainId?: Hex;\n networkClientId?: NetworkClientId;\n }): NetworkClient & { id: NetworkClientId } {\n if (!requestNetworkClientId && !chainId) {\n throw new Error(\n 'Cannot locate network client without networkClientId or chainId',\n );\n }\n\n let networkClient: NetworkClient | undefined;\n let networkClientId = requestNetworkClientId;\n\n try {\n if (requestNetworkClientId) {\n networkClient = this.#getNetworkClientById(requestNetworkClientId);\n }\n } catch (error) {\n log('No network client found with ID', requestNetworkClientId);\n\n if (!chainId) {\n throw error;\n }\n }\n\n if (!networkClient && chainId) {\n networkClientId = this.#findNetworkClientIdByChainId(chainId);\n networkClient = this.#getNetworkClientById(networkClientId);\n }\n\n return {\n ...(networkClient as NetworkClient),\n id: networkClientId as NetworkClientId,\n };\n }\n\n readonly #refreshTrackingMap = (networkClients: NetworkClientRegistry) => {\n const networkClientIds = Object.keys(networkClients);\n const existingNetworkClientIds = Array.from(this.#trackingMap.keys());\n\n // Remove tracking for NetworkClientIds that no longer exist\n const networkClientIdsToRemove = existingNetworkClientIds.filter(\n (id) => !networkClientIds.includes(id),\n );\n\n networkClientIdsToRemove.forEach((id) => {\n this.#stopTrackingByNetworkClientId(id);\n });\n\n // Start tracking new NetworkClientIds from the registry\n const networkClientIdsToAdd = networkClientIds.filter(\n (id) => !existingNetworkClientIds.includes(id),\n );\n\n networkClientIdsToAdd.forEach((id) => {\n this.#startTrackingByNetworkClientId(id);\n });\n\n if (networkClientIdsToAdd.length) {\n log('Added trackers', networkClientIdsToAdd);\n }\n\n if (networkClientIdsToRemove.length) {\n log('Removed trackers', networkClientIdsToRemove);\n }\n };\n\n #stopTrackingByNetworkClientId(networkClientId: NetworkClientId) {\n const trackers = this.#trackingMap.get(networkClientId);\n if (trackers) {\n trackers.pendingTransactionTracker.stop();\n this.#removePendingTransactionTrackerListeners(\n trackers.pendingTransactionTracker,\n );\n this.#trackingMap.delete(networkClientId);\n }\n }\n\n #startTrackingByNetworkClientId(networkClientId: NetworkClientId) {\n const trackers = this.#trackingMap.get(networkClientId);\n if (trackers) {\n return;\n }\n\n const {\n provider,\n blockTracker,\n configuration: { chainId },\n } = this.#getNetworkClientById(networkClientId);\n\n const nonceTracker = this.#createNonceTracker({\n provider,\n blockTracker,\n chainId,\n });\n\n const pendingTransactionTracker = this.#createPendingTransactionTracker({\n provider,\n blockTracker,\n chainId,\n networkClientId,\n });\n\n this.#trackingMap.set(networkClientId, {\n nonceTracker,\n pendingTransactionTracker,\n });\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PendingTransactionTracker.cjs","sourceRoot":"","sources":["../../src/helpers/PendingTransactionTracker.ts"],"names":[],"mappings":"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","sourcesContent":["import { query } from '@metamask/controller-utils';\nimport type EthQuery from '@metamask/eth-query';\nimport type {\n BlockTracker,\n NetworkClientId,\n} from '@metamask/network-controller';\n// This package purposefully relies on Node's EventEmitter module.\n// eslint-disable-next-line import-x/no-nodejs-modules\nimport EventEmitter from 'events';\nimport { cloneDeep, merge } from 'lodash';\n\nimport { TransactionPoller } from './TransactionPoller';\nimport { createModuleLogger, projectLogger } from '../logger';\nimport type { TransactionMeta, TransactionReceipt } from '../types';\nimport { TransactionStatus, TransactionType } from '../types';\n\n/**\n * We wait this many blocks before emitting a 'transaction-dropped' event\n * This is because we could be talking to a node that is out of sync\n */\nconst DROPPED_BLOCK_COUNT = 3;\n\nconst RECEIPT_STATUS_SUCCESS = '0x1';\nconst RECEIPT_STATUS_FAILURE = '0x0';\nconst MAX_RETRY_BLOCK_DISTANCE = 50;\n\nconst KNOWN_TRANSACTION_ERRORS = [\n 'replacement transaction underpriced',\n 'known transaction',\n 'gas price too low to replace',\n 'transaction with the same hash was already imported',\n 'gateway timeout',\n 'nonce too low',\n];\n\nconst log = createModuleLogger(projectLogger, 'pending-transactions');\n\ntype SuccessfulTransactionReceipt = TransactionReceipt & {\n blockNumber: string;\n blockHash: string;\n};\n\ntype Events = {\n 'transaction-confirmed': [txMeta: TransactionMeta];\n 'transaction-dropped': [txMeta: TransactionMeta];\n 'transaction-failed': [txMeta: TransactionMeta, error: Error];\n 'transaction-updated': [txMeta: TransactionMeta, note: string];\n};\n\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface PendingTransactionTrackerEventEmitter extends EventEmitter {\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 on<T extends keyof Events>(\n eventName: T,\n listener: (...args: Events[T]) => void,\n ): this;\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 emit<T extends keyof Events>(eventName: T, ...args: Events[T]): boolean;\n}\n\nexport class PendingTransactionTracker {\n hub: PendingTransactionTrackerEventEmitter;\n\n #droppedBlockCountByHash: Map<string, number>;\n\n #getChainId: () => string;\n\n #getEthQuery: (networkClientId?: NetworkClientId) => EthQuery;\n\n readonly #getNetworkClientId: () => NetworkClientId;\n\n #getTransactions: () => TransactionMeta[];\n\n #isResubmitEnabled: () => boolean;\n\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n #listener: any;\n\n #log: debug.Debugger;\n\n #getGlobalLock: () => Promise<() => void>;\n\n #publishTransaction: (\n ethQuery: EthQuery,\n transactionMeta: TransactionMeta,\n ) => Promise<string>;\n\n #running: boolean;\n\n #transactionPoller: TransactionPoller;\n\n #beforeCheckPendingTransaction: (transactionMeta: TransactionMeta) => boolean;\n\n #beforePublish: (transactionMeta: TransactionMeta) => boolean;\n\n constructor({\n blockTracker,\n getChainId,\n getEthQuery,\n getNetworkClientId,\n getTransactions,\n isResubmitEnabled,\n getGlobalLock,\n publishTransaction,\n hooks,\n }: {\n blockTracker: BlockTracker;\n getChainId: () => string;\n getEthQuery: (networkClientId?: NetworkClientId) => EthQuery;\n getNetworkClientId: () => string;\n getTransactions: () => TransactionMeta[];\n isResubmitEnabled?: () => boolean;\n getGlobalLock: () => Promise<() => void>;\n publishTransaction: (\n ethQuery: EthQuery,\n transactionMeta: TransactionMeta,\n ) => Promise<string>;\n hooks?: {\n beforeCheckPendingTransaction?: (\n transactionMeta: TransactionMeta,\n ) => boolean;\n beforePublish?: (transactionMeta: TransactionMeta) => boolean;\n };\n }) {\n this.hub = new EventEmitter() as PendingTransactionTrackerEventEmitter;\n\n this.#droppedBlockCountByHash = new Map();\n this.#getChainId = getChainId;\n this.#getEthQuery = getEthQuery;\n this.#getNetworkClientId = getNetworkClientId;\n this.#getTransactions = getTransactions;\n this.#isResubmitEnabled = isResubmitEnabled ?? (() => true);\n this.#listener = this.#onLatestBlock.bind(this);\n this.#getGlobalLock = getGlobalLock;\n this.#publishTransaction = publishTransaction;\n this.#running = false;\n this.#transactionPoller = new TransactionPoller(blockTracker);\n this.#beforePublish = hooks?.beforePublish ?? (() => true);\n this.#beforeCheckPendingTransaction =\n hooks?.beforeCheckPendingTransaction ?? (() => true);\n\n this.#log = createModuleLogger(\n log,\n `${getChainId()}:${getNetworkClientId()}`,\n );\n }\n\n startIfPendingTransactions = () => {\n const pendingTransactions = this.#getPendingTransactions();\n\n if (pendingTransactions.length) {\n this.#start(pendingTransactions);\n } else {\n this.stop();\n }\n };\n\n /**\n * Force checks the network if the given transaction is confirmed and updates it's status.\n *\n * @param txMeta - The transaction to check\n */\n async forceCheckTransaction(txMeta: TransactionMeta) {\n const releaseLock = await this.#getGlobalLock();\n\n try {\n await this.#checkTransaction(txMeta);\n } catch (error) {\n /* istanbul ignore next */\n this.#log('Failed to check transaction', error);\n } finally {\n releaseLock();\n }\n }\n\n #start(pendingTransactions: TransactionMeta[]) {\n this.#transactionPoller.setPendingTransactions(pendingTransactions);\n\n if (this.#running) {\n return;\n }\n\n this.#transactionPoller.start(this.#listener);\n this.#running = true;\n\n this.#log('Started polling');\n }\n\n stop() {\n if (!this.#running) {\n return;\n }\n\n this.#transactionPoller.stop();\n this.#running = false;\n\n this.#log('Stopped polling');\n }\n\n async #onLatestBlock(latestBlockNumber: string) {\n const releaseLock = await this.#getGlobalLock();\n\n try {\n await this.#checkTransactions();\n } catch (error) {\n /* istanbul ignore next */\n this.#log('Failed to check transactions', error);\n } finally {\n releaseLock();\n }\n\n try {\n await this.#resubmitTransactions(latestBlockNumber);\n } catch (error) {\n /* istanbul ignore next */\n this.#log('Failed to resubmit transactions', error);\n }\n }\n\n async #checkTransactions() {\n this.#log('Checking transactions');\n\n const pendingTransactions = this.#getPendingTransactions();\n\n if (!pendingTransactions.length) {\n this.#log('No pending transactions to check');\n return;\n }\n\n this.#log('Found pending transactions to check', {\n count: pendingTransactions.length,\n ids: pendingTransactions.map((tx) => tx.id),\n });\n\n await Promise.all(\n pendingTransactions.map((tx) => this.#checkTransaction(tx)),\n );\n }\n\n async #resubmitTransactions(latestBlockNumber: string) {\n if (!this.#isResubmitEnabled() || !this.#running) {\n return;\n }\n\n this.#log('Resubmitting transactions');\n\n const pendingTransactions = this.#getPendingTransactions();\n\n if (!pendingTransactions.length) {\n this.#log('No pending transactions to resubmit');\n return;\n }\n\n this.#log('Found pending transactions to resubmit', {\n count: pendingTransactions.length,\n ids: pendingTransactions.map((tx) => tx.id),\n });\n\n for (const txMeta of pendingTransactions) {\n try {\n await this.#resubmitTransaction(txMeta, latestBlockNumber);\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n /* istanbul ignore next */\n const errorMessage =\n error.value?.message?.toLowerCase() ||\n error.message?.toLowerCase() ||\n String(error);\n\n if (this.#isKnownTransactionError(errorMessage)) {\n this.#log('Ignoring known transaction error', errorMessage);\n continue;\n }\n\n this.#warnTransaction(\n txMeta,\n error.message,\n 'There was an error when resubmitting this transaction.',\n );\n }\n }\n }\n\n #isKnownTransactionError(errorMessage: string) {\n return KNOWN_TRANSACTION_ERRORS.some((knownError) =>\n errorMessage.includes(knownError),\n );\n }\n\n async #resubmitTransaction(\n txMeta: TransactionMeta,\n latestBlockNumber: string,\n ) {\n if (!this.#isResubmitDue(txMeta, latestBlockNumber)) {\n return;\n }\n\n if (!this.#beforePublish(txMeta)) {\n return;\n }\n\n const ethQuery = this.#getEthQuery(txMeta.networkClientId);\n await this.#publishTransaction(ethQuery, txMeta);\n\n const retryCount = (txMeta.retryCount ?? 0) + 1;\n\n this.#updateTransaction(\n merge({}, txMeta, { retryCount }),\n 'PendingTransactionTracker:transaction-retry - Retry count increased',\n );\n }\n\n #isResubmitDue(txMeta: TransactionMeta, latestBlockNumber: string): boolean {\n const txMetaWithFirstRetryBlockNumber = cloneDeep(txMeta);\n\n if (!txMetaWithFirstRetryBlockNumber.firstRetryBlockNumber) {\n txMetaWithFirstRetryBlockNumber.firstRetryBlockNumber = latestBlockNumber;\n\n this.#updateTransaction(\n txMetaWithFirstRetryBlockNumber,\n 'PendingTransactionTracker:#isResubmitDue - First retry block number set',\n );\n }\n\n const { firstRetryBlockNumber } = txMetaWithFirstRetryBlockNumber;\n\n const blocksSinceFirstRetry =\n Number.parseInt(latestBlockNumber, 16) -\n Number.parseInt(firstRetryBlockNumber, 16);\n\n const retryCount = txMeta.retryCount || 0;\n\n // Exponential backoff to limit retries at publishing\n // Capped at ~15 minutes between retries\n const requiredBlocksSinceFirstRetry = Math.min(\n MAX_RETRY_BLOCK_DISTANCE,\n Math.pow(2, retryCount),\n );\n\n return blocksSinceFirstRetry >= requiredBlocksSinceFirstRetry;\n }\n\n async #checkTransaction(txMeta: TransactionMeta) {\n const { hash, id } = txMeta;\n\n if (!hash && this.#beforeCheckPendingTransaction(txMeta)) {\n const error = new Error(\n 'We had an error while submitting this transaction, please try again.',\n );\n\n error.name = 'NoTxHashError';\n\n this.#failTransaction(txMeta, error);\n\n return;\n }\n\n if (this.#isNonceTaken(txMeta)) {\n this.#log('Nonce already taken', id);\n this.#dropTransaction(txMeta);\n return;\n }\n\n try {\n const receipt = await this.#getTransactionReceipt(hash);\n const isSuccess = receipt?.status === RECEIPT_STATUS_SUCCESS;\n const isFailure = receipt?.status === RECEIPT_STATUS_FAILURE;\n\n if (isFailure) {\n this.#log('Transaction receipt has failed status');\n\n this.#failTransaction(\n txMeta,\n new Error('Transaction dropped or replaced'),\n );\n\n return;\n }\n\n const { blockNumber, blockHash } = receipt || {};\n\n if (isSuccess && blockNumber && blockHash) {\n await this.#onTransactionConfirmed(txMeta, {\n ...receipt,\n blockNumber,\n blockHash,\n });\n\n return;\n }\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n this.#log('Failed to check transaction', id, error);\n\n this.#warnTransaction(\n txMeta,\n error.message,\n 'There was a problem loading this transaction.',\n );\n\n return;\n }\n\n if (await this.#isTransactionDropped(txMeta)) {\n this.#dropTransaction(txMeta);\n }\n }\n\n async #onTransactionConfirmed(\n txMeta: TransactionMeta,\n receipt: SuccessfulTransactionReceipt,\n ) {\n const { id } = txMeta;\n const { blockHash } = receipt;\n\n this.#log('Transaction confirmed', id);\n\n const { baseFeePerGas, timestamp: blockTimestamp } =\n await this.#getBlockByHash(blockHash, false);\n\n const updatedTxMeta = cloneDeep(txMeta);\n updatedTxMeta.baseFeePerGas = baseFeePerGas;\n updatedTxMeta.blockTimestamp = blockTimestamp;\n updatedTxMeta.status = TransactionStatus.confirmed;\n updatedTxMeta.txParams = {\n ...updatedTxMeta.txParams,\n gasUsed: receipt.gasUsed,\n };\n updatedTxMeta.txReceipt = receipt;\n updatedTxMeta.verifiedOnBlockchain = true;\n\n this.#updateTransaction(\n updatedTxMeta,\n 'PendingTransactionTracker:#onTransactionConfirmed - Transaction confirmed',\n );\n\n this.hub.emit('transaction-confirmed', updatedTxMeta);\n }\n\n async #isTransactionDropped(txMeta: TransactionMeta) {\n const {\n hash,\n id,\n txParams: { nonce, from },\n } = txMeta;\n\n /* istanbul ignore next */\n if (!nonce || !hash) {\n return false;\n }\n\n const networkNextNonceHex = await this.#getNetworkTransactionCount(from);\n const networkNextNonceNumber = parseInt(networkNextNonceHex, 16);\n const nonceNumber = parseInt(nonce, 16);\n\n if (nonceNumber >= networkNextNonceNumber) {\n return false;\n }\n\n let droppedBlockCount = this.#droppedBlockCountByHash.get(hash);\n\n if (droppedBlockCount === undefined) {\n droppedBlockCount = 0;\n this.#droppedBlockCountByHash.set(hash, droppedBlockCount);\n }\n\n if (droppedBlockCount < DROPPED_BLOCK_COUNT) {\n this.#log('Incrementing dropped block count', { id, droppedBlockCount });\n this.#droppedBlockCountByHash.set(hash, droppedBlockCount + 1);\n return false;\n }\n\n this.#log('Hit dropped block count', id);\n\n this.#droppedBlockCountByHash.delete(hash);\n return true;\n }\n\n #isNonceTaken(txMeta: TransactionMeta): boolean {\n const { id, txParams } = txMeta;\n\n return this.#getChainTransactions().some(\n (tx) =>\n tx.id !== id &&\n tx.txParams.from === txParams.from &&\n tx.status === TransactionStatus.confirmed &&\n tx.txParams.nonce === txParams.nonce &&\n tx.type !== TransactionType.incoming,\n );\n }\n\n #getPendingTransactions(): TransactionMeta[] {\n return this.#getNetworkClientTransactions().filter(\n (tx) =>\n tx.status === TransactionStatus.submitted &&\n !tx.verifiedOnBlockchain &&\n !tx.isUserOperation,\n );\n }\n\n #warnTransaction(txMeta: TransactionMeta, error: string, message: string) {\n this.#updateTransaction(\n {\n ...txMeta,\n warning: { error, message },\n },\n 'PendingTransactionTracker:#warnTransaction - Warning added',\n );\n }\n\n #failTransaction(txMeta: TransactionMeta, error: Error) {\n this.#log('Transaction failed', txMeta.id, error);\n this.hub.emit('transaction-failed', txMeta, error);\n }\n\n #dropTransaction(txMeta: TransactionMeta) {\n this.#log('Transaction dropped', txMeta.id);\n this.hub.emit('transaction-dropped', txMeta);\n }\n\n #updateTransaction(txMeta: TransactionMeta, note: string) {\n this.hub.emit('transaction-updated', txMeta, note);\n }\n\n async #getTransactionReceipt(\n txHash?: string,\n ): Promise<TransactionReceipt | undefined> {\n return await query(this.#getEthQuery(), 'getTransactionReceipt', [txHash]);\n }\n\n async #getBlockByHash(\n blockHash: string,\n includeTransactionDetails: boolean,\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ): Promise<any> {\n return await query(this.#getEthQuery(), 'getBlockByHash', [\n blockHash,\n includeTransactionDetails,\n ]);\n }\n\n async #getNetworkTransactionCount(address: string): Promise<string> {\n return await query(this.#getEthQuery(), 'getTransactionCount', [address]);\n }\n\n #getChainTransactions(): TransactionMeta[] {\n const chainId = this.#getChainId();\n return this.#getTransactions().filter((tx) => tx.chainId === chainId);\n }\n\n #getNetworkClientTransactions(): TransactionMeta[] {\n const networkClientId = this.#getNetworkClientId();\n return this.#getTransactions().filter(\n (tx) => tx.networkClientId === networkClientId,\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"PendingTransactionTracker.cjs","sourceRoot":"","sources":["../../src/helpers/PendingTransactionTracker.ts"],"names":[],"mappings":"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","sourcesContent":["import { query } from '@metamask/controller-utils';\nimport type EthQuery from '@metamask/eth-query';\nimport type {\n BlockTracker,\n NetworkClientId,\n} from '@metamask/network-controller';\n// This package purposefully relies on Node's EventEmitter module.\n// eslint-disable-next-line import-x/no-nodejs-modules\nimport EventEmitter from 'events';\nimport { cloneDeep, merge } from 'lodash';\n\nimport { TransactionPoller } from './TransactionPoller';\nimport { createModuleLogger, projectLogger } from '../logger';\nimport type { TransactionMeta, TransactionReceipt } from '../types';\nimport { TransactionStatus, TransactionType } from '../types';\n\n/**\n * We wait this many blocks before emitting a 'transaction-dropped' event\n * This is because we could be talking to a node that is out of sync\n */\nconst DROPPED_BLOCK_COUNT = 3;\n\nconst RECEIPT_STATUS_SUCCESS = '0x1';\nconst RECEIPT_STATUS_FAILURE = '0x0';\nconst MAX_RETRY_BLOCK_DISTANCE = 50;\n\nconst KNOWN_TRANSACTION_ERRORS = [\n 'replacement transaction underpriced',\n 'known transaction',\n 'gas price too low to replace',\n 'transaction with the same hash was already imported',\n 'gateway timeout',\n 'nonce too low',\n];\n\nconst log = createModuleLogger(projectLogger, 'pending-transactions');\n\ntype SuccessfulTransactionReceipt = TransactionReceipt & {\n blockNumber: string;\n blockHash: string;\n};\n\ntype Events = {\n 'transaction-confirmed': [txMeta: TransactionMeta];\n 'transaction-dropped': [txMeta: TransactionMeta];\n 'transaction-failed': [txMeta: TransactionMeta, error: Error];\n 'transaction-updated': [txMeta: TransactionMeta, note: string];\n};\n\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface PendingTransactionTrackerEventEmitter extends EventEmitter {\n on<T extends keyof Events>(\n eventName: T,\n listener: (...args: Events[T]) => void,\n ): this;\n\n emit<T extends keyof Events>(eventName: T, ...args: Events[T]): boolean;\n}\n\nexport class PendingTransactionTracker {\n hub: PendingTransactionTrackerEventEmitter;\n\n readonly #droppedBlockCountByHash: Map<string, number>;\n\n readonly #getChainId: () => string;\n\n readonly #getEthQuery: (networkClientId?: NetworkClientId) => EthQuery;\n\n readonly #getNetworkClientId: () => NetworkClientId;\n\n readonly #getTransactions: () => TransactionMeta[];\n\n readonly #isResubmitEnabled: () => boolean;\n\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly #listener: any;\n\n readonly #log: debug.Debugger;\n\n readonly #getGlobalLock: () => Promise<() => void>;\n\n readonly #publishTransaction: (\n ethQuery: EthQuery,\n transactionMeta: TransactionMeta,\n ) => Promise<string>;\n\n #running: boolean;\n\n readonly #transactionPoller: TransactionPoller;\n\n readonly #beforeCheckPendingTransaction: (\n transactionMeta: TransactionMeta,\n ) => boolean;\n\n readonly #beforePublish: (transactionMeta: TransactionMeta) => boolean;\n\n constructor({\n blockTracker,\n getChainId,\n getEthQuery,\n getNetworkClientId,\n getTransactions,\n isResubmitEnabled,\n getGlobalLock,\n publishTransaction,\n hooks,\n }: {\n blockTracker: BlockTracker;\n getChainId: () => string;\n getEthQuery: (networkClientId?: NetworkClientId) => EthQuery;\n getNetworkClientId: () => string;\n getTransactions: () => TransactionMeta[];\n isResubmitEnabled?: () => boolean;\n getGlobalLock: () => Promise<() => void>;\n publishTransaction: (\n ethQuery: EthQuery,\n transactionMeta: TransactionMeta,\n ) => Promise<string>;\n hooks?: {\n beforeCheckPendingTransaction?: (\n transactionMeta: TransactionMeta,\n ) => boolean;\n beforePublish?: (transactionMeta: TransactionMeta) => boolean;\n };\n }) {\n this.hub = new EventEmitter() as PendingTransactionTrackerEventEmitter;\n\n this.#droppedBlockCountByHash = new Map();\n this.#getChainId = getChainId;\n this.#getEthQuery = getEthQuery;\n this.#getNetworkClientId = getNetworkClientId;\n this.#getTransactions = getTransactions;\n this.#isResubmitEnabled = isResubmitEnabled ?? (() => true);\n this.#listener = this.#onLatestBlock.bind(this);\n this.#getGlobalLock = getGlobalLock;\n this.#publishTransaction = publishTransaction;\n this.#running = false;\n this.#transactionPoller = new TransactionPoller(blockTracker);\n this.#beforePublish = hooks?.beforePublish ?? (() => true);\n this.#beforeCheckPendingTransaction =\n hooks?.beforeCheckPendingTransaction ?? (() => true);\n\n this.#log = createModuleLogger(\n log,\n `${getChainId()}:${getNetworkClientId()}`,\n );\n }\n\n startIfPendingTransactions = () => {\n const pendingTransactions = this.#getPendingTransactions();\n\n if (pendingTransactions.length) {\n this.#start(pendingTransactions);\n } else {\n this.stop();\n }\n };\n\n /**\n * Force checks the network if the given transaction is confirmed and updates it's status.\n *\n * @param txMeta - The transaction to check\n */\n async forceCheckTransaction(txMeta: TransactionMeta) {\n const releaseLock = await this.#getGlobalLock();\n\n try {\n await this.#checkTransaction(txMeta);\n } catch (error) {\n /* istanbul ignore next */\n this.#log('Failed to check transaction', error);\n } finally {\n releaseLock();\n }\n }\n\n #start(pendingTransactions: TransactionMeta[]) {\n this.#transactionPoller.setPendingTransactions(pendingTransactions);\n\n if (this.#running) {\n return;\n }\n\n this.#transactionPoller.start(this.#listener);\n this.#running = true;\n\n this.#log('Started polling');\n }\n\n stop() {\n if (!this.#running) {\n return;\n }\n\n this.#transactionPoller.stop();\n this.#running = false;\n\n this.#log('Stopped polling');\n }\n\n async #onLatestBlock(latestBlockNumber: string) {\n const releaseLock = await this.#getGlobalLock();\n\n try {\n await this.#checkTransactions();\n } catch (error) {\n /* istanbul ignore next */\n this.#log('Failed to check transactions', error);\n } finally {\n releaseLock();\n }\n\n try {\n await this.#resubmitTransactions(latestBlockNumber);\n } catch (error) {\n /* istanbul ignore next */\n this.#log('Failed to resubmit transactions', error);\n }\n }\n\n async #checkTransactions() {\n this.#log('Checking transactions');\n\n const pendingTransactions = this.#getPendingTransactions();\n\n if (!pendingTransactions.length) {\n this.#log('No pending transactions to check');\n return;\n }\n\n this.#log('Found pending transactions to check', {\n count: pendingTransactions.length,\n ids: pendingTransactions.map((tx) => tx.id),\n });\n\n await Promise.all(\n pendingTransactions.map((tx) => this.#checkTransaction(tx)),\n );\n }\n\n async #resubmitTransactions(latestBlockNumber: string) {\n if (!this.#isResubmitEnabled() || !this.#running) {\n return;\n }\n\n this.#log('Resubmitting transactions');\n\n const pendingTransactions = this.#getPendingTransactions();\n\n if (!pendingTransactions.length) {\n this.#log('No pending transactions to resubmit');\n return;\n }\n\n this.#log('Found pending transactions to resubmit', {\n count: pendingTransactions.length,\n ids: pendingTransactions.map((tx) => tx.id),\n });\n\n for (const txMeta of pendingTransactions) {\n try {\n await this.#resubmitTransaction(txMeta, latestBlockNumber);\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n /* istanbul ignore next */\n const errorMessage =\n error.value?.message?.toLowerCase() ||\n error.message?.toLowerCase() ||\n String(error);\n\n if (this.#isKnownTransactionError(errorMessage)) {\n this.#log('Ignoring known transaction error', errorMessage);\n continue;\n }\n\n this.#warnTransaction(\n txMeta,\n error.message,\n 'There was an error when resubmitting this transaction.',\n );\n }\n }\n }\n\n #isKnownTransactionError(errorMessage: string) {\n return KNOWN_TRANSACTION_ERRORS.some((knownError) =>\n errorMessage.includes(knownError),\n );\n }\n\n async #resubmitTransaction(\n txMeta: TransactionMeta,\n latestBlockNumber: string,\n ) {\n if (!this.#isResubmitDue(txMeta, latestBlockNumber)) {\n return;\n }\n\n if (!this.#beforePublish(txMeta)) {\n return;\n }\n\n const ethQuery = this.#getEthQuery(txMeta.networkClientId);\n await this.#publishTransaction(ethQuery, txMeta);\n\n const retryCount = (txMeta.retryCount ?? 0) + 1;\n\n this.#updateTransaction(\n merge({}, txMeta, { retryCount }),\n 'PendingTransactionTracker:transaction-retry - Retry count increased',\n );\n }\n\n #isResubmitDue(txMeta: TransactionMeta, latestBlockNumber: string): boolean {\n const txMetaWithFirstRetryBlockNumber = cloneDeep(txMeta);\n\n if (!txMetaWithFirstRetryBlockNumber.firstRetryBlockNumber) {\n txMetaWithFirstRetryBlockNumber.firstRetryBlockNumber = latestBlockNumber;\n\n this.#updateTransaction(\n txMetaWithFirstRetryBlockNumber,\n 'PendingTransactionTracker:#isResubmitDue - First retry block number set',\n );\n }\n\n const { firstRetryBlockNumber } = txMetaWithFirstRetryBlockNumber;\n\n const blocksSinceFirstRetry =\n Number.parseInt(latestBlockNumber, 16) -\n Number.parseInt(firstRetryBlockNumber, 16);\n\n const retryCount = txMeta.retryCount || 0;\n\n // Exponential backoff to limit retries at publishing\n // Capped at ~15 minutes between retries\n const requiredBlocksSinceFirstRetry = Math.min(\n MAX_RETRY_BLOCK_DISTANCE,\n Math.pow(2, retryCount),\n );\n\n return blocksSinceFirstRetry >= requiredBlocksSinceFirstRetry;\n }\n\n async #checkTransaction(txMeta: TransactionMeta) {\n const { hash, id } = txMeta;\n\n if (!hash && this.#beforeCheckPendingTransaction(txMeta)) {\n const error = new Error(\n 'We had an error while submitting this transaction, please try again.',\n );\n\n error.name = 'NoTxHashError';\n\n this.#failTransaction(txMeta, error);\n\n return;\n }\n\n if (this.#isNonceTaken(txMeta)) {\n this.#log('Nonce already taken', id);\n this.#dropTransaction(txMeta);\n return;\n }\n\n try {\n const receipt = await this.#getTransactionReceipt(hash);\n const isSuccess = receipt?.status === RECEIPT_STATUS_SUCCESS;\n const isFailure = receipt?.status === RECEIPT_STATUS_FAILURE;\n\n if (isFailure) {\n this.#log('Transaction receipt has failed status');\n\n this.#failTransaction(\n txMeta,\n new Error('Transaction dropped or replaced'),\n );\n\n return;\n }\n\n const { blockNumber, blockHash } = receipt || {};\n\n if (isSuccess && blockNumber && blockHash) {\n await this.#onTransactionConfirmed(txMeta, {\n ...receipt,\n blockNumber,\n blockHash,\n });\n\n return;\n }\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n this.#log('Failed to check transaction', id, error);\n\n this.#warnTransaction(\n txMeta,\n error.message,\n 'There was a problem loading this transaction.',\n );\n\n return;\n }\n\n if (await this.#isTransactionDropped(txMeta)) {\n this.#dropTransaction(txMeta);\n }\n }\n\n async #onTransactionConfirmed(\n txMeta: TransactionMeta,\n receipt: SuccessfulTransactionReceipt,\n ) {\n const { id } = txMeta;\n const { blockHash } = receipt;\n\n this.#log('Transaction confirmed', id);\n\n const { baseFeePerGas, timestamp: blockTimestamp } =\n await this.#getBlockByHash(blockHash, false);\n\n const updatedTxMeta = cloneDeep(txMeta);\n updatedTxMeta.baseFeePerGas = baseFeePerGas;\n updatedTxMeta.blockTimestamp = blockTimestamp;\n updatedTxMeta.status = TransactionStatus.confirmed;\n updatedTxMeta.txParams = {\n ...updatedTxMeta.txParams,\n gasUsed: receipt.gasUsed,\n };\n updatedTxMeta.txReceipt = receipt;\n updatedTxMeta.verifiedOnBlockchain = true;\n\n this.#updateTransaction(\n updatedTxMeta,\n 'PendingTransactionTracker:#onTransactionConfirmed - Transaction confirmed',\n );\n\n this.hub.emit('transaction-confirmed', updatedTxMeta);\n }\n\n async #isTransactionDropped(txMeta: TransactionMeta) {\n const {\n hash,\n id,\n txParams: { nonce, from },\n } = txMeta;\n\n /* istanbul ignore next */\n if (!nonce || !hash) {\n return false;\n }\n\n const networkNextNonceHex = await this.#getNetworkTransactionCount(from);\n const networkNextNonceNumber = parseInt(networkNextNonceHex, 16);\n const nonceNumber = parseInt(nonce, 16);\n\n if (nonceNumber >= networkNextNonceNumber) {\n return false;\n }\n\n let droppedBlockCount = this.#droppedBlockCountByHash.get(hash);\n\n if (droppedBlockCount === undefined) {\n droppedBlockCount = 0;\n this.#droppedBlockCountByHash.set(hash, droppedBlockCount);\n }\n\n if (droppedBlockCount < DROPPED_BLOCK_COUNT) {\n this.#log('Incrementing dropped block count', { id, droppedBlockCount });\n this.#droppedBlockCountByHash.set(hash, droppedBlockCount + 1);\n return false;\n }\n\n this.#log('Hit dropped block count', id);\n\n this.#droppedBlockCountByHash.delete(hash);\n return true;\n }\n\n #isNonceTaken(txMeta: TransactionMeta): boolean {\n const { id, txParams } = txMeta;\n\n return this.#getChainTransactions().some(\n (tx) =>\n tx.id !== id &&\n tx.txParams.from === txParams.from &&\n tx.status === TransactionStatus.confirmed &&\n tx.txParams.nonce === txParams.nonce &&\n tx.type !== TransactionType.incoming,\n );\n }\n\n #getPendingTransactions(): TransactionMeta[] {\n return this.#getNetworkClientTransactions().filter(\n (tx) =>\n tx.status === TransactionStatus.submitted &&\n !tx.verifiedOnBlockchain &&\n !tx.isUserOperation,\n );\n }\n\n #warnTransaction(txMeta: TransactionMeta, error: string, message: string) {\n this.#updateTransaction(\n {\n ...txMeta,\n warning: { error, message },\n },\n 'PendingTransactionTracker:#warnTransaction - Warning added',\n );\n }\n\n #failTransaction(txMeta: TransactionMeta, error: Error) {\n this.#log('Transaction failed', txMeta.id, error);\n this.hub.emit('transaction-failed', txMeta, error);\n }\n\n #dropTransaction(txMeta: TransactionMeta) {\n this.#log('Transaction dropped', txMeta.id);\n this.hub.emit('transaction-dropped', txMeta);\n }\n\n #updateTransaction(txMeta: TransactionMeta, note: string) {\n this.hub.emit('transaction-updated', txMeta, note);\n }\n\n async #getTransactionReceipt(\n txHash?: string,\n ): Promise<TransactionReceipt | undefined> {\n return await query(this.#getEthQuery(), 'getTransactionReceipt', [txHash]);\n }\n\n async #getBlockByHash(\n blockHash: string,\n includeTransactionDetails: boolean,\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ): Promise<any> {\n return await query(this.#getEthQuery(), 'getBlockByHash', [\n blockHash,\n includeTransactionDetails,\n ]);\n }\n\n async #getNetworkTransactionCount(address: string): Promise<string> {\n return await query(this.#getEthQuery(), 'getTransactionCount', [address]);\n }\n\n #getChainTransactions(): TransactionMeta[] {\n const chainId = this.#getChainId();\n return this.#getTransactions().filter((tx) => tx.chainId === chainId);\n }\n\n #getNetworkClientTransactions(): TransactionMeta[] {\n const networkClientId = this.#getNetworkClientId();\n return this.#getTransactions().filter(\n (tx) => tx.networkClientId === networkClientId,\n );\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PendingTransactionTracker.d.cts","sourceRoot":"","sources":["../../src/helpers/PendingTransactionTracker.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,QAAQ,4BAA4B;AAChD,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EAChB,qCAAqC;AAGtC,OAAO,YAAY,eAAe;AAKlC,OAAO,KAAK,EAAE,eAAe,EAAsB,qBAAiB;AA6BpE,KAAK,MAAM,GAAG;IACZ,uBAAuB,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACnD,qBAAqB,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACjD,oBAAoB,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAC9D,qBAAqB,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;CAChE,CAAC;AAKF,MAAM,WAAW,qCAAsC,SAAQ,YAAY;
|
|
1
|
+
{"version":3,"file":"PendingTransactionTracker.d.cts","sourceRoot":"","sources":["../../src/helpers/PendingTransactionTracker.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,QAAQ,4BAA4B;AAChD,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EAChB,qCAAqC;AAGtC,OAAO,YAAY,eAAe;AAKlC,OAAO,KAAK,EAAE,eAAe,EAAsB,qBAAiB;AA6BpE,KAAK,MAAM,GAAG;IACZ,uBAAuB,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACnD,qBAAqB,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACjD,oBAAoB,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAC9D,qBAAqB,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;CAChE,CAAC;AAKF,MAAM,WAAW,qCAAsC,SAAQ,YAAY;IACzE,EAAE,CAAC,CAAC,SAAS,MAAM,MAAM,EACvB,SAAS,EAAE,CAAC,EACZ,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,GACrC,IAAI,CAAC;IAER,IAAI,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;CACzE;AAED,qBAAa,yBAAyB;;IACpC,GAAG,EAAE,qCAAqC,CAAC;gBAqC/B,EACV,YAAY,EACZ,UAAU,EACV,WAAW,EACX,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,kBAAkB,EAClB,KAAK,GACN,EAAE;QACD,YAAY,EAAE,YAAY,CAAC;QAC3B,UAAU,EAAE,MAAM,MAAM,CAAC;QACzB,WAAW,EAAE,CAAC,eAAe,CAAC,EAAE,eAAe,KAAK,QAAQ,CAAC;QAC7D,kBAAkB,EAAE,MAAM,MAAM,CAAC;QACjC,eAAe,EAAE,MAAM,eAAe,EAAE,CAAC;QACzC,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC;QAClC,aAAa,EAAE,MAAM,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;QACzC,kBAAkB,EAAE,CAClB,QAAQ,EAAE,QAAQ,EAClB,eAAe,EAAE,eAAe,KAC7B,OAAO,CAAC,MAAM,CAAC,CAAC;QACrB,KAAK,CAAC,EAAE;YACN,6BAA6B,CAAC,EAAE,CAC9B,eAAe,EAAE,eAAe,KAC7B,OAAO,CAAC;YACb,aAAa,CAAC,EAAE,CAAC,eAAe,EAAE,eAAe,KAAK,OAAO,CAAC;SAC/D,CAAC;KACH;IAwBD,0BAA0B,aAQxB;IAEF;;;;OAIG;IACG,qBAAqB,CAAC,MAAM,EAAE,eAAe;IA0BnD,IAAI;CAmXL"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PendingTransactionTracker.d.mts","sourceRoot":"","sources":["../../src/helpers/PendingTransactionTracker.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,QAAQ,4BAA4B;AAChD,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EAChB,qCAAqC;AAGtC,OAAO,YAAY,eAAe;AAKlC,OAAO,KAAK,EAAE,eAAe,EAAsB,qBAAiB;AA6BpE,KAAK,MAAM,GAAG;IACZ,uBAAuB,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACnD,qBAAqB,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACjD,oBAAoB,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAC9D,qBAAqB,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;CAChE,CAAC;AAKF,MAAM,WAAW,qCAAsC,SAAQ,YAAY;
|
|
1
|
+
{"version":3,"file":"PendingTransactionTracker.d.mts","sourceRoot":"","sources":["../../src/helpers/PendingTransactionTracker.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,QAAQ,4BAA4B;AAChD,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EAChB,qCAAqC;AAGtC,OAAO,YAAY,eAAe;AAKlC,OAAO,KAAK,EAAE,eAAe,EAAsB,qBAAiB;AA6BpE,KAAK,MAAM,GAAG;IACZ,uBAAuB,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACnD,qBAAqB,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACjD,oBAAoB,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAC9D,qBAAqB,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;CAChE,CAAC;AAKF,MAAM,WAAW,qCAAsC,SAAQ,YAAY;IACzE,EAAE,CAAC,CAAC,SAAS,MAAM,MAAM,EACvB,SAAS,EAAE,CAAC,EACZ,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,GACrC,IAAI,CAAC;IAER,IAAI,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;CACzE;AAED,qBAAa,yBAAyB;;IACpC,GAAG,EAAE,qCAAqC,CAAC;gBAqC/B,EACV,YAAY,EACZ,UAAU,EACV,WAAW,EACX,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,kBAAkB,EAClB,KAAK,GACN,EAAE;QACD,YAAY,EAAE,YAAY,CAAC;QAC3B,UAAU,EAAE,MAAM,MAAM,CAAC;QACzB,WAAW,EAAE,CAAC,eAAe,CAAC,EAAE,eAAe,KAAK,QAAQ,CAAC;QAC7D,kBAAkB,EAAE,MAAM,MAAM,CAAC;QACjC,eAAe,EAAE,MAAM,eAAe,EAAE,CAAC;QACzC,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC;QAClC,aAAa,EAAE,MAAM,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;QACzC,kBAAkB,EAAE,CAClB,QAAQ,EAAE,QAAQ,EAClB,eAAe,EAAE,eAAe,KAC7B,OAAO,CAAC,MAAM,CAAC,CAAC;QACrB,KAAK,CAAC,EAAE;YACN,6BAA6B,CAAC,EAAE,CAC9B,eAAe,EAAE,eAAe,KAC7B,OAAO,CAAC;YACb,aAAa,CAAC,EAAE,CAAC,eAAe,EAAE,eAAe,KAAK,OAAO,CAAC;SAC/D,CAAC;KACH;IAwBD,0BAA0B,aAQxB;IAEF;;;;OAIG;IACG,qBAAqB,CAAC,MAAM,EAAE,eAAe;IA0BnD,IAAI;CAmXL"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PendingTransactionTracker.mjs","sourceRoot":"","sources":["../../src/helpers/PendingTransactionTracker.ts"],"names":[],"mappings":"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","sourcesContent":["import { query } from '@metamask/controller-utils';\nimport type EthQuery from '@metamask/eth-query';\nimport type {\n BlockTracker,\n NetworkClientId,\n} from '@metamask/network-controller';\n// This package purposefully relies on Node's EventEmitter module.\n// eslint-disable-next-line import-x/no-nodejs-modules\nimport EventEmitter from 'events';\nimport { cloneDeep, merge } from 'lodash';\n\nimport { TransactionPoller } from './TransactionPoller';\nimport { createModuleLogger, projectLogger } from '../logger';\nimport type { TransactionMeta, TransactionReceipt } from '../types';\nimport { TransactionStatus, TransactionType } from '../types';\n\n/**\n * We wait this many blocks before emitting a 'transaction-dropped' event\n * This is because we could be talking to a node that is out of sync\n */\nconst DROPPED_BLOCK_COUNT = 3;\n\nconst RECEIPT_STATUS_SUCCESS = '0x1';\nconst RECEIPT_STATUS_FAILURE = '0x0';\nconst MAX_RETRY_BLOCK_DISTANCE = 50;\n\nconst KNOWN_TRANSACTION_ERRORS = [\n 'replacement transaction underpriced',\n 'known transaction',\n 'gas price too low to replace',\n 'transaction with the same hash was already imported',\n 'gateway timeout',\n 'nonce too low',\n];\n\nconst log = createModuleLogger(projectLogger, 'pending-transactions');\n\ntype SuccessfulTransactionReceipt = TransactionReceipt & {\n blockNumber: string;\n blockHash: string;\n};\n\ntype Events = {\n 'transaction-confirmed': [txMeta: TransactionMeta];\n 'transaction-dropped': [txMeta: TransactionMeta];\n 'transaction-failed': [txMeta: TransactionMeta, error: Error];\n 'transaction-updated': [txMeta: TransactionMeta, note: string];\n};\n\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface PendingTransactionTrackerEventEmitter extends EventEmitter {\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 on<T extends keyof Events>(\n eventName: T,\n listener: (...args: Events[T]) => void,\n ): this;\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 emit<T extends keyof Events>(eventName: T, ...args: Events[T]): boolean;\n}\n\nexport class PendingTransactionTracker {\n hub: PendingTransactionTrackerEventEmitter;\n\n #droppedBlockCountByHash: Map<string, number>;\n\n #getChainId: () => string;\n\n #getEthQuery: (networkClientId?: NetworkClientId) => EthQuery;\n\n readonly #getNetworkClientId: () => NetworkClientId;\n\n #getTransactions: () => TransactionMeta[];\n\n #isResubmitEnabled: () => boolean;\n\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n #listener: any;\n\n #log: debug.Debugger;\n\n #getGlobalLock: () => Promise<() => void>;\n\n #publishTransaction: (\n ethQuery: EthQuery,\n transactionMeta: TransactionMeta,\n ) => Promise<string>;\n\n #running: boolean;\n\n #transactionPoller: TransactionPoller;\n\n #beforeCheckPendingTransaction: (transactionMeta: TransactionMeta) => boolean;\n\n #beforePublish: (transactionMeta: TransactionMeta) => boolean;\n\n constructor({\n blockTracker,\n getChainId,\n getEthQuery,\n getNetworkClientId,\n getTransactions,\n isResubmitEnabled,\n getGlobalLock,\n publishTransaction,\n hooks,\n }: {\n blockTracker: BlockTracker;\n getChainId: () => string;\n getEthQuery: (networkClientId?: NetworkClientId) => EthQuery;\n getNetworkClientId: () => string;\n getTransactions: () => TransactionMeta[];\n isResubmitEnabled?: () => boolean;\n getGlobalLock: () => Promise<() => void>;\n publishTransaction: (\n ethQuery: EthQuery,\n transactionMeta: TransactionMeta,\n ) => Promise<string>;\n hooks?: {\n beforeCheckPendingTransaction?: (\n transactionMeta: TransactionMeta,\n ) => boolean;\n beforePublish?: (transactionMeta: TransactionMeta) => boolean;\n };\n }) {\n this.hub = new EventEmitter() as PendingTransactionTrackerEventEmitter;\n\n this.#droppedBlockCountByHash = new Map();\n this.#getChainId = getChainId;\n this.#getEthQuery = getEthQuery;\n this.#getNetworkClientId = getNetworkClientId;\n this.#getTransactions = getTransactions;\n this.#isResubmitEnabled = isResubmitEnabled ?? (() => true);\n this.#listener = this.#onLatestBlock.bind(this);\n this.#getGlobalLock = getGlobalLock;\n this.#publishTransaction = publishTransaction;\n this.#running = false;\n this.#transactionPoller = new TransactionPoller(blockTracker);\n this.#beforePublish = hooks?.beforePublish ?? (() => true);\n this.#beforeCheckPendingTransaction =\n hooks?.beforeCheckPendingTransaction ?? (() => true);\n\n this.#log = createModuleLogger(\n log,\n `${getChainId()}:${getNetworkClientId()}`,\n );\n }\n\n startIfPendingTransactions = () => {\n const pendingTransactions = this.#getPendingTransactions();\n\n if (pendingTransactions.length) {\n this.#start(pendingTransactions);\n } else {\n this.stop();\n }\n };\n\n /**\n * Force checks the network if the given transaction is confirmed and updates it's status.\n *\n * @param txMeta - The transaction to check\n */\n async forceCheckTransaction(txMeta: TransactionMeta) {\n const releaseLock = await this.#getGlobalLock();\n\n try {\n await this.#checkTransaction(txMeta);\n } catch (error) {\n /* istanbul ignore next */\n this.#log('Failed to check transaction', error);\n } finally {\n releaseLock();\n }\n }\n\n #start(pendingTransactions: TransactionMeta[]) {\n this.#transactionPoller.setPendingTransactions(pendingTransactions);\n\n if (this.#running) {\n return;\n }\n\n this.#transactionPoller.start(this.#listener);\n this.#running = true;\n\n this.#log('Started polling');\n }\n\n stop() {\n if (!this.#running) {\n return;\n }\n\n this.#transactionPoller.stop();\n this.#running = false;\n\n this.#log('Stopped polling');\n }\n\n async #onLatestBlock(latestBlockNumber: string) {\n const releaseLock = await this.#getGlobalLock();\n\n try {\n await this.#checkTransactions();\n } catch (error) {\n /* istanbul ignore next */\n this.#log('Failed to check transactions', error);\n } finally {\n releaseLock();\n }\n\n try {\n await this.#resubmitTransactions(latestBlockNumber);\n } catch (error) {\n /* istanbul ignore next */\n this.#log('Failed to resubmit transactions', error);\n }\n }\n\n async #checkTransactions() {\n this.#log('Checking transactions');\n\n const pendingTransactions = this.#getPendingTransactions();\n\n if (!pendingTransactions.length) {\n this.#log('No pending transactions to check');\n return;\n }\n\n this.#log('Found pending transactions to check', {\n count: pendingTransactions.length,\n ids: pendingTransactions.map((tx) => tx.id),\n });\n\n await Promise.all(\n pendingTransactions.map((tx) => this.#checkTransaction(tx)),\n );\n }\n\n async #resubmitTransactions(latestBlockNumber: string) {\n if (!this.#isResubmitEnabled() || !this.#running) {\n return;\n }\n\n this.#log('Resubmitting transactions');\n\n const pendingTransactions = this.#getPendingTransactions();\n\n if (!pendingTransactions.length) {\n this.#log('No pending transactions to resubmit');\n return;\n }\n\n this.#log('Found pending transactions to resubmit', {\n count: pendingTransactions.length,\n ids: pendingTransactions.map((tx) => tx.id),\n });\n\n for (const txMeta of pendingTransactions) {\n try {\n await this.#resubmitTransaction(txMeta, latestBlockNumber);\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n /* istanbul ignore next */\n const errorMessage =\n error.value?.message?.toLowerCase() ||\n error.message?.toLowerCase() ||\n String(error);\n\n if (this.#isKnownTransactionError(errorMessage)) {\n this.#log('Ignoring known transaction error', errorMessage);\n continue;\n }\n\n this.#warnTransaction(\n txMeta,\n error.message,\n 'There was an error when resubmitting this transaction.',\n );\n }\n }\n }\n\n #isKnownTransactionError(errorMessage: string) {\n return KNOWN_TRANSACTION_ERRORS.some((knownError) =>\n errorMessage.includes(knownError),\n );\n }\n\n async #resubmitTransaction(\n txMeta: TransactionMeta,\n latestBlockNumber: string,\n ) {\n if (!this.#isResubmitDue(txMeta, latestBlockNumber)) {\n return;\n }\n\n if (!this.#beforePublish(txMeta)) {\n return;\n }\n\n const ethQuery = this.#getEthQuery(txMeta.networkClientId);\n await this.#publishTransaction(ethQuery, txMeta);\n\n const retryCount = (txMeta.retryCount ?? 0) + 1;\n\n this.#updateTransaction(\n merge({}, txMeta, { retryCount }),\n 'PendingTransactionTracker:transaction-retry - Retry count increased',\n );\n }\n\n #isResubmitDue(txMeta: TransactionMeta, latestBlockNumber: string): boolean {\n const txMetaWithFirstRetryBlockNumber = cloneDeep(txMeta);\n\n if (!txMetaWithFirstRetryBlockNumber.firstRetryBlockNumber) {\n txMetaWithFirstRetryBlockNumber.firstRetryBlockNumber = latestBlockNumber;\n\n this.#updateTransaction(\n txMetaWithFirstRetryBlockNumber,\n 'PendingTransactionTracker:#isResubmitDue - First retry block number set',\n );\n }\n\n const { firstRetryBlockNumber } = txMetaWithFirstRetryBlockNumber;\n\n const blocksSinceFirstRetry =\n Number.parseInt(latestBlockNumber, 16) -\n Number.parseInt(firstRetryBlockNumber, 16);\n\n const retryCount = txMeta.retryCount || 0;\n\n // Exponential backoff to limit retries at publishing\n // Capped at ~15 minutes between retries\n const requiredBlocksSinceFirstRetry = Math.min(\n MAX_RETRY_BLOCK_DISTANCE,\n Math.pow(2, retryCount),\n );\n\n return blocksSinceFirstRetry >= requiredBlocksSinceFirstRetry;\n }\n\n async #checkTransaction(txMeta: TransactionMeta) {\n const { hash, id } = txMeta;\n\n if (!hash && this.#beforeCheckPendingTransaction(txMeta)) {\n const error = new Error(\n 'We had an error while submitting this transaction, please try again.',\n );\n\n error.name = 'NoTxHashError';\n\n this.#failTransaction(txMeta, error);\n\n return;\n }\n\n if (this.#isNonceTaken(txMeta)) {\n this.#log('Nonce already taken', id);\n this.#dropTransaction(txMeta);\n return;\n }\n\n try {\n const receipt = await this.#getTransactionReceipt(hash);\n const isSuccess = receipt?.status === RECEIPT_STATUS_SUCCESS;\n const isFailure = receipt?.status === RECEIPT_STATUS_FAILURE;\n\n if (isFailure) {\n this.#log('Transaction receipt has failed status');\n\n this.#failTransaction(\n txMeta,\n new Error('Transaction dropped or replaced'),\n );\n\n return;\n }\n\n const { blockNumber, blockHash } = receipt || {};\n\n if (isSuccess && blockNumber && blockHash) {\n await this.#onTransactionConfirmed(txMeta, {\n ...receipt,\n blockNumber,\n blockHash,\n });\n\n return;\n }\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n this.#log('Failed to check transaction', id, error);\n\n this.#warnTransaction(\n txMeta,\n error.message,\n 'There was a problem loading this transaction.',\n );\n\n return;\n }\n\n if (await this.#isTransactionDropped(txMeta)) {\n this.#dropTransaction(txMeta);\n }\n }\n\n async #onTransactionConfirmed(\n txMeta: TransactionMeta,\n receipt: SuccessfulTransactionReceipt,\n ) {\n const { id } = txMeta;\n const { blockHash } = receipt;\n\n this.#log('Transaction confirmed', id);\n\n const { baseFeePerGas, timestamp: blockTimestamp } =\n await this.#getBlockByHash(blockHash, false);\n\n const updatedTxMeta = cloneDeep(txMeta);\n updatedTxMeta.baseFeePerGas = baseFeePerGas;\n updatedTxMeta.blockTimestamp = blockTimestamp;\n updatedTxMeta.status = TransactionStatus.confirmed;\n updatedTxMeta.txParams = {\n ...updatedTxMeta.txParams,\n gasUsed: receipt.gasUsed,\n };\n updatedTxMeta.txReceipt = receipt;\n updatedTxMeta.verifiedOnBlockchain = true;\n\n this.#updateTransaction(\n updatedTxMeta,\n 'PendingTransactionTracker:#onTransactionConfirmed - Transaction confirmed',\n );\n\n this.hub.emit('transaction-confirmed', updatedTxMeta);\n }\n\n async #isTransactionDropped(txMeta: TransactionMeta) {\n const {\n hash,\n id,\n txParams: { nonce, from },\n } = txMeta;\n\n /* istanbul ignore next */\n if (!nonce || !hash) {\n return false;\n }\n\n const networkNextNonceHex = await this.#getNetworkTransactionCount(from);\n const networkNextNonceNumber = parseInt(networkNextNonceHex, 16);\n const nonceNumber = parseInt(nonce, 16);\n\n if (nonceNumber >= networkNextNonceNumber) {\n return false;\n }\n\n let droppedBlockCount = this.#droppedBlockCountByHash.get(hash);\n\n if (droppedBlockCount === undefined) {\n droppedBlockCount = 0;\n this.#droppedBlockCountByHash.set(hash, droppedBlockCount);\n }\n\n if (droppedBlockCount < DROPPED_BLOCK_COUNT) {\n this.#log('Incrementing dropped block count', { id, droppedBlockCount });\n this.#droppedBlockCountByHash.set(hash, droppedBlockCount + 1);\n return false;\n }\n\n this.#log('Hit dropped block count', id);\n\n this.#droppedBlockCountByHash.delete(hash);\n return true;\n }\n\n #isNonceTaken(txMeta: TransactionMeta): boolean {\n const { id, txParams } = txMeta;\n\n return this.#getChainTransactions().some(\n (tx) =>\n tx.id !== id &&\n tx.txParams.from === txParams.from &&\n tx.status === TransactionStatus.confirmed &&\n tx.txParams.nonce === txParams.nonce &&\n tx.type !== TransactionType.incoming,\n );\n }\n\n #getPendingTransactions(): TransactionMeta[] {\n return this.#getNetworkClientTransactions().filter(\n (tx) =>\n tx.status === TransactionStatus.submitted &&\n !tx.verifiedOnBlockchain &&\n !tx.isUserOperation,\n );\n }\n\n #warnTransaction(txMeta: TransactionMeta, error: string, message: string) {\n this.#updateTransaction(\n {\n ...txMeta,\n warning: { error, message },\n },\n 'PendingTransactionTracker:#warnTransaction - Warning added',\n );\n }\n\n #failTransaction(txMeta: TransactionMeta, error: Error) {\n this.#log('Transaction failed', txMeta.id, error);\n this.hub.emit('transaction-failed', txMeta, error);\n }\n\n #dropTransaction(txMeta: TransactionMeta) {\n this.#log('Transaction dropped', txMeta.id);\n this.hub.emit('transaction-dropped', txMeta);\n }\n\n #updateTransaction(txMeta: TransactionMeta, note: string) {\n this.hub.emit('transaction-updated', txMeta, note);\n }\n\n async #getTransactionReceipt(\n txHash?: string,\n ): Promise<TransactionReceipt | undefined> {\n return await query(this.#getEthQuery(), 'getTransactionReceipt', [txHash]);\n }\n\n async #getBlockByHash(\n blockHash: string,\n includeTransactionDetails: boolean,\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ): Promise<any> {\n return await query(this.#getEthQuery(), 'getBlockByHash', [\n blockHash,\n includeTransactionDetails,\n ]);\n }\n\n async #getNetworkTransactionCount(address: string): Promise<string> {\n return await query(this.#getEthQuery(), 'getTransactionCount', [address]);\n }\n\n #getChainTransactions(): TransactionMeta[] {\n const chainId = this.#getChainId();\n return this.#getTransactions().filter((tx) => tx.chainId === chainId);\n }\n\n #getNetworkClientTransactions(): TransactionMeta[] {\n const networkClientId = this.#getNetworkClientId();\n return this.#getTransactions().filter(\n (tx) => tx.networkClientId === networkClientId,\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"PendingTransactionTracker.mjs","sourceRoot":"","sources":["../../src/helpers/PendingTransactionTracker.ts"],"names":[],"mappings":"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","sourcesContent":["import { query } from '@metamask/controller-utils';\nimport type EthQuery from '@metamask/eth-query';\nimport type {\n BlockTracker,\n NetworkClientId,\n} from '@metamask/network-controller';\n// This package purposefully relies on Node's EventEmitter module.\n// eslint-disable-next-line import-x/no-nodejs-modules\nimport EventEmitter from 'events';\nimport { cloneDeep, merge } from 'lodash';\n\nimport { TransactionPoller } from './TransactionPoller';\nimport { createModuleLogger, projectLogger } from '../logger';\nimport type { TransactionMeta, TransactionReceipt } from '../types';\nimport { TransactionStatus, TransactionType } from '../types';\n\n/**\n * We wait this many blocks before emitting a 'transaction-dropped' event\n * This is because we could be talking to a node that is out of sync\n */\nconst DROPPED_BLOCK_COUNT = 3;\n\nconst RECEIPT_STATUS_SUCCESS = '0x1';\nconst RECEIPT_STATUS_FAILURE = '0x0';\nconst MAX_RETRY_BLOCK_DISTANCE = 50;\n\nconst KNOWN_TRANSACTION_ERRORS = [\n 'replacement transaction underpriced',\n 'known transaction',\n 'gas price too low to replace',\n 'transaction with the same hash was already imported',\n 'gateway timeout',\n 'nonce too low',\n];\n\nconst log = createModuleLogger(projectLogger, 'pending-transactions');\n\ntype SuccessfulTransactionReceipt = TransactionReceipt & {\n blockNumber: string;\n blockHash: string;\n};\n\ntype Events = {\n 'transaction-confirmed': [txMeta: TransactionMeta];\n 'transaction-dropped': [txMeta: TransactionMeta];\n 'transaction-failed': [txMeta: TransactionMeta, error: Error];\n 'transaction-updated': [txMeta: TransactionMeta, note: string];\n};\n\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface PendingTransactionTrackerEventEmitter extends EventEmitter {\n on<T extends keyof Events>(\n eventName: T,\n listener: (...args: Events[T]) => void,\n ): this;\n\n emit<T extends keyof Events>(eventName: T, ...args: Events[T]): boolean;\n}\n\nexport class PendingTransactionTracker {\n hub: PendingTransactionTrackerEventEmitter;\n\n readonly #droppedBlockCountByHash: Map<string, number>;\n\n readonly #getChainId: () => string;\n\n readonly #getEthQuery: (networkClientId?: NetworkClientId) => EthQuery;\n\n readonly #getNetworkClientId: () => NetworkClientId;\n\n readonly #getTransactions: () => TransactionMeta[];\n\n readonly #isResubmitEnabled: () => boolean;\n\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly #listener: any;\n\n readonly #log: debug.Debugger;\n\n readonly #getGlobalLock: () => Promise<() => void>;\n\n readonly #publishTransaction: (\n ethQuery: EthQuery,\n transactionMeta: TransactionMeta,\n ) => Promise<string>;\n\n #running: boolean;\n\n readonly #transactionPoller: TransactionPoller;\n\n readonly #beforeCheckPendingTransaction: (\n transactionMeta: TransactionMeta,\n ) => boolean;\n\n readonly #beforePublish: (transactionMeta: TransactionMeta) => boolean;\n\n constructor({\n blockTracker,\n getChainId,\n getEthQuery,\n getNetworkClientId,\n getTransactions,\n isResubmitEnabled,\n getGlobalLock,\n publishTransaction,\n hooks,\n }: {\n blockTracker: BlockTracker;\n getChainId: () => string;\n getEthQuery: (networkClientId?: NetworkClientId) => EthQuery;\n getNetworkClientId: () => string;\n getTransactions: () => TransactionMeta[];\n isResubmitEnabled?: () => boolean;\n getGlobalLock: () => Promise<() => void>;\n publishTransaction: (\n ethQuery: EthQuery,\n transactionMeta: TransactionMeta,\n ) => Promise<string>;\n hooks?: {\n beforeCheckPendingTransaction?: (\n transactionMeta: TransactionMeta,\n ) => boolean;\n beforePublish?: (transactionMeta: TransactionMeta) => boolean;\n };\n }) {\n this.hub = new EventEmitter() as PendingTransactionTrackerEventEmitter;\n\n this.#droppedBlockCountByHash = new Map();\n this.#getChainId = getChainId;\n this.#getEthQuery = getEthQuery;\n this.#getNetworkClientId = getNetworkClientId;\n this.#getTransactions = getTransactions;\n this.#isResubmitEnabled = isResubmitEnabled ?? (() => true);\n this.#listener = this.#onLatestBlock.bind(this);\n this.#getGlobalLock = getGlobalLock;\n this.#publishTransaction = publishTransaction;\n this.#running = false;\n this.#transactionPoller = new TransactionPoller(blockTracker);\n this.#beforePublish = hooks?.beforePublish ?? (() => true);\n this.#beforeCheckPendingTransaction =\n hooks?.beforeCheckPendingTransaction ?? (() => true);\n\n this.#log = createModuleLogger(\n log,\n `${getChainId()}:${getNetworkClientId()}`,\n );\n }\n\n startIfPendingTransactions = () => {\n const pendingTransactions = this.#getPendingTransactions();\n\n if (pendingTransactions.length) {\n this.#start(pendingTransactions);\n } else {\n this.stop();\n }\n };\n\n /**\n * Force checks the network if the given transaction is confirmed and updates it's status.\n *\n * @param txMeta - The transaction to check\n */\n async forceCheckTransaction(txMeta: TransactionMeta) {\n const releaseLock = await this.#getGlobalLock();\n\n try {\n await this.#checkTransaction(txMeta);\n } catch (error) {\n /* istanbul ignore next */\n this.#log('Failed to check transaction', error);\n } finally {\n releaseLock();\n }\n }\n\n #start(pendingTransactions: TransactionMeta[]) {\n this.#transactionPoller.setPendingTransactions(pendingTransactions);\n\n if (this.#running) {\n return;\n }\n\n this.#transactionPoller.start(this.#listener);\n this.#running = true;\n\n this.#log('Started polling');\n }\n\n stop() {\n if (!this.#running) {\n return;\n }\n\n this.#transactionPoller.stop();\n this.#running = false;\n\n this.#log('Stopped polling');\n }\n\n async #onLatestBlock(latestBlockNumber: string) {\n const releaseLock = await this.#getGlobalLock();\n\n try {\n await this.#checkTransactions();\n } catch (error) {\n /* istanbul ignore next */\n this.#log('Failed to check transactions', error);\n } finally {\n releaseLock();\n }\n\n try {\n await this.#resubmitTransactions(latestBlockNumber);\n } catch (error) {\n /* istanbul ignore next */\n this.#log('Failed to resubmit transactions', error);\n }\n }\n\n async #checkTransactions() {\n this.#log('Checking transactions');\n\n const pendingTransactions = this.#getPendingTransactions();\n\n if (!pendingTransactions.length) {\n this.#log('No pending transactions to check');\n return;\n }\n\n this.#log('Found pending transactions to check', {\n count: pendingTransactions.length,\n ids: pendingTransactions.map((tx) => tx.id),\n });\n\n await Promise.all(\n pendingTransactions.map((tx) => this.#checkTransaction(tx)),\n );\n }\n\n async #resubmitTransactions(latestBlockNumber: string) {\n if (!this.#isResubmitEnabled() || !this.#running) {\n return;\n }\n\n this.#log('Resubmitting transactions');\n\n const pendingTransactions = this.#getPendingTransactions();\n\n if (!pendingTransactions.length) {\n this.#log('No pending transactions to resubmit');\n return;\n }\n\n this.#log('Found pending transactions to resubmit', {\n count: pendingTransactions.length,\n ids: pendingTransactions.map((tx) => tx.id),\n });\n\n for (const txMeta of pendingTransactions) {\n try {\n await this.#resubmitTransaction(txMeta, latestBlockNumber);\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n /* istanbul ignore next */\n const errorMessage =\n error.value?.message?.toLowerCase() ||\n error.message?.toLowerCase() ||\n String(error);\n\n if (this.#isKnownTransactionError(errorMessage)) {\n this.#log('Ignoring known transaction error', errorMessage);\n continue;\n }\n\n this.#warnTransaction(\n txMeta,\n error.message,\n 'There was an error when resubmitting this transaction.',\n );\n }\n }\n }\n\n #isKnownTransactionError(errorMessage: string) {\n return KNOWN_TRANSACTION_ERRORS.some((knownError) =>\n errorMessage.includes(knownError),\n );\n }\n\n async #resubmitTransaction(\n txMeta: TransactionMeta,\n latestBlockNumber: string,\n ) {\n if (!this.#isResubmitDue(txMeta, latestBlockNumber)) {\n return;\n }\n\n if (!this.#beforePublish(txMeta)) {\n return;\n }\n\n const ethQuery = this.#getEthQuery(txMeta.networkClientId);\n await this.#publishTransaction(ethQuery, txMeta);\n\n const retryCount = (txMeta.retryCount ?? 0) + 1;\n\n this.#updateTransaction(\n merge({}, txMeta, { retryCount }),\n 'PendingTransactionTracker:transaction-retry - Retry count increased',\n );\n }\n\n #isResubmitDue(txMeta: TransactionMeta, latestBlockNumber: string): boolean {\n const txMetaWithFirstRetryBlockNumber = cloneDeep(txMeta);\n\n if (!txMetaWithFirstRetryBlockNumber.firstRetryBlockNumber) {\n txMetaWithFirstRetryBlockNumber.firstRetryBlockNumber = latestBlockNumber;\n\n this.#updateTransaction(\n txMetaWithFirstRetryBlockNumber,\n 'PendingTransactionTracker:#isResubmitDue - First retry block number set',\n );\n }\n\n const { firstRetryBlockNumber } = txMetaWithFirstRetryBlockNumber;\n\n const blocksSinceFirstRetry =\n Number.parseInt(latestBlockNumber, 16) -\n Number.parseInt(firstRetryBlockNumber, 16);\n\n const retryCount = txMeta.retryCount || 0;\n\n // Exponential backoff to limit retries at publishing\n // Capped at ~15 minutes between retries\n const requiredBlocksSinceFirstRetry = Math.min(\n MAX_RETRY_BLOCK_DISTANCE,\n Math.pow(2, retryCount),\n );\n\n return blocksSinceFirstRetry >= requiredBlocksSinceFirstRetry;\n }\n\n async #checkTransaction(txMeta: TransactionMeta) {\n const { hash, id } = txMeta;\n\n if (!hash && this.#beforeCheckPendingTransaction(txMeta)) {\n const error = new Error(\n 'We had an error while submitting this transaction, please try again.',\n );\n\n error.name = 'NoTxHashError';\n\n this.#failTransaction(txMeta, error);\n\n return;\n }\n\n if (this.#isNonceTaken(txMeta)) {\n this.#log('Nonce already taken', id);\n this.#dropTransaction(txMeta);\n return;\n }\n\n try {\n const receipt = await this.#getTransactionReceipt(hash);\n const isSuccess = receipt?.status === RECEIPT_STATUS_SUCCESS;\n const isFailure = receipt?.status === RECEIPT_STATUS_FAILURE;\n\n if (isFailure) {\n this.#log('Transaction receipt has failed status');\n\n this.#failTransaction(\n txMeta,\n new Error('Transaction dropped or replaced'),\n );\n\n return;\n }\n\n const { blockNumber, blockHash } = receipt || {};\n\n if (isSuccess && blockNumber && blockHash) {\n await this.#onTransactionConfirmed(txMeta, {\n ...receipt,\n blockNumber,\n blockHash,\n });\n\n return;\n }\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n this.#log('Failed to check transaction', id, error);\n\n this.#warnTransaction(\n txMeta,\n error.message,\n 'There was a problem loading this transaction.',\n );\n\n return;\n }\n\n if (await this.#isTransactionDropped(txMeta)) {\n this.#dropTransaction(txMeta);\n }\n }\n\n async #onTransactionConfirmed(\n txMeta: TransactionMeta,\n receipt: SuccessfulTransactionReceipt,\n ) {\n const { id } = txMeta;\n const { blockHash } = receipt;\n\n this.#log('Transaction confirmed', id);\n\n const { baseFeePerGas, timestamp: blockTimestamp } =\n await this.#getBlockByHash(blockHash, false);\n\n const updatedTxMeta = cloneDeep(txMeta);\n updatedTxMeta.baseFeePerGas = baseFeePerGas;\n updatedTxMeta.blockTimestamp = blockTimestamp;\n updatedTxMeta.status = TransactionStatus.confirmed;\n updatedTxMeta.txParams = {\n ...updatedTxMeta.txParams,\n gasUsed: receipt.gasUsed,\n };\n updatedTxMeta.txReceipt = receipt;\n updatedTxMeta.verifiedOnBlockchain = true;\n\n this.#updateTransaction(\n updatedTxMeta,\n 'PendingTransactionTracker:#onTransactionConfirmed - Transaction confirmed',\n );\n\n this.hub.emit('transaction-confirmed', updatedTxMeta);\n }\n\n async #isTransactionDropped(txMeta: TransactionMeta) {\n const {\n hash,\n id,\n txParams: { nonce, from },\n } = txMeta;\n\n /* istanbul ignore next */\n if (!nonce || !hash) {\n return false;\n }\n\n const networkNextNonceHex = await this.#getNetworkTransactionCount(from);\n const networkNextNonceNumber = parseInt(networkNextNonceHex, 16);\n const nonceNumber = parseInt(nonce, 16);\n\n if (nonceNumber >= networkNextNonceNumber) {\n return false;\n }\n\n let droppedBlockCount = this.#droppedBlockCountByHash.get(hash);\n\n if (droppedBlockCount === undefined) {\n droppedBlockCount = 0;\n this.#droppedBlockCountByHash.set(hash, droppedBlockCount);\n }\n\n if (droppedBlockCount < DROPPED_BLOCK_COUNT) {\n this.#log('Incrementing dropped block count', { id, droppedBlockCount });\n this.#droppedBlockCountByHash.set(hash, droppedBlockCount + 1);\n return false;\n }\n\n this.#log('Hit dropped block count', id);\n\n this.#droppedBlockCountByHash.delete(hash);\n return true;\n }\n\n #isNonceTaken(txMeta: TransactionMeta): boolean {\n const { id, txParams } = txMeta;\n\n return this.#getChainTransactions().some(\n (tx) =>\n tx.id !== id &&\n tx.txParams.from === txParams.from &&\n tx.status === TransactionStatus.confirmed &&\n tx.txParams.nonce === txParams.nonce &&\n tx.type !== TransactionType.incoming,\n );\n }\n\n #getPendingTransactions(): TransactionMeta[] {\n return this.#getNetworkClientTransactions().filter(\n (tx) =>\n tx.status === TransactionStatus.submitted &&\n !tx.verifiedOnBlockchain &&\n !tx.isUserOperation,\n );\n }\n\n #warnTransaction(txMeta: TransactionMeta, error: string, message: string) {\n this.#updateTransaction(\n {\n ...txMeta,\n warning: { error, message },\n },\n 'PendingTransactionTracker:#warnTransaction - Warning added',\n );\n }\n\n #failTransaction(txMeta: TransactionMeta, error: Error) {\n this.#log('Transaction failed', txMeta.id, error);\n this.hub.emit('transaction-failed', txMeta, error);\n }\n\n #dropTransaction(txMeta: TransactionMeta) {\n this.#log('Transaction dropped', txMeta.id);\n this.hub.emit('transaction-dropped', txMeta);\n }\n\n #updateTransaction(txMeta: TransactionMeta, note: string) {\n this.hub.emit('transaction-updated', txMeta, note);\n }\n\n async #getTransactionReceipt(\n txHash?: string,\n ): Promise<TransactionReceipt | undefined> {\n return await query(this.#getEthQuery(), 'getTransactionReceipt', [txHash]);\n }\n\n async #getBlockByHash(\n blockHash: string,\n includeTransactionDetails: boolean,\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ): Promise<any> {\n return await query(this.#getEthQuery(), 'getBlockByHash', [\n blockHash,\n includeTransactionDetails,\n ]);\n }\n\n async #getNetworkTransactionCount(address: string): Promise<string> {\n return await query(this.#getEthQuery(), 'getTransactionCount', [address]);\n }\n\n #getChainTransactions(): TransactionMeta[] {\n const chainId = this.#getChainId();\n return this.#getTransactions().filter((tx) => tx.chainId === chainId);\n }\n\n #getNetworkClientTransactions(): TransactionMeta[] {\n const networkClientId = this.#getNetworkClientId();\n return this.#getTransactions().filter(\n (tx) => tx.networkClientId === networkClientId,\n );\n }\n}\n"]}
|
|
@@ -38,6 +38,7 @@ class TransactionPoller {
|
|
|
38
38
|
}
|
|
39
39
|
/**
|
|
40
40
|
* Start the poller with a listener that will be called on every interval.
|
|
41
|
+
*
|
|
41
42
|
* @param listener - The listener to call on every interval.
|
|
42
43
|
*/
|
|
43
44
|
start(listener) {
|
|
@@ -69,6 +70,7 @@ class TransactionPoller {
|
|
|
69
70
|
* Notify the poller of the pending transactions being monitored.
|
|
70
71
|
* This will reset to the accelerated polling and reset the count
|
|
71
72
|
* when new transactions are added or removed.
|
|
73
|
+
*
|
|
72
74
|
* @param pendingTransactions - The pending transactions to poll.
|
|
73
75
|
*/
|
|
74
76
|
setPendingTransactions(pendingTransactions) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransactionPoller.cjs","sourceRoot":"","sources":["../../src/helpers/TransactionPoller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AACA,2CAAqD;AACrD,mCAAiC;AAEjC,0CAA0C;AAG7B,QAAA,qBAAqB,GAAG,EAAE,CAAC;AAC3B,QAAA,oBAAoB,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,YAAY;AAE1D,MAAM,GAAG,GAAG,IAAA,0BAAkB,EAAC,sBAAa,EAAE,oBAAoB,CAAC,CAAC;AAEpE;;;;GAIG;AACH,MAAa,iBAAiB;IAe5B,YAAY,YAA0B;;QAdtC,8CAAoB,CAAC,EAAC;
|
|
1
|
+
{"version":3,"file":"TransactionPoller.cjs","sourceRoot":"","sources":["../../src/helpers/TransactionPoller.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BlockTracker } from '@metamask/network-controller';\nimport { createModuleLogger } from '@metamask/utils';\nimport { isEqual } from 'lodash';\n\nimport { projectLogger } from '../logger';\nimport type { TransactionMeta } from '../types';\n\nexport const ACCELERATED_COUNT_MAX = 10;\nexport const ACCELERATED_INTERVAL = 1000 * 3; // 3 Seconds\n\nconst log = createModuleLogger(projectLogger, 'transaction-poller');\n\n/**\n * Helper class to orchestrate when to poll pending transactions.\n * Initially starts polling via a timeout chain every 2 seconds up to 5 times.\n * Following that, it will poll on every new block via the block tracker.\n */\nexport class TransactionPoller {\n #acceleratedCount = 0;\n\n readonly #blockTracker: BlockTracker;\n\n #blockTrackerListener?: (latestBlockNumber: string) => void;\n\n #listener?: (latestBlockNumber: string) => Promise<void>;\n\n #pendingTransactions?: TransactionMeta[];\n\n #running = false;\n\n #timeout?: NodeJS.Timeout;\n\n constructor(blockTracker: BlockTracker) {\n this.#blockTracker = blockTracker;\n }\n\n /**\n * Start the poller with a listener that will be called on every interval.\n *\n * @param listener - The listener to call on every interval.\n */\n start(listener: (latestBlockNumber: string) => Promise<void>) {\n if (this.#running) {\n return;\n }\n\n this.#listener = listener;\n this.#running = true;\n\n this.#queue();\n\n log('Started');\n }\n\n /**\n * Stop the poller.\n * Remove all timeouts and block tracker listeners.\n */\n stop() {\n if (!this.#running) {\n return;\n }\n\n this.#running = false;\n this.#listener = undefined;\n this.#acceleratedCount = 0;\n this.#pendingTransactions = undefined;\n\n this.#stopTimeout();\n this.#stopBlockTracker();\n\n log('Stopped');\n }\n\n /**\n * Notify the poller of the pending transactions being monitored.\n * This will reset to the accelerated polling and reset the count\n * when new transactions are added or removed.\n *\n * @param pendingTransactions - The pending transactions to poll.\n */\n setPendingTransactions(pendingTransactions: TransactionMeta[]) {\n const currentPendingTransactionIds = (this.#pendingTransactions ?? []).map(\n (tx) => tx.id,\n );\n\n this.#pendingTransactions = pendingTransactions;\n\n const newPendingTransactionIds = pendingTransactions.map((tx) => tx.id);\n\n const hasUpdatedIds = !isEqual(\n currentPendingTransactionIds,\n newPendingTransactionIds,\n );\n\n if (!this.#running || !hasUpdatedIds) {\n return;\n }\n\n log('Detected new pending transactions', newPendingTransactionIds);\n\n this.#acceleratedCount = 0;\n\n if (this.#blockTrackerListener) {\n this.#stopBlockTracker();\n this.#queue();\n }\n }\n\n #queue() {\n if (!this.#running) {\n return;\n }\n\n if (this.#acceleratedCount >= ACCELERATED_COUNT_MAX) {\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.#blockTrackerListener = (latestBlockNumber) =>\n this.#interval(false, latestBlockNumber);\n\n this.#blockTracker.on('latest', this.#blockTrackerListener);\n\n log('Added block tracker listener');\n\n return;\n }\n\n this.#stopTimeout();\n\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.#timeout = setTimeout(async () => {\n await this.#interval(true);\n this.#queue();\n }, ACCELERATED_INTERVAL);\n }\n\n async #interval(isAccelerated: boolean, latestBlockNumber?: string) {\n if (isAccelerated) {\n log('Accelerated interval', this.#acceleratedCount + 1);\n } else {\n log('Block tracker interval', latestBlockNumber);\n }\n\n const latestBlockNumberFinal =\n latestBlockNumber ?? (await this.#blockTracker.getLatestBlock());\n\n await this.#listener?.(latestBlockNumberFinal);\n\n if (isAccelerated && this.#running) {\n this.#acceleratedCount += 1;\n }\n }\n\n #stopTimeout() {\n if (!this.#timeout) {\n return;\n }\n\n clearTimeout(this.#timeout);\n this.#timeout = undefined;\n }\n\n #stopBlockTracker() {\n if (!this.#blockTrackerListener) {\n return;\n }\n\n this.#blockTracker.removeListener('latest', this.#blockTrackerListener);\n this.#blockTrackerListener = undefined;\n }\n}\n"]}
|
|
@@ -12,6 +12,7 @@ export declare class TransactionPoller {
|
|
|
12
12
|
constructor(blockTracker: BlockTracker);
|
|
13
13
|
/**
|
|
14
14
|
* Start the poller with a listener that will be called on every interval.
|
|
15
|
+
*
|
|
15
16
|
* @param listener - The listener to call on every interval.
|
|
16
17
|
*/
|
|
17
18
|
start(listener: (latestBlockNumber: string) => Promise<void>): void;
|
|
@@ -24,6 +25,7 @@ export declare class TransactionPoller {
|
|
|
24
25
|
* Notify the poller of the pending transactions being monitored.
|
|
25
26
|
* This will reset to the accelerated polling and reset the count
|
|
26
27
|
* when new transactions are added or removed.
|
|
28
|
+
*
|
|
27
29
|
* @param pendingTransactions - The pending transactions to poll.
|
|
28
30
|
*/
|
|
29
31
|
setPendingTransactions(pendingTransactions: TransactionMeta[]): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransactionPoller.d.cts","sourceRoot":"","sources":["../../src/helpers/TransactionPoller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,qCAAqC;AAKjE,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAiB;AAEhD,eAAO,MAAM,qBAAqB,KAAK,CAAC;AACxC,eAAO,MAAM,oBAAoB,QAAW,CAAC;AAI7C;;;;GAIG;AACH,qBAAa,iBAAiB;;gBAehB,YAAY,EAAE,YAAY;IAItC
|
|
1
|
+
{"version":3,"file":"TransactionPoller.d.cts","sourceRoot":"","sources":["../../src/helpers/TransactionPoller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,qCAAqC;AAKjE,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAiB;AAEhD,eAAO,MAAM,qBAAqB,KAAK,CAAC;AACxC,eAAO,MAAM,oBAAoB,QAAW,CAAC;AAI7C;;;;GAIG;AACH,qBAAa,iBAAiB;;gBAehB,YAAY,EAAE,YAAY;IAItC;;;;OAIG;IACH,KAAK,CAAC,QAAQ,EAAE,CAAC,iBAAiB,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC;IAa5D;;;OAGG;IACH,IAAI;IAgBJ;;;;;;OAMG;IACH,sBAAsB,CAAC,mBAAmB,EAAE,eAAe,EAAE;CAwF9D"}
|
|
@@ -12,6 +12,7 @@ export declare class TransactionPoller {
|
|
|
12
12
|
constructor(blockTracker: BlockTracker);
|
|
13
13
|
/**
|
|
14
14
|
* Start the poller with a listener that will be called on every interval.
|
|
15
|
+
*
|
|
15
16
|
* @param listener - The listener to call on every interval.
|
|
16
17
|
*/
|
|
17
18
|
start(listener: (latestBlockNumber: string) => Promise<void>): void;
|
|
@@ -24,6 +25,7 @@ export declare class TransactionPoller {
|
|
|
24
25
|
* Notify the poller of the pending transactions being monitored.
|
|
25
26
|
* This will reset to the accelerated polling and reset the count
|
|
26
27
|
* when new transactions are added or removed.
|
|
28
|
+
*
|
|
27
29
|
* @param pendingTransactions - The pending transactions to poll.
|
|
28
30
|
*/
|
|
29
31
|
setPendingTransactions(pendingTransactions: TransactionMeta[]): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransactionPoller.d.mts","sourceRoot":"","sources":["../../src/helpers/TransactionPoller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,qCAAqC;AAKjE,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAiB;AAEhD,eAAO,MAAM,qBAAqB,KAAK,CAAC;AACxC,eAAO,MAAM,oBAAoB,QAAW,CAAC;AAI7C;;;;GAIG;AACH,qBAAa,iBAAiB;;gBAehB,YAAY,EAAE,YAAY;IAItC
|
|
1
|
+
{"version":3,"file":"TransactionPoller.d.mts","sourceRoot":"","sources":["../../src/helpers/TransactionPoller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,qCAAqC;AAKjE,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAiB;AAEhD,eAAO,MAAM,qBAAqB,KAAK,CAAC;AACxC,eAAO,MAAM,oBAAoB,QAAW,CAAC;AAI7C;;;;GAIG;AACH,qBAAa,iBAAiB;;gBAehB,YAAY,EAAE,YAAY;IAItC;;;;OAIG;IACH,KAAK,CAAC,QAAQ,EAAE,CAAC,iBAAiB,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC;IAa5D;;;OAGG;IACH,IAAI;IAgBJ;;;;;;OAMG;IACH,sBAAsB,CAAC,mBAAmB,EAAE,eAAe,EAAE;CAwF9D"}
|
|
@@ -36,6 +36,7 @@ export class TransactionPoller {
|
|
|
36
36
|
}
|
|
37
37
|
/**
|
|
38
38
|
* Start the poller with a listener that will be called on every interval.
|
|
39
|
+
*
|
|
39
40
|
* @param listener - The listener to call on every interval.
|
|
40
41
|
*/
|
|
41
42
|
start(listener) {
|
|
@@ -67,6 +68,7 @@ export class TransactionPoller {
|
|
|
67
68
|
* Notify the poller of the pending transactions being monitored.
|
|
68
69
|
* This will reset to the accelerated polling and reset the count
|
|
69
70
|
* when new transactions are added or removed.
|
|
71
|
+
*
|
|
70
72
|
* @param pendingTransactions - The pending transactions to poll.
|
|
71
73
|
*/
|
|
72
74
|
setPendingTransactions(pendingTransactions) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransactionPoller.mjs","sourceRoot":"","sources":["../../src/helpers/TransactionPoller.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,OAAO,EAAE,kBAAkB,EAAE,wBAAwB;;;AAGrD,OAAO,EAAE,aAAa,EAAE,sBAAkB;AAG1C,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,CAAC;AACxC,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,YAAY;AAE1D,MAAM,GAAG,GAAG,kBAAkB,CAAC,aAAa,EAAE,oBAAoB,CAAC,CAAC;AAEpE;;;;GAIG;AACH,MAAM,OAAO,iBAAiB;IAe5B,YAAY,YAA0B;;QAdtC,8CAAoB,CAAC,EAAC;
|
|
1
|
+
{"version":3,"file":"TransactionPoller.mjs","sourceRoot":"","sources":["../../src/helpers/TransactionPoller.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,OAAO,EAAE,kBAAkB,EAAE,wBAAwB;;;AAGrD,OAAO,EAAE,aAAa,EAAE,sBAAkB;AAG1C,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,CAAC;AACxC,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,YAAY;AAE1D,MAAM,GAAG,GAAG,kBAAkB,CAAC,aAAa,EAAE,oBAAoB,CAAC,CAAC;AAEpE;;;;GAIG;AACH,MAAM,OAAO,iBAAiB;IAe5B,YAAY,YAA0B;;QAdtC,8CAAoB,CAAC,EAAC;QAEb,kDAA4B;QAErC,0DAA4D;QAE5D,8CAAyD;QAEzD,yDAAyC;QAEzC,qCAAW,KAAK,EAAC;QAEjB,6CAA0B;QAGxB,uBAAA,IAAI,mCAAiB,YAAY,MAAA,CAAC;IACpC,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,QAAsD;QAC1D,IAAI,uBAAA,IAAI,kCAAS,EAAE;YACjB,OAAO;SACR;QAED,uBAAA,IAAI,+BAAa,QAAQ,MAAA,CAAC;QAC1B,uBAAA,IAAI,8BAAY,IAAI,MAAA,CAAC;QAErB,uBAAA,IAAI,8DAAO,MAAX,IAAI,CAAS,CAAC;QAEd,GAAG,CAAC,SAAS,CAAC,CAAC;IACjB,CAAC;IAED;;;OAGG;IACH,IAAI;QACF,IAAI,CAAC,uBAAA,IAAI,kCAAS,EAAE;YAClB,OAAO;SACR;QAED,uBAAA,IAAI,8BAAY,KAAK,MAAA,CAAC;QACtB,uBAAA,IAAI,+BAAa,SAAS,MAAA,CAAC;QAC3B,uBAAA,IAAI,uCAAqB,CAAC,MAAA,CAAC;QAC3B,uBAAA,IAAI,0CAAwB,SAAS,MAAA,CAAC;QAEtC,uBAAA,IAAI,oEAAa,MAAjB,IAAI,CAAe,CAAC;QACpB,uBAAA,IAAI,yEAAkB,MAAtB,IAAI,CAAoB,CAAC;QAEzB,GAAG,CAAC,SAAS,CAAC,CAAC;IACjB,CAAC;IAED;;;;;;OAMG;IACH,sBAAsB,CAAC,mBAAsC;QAC3D,MAAM,4BAA4B,GAAG,CAAC,uBAAA,IAAI,8CAAqB,IAAI,EAAE,CAAC,CAAC,GAAG,CACxE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CACd,CAAC;QAEF,uBAAA,IAAI,0CAAwB,mBAAmB,MAAA,CAAC;QAEhD,MAAM,wBAAwB,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAExE,MAAM,aAAa,GAAG,CAAC,OAAO,CAC5B,4BAA4B,EAC5B,wBAAwB,CACzB,CAAC;QAEF,IAAI,CAAC,uBAAA,IAAI,kCAAS,IAAI,CAAC,aAAa,EAAE;YACpC,OAAO;SACR;QAED,GAAG,CAAC,mCAAmC,EAAE,wBAAwB,CAAC,CAAC;QAEnE,uBAAA,IAAI,uCAAqB,CAAC,MAAA,CAAC;QAE3B,IAAI,uBAAA,IAAI,+CAAsB,EAAE;YAC9B,uBAAA,IAAI,yEAAkB,MAAtB,IAAI,CAAoB,CAAC;YACzB,uBAAA,IAAI,8DAAO,MAAX,IAAI,CAAS,CAAC;SACf;IACH,CAAC;CA8DF;;IA3DG,IAAI,CAAC,uBAAA,IAAI,kCAAS,EAAE;QAClB,OAAO;KACR;IAED,IAAI,uBAAA,IAAI,2CAAkB,IAAI,qBAAqB,EAAE;QACnD,kEAAkE;QAClE,uBAAA,IAAI,2CAAyB,CAAC,iBAAiB,EAAE,EAAE,CACjD,uBAAA,IAAI,iEAAU,MAAd,IAAI,EAAW,KAAK,EAAE,iBAAiB,CAAC,MAAA,CAAC;QAE3C,uBAAA,IAAI,uCAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,uBAAA,IAAI,+CAAsB,CAAC,CAAC;QAE5D,GAAG,CAAC,8BAA8B,CAAC,CAAC;QAEpC,OAAO;KACR;IAED,uBAAA,IAAI,oEAAa,MAAjB,IAAI,CAAe,CAAC;IAEpB,kEAAkE;IAClE,uBAAA,IAAI,8BAAY,UAAU,CAAC,KAAK,IAAI,EAAE;QACpC,MAAM,uBAAA,IAAI,iEAAU,MAAd,IAAI,EAAW,IAAI,CAAC,CAAC;QAC3B,uBAAA,IAAI,8DAAO,MAAX,IAAI,CAAS,CAAC;IAChB,CAAC,EAAE,oBAAoB,CAAC,MAAA,CAAC;AAC3B,CAAC,gCAED,KAAK,sCAAW,aAAsB,EAAE,iBAA0B;IAChE,IAAI,aAAa,EAAE;QACjB,GAAG,CAAC,sBAAsB,EAAE,uBAAA,IAAI,2CAAkB,GAAG,CAAC,CAAC,CAAC;KACzD;SAAM;QACL,GAAG,CAAC,wBAAwB,EAAE,iBAAiB,CAAC,CAAC;KAClD;IAED,MAAM,sBAAsB,GAC1B,iBAAiB,IAAI,CAAC,MAAM,uBAAA,IAAI,uCAAc,CAAC,cAAc,EAAE,CAAC,CAAC;IAEnE,MAAM,uBAAA,IAAI,mCAAU,EAAE,KAAhB,IAAI,EAAa,sBAAsB,CAAC,CAAC;IAE/C,IAAI,aAAa,IAAI,uBAAA,IAAI,kCAAS,EAAE;QAClC,2IAA0B,CAAC,MAAA,CAAC;KAC7B;AACH,CAAC;IAGC,IAAI,CAAC,uBAAA,IAAI,kCAAS,EAAE;QAClB,OAAO;KACR;IAED,YAAY,CAAC,uBAAA,IAAI,kCAAS,CAAC,CAAC;IAC5B,uBAAA,IAAI,8BAAY,SAAS,MAAA,CAAC;AAC5B,CAAC;IAGC,IAAI,CAAC,uBAAA,IAAI,+CAAsB,EAAE;QAC/B,OAAO;KACR;IAED,uBAAA,IAAI,uCAAc,CAAC,cAAc,CAAC,QAAQ,EAAE,uBAAA,IAAI,+CAAsB,CAAC,CAAC;IACxE,uBAAA,IAAI,2CAAyB,SAAS,MAAA,CAAC;AACzC,CAAC","sourcesContent":["import type { BlockTracker } from '@metamask/network-controller';\nimport { createModuleLogger } from '@metamask/utils';\nimport { isEqual } from 'lodash';\n\nimport { projectLogger } from '../logger';\nimport type { TransactionMeta } from '../types';\n\nexport const ACCELERATED_COUNT_MAX = 10;\nexport const ACCELERATED_INTERVAL = 1000 * 3; // 3 Seconds\n\nconst log = createModuleLogger(projectLogger, 'transaction-poller');\n\n/**\n * Helper class to orchestrate when to poll pending transactions.\n * Initially starts polling via a timeout chain every 2 seconds up to 5 times.\n * Following that, it will poll on every new block via the block tracker.\n */\nexport class TransactionPoller {\n #acceleratedCount = 0;\n\n readonly #blockTracker: BlockTracker;\n\n #blockTrackerListener?: (latestBlockNumber: string) => void;\n\n #listener?: (latestBlockNumber: string) => Promise<void>;\n\n #pendingTransactions?: TransactionMeta[];\n\n #running = false;\n\n #timeout?: NodeJS.Timeout;\n\n constructor(blockTracker: BlockTracker) {\n this.#blockTracker = blockTracker;\n }\n\n /**\n * Start the poller with a listener that will be called on every interval.\n *\n * @param listener - The listener to call on every interval.\n */\n start(listener: (latestBlockNumber: string) => Promise<void>) {\n if (this.#running) {\n return;\n }\n\n this.#listener = listener;\n this.#running = true;\n\n this.#queue();\n\n log('Started');\n }\n\n /**\n * Stop the poller.\n * Remove all timeouts and block tracker listeners.\n */\n stop() {\n if (!this.#running) {\n return;\n }\n\n this.#running = false;\n this.#listener = undefined;\n this.#acceleratedCount = 0;\n this.#pendingTransactions = undefined;\n\n this.#stopTimeout();\n this.#stopBlockTracker();\n\n log('Stopped');\n }\n\n /**\n * Notify the poller of the pending transactions being monitored.\n * This will reset to the accelerated polling and reset the count\n * when new transactions are added or removed.\n *\n * @param pendingTransactions - The pending transactions to poll.\n */\n setPendingTransactions(pendingTransactions: TransactionMeta[]) {\n const currentPendingTransactionIds = (this.#pendingTransactions ?? []).map(\n (tx) => tx.id,\n );\n\n this.#pendingTransactions = pendingTransactions;\n\n const newPendingTransactionIds = pendingTransactions.map((tx) => tx.id);\n\n const hasUpdatedIds = !isEqual(\n currentPendingTransactionIds,\n newPendingTransactionIds,\n );\n\n if (!this.#running || !hasUpdatedIds) {\n return;\n }\n\n log('Detected new pending transactions', newPendingTransactionIds);\n\n this.#acceleratedCount = 0;\n\n if (this.#blockTrackerListener) {\n this.#stopBlockTracker();\n this.#queue();\n }\n }\n\n #queue() {\n if (!this.#running) {\n return;\n }\n\n if (this.#acceleratedCount >= ACCELERATED_COUNT_MAX) {\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.#blockTrackerListener = (latestBlockNumber) =>\n this.#interval(false, latestBlockNumber);\n\n this.#blockTracker.on('latest', this.#blockTrackerListener);\n\n log('Added block tracker listener');\n\n return;\n }\n\n this.#stopTimeout();\n\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.#timeout = setTimeout(async () => {\n await this.#interval(true);\n this.#queue();\n }, ACCELERATED_INTERVAL);\n }\n\n async #interval(isAccelerated: boolean, latestBlockNumber?: string) {\n if (isAccelerated) {\n log('Accelerated interval', this.#acceleratedCount + 1);\n } else {\n log('Block tracker interval', latestBlockNumber);\n }\n\n const latestBlockNumberFinal =\n latestBlockNumber ?? (await this.#blockTracker.getLatestBlock());\n\n await this.#listener?.(latestBlockNumberFinal);\n\n if (isAccelerated && this.#running) {\n this.#acceleratedCount += 1;\n }\n }\n\n #stopTimeout() {\n if (!this.#timeout) {\n return;\n }\n\n clearTimeout(this.#timeout);\n this.#timeout = undefined;\n }\n\n #stopBlockTracker() {\n if (!this.#blockTrackerListener) {\n return;\n }\n\n this.#blockTracker.removeListener('latest', this.#blockTrackerListener);\n this.#blockTrackerListener = undefined;\n }\n}\n"]}
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AA0BA,qEAIiC;AAH/B,oHAAA,WAAW,OAAA;AACX,sHAAA,aAAa,OAAA;AACb,8HAAA,qBAAqB,OAAA;
|
|
1
|
+
{"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AA0BA,qEAIiC;AAH/B,oHAAA,WAAW,OAAA;AACX,sHAAA,aAAa,OAAA;AACb,8HAAA,qBAAqB,OAAA;AAmCvB,qCAUiB;AATf,4GAAA,mBAAmB,OAAA;AACnB,2GAAA,kBAAkB,OAAA;AAClB,4GAAA,mBAAmB,OAAA;AACnB,gHAAA,uBAAuB,OAAA;AACvB,gHAAA,uBAAuB,OAAA;AACvB,0GAAA,iBAAiB,OAAA;AACjB,wGAAA,eAAe,OAAA;AACf,qGAAA,YAAY,OAAA;AACZ,qGAAA,YAAY,OAAA;AAEd,+CAGyB;AAFvB,8HAAA,mCAAmC,OAAA;AACnC,yHAAA,8BAA8B,OAAA;AAEhC,iEAAoE;AAA3D,4HAAA,wBAAwB,OAAA;AACjC,iDAAwD;AAA/C,gHAAA,oBAAoB,OAAA;AAC7B,2CAGuB;AAFrB,6GAAA,oBAAoB,OAAA;AACpB,mHAAA,0BAA0B,OAAA;AAE5B,6CAAwC;AAA/B,sGAAA,SAAS,OAAA;AAClB,uGAAgI;AAAvH,+JAAA,mBAAmB,OAA6C;AACzE,+CAA2C;AAAlC,mGAAA,QAAQ,OAAA","sourcesContent":["export type {\n MethodData,\n Result,\n TransactionControllerActions,\n TransactionControllerEvents,\n TransactionControllerGetStateAction,\n TransactionControllerIncomingTransactionsReceivedEvent,\n TransactionControllerPostTransactionBalanceUpdatedEvent,\n TransactionControllerSpeedupTransactionAddedEvent,\n TransactionControllerState,\n TransactionControllerStateChangeEvent,\n TransactionControllerTransactionApprovedEvent,\n TransactionControllerTransactionConfirmedEvent,\n TransactionControllerTransactionDroppedEvent,\n TransactionControllerTransactionFailedEvent,\n TransactionControllerTransactionFinishedEvent,\n TransactionControllerTransactionNewSwapApprovalEvent,\n TransactionControllerTransactionNewSwapEvent,\n TransactionControllerTransactionPublishingSkipped,\n TransactionControllerTransactionRejectedEvent,\n TransactionControllerTransactionStatusUpdatedEvent,\n TransactionControllerTransactionSubmittedEvent,\n TransactionControllerUnapprovedTransactionAddedEvent,\n TransactionControllerMessenger,\n TransactionControllerOptions,\n} from './TransactionController';\nexport {\n CANCEL_RATE,\n SPEED_UP_RATE,\n TransactionController,\n} from './TransactionController';\nexport type {\n Authorization,\n AuthorizationList,\n BatchTransactionParams,\n DappSuggestedGasFees,\n DefaultGasEstimates,\n FeeMarketEIP1559Values,\n FeeMarketGasFeeEstimateForLevel,\n FeeMarketGasFeeEstimates,\n GasFeeEstimates,\n GasPriceGasFeeEstimates,\n GasPriceValue,\n InferTransactionTypeResult,\n LegacyGasFeeEstimates,\n Log,\n SavedGasFees,\n SecurityAlertResponse,\n SecurityProviderRequest,\n SendFlowHistoryEntry,\n SimulationBalanceChange,\n SimulationData,\n SimulationError,\n SimulationToken,\n SimulationTokenBalanceChange,\n TransactionBatchRequest,\n TransactionBatchResult,\n TransactionError,\n TransactionHistory,\n TransactionHistoryEntry,\n TransactionMeta,\n TransactionParams,\n TransactionReceipt,\n} from './types';\nexport {\n GasFeeEstimateLevel,\n GasFeeEstimateType,\n SimulationErrorCode,\n SimulationTokenStandard,\n TransactionEnvelopeType,\n TransactionStatus,\n TransactionType,\n UserFeeLevel,\n WalletDevice,\n} from './types';\nexport {\n DISPLAYED_TRANSACTION_HISTORY_PATHS,\n MAX_TRANSACTION_HISTORY_LENGTH,\n} from './utils/history';\nexport { determineTransactionType } from './utils/transaction-type';\nexport { mergeGasFeeEstimates } from './utils/gas-flow';\nexport {\n isEIP1559Transaction,\n normalizeTransactionParams,\n} from './utils/utils';\nexport { CHAIN_IDS } from './constants';\nexport { SUPPORTED_CHAIN_IDS as INCOMING_TRANSACTIONS_SUPPORTED_CHAIN_IDS } from './helpers/AccountsApiRemoteTransactionSource';\nexport { HARDFORK } from './utils/prepare';\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type { MethodData, Result, TransactionControllerActions, TransactionControllerEvents, TransactionControllerGetStateAction, TransactionControllerIncomingTransactionsReceivedEvent, TransactionControllerPostTransactionBalanceUpdatedEvent, TransactionControllerSpeedupTransactionAddedEvent, TransactionControllerState, TransactionControllerStateChangeEvent, TransactionControllerTransactionApprovedEvent, TransactionControllerTransactionConfirmedEvent, TransactionControllerTransactionDroppedEvent, TransactionControllerTransactionFailedEvent, TransactionControllerTransactionFinishedEvent, TransactionControllerTransactionNewSwapApprovalEvent, TransactionControllerTransactionNewSwapEvent, TransactionControllerTransactionPublishingSkipped, TransactionControllerTransactionRejectedEvent, TransactionControllerTransactionStatusUpdatedEvent, TransactionControllerTransactionSubmittedEvent, TransactionControllerUnapprovedTransactionAddedEvent, TransactionControllerMessenger, TransactionControllerOptions, } from "./TransactionController.cjs";
|
|
2
2
|
export { CANCEL_RATE, SPEED_UP_RATE, TransactionController, } from "./TransactionController.cjs";
|
|
3
|
-
export type { Authorization, AuthorizationList, DappSuggestedGasFees, DefaultGasEstimates, FeeMarketEIP1559Values, FeeMarketGasFeeEstimateForLevel, FeeMarketGasFeeEstimates, GasFeeEstimates, GasPriceGasFeeEstimates, GasPriceValue, InferTransactionTypeResult, LegacyGasFeeEstimates, Log, SavedGasFees, SecurityAlertResponse, SecurityProviderRequest, SendFlowHistoryEntry, SimulationBalanceChange, SimulationData, SimulationError, SimulationToken, SimulationTokenBalanceChange, TransactionError, TransactionHistory, TransactionHistoryEntry, TransactionMeta, TransactionParams, TransactionReceipt, } from "./types.cjs";
|
|
3
|
+
export type { Authorization, AuthorizationList, BatchTransactionParams, DappSuggestedGasFees, DefaultGasEstimates, FeeMarketEIP1559Values, FeeMarketGasFeeEstimateForLevel, FeeMarketGasFeeEstimates, GasFeeEstimates, GasPriceGasFeeEstimates, GasPriceValue, InferTransactionTypeResult, LegacyGasFeeEstimates, Log, SavedGasFees, SecurityAlertResponse, SecurityProviderRequest, SendFlowHistoryEntry, SimulationBalanceChange, SimulationData, SimulationError, SimulationToken, SimulationTokenBalanceChange, TransactionBatchRequest, TransactionBatchResult, TransactionError, TransactionHistory, TransactionHistoryEntry, TransactionMeta, TransactionParams, TransactionReceipt, } from "./types.cjs";
|
|
4
4
|
export { GasFeeEstimateLevel, GasFeeEstimateType, SimulationErrorCode, SimulationTokenStandard, TransactionEnvelopeType, TransactionStatus, TransactionType, UserFeeLevel, WalletDevice, } from "./types.cjs";
|
|
5
5
|
export { DISPLAYED_TRANSACTION_HISTORY_PATHS, MAX_TRANSACTION_HISTORY_LENGTH, } from "./utils/history.cjs";
|
|
6
6
|
export { determineTransactionType } from "./utils/transaction-type.cjs";
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,UAAU,EACV,MAAM,EACN,4BAA4B,EAC5B,2BAA2B,EAC3B,mCAAmC,EACnC,sDAAsD,EACtD,uDAAuD,EACvD,iDAAiD,EACjD,0BAA0B,EAC1B,qCAAqC,EACrC,6CAA6C,EAC7C,8CAA8C,EAC9C,4CAA4C,EAC5C,2CAA2C,EAC3C,6CAA6C,EAC7C,oDAAoD,EACpD,4CAA4C,EAC5C,iDAAiD,EACjD,6CAA6C,EAC7C,kDAAkD,EAClD,8CAA8C,EAC9C,oDAAoD,EACpD,8BAA8B,EAC9B,4BAA4B,GAC7B,oCAAgC;AACjC,OAAO,EACL,WAAW,EACX,aAAa,EACb,qBAAqB,GACtB,oCAAgC;AACjC,YAAY,EACV,aAAa,EACb,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,+BAA+B,EAC/B,wBAAwB,EACxB,eAAe,EACf,uBAAuB,EACvB,aAAa,EACb,0BAA0B,EAC1B,qBAAqB,EACrB,GAAG,EACH,YAAY,EACZ,qBAAqB,EACrB,uBAAuB,EACvB,oBAAoB,EACpB,uBAAuB,EACvB,cAAc,EACd,eAAe,EACf,eAAe,EACf,4BAA4B,EAC5B,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,eAAe,EACf,iBAAiB,EACjB,kBAAkB,GACnB,oBAAgB;AACjB,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,uBAAuB,EACvB,uBAAuB,EACvB,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,YAAY,GACb,oBAAgB;AACjB,OAAO,EACL,mCAAmC,EACnC,8BAA8B,GAC/B,4BAAwB;AACzB,OAAO,EAAE,wBAAwB,EAAE,qCAAiC;AACpE,OAAO,EAAE,oBAAoB,EAAE,6BAAyB;AACxD,OAAO,EACL,oBAAoB,EACpB,0BAA0B,GAC3B,0BAAsB;AACvB,OAAO,EAAE,SAAS,EAAE,wBAAoB;AACxC,OAAO,EAAE,mBAAmB,IAAI,yCAAyC,EAAE,yDAAqD;AAChI,OAAO,EAAE,QAAQ,EAAE,4BAAwB"}
|
|
1
|
+
{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,UAAU,EACV,MAAM,EACN,4BAA4B,EAC5B,2BAA2B,EAC3B,mCAAmC,EACnC,sDAAsD,EACtD,uDAAuD,EACvD,iDAAiD,EACjD,0BAA0B,EAC1B,qCAAqC,EACrC,6CAA6C,EAC7C,8CAA8C,EAC9C,4CAA4C,EAC5C,2CAA2C,EAC3C,6CAA6C,EAC7C,oDAAoD,EACpD,4CAA4C,EAC5C,iDAAiD,EACjD,6CAA6C,EAC7C,kDAAkD,EAClD,8CAA8C,EAC9C,oDAAoD,EACpD,8BAA8B,EAC9B,4BAA4B,GAC7B,oCAAgC;AACjC,OAAO,EACL,WAAW,EACX,aAAa,EACb,qBAAqB,GACtB,oCAAgC;AACjC,YAAY,EACV,aAAa,EACb,iBAAiB,EACjB,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,+BAA+B,EAC/B,wBAAwB,EACxB,eAAe,EACf,uBAAuB,EACvB,aAAa,EACb,0BAA0B,EAC1B,qBAAqB,EACrB,GAAG,EACH,YAAY,EACZ,qBAAqB,EACrB,uBAAuB,EACvB,oBAAoB,EACpB,uBAAuB,EACvB,cAAc,EACd,eAAe,EACf,eAAe,EACf,4BAA4B,EAC5B,uBAAuB,EACvB,sBAAsB,EACtB,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,eAAe,EACf,iBAAiB,EACjB,kBAAkB,GACnB,oBAAgB;AACjB,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,uBAAuB,EACvB,uBAAuB,EACvB,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,YAAY,GACb,oBAAgB;AACjB,OAAO,EACL,mCAAmC,EACnC,8BAA8B,GAC/B,4BAAwB;AACzB,OAAO,EAAE,wBAAwB,EAAE,qCAAiC;AACpE,OAAO,EAAE,oBAAoB,EAAE,6BAAyB;AACxD,OAAO,EACL,oBAAoB,EACpB,0BAA0B,GAC3B,0BAAsB;AACvB,OAAO,EAAE,SAAS,EAAE,wBAAoB;AACxC,OAAO,EAAE,mBAAmB,IAAI,yCAAyC,EAAE,yDAAqD;AAChI,OAAO,EAAE,QAAQ,EAAE,4BAAwB"}
|