@metamask/transaction-controller 18.2.0 → 18.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/CHANGELOG.md +372 -0
  2. package/dist/TransactionController.d.ts +10 -10
  3. package/dist/TransactionController.d.ts.map +1 -1
  4. package/dist/TransactionController.js +50 -38
  5. package/dist/TransactionController.js.map +1 -1
  6. package/dist/constants.js +1 -1
  7. package/dist/constants.js.map +1 -1
  8. package/dist/helpers/IncomingTransactionHelper.d.ts.map +1 -1
  9. package/dist/helpers/IncomingTransactionHelper.js +4 -0
  10. package/dist/helpers/IncomingTransactionHelper.js.map +1 -1
  11. package/dist/helpers/PendingTransactionTracker.d.ts +1 -2
  12. package/dist/helpers/PendingTransactionTracker.d.ts.map +1 -1
  13. package/dist/helpers/PendingTransactionTracker.js +24 -12
  14. package/dist/helpers/PendingTransactionTracker.js.map +1 -1
  15. package/dist/index.d.ts +1 -0
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +3 -1
  18. package/dist/index.js.map +1 -1
  19. package/dist/types.d.ts +4 -0
  20. package/dist/types.d.ts.map +1 -1
  21. package/dist/types.js.map +1 -1
  22. package/dist/utils/gas.d.ts.map +1 -1
  23. package/dist/utils/gas.js +2 -0
  24. package/dist/utils/gas.js.map +1 -1
  25. package/dist/utils/history.js +8 -2
  26. package/dist/utils/history.js.map +1 -1
  27. package/dist/utils/nonce.d.ts.map +1 -1
  28. package/dist/utils/nonce.js +2 -1
  29. package/dist/utils/nonce.js.map +1 -1
  30. package/dist/utils/swaps.js +4 -0
  31. package/dist/utils/swaps.js.map +1 -1
  32. package/dist/utils/transaction-type.d.ts.map +1 -1
  33. package/dist/utils/transaction-type.js +19 -12
  34. package/dist/utils/transaction-type.js.map +1 -1
  35. package/dist/utils/utils.d.ts.map +1 -1
  36. package/dist/utils/utils.js +6 -0
  37. package/dist/utils/utils.js.map +1 -1
  38. package/dist/utils/validation.js +2 -0
  39. package/dist/utils/validation.js.map +1 -1
  40. package/package.json +5 -5
  41. package/dist/EtherscanRemoteTransactionSource.d.ts +0 -15
  42. package/dist/EtherscanRemoteTransactionSource.d.ts.map +0 -1
  43. package/dist/EtherscanRemoteTransactionSource.js +0 -122
  44. package/dist/EtherscanRemoteTransactionSource.js.map +0 -1
  45. package/dist/IncomingTransactionHelper.d.ts +0 -25
  46. package/dist/IncomingTransactionHelper.d.ts.map +0 -1
  47. package/dist/IncomingTransactionHelper.js +0 -198
  48. package/dist/IncomingTransactionHelper.js.map +0 -1
  49. package/dist/etherscan.d.ts +0 -64
  50. package/dist/etherscan.d.ts.map +0 -1
  51. package/dist/etherscan.js +0 -109
  52. package/dist/etherscan.js.map +0 -1
  53. package/dist/external-transactions.d.ts +0 -10
  54. package/dist/external-transactions.d.ts.map +0 -1
  55. package/dist/external-transactions.js +0 -36
  56. package/dist/external-transactions.js.map +0 -1
  57. package/dist/history.d.ts +0 -15
  58. package/dist/history.d.ts.map +0 -1
  59. package/dist/history.js +0 -75
  60. package/dist/history.js.map +0 -1
  61. package/dist/mocks/txsMock.d.ts +0 -64
  62. package/dist/mocks/txsMock.d.ts.map +0 -1
  63. package/dist/mocks/txsMock.js +0 -515
  64. package/dist/mocks/txsMock.js.map +0 -1
  65. package/dist/transaction-type.d.ts +0 -14
  66. package/dist/transaction-type.d.ts.map +0 -1
  67. package/dist/transaction-type.js +0 -114
  68. package/dist/transaction-type.js.map +0 -1
  69. package/dist/utils.d.ts +0 -72
  70. package/dist/utils.d.ts.map +0 -1
  71. package/dist/utils.js +0 -235
  72. package/dist/utils.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"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","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport { ORIGIN_METAMASK, isValidHexAddress } from '@metamask/controller-utils';\nimport { abiERC20 } from '@metamask/metamask-eth-abis';\nimport { providerErrors, rpcErrors } from '@metamask/rpc-errors';\n\nimport { TransactionEnvelopeType, type TransactionParams } from '../types';\nimport { isEIP1559Transaction } from './utils';\n\ntype GasFieldsToValidate = 'gasPrice' | 'maxFeePerGas' | 'maxPriorityFeePerGas';\n\n/**\n * Validates whether a transaction initiated by a specific 'from' address is permitted by the origin.\n *\n * @param permittedAddresses - The permitted accounts for the given origin.\n * @param selectedAddress - The currently selected Ethereum address in the wallet.\n * @param from - The address from which the transaction is initiated.\n * @param origin - The origin or source of the transaction.\n * @throws Throws an error if the transaction is not permitted.\n */\nexport async function validateTransactionOrigin(\n permittedAddresses: string[],\n selectedAddress: string,\n from: string,\n origin: string,\n) {\n if (origin === ORIGIN_METAMASK) {\n // Ensure the 'from' address matches the currently selected address\n if (from !== selectedAddress) {\n throw rpcErrors.internal({\n message: `Internally initiated transaction is using invalid account.`,\n data: {\n origin,\n fromAddress: from,\n selectedAddress,\n },\n });\n }\n return;\n }\n\n // Check if the origin has permissions to initiate transactions from the specified address\n if (!permittedAddresses.includes(from)) {\n throw providerErrors.unauthorized({ data: { origin } });\n }\n}\n\n/**\n * Validates the transaction params for required properties and throws in\n * the event of any validation error.\n *\n * @param txParams - Transaction params object to validate.\n * @param isEIP1559Compatible - whether or not the current network supports EIP-1559 transactions.\n */\nexport function validateTxParams(\n txParams: TransactionParams,\n isEIP1559Compatible = true,\n) {\n validateEIP1559Compatibility(txParams, isEIP1559Compatible);\n validateParamFrom(txParams.from);\n validateParamRecipient(txParams);\n validateParamValue(txParams.value);\n validateParamData(txParams.data);\n validateParamChainId(txParams.chainId);\n validateGasFeeParams(txParams);\n}\n\n/**\n * Validates EIP-1559 compatibility for transaction creation.\n *\n * @param txParams - The transaction parameters to validate.\n * @param isEIP1559Compatible - Indicates if the current network supports EIP-1559.\n * @throws Throws invalid params if the transaction specifies EIP-1559 but the network does not support it.\n */\nfunction validateEIP1559Compatibility(\n txParams: TransactionParams,\n isEIP1559Compatible: boolean,\n) {\n if (isEIP1559Transaction(txParams) && !isEIP1559Compatible) {\n throw rpcErrors.invalidParams(\n 'Invalid transaction params: params specify an EIP-1559 transaction but the current network does not support EIP-1559',\n );\n }\n}\n\n/**\n * Validates value property, ensuring it is a valid positive integer number\n * denominated in wei.\n *\n * @param value - The value to validate, expressed as a string.\n * @throws Throws an error if the value is not a valid positive integer\n * number denominated in wei.\n * - If the value contains a hyphen (-), it is considered invalid.\n * - If the value contains a decimal point (.), it is considered invalid.\n * - If the value is not a finite number, is NaN, or is not a safe integer, it is considered invalid.\n */\nfunction validateParamValue(value?: string) {\n if (value !== undefined) {\n if (value.includes('-')) {\n throw rpcErrors.invalidParams(\n `Invalid transaction value \"${value}\": not a positive number.`,\n );\n }\n\n if (value.includes('.')) {\n throw rpcErrors.invalidParams(\n `Invalid transaction value \"${value}\": number must be in wei.`,\n );\n }\n const intValue = parseInt(value, 10);\n const isValid =\n Number.isFinite(intValue) &&\n !Number.isNaN(intValue) &&\n !isNaN(Number(value)) &&\n Number.isSafeInteger(intValue);\n if (!isValid) {\n throw rpcErrors.invalidParams(\n `Invalid transaction value ${value}: number must be a valid number.`,\n );\n }\n }\n}\n\n/**\n * Validates the recipient address in a transaction's parameters.\n *\n * @param txParams - The transaction parameters object to validate.\n * @throws Throws an error if the recipient address is invalid:\n * - If the recipient address is an empty string ('0x') or undefined and the transaction contains data,\n * the \"to\" field is removed from the transaction parameters.\n * - If the recipient address is not a valid hexadecimal Ethereum address, an error is thrown.\n */\nfunction validateParamRecipient(txParams: TransactionParams) {\n if (txParams.to === '0x' || txParams.to === undefined) {\n if (txParams.data) {\n delete txParams.to;\n } else {\n throw rpcErrors.invalidParams(`Invalid \"to\" address.`);\n }\n } else if (txParams.to !== undefined && !isValidHexAddress(txParams.to)) {\n throw rpcErrors.invalidParams(`Invalid \"to\" address.`);\n }\n}\n\n/**\n * Validates the recipient address in a transaction's parameters.\n *\n * @param from - The from property to validate.\n * @throws Throws an error if the recipient address is invalid:\n * - If the recipient address is an empty string ('0x') or undefined and the transaction contains data,\n * the \"to\" field is removed from the transaction parameters.\n * - If the recipient address is not a valid hexadecimal Ethereum address, an error is thrown.\n */\nfunction validateParamFrom(from: string) {\n if (!from || typeof from !== 'string') {\n throw rpcErrors.invalidParams(\n `Invalid \"from\" address ${from}: not a string.`,\n );\n }\n if (!isValidHexAddress(from)) {\n throw rpcErrors.invalidParams('Invalid \"from\" address.');\n }\n}\n\n/**\n * Validates input data for transactions.\n *\n * @param value - The input data to validate.\n * @throws Throws invalid params if the input data is invalid.\n */\nfunction validateParamData(value?: string) {\n if (value) {\n const ERC20Interface = new Interface(abiERC20);\n try {\n ERC20Interface.parseTransaction({ data: value });\n } catch (error: any) {\n if (error.message.match(/BUFFER_OVERRUN/u)) {\n throw rpcErrors.invalidParams(\n 'Invalid transaction params: data out-of-bounds, BUFFER_OVERRUN.',\n );\n }\n }\n }\n}\n\n/**\n * Validates chainId type.\n *\n * @param chainId - The chainId to validate.\n */\nfunction validateParamChainId(chainId: number | string | undefined) {\n if (\n chainId !== undefined &&\n typeof chainId !== 'number' &&\n typeof chainId !== 'string'\n ) {\n throw rpcErrors.invalidParams(\n `Invalid transaction params: chainId is not a Number or hex string. got: (${chainId})`,\n );\n }\n}\n\n/**\n * Validates gas values.\n *\n * @param txParams - The transaction parameters to validate.\n */\nfunction validateGasFeeParams(txParams: TransactionParams) {\n if (txParams.gasPrice) {\n ensureProperTransactionEnvelopeTypeProvided(txParams, 'gasPrice');\n ensureMutuallyExclusiveFieldsNotProvided(\n txParams,\n 'gasPrice',\n 'maxFeePerGas',\n );\n ensureMutuallyExclusiveFieldsNotProvided(\n txParams,\n 'gasPrice',\n 'maxPriorityFeePerGas',\n );\n ensureFieldIsString(txParams, 'gasPrice');\n }\n\n if (txParams.maxFeePerGas) {\n ensureProperTransactionEnvelopeTypeProvided(txParams, 'maxFeePerGas');\n ensureMutuallyExclusiveFieldsNotProvided(\n txParams,\n 'maxFeePerGas',\n 'gasPrice',\n );\n ensureFieldIsString(txParams, 'maxFeePerGas');\n }\n\n if (txParams.maxPriorityFeePerGas) {\n ensureProperTransactionEnvelopeTypeProvided(\n txParams,\n 'maxPriorityFeePerGas',\n );\n ensureMutuallyExclusiveFieldsNotProvided(\n txParams,\n 'maxPriorityFeePerGas',\n 'gasPrice',\n );\n ensureFieldIsString(txParams, 'maxPriorityFeePerGas');\n }\n}\n\n/**\n * Ensures that the provided txParams has the proper 'type' specified for the\n * given field, if it is provided. If types do not match throws an\n * invalidParams error.\n *\n * @param txParams - The transaction parameters object\n * @param field - The current field being validated\n * @throws {ethErrors.rpc.invalidParams} Throws if type does not match the\n * expectations for provided field.\n */\nfunction ensureProperTransactionEnvelopeTypeProvided(\n txParams: TransactionParams,\n field: GasFieldsToValidate,\n) {\n switch (field) {\n case 'maxFeePerGas':\n case 'maxPriorityFeePerGas':\n if (\n txParams.type &&\n txParams.type !== TransactionEnvelopeType.feeMarket\n ) {\n throw rpcErrors.invalidParams(\n `Invalid transaction envelope type: specified type \"${txParams.type}\" but including maxFeePerGas and maxPriorityFeePerGas requires type: \"${TransactionEnvelopeType.feeMarket}\"`,\n );\n }\n break;\n case 'gasPrice':\n default:\n if (\n txParams.type &&\n txParams.type === TransactionEnvelopeType.feeMarket\n ) {\n throw rpcErrors.invalidParams(\n `Invalid transaction envelope type: specified type \"${txParams.type}\" but included a gasPrice instead of maxFeePerGas and maxPriorityFeePerGas`,\n );\n }\n }\n}\n\n/**\n * Given two fields, ensure that the second field is not included in txParams,\n * and if it is throw an invalidParams error.\n *\n * @param txParams - The transaction parameters object\n * @param fieldBeingValidated - The current field being validated\n * @param mutuallyExclusiveField - The field to ensure is not provided\n * @throws {ethErrors.rpc.invalidParams} Throws if mutuallyExclusiveField is\n * present in txParams.\n */\nfunction ensureMutuallyExclusiveFieldsNotProvided(\n txParams: TransactionParams,\n fieldBeingValidated: GasFieldsToValidate,\n mutuallyExclusiveField: GasFieldsToValidate,\n) {\n if (typeof txParams[mutuallyExclusiveField] !== 'undefined') {\n throw rpcErrors.invalidParams(\n `Invalid transaction params: specified ${fieldBeingValidated} but also included ${mutuallyExclusiveField}, these cannot be mixed`,\n );\n }\n}\n\n/**\n * Ensures that the provided value for field is a string, throws an\n * invalidParams error if field is not a string.\n *\n * @param txParams - The transaction parameters object\n * @param field - The current field being validated\n * @throws {rpcErrors.invalidParams} Throws if field is not a string\n */\nfunction ensureFieldIsString(\n txParams: TransactionParams,\n field: GasFieldsToValidate,\n) {\n if (typeof txParams[field] !== 'string') {\n throw rpcErrors.invalidParams(\n `Invalid transaction params: ${field} is not a string. got: (${txParams[field]})`,\n );\n }\n}\n"]}
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"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","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport { ORIGIN_METAMASK, isValidHexAddress } from '@metamask/controller-utils';\nimport { abiERC20 } from '@metamask/metamask-eth-abis';\nimport { providerErrors, rpcErrors } from '@metamask/rpc-errors';\n\nimport { TransactionEnvelopeType, type TransactionParams } from '../types';\nimport { isEIP1559Transaction } from './utils';\n\ntype GasFieldsToValidate = 'gasPrice' | 'maxFeePerGas' | 'maxPriorityFeePerGas';\n\n/**\n * Validates whether a transaction initiated by a specific 'from' address is permitted by the origin.\n *\n * @param permittedAddresses - The permitted accounts for the given origin.\n * @param selectedAddress - The currently selected Ethereum address in the wallet.\n * @param from - The address from which the transaction is initiated.\n * @param origin - The origin or source of the transaction.\n * @throws Throws an error if the transaction is not permitted.\n */\nexport async function validateTransactionOrigin(\n permittedAddresses: string[],\n selectedAddress: string,\n from: string,\n origin: string,\n) {\n if (origin === ORIGIN_METAMASK) {\n // Ensure the 'from' address matches the currently selected address\n if (from !== selectedAddress) {\n throw rpcErrors.internal({\n message: `Internally initiated transaction is using invalid account.`,\n data: {\n origin,\n fromAddress: from,\n selectedAddress,\n },\n });\n }\n return;\n }\n\n // Check if the origin has permissions to initiate transactions from the specified address\n if (!permittedAddresses.includes(from)) {\n throw providerErrors.unauthorized({ data: { origin } });\n }\n}\n\n/**\n * Validates the transaction params for required properties and throws in\n * the event of any validation error.\n *\n * @param txParams - Transaction params object to validate.\n * @param isEIP1559Compatible - whether or not the current network supports EIP-1559 transactions.\n */\nexport function validateTxParams(\n txParams: TransactionParams,\n isEIP1559Compatible = true,\n) {\n validateEIP1559Compatibility(txParams, isEIP1559Compatible);\n validateParamFrom(txParams.from);\n validateParamRecipient(txParams);\n validateParamValue(txParams.value);\n validateParamData(txParams.data);\n validateParamChainId(txParams.chainId);\n validateGasFeeParams(txParams);\n}\n\n/**\n * Validates EIP-1559 compatibility for transaction creation.\n *\n * @param txParams - The transaction parameters to validate.\n * @param isEIP1559Compatible - Indicates if the current network supports EIP-1559.\n * @throws Throws invalid params if the transaction specifies EIP-1559 but the network does not support it.\n */\nfunction validateEIP1559Compatibility(\n txParams: TransactionParams,\n isEIP1559Compatible: boolean,\n) {\n if (isEIP1559Transaction(txParams) && !isEIP1559Compatible) {\n throw rpcErrors.invalidParams(\n 'Invalid transaction params: params specify an EIP-1559 transaction but the current network does not support EIP-1559',\n );\n }\n}\n\n/**\n * Validates value property, ensuring it is a valid positive integer number\n * denominated in wei.\n *\n * @param value - The value to validate, expressed as a string.\n * @throws Throws an error if the value is not a valid positive integer\n * number denominated in wei.\n * - If the value contains a hyphen (-), it is considered invalid.\n * - If the value contains a decimal point (.), it is considered invalid.\n * - If the value is not a finite number, is NaN, or is not a safe integer, it is considered invalid.\n */\nfunction validateParamValue(value?: string) {\n if (value !== undefined) {\n if (value.includes('-')) {\n throw rpcErrors.invalidParams(\n `Invalid transaction value \"${value}\": not a positive number.`,\n );\n }\n\n if (value.includes('.')) {\n throw rpcErrors.invalidParams(\n `Invalid transaction value \"${value}\": number must be in wei.`,\n );\n }\n const intValue = parseInt(value, 10);\n const isValid =\n Number.isFinite(intValue) &&\n !Number.isNaN(intValue) &&\n !isNaN(Number(value)) &&\n Number.isSafeInteger(intValue);\n if (!isValid) {\n throw rpcErrors.invalidParams(\n `Invalid transaction value ${value}: number must be a valid number.`,\n );\n }\n }\n}\n\n/**\n * Validates the recipient address in a transaction's parameters.\n *\n * @param txParams - The transaction parameters object to validate.\n * @throws Throws an error if the recipient address is invalid:\n * - If the recipient address is an empty string ('0x') or undefined and the transaction contains data,\n * the \"to\" field is removed from the transaction parameters.\n * - If the recipient address is not a valid hexadecimal Ethereum address, an error is thrown.\n */\nfunction validateParamRecipient(txParams: TransactionParams) {\n if (txParams.to === '0x' || txParams.to === undefined) {\n if (txParams.data) {\n delete txParams.to;\n } else {\n throw rpcErrors.invalidParams(`Invalid \"to\" address.`);\n }\n } else if (txParams.to !== undefined && !isValidHexAddress(txParams.to)) {\n throw rpcErrors.invalidParams(`Invalid \"to\" address.`);\n }\n}\n\n/**\n * Validates the recipient address in a transaction's parameters.\n *\n * @param from - The from property to validate.\n * @throws Throws an error if the recipient address is invalid:\n * - If the recipient address is an empty string ('0x') or undefined and the transaction contains data,\n * the \"to\" field is removed from the transaction parameters.\n * - If the recipient address is not a valid hexadecimal Ethereum address, an error is thrown.\n */\nfunction validateParamFrom(from: string) {\n if (!from || typeof from !== 'string') {\n throw rpcErrors.invalidParams(\n `Invalid \"from\" address ${from}: not a string.`,\n );\n }\n if (!isValidHexAddress(from)) {\n throw rpcErrors.invalidParams('Invalid \"from\" address.');\n }\n}\n\n/**\n * Validates input data for transactions.\n *\n * @param value - The input data to validate.\n * @throws Throws invalid params if the input data is invalid.\n */\nfunction validateParamData(value?: string) {\n if (value) {\n const ERC20Interface = new Interface(abiERC20);\n try {\n ERC20Interface.parseTransaction({ data: value });\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n if (error.message.match(/BUFFER_OVERRUN/u)) {\n throw rpcErrors.invalidParams(\n 'Invalid transaction params: data out-of-bounds, BUFFER_OVERRUN.',\n );\n }\n }\n }\n}\n\n/**\n * Validates chainId type.\n *\n * @param chainId - The chainId to validate.\n */\nfunction validateParamChainId(chainId: number | string | undefined) {\n if (\n chainId !== undefined &&\n typeof chainId !== 'number' &&\n typeof chainId !== 'string'\n ) {\n throw rpcErrors.invalidParams(\n `Invalid transaction params: chainId is not a Number or hex string. got: (${chainId})`,\n );\n }\n}\n\n/**\n * Validates gas values.\n *\n * @param txParams - The transaction parameters to validate.\n */\nfunction validateGasFeeParams(txParams: TransactionParams) {\n if (txParams.gasPrice) {\n ensureProperTransactionEnvelopeTypeProvided(txParams, 'gasPrice');\n ensureMutuallyExclusiveFieldsNotProvided(\n txParams,\n 'gasPrice',\n 'maxFeePerGas',\n );\n ensureMutuallyExclusiveFieldsNotProvided(\n txParams,\n 'gasPrice',\n 'maxPriorityFeePerGas',\n );\n ensureFieldIsString(txParams, 'gasPrice');\n }\n\n if (txParams.maxFeePerGas) {\n ensureProperTransactionEnvelopeTypeProvided(txParams, 'maxFeePerGas');\n ensureMutuallyExclusiveFieldsNotProvided(\n txParams,\n 'maxFeePerGas',\n 'gasPrice',\n );\n ensureFieldIsString(txParams, 'maxFeePerGas');\n }\n\n if (txParams.maxPriorityFeePerGas) {\n ensureProperTransactionEnvelopeTypeProvided(\n txParams,\n 'maxPriorityFeePerGas',\n );\n ensureMutuallyExclusiveFieldsNotProvided(\n txParams,\n 'maxPriorityFeePerGas',\n 'gasPrice',\n );\n ensureFieldIsString(txParams, 'maxPriorityFeePerGas');\n }\n}\n\n/**\n * Ensures that the provided txParams has the proper 'type' specified for the\n * given field, if it is provided. If types do not match throws an\n * invalidParams error.\n *\n * @param txParams - The transaction parameters object\n * @param field - The current field being validated\n * @throws {ethErrors.rpc.invalidParams} Throws if type does not match the\n * expectations for provided field.\n */\nfunction ensureProperTransactionEnvelopeTypeProvided(\n txParams: TransactionParams,\n field: GasFieldsToValidate,\n) {\n switch (field) {\n case 'maxFeePerGas':\n case 'maxPriorityFeePerGas':\n if (\n txParams.type &&\n txParams.type !== TransactionEnvelopeType.feeMarket\n ) {\n throw rpcErrors.invalidParams(\n `Invalid transaction envelope type: specified type \"${txParams.type}\" but including maxFeePerGas and maxPriorityFeePerGas requires type: \"${TransactionEnvelopeType.feeMarket}\"`,\n );\n }\n break;\n case 'gasPrice':\n default:\n if (\n txParams.type &&\n txParams.type === TransactionEnvelopeType.feeMarket\n ) {\n throw rpcErrors.invalidParams(\n `Invalid transaction envelope type: specified type \"${txParams.type}\" but included a gasPrice instead of maxFeePerGas and maxPriorityFeePerGas`,\n );\n }\n }\n}\n\n/**\n * Given two fields, ensure that the second field is not included in txParams,\n * and if it is throw an invalidParams error.\n *\n * @param txParams - The transaction parameters object\n * @param fieldBeingValidated - The current field being validated\n * @param mutuallyExclusiveField - The field to ensure is not provided\n * @throws {ethErrors.rpc.invalidParams} Throws if mutuallyExclusiveField is\n * present in txParams.\n */\nfunction ensureMutuallyExclusiveFieldsNotProvided(\n txParams: TransactionParams,\n fieldBeingValidated: GasFieldsToValidate,\n mutuallyExclusiveField: GasFieldsToValidate,\n) {\n if (typeof txParams[mutuallyExclusiveField] !== 'undefined') {\n throw rpcErrors.invalidParams(\n `Invalid transaction params: specified ${fieldBeingValidated} but also included ${mutuallyExclusiveField}, these cannot be mixed`,\n );\n }\n}\n\n/**\n * Ensures that the provided value for field is a string, throws an\n * invalidParams error if field is not a string.\n *\n * @param txParams - The transaction parameters object\n * @param field - The current field being validated\n * @throws {rpcErrors.invalidParams} Throws if field is not a string\n */\nfunction ensureFieldIsString(\n txParams: TransactionParams,\n field: GasFieldsToValidate,\n) {\n if (typeof txParams[field] !== 'string') {\n throw rpcErrors.invalidParams(\n `Invalid transaction params: ${field} is not a string. got: (${txParams[field]})`,\n );\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask/transaction-controller",
3
- "version": "18.2.0",
3
+ "version": "18.3.1",
4
4
  "description": "Stores transactions alongside their periodically updated statuses and manages interactions such as approval and cancellation",
