@metamask/transaction-controller 62.5.0 → 62.6.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 +21 -1
- package/dist/TransactionController.cjs +105 -48
- package/dist/TransactionController.cjs.map +1 -1
- package/dist/TransactionController.d.cts +33 -21
- package/dist/TransactionController.d.cts.map +1 -1
- package/dist/TransactionController.d.mts +33 -21
- package/dist/TransactionController.d.mts.map +1 -1
- package/dist/TransactionController.mjs +106 -49
- package/dist/TransactionController.mjs.map +1 -1
- package/dist/api/accounts-api.cjs +1 -1
- package/dist/api/accounts-api.cjs.map +1 -1
- package/dist/api/accounts-api.mjs +1 -1
- package/dist/api/accounts-api.mjs.map +1 -1
- package/dist/api/simulation-api.cjs +1 -1
- package/dist/api/simulation-api.cjs.map +1 -1
- package/dist/api/simulation-api.mjs +1 -1
- package/dist/api/simulation-api.mjs.map +1 -1
- package/dist/gas-flows/LineaGasFeeFlow.cjs.map +1 -1
- package/dist/gas-flows/LineaGasFeeFlow.mjs.map +1 -1
- package/dist/gas-flows/OptimismLayer1GasFeeFlow.cjs +28 -17
- package/dist/gas-flows/OptimismLayer1GasFeeFlow.cjs.map +1 -1
- package/dist/gas-flows/OptimismLayer1GasFeeFlow.d.cts +1 -6
- package/dist/gas-flows/OptimismLayer1GasFeeFlow.d.cts.map +1 -1
- package/dist/gas-flows/OptimismLayer1GasFeeFlow.d.mts +1 -6
- package/dist/gas-flows/OptimismLayer1GasFeeFlow.d.mts.map +1 -1
- package/dist/gas-flows/OptimismLayer1GasFeeFlow.mjs +28 -17
- package/dist/gas-flows/OptimismLayer1GasFeeFlow.mjs.map +1 -1
- package/dist/gas-flows/OracleLayer1GasFeeFlow.cjs +1 -0
- package/dist/gas-flows/OracleLayer1GasFeeFlow.cjs.map +1 -1
- package/dist/gas-flows/OracleLayer1GasFeeFlow.d.cts.map +1 -1
- package/dist/gas-flows/OracleLayer1GasFeeFlow.d.mts.map +1 -1
- package/dist/gas-flows/OracleLayer1GasFeeFlow.mjs +1 -0
- package/dist/gas-flows/OracleLayer1GasFeeFlow.mjs.map +1 -1
- package/dist/helpers/AccountsApiRemoteTransactionSource.cjs.map +1 -1
- package/dist/helpers/AccountsApiRemoteTransactionSource.mjs.map +1 -1
- package/dist/helpers/GasFeePoller.cjs.map +1 -1
- package/dist/helpers/GasFeePoller.mjs.map +1 -1
- package/dist/helpers/IncomingTransactionHelper.cjs.map +1 -1
- package/dist/helpers/IncomingTransactionHelper.d.cts.map +1 -1
- package/dist/helpers/IncomingTransactionHelper.d.mts.map +1 -1
- package/dist/helpers/IncomingTransactionHelper.mjs.map +1 -1
- package/dist/helpers/MultichainTrackingHelper.cjs +2 -2
- package/dist/helpers/MultichainTrackingHelper.cjs.map +1 -1
- package/dist/helpers/MultichainTrackingHelper.d.cts.map +1 -1
- package/dist/helpers/MultichainTrackingHelper.d.mts.map +1 -1
- package/dist/helpers/MultichainTrackingHelper.mjs +2 -2
- package/dist/helpers/MultichainTrackingHelper.mjs.map +1 -1
- package/dist/helpers/PendingTransactionTracker.cjs +88 -22
- package/dist/helpers/PendingTransactionTracker.cjs.map +1 -1
- package/dist/helpers/PendingTransactionTracker.d.cts +7 -6
- package/dist/helpers/PendingTransactionTracker.d.cts.map +1 -1
- package/dist/helpers/PendingTransactionTracker.d.mts +7 -6
- package/dist/helpers/PendingTransactionTracker.d.mts.map +1 -1
- package/dist/helpers/PendingTransactionTracker.mjs +88 -22
- package/dist/helpers/PendingTransactionTracker.mjs.map +1 -1
- package/dist/helpers/ResimulateHelper.cjs.map +1 -1
- package/dist/helpers/ResimulateHelper.d.cts +1 -4
- package/dist/helpers/ResimulateHelper.d.cts.map +1 -1
- package/dist/helpers/ResimulateHelper.d.mts +1 -4
- package/dist/helpers/ResimulateHelper.d.mts.map +1 -1
- package/dist/helpers/ResimulateHelper.mjs.map +1 -1
- package/dist/helpers/TransactionPoller.cjs.map +1 -1
- package/dist/helpers/TransactionPoller.d.cts.map +1 -1
- package/dist/helpers/TransactionPoller.d.mts.map +1 -1
- package/dist/helpers/TransactionPoller.mjs.map +1 -1
- package/dist/hooks/CollectPublishHook.cjs +1 -1
- package/dist/hooks/CollectPublishHook.cjs.map +1 -1
- package/dist/hooks/CollectPublishHook.d.cts.map +1 -1
- package/dist/hooks/CollectPublishHook.d.mts.map +1 -1
- package/dist/hooks/CollectPublishHook.mjs +1 -1
- package/dist/hooks/CollectPublishHook.mjs.map +1 -1
- package/dist/hooks/ExtraTransactionsPublishHook.cjs.map +1 -1
- package/dist/hooks/ExtraTransactionsPublishHook.mjs.map +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/types.cjs +5 -0
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +6 -0
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +6 -0
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs +5 -0
- package/dist/types.mjs.map +1 -1
- package/dist/utils/balance-changes.cjs +5 -5
- package/dist/utils/balance-changes.cjs.map +1 -1
- package/dist/utils/balance-changes.d.cts.map +1 -1
- package/dist/utils/balance-changes.d.mts.map +1 -1
- package/dist/utils/balance-changes.mjs +5 -5
- package/dist/utils/balance-changes.mjs.map +1 -1
- package/dist/utils/balance.cjs.map +1 -1
- package/dist/utils/balance.d.cts.map +1 -1
- package/dist/utils/balance.d.mts.map +1 -1
- package/dist/utils/balance.mjs.map +1 -1
- package/dist/utils/batch.cjs +9 -4
- package/dist/utils/batch.cjs.map +1 -1
- package/dist/utils/batch.d.cts.map +1 -1
- package/dist/utils/batch.d.mts.map +1 -1
- package/dist/utils/batch.mjs +9 -4
- package/dist/utils/batch.mjs.map +1 -1
- package/dist/utils/eip7702.cjs +4 -3
- package/dist/utils/eip7702.cjs.map +1 -1
- package/dist/utils/eip7702.d.cts +1 -1
- package/dist/utils/eip7702.d.cts.map +1 -1
- package/dist/utils/eip7702.d.mts +1 -1
- package/dist/utils/eip7702.d.mts.map +1 -1
- package/dist/utils/eip7702.mjs +4 -3
- package/dist/utils/eip7702.mjs.map +1 -1
- package/dist/utils/external-transactions.cjs.map +1 -1
- package/dist/utils/external-transactions.d.cts.map +1 -1
- package/dist/utils/external-transactions.d.mts.map +1 -1
- package/dist/utils/external-transactions.mjs.map +1 -1
- package/dist/utils/feature-flags.cjs +22 -7
- package/dist/utils/feature-flags.cjs.map +1 -1
- package/dist/utils/feature-flags.d.cts +24 -0
- package/dist/utils/feature-flags.d.cts.map +1 -1
- package/dist/utils/feature-flags.d.mts +24 -0
- package/dist/utils/feature-flags.d.mts.map +1 -1
- package/dist/utils/feature-flags.mjs +20 -6
- package/dist/utils/feature-flags.mjs.map +1 -1
- package/dist/utils/first-time-interaction.cjs +3 -5
- package/dist/utils/first-time-interaction.cjs.map +1 -1
- package/dist/utils/first-time-interaction.d.cts.map +1 -1
- package/dist/utils/first-time-interaction.d.mts.map +1 -1
- package/dist/utils/first-time-interaction.mjs +3 -5
- package/dist/utils/first-time-interaction.mjs.map +1 -1
- package/dist/utils/gas-fee-tokens.cjs +1 -1
- package/dist/utils/gas-fee-tokens.cjs.map +1 -1
- package/dist/utils/gas-fee-tokens.d.cts.map +1 -1
- package/dist/utils/gas-fee-tokens.d.mts.map +1 -1
- package/dist/utils/gas-fee-tokens.mjs +1 -1
- package/dist/utils/gas-fee-tokens.mjs.map +1 -1
- package/dist/utils/gas-fees.cjs +1 -3
- package/dist/utils/gas-fees.cjs.map +1 -1
- package/dist/utils/gas-fees.d.cts +1 -1
- package/dist/utils/gas-fees.d.cts.map +1 -1
- package/dist/utils/gas-fees.d.mts +1 -1
- package/dist/utils/gas-fees.d.mts.map +1 -1
- package/dist/utils/gas-fees.mjs +1 -3
- package/dist/utils/gas-fees.mjs.map +1 -1
- package/dist/utils/gas.cjs +71 -15
- package/dist/utils/gas.cjs.map +1 -1
- package/dist/utils/gas.d.cts +18 -12
- package/dist/utils/gas.d.cts.map +1 -1
- package/dist/utils/gas.d.mts +18 -12
- package/dist/utils/gas.d.mts.map +1 -1
- package/dist/utils/gas.mjs +70 -15
- package/dist/utils/gas.mjs.map +1 -1
- 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.map +1 -1
- package/dist/utils/prepare.cjs.map +1 -1
- package/dist/utils/prepare.d.cts +1 -1
- package/dist/utils/prepare.d.cts.map +1 -1
- package/dist/utils/prepare.d.mts +1 -1
- package/dist/utils/prepare.d.mts.map +1 -1
- package/dist/utils/prepare.mjs.map +1 -1
- package/dist/utils/swaps.cjs.map +1 -1
- package/dist/utils/swaps.mjs.map +1 -1
- package/dist/utils/utils.cjs +10 -10
- package/dist/utils/utils.cjs.map +1 -1
- package/dist/utils/utils.d.cts +4 -4
- package/dist/utils/utils.d.cts.map +1 -1
- package/dist/utils/utils.d.mts +4 -4
- package/dist/utils/utils.d.mts.map +1 -1
- package/dist/utils/utils.mjs +10 -10
- package/dist/utils/utils.mjs.map +1 -1
- package/dist/utils/validation.cjs.map +1 -1
- package/dist/utils/validation.d.cts.map +1 -1
- package/dist/utils/validation.d.mts.map +1 -1
- package/dist/utils/validation.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -84,7 +84,7 @@ async function getAccountTransactions(request) {
|
|
|
84
84
|
url += `?${params.join('&')}`;
|
|
85
85
|
}
|
|
86
86
|
log('Getting account transactions', { request, url });
|
|
87
|
-
const clientId = [CLIENT_ID, ...(tags
|
|
87
|
+
const clientId = [CLIENT_ID, ...(tags ?? [])].join('__');
|
|
88
88
|
const headers = {
|
|
89
89
|
[CLIENT_HEADER]: clientId,
|
|
90
90
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accounts-api.cjs","sourceRoot":"","sources":["../../src/api/accounts-api.ts"],"names":[],"mappings":"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","sourcesContent":["import { successfulFetch } from '@metamask/controller-utils';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\n\nimport { FirstTimeInteractionError } from '../errors';\nimport { projectLogger } from '../logger';\n\nexport type AccountAddressRelationshipResponse = {\n chainId?: number;\n count?: number;\n data?: {\n hash: string;\n timestamp: string;\n chainId: number;\n blockNumber: string;\n blockHash: string;\n gas: number;\n gasUsed: number;\n gasPrice: string;\n effectiveGasPrice: number;\n nonce: number;\n cumulativeGasUsed: number;\n methodId: string;\n value: string;\n to: string;\n from: string;\n };\n txHash?: string;\n};\n\nexport type AccountAddressRelationshipResult =\n AccountAddressRelationshipResponse & {\n error?: {\n code: string;\n message: string;\n };\n };\n\nexport type GetAccountAddressRelationshipRequest = {\n /** Chain ID of account relationship to check. */\n chainId: number;\n\n /** Recipient of the transaction. */\n to: string;\n\n /** Sender of the transaction. */\n from: string;\n};\n\nexport type TransactionResponse = {\n hash: Hex;\n timestamp: string;\n chainId: number;\n blockNumber: number;\n blockHash: Hex;\n gas: number;\n gasUsed: number;\n gasPrice: string;\n effectiveGasPrice: string;\n nonce: number;\n cumulativeGasUsed: number;\n methodId?: Hex;\n value: string;\n to: string;\n from: string;\n isError: boolean;\n valueTransfers: {\n contractAddress: string;\n decimal: number;\n symbol: string;\n from: string;\n to: string;\n amount: string;\n }[];\n};\n\nexport type GetAccountTransactionsRequest = {\n address: Hex;\n chainIds?: Hex[];\n cursor?: string;\n endTimestamp?: number;\n sortDirection?: 'ASC' | 'DESC';\n startTimestamp?: number;\n tags?: string[];\n};\n\nexport type GetAccountTransactionsResponse = {\n data: TransactionResponse[];\n pageInfo: {\n count: number;\n hasNextPage: boolean;\n cursor?: string;\n };\n};\n\nconst BASE_URL = `https://accounts.api.cx.metamask.io`;\nconst BASE_URL_ACCOUNTS = `${BASE_URL}/v1/accounts/`;\nconst CLIENT_HEADER = 'x-metamask-clientproduct';\nconst CLIENT_ID = 'metamask-transaction-controller';\n\nconst SUPPORTED_CHAIN_IDS_FOR_RELATIONSHIP_API = [\n 1, // Ethereum Mainnet\n 10, // Optimism\n 56, // BSC\n 137, // Polygon\n 8453, // Base\n 42161, // Arbitrum\n 59144, // Linea\n 534352, // Scroll\n 1329, // Sei\n 143, // Monad\n];\n\nconst log = createModuleLogger(projectLogger, 'accounts-api');\n\n/**\n * Fetch account address relationship from the accounts API.\n *\n * @param request - The request object.\n * @returns The raw response object from the API.\n */\nexport async function getAccountAddressRelationship(\n request: GetAccountAddressRelationshipRequest,\n): Promise<AccountAddressRelationshipResult> {\n const { chainId, from, to } = request;\n\n if (!SUPPORTED_CHAIN_IDS_FOR_RELATIONSHIP_API.includes(chainId)) {\n log('Unsupported chain ID for account relationship API', chainId);\n throw new FirstTimeInteractionError('Unsupported chain ID');\n }\n\n const url = `${BASE_URL}/v1/networks/${chainId}/accounts/${from}/relationships/${to}`;\n\n log('Getting account address relationship', { request, url });\n\n const headers = {\n [CLIENT_HEADER]: CLIENT_ID,\n };\n\n const response = await successfulFetch(url, { headers });\n\n if (response.status === 204) {\n // The accounts API returns a 204 status code when there are no transactions with empty body\n // imitating a count of 0\n return { count: 0 };\n }\n\n const responseJson: AccountAddressRelationshipResult = await response.json();\n\n log('Retrieved account address relationship', responseJson);\n\n if (responseJson.error) {\n const { code, message } = responseJson.error;\n throw new FirstTimeInteractionError(message, code);\n }\n\n return responseJson;\n}\n\n/**\n * Fetch account transactions from the accounts API.\n *\n * @param request - The request object.\n * @returns The response object.\n */\nexport async function getAccountTransactions(\n request: GetAccountTransactionsRequest,\n): Promise<GetAccountTransactionsResponse> {\n const {\n address,\n chainIds,\n cursor,\n endTimestamp,\n sortDirection,\n startTimestamp,\n tags,\n } = request;\n\n let url = `${BASE_URL_ACCOUNTS}${address}/transactions`;\n const params = [];\n\n if (chainIds) {\n const network = chainIds.join(',');\n params.push(`networks=${network}`);\n }\n\n if (startTimestamp) {\n params.push(`startTimestamp=${startTimestamp}`);\n }\n\n if (endTimestamp) {\n params.push(`endTimestamp=${endTimestamp}`);\n }\n\n if (cursor) {\n params.push(`cursor=${cursor}`);\n }\n\n if (sortDirection) {\n params.push(`sortDirection=${sortDirection}`);\n }\n\n if (params.length) {\n url += `?${params.join('&')}`;\n }\n\n log('Getting account transactions', { request, url });\n\n const clientId = [CLIENT_ID, ...(tags
|
|
1
|
+
{"version":3,"file":"accounts-api.cjs","sourceRoot":"","sources":["../../src/api/accounts-api.ts"],"names":[],"mappings":"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","sourcesContent":["import { successfulFetch } from '@metamask/controller-utils';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\n\nimport { FirstTimeInteractionError } from '../errors';\nimport { projectLogger } from '../logger';\n\nexport type AccountAddressRelationshipResponse = {\n chainId?: number;\n count?: number;\n data?: {\n hash: string;\n timestamp: string;\n chainId: number;\n blockNumber: string;\n blockHash: string;\n gas: number;\n gasUsed: number;\n gasPrice: string;\n effectiveGasPrice: number;\n nonce: number;\n cumulativeGasUsed: number;\n methodId: string;\n value: string;\n to: string;\n from: string;\n };\n txHash?: string;\n};\n\nexport type AccountAddressRelationshipResult =\n AccountAddressRelationshipResponse & {\n error?: {\n code: string;\n message: string;\n };\n };\n\nexport type GetAccountAddressRelationshipRequest = {\n /** Chain ID of account relationship to check. */\n chainId: number;\n\n /** Recipient of the transaction. */\n to: string;\n\n /** Sender of the transaction. */\n from: string;\n};\n\nexport type TransactionResponse = {\n hash: Hex;\n timestamp: string;\n chainId: number;\n blockNumber: number;\n blockHash: Hex;\n gas: number;\n gasUsed: number;\n gasPrice: string;\n effectiveGasPrice: string;\n nonce: number;\n cumulativeGasUsed: number;\n methodId?: Hex;\n value: string;\n to: string;\n from: string;\n isError: boolean;\n valueTransfers: {\n contractAddress: string;\n decimal: number;\n symbol: string;\n from: string;\n to: string;\n amount: string;\n }[];\n};\n\nexport type GetAccountTransactionsRequest = {\n address: Hex;\n chainIds?: Hex[];\n cursor?: string;\n endTimestamp?: number;\n sortDirection?: 'ASC' | 'DESC';\n startTimestamp?: number;\n tags?: string[];\n};\n\nexport type GetAccountTransactionsResponse = {\n data: TransactionResponse[];\n pageInfo: {\n count: number;\n hasNextPage: boolean;\n cursor?: string;\n };\n};\n\nconst BASE_URL = `https://accounts.api.cx.metamask.io`;\nconst BASE_URL_ACCOUNTS = `${BASE_URL}/v1/accounts/`;\nconst CLIENT_HEADER = 'x-metamask-clientproduct';\nconst CLIENT_ID = 'metamask-transaction-controller';\n\nconst SUPPORTED_CHAIN_IDS_FOR_RELATIONSHIP_API = [\n 1, // Ethereum Mainnet\n 10, // Optimism\n 56, // BSC\n 137, // Polygon\n 8453, // Base\n 42161, // Arbitrum\n 59144, // Linea\n 534352, // Scroll\n 1329, // Sei\n 143, // Monad\n];\n\nconst log = createModuleLogger(projectLogger, 'accounts-api');\n\n/**\n * Fetch account address relationship from the accounts API.\n *\n * @param request - The request object.\n * @returns The raw response object from the API.\n */\nexport async function getAccountAddressRelationship(\n request: GetAccountAddressRelationshipRequest,\n): Promise<AccountAddressRelationshipResult> {\n const { chainId, from, to } = request;\n\n if (!SUPPORTED_CHAIN_IDS_FOR_RELATIONSHIP_API.includes(chainId)) {\n log('Unsupported chain ID for account relationship API', chainId);\n throw new FirstTimeInteractionError('Unsupported chain ID');\n }\n\n const url = `${BASE_URL}/v1/networks/${chainId}/accounts/${from}/relationships/${to}`;\n\n log('Getting account address relationship', { request, url });\n\n const headers = {\n [CLIENT_HEADER]: CLIENT_ID,\n };\n\n const response = await successfulFetch(url, { headers });\n\n if (response.status === 204) {\n // The accounts API returns a 204 status code when there are no transactions with empty body\n // imitating a count of 0\n return { count: 0 };\n }\n\n const responseJson: AccountAddressRelationshipResult = await response.json();\n\n log('Retrieved account address relationship', responseJson);\n\n if (responseJson.error) {\n const { code, message } = responseJson.error;\n throw new FirstTimeInteractionError(message, code);\n }\n\n return responseJson;\n}\n\n/**\n * Fetch account transactions from the accounts API.\n *\n * @param request - The request object.\n * @returns The response object.\n */\nexport async function getAccountTransactions(\n request: GetAccountTransactionsRequest,\n): Promise<GetAccountTransactionsResponse> {\n const {\n address,\n chainIds,\n cursor,\n endTimestamp,\n sortDirection,\n startTimestamp,\n tags,\n } = request;\n\n let url = `${BASE_URL_ACCOUNTS}${address}/transactions`;\n const params = [];\n\n if (chainIds) {\n const network = chainIds.join(',');\n params.push(`networks=${network}`);\n }\n\n if (startTimestamp) {\n params.push(`startTimestamp=${startTimestamp}`);\n }\n\n if (endTimestamp) {\n params.push(`endTimestamp=${endTimestamp}`);\n }\n\n if (cursor) {\n params.push(`cursor=${cursor}`);\n }\n\n if (sortDirection) {\n params.push(`sortDirection=${sortDirection}`);\n }\n\n if (params.length) {\n url += `?${params.join('&')}`;\n }\n\n log('Getting account transactions', { request, url });\n\n const clientId = [CLIENT_ID, ...(tags ?? [])].join('__');\n\n const headers = {\n [CLIENT_HEADER]: clientId,\n };\n\n const response = await successfulFetch(url, { headers });\n const responseJson = await response.json();\n\n log('Retrieved account transactions', responseJson);\n\n return responseJson;\n}\n"]}
|
|
@@ -80,7 +80,7 @@ export async function getAccountTransactions(request) {
|
|
|
80
80
|
url += `?${params.join('&')}`;
|
|
81
81
|
}
|
|
82
82
|
log('Getting account transactions', { request, url });
|
|
83
|
-
const clientId = [CLIENT_ID, ...(tags
|
|
83
|
+
const clientId = [CLIENT_ID, ...(tags ?? [])].join('__');
|
|
84
84
|
const headers = {
|
|
85
85
|
[CLIENT_HEADER]: clientId,
|
|
86
86
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accounts-api.mjs","sourceRoot":"","sources":["../../src/api/accounts-api.ts"],"names":[],"mappings":"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","sourcesContent":["import { successfulFetch } from '@metamask/controller-utils';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\n\nimport { FirstTimeInteractionError } from '../errors';\nimport { projectLogger } from '../logger';\n\nexport type AccountAddressRelationshipResponse = {\n chainId?: number;\n count?: number;\n data?: {\n hash: string;\n timestamp: string;\n chainId: number;\n blockNumber: string;\n blockHash: string;\n gas: number;\n gasUsed: number;\n gasPrice: string;\n effectiveGasPrice: number;\n nonce: number;\n cumulativeGasUsed: number;\n methodId: string;\n value: string;\n to: string;\n from: string;\n };\n txHash?: string;\n};\n\nexport type AccountAddressRelationshipResult =\n AccountAddressRelationshipResponse & {\n error?: {\n code: string;\n message: string;\n };\n };\n\nexport type GetAccountAddressRelationshipRequest = {\n /** Chain ID of account relationship to check. */\n chainId: number;\n\n /** Recipient of the transaction. */\n to: string;\n\n /** Sender of the transaction. */\n from: string;\n};\n\nexport type TransactionResponse = {\n hash: Hex;\n timestamp: string;\n chainId: number;\n blockNumber: number;\n blockHash: Hex;\n gas: number;\n gasUsed: number;\n gasPrice: string;\n effectiveGasPrice: string;\n nonce: number;\n cumulativeGasUsed: number;\n methodId?: Hex;\n value: string;\n to: string;\n from: string;\n isError: boolean;\n valueTransfers: {\n contractAddress: string;\n decimal: number;\n symbol: string;\n from: string;\n to: string;\n amount: string;\n }[];\n};\n\nexport type GetAccountTransactionsRequest = {\n address: Hex;\n chainIds?: Hex[];\n cursor?: string;\n endTimestamp?: number;\n sortDirection?: 'ASC' | 'DESC';\n startTimestamp?: number;\n tags?: string[];\n};\n\nexport type GetAccountTransactionsResponse = {\n data: TransactionResponse[];\n pageInfo: {\n count: number;\n hasNextPage: boolean;\n cursor?: string;\n };\n};\n\nconst BASE_URL = `https://accounts.api.cx.metamask.io`;\nconst BASE_URL_ACCOUNTS = `${BASE_URL}/v1/accounts/`;\nconst CLIENT_HEADER = 'x-metamask-clientproduct';\nconst CLIENT_ID = 'metamask-transaction-controller';\n\nconst SUPPORTED_CHAIN_IDS_FOR_RELATIONSHIP_API = [\n 1, // Ethereum Mainnet\n 10, // Optimism\n 56, // BSC\n 137, // Polygon\n 8453, // Base\n 42161, // Arbitrum\n 59144, // Linea\n 534352, // Scroll\n 1329, // Sei\n 143, // Monad\n];\n\nconst log = createModuleLogger(projectLogger, 'accounts-api');\n\n/**\n * Fetch account address relationship from the accounts API.\n *\n * @param request - The request object.\n * @returns The raw response object from the API.\n */\nexport async function getAccountAddressRelationship(\n request: GetAccountAddressRelationshipRequest,\n): Promise<AccountAddressRelationshipResult> {\n const { chainId, from, to } = request;\n\n if (!SUPPORTED_CHAIN_IDS_FOR_RELATIONSHIP_API.includes(chainId)) {\n log('Unsupported chain ID for account relationship API', chainId);\n throw new FirstTimeInteractionError('Unsupported chain ID');\n }\n\n const url = `${BASE_URL}/v1/networks/${chainId}/accounts/${from}/relationships/${to}`;\n\n log('Getting account address relationship', { request, url });\n\n const headers = {\n [CLIENT_HEADER]: CLIENT_ID,\n };\n\n const response = await successfulFetch(url, { headers });\n\n if (response.status === 204) {\n // The accounts API returns a 204 status code when there are no transactions with empty body\n // imitating a count of 0\n return { count: 0 };\n }\n\n const responseJson: AccountAddressRelationshipResult = await response.json();\n\n log('Retrieved account address relationship', responseJson);\n\n if (responseJson.error) {\n const { code, message } = responseJson.error;\n throw new FirstTimeInteractionError(message, code);\n }\n\n return responseJson;\n}\n\n/**\n * Fetch account transactions from the accounts API.\n *\n * @param request - The request object.\n * @returns The response object.\n */\nexport async function getAccountTransactions(\n request: GetAccountTransactionsRequest,\n): Promise<GetAccountTransactionsResponse> {\n const {\n address,\n chainIds,\n cursor,\n endTimestamp,\n sortDirection,\n startTimestamp,\n tags,\n } = request;\n\n let url = `${BASE_URL_ACCOUNTS}${address}/transactions`;\n const params = [];\n\n if (chainIds) {\n const network = chainIds.join(',');\n params.push(`networks=${network}`);\n }\n\n if (startTimestamp) {\n params.push(`startTimestamp=${startTimestamp}`);\n }\n\n if (endTimestamp) {\n params.push(`endTimestamp=${endTimestamp}`);\n }\n\n if (cursor) {\n params.push(`cursor=${cursor}`);\n }\n\n if (sortDirection) {\n params.push(`sortDirection=${sortDirection}`);\n }\n\n if (params.length) {\n url += `?${params.join('&')}`;\n }\n\n log('Getting account transactions', { request, url });\n\n const clientId = [CLIENT_ID, ...(tags
|
|
1
|
+
{"version":3,"file":"accounts-api.mjs","sourceRoot":"","sources":["../../src/api/accounts-api.ts"],"names":[],"mappings":"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","sourcesContent":["import { successfulFetch } from '@metamask/controller-utils';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\n\nimport { FirstTimeInteractionError } from '../errors';\nimport { projectLogger } from '../logger';\n\nexport type AccountAddressRelationshipResponse = {\n chainId?: number;\n count?: number;\n data?: {\n hash: string;\n timestamp: string;\n chainId: number;\n blockNumber: string;\n blockHash: string;\n gas: number;\n gasUsed: number;\n gasPrice: string;\n effectiveGasPrice: number;\n nonce: number;\n cumulativeGasUsed: number;\n methodId: string;\n value: string;\n to: string;\n from: string;\n };\n txHash?: string;\n};\n\nexport type AccountAddressRelationshipResult =\n AccountAddressRelationshipResponse & {\n error?: {\n code: string;\n message: string;\n };\n };\n\nexport type GetAccountAddressRelationshipRequest = {\n /** Chain ID of account relationship to check. */\n chainId: number;\n\n /** Recipient of the transaction. */\n to: string;\n\n /** Sender of the transaction. */\n from: string;\n};\n\nexport type TransactionResponse = {\n hash: Hex;\n timestamp: string;\n chainId: number;\n blockNumber: number;\n blockHash: Hex;\n gas: number;\n gasUsed: number;\n gasPrice: string;\n effectiveGasPrice: string;\n nonce: number;\n cumulativeGasUsed: number;\n methodId?: Hex;\n value: string;\n to: string;\n from: string;\n isError: boolean;\n valueTransfers: {\n contractAddress: string;\n decimal: number;\n symbol: string;\n from: string;\n to: string;\n amount: string;\n }[];\n};\n\nexport type GetAccountTransactionsRequest = {\n address: Hex;\n chainIds?: Hex[];\n cursor?: string;\n endTimestamp?: number;\n sortDirection?: 'ASC' | 'DESC';\n startTimestamp?: number;\n tags?: string[];\n};\n\nexport type GetAccountTransactionsResponse = {\n data: TransactionResponse[];\n pageInfo: {\n count: number;\n hasNextPage: boolean;\n cursor?: string;\n };\n};\n\nconst BASE_URL = `https://accounts.api.cx.metamask.io`;\nconst BASE_URL_ACCOUNTS = `${BASE_URL}/v1/accounts/`;\nconst CLIENT_HEADER = 'x-metamask-clientproduct';\nconst CLIENT_ID = 'metamask-transaction-controller';\n\nconst SUPPORTED_CHAIN_IDS_FOR_RELATIONSHIP_API = [\n 1, // Ethereum Mainnet\n 10, // Optimism\n 56, // BSC\n 137, // Polygon\n 8453, // Base\n 42161, // Arbitrum\n 59144, // Linea\n 534352, // Scroll\n 1329, // Sei\n 143, // Monad\n];\n\nconst log = createModuleLogger(projectLogger, 'accounts-api');\n\n/**\n * Fetch account address relationship from the accounts API.\n *\n * @param request - The request object.\n * @returns The raw response object from the API.\n */\nexport async function getAccountAddressRelationship(\n request: GetAccountAddressRelationshipRequest,\n): Promise<AccountAddressRelationshipResult> {\n const { chainId, from, to } = request;\n\n if (!SUPPORTED_CHAIN_IDS_FOR_RELATIONSHIP_API.includes(chainId)) {\n log('Unsupported chain ID for account relationship API', chainId);\n throw new FirstTimeInteractionError('Unsupported chain ID');\n }\n\n const url = `${BASE_URL}/v1/networks/${chainId}/accounts/${from}/relationships/${to}`;\n\n log('Getting account address relationship', { request, url });\n\n const headers = {\n [CLIENT_HEADER]: CLIENT_ID,\n };\n\n const response = await successfulFetch(url, { headers });\n\n if (response.status === 204) {\n // The accounts API returns a 204 status code when there are no transactions with empty body\n // imitating a count of 0\n return { count: 0 };\n }\n\n const responseJson: AccountAddressRelationshipResult = await response.json();\n\n log('Retrieved account address relationship', responseJson);\n\n if (responseJson.error) {\n const { code, message } = responseJson.error;\n throw new FirstTimeInteractionError(message, code);\n }\n\n return responseJson;\n}\n\n/**\n * Fetch account transactions from the accounts API.\n *\n * @param request - The request object.\n * @returns The response object.\n */\nexport async function getAccountTransactions(\n request: GetAccountTransactionsRequest,\n): Promise<GetAccountTransactionsResponse> {\n const {\n address,\n chainIds,\n cursor,\n endTimestamp,\n sortDirection,\n startTimestamp,\n tags,\n } = request;\n\n let url = `${BASE_URL_ACCOUNTS}${address}/transactions`;\n const params = [];\n\n if (chainIds) {\n const network = chainIds.join(',');\n params.push(`networks=${network}`);\n }\n\n if (startTimestamp) {\n params.push(`startTimestamp=${startTimestamp}`);\n }\n\n if (endTimestamp) {\n params.push(`endTimestamp=${endTimestamp}`);\n }\n\n if (cursor) {\n params.push(`cursor=${cursor}`);\n }\n\n if (sortDirection) {\n params.push(`sortDirection=${sortDirection}`);\n }\n\n if (params.length) {\n url += `?${params.join('&')}`;\n }\n\n log('Getting account transactions', { request, url });\n\n const clientId = [CLIENT_ID, ...(tags ?? [])].join('__');\n\n const headers = {\n [CLIENT_HEADER]: clientId,\n };\n\n const response = await successfulFetch(url, { headers });\n const responseJson = await response.json();\n\n log('Retrieved account transactions', responseJson);\n\n return responseJson;\n}\n"]}
|
|
@@ -106,7 +106,7 @@ function finalizeRequest(request) {
|
|
|
106
106
|
if (!isToDelegationManager) {
|
|
107
107
|
continue;
|
|
108
108
|
}
|
|
109
|
-
newRequest.overrides = newRequest.overrides
|
|
109
|
+
newRequest.overrides = newRequest.overrides ?? {};
|
|
110
110
|
newRequest.overrides[normalizedTo] = {
|
|
111
111
|
code: constants_1.CODE_DELEGATION_MANAGER_NO_SIGNATURE_ERRORS,
|
|
112
112
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simulation-api.cjs","sourceRoot":"","sources":["../../src/api/simulation-api.ts"],"names":[],"mappings":"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","sourcesContent":["import { convertHexToDecimal } from '@metamask/controller-utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\nimport { cloneDeep } from 'lodash';\n\nimport {\n CODE_DELEGATION_MANAGER_NO_SIGNATURE_ERRORS,\n DELEGATION_MANAGER_ADDRESSES,\n} from '../constants';\nimport { SimulationChainNotSupportedError, SimulationError } from '../errors';\nimport { projectLogger } from '../logger';\nimport type { GetSimulationConfig } from '../types';\n\nconst log = createModuleLogger(projectLogger, 'simulation-api');\n\nconst RPC_METHOD = 'infura_simulateTransactions';\nconst BASE_URL = 'https://tx-sentinel-{0}.api.cx.metamask.io/';\nconst ENDPOINT_NETWORKS = 'networks';\n\n/** Single transaction to simulate in a simulation API request. */\nexport type SimulationRequestTransaction = {\n authorizationList?: {\n /** Address of a smart contract that contains the code to be set. */\n address: Hex;\n\n /** Address of the account being upgraded. */\n from: Hex;\n }[];\n\n /** Data to send with the transaction. */\n data?: Hex;\n\n /** Sender of the transaction. */\n from: Hex;\n\n /** Gas limit for the transaction. */\n gas?: Hex;\n\n /** Maximum fee per gas for the transaction. */\n maxFeePerGas?: Hex;\n\n /** Maximum priority fee per gas for the transaction. */\n maxPriorityFeePerGas?: Hex;\n\n /** Recipient of the transaction. */\n to?: Hex;\n\n /** Value to send with the transaction. */\n value?: Hex;\n};\n\n/** Request to the simulation API to simulate transactions. */\nexport type SimulationRequest = {\n blockOverrides?: {\n time?: Hex;\n };\n\n /**\n * Function to get the simulation configuration.\n */\n getSimulationConfig: GetSimulationConfig;\n\n /**\n * Overrides to the state of the blockchain, keyed by address.\n */\n overrides?: {\n [address: Hex]: {\n /** Override the code for an address. */\n code?: Hex;\n\n /** Overrides to the storage slots for an address. */\n stateDiff?: {\n [slot: Hex]: Hex;\n };\n };\n };\n\n /**\n * Whether to include available token fees.\n */\n suggestFees?: {\n /* Whether to estimate gas for the transaction being submitted via a delegation. */\n with7702?: boolean;\n\n /* Whether to include the gas fee of the token transfer. */\n withFeeTransfer?: boolean;\n\n /* Whether to include the native transfer if available. */\n withTransfer?: boolean;\n };\n\n /**\n * Transactions to be sequentially simulated.\n * State changes impact subsequent transactions in the list.\n */\n transactions: SimulationRequestTransaction[];\n\n /**\n * Whether to include call traces in the response.\n * Defaults to false.\n */\n withCallTrace?: boolean;\n\n /**\n * Whether to include the default block data in the simulation.\n * Defaults to false.\n */\n withDefaultBlockOverrides?: boolean;\n\n /**\n * Whether to use the gas fees in the simulation.\n * Defaults to false.\n */\n withGas?: boolean;\n\n /**\n * Whether to include event logs in the response.\n * Defaults to false.\n */\n withLogs?: boolean;\n};\n\n/** Raw event log emitted by a simulated transaction. */\nexport type SimulationResponseLog = {\n /** Address of the account that created the event. */\n address: Hex;\n\n /** Raw data in the event that is not indexed. */\n data: Hex;\n\n /** Raw indexed data from the event. */\n topics: Hex[];\n};\n\n/** Call trace of a single simulated transaction. */\nexport type SimulationResponseCallTrace = {\n /** Nested calls. */\n calls: SimulationResponseCallTrace[];\n\n /** Raw event logs created by the call. */\n logs: SimulationResponseLog[];\n};\n\n/**\n * Changes to the blockchain state.\n * Keyed by account address.\n */\nexport type SimulationResponseStateDiff = {\n [address: Hex]: {\n /** Native balance of the account. */\n balance?: Hex;\n\n /** Nonce of the account. */\n nonce?: Hex;\n\n /** Storage values per slot. */\n storage?: {\n [slot: Hex]: Hex;\n };\n };\n};\n\nexport type SimulationResponseTokenFee = {\n /** Token data independent of current transaction. */\n token: {\n /** Address of the token contract. */\n address: Hex;\n\n /** Decimals of the token. */\n decimals: number;\n\n /** Symbol of the token. */\n symbol: string;\n };\n\n /** Amount of tokens needed to pay for gas. */\n balanceNeededToken: Hex;\n\n /** Current token balance of sender. */\n currentBalanceToken: Hex;\n\n /** Account address that token should be transferred to. */\n feeRecipient: Hex;\n\n /** Conversation rate of 1 token to native WEI. */\n rateWei: Hex;\n\n /** Portion of `balanceNeededToken` that is the fee paid to MetaMask. */\n serviceFee?: Hex;\n\n /** Estimated gas limit required for fee transfer. */\n transferEstimate: Hex;\n};\n\n/** Response from the simulation API for a single transaction. */\nexport type SimulationResponseTransaction = {\n /** Hierarchy of call data including nested calls and logs. */\n callTrace?: SimulationResponseCallTrace;\n\n /** An error message indicating the transaction could not be simulated. */\n error?: string;\n\n /** Recommended gas fees for the transaction. */\n fees?: {\n /** Gas limit for the fee level. */\n gas: Hex;\n\n /** Maximum fee per gas for the fee level. */\n maxFeePerGas: Hex;\n\n /** Maximum priority fee per gas for the fee level. */\n maxPriorityFeePerGas: Hex;\n\n /** Token fee data for the fee level. */\n tokenFees: SimulationResponseTokenFee[];\n }[];\n\n /**\n * Estimated total gas cost of the transaction.\n * Included in the stateDiff if `withGas` is true.\n */\n gasCost?: number;\n\n /** Required `gasLimit` for the transaction. */\n gasLimit?: Hex;\n\n /** Total gas used by the transaction. */\n gasUsed?: Hex;\n\n /** Return value of the transaction, such as the balance if calling balanceOf. */\n return: Hex;\n\n /** Changes to the blockchain state. */\n stateDiff?: {\n /** Initial blockchain state before the transaction. */\n pre?: SimulationResponseStateDiff;\n\n /** Updated blockchain state after the transaction. */\n post?: SimulationResponseStateDiff;\n };\n};\n\n/** Response from the simulation API. */\nexport type SimulationResponse = {\n /** Simulation data for each transaction in the request. */\n transactions: SimulationResponseTransaction[];\n\n sponsorship: {\n /** Whether the gas costs are sponsored meaning a transfer is not required. */\n isSponsored: boolean;\n\n /** Error message for the determination of sponsorship. */\n error: string | null;\n };\n};\n\n/** Data for a network supported by the Simulation API. */\ntype SimulationNetwork = {\n /** Subdomain of the API for the network. */\n network: string;\n\n /** Whether the network supports confirmation simulations. */\n confirmations: boolean;\n};\n\n/** Response from the simulation API containing supported networks. */\ntype SimulationNetworkResponse = {\n [chainIdDecimal: string]: SimulationNetwork;\n};\n\nlet requestIdCounter = 0;\n\n/**\n * Simulate transactions using the transaction simulation API.\n *\n * @param chainId - The chain ID to simulate transactions on.\n * @param request - The request to simulate transactions.\n * @returns The response from the simulation API.\n */\nexport async function simulateTransactions(\n chainId: Hex,\n request: SimulationRequest,\n): Promise<SimulationResponse> {\n let url = await getSimulationUrl(chainId);\n\n const { newUrl, authorization } =\n (await request.getSimulationConfig(url)) || {};\n if (newUrl) {\n url = newUrl;\n }\n\n const requestId = requestIdCounter;\n requestIdCounter += 1;\n\n const finalRequest = finalizeRequest(request);\n\n log('Sending request', url, request);\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n // Add optional authorization header, if provided.\n if (authorization) {\n headers.Authorization = authorization;\n }\n\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n id: String(requestId),\n jsonrpc: '2.0',\n method: RPC_METHOD,\n params: [finalRequest],\n }),\n });\n\n const responseJson = await response.json();\n\n log('Received response', responseJson);\n\n if (responseJson.error) {\n const { code, message } = responseJson.error;\n throw new SimulationError(message, code);\n }\n\n return responseJson?.result;\n}\n\n/**\n * Get the URL for the transaction simulation API.\n *\n * @param chainId - The chain ID to get the URL for.\n * @returns The URL for the transaction simulation API.\n */\nasync function getSimulationUrl(chainId: Hex): Promise<string> {\n const networkData = await getNetworkData();\n const chainIdDecimal = convertHexToDecimal(chainId);\n const network = networkData[chainIdDecimal];\n\n if (!network?.confirmations) {\n log('Chain is not supported', chainId);\n throw new SimulationChainNotSupportedError(chainId);\n }\n\n return getUrl(network.network);\n}\n\n/**\n * Retrieve the supported network data from the simulation API.\n *\n * @returns The network data response from the simulation API.\n */\nasync function getNetworkData(): Promise<SimulationNetworkResponse> {\n const url = `${getUrl('ethereum-mainnet')}${ENDPOINT_NETWORKS}`;\n const response = await fetch(url);\n return response.json();\n}\n\n/**\n * Generate the URL for the specified subdomain in the simulation API.\n *\n * @param subdomain - The subdomain to generate the URL for.\n * @returns The URL for the transaction simulation API.\n */\nfunction getUrl(subdomain: string): string {\n return BASE_URL.replace('{0}', subdomain);\n}\n\n/**\n * Finalize the simulation request.\n * Overrides the DelegationManager code to remove signature errors.\n * Temporary pending support in the simulation API.\n *\n * @param request - The simulation request to finalize.\n * @returns The finalized simulation request.\n */\nfunction finalizeRequest(request: SimulationRequest): SimulationRequest {\n const newRequest = cloneDeep(request);\n\n for (const transaction of newRequest.transactions) {\n const normalizedTo = transaction.to?.toLowerCase() as Hex;\n\n const isToDelegationManager =\n DELEGATION_MANAGER_ADDRESSES.includes(normalizedTo);\n\n if (!isToDelegationManager) {\n continue;\n }\n\n newRequest.overrides = newRequest.overrides || {};\n\n newRequest.overrides[normalizedTo] = {\n code: CODE_DELEGATION_MANAGER_NO_SIGNATURE_ERRORS,\n };\n }\n\n return newRequest;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"simulation-api.cjs","sourceRoot":"","sources":["../../src/api/simulation-api.ts"],"names":[],"mappings":"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","sourcesContent":["import { convertHexToDecimal } from '@metamask/controller-utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\nimport { cloneDeep } from 'lodash';\n\nimport {\n CODE_DELEGATION_MANAGER_NO_SIGNATURE_ERRORS,\n DELEGATION_MANAGER_ADDRESSES,\n} from '../constants';\nimport { SimulationChainNotSupportedError, SimulationError } from '../errors';\nimport { projectLogger } from '../logger';\nimport type { GetSimulationConfig } from '../types';\n\nconst log = createModuleLogger(projectLogger, 'simulation-api');\n\nconst RPC_METHOD = 'infura_simulateTransactions';\nconst BASE_URL = 'https://tx-sentinel-{0}.api.cx.metamask.io/';\nconst ENDPOINT_NETWORKS = 'networks';\n\n/** Single transaction to simulate in a simulation API request. */\nexport type SimulationRequestTransaction = {\n authorizationList?: {\n /** Address of a smart contract that contains the code to be set. */\n address: Hex;\n\n /** Address of the account being upgraded. */\n from: Hex;\n }[];\n\n /** Data to send with the transaction. */\n data?: Hex;\n\n /** Sender of the transaction. */\n from: Hex;\n\n /** Gas limit for the transaction. */\n gas?: Hex;\n\n /** Maximum fee per gas for the transaction. */\n maxFeePerGas?: Hex;\n\n /** Maximum priority fee per gas for the transaction. */\n maxPriorityFeePerGas?: Hex;\n\n /** Recipient of the transaction. */\n to?: Hex;\n\n /** Value to send with the transaction. */\n value?: Hex;\n};\n\n/** Request to the simulation API to simulate transactions. */\nexport type SimulationRequest = {\n blockOverrides?: {\n time?: Hex;\n };\n\n /**\n * Function to get the simulation configuration.\n */\n getSimulationConfig: GetSimulationConfig;\n\n /**\n * Overrides to the state of the blockchain, keyed by address.\n */\n overrides?: {\n [address: Hex]: {\n /** Override the code for an address. */\n code?: Hex;\n\n /** Overrides to the storage slots for an address. */\n stateDiff?: {\n [slot: Hex]: Hex;\n };\n };\n };\n\n /**\n * Whether to include available token fees.\n */\n suggestFees?: {\n /* Whether to estimate gas for the transaction being submitted via a delegation. */\n with7702?: boolean;\n\n /* Whether to include the gas fee of the token transfer. */\n withFeeTransfer?: boolean;\n\n /* Whether to include the native transfer if available. */\n withTransfer?: boolean;\n };\n\n /**\n * Transactions to be sequentially simulated.\n * State changes impact subsequent transactions in the list.\n */\n transactions: SimulationRequestTransaction[];\n\n /**\n * Whether to include call traces in the response.\n * Defaults to false.\n */\n withCallTrace?: boolean;\n\n /**\n * Whether to include the default block data in the simulation.\n * Defaults to false.\n */\n withDefaultBlockOverrides?: boolean;\n\n /**\n * Whether to use the gas fees in the simulation.\n * Defaults to false.\n */\n withGas?: boolean;\n\n /**\n * Whether to include event logs in the response.\n * Defaults to false.\n */\n withLogs?: boolean;\n};\n\n/** Raw event log emitted by a simulated transaction. */\nexport type SimulationResponseLog = {\n /** Address of the account that created the event. */\n address: Hex;\n\n /** Raw data in the event that is not indexed. */\n data: Hex;\n\n /** Raw indexed data from the event. */\n topics: Hex[];\n};\n\n/** Call trace of a single simulated transaction. */\nexport type SimulationResponseCallTrace = {\n /** Nested calls. */\n calls: SimulationResponseCallTrace[];\n\n /** Raw event logs created by the call. */\n logs: SimulationResponseLog[];\n};\n\n/**\n * Changes to the blockchain state.\n * Keyed by account address.\n */\nexport type SimulationResponseStateDiff = {\n [address: Hex]: {\n /** Native balance of the account. */\n balance?: Hex;\n\n /** Nonce of the account. */\n nonce?: Hex;\n\n /** Storage values per slot. */\n storage?: {\n [slot: Hex]: Hex;\n };\n };\n};\n\nexport type SimulationResponseTokenFee = {\n /** Token data independent of current transaction. */\n token: {\n /** Address of the token contract. */\n address: Hex;\n\n /** Decimals of the token. */\n decimals: number;\n\n /** Symbol of the token. */\n symbol: string;\n };\n\n /** Amount of tokens needed to pay for gas. */\n balanceNeededToken: Hex;\n\n /** Current token balance of sender. */\n currentBalanceToken: Hex;\n\n /** Account address that token should be transferred to. */\n feeRecipient: Hex;\n\n /** Conversation rate of 1 token to native WEI. */\n rateWei: Hex;\n\n /** Portion of `balanceNeededToken` that is the fee paid to MetaMask. */\n serviceFee?: Hex;\n\n /** Estimated gas limit required for fee transfer. */\n transferEstimate: Hex;\n};\n\n/** Response from the simulation API for a single transaction. */\nexport type SimulationResponseTransaction = {\n /** Hierarchy of call data including nested calls and logs. */\n callTrace?: SimulationResponseCallTrace;\n\n /** An error message indicating the transaction could not be simulated. */\n error?: string;\n\n /** Recommended gas fees for the transaction. */\n fees?: {\n /** Gas limit for the fee level. */\n gas: Hex;\n\n /** Maximum fee per gas for the fee level. */\n maxFeePerGas: Hex;\n\n /** Maximum priority fee per gas for the fee level. */\n maxPriorityFeePerGas: Hex;\n\n /** Token fee data for the fee level. */\n tokenFees: SimulationResponseTokenFee[];\n }[];\n\n /**\n * Estimated total gas cost of the transaction.\n * Included in the stateDiff if `withGas` is true.\n */\n gasCost?: number;\n\n /** Required `gasLimit` for the transaction. */\n gasLimit?: Hex;\n\n /** Total gas used by the transaction. */\n gasUsed?: Hex;\n\n /** Return value of the transaction, such as the balance if calling balanceOf. */\n return: Hex;\n\n /** Changes to the blockchain state. */\n stateDiff?: {\n /** Initial blockchain state before the transaction. */\n pre?: SimulationResponseStateDiff;\n\n /** Updated blockchain state after the transaction. */\n post?: SimulationResponseStateDiff;\n };\n};\n\n/** Response from the simulation API. */\nexport type SimulationResponse = {\n /** Simulation data for each transaction in the request. */\n transactions: SimulationResponseTransaction[];\n\n sponsorship: {\n /** Whether the gas costs are sponsored meaning a transfer is not required. */\n isSponsored: boolean;\n\n /** Error message for the determination of sponsorship. */\n error: string | null;\n };\n};\n\n/** Data for a network supported by the Simulation API. */\ntype SimulationNetwork = {\n /** Subdomain of the API for the network. */\n network: string;\n\n /** Whether the network supports confirmation simulations. */\n confirmations: boolean;\n};\n\n/** Response from the simulation API containing supported networks. */\ntype SimulationNetworkResponse = {\n [chainIdDecimal: string]: SimulationNetwork;\n};\n\nlet requestIdCounter = 0;\n\n/**\n * Simulate transactions using the transaction simulation API.\n *\n * @param chainId - The chain ID to simulate transactions on.\n * @param request - The request to simulate transactions.\n * @returns The response from the simulation API.\n */\nexport async function simulateTransactions(\n chainId: Hex,\n request: SimulationRequest,\n): Promise<SimulationResponse> {\n let url = await getSimulationUrl(chainId);\n\n const { newUrl, authorization } =\n (await request.getSimulationConfig(url)) || {};\n if (newUrl) {\n url = newUrl;\n }\n\n const requestId = requestIdCounter;\n requestIdCounter += 1;\n\n const finalRequest = finalizeRequest(request);\n\n log('Sending request', url, request);\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n // Add optional authorization header, if provided.\n if (authorization) {\n headers.Authorization = authorization;\n }\n\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n id: String(requestId),\n jsonrpc: '2.0',\n method: RPC_METHOD,\n params: [finalRequest],\n }),\n });\n\n const responseJson = await response.json();\n\n log('Received response', responseJson);\n\n if (responseJson.error) {\n const { code, message } = responseJson.error;\n throw new SimulationError(message, code);\n }\n\n return responseJson?.result;\n}\n\n/**\n * Get the URL for the transaction simulation API.\n *\n * @param chainId - The chain ID to get the URL for.\n * @returns The URL for the transaction simulation API.\n */\nasync function getSimulationUrl(chainId: Hex): Promise<string> {\n const networkData = await getNetworkData();\n const chainIdDecimal = convertHexToDecimal(chainId);\n const network = networkData[chainIdDecimal];\n\n if (!network?.confirmations) {\n log('Chain is not supported', chainId);\n throw new SimulationChainNotSupportedError(chainId);\n }\n\n return getUrl(network.network);\n}\n\n/**\n * Retrieve the supported network data from the simulation API.\n *\n * @returns The network data response from the simulation API.\n */\nasync function getNetworkData(): Promise<SimulationNetworkResponse> {\n const url = `${getUrl('ethereum-mainnet')}${ENDPOINT_NETWORKS}`;\n const response = await fetch(url);\n return response.json();\n}\n\n/**\n * Generate the URL for the specified subdomain in the simulation API.\n *\n * @param subdomain - The subdomain to generate the URL for.\n * @returns The URL for the transaction simulation API.\n */\nfunction getUrl(subdomain: string): string {\n return BASE_URL.replace('{0}', subdomain);\n}\n\n/**\n * Finalize the simulation request.\n * Overrides the DelegationManager code to remove signature errors.\n * Temporary pending support in the simulation API.\n *\n * @param request - The simulation request to finalize.\n * @returns The finalized simulation request.\n */\nfunction finalizeRequest(request: SimulationRequest): SimulationRequest {\n const newRequest = cloneDeep(request);\n\n for (const transaction of newRequest.transactions) {\n const normalizedTo = transaction.to?.toLowerCase() as Hex;\n\n const isToDelegationManager =\n DELEGATION_MANAGER_ADDRESSES.includes(normalizedTo);\n\n if (!isToDelegationManager) {\n continue;\n }\n\n newRequest.overrides = newRequest.overrides ?? {};\n\n newRequest.overrides[normalizedTo] = {\n code: CODE_DELEGATION_MANAGER_NO_SIGNATURE_ERRORS,\n };\n }\n\n return newRequest;\n}\n"]}
|
|
@@ -103,7 +103,7 @@ function finalizeRequest(request) {
|
|
|
103
103
|
if (!isToDelegationManager) {
|
|
104
104
|
continue;
|
|
105
105
|
}
|
|
106
|
-
newRequest.overrides = newRequest.overrides
|
|
106
|
+
newRequest.overrides = newRequest.overrides ?? {};
|
|
107
107
|
newRequest.overrides[normalizedTo] = {
|
|
108
108
|
code: CODE_DELEGATION_MANAGER_NO_SIGNATURE_ERRORS,
|
|
109
109
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simulation-api.mjs","sourceRoot":"","sources":["../../src/api/simulation-api.ts"],"names":[],"mappings":"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","sourcesContent":["import { convertHexToDecimal } from '@metamask/controller-utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\nimport { cloneDeep } from 'lodash';\n\nimport {\n CODE_DELEGATION_MANAGER_NO_SIGNATURE_ERRORS,\n DELEGATION_MANAGER_ADDRESSES,\n} from '../constants';\nimport { SimulationChainNotSupportedError, SimulationError } from '../errors';\nimport { projectLogger } from '../logger';\nimport type { GetSimulationConfig } from '../types';\n\nconst log = createModuleLogger(projectLogger, 'simulation-api');\n\nconst RPC_METHOD = 'infura_simulateTransactions';\nconst BASE_URL = 'https://tx-sentinel-{0}.api.cx.metamask.io/';\nconst ENDPOINT_NETWORKS = 'networks';\n\n/** Single transaction to simulate in a simulation API request. */\nexport type SimulationRequestTransaction = {\n authorizationList?: {\n /** Address of a smart contract that contains the code to be set. */\n address: Hex;\n\n /** Address of the account being upgraded. */\n from: Hex;\n }[];\n\n /** Data to send with the transaction. */\n data?: Hex;\n\n /** Sender of the transaction. */\n from: Hex;\n\n /** Gas limit for the transaction. */\n gas?: Hex;\n\n /** Maximum fee per gas for the transaction. */\n maxFeePerGas?: Hex;\n\n /** Maximum priority fee per gas for the transaction. */\n maxPriorityFeePerGas?: Hex;\n\n /** Recipient of the transaction. */\n to?: Hex;\n\n /** Value to send with the transaction. */\n value?: Hex;\n};\n\n/** Request to the simulation API to simulate transactions. */\nexport type SimulationRequest = {\n blockOverrides?: {\n time?: Hex;\n };\n\n /**\n * Function to get the simulation configuration.\n */\n getSimulationConfig: GetSimulationConfig;\n\n /**\n * Overrides to the state of the blockchain, keyed by address.\n */\n overrides?: {\n [address: Hex]: {\n /** Override the code for an address. */\n code?: Hex;\n\n /** Overrides to the storage slots for an address. */\n stateDiff?: {\n [slot: Hex]: Hex;\n };\n };\n };\n\n /**\n * Whether to include available token fees.\n */\n suggestFees?: {\n /* Whether to estimate gas for the transaction being submitted via a delegation. */\n with7702?: boolean;\n\n /* Whether to include the gas fee of the token transfer. */\n withFeeTransfer?: boolean;\n\n /* Whether to include the native transfer if available. */\n withTransfer?: boolean;\n };\n\n /**\n * Transactions to be sequentially simulated.\n * State changes impact subsequent transactions in the list.\n */\n transactions: SimulationRequestTransaction[];\n\n /**\n * Whether to include call traces in the response.\n * Defaults to false.\n */\n withCallTrace?: boolean;\n\n /**\n * Whether to include the default block data in the simulation.\n * Defaults to false.\n */\n withDefaultBlockOverrides?: boolean;\n\n /**\n * Whether to use the gas fees in the simulation.\n * Defaults to false.\n */\n withGas?: boolean;\n\n /**\n * Whether to include event logs in the response.\n * Defaults to false.\n */\n withLogs?: boolean;\n};\n\n/** Raw event log emitted by a simulated transaction. */\nexport type SimulationResponseLog = {\n /** Address of the account that created the event. */\n address: Hex;\n\n /** Raw data in the event that is not indexed. */\n data: Hex;\n\n /** Raw indexed data from the event. */\n topics: Hex[];\n};\n\n/** Call trace of a single simulated transaction. */\nexport type SimulationResponseCallTrace = {\n /** Nested calls. */\n calls: SimulationResponseCallTrace[];\n\n /** Raw event logs created by the call. */\n logs: SimulationResponseLog[];\n};\n\n/**\n * Changes to the blockchain state.\n * Keyed by account address.\n */\nexport type SimulationResponseStateDiff = {\n [address: Hex]: {\n /** Native balance of the account. */\n balance?: Hex;\n\n /** Nonce of the account. */\n nonce?: Hex;\n\n /** Storage values per slot. */\n storage?: {\n [slot: Hex]: Hex;\n };\n };\n};\n\nexport type SimulationResponseTokenFee = {\n /** Token data independent of current transaction. */\n token: {\n /** Address of the token contract. */\n address: Hex;\n\n /** Decimals of the token. */\n decimals: number;\n\n /** Symbol of the token. */\n symbol: string;\n };\n\n /** Amount of tokens needed to pay for gas. */\n balanceNeededToken: Hex;\n\n /** Current token balance of sender. */\n currentBalanceToken: Hex;\n\n /** Account address that token should be transferred to. */\n feeRecipient: Hex;\n\n /** Conversation rate of 1 token to native WEI. */\n rateWei: Hex;\n\n /** Portion of `balanceNeededToken` that is the fee paid to MetaMask. */\n serviceFee?: Hex;\n\n /** Estimated gas limit required for fee transfer. */\n transferEstimate: Hex;\n};\n\n/** Response from the simulation API for a single transaction. */\nexport type SimulationResponseTransaction = {\n /** Hierarchy of call data including nested calls and logs. */\n callTrace?: SimulationResponseCallTrace;\n\n /** An error message indicating the transaction could not be simulated. */\n error?: string;\n\n /** Recommended gas fees for the transaction. */\n fees?: {\n /** Gas limit for the fee level. */\n gas: Hex;\n\n /** Maximum fee per gas for the fee level. */\n maxFeePerGas: Hex;\n\n /** Maximum priority fee per gas for the fee level. */\n maxPriorityFeePerGas: Hex;\n\n /** Token fee data for the fee level. */\n tokenFees: SimulationResponseTokenFee[];\n }[];\n\n /**\n * Estimated total gas cost of the transaction.\n * Included in the stateDiff if `withGas` is true.\n */\n gasCost?: number;\n\n /** Required `gasLimit` for the transaction. */\n gasLimit?: Hex;\n\n /** Total gas used by the transaction. */\n gasUsed?: Hex;\n\n /** Return value of the transaction, such as the balance if calling balanceOf. */\n return: Hex;\n\n /** Changes to the blockchain state. */\n stateDiff?: {\n /** Initial blockchain state before the transaction. */\n pre?: SimulationResponseStateDiff;\n\n /** Updated blockchain state after the transaction. */\n post?: SimulationResponseStateDiff;\n };\n};\n\n/** Response from the simulation API. */\nexport type SimulationResponse = {\n /** Simulation data for each transaction in the request. */\n transactions: SimulationResponseTransaction[];\n\n sponsorship: {\n /** Whether the gas costs are sponsored meaning a transfer is not required. */\n isSponsored: boolean;\n\n /** Error message for the determination of sponsorship. */\n error: string | null;\n };\n};\n\n/** Data for a network supported by the Simulation API. */\ntype SimulationNetwork = {\n /** Subdomain of the API for the network. */\n network: string;\n\n /** Whether the network supports confirmation simulations. */\n confirmations: boolean;\n};\n\n/** Response from the simulation API containing supported networks. */\ntype SimulationNetworkResponse = {\n [chainIdDecimal: string]: SimulationNetwork;\n};\n\nlet requestIdCounter = 0;\n\n/**\n * Simulate transactions using the transaction simulation API.\n *\n * @param chainId - The chain ID to simulate transactions on.\n * @param request - The request to simulate transactions.\n * @returns The response from the simulation API.\n */\nexport async function simulateTransactions(\n chainId: Hex,\n request: SimulationRequest,\n): Promise<SimulationResponse> {\n let url = await getSimulationUrl(chainId);\n\n const { newUrl, authorization } =\n (await request.getSimulationConfig(url)) || {};\n if (newUrl) {\n url = newUrl;\n }\n\n const requestId = requestIdCounter;\n requestIdCounter += 1;\n\n const finalRequest = finalizeRequest(request);\n\n log('Sending request', url, request);\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n // Add optional authorization header, if provided.\n if (authorization) {\n headers.Authorization = authorization;\n }\n\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n id: String(requestId),\n jsonrpc: '2.0',\n method: RPC_METHOD,\n params: [finalRequest],\n }),\n });\n\n const responseJson = await response.json();\n\n log('Received response', responseJson);\n\n if (responseJson.error) {\n const { code, message } = responseJson.error;\n throw new SimulationError(message, code);\n }\n\n return responseJson?.result;\n}\n\n/**\n * Get the URL for the transaction simulation API.\n *\n * @param chainId - The chain ID to get the URL for.\n * @returns The URL for the transaction simulation API.\n */\nasync function getSimulationUrl(chainId: Hex): Promise<string> {\n const networkData = await getNetworkData();\n const chainIdDecimal = convertHexToDecimal(chainId);\n const network = networkData[chainIdDecimal];\n\n if (!network?.confirmations) {\n log('Chain is not supported', chainId);\n throw new SimulationChainNotSupportedError(chainId);\n }\n\n return getUrl(network.network);\n}\n\n/**\n * Retrieve the supported network data from the simulation API.\n *\n * @returns The network data response from the simulation API.\n */\nasync function getNetworkData(): Promise<SimulationNetworkResponse> {\n const url = `${getUrl('ethereum-mainnet')}${ENDPOINT_NETWORKS}`;\n const response = await fetch(url);\n return response.json();\n}\n\n/**\n * Generate the URL for the specified subdomain in the simulation API.\n *\n * @param subdomain - The subdomain to generate the URL for.\n * @returns The URL for the transaction simulation API.\n */\nfunction getUrl(subdomain: string): string {\n return BASE_URL.replace('{0}', subdomain);\n}\n\n/**\n * Finalize the simulation request.\n * Overrides the DelegationManager code to remove signature errors.\n * Temporary pending support in the simulation API.\n *\n * @param request - The simulation request to finalize.\n * @returns The finalized simulation request.\n */\nfunction finalizeRequest(request: SimulationRequest): SimulationRequest {\n const newRequest = cloneDeep(request);\n\n for (const transaction of newRequest.transactions) {\n const normalizedTo = transaction.to?.toLowerCase() as Hex;\n\n const isToDelegationManager =\n DELEGATION_MANAGER_ADDRESSES.includes(normalizedTo);\n\n if (!isToDelegationManager) {\n continue;\n }\n\n newRequest.overrides = newRequest.overrides || {};\n\n newRequest.overrides[normalizedTo] = {\n code: CODE_DELEGATION_MANAGER_NO_SIGNATURE_ERRORS,\n };\n }\n\n return newRequest;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"simulation-api.mjs","sourceRoot":"","sources":["../../src/api/simulation-api.ts"],"names":[],"mappings":"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","sourcesContent":["import { convertHexToDecimal } from '@metamask/controller-utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\nimport { cloneDeep } from 'lodash';\n\nimport {\n CODE_DELEGATION_MANAGER_NO_SIGNATURE_ERRORS,\n DELEGATION_MANAGER_ADDRESSES,\n} from '../constants';\nimport { SimulationChainNotSupportedError, SimulationError } from '../errors';\nimport { projectLogger } from '../logger';\nimport type { GetSimulationConfig } from '../types';\n\nconst log = createModuleLogger(projectLogger, 'simulation-api');\n\nconst RPC_METHOD = 'infura_simulateTransactions';\nconst BASE_URL = 'https://tx-sentinel-{0}.api.cx.metamask.io/';\nconst ENDPOINT_NETWORKS = 'networks';\n\n/** Single transaction to simulate in a simulation API request. */\nexport type SimulationRequestTransaction = {\n authorizationList?: {\n /** Address of a smart contract that contains the code to be set. */\n address: Hex;\n\n /** Address of the account being upgraded. */\n from: Hex;\n }[];\n\n /** Data to send with the transaction. */\n data?: Hex;\n\n /** Sender of the transaction. */\n from: Hex;\n\n /** Gas limit for the transaction. */\n gas?: Hex;\n\n /** Maximum fee per gas for the transaction. */\n maxFeePerGas?: Hex;\n\n /** Maximum priority fee per gas for the transaction. */\n maxPriorityFeePerGas?: Hex;\n\n /** Recipient of the transaction. */\n to?: Hex;\n\n /** Value to send with the transaction. */\n value?: Hex;\n};\n\n/** Request to the simulation API to simulate transactions. */\nexport type SimulationRequest = {\n blockOverrides?: {\n time?: Hex;\n };\n\n /**\n * Function to get the simulation configuration.\n */\n getSimulationConfig: GetSimulationConfig;\n\n /**\n * Overrides to the state of the blockchain, keyed by address.\n */\n overrides?: {\n [address: Hex]: {\n /** Override the code for an address. */\n code?: Hex;\n\n /** Overrides to the storage slots for an address. */\n stateDiff?: {\n [slot: Hex]: Hex;\n };\n };\n };\n\n /**\n * Whether to include available token fees.\n */\n suggestFees?: {\n /* Whether to estimate gas for the transaction being submitted via a delegation. */\n with7702?: boolean;\n\n /* Whether to include the gas fee of the token transfer. */\n withFeeTransfer?: boolean;\n\n /* Whether to include the native transfer if available. */\n withTransfer?: boolean;\n };\n\n /**\n * Transactions to be sequentially simulated.\n * State changes impact subsequent transactions in the list.\n */\n transactions: SimulationRequestTransaction[];\n\n /**\n * Whether to include call traces in the response.\n * Defaults to false.\n */\n withCallTrace?: boolean;\n\n /**\n * Whether to include the default block data in the simulation.\n * Defaults to false.\n */\n withDefaultBlockOverrides?: boolean;\n\n /**\n * Whether to use the gas fees in the simulation.\n * Defaults to false.\n */\n withGas?: boolean;\n\n /**\n * Whether to include event logs in the response.\n * Defaults to false.\n */\n withLogs?: boolean;\n};\n\n/** Raw event log emitted by a simulated transaction. */\nexport type SimulationResponseLog = {\n /** Address of the account that created the event. */\n address: Hex;\n\n /** Raw data in the event that is not indexed. */\n data: Hex;\n\n /** Raw indexed data from the event. */\n topics: Hex[];\n};\n\n/** Call trace of a single simulated transaction. */\nexport type SimulationResponseCallTrace = {\n /** Nested calls. */\n calls: SimulationResponseCallTrace[];\n\n /** Raw event logs created by the call. */\n logs: SimulationResponseLog[];\n};\n\n/**\n * Changes to the blockchain state.\n * Keyed by account address.\n */\nexport type SimulationResponseStateDiff = {\n [address: Hex]: {\n /** Native balance of the account. */\n balance?: Hex;\n\n /** Nonce of the account. */\n nonce?: Hex;\n\n /** Storage values per slot. */\n storage?: {\n [slot: Hex]: Hex;\n };\n };\n};\n\nexport type SimulationResponseTokenFee = {\n /** Token data independent of current transaction. */\n token: {\n /** Address of the token contract. */\n address: Hex;\n\n /** Decimals of the token. */\n decimals: number;\n\n /** Symbol of the token. */\n symbol: string;\n };\n\n /** Amount of tokens needed to pay for gas. */\n balanceNeededToken: Hex;\n\n /** Current token balance of sender. */\n currentBalanceToken: Hex;\n\n /** Account address that token should be transferred to. */\n feeRecipient: Hex;\n\n /** Conversation rate of 1 token to native WEI. */\n rateWei: Hex;\n\n /** Portion of `balanceNeededToken` that is the fee paid to MetaMask. */\n serviceFee?: Hex;\n\n /** Estimated gas limit required for fee transfer. */\n transferEstimate: Hex;\n};\n\n/** Response from the simulation API for a single transaction. */\nexport type SimulationResponseTransaction = {\n /** Hierarchy of call data including nested calls and logs. */\n callTrace?: SimulationResponseCallTrace;\n\n /** An error message indicating the transaction could not be simulated. */\n error?: string;\n\n /** Recommended gas fees for the transaction. */\n fees?: {\n /** Gas limit for the fee level. */\n gas: Hex;\n\n /** Maximum fee per gas for the fee level. */\n maxFeePerGas: Hex;\n\n /** Maximum priority fee per gas for the fee level. */\n maxPriorityFeePerGas: Hex;\n\n /** Token fee data for the fee level. */\n tokenFees: SimulationResponseTokenFee[];\n }[];\n\n /**\n * Estimated total gas cost of the transaction.\n * Included in the stateDiff if `withGas` is true.\n */\n gasCost?: number;\n\n /** Required `gasLimit` for the transaction. */\n gasLimit?: Hex;\n\n /** Total gas used by the transaction. */\n gasUsed?: Hex;\n\n /** Return value of the transaction, such as the balance if calling balanceOf. */\n return: Hex;\n\n /** Changes to the blockchain state. */\n stateDiff?: {\n /** Initial blockchain state before the transaction. */\n pre?: SimulationResponseStateDiff;\n\n /** Updated blockchain state after the transaction. */\n post?: SimulationResponseStateDiff;\n };\n};\n\n/** Response from the simulation API. */\nexport type SimulationResponse = {\n /** Simulation data for each transaction in the request. */\n transactions: SimulationResponseTransaction[];\n\n sponsorship: {\n /** Whether the gas costs are sponsored meaning a transfer is not required. */\n isSponsored: boolean;\n\n /** Error message for the determination of sponsorship. */\n error: string | null;\n };\n};\n\n/** Data for a network supported by the Simulation API. */\ntype SimulationNetwork = {\n /** Subdomain of the API for the network. */\n network: string;\n\n /** Whether the network supports confirmation simulations. */\n confirmations: boolean;\n};\n\n/** Response from the simulation API containing supported networks. */\ntype SimulationNetworkResponse = {\n [chainIdDecimal: string]: SimulationNetwork;\n};\n\nlet requestIdCounter = 0;\n\n/**\n * Simulate transactions using the transaction simulation API.\n *\n * @param chainId - The chain ID to simulate transactions on.\n * @param request - The request to simulate transactions.\n * @returns The response from the simulation API.\n */\nexport async function simulateTransactions(\n chainId: Hex,\n request: SimulationRequest,\n): Promise<SimulationResponse> {\n let url = await getSimulationUrl(chainId);\n\n const { newUrl, authorization } =\n (await request.getSimulationConfig(url)) || {};\n if (newUrl) {\n url = newUrl;\n }\n\n const requestId = requestIdCounter;\n requestIdCounter += 1;\n\n const finalRequest = finalizeRequest(request);\n\n log('Sending request', url, request);\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n // Add optional authorization header, if provided.\n if (authorization) {\n headers.Authorization = authorization;\n }\n\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n id: String(requestId),\n jsonrpc: '2.0',\n method: RPC_METHOD,\n params: [finalRequest],\n }),\n });\n\n const responseJson = await response.json();\n\n log('Received response', responseJson);\n\n if (responseJson.error) {\n const { code, message } = responseJson.error;\n throw new SimulationError(message, code);\n }\n\n return responseJson?.result;\n}\n\n/**\n * Get the URL for the transaction simulation API.\n *\n * @param chainId - The chain ID to get the URL for.\n * @returns The URL for the transaction simulation API.\n */\nasync function getSimulationUrl(chainId: Hex): Promise<string> {\n const networkData = await getNetworkData();\n const chainIdDecimal = convertHexToDecimal(chainId);\n const network = networkData[chainIdDecimal];\n\n if (!network?.confirmations) {\n log('Chain is not supported', chainId);\n throw new SimulationChainNotSupportedError(chainId);\n }\n\n return getUrl(network.network);\n}\n\n/**\n * Retrieve the supported network data from the simulation API.\n *\n * @returns The network data response from the simulation API.\n */\nasync function getNetworkData(): Promise<SimulationNetworkResponse> {\n const url = `${getUrl('ethereum-mainnet')}${ENDPOINT_NETWORKS}`;\n const response = await fetch(url);\n return response.json();\n}\n\n/**\n * Generate the URL for the specified subdomain in the simulation API.\n *\n * @param subdomain - The subdomain to generate the URL for.\n * @returns The URL for the transaction simulation API.\n */\nfunction getUrl(subdomain: string): string {\n return BASE_URL.replace('{0}', subdomain);\n}\n\n/**\n * Finalize the simulation request.\n * Overrides the DelegationManager code to remove signature errors.\n * Temporary pending support in the simulation API.\n *\n * @param request - The simulation request to finalize.\n * @returns The finalized simulation request.\n */\nfunction finalizeRequest(request: SimulationRequest): SimulationRequest {\n const newRequest = cloneDeep(request);\n\n for (const transaction of newRequest.transactions) {\n const normalizedTo = transaction.to?.toLowerCase() as Hex;\n\n const isToDelegationManager =\n DELEGATION_MANAGER_ADDRESSES.includes(normalizedTo);\n\n if (!isToDelegationManager) {\n continue;\n }\n\n newRequest.overrides = newRequest.overrides ?? {};\n\n newRequest.overrides[normalizedTo] = {\n code: CODE_DELEGATION_MANAGER_NO_SIGNATURE_ERRORS,\n };\n }\n\n return newRequest;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LineaGasFeeFlow.cjs","sourceRoot":"","sources":["../../src/gas-flows/LineaGasFeeFlow.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChainId, hexToBN, query, toHex } from '@metamask/controller-utils';\nimport type EthQuery from '@metamask/eth-query';\nimport { createModuleLogger } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\nimport type BN from 'bn.js';\n\nimport { DefaultGasFeeFlow } from './DefaultGasFeeFlow';\nimport { projectLogger } from '../logger';\nimport type { TransactionControllerMessenger } from '../TransactionController';\nimport type {\n GasFeeEstimates,\n GasFeeFlow,\n GasFeeFlowRequest,\n GasFeeFlowResponse,\n TransactionMeta,\n} from '../types';\nimport { GasFeeEstimateLevel, GasFeeEstimateType } from '../types';\n\ntype LineaEstimateGasResponse = {\n baseFeePerGas: Hex;\n priorityFeePerGas: Hex;\n};\n\ntype FeesByLevel = {\n [key in GasFeeEstimateLevel]: BN;\n};\n\nconst log = createModuleLogger(projectLogger, 'linea-gas-fee-flow');\n\nconst LINEA_CHAIN_IDS: Hex[] = [\n ChainId['linea-mainnet'],\n ChainId['linea-goerli'],\n ChainId['linea-sepolia'],\n];\n\nconst BASE_FEE_MULTIPLIERS = {\n low: 1,\n medium: 1.35,\n high: 1.7,\n};\n\nconst PRIORITY_FEE_MULTIPLIERS = {\n low: 1,\n medium: 1.05,\n high: 1.1,\n};\n\n/**\n * Implementation of a gas fee flow specific to Linea networks that obtains gas fee estimates using:\n * - The `linea_estimateGas` RPC method to obtain the base fee and lowest priority fee.\n * - Static multipliers to increase the base and priority fees.\n */\nexport class LineaGasFeeFlow implements GasFeeFlow {\n matchesTransaction({\n transactionMeta,\n }: {\n transactionMeta: TransactionMeta;\n messenger: TransactionControllerMessenger;\n }): boolean {\n return LINEA_CHAIN_IDS.includes(transactionMeta.chainId);\n }\n\n async getGasFees(request: GasFeeFlowRequest): Promise<GasFeeFlowResponse> {\n try {\n return await this.#getLineaGasFees(request);\n } catch (error) {\n log('Using default flow as fallback due to error', error);\n return new DefaultGasFeeFlow().getGasFees(request);\n }\n }\n\n async #getLineaGasFees(\n request: GasFeeFlowRequest,\n ): Promise<GasFeeFlowResponse> {\n const { ethQuery, transactionMeta } = request;\n\n const lineaResponse = await this.#getLineaResponse(\n transactionMeta,\n ethQuery,\n );\n\n log('Received Linea response', lineaResponse);\n\n const baseFees = this.#getValuesFromMultipliers(\n lineaResponse.baseFeePerGas,\n BASE_FEE_MULTIPLIERS,\n );\n\n log('Generated base fees', this.#feesToString(baseFees));\n\n const priorityFees = this.#getValuesFromMultipliers(\n lineaResponse.priorityFeePerGas,\n PRIORITY_FEE_MULTIPLIERS,\n );\n\n log('Generated priority fees', this.#feesToString(priorityFees));\n\n const maxFees = this.#getMaxFees(baseFees, priorityFees);\n\n log('Generated max fees', this.#feesToString(maxFees));\n\n const estimates = Object.values(GasFeeEstimateLevel).reduce(\n (result, level) => ({\n ...result,\n [level]: {\n maxFeePerGas: toHex(maxFees[level]),\n maxPriorityFeePerGas: toHex(priorityFees[level]),\n },\n }),\n { type: GasFeeEstimateType.FeeMarket } as GasFeeEstimates,\n );\n\n return { estimates };\n }\n\n #getLineaResponse(\n transactionMeta: TransactionMeta,\n ethQuery: EthQuery,\n ): Promise<LineaEstimateGasResponse> {\n return query(ethQuery, 'linea_estimateGas', [\n {\n from: transactionMeta.txParams.from,\n to: transactionMeta.txParams.to,\n value: transactionMeta.txParams.value,\n input: transactionMeta.txParams.data,\n },\n ]);\n }\n\n #getValuesFromMultipliers(\n value: Hex,\n multipliers: { low: number; medium: number; high: number },\n ): FeesByLevel {\n const base = hexToBN(value);\n const low = base.muln(multipliers.low);\n const medium = base.muln(multipliers.medium);\n const high = base.muln(multipliers.high);\n\n return {\n low,\n medium,\n high,\n };\n }\n\n #getMaxFees(\n baseFees: Record<GasFeeEstimateLevel, BN>,\n priorityFees: Record<GasFeeEstimateLevel, BN>,\n ): FeesByLevel {\n return {\n low: baseFees.low.add(priorityFees.low),\n medium: baseFees.medium.add(priorityFees.medium),\n high: baseFees.high.add(priorityFees.high),\n };\n }\n\n #feesToString(fees: FeesByLevel) {\n return Object.values(GasFeeEstimateLevel).map((level) =>\n fees[level].toString(10),\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"LineaGasFeeFlow.cjs","sourceRoot":"","sources":["../../src/gas-flows/LineaGasFeeFlow.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChainId, hexToBN, query, toHex } from '@metamask/controller-utils';\nimport type EthQuery from '@metamask/eth-query';\nimport { createModuleLogger } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\nimport type BN from 'bn.js';\n\nimport { DefaultGasFeeFlow } from './DefaultGasFeeFlow';\nimport { projectLogger } from '../logger';\nimport type { TransactionControllerMessenger } from '../TransactionController';\nimport type {\n GasFeeEstimates,\n GasFeeFlow,\n GasFeeFlowRequest,\n GasFeeFlowResponse,\n TransactionMeta,\n} from '../types';\nimport { GasFeeEstimateLevel, GasFeeEstimateType } from '../types';\n\ntype LineaEstimateGasResponse = {\n baseFeePerGas: Hex;\n priorityFeePerGas: Hex;\n};\n\ntype FeesByLevel = {\n [key in GasFeeEstimateLevel]: BN;\n};\n\nconst log = createModuleLogger(projectLogger, 'linea-gas-fee-flow');\n\nconst LINEA_CHAIN_IDS: Hex[] = [\n ChainId['linea-mainnet'],\n ChainId['linea-goerli'],\n ChainId['linea-sepolia'],\n];\n\nconst BASE_FEE_MULTIPLIERS = {\n low: 1,\n medium: 1.35,\n high: 1.7,\n};\n\nconst PRIORITY_FEE_MULTIPLIERS = {\n low: 1,\n medium: 1.05,\n high: 1.1,\n};\n\n/**\n * Implementation of a gas fee flow specific to Linea networks that obtains gas fee estimates using:\n * - The `linea_estimateGas` RPC method to obtain the base fee and lowest priority fee.\n * - Static multipliers to increase the base and priority fees.\n */\nexport class LineaGasFeeFlow implements GasFeeFlow {\n matchesTransaction({\n transactionMeta,\n }: {\n transactionMeta: TransactionMeta;\n messenger: TransactionControllerMessenger;\n }): boolean {\n return LINEA_CHAIN_IDS.includes(transactionMeta.chainId);\n }\n\n async getGasFees(request: GasFeeFlowRequest): Promise<GasFeeFlowResponse> {\n try {\n return await this.#getLineaGasFees(request);\n } catch (error) {\n log('Using default flow as fallback due to error', error);\n return new DefaultGasFeeFlow().getGasFees(request);\n }\n }\n\n async #getLineaGasFees(\n request: GasFeeFlowRequest,\n ): Promise<GasFeeFlowResponse> {\n const { ethQuery, transactionMeta } = request;\n\n const lineaResponse = await this.#getLineaResponse(\n transactionMeta,\n ethQuery,\n );\n\n log('Received Linea response', lineaResponse);\n\n const baseFees = this.#getValuesFromMultipliers(\n lineaResponse.baseFeePerGas,\n BASE_FEE_MULTIPLIERS,\n );\n\n log('Generated base fees', this.#feesToString(baseFees));\n\n const priorityFees = this.#getValuesFromMultipliers(\n lineaResponse.priorityFeePerGas,\n PRIORITY_FEE_MULTIPLIERS,\n );\n\n log('Generated priority fees', this.#feesToString(priorityFees));\n\n const maxFees = this.#getMaxFees(baseFees, priorityFees);\n\n log('Generated max fees', this.#feesToString(maxFees));\n\n const estimates = Object.values(GasFeeEstimateLevel).reduce(\n (result, level) => ({\n ...result,\n [level]: {\n maxFeePerGas: toHex(maxFees[level]),\n maxPriorityFeePerGas: toHex(priorityFees[level]),\n },\n }),\n { type: GasFeeEstimateType.FeeMarket } as GasFeeEstimates,\n );\n\n return { estimates };\n }\n\n #getLineaResponse(\n transactionMeta: TransactionMeta,\n ethQuery: EthQuery,\n ): Promise<LineaEstimateGasResponse> {\n return query(ethQuery, 'linea_estimateGas', [\n {\n from: transactionMeta.txParams.from,\n to: transactionMeta.txParams.to,\n value: transactionMeta.txParams.value,\n input: transactionMeta.txParams.data,\n },\n ]);\n }\n\n #getValuesFromMultipliers(\n value: Hex,\n multipliers: { low: number; medium: number; high: number },\n ): FeesByLevel {\n const base = hexToBN(value);\n const low = base.muln(multipliers.low);\n const medium = base.muln(multipliers.medium);\n const high = base.muln(multipliers.high);\n\n return {\n low,\n medium,\n high,\n };\n }\n\n #getMaxFees(\n baseFees: Record<GasFeeEstimateLevel, BN>,\n priorityFees: Record<GasFeeEstimateLevel, BN>,\n ): FeesByLevel {\n return {\n low: baseFees.low.add(priorityFees.low),\n medium: baseFees.medium.add(priorityFees.medium),\n high: baseFees.high.add(priorityFees.high),\n };\n }\n\n #feesToString(fees: FeesByLevel): string[] {\n return Object.values(GasFeeEstimateLevel).map((level) =>\n fees[level].toString(10),\n );\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LineaGasFeeFlow.mjs","sourceRoot":"","sources":["../../src/gas-flows/LineaGasFeeFlow.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChainId, hexToBN, query, toHex } from '@metamask/controller-utils';\nimport type EthQuery from '@metamask/eth-query';\nimport { createModuleLogger } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\nimport type BN from 'bn.js';\n\nimport { DefaultGasFeeFlow } from './DefaultGasFeeFlow';\nimport { projectLogger } from '../logger';\nimport type { TransactionControllerMessenger } from '../TransactionController';\nimport type {\n GasFeeEstimates,\n GasFeeFlow,\n GasFeeFlowRequest,\n GasFeeFlowResponse,\n TransactionMeta,\n} from '../types';\nimport { GasFeeEstimateLevel, GasFeeEstimateType } from '../types';\n\ntype LineaEstimateGasResponse = {\n baseFeePerGas: Hex;\n priorityFeePerGas: Hex;\n};\n\ntype FeesByLevel = {\n [key in GasFeeEstimateLevel]: BN;\n};\n\nconst log = createModuleLogger(projectLogger, 'linea-gas-fee-flow');\n\nconst LINEA_CHAIN_IDS: Hex[] = [\n ChainId['linea-mainnet'],\n ChainId['linea-goerli'],\n ChainId['linea-sepolia'],\n];\n\nconst BASE_FEE_MULTIPLIERS = {\n low: 1,\n medium: 1.35,\n high: 1.7,\n};\n\nconst PRIORITY_FEE_MULTIPLIERS = {\n low: 1,\n medium: 1.05,\n high: 1.1,\n};\n\n/**\n * Implementation of a gas fee flow specific to Linea networks that obtains gas fee estimates using:\n * - The `linea_estimateGas` RPC method to obtain the base fee and lowest priority fee.\n * - Static multipliers to increase the base and priority fees.\n */\nexport class LineaGasFeeFlow implements GasFeeFlow {\n matchesTransaction({\n transactionMeta,\n }: {\n transactionMeta: TransactionMeta;\n messenger: TransactionControllerMessenger;\n }): boolean {\n return LINEA_CHAIN_IDS.includes(transactionMeta.chainId);\n }\n\n async getGasFees(request: GasFeeFlowRequest): Promise<GasFeeFlowResponse> {\n try {\n return await this.#getLineaGasFees(request);\n } catch (error) {\n log('Using default flow as fallback due to error', error);\n return new DefaultGasFeeFlow().getGasFees(request);\n }\n }\n\n async #getLineaGasFees(\n request: GasFeeFlowRequest,\n ): Promise<GasFeeFlowResponse> {\n const { ethQuery, transactionMeta } = request;\n\n const lineaResponse = await this.#getLineaResponse(\n transactionMeta,\n ethQuery,\n );\n\n log('Received Linea response', lineaResponse);\n\n const baseFees = this.#getValuesFromMultipliers(\n lineaResponse.baseFeePerGas,\n BASE_FEE_MULTIPLIERS,\n );\n\n log('Generated base fees', this.#feesToString(baseFees));\n\n const priorityFees = this.#getValuesFromMultipliers(\n lineaResponse.priorityFeePerGas,\n PRIORITY_FEE_MULTIPLIERS,\n );\n\n log('Generated priority fees', this.#feesToString(priorityFees));\n\n const maxFees = this.#getMaxFees(baseFees, priorityFees);\n\n log('Generated max fees', this.#feesToString(maxFees));\n\n const estimates = Object.values(GasFeeEstimateLevel).reduce(\n (result, level) => ({\n ...result,\n [level]: {\n maxFeePerGas: toHex(maxFees[level]),\n maxPriorityFeePerGas: toHex(priorityFees[level]),\n },\n }),\n { type: GasFeeEstimateType.FeeMarket } as GasFeeEstimates,\n );\n\n return { estimates };\n }\n\n #getLineaResponse(\n transactionMeta: TransactionMeta,\n ethQuery: EthQuery,\n ): Promise<LineaEstimateGasResponse> {\n return query(ethQuery, 'linea_estimateGas', [\n {\n from: transactionMeta.txParams.from,\n to: transactionMeta.txParams.to,\n value: transactionMeta.txParams.value,\n input: transactionMeta.txParams.data,\n },\n ]);\n }\n\n #getValuesFromMultipliers(\n value: Hex,\n multipliers: { low: number; medium: number; high: number },\n ): FeesByLevel {\n const base = hexToBN(value);\n const low = base.muln(multipliers.low);\n const medium = base.muln(multipliers.medium);\n const high = base.muln(multipliers.high);\n\n return {\n low,\n medium,\n high,\n };\n }\n\n #getMaxFees(\n baseFees: Record<GasFeeEstimateLevel, BN>,\n priorityFees: Record<GasFeeEstimateLevel, BN>,\n ): FeesByLevel {\n return {\n low: baseFees.low.add(priorityFees.low),\n medium: baseFees.medium.add(priorityFees.medium),\n high: baseFees.high.add(priorityFees.high),\n };\n }\n\n #feesToString(fees: FeesByLevel) {\n return Object.values(GasFeeEstimateLevel).map((level) =>\n fees[level].toString(10),\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"LineaGasFeeFlow.mjs","sourceRoot":"","sources":["../../src/gas-flows/LineaGasFeeFlow.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChainId, hexToBN, query, toHex } from '@metamask/controller-utils';\nimport type EthQuery from '@metamask/eth-query';\nimport { createModuleLogger } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\nimport type BN from 'bn.js';\n\nimport { DefaultGasFeeFlow } from './DefaultGasFeeFlow';\nimport { projectLogger } from '../logger';\nimport type { TransactionControllerMessenger } from '../TransactionController';\nimport type {\n GasFeeEstimates,\n GasFeeFlow,\n GasFeeFlowRequest,\n GasFeeFlowResponse,\n TransactionMeta,\n} from '../types';\nimport { GasFeeEstimateLevel, GasFeeEstimateType } from '../types';\n\ntype LineaEstimateGasResponse = {\n baseFeePerGas: Hex;\n priorityFeePerGas: Hex;\n};\n\ntype FeesByLevel = {\n [key in GasFeeEstimateLevel]: BN;\n};\n\nconst log = createModuleLogger(projectLogger, 'linea-gas-fee-flow');\n\nconst LINEA_CHAIN_IDS: Hex[] = [\n ChainId['linea-mainnet'],\n ChainId['linea-goerli'],\n ChainId['linea-sepolia'],\n];\n\nconst BASE_FEE_MULTIPLIERS = {\n low: 1,\n medium: 1.35,\n high: 1.7,\n};\n\nconst PRIORITY_FEE_MULTIPLIERS = {\n low: 1,\n medium: 1.05,\n high: 1.1,\n};\n\n/**\n * Implementation of a gas fee flow specific to Linea networks that obtains gas fee estimates using:\n * - The `linea_estimateGas` RPC method to obtain the base fee and lowest priority fee.\n * - Static multipliers to increase the base and priority fees.\n */\nexport class LineaGasFeeFlow implements GasFeeFlow {\n matchesTransaction({\n transactionMeta,\n }: {\n transactionMeta: TransactionMeta;\n messenger: TransactionControllerMessenger;\n }): boolean {\n return LINEA_CHAIN_IDS.includes(transactionMeta.chainId);\n }\n\n async getGasFees(request: GasFeeFlowRequest): Promise<GasFeeFlowResponse> {\n try {\n return await this.#getLineaGasFees(request);\n } catch (error) {\n log('Using default flow as fallback due to error', error);\n return new DefaultGasFeeFlow().getGasFees(request);\n }\n }\n\n async #getLineaGasFees(\n request: GasFeeFlowRequest,\n ): Promise<GasFeeFlowResponse> {\n const { ethQuery, transactionMeta } = request;\n\n const lineaResponse = await this.#getLineaResponse(\n transactionMeta,\n ethQuery,\n );\n\n log('Received Linea response', lineaResponse);\n\n const baseFees = this.#getValuesFromMultipliers(\n lineaResponse.baseFeePerGas,\n BASE_FEE_MULTIPLIERS,\n );\n\n log('Generated base fees', this.#feesToString(baseFees));\n\n const priorityFees = this.#getValuesFromMultipliers(\n lineaResponse.priorityFeePerGas,\n PRIORITY_FEE_MULTIPLIERS,\n );\n\n log('Generated priority fees', this.#feesToString(priorityFees));\n\n const maxFees = this.#getMaxFees(baseFees, priorityFees);\n\n log('Generated max fees', this.#feesToString(maxFees));\n\n const estimates = Object.values(GasFeeEstimateLevel).reduce(\n (result, level) => ({\n ...result,\n [level]: {\n maxFeePerGas: toHex(maxFees[level]),\n maxPriorityFeePerGas: toHex(priorityFees[level]),\n },\n }),\n { type: GasFeeEstimateType.FeeMarket } as GasFeeEstimates,\n );\n\n return { estimates };\n }\n\n #getLineaResponse(\n transactionMeta: TransactionMeta,\n ethQuery: EthQuery,\n ): Promise<LineaEstimateGasResponse> {\n return query(ethQuery, 'linea_estimateGas', [\n {\n from: transactionMeta.txParams.from,\n to: transactionMeta.txParams.to,\n value: transactionMeta.txParams.value,\n input: transactionMeta.txParams.data,\n },\n ]);\n }\n\n #getValuesFromMultipliers(\n value: Hex,\n multipliers: { low: number; medium: number; high: number },\n ): FeesByLevel {\n const base = hexToBN(value);\n const low = base.muln(multipliers.low);\n const medium = base.muln(multipliers.medium);\n const high = base.muln(multipliers.high);\n\n return {\n low,\n medium,\n high,\n };\n }\n\n #getMaxFees(\n baseFees: Record<GasFeeEstimateLevel, BN>,\n priorityFees: Record<GasFeeEstimateLevel, BN>,\n ): FeesByLevel {\n return {\n low: baseFees.low.add(priorityFees.low),\n medium: baseFees.medium.add(priorityFees.medium),\n high: baseFees.high.add(priorityFees.high),\n };\n }\n\n #feesToString(fees: FeesByLevel): string[] {\n return Object.values(GasFeeEstimateLevel).map((level) =>\n fees[level].toString(10),\n );\n }\n}\n"]}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
4
|
+
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");
|
|
5
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
6
|
+
};
|
|
7
|
+
var _OptimismLayer1GasFeeFlow_instances, _OptimismLayer1GasFeeFlow_fetchOptimismSupportedChains;
|
|
2
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
9
|
exports.OptimismLayer1GasFeeFlow = void 0;
|
|
4
10
|
const controller_utils_1 = require("@metamask/controller-utils");
|
|
@@ -19,30 +25,35 @@ const GAS_SUPPORTED_NETWORKS_ENDPOINT = 'https://gas.api.cx.metamask.io/v1/suppo
|
|
|
19
25
|
* Optimism layer 1 gas fee flow that obtains gas fee estimate using an oracle contract.
|
|
20
26
|
*/
|
|
21
27
|
class OptimismLayer1GasFeeFlow extends OracleLayer1GasFeeFlow_1.OracleLayer1GasFeeFlow {
|
|
28
|
+
constructor() {
|
|
29
|
+
super(...arguments);
|
|
30
|
+
_OptimismLayer1GasFeeFlow_instances.add(this);
|
|
31
|
+
}
|
|
22
32
|
async matchesTransaction({ transactionMeta, }) {
|
|
23
33
|
const chainIdAsNumber = (0, utils_1.hexToNumber)(transactionMeta.chainId);
|
|
24
|
-
const supportedChains = await
|
|
34
|
+
const supportedChains = await __classPrivateFieldGet(this, _OptimismLayer1GasFeeFlow_instances, "m", _OptimismLayer1GasFeeFlow_fetchOptimismSupportedChains).call(this);
|
|
25
35
|
if (supportedChains?.has(chainIdAsNumber)) {
|
|
26
36
|
return true;
|
|
27
37
|
}
|
|
28
38
|
return FALLBACK_OPTIMISM_STACK_CHAIN_IDS.includes(transactionMeta.chainId);
|
|
29
39
|
}
|
|
30
|
-
// Uses default oracle address from base class
|
|
31
|
-
/**
|
|
32
|
-
* Fetch remote OP-stack support list; fall back to local list when unavailable.
|
|
33
|
-
*
|
|
34
|
-
* @returns A set of supported OP-stack chain IDs or null on failure.
|
|
35
|
-
*/
|
|
36
|
-
static async fetchOptimismSupportedChains() {
|
|
37
|
-
try {
|
|
38
|
-
const res = await (0, controller_utils_1.handleFetch)(GAS_SUPPORTED_NETWORKS_ENDPOINT);
|
|
39
|
-
const list = res?.partialSupport?.optimism ?? [];
|
|
40
|
-
return new Set(list);
|
|
41
|
-
}
|
|
42
|
-
catch {
|
|
43
|
-
return null;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
40
|
}
|
|
47
41
|
exports.OptimismLayer1GasFeeFlow = OptimismLayer1GasFeeFlow;
|
|
42
|
+
_OptimismLayer1GasFeeFlow_instances = new WeakSet(), _OptimismLayer1GasFeeFlow_fetchOptimismSupportedChains =
|
|
43
|
+
// Uses default oracle address from base class
|
|
44
|
+
/**
|
|
45
|
+
* Fetch remote OP-stack support list; fall back to local list when unavailable.
|
|
46
|
+
*
|
|
47
|
+
* @returns A set of supported OP-stack chain IDs or null on failure.
|
|
48
|
+
*/
|
|
49
|
+
async function _OptimismLayer1GasFeeFlow_fetchOptimismSupportedChains() {
|
|
50
|
+
try {
|
|
51
|
+
const res = await (0, controller_utils_1.handleFetch)(GAS_SUPPORTED_NETWORKS_ENDPOINT);
|
|
52
|
+
const list = res?.partialSupport?.optimism ?? [];
|
|
53
|
+
return new Set(list);
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
48
59
|
//# sourceMappingURL=OptimismLayer1GasFeeFlow.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OptimismLayer1GasFeeFlow.cjs","sourceRoot":"","sources":["../../src/gas-flows/OptimismLayer1GasFeeFlow.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"OptimismLayer1GasFeeFlow.cjs","sourceRoot":"","sources":["../../src/gas-flows/OptimismLayer1GasFeeFlow.ts"],"names":[],"mappings":";;;;;;;;;AAAA,iEAAyD;AACzD,2CAA8C;AAG9C,yEAAkE;AAClE,gDAAyC;AAIzC,MAAM,iCAAiC,GAAU;IAC/C,qBAAS,CAAC,QAAQ;IAClB,qBAAS,CAAC,gBAAgB;IAC1B,qBAAS,CAAC,IAAI;IACd,qBAAS,CAAC,YAAY;IACtB,qBAAS,CAAC,KAAK;IACf,qBAAS,CAAC,aAAa;IACvB,qBAAS,CAAC,IAAI;CACf,CAAC;AAWF,MAAM,+BAA+B,GACnC,qDAAqD,CAAC;AAExD;;GAEG;AACH,MAAa,wBAAyB,SAAQ,+CAAsB;IAApE;;;IAoCA,CAAC;IAnCC,KAAK,CAAC,kBAAkB,CAAC,EACvB,eAAe,GAIhB;QACC,MAAM,eAAe,GAAG,IAAA,mBAAW,EAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QAE7D,MAAM,eAAe,GAAG,MAAM,uBAAA,IAAI,mGAA8B,MAAlC,IAAI,CAAgC,CAAC;QAEnE,IAAI,eAAe,EAAE,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC;YAC1C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,iCAAiC,CAAC,QAAQ,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IAC7E,CAAC;CAoBF;AApCD,4DAoCC;;AAlBC,8CAA8C;AAE9C;;;;GAIG;AACH,KAAK;IACH,IAAI,CAAC;QACH,MAAM,GAAG,GAA8B,MAAM,IAAA,8BAAW,EACtD,+BAA+B,CAChC,CAAC;QACF,MAAM,IAAI,GAAG,GAAG,EAAE,cAAc,EAAE,QAAQ,IAAI,EAAE,CAAC;QACjD,OAAO,IAAI,GAAG,CAAS,IAAI,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC","sourcesContent":["import { handleFetch } from '@metamask/controller-utils';\nimport { hexToNumber } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\n\nimport { OracleLayer1GasFeeFlow } from './OracleLayer1GasFeeFlow';\nimport { CHAIN_IDS } from '../constants';\nimport type { TransactionControllerMessenger } from '../TransactionController';\nimport type { TransactionMeta } from '../types';\n\nconst FALLBACK_OPTIMISM_STACK_CHAIN_IDS: Hex[] = [\n CHAIN_IDS.OPTIMISM,\n CHAIN_IDS.OPTIMISM_TESTNET,\n CHAIN_IDS.BASE,\n CHAIN_IDS.BASE_TESTNET,\n CHAIN_IDS.OPBNB,\n CHAIN_IDS.OPBNB_TESTNET,\n CHAIN_IDS.ZORA,\n];\n\n// Default oracle address now provided by base class\n\ntype SupportedNetworksResponse = {\n readonly fullSupport: readonly number[];\n readonly partialSupport: {\n readonly optimism: readonly number[];\n };\n};\n\nconst GAS_SUPPORTED_NETWORKS_ENDPOINT =\n 'https://gas.api.cx.metamask.io/v1/supportedNetworks';\n\n/**\n * Optimism layer 1 gas fee flow that obtains gas fee estimate using an oracle contract.\n */\nexport class OptimismLayer1GasFeeFlow extends OracleLayer1GasFeeFlow {\n async matchesTransaction({\n transactionMeta,\n }: {\n transactionMeta: TransactionMeta;\n messenger: TransactionControllerMessenger;\n }): Promise<boolean> {\n const chainIdAsNumber = hexToNumber(transactionMeta.chainId);\n\n const supportedChains = await this.#fetchOptimismSupportedChains();\n\n if (supportedChains?.has(chainIdAsNumber)) {\n return true;\n }\n\n return FALLBACK_OPTIMISM_STACK_CHAIN_IDS.includes(transactionMeta.chainId);\n }\n\n // Uses default oracle address from base class\n\n /**\n * Fetch remote OP-stack support list; fall back to local list when unavailable.\n *\n * @returns A set of supported OP-stack chain IDs or null on failure.\n */\n async #fetchOptimismSupportedChains(): Promise<Set<number> | null> {\n try {\n const res: SupportedNetworksResponse = await handleFetch(\n GAS_SUPPORTED_NETWORKS_ENDPOINT,\n );\n const list = res?.partialSupport?.optimism ?? [];\n return new Set<number>(list);\n } catch {\n return null;\n }\n }\n}\n"]}
|
|
@@ -5,15 +5,10 @@ import type { TransactionMeta } from "../types.cjs";
|
|
|
5
5
|
* Optimism layer 1 gas fee flow that obtains gas fee estimate using an oracle contract.
|
|
6
6
|
*/
|
|
7
7
|
export declare class OptimismLayer1GasFeeFlow extends OracleLayer1GasFeeFlow {
|
|
8
|
+
#private;
|
|
8
9
|
matchesTransaction({ transactionMeta, }: {
|
|
9
10
|
transactionMeta: TransactionMeta;
|
|
10
11
|
messenger: TransactionControllerMessenger;
|
|
11
12
|
}): Promise<boolean>;
|
|
12
|
-
/**
|
|
13
|
-
* Fetch remote OP-stack support list; fall back to local list when unavailable.
|
|
14
|
-
*
|
|
15
|
-
* @returns A set of supported OP-stack chain IDs or null on failure.
|
|
16
|
-
*/
|
|
17
|
-
private static fetchOptimismSupportedChains;
|
|
18
13
|
}
|
|
19
14
|
//# sourceMappingURL=OptimismLayer1GasFeeFlow.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OptimismLayer1GasFeeFlow.d.cts","sourceRoot":"","sources":["../../src/gas-flows/OptimismLayer1GasFeeFlow.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,sBAAsB,EAAE,qCAAiC;AAElE,OAAO,KAAK,EAAE,8BAA8B,EAAE,qCAAiC;AAC/E,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAiB;AAwBhD;;GAEG;AACH,qBAAa,wBAAyB,SAAQ,sBAAsB
|
|
1
|
+
{"version":3,"file":"OptimismLayer1GasFeeFlow.d.cts","sourceRoot":"","sources":["../../src/gas-flows/OptimismLayer1GasFeeFlow.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,sBAAsB,EAAE,qCAAiC;AAElE,OAAO,KAAK,EAAE,8BAA8B,EAAE,qCAAiC;AAC/E,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAiB;AAwBhD;;GAEG;AACH,qBAAa,wBAAyB,SAAQ,sBAAsB;;IAC5D,kBAAkB,CAAC,EACvB,eAAe,GAChB,EAAE;QACD,eAAe,EAAE,eAAe,CAAC;QACjC,SAAS,EAAE,8BAA8B,CAAC;KAC3C,GAAG,OAAO,CAAC,OAAO,CAAC;CA8BrB"}
|
|
@@ -5,15 +5,10 @@ import type { TransactionMeta } from "../types.mjs";
|
|
|
5
5
|
* Optimism layer 1 gas fee flow that obtains gas fee estimate using an oracle contract.
|
|
6
6
|
*/
|
|
7
7
|
export declare class OptimismLayer1GasFeeFlow extends OracleLayer1GasFeeFlow {
|
|
8
|
+
#private;
|
|
8
9
|
matchesTransaction({ transactionMeta, }: {
|
|
9
10
|
transactionMeta: TransactionMeta;
|
|
10
11
|
messenger: TransactionControllerMessenger;
|
|
11
12
|
}): Promise<boolean>;
|
|
12
|
-
/**
|
|
13
|
-
* Fetch remote OP-stack support list; fall back to local list when unavailable.
|
|
14
|
-
*
|
|
15
|
-
* @returns A set of supported OP-stack chain IDs or null on failure.
|
|
16
|
-
*/
|
|
17
|
-
private static fetchOptimismSupportedChains;
|
|
18
13
|
}
|
|
19
14
|
//# sourceMappingURL=OptimismLayer1GasFeeFlow.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OptimismLayer1GasFeeFlow.d.mts","sourceRoot":"","sources":["../../src/gas-flows/OptimismLayer1GasFeeFlow.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,sBAAsB,EAAE,qCAAiC;AAElE,OAAO,KAAK,EAAE,8BAA8B,EAAE,qCAAiC;AAC/E,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAiB;AAwBhD;;GAEG;AACH,qBAAa,wBAAyB,SAAQ,sBAAsB
|
|
1
|
+
{"version":3,"file":"OptimismLayer1GasFeeFlow.d.mts","sourceRoot":"","sources":["../../src/gas-flows/OptimismLayer1GasFeeFlow.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,sBAAsB,EAAE,qCAAiC;AAElE,OAAO,KAAK,EAAE,8BAA8B,EAAE,qCAAiC;AAC/E,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAiB;AAwBhD;;GAEG;AACH,qBAAa,wBAAyB,SAAQ,sBAAsB;;IAC5D,kBAAkB,CAAC,EACvB,eAAe,GAChB,EAAE;QACD,eAAe,EAAE,eAAe,CAAC;QACjC,SAAS,EAAE,8BAA8B,CAAC;KAC3C,GAAG,OAAO,CAAC,OAAO,CAAC;CA8BrB"}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
2
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
3
|
+
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");
|
|
4
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
|
+
};
|
|
6
|
+
var _OptimismLayer1GasFeeFlow_instances, _OptimismLayer1GasFeeFlow_fetchOptimismSupportedChains;
|
|
1
7
|
import { handleFetch } from "@metamask/controller-utils";
|
|
2
8
|
import { hexToNumber } from "@metamask/utils";
|
|
3
9
|
import { OracleLayer1GasFeeFlow } from "./OracleLayer1GasFeeFlow.mjs";
|
|
@@ -16,29 +22,34 @@ const GAS_SUPPORTED_NETWORKS_ENDPOINT = 'https://gas.api.cx.metamask.io/v1/suppo
|
|
|
16
22
|
* Optimism layer 1 gas fee flow that obtains gas fee estimate using an oracle contract.
|
|
17
23
|
*/
|
|
18
24
|
export class OptimismLayer1GasFeeFlow extends OracleLayer1GasFeeFlow {
|
|
25
|
+
constructor() {
|
|
26
|
+
super(...arguments);
|
|
27
|
+
_OptimismLayer1GasFeeFlow_instances.add(this);
|
|
28
|
+
}
|
|
19
29
|
async matchesTransaction({ transactionMeta, }) {
|
|
20
30
|
const chainIdAsNumber = hexToNumber(transactionMeta.chainId);
|
|
21
|
-
const supportedChains = await
|
|
31
|
+
const supportedChains = await __classPrivateFieldGet(this, _OptimismLayer1GasFeeFlow_instances, "m", _OptimismLayer1GasFeeFlow_fetchOptimismSupportedChains).call(this);
|
|
22
32
|
if (supportedChains?.has(chainIdAsNumber)) {
|
|
23
33
|
return true;
|
|
24
34
|
}
|
|
25
35
|
return FALLBACK_OPTIMISM_STACK_CHAIN_IDS.includes(transactionMeta.chainId);
|
|
26
36
|
}
|
|
27
|
-
// Uses default oracle address from base class
|
|
28
|
-
/**
|
|
29
|
-
* Fetch remote OP-stack support list; fall back to local list when unavailable.
|
|
30
|
-
*
|
|
31
|
-
* @returns A set of supported OP-stack chain IDs or null on failure.
|
|
32
|
-
*/
|
|
33
|
-
static async fetchOptimismSupportedChains() {
|
|
34
|
-
try {
|
|
35
|
-
const res = await handleFetch(GAS_SUPPORTED_NETWORKS_ENDPOINT);
|
|
36
|
-
const list = res?.partialSupport?.optimism ?? [];
|
|
37
|
-
return new Set(list);
|
|
38
|
-
}
|
|
39
|
-
catch {
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
37
|
}
|
|
38
|
+
_OptimismLayer1GasFeeFlow_instances = new WeakSet(), _OptimismLayer1GasFeeFlow_fetchOptimismSupportedChains =
|
|
39
|
+
// Uses default oracle address from base class
|
|
40
|
+
/**
|
|
41
|
+
* Fetch remote OP-stack support list; fall back to local list when unavailable.
|
|
42
|
+
*
|
|
43
|
+
* @returns A set of supported OP-stack chain IDs or null on failure.
|
|
44
|
+
*/
|
|
45
|
+
async function _OptimismLayer1GasFeeFlow_fetchOptimismSupportedChains() {
|
|
46
|
+
try {
|
|
47
|
+
const res = await handleFetch(GAS_SUPPORTED_NETWORKS_ENDPOINT);
|
|
48
|
+
const list = res?.partialSupport?.optimism ?? [];
|
|
49
|
+
return new Set(list);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
44
55
|
//# sourceMappingURL=OptimismLayer1GasFeeFlow.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OptimismLayer1GasFeeFlow.mjs","sourceRoot":"","sources":["../../src/gas-flows/OptimismLayer1GasFeeFlow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,mCAAmC;AACzD,OAAO,EAAE,WAAW,EAAE,wBAAwB;AAG9C,OAAO,EAAE,sBAAsB,EAAE,qCAAiC;AAClE,OAAO,EAAE,SAAS,EAAE,yBAAqB;AAIzC,MAAM,iCAAiC,GAAU;IAC/C,SAAS,CAAC,QAAQ;IAClB,SAAS,CAAC,gBAAgB;IAC1B,SAAS,CAAC,IAAI;IACd,SAAS,CAAC,YAAY;IACtB,SAAS,CAAC,KAAK;IACf,SAAS,CAAC,aAAa;IACvB,SAAS,CAAC,IAAI;CACf,CAAC;AAWF,MAAM,+BAA+B,GACnC,qDAAqD,CAAC;AAExD;;GAEG;AACH,MAAM,OAAO,wBAAyB,SAAQ,sBAAsB;
|
|
1
|
+
{"version":3,"file":"OptimismLayer1GasFeeFlow.mjs","sourceRoot":"","sources":["../../src/gas-flows/OptimismLayer1GasFeeFlow.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,WAAW,EAAE,mCAAmC;AACzD,OAAO,EAAE,WAAW,EAAE,wBAAwB;AAG9C,OAAO,EAAE,sBAAsB,EAAE,qCAAiC;AAClE,OAAO,EAAE,SAAS,EAAE,yBAAqB;AAIzC,MAAM,iCAAiC,GAAU;IAC/C,SAAS,CAAC,QAAQ;IAClB,SAAS,CAAC,gBAAgB;IAC1B,SAAS,CAAC,IAAI;IACd,SAAS,CAAC,YAAY;IACtB,SAAS,CAAC,KAAK;IACf,SAAS,CAAC,aAAa;IACvB,SAAS,CAAC,IAAI;CACf,CAAC;AAWF,MAAM,+BAA+B,GACnC,qDAAqD,CAAC;AAExD;;GAEG;AACH,MAAM,OAAO,wBAAyB,SAAQ,sBAAsB;IAApE;;;IAoCA,CAAC;IAnCC,KAAK,CAAC,kBAAkB,CAAC,EACvB,eAAe,GAIhB;QACC,MAAM,eAAe,GAAG,WAAW,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QAE7D,MAAM,eAAe,GAAG,MAAM,uBAAA,IAAI,mGAA8B,MAAlC,IAAI,CAAgC,CAAC;QAEnE,IAAI,eAAe,EAAE,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC;YAC1C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,iCAAiC,CAAC,QAAQ,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IAC7E,CAAC;CAoBF;;AAlBC,8CAA8C;AAE9C;;;;GAIG;AACH,KAAK;IACH,IAAI,CAAC;QACH,MAAM,GAAG,GAA8B,MAAM,WAAW,CACtD,+BAA+B,CAChC,CAAC;QACF,MAAM,IAAI,GAAG,GAAG,EAAE,cAAc,EAAE,QAAQ,IAAI,EAAE,CAAC;QACjD,OAAO,IAAI,GAAG,CAAS,IAAI,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC","sourcesContent":["import { handleFetch } from '@metamask/controller-utils';\nimport { hexToNumber } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\n\nimport { OracleLayer1GasFeeFlow } from './OracleLayer1GasFeeFlow';\nimport { CHAIN_IDS } from '../constants';\nimport type { TransactionControllerMessenger } from '../TransactionController';\nimport type { TransactionMeta } from '../types';\n\nconst FALLBACK_OPTIMISM_STACK_CHAIN_IDS: Hex[] = [\n CHAIN_IDS.OPTIMISM,\n CHAIN_IDS.OPTIMISM_TESTNET,\n CHAIN_IDS.BASE,\n CHAIN_IDS.BASE_TESTNET,\n CHAIN_IDS.OPBNB,\n CHAIN_IDS.OPBNB_TESTNET,\n CHAIN_IDS.ZORA,\n];\n\n// Default oracle address now provided by base class\n\ntype SupportedNetworksResponse = {\n readonly fullSupport: readonly number[];\n readonly partialSupport: {\n readonly optimism: readonly number[];\n };\n};\n\nconst GAS_SUPPORTED_NETWORKS_ENDPOINT =\n 'https://gas.api.cx.metamask.io/v1/supportedNetworks';\n\n/**\n * Optimism layer 1 gas fee flow that obtains gas fee estimate using an oracle contract.\n */\nexport class OptimismLayer1GasFeeFlow extends OracleLayer1GasFeeFlow {\n async matchesTransaction({\n transactionMeta,\n }: {\n transactionMeta: TransactionMeta;\n messenger: TransactionControllerMessenger;\n }): Promise<boolean> {\n const chainIdAsNumber = hexToNumber(transactionMeta.chainId);\n\n const supportedChains = await this.#fetchOptimismSupportedChains();\n\n if (supportedChains?.has(chainIdAsNumber)) {\n return true;\n }\n\n return FALLBACK_OPTIMISM_STACK_CHAIN_IDS.includes(transactionMeta.chainId);\n }\n\n // Uses default oracle address from base class\n\n /**\n * Fetch remote OP-stack support list; fall back to local list when unavailable.\n *\n * @returns A set of supported OP-stack chain IDs or null on failure.\n */\n async #fetchOptimismSupportedChains(): Promise<Set<number> | null> {\n try {\n const res: SupportedNetworksResponse = await handleFetch(\n GAS_SUPPORTED_NETWORKS_ENDPOINT,\n );\n const list = res?.partialSupport?.optimism ?? [];\n return new Set<number>(list);\n } catch {\n return null;\n }\n }\n}\n"]}
|
|
@@ -138,6 +138,7 @@ _OracleLayer1GasFeeFlow_instances = new WeakSet(), _OracleLayer1GasFeeFlow_getOr
|
|
|
138
138
|
const { chainId } = transactionMeta;
|
|
139
139
|
let unserializedTransaction = (0, prepare_1.prepareTransaction)(chainId, txParams);
|
|
140
140
|
if (sign) {
|
|
141
|
+
// eslint-disable-next-line no-restricted-globals
|
|
141
142
|
const keyBuffer = Buffer.from(DUMMY_KEY, 'hex');
|
|
142
143
|
const keyBytes = Uint8Array.from(keyBuffer);
|
|
143
144
|
unserializedTransaction = unserializedTransaction.sign(keyBytes);
|