@metamask/transaction-controller 69.0.0 → 69.2.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 +16 -1
- package/LICENSE +1 -0
- package/dist/gas-flows/MantleLayer1GasFeeFlow.cjs +21 -6
- package/dist/gas-flows/MantleLayer1GasFeeFlow.cjs.map +1 -1
- package/dist/gas-flows/MantleLayer1GasFeeFlow.d.cts.map +1 -1
- package/dist/gas-flows/MantleLayer1GasFeeFlow.d.mts.map +1 -1
- package/dist/gas-flows/MantleLayer1GasFeeFlow.mjs +21 -6
- package/dist/gas-flows/MantleLayer1GasFeeFlow.mjs.map +1 -1
- package/dist/gas-flows/OracleLayer1GasFeeFlow.cjs +37 -20
- package/dist/gas-flows/OracleLayer1GasFeeFlow.cjs.map +1 -1
- package/dist/gas-flows/OracleLayer1GasFeeFlow.d.cts +1 -1
- package/dist/gas-flows/OracleLayer1GasFeeFlow.d.cts.map +1 -1
- package/dist/gas-flows/OracleLayer1GasFeeFlow.d.mts +1 -1
- package/dist/gas-flows/OracleLayer1GasFeeFlow.d.mts.map +1 -1
- package/dist/gas-flows/OracleLayer1GasFeeFlow.mjs +37 -20
- package/dist/gas-flows/OracleLayer1GasFeeFlow.mjs.map +1 -1
- package/dist/index.cjs +3 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +1 -0
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -0
- package/dist/index.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +3 -3
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +3 -3
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/utils/layer1-gas-fee-flow.cjs +1 -6
- package/dist/utils/layer1-gas-fee-flow.cjs.map +1 -1
- package/dist/utils/layer1-gas-fee-flow.d.cts.map +1 -1
- package/dist/utils/layer1-gas-fee-flow.d.mts.map +1 -1
- package/dist/utils/layer1-gas-fee-flow.mjs +1 -6
- package/dist/utils/layer1-gas-fee-flow.mjs.map +1 -1
- package/dist/utils/transaction-type.cjs +17 -1
- package/dist/utils/transaction-type.cjs.map +1 -1
- package/dist/utils/transaction-type.d.cts +11 -1
- package/dist/utils/transaction-type.d.cts.map +1 -1
- package/dist/utils/transaction-type.d.mts +11 -1
- package/dist/utils/transaction-type.d.mts.map +1 -1
- package/dist/utils/transaction-type.mjs +15 -0
- package/dist/utils/transaction-type.mjs.map +1 -1
- package/package.json +3 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.decodeTransactionData = exports.determineTransactionType = exports.ESTIMATE_GAS_ERROR = void 0;
|
|
3
|
+
exports.hasTransactionType = exports.decodeTransactionData = exports.determineTransactionType = exports.ESTIMATE_GAS_ERROR = void 0;
|
|
4
4
|
const abi_1 = require("@ethersproject/abi");
|
|
5
5
|
const metamask_eth_abis_1 = require("@metamask/metamask-eth-abis");
|
|
6
6
|
const types_1 = require("../types.cjs");
|
|
@@ -140,4 +140,20 @@ async function readAddressAsContract(messenger, networkClientId, address) {
|
|
|
140
140
|
: false;
|
|
141
141
|
return { contractCode, isContractAddress };
|
|
142
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* Check whether a transaction (or any of its nested transactions) has one of
|
|
145
|
+
* the given types.
|
|
146
|
+
*
|
|
147
|
+
* @param transactionMeta - Transaction metadata.
|
|
148
|
+
* @param types - Transaction types to match against.
|
|
149
|
+
* @returns `true` when the transaction or a nested transaction has one of the given types.
|
|
150
|
+
*/
|
|
151
|
+
function hasTransactionType(transactionMeta, types) {
|
|
152
|
+
const { nestedTransactions, type } = transactionMeta ?? {};
|
|
153
|
+
if (types.includes(type)) {
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
return (nestedTransactions?.some((tx) => types.includes(tx.type)) ?? false);
|
|
157
|
+
}
|
|
158
|
+
exports.hasTransactionType = hasTransactionType;
|
|
143
159
|
//# sourceMappingURL=transaction-type.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transaction-type.cjs","sourceRoot":"","sources":["../../src/utils/transaction-type.ts"],"names":[],"mappings":"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","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport type { TransactionDescription } from '@ethersproject/abi';\nimport {\n abiERC721,\n abiERC20,\n abiERC1155,\n abiFiatTokenV2,\n} from '@metamask/metamask-eth-abis';\nimport type { NetworkClientId } from '@metamask/network-controller';\n\nimport type { TransactionControllerMessenger } from '../TransactionController';\nimport type { InferTransactionTypeResult, TransactionParams } from '../types';\nimport { TransactionType } from '../types';\nimport { DELEGATION_PREFIX } from './eip7702';\nimport { rpcRequest } from './provider';\n\nexport const ESTIMATE_GAS_ERROR = 'eth_estimateGas rpc method error';\n\nconst ERC20Interface = new Interface(abiERC20);\nconst ERC721Interface = new Interface(abiERC721);\nconst ERC1155Interface = new Interface(abiERC1155);\nconst USDCInterface = new Interface(abiFiatTokenV2);\n\n/**\n * Determines the type of the transaction by analyzing the txParams.\n * It will never return TRANSACTION_TYPE_CANCEL or TRANSACTION_TYPE_RETRY as these\n * represent specific events that we specify manually at transaction creation.\n *\n * @param txParams - Parameters for the transaction.\n * @param options - Optional messenger and network client ID to query the network.\n * @param options.messenger - The TransactionController messenger.\n * @param options.networkClientId - The network client ID to use.\n * @returns A object with the transaction type and the contract code response in Hex.\n */\nexport async function determineTransactionType(\n txParams: TransactionParams,\n options?: {\n messenger: TransactionControllerMessenger;\n networkClientId: NetworkClientId;\n },\n): Promise<InferTransactionTypeResult> {\n const { data, to } = txParams;\n\n const hasRealBytecode = Boolean(data && data !== '0x' && data.length > 2);\n\n if (hasRealBytecode && !to) {\n return { type: TransactionType.deployContract, getCodeResponse: undefined };\n }\n\n let getCodeResponse;\n let isContractAddress = Boolean(data?.length);\n\n if (options) {\n const { messenger, networkClientId } = options;\n const response = await readAddressAsContract(\n messenger,\n networkClientId,\n to,\n );\n\n getCodeResponse = response.contractCode;\n isContractAddress = response.isContractAddress;\n }\n\n if (!isContractAddress) {\n return { type: TransactionType.simpleSend, getCodeResponse };\n }\n\n const hasValue = Number(txParams.value ?? '0') !== 0;\n\n const contractInteractionResult = {\n type: TransactionType.contractInteraction,\n getCodeResponse,\n };\n\n if (!data || hasValue) {\n return contractInteractionResult;\n }\n\n const name = getMethodName(data);\n\n if (!name) {\n return contractInteractionResult;\n }\n\n const tokenMethodName = [\n TransactionType.tokenMethodApprove,\n TransactionType.tokenMethodSetApprovalForAll,\n TransactionType.tokenMethodTransfer,\n TransactionType.tokenMethodTransferFrom,\n TransactionType.tokenMethodSafeTransferFrom,\n TransactionType.tokenMethodIncreaseAllowance,\n ].find((methodName) => methodName.toLowerCase() === name.toLowerCase());\n\n if (tokenMethodName) {\n return { type: tokenMethodName, getCodeResponse };\n }\n\n return contractInteractionResult;\n}\n\n/**\n * Parses transaction data using ABIs for three different token standards: ERC20, ERC721, ERC1155 and USDC.\n * The data will decode correctly if the transaction is an interaction with a contract that matches one of these\n * contract standards\n *\n * @param data - Encoded transaction data.\n * @param options - Options bag.\n * @param options.getMethodName - Whether to get the method name.\n * @returns A representation of an ethereum contract call.\n */\nexport function decodeTransactionData(\n data: string,\n options?: {\n getMethodName?: boolean;\n },\n): undefined | TransactionDescription | string {\n if (!data || data.length < 10) {\n return undefined;\n }\n\n const fourByte = data.substring(0, 10).toLowerCase();\n\n for (const iface of [\n ERC20Interface,\n ERC721Interface,\n ERC1155Interface,\n USDCInterface,\n ]) {\n try {\n if (options?.getMethodName) {\n return iface.getFunction(fourByte)?.name;\n }\n return iface.parseTransaction({ data });\n } catch {\n // Intentionally empty\n }\n }\n\n return undefined;\n}\n\n/**\n * Attempts to get the method name from the given transaction data.\n *\n * @param data - Encoded transaction data.\n * @returns The method name.\n */\nfunction getMethodName(data?: string): string | undefined {\n return decodeTransactionData(data as string, {\n getMethodName: true,\n }) as string | undefined;\n}\n\n/**\n * Reads an Ethereum address and determines if it is a contract address.\n *\n * @param messenger - The TransactionController messenger.\n * @param networkClientId - The network client ID to use.\n * @param address - The Ethereum address.\n * @returns An object containing the contract code and a boolean indicating if it is a contract address.\n */\nasync function readAddressAsContract(\n messenger: TransactionControllerMessenger,\n networkClientId: NetworkClientId,\n address?: string,\n): Promise<{\n contractCode: string | null;\n isContractAddress: boolean;\n}> {\n let contractCode;\n try {\n contractCode = (await rpcRequest({\n messenger,\n networkClientId,\n method: 'eth_getCode',\n params: [address as string, 'latest'],\n })) as string;\n // Not used\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n contractCode = null;\n }\n\n const isContractAddress = contractCode\n ? contractCode !== '0x' &&\n contractCode !== '0x0' &&\n !contractCode.startsWith(DELEGATION_PREFIX)\n : false;\n return { contractCode, isContractAddress };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"transaction-type.cjs","sourceRoot":"","sources":["../../src/utils/transaction-type.ts"],"names":[],"mappings":"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","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport type { TransactionDescription } from '@ethersproject/abi';\nimport {\n abiERC721,\n abiERC20,\n abiERC1155,\n abiFiatTokenV2,\n} from '@metamask/metamask-eth-abis';\nimport type { NetworkClientId } from '@metamask/network-controller';\n\nimport type { TransactionControllerMessenger } from '../TransactionController';\nimport type {\n InferTransactionTypeResult,\n TransactionMeta,\n TransactionParams,\n} from '../types';\nimport { TransactionType } from '../types';\nimport { DELEGATION_PREFIX } from './eip7702';\nimport { rpcRequest } from './provider';\n\nexport const ESTIMATE_GAS_ERROR = 'eth_estimateGas rpc method error';\n\nconst ERC20Interface = new Interface(abiERC20);\nconst ERC721Interface = new Interface(abiERC721);\nconst ERC1155Interface = new Interface(abiERC1155);\nconst USDCInterface = new Interface(abiFiatTokenV2);\n\n/**\n * Determines the type of the transaction by analyzing the txParams.\n * It will never return TRANSACTION_TYPE_CANCEL or TRANSACTION_TYPE_RETRY as these\n * represent specific events that we specify manually at transaction creation.\n *\n * @param txParams - Parameters for the transaction.\n * @param options - Optional messenger and network client ID to query the network.\n * @param options.messenger - The TransactionController messenger.\n * @param options.networkClientId - The network client ID to use.\n * @returns A object with the transaction type and the contract code response in Hex.\n */\nexport async function determineTransactionType(\n txParams: TransactionParams,\n options?: {\n messenger: TransactionControllerMessenger;\n networkClientId: NetworkClientId;\n },\n): Promise<InferTransactionTypeResult> {\n const { data, to } = txParams;\n\n const hasRealBytecode = Boolean(data && data !== '0x' && data.length > 2);\n\n if (hasRealBytecode && !to) {\n return { type: TransactionType.deployContract, getCodeResponse: undefined };\n }\n\n let getCodeResponse;\n let isContractAddress = Boolean(data?.length);\n\n if (options) {\n const { messenger, networkClientId } = options;\n const response = await readAddressAsContract(\n messenger,\n networkClientId,\n to,\n );\n\n getCodeResponse = response.contractCode;\n isContractAddress = response.isContractAddress;\n }\n\n if (!isContractAddress) {\n return { type: TransactionType.simpleSend, getCodeResponse };\n }\n\n const hasValue = Number(txParams.value ?? '0') !== 0;\n\n const contractInteractionResult = {\n type: TransactionType.contractInteraction,\n getCodeResponse,\n };\n\n if (!data || hasValue) {\n return contractInteractionResult;\n }\n\n const name = getMethodName(data);\n\n if (!name) {\n return contractInteractionResult;\n }\n\n const tokenMethodName = [\n TransactionType.tokenMethodApprove,\n TransactionType.tokenMethodSetApprovalForAll,\n TransactionType.tokenMethodTransfer,\n TransactionType.tokenMethodTransferFrom,\n TransactionType.tokenMethodSafeTransferFrom,\n TransactionType.tokenMethodIncreaseAllowance,\n ].find((methodName) => methodName.toLowerCase() === name.toLowerCase());\n\n if (tokenMethodName) {\n return { type: tokenMethodName, getCodeResponse };\n }\n\n return contractInteractionResult;\n}\n\n/**\n * Parses transaction data using ABIs for three different token standards: ERC20, ERC721, ERC1155 and USDC.\n * The data will decode correctly if the transaction is an interaction with a contract that matches one of these\n * contract standards\n *\n * @param data - Encoded transaction data.\n * @param options - Options bag.\n * @param options.getMethodName - Whether to get the method name.\n * @returns A representation of an ethereum contract call.\n */\nexport function decodeTransactionData(\n data: string,\n options?: {\n getMethodName?: boolean;\n },\n): undefined | TransactionDescription | string {\n if (!data || data.length < 10) {\n return undefined;\n }\n\n const fourByte = data.substring(0, 10).toLowerCase();\n\n for (const iface of [\n ERC20Interface,\n ERC721Interface,\n ERC1155Interface,\n USDCInterface,\n ]) {\n try {\n if (options?.getMethodName) {\n return iface.getFunction(fourByte)?.name;\n }\n return iface.parseTransaction({ data });\n } catch {\n // Intentionally empty\n }\n }\n\n return undefined;\n}\n\n/**\n * Attempts to get the method name from the given transaction data.\n *\n * @param data - Encoded transaction data.\n * @returns The method name.\n */\nfunction getMethodName(data?: string): string | undefined {\n return decodeTransactionData(data as string, {\n getMethodName: true,\n }) as string | undefined;\n}\n\n/**\n * Reads an Ethereum address and determines if it is a contract address.\n *\n * @param messenger - The TransactionController messenger.\n * @param networkClientId - The network client ID to use.\n * @param address - The Ethereum address.\n * @returns An object containing the contract code and a boolean indicating if it is a contract address.\n */\nasync function readAddressAsContract(\n messenger: TransactionControllerMessenger,\n networkClientId: NetworkClientId,\n address?: string,\n): Promise<{\n contractCode: string | null;\n isContractAddress: boolean;\n}> {\n let contractCode;\n try {\n contractCode = (await rpcRequest({\n messenger,\n networkClientId,\n method: 'eth_getCode',\n params: [address as string, 'latest'],\n })) as string;\n // Not used\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n contractCode = null;\n }\n\n const isContractAddress = contractCode\n ? contractCode !== '0x' &&\n contractCode !== '0x0' &&\n !contractCode.startsWith(DELEGATION_PREFIX)\n : false;\n return { contractCode, isContractAddress };\n}\n\n/**\n * Check whether a transaction (or any of its nested transactions) has one of\n * the given types.\n *\n * @param transactionMeta - Transaction metadata.\n * @param types - Transaction types to match against.\n * @returns `true` when the transaction or a nested transaction has one of the given types.\n */\nexport function hasTransactionType(\n transactionMeta: TransactionMeta | undefined,\n types: readonly TransactionType[],\n): boolean {\n const { nestedTransactions, type } = transactionMeta ?? {};\n\n if (types.includes(type as TransactionType)) {\n return true;\n }\n\n return (\n nestedTransactions?.some((tx) =>\n types.includes(tx.type as TransactionType),\n ) ?? false\n );\n}\n"]}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { TransactionDescription } from "@ethersproject/abi";
|
|
2
2
|
import type { NetworkClientId } from "@metamask/network-controller";
|
|
3
3
|
import type { TransactionControllerMessenger } from "../TransactionController.cjs";
|
|
4
|
-
import type { InferTransactionTypeResult, TransactionParams } from "../types.cjs";
|
|
4
|
+
import type { InferTransactionTypeResult, TransactionMeta, TransactionParams } from "../types.cjs";
|
|
5
|
+
import { TransactionType } from "../types.cjs";
|
|
5
6
|
export declare const ESTIMATE_GAS_ERROR = "eth_estimateGas rpc method error";
|
|
6
7
|
/**
|
|
7
8
|
* Determines the type of the transaction by analyzing the txParams.
|
|
@@ -31,4 +32,13 @@ export declare function determineTransactionType(txParams: TransactionParams, op
|
|
|
31
32
|
export declare function decodeTransactionData(data: string, options?: {
|
|
32
33
|
getMethodName?: boolean;
|
|
33
34
|
}): undefined | TransactionDescription | string;
|
|
35
|
+
/**
|
|
36
|
+
* Check whether a transaction (or any of its nested transactions) has one of
|
|
37
|
+
* the given types.
|
|
38
|
+
*
|
|
39
|
+
* @param transactionMeta - Transaction metadata.
|
|
40
|
+
* @param types - Transaction types to match against.
|
|
41
|
+
* @returns `true` when the transaction or a nested transaction has one of the given types.
|
|
42
|
+
*/
|
|
43
|
+
export declare function hasTransactionType(transactionMeta: TransactionMeta | undefined, types: readonly TransactionType[]): boolean;
|
|
34
44
|
//# sourceMappingURL=transaction-type.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transaction-type.d.cts","sourceRoot":"","sources":["../../src/utils/transaction-type.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,2BAA2B;AAOjE,OAAO,KAAK,EAAE,eAAe,EAAE,qCAAqC;AAEpE,OAAO,KAAK,EAAE,8BAA8B,EAAE,qCAAiC;AAC/E,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"transaction-type.d.cts","sourceRoot":"","sources":["../../src/utils/transaction-type.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,2BAA2B;AAOjE,OAAO,KAAK,EAAE,eAAe,EAAE,qCAAqC;AAEpE,OAAO,KAAK,EAAE,8BAA8B,EAAE,qCAAiC;AAC/E,OAAO,KAAK,EACV,0BAA0B,EAC1B,eAAe,EACf,iBAAiB,EAClB,qBAAiB;AAClB,OAAO,EAAE,eAAe,EAAE,qBAAiB;AAI3C,eAAO,MAAM,kBAAkB,qCAAqC,CAAC;AAOrE;;;;;;;;;;GAUG;AACH,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,CAAC,EAAE;IACR,SAAS,EAAE,8BAA8B,CAAC;IAC1C,eAAe,EAAE,eAAe,CAAC;CAClC,GACA,OAAO,CAAC,0BAA0B,CAAC,CA2DrC;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IACR,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,GACA,SAAS,GAAG,sBAAsB,GAAG,MAAM,CAwB7C;AAoDD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,eAAe,EAAE,eAAe,GAAG,SAAS,EAC5C,KAAK,EAAE,SAAS,eAAe,EAAE,GAChC,OAAO,CAYT"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { TransactionDescription } from "@ethersproject/abi";
|
|
2
2
|
import type { NetworkClientId } from "@metamask/network-controller";
|
|
3
3
|
import type { TransactionControllerMessenger } from "../TransactionController.mjs";
|
|
4
|
-
import type { InferTransactionTypeResult, TransactionParams } from "../types.mjs";
|
|
4
|
+
import type { InferTransactionTypeResult, TransactionMeta, TransactionParams } from "../types.mjs";
|
|
5
|
+
import { TransactionType } from "../types.mjs";
|
|
5
6
|
export declare const ESTIMATE_GAS_ERROR = "eth_estimateGas rpc method error";
|
|
6
7
|
/**
|
|
7
8
|
* Determines the type of the transaction by analyzing the txParams.
|
|
@@ -31,4 +32,13 @@ export declare function determineTransactionType(txParams: TransactionParams, op
|
|
|
31
32
|
export declare function decodeTransactionData(data: string, options?: {
|
|
32
33
|
getMethodName?: boolean;
|
|
33
34
|
}): undefined | TransactionDescription | string;
|
|
35
|
+
/**
|
|
36
|
+
* Check whether a transaction (or any of its nested transactions) has one of
|
|
37
|
+
* the given types.
|
|
38
|
+
*
|
|
39
|
+
* @param transactionMeta - Transaction metadata.
|
|
40
|
+
* @param types - Transaction types to match against.
|
|
41
|
+
* @returns `true` when the transaction or a nested transaction has one of the given types.
|
|
42
|
+
*/
|
|
43
|
+
export declare function hasTransactionType(transactionMeta: TransactionMeta | undefined, types: readonly TransactionType[]): boolean;
|
|
34
44
|
//# sourceMappingURL=transaction-type.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transaction-type.d.mts","sourceRoot":"","sources":["../../src/utils/transaction-type.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,2BAA2B;AAOjE,OAAO,KAAK,EAAE,eAAe,EAAE,qCAAqC;AAEpE,OAAO,KAAK,EAAE,8BAA8B,EAAE,qCAAiC;AAC/E,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"transaction-type.d.mts","sourceRoot":"","sources":["../../src/utils/transaction-type.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,2BAA2B;AAOjE,OAAO,KAAK,EAAE,eAAe,EAAE,qCAAqC;AAEpE,OAAO,KAAK,EAAE,8BAA8B,EAAE,qCAAiC;AAC/E,OAAO,KAAK,EACV,0BAA0B,EAC1B,eAAe,EACf,iBAAiB,EAClB,qBAAiB;AAClB,OAAO,EAAE,eAAe,EAAE,qBAAiB;AAI3C,eAAO,MAAM,kBAAkB,qCAAqC,CAAC;AAOrE;;;;;;;;;;GAUG;AACH,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,CAAC,EAAE;IACR,SAAS,EAAE,8BAA8B,CAAC;IAC1C,eAAe,EAAE,eAAe,CAAC;CAClC,GACA,OAAO,CAAC,0BAA0B,CAAC,CA2DrC;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IACR,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,GACA,SAAS,GAAG,sBAAsB,GAAG,MAAM,CAwB7C;AAoDD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,eAAe,EAAE,eAAe,GAAG,SAAS,EAC5C,KAAK,EAAE,SAAS,eAAe,EAAE,GAChC,OAAO,CAYT"}
|
|
@@ -135,4 +135,19 @@ async function readAddressAsContract(messenger, networkClientId, address) {
|
|
|
135
135
|
: false;
|
|
136
136
|
return { contractCode, isContractAddress };
|
|
137
137
|
}
|
|
138
|
+
/**
|
|
139
|
+
* Check whether a transaction (or any of its nested transactions) has one of
|
|
140
|
+
* the given types.
|
|
141
|
+
*
|
|
142
|
+
* @param transactionMeta - Transaction metadata.
|
|
143
|
+
* @param types - Transaction types to match against.
|
|
144
|
+
* @returns `true` when the transaction or a nested transaction has one of the given types.
|
|
145
|
+
*/
|
|
146
|
+
export function hasTransactionType(transactionMeta, types) {
|
|
147
|
+
const { nestedTransactions, type } = transactionMeta ?? {};
|
|
148
|
+
if (types.includes(type)) {
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
return (nestedTransactions?.some((tx) => types.includes(tx.type)) ?? false);
|
|
152
|
+
}
|
|
138
153
|
//# sourceMappingURL=transaction-type.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transaction-type.mjs","sourceRoot":"","sources":["../../src/utils/transaction-type.ts"],"names":[],"mappings":"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","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport type { TransactionDescription } from '@ethersproject/abi';\nimport {\n abiERC721,\n abiERC20,\n abiERC1155,\n abiFiatTokenV2,\n} from '@metamask/metamask-eth-abis';\nimport type { NetworkClientId } from '@metamask/network-controller';\n\nimport type { TransactionControllerMessenger } from '../TransactionController';\nimport type { InferTransactionTypeResult, TransactionParams } from '../types';\nimport { TransactionType } from '../types';\nimport { DELEGATION_PREFIX } from './eip7702';\nimport { rpcRequest } from './provider';\n\nexport const ESTIMATE_GAS_ERROR = 'eth_estimateGas rpc method error';\n\nconst ERC20Interface = new Interface(abiERC20);\nconst ERC721Interface = new Interface(abiERC721);\nconst ERC1155Interface = new Interface(abiERC1155);\nconst USDCInterface = new Interface(abiFiatTokenV2);\n\n/**\n * Determines the type of the transaction by analyzing the txParams.\n * It will never return TRANSACTION_TYPE_CANCEL or TRANSACTION_TYPE_RETRY as these\n * represent specific events that we specify manually at transaction creation.\n *\n * @param txParams - Parameters for the transaction.\n * @param options - Optional messenger and network client ID to query the network.\n * @param options.messenger - The TransactionController messenger.\n * @param options.networkClientId - The network client ID to use.\n * @returns A object with the transaction type and the contract code response in Hex.\n */\nexport async function determineTransactionType(\n txParams: TransactionParams,\n options?: {\n messenger: TransactionControllerMessenger;\n networkClientId: NetworkClientId;\n },\n): Promise<InferTransactionTypeResult> {\n const { data, to } = txParams;\n\n const hasRealBytecode = Boolean(data && data !== '0x' && data.length > 2);\n\n if (hasRealBytecode && !to) {\n return { type: TransactionType.deployContract, getCodeResponse: undefined };\n }\n\n let getCodeResponse;\n let isContractAddress = Boolean(data?.length);\n\n if (options) {\n const { messenger, networkClientId } = options;\n const response = await readAddressAsContract(\n messenger,\n networkClientId,\n to,\n );\n\n getCodeResponse = response.contractCode;\n isContractAddress = response.isContractAddress;\n }\n\n if (!isContractAddress) {\n return { type: TransactionType.simpleSend, getCodeResponse };\n }\n\n const hasValue = Number(txParams.value ?? '0') !== 0;\n\n const contractInteractionResult = {\n type: TransactionType.contractInteraction,\n getCodeResponse,\n };\n\n if (!data || hasValue) {\n return contractInteractionResult;\n }\n\n const name = getMethodName(data);\n\n if (!name) {\n return contractInteractionResult;\n }\n\n const tokenMethodName = [\n TransactionType.tokenMethodApprove,\n TransactionType.tokenMethodSetApprovalForAll,\n TransactionType.tokenMethodTransfer,\n TransactionType.tokenMethodTransferFrom,\n TransactionType.tokenMethodSafeTransferFrom,\n TransactionType.tokenMethodIncreaseAllowance,\n ].find((methodName) => methodName.toLowerCase() === name.toLowerCase());\n\n if (tokenMethodName) {\n return { type: tokenMethodName, getCodeResponse };\n }\n\n return contractInteractionResult;\n}\n\n/**\n * Parses transaction data using ABIs for three different token standards: ERC20, ERC721, ERC1155 and USDC.\n * The data will decode correctly if the transaction is an interaction with a contract that matches one of these\n * contract standards\n *\n * @param data - Encoded transaction data.\n * @param options - Options bag.\n * @param options.getMethodName - Whether to get the method name.\n * @returns A representation of an ethereum contract call.\n */\nexport function decodeTransactionData(\n data: string,\n options?: {\n getMethodName?: boolean;\n },\n): undefined | TransactionDescription | string {\n if (!data || data.length < 10) {\n return undefined;\n }\n\n const fourByte = data.substring(0, 10).toLowerCase();\n\n for (const iface of [\n ERC20Interface,\n ERC721Interface,\n ERC1155Interface,\n USDCInterface,\n ]) {\n try {\n if (options?.getMethodName) {\n return iface.getFunction(fourByte)?.name;\n }\n return iface.parseTransaction({ data });\n } catch {\n // Intentionally empty\n }\n }\n\n return undefined;\n}\n\n/**\n * Attempts to get the method name from the given transaction data.\n *\n * @param data - Encoded transaction data.\n * @returns The method name.\n */\nfunction getMethodName(data?: string): string | undefined {\n return decodeTransactionData(data as string, {\n getMethodName: true,\n }) as string | undefined;\n}\n\n/**\n * Reads an Ethereum address and determines if it is a contract address.\n *\n * @param messenger - The TransactionController messenger.\n * @param networkClientId - The network client ID to use.\n * @param address - The Ethereum address.\n * @returns An object containing the contract code and a boolean indicating if it is a contract address.\n */\nasync function readAddressAsContract(\n messenger: TransactionControllerMessenger,\n networkClientId: NetworkClientId,\n address?: string,\n): Promise<{\n contractCode: string | null;\n isContractAddress: boolean;\n}> {\n let contractCode;\n try {\n contractCode = (await rpcRequest({\n messenger,\n networkClientId,\n method: 'eth_getCode',\n params: [address as string, 'latest'],\n })) as string;\n // Not used\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n contractCode = null;\n }\n\n const isContractAddress = contractCode\n ? contractCode !== '0x' &&\n contractCode !== '0x0' &&\n !contractCode.startsWith(DELEGATION_PREFIX)\n : false;\n return { contractCode, isContractAddress };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"transaction-type.mjs","sourceRoot":"","sources":["../../src/utils/transaction-type.ts"],"names":[],"mappings":"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","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport type { TransactionDescription } from '@ethersproject/abi';\nimport {\n abiERC721,\n abiERC20,\n abiERC1155,\n abiFiatTokenV2,\n} from '@metamask/metamask-eth-abis';\nimport type { NetworkClientId } from '@metamask/network-controller';\n\nimport type { TransactionControllerMessenger } from '../TransactionController';\nimport type {\n InferTransactionTypeResult,\n TransactionMeta,\n TransactionParams,\n} from '../types';\nimport { TransactionType } from '../types';\nimport { DELEGATION_PREFIX } from './eip7702';\nimport { rpcRequest } from './provider';\n\nexport const ESTIMATE_GAS_ERROR = 'eth_estimateGas rpc method error';\n\nconst ERC20Interface = new Interface(abiERC20);\nconst ERC721Interface = new Interface(abiERC721);\nconst ERC1155Interface = new Interface(abiERC1155);\nconst USDCInterface = new Interface(abiFiatTokenV2);\n\n/**\n * Determines the type of the transaction by analyzing the txParams.\n * It will never return TRANSACTION_TYPE_CANCEL or TRANSACTION_TYPE_RETRY as these\n * represent specific events that we specify manually at transaction creation.\n *\n * @param txParams - Parameters for the transaction.\n * @param options - Optional messenger and network client ID to query the network.\n * @param options.messenger - The TransactionController messenger.\n * @param options.networkClientId - The network client ID to use.\n * @returns A object with the transaction type and the contract code response in Hex.\n */\nexport async function determineTransactionType(\n txParams: TransactionParams,\n options?: {\n messenger: TransactionControllerMessenger;\n networkClientId: NetworkClientId;\n },\n): Promise<InferTransactionTypeResult> {\n const { data, to } = txParams;\n\n const hasRealBytecode = Boolean(data && data !== '0x' && data.length > 2);\n\n if (hasRealBytecode && !to) {\n return { type: TransactionType.deployContract, getCodeResponse: undefined };\n }\n\n let getCodeResponse;\n let isContractAddress = Boolean(data?.length);\n\n if (options) {\n const { messenger, networkClientId } = options;\n const response = await readAddressAsContract(\n messenger,\n networkClientId,\n to,\n );\n\n getCodeResponse = response.contractCode;\n isContractAddress = response.isContractAddress;\n }\n\n if (!isContractAddress) {\n return { type: TransactionType.simpleSend, getCodeResponse };\n }\n\n const hasValue = Number(txParams.value ?? '0') !== 0;\n\n const contractInteractionResult = {\n type: TransactionType.contractInteraction,\n getCodeResponse,\n };\n\n if (!data || hasValue) {\n return contractInteractionResult;\n }\n\n const name = getMethodName(data);\n\n if (!name) {\n return contractInteractionResult;\n }\n\n const tokenMethodName = [\n TransactionType.tokenMethodApprove,\n TransactionType.tokenMethodSetApprovalForAll,\n TransactionType.tokenMethodTransfer,\n TransactionType.tokenMethodTransferFrom,\n TransactionType.tokenMethodSafeTransferFrom,\n TransactionType.tokenMethodIncreaseAllowance,\n ].find((methodName) => methodName.toLowerCase() === name.toLowerCase());\n\n if (tokenMethodName) {\n return { type: tokenMethodName, getCodeResponse };\n }\n\n return contractInteractionResult;\n}\n\n/**\n * Parses transaction data using ABIs for three different token standards: ERC20, ERC721, ERC1155 and USDC.\n * The data will decode correctly if the transaction is an interaction with a contract that matches one of these\n * contract standards\n *\n * @param data - Encoded transaction data.\n * @param options - Options bag.\n * @param options.getMethodName - Whether to get the method name.\n * @returns A representation of an ethereum contract call.\n */\nexport function decodeTransactionData(\n data: string,\n options?: {\n getMethodName?: boolean;\n },\n): undefined | TransactionDescription | string {\n if (!data || data.length < 10) {\n return undefined;\n }\n\n const fourByte = data.substring(0, 10).toLowerCase();\n\n for (const iface of [\n ERC20Interface,\n ERC721Interface,\n ERC1155Interface,\n USDCInterface,\n ]) {\n try {\n if (options?.getMethodName) {\n return iface.getFunction(fourByte)?.name;\n }\n return iface.parseTransaction({ data });\n } catch {\n // Intentionally empty\n }\n }\n\n return undefined;\n}\n\n/**\n * Attempts to get the method name from the given transaction data.\n *\n * @param data - Encoded transaction data.\n * @returns The method name.\n */\nfunction getMethodName(data?: string): string | undefined {\n return decodeTransactionData(data as string, {\n getMethodName: true,\n }) as string | undefined;\n}\n\n/**\n * Reads an Ethereum address and determines if it is a contract address.\n *\n * @param messenger - The TransactionController messenger.\n * @param networkClientId - The network client ID to use.\n * @param address - The Ethereum address.\n * @returns An object containing the contract code and a boolean indicating if it is a contract address.\n */\nasync function readAddressAsContract(\n messenger: TransactionControllerMessenger,\n networkClientId: NetworkClientId,\n address?: string,\n): Promise<{\n contractCode: string | null;\n isContractAddress: boolean;\n}> {\n let contractCode;\n try {\n contractCode = (await rpcRequest({\n messenger,\n networkClientId,\n method: 'eth_getCode',\n params: [address as string, 'latest'],\n })) as string;\n // Not used\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n contractCode = null;\n }\n\n const isContractAddress = contractCode\n ? contractCode !== '0x' &&\n contractCode !== '0x0' &&\n !contractCode.startsWith(DELEGATION_PREFIX)\n : false;\n return { contractCode, isContractAddress };\n}\n\n/**\n * Check whether a transaction (or any of its nested transactions) has one of\n * the given types.\n *\n * @param transactionMeta - Transaction metadata.\n * @param types - Transaction types to match against.\n * @returns `true` when the transaction or a nested transaction has one of the given types.\n */\nexport function hasTransactionType(\n transactionMeta: TransactionMeta | undefined,\n types: readonly TransactionType[],\n): boolean {\n const { nestedTransactions, type } = transactionMeta ?? {};\n\n if (types.includes(type as TransactionType)) {\n return true;\n }\n\n return (\n nestedTransactions?.some((tx) =>\n types.includes(tx.type as TransactionType),\n ) ?? false\n );\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamask/transaction-controller",
|
|
3
|
-
"version": "69.
|
|
3
|
+
"version": "69.2.0",
|
|
4
4
|
"description": "Stores transactions alongside their periodically updated statuses and manages interactions such as approval and cancellation",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Ethereum",
|
|
@@ -44,6 +44,8 @@
|
|
|
44
44
|
"build:docs": "typedoc",
|
|
45
45
|
"changelog:update": "../../scripts/update-changelog.sh @metamask/transaction-controller",
|
|
46
46
|
"changelog:validate": "../../scripts/validate-changelog.sh @metamask/transaction-controller",
|
|
47
|
+
"lint:tsconfigs": "tsx ../../scripts/lint-tsconfigs/lint-tsconfigs.mts",
|
|
48
|
+
"lint:tsconfigs:fix": "tsx ../../scripts/lint-tsconfigs/lint-tsconfigs.mts --fix",
|
|
47
49
|
"messenger-action-types:check": "tsx ../../packages/messenger-cli/src/cli.ts --formatter oxfmt --check",
|
|
48
50
|
"messenger-action-types:generate": "tsx ../../packages/messenger-cli/src/cli.ts --formatter oxfmt --generate",
|
|
49
51
|
"since-latest-release": "../../scripts/since-latest-release.sh",
|
|
@@ -58,7 +60,6 @@
|
|
|
58
60
|
"@ethereumjs/util": "^9.1.0",
|
|
59
61
|
"@ethersproject/abi": "^5.7.0",
|
|
60
62
|
"@ethersproject/contracts": "^5.7.0",
|
|
61
|
-
"@ethersproject/providers": "^5.7.0",
|
|
62
63
|
"@ethersproject/wallet": "^5.7.0",
|
|
63
64
|
"@metamask/accounts-controller": "^39.0.5",
|
|
64
65
|
"@metamask/approval-controller": "^9.0.2",
|