5
5
  "keywords": [
6
6
  "MetaMask",
@@ -33,9 +33,9 @@
33
33
  "@ethereumjs/common": "^3.2.0",
34
34
  "@ethereumjs/tx": "^4.2.0",
35
35
  "@ethersproject/abi": "^5.7.0",
36
- "@metamask/approval-controller": "^5.0.0",
36
+ "@metamask/approval-controller": "^5.1.0",
37
37
  "@metamask/base-controller": "^4.0.0",
38
- "@metamask/controller-utils": "^6.1.0",
38
+ "@metamask/controller-utils": "^8.0.0",
39
39
  "@metamask/eth-query": "^4.0.0",
40
40
  "@metamask/gas-fee-controller": "^11.0.0",
41
41
  "@metamask/metamask-eth-abis": "^3.0.0",
@@ -65,7 +65,7 @@
65
65
  "typescript": "~4.8.4"
66
66
  },
67
67
  "peerDependencies": {
68
- "@metamask/approval-controller": "^5.0.0",
68
+ "@metamask/approval-controller": "^5.1.0",
69
69
  "@metamask/gas-fee-controller": "^11.0.0",
70
70
  "@metamask/network-controller": "^17.0.0",
71
71
  "babel-runtime": "^6.26.0"
@@ -77,4 +77,4 @@
77
77
  "access": "public",
78
78
  "registry": "https://registry.npmjs.org/"
79
79
  }
80
- }
80
+ }
@@ -1,15 +0,0 @@
1
- import type { Hex } from '@metamask/utils';
2
- import type { RemoteTransactionSource, RemoteTransactionSourceRequest, TransactionMeta } from './types';
3
- /**
4
- * A RemoteTransactionSource that fetches transaction data from Etherscan.
5
- */
6
- export declare class EtherscanRemoteTransactionSource implements RemoteTransactionSource {
7
- #private;
8
- constructor({ includeTokenTransfers, }?: {
9
- includeTokenTransfers?: boolean;
10
- });
11
- isSupportedNetwork(chainId: Hex): boolean;
12
- getLastBlockVariations(): string[];
13
- fetchTransactions(request: RemoteTransactionSourceRequest): Promise<TransactionMeta[]>;
14
- }
15
- //# sourceMappingURL=EtherscanRemoteTransactionSource.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"EtherscanRemoteTransactionSource.d.ts","sourceRoot":"","sources":["../src/EtherscanRemoteTransactionSource.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAiB3C,OAAO,KAAK,EACV,uBAAuB,EACvB,8BAA8B,EAC9B,eAAe,EAChB,MAAM,SAAS,CAAC;AAGjB;;GAEG;AACH,qBAAa,gCACX,YAAW,uBAAuB;;gBAMtB,EACV,qBAAqB,GACtB,GAAE;QAAE,qBAAqB,CAAC,EAAE,OAAO,CAAA;KAAO;IAK3C,kBAAkB,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO;IAIzC,sBAAsB,IAAI,MAAM,EAAE;IAI5B,iBAAiB,CACrB,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,eAAe,EAAE,CAAC;CAkI9B"}
@@ -1,122 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
12
- if (kind === "m") throw new TypeError("Private method is not writable");
13
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
14
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
15
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
16
- };
17
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
18
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
19
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
20
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
21
- };
22
- var _EtherscanRemoteTransactionSource_instances, _EtherscanRemoteTransactionSource_includeTokenTransfers, _EtherscanRemoteTransactionSource_isTokenRequestPending, _EtherscanRemoteTransactionSource_fetchNormalTransactions, _EtherscanRemoteTransactionSource_fetchTokenTransactions, _EtherscanRemoteTransactionSource_getResponseTransactions, _EtherscanRemoteTransactionSource_normalizeTransaction, _EtherscanRemoteTransactionSource_normalizeTokenTransaction, _EtherscanRemoteTransactionSource_normalizeTransactionBase;
23
- Object.defineProperty(exports, "__esModule", { value: true });
24
- exports.EtherscanRemoteTransactionSource = void 0;
25
- const controller_utils_1 = require("@metamask/controller-utils");
26
- const ethereumjs_util_1 = require("ethereumjs-util");
27
- const uuid_1 = require("uuid");
28
- const constants_1 = require("./constants");
29
- const etherscan_1 = require("./etherscan");
30
- const logger_1 = require("./logger");
31
- const types_1 = require("./types");
32
- /**
33
- * A RemoteTransactionSource that fetches transaction data from Etherscan.
34
- */
35
- class EtherscanRemoteTransactionSource {
36
- constructor({ includeTokenTransfers, } = {}) {
37
- _EtherscanRemoteTransactionSource_instances.add(this);
38
- _EtherscanRemoteTransactionSource_includeTokenTransfers.set(this, void 0);
39
- _EtherscanRemoteTransactionSource_isTokenRequestPending.set(this, void 0);
40
- _EtherscanRemoteTransactionSource_fetchNormalTransactions.set(this, (request, etherscanRequest) => __awaiter(this, void 0, void 0, function* () {
41
- const { currentChainId } = request;
42
- const etherscanTransactions = yield (0, etherscan_1.fetchEtherscanTransactions)(etherscanRequest);
43
- return __classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_instances, "m", _EtherscanRemoteTransactionSource_getResponseTransactions).call(this, etherscanTransactions).map((tx) => __classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_instances, "m", _EtherscanRemoteTransactionSource_normalizeTransaction).call(this, tx, currentChainId));
44
- }));
45
- _EtherscanRemoteTransactionSource_fetchTokenTransactions.set(this, (request, etherscanRequest) => __awaiter(this, void 0, void 0, function* () {
46
- const { currentChainId } = request;
47
- const etherscanTransactions = yield (0, etherscan_1.fetchEtherscanTokenTransactions)(etherscanRequest);
48
- return __classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_instances, "m", _EtherscanRemoteTransactionSource_getResponseTransactions).call(this, etherscanTransactions).map((tx) => __classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_instances, "m", _EtherscanRemoteTransactionSource_normalizeTokenTransaction).call(this, tx, currentChainId));
49
- }));
50
- __classPrivateFieldSet(this, _EtherscanRemoteTransactionSource_includeTokenTransfers, includeTokenTransfers !== null && includeTokenTransfers !== void 0 ? includeTokenTransfers : true, "f");
51
- __classPrivateFieldSet(this, _EtherscanRemoteTransactionSource_isTokenRequestPending, false, "f");
52
- }
53
- isSupportedNetwork(chainId) {
54
- return Object.keys(constants_1.ETHERSCAN_SUPPORTED_NETWORKS).includes(chainId);
55
- }
56
- getLastBlockVariations() {
57
- return [__classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_isTokenRequestPending, "f") ? 'token' : 'normal'];
58
- }
59
- fetchTransactions(request) {
60
- return __awaiter(this, void 0, void 0, function* () {
61
- const etherscanRequest = Object.assign(Object.assign({}, request), { chainId: request.currentChainId });
62
- const transactions = __classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_isTokenRequestPending, "f")
63
- ? yield __classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_fetchTokenTransactions, "f").call(this, request, etherscanRequest)
64
- : yield __classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_fetchNormalTransactions, "f").call(this, request, etherscanRequest);
65
- if (__classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_includeTokenTransfers, "f")) {
66
- __classPrivateFieldSet(this, _EtherscanRemoteTransactionSource_isTokenRequestPending, !__classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_isTokenRequestPending, "f"), "f");
67
- }
68
- return transactions;
69
- });
70
- }
71
- }
72
- exports.EtherscanRemoteTransactionSource = EtherscanRemoteTransactionSource;
73
- _EtherscanRemoteTransactionSource_includeTokenTransfers = new WeakMap(), _EtherscanRemoteTransactionSource_isTokenRequestPending = new WeakMap(), _EtherscanRemoteTransactionSource_fetchNormalTransactions = new WeakMap(), _EtherscanRemoteTransactionSource_fetchTokenTransactions = new WeakMap(), _EtherscanRemoteTransactionSource_instances = new WeakSet(), _EtherscanRemoteTransactionSource_getResponseTransactions = function _EtherscanRemoteTransactionSource_getResponseTransactions(response) {
74
- let result = response.result;
75
- if (response.status === '0') {
76
- result = [];
77
- if (response.result.length) {
78
- (0, logger_1.incomingTransactionsLogger)('Ignored Etherscan request error', {
79
- message: response.result,
80
- type: __classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_isTokenRequestPending, "f") ? 'token' : 'normal',
81
- });
82
- }
83
- }
84
- return result;
85
- }, _EtherscanRemoteTransactionSource_normalizeTransaction = function _EtherscanRemoteTransactionSource_normalizeTransaction(txMeta, currentChainId) {
86
- const base = __classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_instances, "m", _EtherscanRemoteTransactionSource_normalizeTransactionBase).call(this, txMeta, currentChainId);
87
- return Object.assign(Object.assign(Object.assign({}, base), { txParams: Object.assign(Object.assign({}, base.txParams), { data: txMeta.input }) }), (txMeta.isError === '0'
88
- ? { status: types_1.TransactionStatus.confirmed }
89
- : {
90
- error: new Error('Transaction failed'),
91
- status: types_1.TransactionStatus.failed,
92
- }));
93
- }, _EtherscanRemoteTransactionSource_normalizeTokenTransaction = function _EtherscanRemoteTransactionSource_normalizeTokenTransaction(txMeta, currentChainId) {
94
- const base = __classPrivateFieldGet(this, _EtherscanRemoteTransactionSource_instances, "m", _EtherscanRemoteTransactionSource_normalizeTransactionBase).call(this, txMeta, currentChainId);
95
- return Object.assign(Object.assign({}, base), { isTransfer: true, transferInformation: {
96
- contractAddress: txMeta.contractAddress,
97
- decimals: Number(txMeta.tokenDecimal),
98
- symbol: txMeta.tokenSymbol,
99
- } });
100
- }, _EtherscanRemoteTransactionSource_normalizeTransactionBase = function _EtherscanRemoteTransactionSource_normalizeTransactionBase(txMeta, currentChainId) {
101
- const time = parseInt(txMeta.timeStamp, 10) * 1000;
102
- return {
103
- blockNumber: txMeta.blockNumber,
104
- chainId: currentChainId,
105
- hash: txMeta.hash,
106
- id: (0, uuid_1.v1)({ msecs: time }),
107
- status: types_1.TransactionStatus.confirmed,
108
- time,
109
- txParams: {
110
- chainId: currentChainId,
111
- from: txMeta.from,
112
- gas: (0, controller_utils_1.BNToHex)(new ethereumjs_util_1.BN(txMeta.gas)),
113
- gasPrice: (0, controller_utils_1.BNToHex)(new ethereumjs_util_1.BN(txMeta.gasPrice)),
114
- gasUsed: (0, controller_utils_1.BNToHex)(new ethereumjs_util_1.BN(txMeta.gasUsed)),
115
- nonce: (0, controller_utils_1.BNToHex)(new ethereumjs_util_1.BN(txMeta.nonce)),
116
- to: txMeta.to,
117
- value: (0, controller_utils_1.BNToHex)(new ethereumjs_util_1.BN(txMeta.value)),
118
- },
119
- verifiedOnBlockchain: false,
120
- };
121
- };
122
- //# sourceMappingURL=EtherscanRemoteTransactionSource.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"EtherscanRemoteTransactionSource.js","sourceRoot":"","sources":["../src/EtherscanRemoteTransactionSource.ts"],"names":[],"mappings":"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","sourcesContent":["import { BNToHex } from '@metamask/controller-utils';\nimport type { Hex } from '@metamask/utils';\nimport { BN } from 'ethereumjs-util';\nimport { v1 as random } from 'uuid';\n\nimport { ETHERSCAN_SUPPORTED_NETWORKS } from './constants';\nimport type {\n EtherscanTokenTransactionMeta,\n EtherscanTransactionMeta,\n EtherscanTransactionMetaBase,\n EtherscanTransactionRequest,\n EtherscanTransactionResponse,\n} from './etherscan';\nimport {\n fetchEtherscanTokenTransactions,\n fetchEtherscanTransactions,\n} from './etherscan';\nimport { incomingTransactionsLogger as log } from './logger';\nimport type {\n RemoteTransactionSource,\n RemoteTransactionSourceRequest,\n TransactionMeta,\n} from './types';\nimport { TransactionStatus } from './types';\n\n/**\n * A RemoteTransactionSource that fetches transaction data from Etherscan.\n */\nexport class EtherscanRemoteTransactionSource\n implements RemoteTransactionSource\n{\n #includeTokenTransfers: boolean;\n\n #isTokenRequestPending: boolean;\n\n constructor({\n includeTokenTransfers,\n }: { includeTokenTransfers?: boolean } = {}) {\n this.#includeTokenTransfers = includeTokenTransfers ?? true;\n this.#isTokenRequestPending = false;\n }\n\n isSupportedNetwork(chainId: Hex): boolean {\n return Object.keys(ETHERSCAN_SUPPORTED_NETWORKS).includes(chainId);\n }\n\n getLastBlockVariations(): string[] {\n return [this.#isTokenRequestPending ? 'token' : 'normal'];\n }\n\n async fetchTransactions(\n request: RemoteTransactionSourceRequest,\n ): Promise<TransactionMeta[]> {\n const etherscanRequest: EtherscanTransactionRequest = {\n ...request,\n chainId: request.currentChainId,\n };\n\n const transactions = this.#isTokenRequestPending\n ? await this.#fetchTokenTransactions(request, etherscanRequest)\n : await this.#fetchNormalTransactions(request, etherscanRequest);\n\n if (this.#includeTokenTransfers) {\n this.#isTokenRequestPending = !this.#isTokenRequestPending;\n }\n\n return transactions;\n }\n\n #fetchNormalTransactions = async (\n request: RemoteTransactionSourceRequest,\n etherscanRequest: EtherscanTransactionRequest,\n ) => {\n const { currentChainId } = request;\n\n const etherscanTransactions = await fetchEtherscanTransactions(\n etherscanRequest,\n );\n\n return this.#getResponseTransactions(etherscanTransactions).map((tx) =>\n this.#normalizeTransaction(tx, currentChainId),\n );\n };\n\n #fetchTokenTransactions = async (\n request: RemoteTransactionSourceRequest,\n etherscanRequest: EtherscanTransactionRequest,\n ) => {\n const { currentChainId } = request;\n\n const etherscanTransactions = await fetchEtherscanTokenTransactions(\n etherscanRequest,\n );\n\n return this.#getResponseTransactions(etherscanTransactions).map((tx) =>\n this.#normalizeTokenTransaction(tx, currentChainId),\n );\n };\n\n #getResponseTransactions<T extends EtherscanTransactionMetaBase>(\n response: EtherscanTransactionResponse<T>,\n ): T[] {\n let result = response.result as T[];\n\n if (response.status === '0') {\n result = [];\n\n if (response.result.length) {\n log('Ignored Etherscan request error', {\n message: response.result,\n type: this.#isTokenRequestPending ? 'token' : 'normal',\n });\n }\n }\n\n return result;\n }\n\n #normalizeTransaction(\n txMeta: EtherscanTransactionMeta,\n currentChainId: Hex,\n ): TransactionMeta {\n const base = this.#normalizeTransactionBase(txMeta, currentChainId);\n\n return {\n ...base,\n txParams: {\n ...base.txParams,\n data: txMeta.input,\n },\n ...(txMeta.isError === '0'\n ? { status: TransactionStatus.confirmed }\n : {\n error: new Error('Transaction failed'),\n status: TransactionStatus.failed,\n }),\n };\n }\n\n #normalizeTokenTransaction(\n txMeta: EtherscanTokenTransactionMeta,\n currentChainId: Hex,\n ): TransactionMeta {\n const base = this.#normalizeTransactionBase(txMeta, currentChainId);\n\n return {\n ...base,\n isTransfer: true,\n transferInformation: {\n contractAddress: txMeta.contractAddress,\n decimals: Number(txMeta.tokenDecimal),\n symbol: txMeta.tokenSymbol,\n },\n };\n }\n\n #normalizeTransactionBase(\n txMeta: EtherscanTransactionMetaBase,\n currentChainId: Hex,\n ): TransactionMeta {\n const time = parseInt(txMeta.timeStamp, 10) * 1000;\n\n return {\n blockNumber: txMeta.blockNumber,\n chainId: currentChainId,\n hash: txMeta.hash,\n id: random({ msecs: time }),\n status: TransactionStatus.confirmed,\n time,\n txParams: {\n chainId: currentChainId,\n from: txMeta.from,\n gas: BNToHex(new BN(txMeta.gas)),\n gasPrice: BNToHex(new BN(txMeta.gasPrice)),\n gasUsed: BNToHex(new BN(txMeta.gasUsed)),\n nonce: BNToHex(new BN(txMeta.nonce)),\n to: txMeta.to,\n value: BNToHex(new BN(txMeta.value)),\n },\n verifiedOnBlockchain: false,\n };\n }\n}\n"]}
@@ -1,25 +0,0 @@
1
- /// <reference types="node" />
2
- import type { BlockTracker, NetworkState } from '@metamask/network-controller';
3
- import type { Hex } from '@metamask/utils';
4
- import EventEmitter from 'events';
5
- import type { RemoteTransactionSource, TransactionMeta } from './types';
6
- export declare class IncomingTransactionHelper {
7
- #private;
8
- hub: EventEmitter;
9
- constructor({ blockTracker, getCurrentAccount, getLastFetchedBlockNumbers, getLocalTransactions, getNetworkState, isEnabled, queryEntireHistory, remoteTransactionSource, transactionLimit, updateTransactions, }: {
10
- blockTracker: BlockTracker;
11
- getCurrentAccount: () => string;
12
- getLastFetchedBlockNumbers: () => Record<string, number>;
13
- getLocalTransactions?: () => TransactionMeta[];
14
- getNetworkState: () => NetworkState;
15
- isEnabled?: () => boolean;
16
- queryEntireHistory?: boolean;
17
- remoteTransactionSource: RemoteTransactionSource;
18
- transactionLimit?: number;
19
- updateTransactions?: boolean;
20
- });
21
- start(): void;
22
- stop(): void;
23
- update(latestBlockNumberHex?: Hex): Promise<void>;
24
- }
25
- //# sourceMappingURL=IncomingTransactionHelper.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"IncomingTransactionHelper.d.ts","sourceRoot":"","sources":["../src/IncomingTransactionHelper.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC/E,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAE3C,OAAO,YAAY,MAAM,QAAQ,CAAC;AAGlC,OAAO,KAAK,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AASxE,qBAAa,yBAAyB;;IACpC,GAAG,EAAE,YAAY,CAAC;gBA4BN,EACV,YAAY,EACZ,iBAAiB,EACjB,0BAA0B,EAC1B,oBAAoB,EACpB,eAAe,EACf,SAAS,EACT,kBAAkB,EAClB,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,GACnB,EAAE;QACD,YAAY,EAAE,YAAY,CAAC;QAC3B,iBAAiB,EAAE,MAAM,MAAM,CAAC;QAChC,0BAA0B,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACzD,oBAAoB,CAAC,EAAE,MAAM,eAAe,EAAE,CAAC;QAC/C,eAAe,EAAE,MAAM,YAAY,CAAC;QACpC,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;QAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B,uBAAuB,EAAE,uBAAuB,CAAC;QACjD,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;KAC9B;IA0BD,KAAK;IAaL,IAAI;IAKE,MAAM,CAAC,oBAAoB,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;CAmMxD"}
@@ -1,198 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
12
- if (kind === "m") throw new TypeError("Private method is not writable");
13
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
14
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
15
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
16
- };
17
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
18
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
19
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
20
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
21
- };
22
- var __importDefault = (this && this.__importDefault) || function (mod) {
23
- return (mod && mod.__esModule) ? mod : { "default": mod };
24
- };
25
- var _IncomingTransactionHelper_instances, _IncomingTransactionHelper_blockTracker, _IncomingTransactionHelper_getCurrentAccount, _IncomingTransactionHelper_getLastFetchedBlockNumbers, _IncomingTransactionHelper_getLocalTransactions, _IncomingTransactionHelper_getNetworkState, _IncomingTransactionHelper_isEnabled, _IncomingTransactionHelper_isRunning, _IncomingTransactionHelper_mutex, _IncomingTransactionHelper_onLatestBlock, _IncomingTransactionHelper_queryEntireHistory, _IncomingTransactionHelper_remoteTransactionSource, _IncomingTransactionHelper_transactionLimit, _IncomingTransactionHelper_updateTransactions, _IncomingTransactionHelper_sortTransactionsByTime, _IncomingTransactionHelper_getNewTransactions, _IncomingTransactionHelper_getUpdatedTransactions, _IncomingTransactionHelper_isTransactionOutdated, _IncomingTransactionHelper_getFromBlock, _IncomingTransactionHelper_updateLastFetchedBlockNumber, _IncomingTransactionHelper_getBlockNumberKey, _IncomingTransactionHelper_canStart, _IncomingTransactionHelper_getCurrentChainId;
26
- Object.defineProperty(exports, "__esModule", { value: true });
27
- exports.IncomingTransactionHelper = void 0;
28
- const async_mutex_1 = require("async-mutex");
29
- const events_1 = __importDefault(require("events"));
30
- const logger_1 = require("./logger");
31
- const RECENT_HISTORY_BLOCK_RANGE = 10;
32
- const UPDATE_CHECKS = [
33
- (txMeta) => txMeta.status,
34
- (txMeta) => txMeta.txParams.gasUsed,
35
- ];
36
- class IncomingTransactionHelper {
37
- constructor({ blockTracker, getCurrentAccount, getLastFetchedBlockNumbers, getLocalTransactions, getNetworkState, isEnabled, queryEntireHistory, remoteTransactionSource, transactionLimit, updateTransactions, }) {
38
- _IncomingTransactionHelper_instances.add(this);
39
- _IncomingTransactionHelper_blockTracker.set(this, void 0);
40
- _IncomingTransactionHelper_getCurrentAccount.set(this, void 0);
41
- _IncomingTransactionHelper_getLastFetchedBlockNumbers.set(this, void 0);
42
- _IncomingTransactionHelper_getLocalTransactions.set(this, void 0);
43
- _IncomingTransactionHelper_getNetworkState.set(this, void 0);
44
- _IncomingTransactionHelper_isEnabled.set(this, void 0);
45
- _IncomingTransactionHelper_isRunning.set(this, void 0);
46
- _IncomingTransactionHelper_mutex.set(this, new async_mutex_1.Mutex());
47
- _IncomingTransactionHelper_onLatestBlock.set(this, void 0);
48
- _IncomingTransactionHelper_queryEntireHistory.set(this, void 0);
49
- _IncomingTransactionHelper_remoteTransactionSource.set(this, void 0);
50
- _IncomingTransactionHelper_transactionLimit.set(this, void 0);
51
- _IncomingTransactionHelper_updateTransactions.set(this, void 0);
52
- this.hub = new events_1.default();
53
- __classPrivateFieldSet(this, _IncomingTransactionHelper_blockTracker, blockTracker, "f");
54
- __classPrivateFieldSet(this, _IncomingTransactionHelper_getCurrentAccount, getCurrentAccount, "f");
55
- __classPrivateFieldSet(this, _IncomingTransactionHelper_getLastFetchedBlockNumbers, getLastFetchedBlockNumbers, "f");
56
- __classPrivateFieldSet(this, _IncomingTransactionHelper_getLocalTransactions, getLocalTransactions || (() => []), "f");
57
- __classPrivateFieldSet(this, _IncomingTransactionHelper_getNetworkState, getNetworkState, "f");
58
- __classPrivateFieldSet(this, _IncomingTransactionHelper_isEnabled, isEnabled !== null && isEnabled !== void 0 ? isEnabled : (() => true), "f");
59
- __classPrivateFieldSet(this, _IncomingTransactionHelper_isRunning, false, "f");
60
- __classPrivateFieldSet(this, _IncomingTransactionHelper_queryEntireHistory, queryEntireHistory !== null && queryEntireHistory !== void 0 ? queryEntireHistory : true, "f");
61
- __classPrivateFieldSet(this, _IncomingTransactionHelper_remoteTransactionSource, remoteTransactionSource, "f");
62
- __classPrivateFieldSet(this, _IncomingTransactionHelper_transactionLimit, transactionLimit, "f");
63
- __classPrivateFieldSet(this, _IncomingTransactionHelper_updateTransactions, updateTransactions !== null && updateTransactions !== void 0 ? updateTransactions : false, "f");
64
- // Using a property instead of a method to provide a listener reference
65
- // with the correct scope that we can remove later if stopped.
66
- __classPrivateFieldSet(this, _IncomingTransactionHelper_onLatestBlock, (blockNumberHex) => __awaiter(this, void 0, void 0, function* () {
67
- try {
68
- yield this.update(blockNumberHex);
69
- }
70
- catch (error) {
71
- console.error('Error while checking incoming transactions', error);
72
- }
73
- }), "f");
74
- }
75
- start() {
76
- if (__classPrivateFieldGet(this, _IncomingTransactionHelper_isRunning, "f")) {
77
- return;
78
- }
79
- if (!__classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_canStart).call(this)) {
80
- return;
81
- }
82
- __classPrivateFieldGet(this, _IncomingTransactionHelper_blockTracker, "f").addListener('latest', __classPrivateFieldGet(this, _IncomingTransactionHelper_onLatestBlock, "f"));
83
- __classPrivateFieldSet(this, _IncomingTransactionHelper_isRunning, true, "f");
84
- }
85
- stop() {
86
- __classPrivateFieldGet(this, _IncomingTransactionHelper_blockTracker, "f").removeListener('latest', __classPrivateFieldGet(this, _IncomingTransactionHelper_onLatestBlock, "f"));
87
- __classPrivateFieldSet(this, _IncomingTransactionHelper_isRunning, false, "f");
88
- }
89
- update(latestBlockNumberHex) {
90
- var _a, _b, _c;
91
- return __awaiter(this, void 0, void 0, function* () {
92
- const releaseLock = yield __classPrivateFieldGet(this, _IncomingTransactionHelper_mutex, "f").acquire();
93
- (0, logger_1.incomingTransactionsLogger)('Checking for incoming transactions');
94
- try {
95
- if (!__classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_canStart).call(this)) {
96
- return;
97
- }
98
- const latestBlockNumber = parseInt(latestBlockNumberHex || (yield __classPrivateFieldGet(this, _IncomingTransactionHelper_blockTracker, "f").getLatestBlock()), 16);
99
- const additionalLastFetchedKeys = (_c = (_b = (_a = __classPrivateFieldGet(this, _IncomingTransactionHelper_remoteTransactionSource, "f")).getLastBlockVariations) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : [];
100
- const fromBlock = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_getFromBlock).call(this, latestBlockNumber, additionalLastFetchedKeys);
101
- const address = __classPrivateFieldGet(this, _IncomingTransactionHelper_getCurrentAccount, "f").call(this);
102
- const currentChainId = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_getCurrentChainId).call(this);
103
- let remoteTransactions = [];
104
- try {
105
- remoteTransactions =
106
- yield __classPrivateFieldGet(this, _IncomingTransactionHelper_remoteTransactionSource, "f").fetchTransactions({
107
- address,
108
- currentChainId,
109
- fromBlock,
110
- limit: __classPrivateFieldGet(this, _IncomingTransactionHelper_transactionLimit, "f"),
111
- });
112
- }
113
- catch (error) {
114
- (0, logger_1.incomingTransactionsLogger)('Error while fetching remote transactions', error);
115
- return;
116
- }
117
- if (!__classPrivateFieldGet(this, _IncomingTransactionHelper_updateTransactions, "f")) {
118
- remoteTransactions = remoteTransactions.filter((tx) => { var _a; return ((_a = tx.txParams.to) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === address.toLowerCase(); });
119
- }
120
- const localTransactions = !__classPrivateFieldGet(this, _IncomingTransactionHelper_updateTransactions, "f")
121
- ? []
122
- : __classPrivateFieldGet(this, _IncomingTransactionHelper_getLocalTransactions, "f").call(this);
123
- const newTransactions = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_getNewTransactions).call(this, remoteTransactions, localTransactions);
124
- const updatedTransactions = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_getUpdatedTransactions).call(this, remoteTransactions, localTransactions);
125
- if (newTransactions.length > 0 || updatedTransactions.length > 0) {
126
- __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_sortTransactionsByTime).call(this, newTransactions);
127
- __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_sortTransactionsByTime).call(this, updatedTransactions);
128
- (0, logger_1.incomingTransactionsLogger)('Found incoming transactions', {
129
- new: newTransactions,
130
- updated: updatedTransactions,
131
- });
132
- this.hub.emit('transactions', {
133
- added: newTransactions,
134
- updated: updatedTransactions,
135
- });
136
- }
137
- __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_updateLastFetchedBlockNumber).call(this, remoteTransactions, additionalLastFetchedKeys);
138
- }
139
- finally {
140
- releaseLock();
141
- }
142
- });
143
- }
144
- }
145
- exports.IncomingTransactionHelper = IncomingTransactionHelper;
146
- _IncomingTransactionHelper_blockTracker = new WeakMap(), _IncomingTransactionHelper_getCurrentAccount = new WeakMap(), _IncomingTransactionHelper_getLastFetchedBlockNumbers = new WeakMap(), _IncomingTransactionHelper_getLocalTransactions = new WeakMap(), _IncomingTransactionHelper_getNetworkState = new WeakMap(), _IncomingTransactionHelper_isEnabled = new WeakMap(), _IncomingTransactionHelper_isRunning = new WeakMap(), _IncomingTransactionHelper_mutex = new WeakMap(), _IncomingTransactionHelper_onLatestBlock = new WeakMap(), _IncomingTransactionHelper_queryEntireHistory = new WeakMap(), _IncomingTransactionHelper_remoteTransactionSource = new WeakMap(), _IncomingTransactionHelper_transactionLimit = new WeakMap(), _IncomingTransactionHelper_updateTransactions = new WeakMap(), _IncomingTransactionHelper_instances = new WeakSet(), _IncomingTransactionHelper_sortTransactionsByTime = function _IncomingTransactionHelper_sortTransactionsByTime(transactions) {
147
- transactions.sort((a, b) => (a.time < b.time ? -1 : 1));
148
- }, _IncomingTransactionHelper_getNewTransactions = function _IncomingTransactionHelper_getNewTransactions(remoteTxs, localTxs) {
149
- return remoteTxs.filter((tx) => !localTxs.some(({ hash }) => hash === tx.hash));
150
- }, _IncomingTransactionHelper_getUpdatedTransactions = function _IncomingTransactionHelper_getUpdatedTransactions(remoteTxs, localTxs) {
151
- return remoteTxs.filter((remoteTx) => localTxs.some((localTx) => remoteTx.hash === localTx.hash &&
152
- __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_isTransactionOutdated).call(this, remoteTx, localTx)));
153
- }, _IncomingTransactionHelper_isTransactionOutdated = function _IncomingTransactionHelper_isTransactionOutdated(remoteTx, localTx) {
154
- return UPDATE_CHECKS.some((getValue) => getValue(remoteTx) !== getValue(localTx));
155
- }, _IncomingTransactionHelper_getFromBlock = function _IncomingTransactionHelper_getFromBlock(latestBlockNumber, additionalKeys) {
156
- const lastFetchedKey = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_getBlockNumberKey).call(this, additionalKeys);
157
- const lastFetchedBlockNumber = __classPrivateFieldGet(this, _IncomingTransactionHelper_getLastFetchedBlockNumbers, "f").call(this)[lastFetchedKey];
158
- if (lastFetchedBlockNumber) {
159
- return lastFetchedBlockNumber + 1;
160
- }
161
- return __classPrivateFieldGet(this, _IncomingTransactionHelper_queryEntireHistory, "f")
162
- ? undefined
163
- : latestBlockNumber - RECENT_HISTORY_BLOCK_RANGE;
164
- }, _IncomingTransactionHelper_updateLastFetchedBlockNumber = function _IncomingTransactionHelper_updateLastFetchedBlockNumber(remoteTxs, additionalKeys) {
165
- let lastFetchedBlockNumber = -1;
166
- for (const tx of remoteTxs) {
167
- const currentBlockNumberValue = tx.blockNumber
168
- ? parseInt(tx.blockNumber, 10)
169
- : -1;
170
- lastFetchedBlockNumber = Math.max(lastFetchedBlockNumber, currentBlockNumberValue);
171
- }
172
- if (lastFetchedBlockNumber === -1) {
173
- return;
174
- }
175
- const lastFetchedKey = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_getBlockNumberKey).call(this, additionalKeys);
176
- const lastFetchedBlockNumbers = __classPrivateFieldGet(this, _IncomingTransactionHelper_getLastFetchedBlockNumbers, "f").call(this);
177
- const previousValue = lastFetchedBlockNumbers[lastFetchedKey];
178
- if (previousValue >= lastFetchedBlockNumber) {
179
- return;
180
- }
181
- lastFetchedBlockNumbers[lastFetchedKey] = lastFetchedBlockNumber;
182
- this.hub.emit('updatedLastFetchedBlockNumbers', {
183
- lastFetchedBlockNumbers,
184
- blockNumber: lastFetchedBlockNumber,
185
- });
186
- }, _IncomingTransactionHelper_getBlockNumberKey = function _IncomingTransactionHelper_getBlockNumberKey(additionalKeys) {
187
- const currentChainId = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_getCurrentChainId).call(this);
188
- const currentAccount = __classPrivateFieldGet(this, _IncomingTransactionHelper_getCurrentAccount, "f").call(this).toLowerCase();
189
- return [currentChainId, currentAccount, ...additionalKeys].join('#');
190
- }, _IncomingTransactionHelper_canStart = function _IncomingTransactionHelper_canStart() {
191
- const isEnabled = __classPrivateFieldGet(this, _IncomingTransactionHelper_isEnabled, "f").call(this);
192
- const currentChainId = __classPrivateFieldGet(this, _IncomingTransactionHelper_instances, "m", _IncomingTransactionHelper_getCurrentChainId).call(this);
193
- const isSupportedNetwork = __classPrivateFieldGet(this, _IncomingTransactionHelper_remoteTransactionSource, "f").isSupportedNetwork(currentChainId);
194
- return isEnabled && isSupportedNetwork;
195
- }, _IncomingTransactionHelper_getCurrentChainId = function _IncomingTransactionHelper_getCurrentChainId() {
196
- return __classPrivateFieldGet(this, _IncomingTransactionHelper_getNetworkState, "f").call(this).providerConfig.chainId;
197
- };
198
- //# sourceMappingURL=IncomingTransactionHelper.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"IncomingTransactionHelper.js","sourceRoot":"","sources":["../src/IncomingTransactionHelper.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BlockTracker, NetworkState } from '@metamask/network-controller';\nimport type { Hex } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\nimport EventEmitter from 'events';\n\nimport { incomingTransactionsLogger as log } from './logger';\nimport type { RemoteTransactionSource, TransactionMeta } from './types';\n\nconst RECENT_HISTORY_BLOCK_RANGE = 10;\n\nconst UPDATE_CHECKS: ((txMeta: TransactionMeta) => any)[] = [\n (txMeta) => txMeta.status,\n (txMeta) => txMeta.txParams.gasUsed,\n];\n\nexport class IncomingTransactionHelper {\n hub: EventEmitter;\n\n #blockTracker: BlockTracker;\n\n #getCurrentAccount: () => string;\n\n #getLastFetchedBlockNumbers: () => Record<string, number>;\n\n #getLocalTransactions: () => TransactionMeta[];\n\n #getNetworkState: () => NetworkState;\n\n #isEnabled: () => boolean;\n\n #isRunning: boolean;\n\n #mutex = new Mutex();\n\n #onLatestBlock: (blockNumberHex: Hex) => Promise<void>;\n\n #queryEntireHistory: boolean;\n\n #remoteTransactionSource: RemoteTransactionSource;\n\n #transactionLimit?: number;\n\n #updateTransactions: boolean;\n\n constructor({\n blockTracker,\n getCurrentAccount,\n getLastFetchedBlockNumbers,\n getLocalTransactions,\n getNetworkState,\n isEnabled,\n queryEntireHistory,\n remoteTransactionSource,\n transactionLimit,\n updateTransactions,\n }: {\n blockTracker: BlockTracker;\n getCurrentAccount: () => string;\n getLastFetchedBlockNumbers: () => Record<string, number>;\n getLocalTransactions?: () => TransactionMeta[];\n getNetworkState: () => NetworkState;\n isEnabled?: () => boolean;\n queryEntireHistory?: boolean;\n remoteTransactionSource: RemoteTransactionSource;\n transactionLimit?: number;\n updateTransactions?: boolean;\n }) {\n this.hub = new EventEmitter();\n\n this.#blockTracker = blockTracker;\n this.#getCurrentAccount = getCurrentAccount;\n this.#getLastFetchedBlockNumbers = getLastFetchedBlockNumbers;\n this.#getLocalTransactions = getLocalTransactions || (() => []);\n this.#getNetworkState = getNetworkState;\n this.#isEnabled = isEnabled ?? (() => true);\n this.#isRunning = false;\n this.#queryEntireHistory = queryEntireHistory ?? true;\n this.#remoteTransactionSource = remoteTransactionSource;\n this.#transactionLimit = transactionLimit;\n this.#updateTransactions = updateTransactions ?? false;\n\n // Using a property instead of a method to provide a listener reference\n // with the correct scope that we can remove later if stopped.\n this.#onLatestBlock = async (blockNumberHex: Hex) => {\n try {\n await this.update(blockNumberHex);\n } catch (error) {\n console.error('Error while checking incoming transactions', error);\n }\n };\n }\n\n start() {\n if (this.#isRunning) {\n return;\n }\n\n if (!this.#canStart()) {\n return;\n }\n\n this.#blockTracker.addListener('latest', this.#onLatestBlock);\n this.#isRunning = true;\n }\n\n stop() {\n this.#blockTracker.removeListener('latest', this.#onLatestBlock);\n this.#isRunning = false;\n }\n\n async update(latestBlockNumberHex?: Hex): Promise<void> {\n const releaseLock = await this.#mutex.acquire();\n\n log('Checking for incoming transactions');\n\n try {\n if (!this.#canStart()) {\n return;\n }\n\n const latestBlockNumber = parseInt(\n latestBlockNumberHex || (await this.#blockTracker.getLatestBlock()),\n 16,\n );\n\n const additionalLastFetchedKeys =\n this.#remoteTransactionSource.getLastBlockVariations?.() ?? [];\n\n const fromBlock = this.#getFromBlock(\n latestBlockNumber,\n additionalLastFetchedKeys,\n );\n\n const address = this.#getCurrentAccount();\n const currentChainId = this.#getCurrentChainId();\n\n let remoteTransactions = [];\n\n try {\n remoteTransactions =\n await this.#remoteTransactionSource.fetchTransactions({\n address,\n currentChainId,\n fromBlock,\n limit: this.#transactionLimit,\n });\n } catch (error: any) {\n log('Error while fetching remote transactions', error);\n return;\n }\n\n if (!this.#updateTransactions) {\n remoteTransactions = remoteTransactions.filter(\n (tx) => tx.txParams.to?.toLowerCase() === address.toLowerCase(),\n );\n }\n\n const localTransactions = !this.#updateTransactions\n ? []\n : this.#getLocalTransactions();\n\n const newTransactions = this.#getNewTransactions(\n remoteTransactions,\n localTransactions,\n );\n\n const updatedTransactions = this.#getUpdatedTransactions(\n remoteTransactions,\n localTransactions,\n );\n\n if (newTransactions.length > 0 || updatedTransactions.length > 0) {\n this.#sortTransactionsByTime(newTransactions);\n this.#sortTransactionsByTime(updatedTransactions);\n\n log('Found incoming transactions', {\n new: newTransactions,\n updated: updatedTransactions,\n });\n\n this.hub.emit('transactions', {\n added: newTransactions,\n updated: updatedTransactions,\n });\n }\n\n this.#updateLastFetchedBlockNumber(\n remoteTransactions,\n additionalLastFetchedKeys,\n );\n } finally {\n releaseLock();\n }\n }\n\n #sortTransactionsByTime(transactions: TransactionMeta[]) {\n transactions.sort((a, b) => (a.time < b.time ? -1 : 1));\n }\n\n #getNewTransactions(\n remoteTxs: TransactionMeta[],\n localTxs: TransactionMeta[],\n ): TransactionMeta[] {\n return remoteTxs.filter(\n (tx) => !localTxs.some(({ hash }) => hash === tx.hash),\n );\n }\n\n #getUpdatedTransactions(\n remoteTxs: TransactionMeta[],\n localTxs: TransactionMeta[],\n ): TransactionMeta[] {\n return remoteTxs.filter((remoteTx) =>\n localTxs.some(\n (localTx) =>\n remoteTx.hash === localTx.hash &&\n this.#isTransactionOutdated(remoteTx, localTx),\n ),\n );\n }\n\n #isTransactionOutdated(\n remoteTx: TransactionMeta,\n localTx: TransactionMeta,\n ): boolean {\n return UPDATE_CHECKS.some(\n (getValue) => getValue(remoteTx) !== getValue(localTx),\n );\n }\n\n #getFromBlock(\n latestBlockNumber: number,\n additionalKeys: string[],\n ): number | undefined {\n const lastFetchedKey = this.#getBlockNumberKey(additionalKeys);\n\n const lastFetchedBlockNumber =\n this.#getLastFetchedBlockNumbers()[lastFetchedKey];\n\n if (lastFetchedBlockNumber) {\n return lastFetchedBlockNumber + 1;\n }\n\n return this.#queryEntireHistory\n ? undefined\n : latestBlockNumber - RECENT_HISTORY_BLOCK_RANGE;\n }\n\n #updateLastFetchedBlockNumber(\n remoteTxs: TransactionMeta[],\n additionalKeys: string[],\n ) {\n let lastFetchedBlockNumber = -1;\n\n for (const tx of remoteTxs) {\n const currentBlockNumberValue = tx.blockNumber\n ? parseInt(tx.blockNumber, 10)\n : -1;\n\n lastFetchedBlockNumber = Math.max(\n lastFetchedBlockNumber,\n currentBlockNumberValue,\n );\n }\n\n if (lastFetchedBlockNumber === -1) {\n return;\n }\n\n const lastFetchedKey = this.#getBlockNumberKey(additionalKeys);\n const lastFetchedBlockNumbers = this.#getLastFetchedBlockNumbers();\n const previousValue = lastFetchedBlockNumbers[lastFetchedKey];\n\n if (previousValue >= lastFetchedBlockNumber) {\n return;\n }\n\n lastFetchedBlockNumbers[lastFetchedKey] = lastFetchedBlockNumber;\n\n this.hub.emit('updatedLastFetchedBlockNumbers', {\n lastFetchedBlockNumbers,\n blockNumber: lastFetchedBlockNumber,\n });\n }\n\n #getBlockNumberKey(additionalKeys: string[]): string {\n const currentChainId = this.#getCurrentChainId();\n const currentAccount = this.#getCurrentAccount().toLowerCase();\n\n return [currentChainId, currentAccount, ...additionalKeys].join('#');\n }\n\n #canStart(): boolean {\n const isEnabled = this.#isEnabled();\n const currentChainId = this.#getCurrentChainId();\n\n const isSupportedNetwork =\n this.#remoteTransactionSource.isSupportedNetwork(currentChainId);\n\n return isEnabled && isSupportedNetwork;\n }\n\n #getCurrentChainId(): Hex {\n return this.#getNetworkState().providerConfig.chainId;\n }\n}\n"]}
@@ -1,64 +0,0 @@
1
- import type { Hex } from '@metamask/utils';
2
- export interface EtherscanTransactionMetaBase {
3
- blockNumber: string;
4
- blockHash: string;
5
- confirmations: string;
6
- contractAddress: string;
7
- cumulativeGasUsed: string;
8
- from: string;
9
- gas: string;
10
- gasPrice: string;
11
- gasUsed: string;
12
- hash: string;
13
- nonce: string;
14
- timeStamp: string;
15
- to: string;
16
- transactionIndex: string;
17
- value: string;
18
- }
19
- export interface EtherscanTransactionMeta extends EtherscanTransactionMetaBase {
20
- functionName: string;
21
- input: string;
22
- isError: string;
23
- methodId: string;
24
- txreceipt_status: string;
25
- }
26
- export interface EtherscanTokenTransactionMeta extends EtherscanTransactionMetaBase {
27
- tokenDecimal: string;
28
- tokenName: string;
29
- tokenSymbol: string;
30
- }
31
- export interface EtherscanTransactionResponse<T extends EtherscanTransactionMetaBase> {
32
- status: '0' | '1';
33
- message?: string;
34
- result: string | T[];
35
- }
36
- export interface EtherscanTransactionRequest {
37
- address: string;
38
- chainId: Hex;
39
- fromBlock?: number;
40
- limit?: number;
41
- }
42
- /**
43
- * Retrieves transaction data from Etherscan.
44
- *
45
- * @param request - Configuration required to fetch transactions.
46
- * @param request.address - Address to retrieve transactions for.
47
- * @param request.chainId - Current chain ID used to determine subdomain and domain.
48
- * @param request.fromBlock - Block number to start fetching transactions from.
49
- * @param request.limit - Number of transactions to retrieve.
50
- * @returns An Etherscan response object containing the request status and an array of token transaction data.
51
- */
52
- export declare function fetchEtherscanTransactions({ address, chainId, fromBlock, limit, }: EtherscanTransactionRequest): Promise<EtherscanTransactionResponse<EtherscanTransactionMeta>>;
53
- /**
54
- * Retrieves token transaction data from Etherscan.
55
- *
56
- * @param request - Configuration required to fetch token transactions.
57
- * @param request.address - Address to retrieve token transactions for.
58
- * @param request.chainId - Current chain ID used to determine subdomain and domain.
59
- * @param request.fromBlock - Block number to start fetching token transactions from.
60
- * @param request.limit - Number of token transactions to retrieve.
61
- * @returns An Etherscan response object containing the request status and an array of token transaction data.
62
- */
63
- export declare function fetchEtherscanTokenTransactions({ address, chainId, fromBlock, limit, }: EtherscanTransactionRequest): Promise<EtherscanTransactionResponse<EtherscanTokenTransactionMeta>>;
64
- //# sourceMappingURL=etherscan.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"etherscan.d.ts","sourceRoot":"","sources":["../src/etherscan.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAK3C,MAAM,WAAW,4BAA4B;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,gBAAgB,EAAE,MAAM,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,wBAAyB,SAAQ,4BAA4B;IAC5E,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,6BACf,SAAQ,4BAA4B;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,4BAA4B,CAC3C,CAAC,SAAS,4BAA4B;IAEtC,MAAM,EAAE,GAAG,GAAG,GAAG,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,GAAG,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;GASG;AACH,wBAAsB,0BAA0B,CAAC,EAC/C,OAAO,EACP,OAAO,EACP,SAAS,EACT,KAAK,GACN,EAAE,2BAA2B,GAAG,OAAO,CACtC,4BAA4B,CAAC,wBAAwB,CAAC,CACvD,CAOA;AAED;;;;;;;;;GASG;AACH,wBAAsB,+BAA+B,CAAC,EACpD,OAAO,EACP,OAAO,EACP,SAAS,EACT,KAAK,GACN,EAAE,2BAA2B,GAAG,OAAO,CACtC,4BAA4B,CAAC,6BAA6B,CAAC,CAC5D,CAOA"}