@metamask/transaction-controller 35.0.0 → 35.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -1
- package/dist/TransactionController.js +3 -3
- package/dist/TransactionController.mjs +2 -2
- package/dist/{chunk-EVL6KODQ.mjs → chunk-3AVRGHUO.mjs} +17 -9
- package/dist/chunk-3AVRGHUO.mjs.map +1 -0
- package/dist/{chunk-UKV5HIMT.mjs → chunk-J2OIT7FN.mjs} +2 -2
- package/dist/{chunk-74W7X6BE.js → chunk-NNCUD3QF.js} +17 -9
- package/dist/chunk-NNCUD3QF.js.map +1 -0
- package/dist/{chunk-S7Q622IS.js → chunk-PHSSZPCU.js} +3 -3
- package/dist/index.js +3 -3
- package/dist/index.mjs +2 -2
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/types/utils/simulation.d.ts.map +1 -1
- package/dist/utils/simulation.js +2 -2
- package/dist/utils/simulation.mjs +1 -1
- package/package.json +17 -17
- package/dist/chunk-74W7X6BE.js.map +0 -1
- package/dist/chunk-EVL6KODQ.mjs.map +0 -1
- /package/dist/{chunk-UKV5HIMT.mjs.map → chunk-J2OIT7FN.mjs.map} +0 -0
- /package/dist/{chunk-S7Q622IS.js.map → chunk-PHSSZPCU.js.map} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [35.0.1]
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- **BREAKING:** Bump peerDependency `@metamask/accounts-controller` from `^17.0.0` to `^18.0.0` ([#4548](https://github.com/MetaMask/core/pull/4548))
|
|
15
|
+
- Remove `@metamask/accounts-controller`, `@metamask/approval-controller`, `@metamask/gas-fee-controller`, and `@metamask/network-controller` dependencies [#4556](https://github.com/MetaMask/core/pull/4556)
|
|
16
|
+
- These were listed under `peerDependencies` already, so they were redundant as dependencies.
|
|
17
|
+
- Upgrade TypeScript version to `~5.0.4` and set `moduleResolution` option to `Node16` ([#3645](https://github.com/MetaMask/core/pull/3645))
|
|
18
|
+
- Bump `@metamask/base-controller` from `^6.0.0` to `^6.0.2` ([#4517](https://github.com/MetaMask/core/pull/4517), [#4544](https://github.com/MetaMask/core/pull/4544))
|
|
19
|
+
- Bump `@metamask/controller-utils` from `^11.0.0` to `^11.0.2` ([#4517](https://github.com/MetaMask/core/pull/4517), [#4544](https://github.com/MetaMask/core/pull/4544))
|
|
20
|
+
- Bump `@metamask/rpc-errors` from `^6.2.1` to `^6.3.1` ([#4516](https://github.com/MetaMask/core/pull/4516))
|
|
21
|
+
- Bump `@metamask/utils` from `^8.3.0` to `^9.1.0` ([#4516](https://github.com/MetaMask/core/pull/4516), [#4529](https://github.com/MetaMask/core/pull/4529))
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- Fix simulation data parsing logic to avoid failed simulations creating `ApprovalForAll` events ([#4512](https://github.com/MetaMask/core/pull/4512))
|
|
26
|
+
|
|
10
27
|
## [35.0.0]
|
|
11
28
|
|
|
12
29
|
### Changed
|
|
@@ -917,7 +934,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
917
934
|
|
|
918
935
|
All changes listed after this point were applied to this package following the monorepo conversion.
|
|
919
936
|
|
|
920
|
-
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@35.0.
|
|
937
|
+
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@35.0.1...HEAD
|
|
938
|
+
[35.0.1]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@35.0.0...@metamask/transaction-controller@35.0.1
|
|
921
939
|
[35.0.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@34.0.0...@metamask/transaction-controller@35.0.0
|
|
922
940
|
[34.0.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@33.0.1...@metamask/transaction-controller@34.0.0
|
|
923
941
|
[33.0.1]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@33.0.0...@metamask/transaction-controller@33.0.1
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
var
|
|
7
|
+
var _chunkPHSSZPCUjs = require('./chunk-PHSSZPCU.js');
|
|
8
8
|
require('./chunk-PRUNMTRD.js');
|
|
9
|
-
require('./chunk-
|
|
9
|
+
require('./chunk-NNCUD3QF.js');
|
|
10
10
|
require('./chunk-KT6UAKBB.js');
|
|
11
11
|
require('./chunk-SD6CWFDF.js');
|
|
12
12
|
require('./chunk-RXIUMVA5.js');
|
|
@@ -41,5 +41,5 @@ require('./chunk-Z4BLTVTB.js');
|
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
|
|
44
|
-
exports.ApprovalState =
|
|
44
|
+
exports.ApprovalState = _chunkPHSSZPCUjs.ApprovalState; exports.CANCEL_RATE = _chunkPHSSZPCUjs.CANCEL_RATE; exports.HARDFORK = _chunkPHSSZPCUjs.HARDFORK; exports.SPEED_UP_RATE = _chunkPHSSZPCUjs.SPEED_UP_RATE; exports.TransactionController = _chunkPHSSZPCUjs.TransactionController;
|
|
45
45
|
//# sourceMappingURL=TransactionController.js.map
|
|
@@ -4,9 +4,9 @@ import {
|
|
|
4
4
|
HARDFORK,
|
|
5
5
|
SPEED_UP_RATE,
|
|
6
6
|
TransactionController
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-J2OIT7FN.mjs";
|
|
8
8
|
import "./chunk-6DDVVUJC.mjs";
|
|
9
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-3AVRGHUO.mjs";
|
|
10
10
|
import "./chunk-K4KOSAGM.mjs";
|
|
11
11
|
import "./chunk-KG4UW4K4.mjs";
|
|
12
12
|
import "./chunk-5ZEJT5SN.mjs";
|
|
@@ -136,7 +136,12 @@ function getEvents(response) {
|
|
|
136
136
|
log("Failed to find inputs for event", event);
|
|
137
137
|
return void 0;
|
|
138
138
|
}
|
|
139
|
-
|
|
139
|
+
if (!SUPPORTED_EVENTS.includes(event.name)) {
|
|
140
|
+
log("Ignoring unsupported event", event.name, event);
|
|
141
|
+
return void 0;
|
|
142
|
+
}
|
|
143
|
+
log("Normalizing event args", event.name, event);
|
|
144
|
+
const args = normalizeEventArgs(event.args, inputs);
|
|
140
145
|
return {
|
|
141
146
|
contractAddress: currentLog.address,
|
|
142
147
|
tokenStandard: event.standard,
|
|
@@ -146,19 +151,22 @@ function getEvents(response) {
|
|
|
146
151
|
};
|
|
147
152
|
}).filter((e) => e !== void 0);
|
|
148
153
|
}
|
|
149
|
-
function
|
|
154
|
+
function normalizeEventArgs(args, abiInputs) {
|
|
150
155
|
return args.reduce((result, arg, index) => {
|
|
151
156
|
const name = abiInputs[index].name.replace("_", "");
|
|
152
|
-
const value =
|
|
157
|
+
const value = normalizeEventArgValue(arg);
|
|
153
158
|
result[name] = value;
|
|
154
159
|
return result;
|
|
155
160
|
}, {});
|
|
156
161
|
}
|
|
157
|
-
function
|
|
162
|
+
function normalizeEventArgValue(value) {
|
|
158
163
|
if (Array.isArray(value)) {
|
|
159
|
-
return value.map(
|
|
164
|
+
return value.map(normalizeEventArgValue);
|
|
160
165
|
}
|
|
161
|
-
|
|
166
|
+
let normalizedValue = value;
|
|
167
|
+
normalizedValue = normalizedValue.toHexString?.() ?? normalizedValue;
|
|
168
|
+
normalizedValue = normalizedValue.toLowerCase?.() ?? normalizedValue;
|
|
169
|
+
return normalizedValue;
|
|
162
170
|
}
|
|
163
171
|
async function getTokenBalanceChanges(request, events) {
|
|
164
172
|
const balanceTxs = getTokenBalanceTransactions(request, events);
|
|
@@ -210,12 +218,12 @@ function getTokenBalanceTransactions(request, events) {
|
|
|
210
218
|
const before = /* @__PURE__ */ new Map();
|
|
211
219
|
const after = /* @__PURE__ */ new Map();
|
|
212
220
|
const userEvents = events.filter(
|
|
213
|
-
(event) =>
|
|
221
|
+
(event) => [event.args.from, event.args.to].includes(request.from)
|
|
214
222
|
);
|
|
215
223
|
log("Filtered user events", userEvents);
|
|
216
224
|
for (const event of userEvents) {
|
|
217
225
|
const tokenIds = getEventTokenIds(event);
|
|
218
|
-
log("Extracted token
|
|
226
|
+
log("Extracted token IDs", tokenIds);
|
|
219
227
|
for (const tokenId of tokenIds) {
|
|
220
228
|
const simulationToken = {
|
|
221
229
|
address: event.contractAddress,
|
|
@@ -349,4 +357,4 @@ export {
|
|
|
349
357
|
getSimulationData,
|
|
350
358
|
getEvents
|
|
351
359
|
};
|
|
352
|
-
//# sourceMappingURL=chunk-
|
|
360
|
+
//# sourceMappingURL=chunk-3AVRGHUO.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/simulation.ts"],"sourcesContent":["import type { Fragment, LogDescription, Result } from '@ethersproject/abi';\nimport { Interface } from '@ethersproject/abi';\nimport { hexToBN, toHex } from '@metamask/controller-utils';\nimport { abiERC20, abiERC721, abiERC1155 } from '@metamask/metamask-eth-abis';\nimport { createModuleLogger, type Hex } from '@metamask/utils';\n\nimport {\n ABI_SIMULATION_ERC20_WRAPPED,\n ABI_SIMULATION_ERC721_LEGACY,\n} from '../constants';\nimport {\n SimulationError,\n SimulationInvalidResponseError,\n SimulationRevertedError,\n} from '../errors';\nimport { projectLogger } from '../logger';\nimport type {\n SimulationBalanceChange,\n SimulationData,\n SimulationTokenBalanceChange,\n SimulationToken,\n} from '../types';\nimport { SimulationTokenStandard } from '../types';\nimport { simulateTransactions } from './simulation-api';\nimport type {\n SimulationResponseLog,\n SimulationRequestTransaction,\n SimulationResponse,\n SimulationResponseCallTrace,\n SimulationResponseTransaction,\n} from './simulation-api';\n\nexport enum SupportedToken {\n ERC20 = 'erc20',\n ERC721 = 'erc721',\n ERC1155 = 'erc1155',\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ERC20_WRAPPED = 'erc20Wrapped',\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ERC721_LEGACY = 'erc721Legacy',\n}\n\ntype ABI = Fragment[];\n\nexport type GetSimulationDataRequest = {\n chainId: Hex;\n from: Hex;\n to?: Hex;\n value?: Hex;\n data?: Hex;\n};\n\ntype ParsedEvent = {\n contractAddress: Hex;\n tokenStandard: SimulationTokenStandard;\n name: string;\n args: Record<string, Hex | Hex[]>;\n abi: ABI;\n};\n\nconst log = createModuleLogger(projectLogger, 'simulation');\n\nconst SUPPORTED_EVENTS = [\n 'Transfer',\n 'TransferSingle',\n 'TransferBatch',\n 'Deposit',\n 'Withdrawal',\n];\n\nconst SUPPORTED_TOKEN_ABIS = {\n [SupportedToken.ERC20]: {\n abi: abiERC20,\n standard: SimulationTokenStandard.erc20,\n },\n [SupportedToken.ERC721]: {\n abi: abiERC721,\n standard: SimulationTokenStandard.erc721,\n },\n [SupportedToken.ERC1155]: {\n abi: abiERC1155,\n standard: SimulationTokenStandard.erc1155,\n },\n [SupportedToken.ERC20_WRAPPED]: {\n abi: ABI_SIMULATION_ERC20_WRAPPED,\n standard: SimulationTokenStandard.erc20,\n },\n [SupportedToken.ERC721_LEGACY]: {\n abi: ABI_SIMULATION_ERC721_LEGACY,\n standard: SimulationTokenStandard.erc721,\n },\n};\n\nconst REVERTED_ERRORS = ['execution reverted', 'insufficient funds for gas'];\n\ntype BalanceTransactionMap = Map<SimulationToken, SimulationRequestTransaction>;\n\n/**\n * Generate simulation data for a transaction.\n * @param request - The transaction to simulate.\n * @param request.chainId - The chain ID of the transaction.\n * @param request.from - The sender of the transaction.\n * @param request.to - The recipient of the transaction.\n * @param request.value - The value of the transaction.\n * @param request.data - The data of the transaction.\n * @returns The simulation data.\n */\nexport async function getSimulationData(\n request: GetSimulationDataRequest,\n): Promise<SimulationData> {\n const { chainId, from, to, value, data } = request;\n\n log('Getting simulation data', request);\n\n try {\n const response = await simulateTransactions(chainId, {\n transactions: [\n {\n data,\n from,\n maxFeePerGas: '0x0',\n maxPriorityFeePerGas: '0x0',\n to,\n value,\n },\n ],\n withCallTrace: true,\n withLogs: true,\n });\n\n const transactionError = response.transactions?.[0]?.error;\n\n if (transactionError) {\n throw new SimulationError(transactionError);\n }\n\n const nativeBalanceChange = getNativeBalanceChange(request.from, response);\n const events = getEvents(response);\n\n log('Parsed events', events);\n\n const tokenBalanceChanges = await getTokenBalanceChanges(request, events);\n\n return {\n nativeBalanceChange,\n tokenBalanceChanges,\n };\n } catch (error) {\n log('Failed to get simulation data', error, request);\n\n let simulationError = error as SimulationError;\n\n if (\n REVERTED_ERRORS.some((revertErrorMessage) =>\n simulationError.message?.includes(revertErrorMessage),\n )\n ) {\n simulationError = new SimulationRevertedError();\n }\n\n const { code, message } = simulationError;\n\n return {\n tokenBalanceChanges: [],\n error: {\n code,\n message,\n },\n };\n }\n}\n\n/**\n * Extract the native balance change from a simulation response.\n * @param userAddress - The user's account address.\n * @param response - The simulation response.\n * @returns The native balance change or undefined if unchanged.\n */\nfunction getNativeBalanceChange(\n userAddress: Hex,\n response: SimulationResponse,\n): SimulationBalanceChange | undefined {\n const transactionResponse = response.transactions[0];\n\n /* istanbul ignore next */\n if (!transactionResponse) {\n return undefined;\n }\n\n const { stateDiff } = transactionResponse;\n const previousBalance = stateDiff?.pre?.[userAddress]?.balance;\n const newBalance = stateDiff?.post?.[userAddress]?.balance;\n\n if (!previousBalance || !newBalance) {\n return undefined;\n }\n\n return getSimulationBalanceChange(previousBalance, newBalance);\n}\n\n/**\n * Extract events from a simulation response.\n * @param response - The simulation response.\n * @returns The parsed events.\n */\nexport function getEvents(response: SimulationResponse): ParsedEvent[] {\n /* istanbul ignore next */\n const logs = extractLogs(\n response.transactions[0]?.callTrace ?? ({} as SimulationResponseCallTrace),\n );\n\n log('Extracted logs', logs);\n\n const interfaces = getContractInterfaces();\n\n return logs\n .map((currentLog) => {\n const event = parseLog(currentLog, interfaces);\n\n if (!event) {\n log('Failed to parse log', currentLog);\n return undefined;\n }\n\n /* istanbul ignore next */\n const inputs = event.abi.find((e) => e.name === event.name)?.inputs;\n\n /* istanbul ignore if */\n if (!inputs) {\n log('Failed to find inputs for event', event);\n return undefined;\n }\n\n if (!SUPPORTED_EVENTS.includes(event.name)) {\n log('Ignoring unsupported event', event.name, event);\n return undefined;\n }\n\n log('Normalizing event args', event.name, event);\n\n const args = normalizeEventArgs(event.args, inputs);\n\n return {\n contractAddress: currentLog.address,\n tokenStandard: event.standard,\n name: event.name,\n args,\n abi: event.abi,\n };\n })\n .filter((e) => e !== undefined) as ParsedEvent[];\n}\n\n/**\n * Normalize event arguments using ABI input definitions.\n * @param args - The raw event arguments.\n * @param abiInputs - The ABI input definitions.\n * @returns The normalized event arguments.\n */\nfunction normalizeEventArgs(\n args: Result,\n abiInputs: { name: string }[],\n): Record<string, Hex | Hex[]> {\n return args.reduce((result, arg, index) => {\n const name = abiInputs[index].name.replace('_', '');\n const value = normalizeEventArgValue(arg);\n\n result[name] = value;\n\n return result;\n }, {});\n}\n\n/**\n * Normalize an event argument value.\n * @param value - The event argument value.\n * @returns The normalized event argument value.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction normalizeEventArgValue(value: any): any {\n if (Array.isArray(value)) {\n return value.map(normalizeEventArgValue);\n }\n\n let normalizedValue = value;\n\n normalizedValue = normalizedValue.toHexString?.() ?? normalizedValue;\n normalizedValue = normalizedValue.toLowerCase?.() ?? normalizedValue;\n\n return normalizedValue;\n}\n\n/**\n * Generate token balance changes from parsed events.\n * @param request - The transaction that was simulated.\n * @param events - The parsed events.\n * @returns An array of token balance changes.\n */\nasync function getTokenBalanceChanges(\n request: GetSimulationDataRequest,\n events: ParsedEvent[],\n): Promise<SimulationTokenBalanceChange[]> {\n const balanceTxs = getTokenBalanceTransactions(request, events);\n\n log('Generated balance transactions', [...balanceTxs.after.values()]);\n\n const transactions = [\n ...balanceTxs.before.values(),\n request,\n ...balanceTxs.after.values(),\n ];\n\n if (transactions.length === 1) {\n return [];\n }\n\n const response = await simulateTransactions(request.chainId as Hex, {\n transactions,\n });\n\n log('Balance simulation response', response);\n\n if (response.transactions.length !== transactions.length) {\n throw new SimulationInvalidResponseError();\n }\n\n let prevBalanceTxIndex = 0;\n return [...balanceTxs.after.keys()]\n .map((token, index) => {\n const previousBalanceCheckSkipped = !balanceTxs.before.get(token);\n const previousBalance = previousBalanceCheckSkipped\n ? '0x0'\n : getValueFromBalanceTransaction(\n request.from,\n token,\n // eslint-disable-next-line no-plusplus\n response.transactions[prevBalanceTxIndex++],\n );\n\n const newBalance = getValueFromBalanceTransaction(\n request.from,\n token,\n response.transactions[index + balanceTxs.before.size + 1],\n );\n\n const balanceChange = getSimulationBalanceChange(\n previousBalance,\n newBalance,\n );\n\n if (!balanceChange) {\n return undefined;\n }\n\n return {\n ...token,\n ...balanceChange,\n };\n })\n .filter((change) => change !== undefined) as SimulationTokenBalanceChange[];\n}\n\n/**\n * Generate transactions to check token balances.\n * @param request - The transaction that was simulated.\n * @param events - The parsed events.\n * @returns A map of token balance transactions keyed by token.\n */\nfunction getTokenBalanceTransactions(\n request: GetSimulationDataRequest,\n events: ParsedEvent[],\n): {\n before: BalanceTransactionMap;\n after: BalanceTransactionMap;\n} {\n const tokenKeys = new Set();\n const before = new Map();\n const after = new Map();\n\n const userEvents = events.filter((event) =>\n [event.args.from, event.args.to].includes(request.from),\n );\n\n log('Filtered user events', userEvents);\n\n for (const event of userEvents) {\n const tokenIds = getEventTokenIds(event);\n\n log('Extracted token IDs', tokenIds);\n\n for (const tokenId of tokenIds) {\n const simulationToken: SimulationToken = {\n address: event.contractAddress,\n standard: event.tokenStandard,\n id: tokenId,\n };\n\n const tokenKey = JSON.stringify(simulationToken);\n\n if (tokenKeys.has(tokenKey)) {\n log(\n 'Ignoring additional event with same contract and token ID',\n simulationToken,\n );\n continue;\n }\n\n tokenKeys.add(tokenKey);\n\n const data = getBalanceTransactionData(\n event.tokenStandard,\n request.from,\n tokenId,\n );\n\n const transaction: SimulationRequestTransaction = {\n from: request.from,\n to: event.contractAddress,\n data,\n };\n\n if (skipPriorBalanceCheck(event)) {\n after.set(simulationToken, transaction);\n } else {\n before.set(simulationToken, transaction);\n after.set(simulationToken, transaction);\n }\n }\n }\n\n return { before, after };\n}\n\n/**\n * Check if an event needs to check the previous balance.\n * @param event - The parsed event.\n * @returns True if the prior balance check should be skipped.\n */\nfunction skipPriorBalanceCheck(event: ParsedEvent): boolean {\n // In the case of an NFT mint, we cannot check the NFT owner before the mint\n // as the balance check transaction would revert.\n return (\n event.name === 'Transfer' &&\n event.tokenStandard === SimulationTokenStandard.erc721 &&\n parseInt(event.args.from as string, 16) === 0\n );\n}\n\n/**\n * Extract token IDs from a parsed event.\n * @param event - The parsed event.\n * @returns An array of token IDs.\n */\nfunction getEventTokenIds(event: ParsedEvent): (Hex | undefined)[] {\n if (event.tokenStandard === SimulationTokenStandard.erc721) {\n return [event.args.tokenId as Hex];\n }\n\n if (\n event.tokenStandard === SimulationTokenStandard.erc1155 &&\n event.name === 'TransferSingle'\n ) {\n return [event.args.id as Hex];\n }\n\n if (\n event.tokenStandard === SimulationTokenStandard.erc1155 &&\n event.name === 'TransferBatch'\n ) {\n return event.args.ids as Hex[];\n }\n\n // ERC-20 does not have a token ID so default to undefined.\n return [undefined];\n}\n\n/**\n * Extract the value from a balance transaction response.\n * @param from - The address to check the balance of.\n * @param token - The token to check the balance of.\n * @param response - The balance transaction response.\n * @returns The value of the balance transaction.\n */\nfunction getValueFromBalanceTransaction(\n from: Hex,\n token: SimulationToken,\n response: SimulationResponseTransaction,\n): Hex {\n const normalizedReturn = normalizeReturnValue(response.return);\n\n if (token.standard === SimulationTokenStandard.erc721) {\n return normalizedReturn === from ? '0x1' : '0x0';\n }\n\n return normalizedReturn;\n}\n\n/**\n * Generate the balance transaction data for a token.\n * @param tokenStandard - The token standard.\n * @param from - The address to check the balance of.\n * @param tokenId - The token ID to check the balance of.\n * @returns The balance transaction data.\n */\nfunction getBalanceTransactionData(\n tokenStandard: SimulationTokenStandard,\n from: Hex,\n tokenId?: Hex,\n): Hex {\n switch (tokenStandard) {\n case SimulationTokenStandard.erc721:\n return new Interface(abiERC721).encodeFunctionData('ownerOf', [\n tokenId,\n ]) as Hex;\n\n case SimulationTokenStandard.erc1155:\n return new Interface(abiERC1155).encodeFunctionData('balanceOf', [\n from,\n tokenId,\n ]) as Hex;\n\n default:\n return new Interface(abiERC20).encodeFunctionData('balanceOf', [\n from,\n ]) as Hex;\n }\n}\n\n/**\n * Parse a raw event log using known ABIs.\n * @param eventLog - The raw event log.\n * @param interfaces - The contract interfaces.\n * @returns The parsed event log or undefined if it could not be parsed.\n */\nfunction parseLog(\n eventLog: SimulationResponseLog,\n interfaces: Map<SupportedToken, Interface>,\n):\n | (LogDescription & { abi: ABI; standard: SimulationTokenStandard })\n | undefined {\n const supportedTokens = Object.values(SupportedToken);\n\n for (const token of supportedTokens) {\n try {\n const contractInterface = interfaces.get(token) as Interface;\n const { abi, standard } = SUPPORTED_TOKEN_ABIS[token];\n\n return {\n ...contractInterface.parseLog(eventLog),\n abi,\n standard,\n };\n } catch (e) {\n continue;\n }\n }\n\n return undefined;\n}\n\n/**\n * Extract all logs from a call trace tree.\n * @param call - The root call trace.\n * @returns An array of logs.\n */\nfunction extractLogs(\n call: SimulationResponseCallTrace,\n): SimulationResponseLog[] {\n /* istanbul ignore next */\n const logs = call.logs ?? [];\n\n /* istanbul ignore next */\n const nestedCalls = call.calls ?? [];\n\n return [\n ...logs,\n ...nestedCalls.map((nestedCall) => extractLogs(nestedCall)).flat(),\n ];\n}\n\n/**\n * Generate balance change data from previous and new balances.\n * @param previousBalance - The previous balance.\n * @param newBalance - The new balance.\n * @returns The balance change data or undefined if unchanged.\n */\nfunction getSimulationBalanceChange(\n previousBalance: Hex,\n newBalance: Hex,\n): SimulationBalanceChange | undefined {\n const differenceBN = hexToBN(newBalance).sub(hexToBN(previousBalance));\n const isDecrease = differenceBN.isNeg();\n const difference = toHex(differenceBN.abs());\n\n if (differenceBN.isZero()) {\n log('Balance change is zero');\n return undefined;\n }\n\n return {\n previousBalance,\n newBalance,\n difference,\n isDecrease,\n };\n}\n\n/**\n * Normalize a return value.\n * @param value - The return value to normalize.\n * @returns The normalized return value.\n */\nfunction normalizeReturnValue(value: Hex): Hex {\n return toHex(hexToBN(value));\n}\n\n/**\n * Get the contract interfaces for all supported tokens.\n * @returns A map of supported tokens to their contract interfaces.\n */\nfunction getContractInterfaces(): Map<SupportedToken, Interface> {\n const supportedTokens = Object.values(SupportedToken);\n\n return new Map(\n supportedTokens.map((tokenType) => {\n const { abi } = SUPPORTED_TOKEN_ABIS[tokenType];\n const contractInterface = new Interface(abi);\n return [tokenType, contractInterface];\n }),\n );\n}\n"],"mappings":"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","names":["SupportedToken"]}
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "./chunk-6DDVVUJC.mjs";
|
|
5
5
|
import {
|
|
6
6
|
getSimulationData
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-3AVRGHUO.mjs";
|
|
8
8
|
import {
|
|
9
9
|
determineTransactionType
|
|
10
10
|
} from "./chunk-KG4UW4K4.mjs";
|
|
@@ -2563,4 +2563,4 @@ export {
|
|
|
2563
2563
|
ApprovalState,
|
|
2564
2564
|
TransactionController
|
|
2565
2565
|
};
|
|
2566
|
-
//# sourceMappingURL=chunk-
|
|
2566
|
+
//# sourceMappingURL=chunk-J2OIT7FN.mjs.map
|
|
@@ -136,7 +136,12 @@ function getEvents(response) {
|
|
|
136
136
|
log("Failed to find inputs for event", event);
|
|
137
137
|
return void 0;
|
|
138
138
|
}
|
|
139
|
-
|
|
139
|
+
if (!SUPPORTED_EVENTS.includes(event.name)) {
|
|
140
|
+
log("Ignoring unsupported event", event.name, event);
|
|
141
|
+
return void 0;
|
|
142
|
+
}
|
|
143
|
+
log("Normalizing event args", event.name, event);
|
|
144
|
+
const args = normalizeEventArgs(event.args, inputs);
|
|
140
145
|
return {
|
|
141
146
|
contractAddress: currentLog.address,
|
|
142
147
|
tokenStandard: event.standard,
|
|
@@ -146,19 +151,22 @@ function getEvents(response) {
|
|
|
146
151
|
};
|
|
147
152
|
}).filter((e) => e !== void 0);
|
|
148
153
|
}
|
|
149
|
-
function
|
|
154
|
+
function normalizeEventArgs(args, abiInputs) {
|
|
150
155
|
return args.reduce((result, arg, index) => {
|
|
151
156
|
const name = abiInputs[index].name.replace("_", "");
|
|
152
|
-
const value =
|
|
157
|
+
const value = normalizeEventArgValue(arg);
|
|
153
158
|
result[name] = value;
|
|
154
159
|
return result;
|
|
155
160
|
}, {});
|
|
156
161
|
}
|
|
157
|
-
function
|
|
162
|
+
function normalizeEventArgValue(value) {
|
|
158
163
|
if (Array.isArray(value)) {
|
|
159
|
-
return value.map(
|
|
164
|
+
return value.map(normalizeEventArgValue);
|
|
160
165
|
}
|
|
161
|
-
|
|
166
|
+
let normalizedValue = value;
|
|
167
|
+
normalizedValue = normalizedValue.toHexString?.() ?? normalizedValue;
|
|
168
|
+
normalizedValue = normalizedValue.toLowerCase?.() ?? normalizedValue;
|
|
169
|
+
return normalizedValue;
|
|
162
170
|
}
|
|
163
171
|
async function getTokenBalanceChanges(request, events) {
|
|
164
172
|
const balanceTxs = getTokenBalanceTransactions(request, events);
|
|
@@ -210,12 +218,12 @@ function getTokenBalanceTransactions(request, events) {
|
|
|
210
218
|
const before = /* @__PURE__ */ new Map();
|
|
211
219
|
const after = /* @__PURE__ */ new Map();
|
|
212
220
|
const userEvents = events.filter(
|
|
213
|
-
(event) =>
|
|
221
|
+
(event) => [event.args.from, event.args.to].includes(request.from)
|
|
214
222
|
);
|
|
215
223
|
log("Filtered user events", userEvents);
|
|
216
224
|
for (const event of userEvents) {
|
|
217
225
|
const tokenIds = getEventTokenIds(event);
|
|
218
|
-
log("Extracted token
|
|
226
|
+
log("Extracted token IDs", tokenIds);
|
|
219
227
|
for (const tokenId of tokenIds) {
|
|
220
228
|
const simulationToken = {
|
|
221
229
|
address: event.contractAddress,
|
|
@@ -349,4 +357,4 @@ function getContractInterfaces() {
|
|
|
349
357
|
|
|
350
358
|
|
|
351
359
|
exports.SupportedToken = SupportedToken; exports.getSimulationData = getSimulationData; exports.getEvents = getEvents;
|
|
352
|
-
//# sourceMappingURL=chunk-
|
|
360
|
+
//# sourceMappingURL=chunk-NNCUD3QF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/simulation.ts"],"names":["SupportedToken"],"mappings":"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","sourcesContent":["import type { Fragment, LogDescription, Result } from '@ethersproject/abi';\nimport { Interface } from '@ethersproject/abi';\nimport { hexToBN, toHex } from '@metamask/controller-utils';\nimport { abiERC20, abiERC721, abiERC1155 } from '@metamask/metamask-eth-abis';\nimport { createModuleLogger, type Hex } from '@metamask/utils';\n\nimport {\n ABI_SIMULATION_ERC20_WRAPPED,\n ABI_SIMULATION_ERC721_LEGACY,\n} from '../constants';\nimport {\n SimulationError,\n SimulationInvalidResponseError,\n SimulationRevertedError,\n} from '../errors';\nimport { projectLogger } from '../logger';\nimport type {\n SimulationBalanceChange,\n SimulationData,\n SimulationTokenBalanceChange,\n SimulationToken,\n} from '../types';\nimport { SimulationTokenStandard } from '../types';\nimport { simulateTransactions } from './simulation-api';\nimport type {\n SimulationResponseLog,\n SimulationRequestTransaction,\n SimulationResponse,\n SimulationResponseCallTrace,\n SimulationResponseTransaction,\n} from './simulation-api';\n\nexport enum SupportedToken {\n ERC20 = 'erc20',\n ERC721 = 'erc721',\n ERC1155 = 'erc1155',\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ERC20_WRAPPED = 'erc20Wrapped',\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ERC721_LEGACY = 'erc721Legacy',\n}\n\ntype ABI = Fragment[];\n\nexport type GetSimulationDataRequest = {\n chainId: Hex;\n from: Hex;\n to?: Hex;\n value?: Hex;\n data?: Hex;\n};\n\ntype ParsedEvent = {\n contractAddress: Hex;\n tokenStandard: SimulationTokenStandard;\n name: string;\n args: Record<string, Hex | Hex[]>;\n abi: ABI;\n};\n\nconst log = createModuleLogger(projectLogger, 'simulation');\n\nconst SUPPORTED_EVENTS = [\n 'Transfer',\n 'TransferSingle',\n 'TransferBatch',\n 'Deposit',\n 'Withdrawal',\n];\n\nconst SUPPORTED_TOKEN_ABIS = {\n [SupportedToken.ERC20]: {\n abi: abiERC20,\n standard: SimulationTokenStandard.erc20,\n },\n [SupportedToken.ERC721]: {\n abi: abiERC721,\n standard: SimulationTokenStandard.erc721,\n },\n [SupportedToken.ERC1155]: {\n abi: abiERC1155,\n standard: SimulationTokenStandard.erc1155,\n },\n [SupportedToken.ERC20_WRAPPED]: {\n abi: ABI_SIMULATION_ERC20_WRAPPED,\n standard: SimulationTokenStandard.erc20,\n },\n [SupportedToken.ERC721_LEGACY]: {\n abi: ABI_SIMULATION_ERC721_LEGACY,\n standard: SimulationTokenStandard.erc721,\n },\n};\n\nconst REVERTED_ERRORS = ['execution reverted', 'insufficient funds for gas'];\n\ntype BalanceTransactionMap = Map<SimulationToken, SimulationRequestTransaction>;\n\n/**\n * Generate simulation data for a transaction.\n * @param request - The transaction to simulate.\n * @param request.chainId - The chain ID of the transaction.\n * @param request.from - The sender of the transaction.\n * @param request.to - The recipient of the transaction.\n * @param request.value - The value of the transaction.\n * @param request.data - The data of the transaction.\n * @returns The simulation data.\n */\nexport async function getSimulationData(\n request: GetSimulationDataRequest,\n): Promise<SimulationData> {\n const { chainId, from, to, value, data } = request;\n\n log('Getting simulation data', request);\n\n try {\n const response = await simulateTransactions(chainId, {\n transactions: [\n {\n data,\n from,\n maxFeePerGas: '0x0',\n maxPriorityFeePerGas: '0x0',\n to,\n value,\n },\n ],\n withCallTrace: true,\n withLogs: true,\n });\n\n const transactionError = response.transactions?.[0]?.error;\n\n if (transactionError) {\n throw new SimulationError(transactionError);\n }\n\n const nativeBalanceChange = getNativeBalanceChange(request.from, response);\n const events = getEvents(response);\n\n log('Parsed events', events);\n\n const tokenBalanceChanges = await getTokenBalanceChanges(request, events);\n\n return {\n nativeBalanceChange,\n tokenBalanceChanges,\n };\n } catch (error) {\n log('Failed to get simulation data', error, request);\n\n let simulationError = error as SimulationError;\n\n if (\n REVERTED_ERRORS.some((revertErrorMessage) =>\n simulationError.message?.includes(revertErrorMessage),\n )\n ) {\n simulationError = new SimulationRevertedError();\n }\n\n const { code, message } = simulationError;\n\n return {\n tokenBalanceChanges: [],\n error: {\n code,\n message,\n },\n };\n }\n}\n\n/**\n * Extract the native balance change from a simulation response.\n * @param userAddress - The user's account address.\n * @param response - The simulation response.\n * @returns The native balance change or undefined if unchanged.\n */\nfunction getNativeBalanceChange(\n userAddress: Hex,\n response: SimulationResponse,\n): SimulationBalanceChange | undefined {\n const transactionResponse = response.transactions[0];\n\n /* istanbul ignore next */\n if (!transactionResponse) {\n return undefined;\n }\n\n const { stateDiff } = transactionResponse;\n const previousBalance = stateDiff?.pre?.[userAddress]?.balance;\n const newBalance = stateDiff?.post?.[userAddress]?.balance;\n\n if (!previousBalance || !newBalance) {\n return undefined;\n }\n\n return getSimulationBalanceChange(previousBalance, newBalance);\n}\n\n/**\n * Extract events from a simulation response.\n * @param response - The simulation response.\n * @returns The parsed events.\n */\nexport function getEvents(response: SimulationResponse): ParsedEvent[] {\n /* istanbul ignore next */\n const logs = extractLogs(\n response.transactions[0]?.callTrace ?? ({} as SimulationResponseCallTrace),\n );\n\n log('Extracted logs', logs);\n\n const interfaces = getContractInterfaces();\n\n return logs\n .map((currentLog) => {\n const event = parseLog(currentLog, interfaces);\n\n if (!event) {\n log('Failed to parse log', currentLog);\n return undefined;\n }\n\n /* istanbul ignore next */\n const inputs = event.abi.find((e) => e.name === event.name)?.inputs;\n\n /* istanbul ignore if */\n if (!inputs) {\n log('Failed to find inputs for event', event);\n return undefined;\n }\n\n if (!SUPPORTED_EVENTS.includes(event.name)) {\n log('Ignoring unsupported event', event.name, event);\n return undefined;\n }\n\n log('Normalizing event args', event.name, event);\n\n const args = normalizeEventArgs(event.args, inputs);\n\n return {\n contractAddress: currentLog.address,\n tokenStandard: event.standard,\n name: event.name,\n args,\n abi: event.abi,\n };\n })\n .filter((e) => e !== undefined) as ParsedEvent[];\n}\n\n/**\n * Normalize event arguments using ABI input definitions.\n * @param args - The raw event arguments.\n * @param abiInputs - The ABI input definitions.\n * @returns The normalized event arguments.\n */\nfunction normalizeEventArgs(\n args: Result,\n abiInputs: { name: string }[],\n): Record<string, Hex | Hex[]> {\n return args.reduce((result, arg, index) => {\n const name = abiInputs[index].name.replace('_', '');\n const value = normalizeEventArgValue(arg);\n\n result[name] = value;\n\n return result;\n }, {});\n}\n\n/**\n * Normalize an event argument value.\n * @param value - The event argument value.\n * @returns The normalized event argument value.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction normalizeEventArgValue(value: any): any {\n if (Array.isArray(value)) {\n return value.map(normalizeEventArgValue);\n }\n\n let normalizedValue = value;\n\n normalizedValue = normalizedValue.toHexString?.() ?? normalizedValue;\n normalizedValue = normalizedValue.toLowerCase?.() ?? normalizedValue;\n\n return normalizedValue;\n}\n\n/**\n * Generate token balance changes from parsed events.\n * @param request - The transaction that was simulated.\n * @param events - The parsed events.\n * @returns An array of token balance changes.\n */\nasync function getTokenBalanceChanges(\n request: GetSimulationDataRequest,\n events: ParsedEvent[],\n): Promise<SimulationTokenBalanceChange[]> {\n const balanceTxs = getTokenBalanceTransactions(request, events);\n\n log('Generated balance transactions', [...balanceTxs.after.values()]);\n\n const transactions = [\n ...balanceTxs.before.values(),\n request,\n ...balanceTxs.after.values(),\n ];\n\n if (transactions.length === 1) {\n return [];\n }\n\n const response = await simulateTransactions(request.chainId as Hex, {\n transactions,\n });\n\n log('Balance simulation response', response);\n\n if (response.transactions.length !== transactions.length) {\n throw new SimulationInvalidResponseError();\n }\n\n let prevBalanceTxIndex = 0;\n return [...balanceTxs.after.keys()]\n .map((token, index) => {\n const previousBalanceCheckSkipped = !balanceTxs.before.get(token);\n const previousBalance = previousBalanceCheckSkipped\n ? '0x0'\n : getValueFromBalanceTransaction(\n request.from,\n token,\n // eslint-disable-next-line no-plusplus\n response.transactions[prevBalanceTxIndex++],\n );\n\n const newBalance = getValueFromBalanceTransaction(\n request.from,\n token,\n response.transactions[index + balanceTxs.before.size + 1],\n );\n\n const balanceChange = getSimulationBalanceChange(\n previousBalance,\n newBalance,\n );\n\n if (!balanceChange) {\n return undefined;\n }\n\n return {\n ...token,\n ...balanceChange,\n };\n })\n .filter((change) => change !== undefined) as SimulationTokenBalanceChange[];\n}\n\n/**\n * Generate transactions to check token balances.\n * @param request - The transaction that was simulated.\n * @param events - The parsed events.\n * @returns A map of token balance transactions keyed by token.\n */\nfunction getTokenBalanceTransactions(\n request: GetSimulationDataRequest,\n events: ParsedEvent[],\n): {\n before: BalanceTransactionMap;\n after: BalanceTransactionMap;\n} {\n const tokenKeys = new Set();\n const before = new Map();\n const after = new Map();\n\n const userEvents = events.filter((event) =>\n [event.args.from, event.args.to].includes(request.from),\n );\n\n log('Filtered user events', userEvents);\n\n for (const event of userEvents) {\n const tokenIds = getEventTokenIds(event);\n\n log('Extracted token IDs', tokenIds);\n\n for (const tokenId of tokenIds) {\n const simulationToken: SimulationToken = {\n address: event.contractAddress,\n standard: event.tokenStandard,\n id: tokenId,\n };\n\n const tokenKey = JSON.stringify(simulationToken);\n\n if (tokenKeys.has(tokenKey)) {\n log(\n 'Ignoring additional event with same contract and token ID',\n simulationToken,\n );\n continue;\n }\n\n tokenKeys.add(tokenKey);\n\n const data = getBalanceTransactionData(\n event.tokenStandard,\n request.from,\n tokenId,\n );\n\n const transaction: SimulationRequestTransaction = {\n from: request.from,\n to: event.contractAddress,\n data,\n };\n\n if (skipPriorBalanceCheck(event)) {\n after.set(simulationToken, transaction);\n } else {\n before.set(simulationToken, transaction);\n after.set(simulationToken, transaction);\n }\n }\n }\n\n return { before, after };\n}\n\n/**\n * Check if an event needs to check the previous balance.\n * @param event - The parsed event.\n * @returns True if the prior balance check should be skipped.\n */\nfunction skipPriorBalanceCheck(event: ParsedEvent): boolean {\n // In the case of an NFT mint, we cannot check the NFT owner before the mint\n // as the balance check transaction would revert.\n return (\n event.name === 'Transfer' &&\n event.tokenStandard === SimulationTokenStandard.erc721 &&\n parseInt(event.args.from as string, 16) === 0\n );\n}\n\n/**\n * Extract token IDs from a parsed event.\n * @param event - The parsed event.\n * @returns An array of token IDs.\n */\nfunction getEventTokenIds(event: ParsedEvent): (Hex | undefined)[] {\n if (event.tokenStandard === SimulationTokenStandard.erc721) {\n return [event.args.tokenId as Hex];\n }\n\n if (\n event.tokenStandard === SimulationTokenStandard.erc1155 &&\n event.name === 'TransferSingle'\n ) {\n return [event.args.id as Hex];\n }\n\n if (\n event.tokenStandard === SimulationTokenStandard.erc1155 &&\n event.name === 'TransferBatch'\n ) {\n return event.args.ids as Hex[];\n }\n\n // ERC-20 does not have a token ID so default to undefined.\n return [undefined];\n}\n\n/**\n * Extract the value from a balance transaction response.\n * @param from - The address to check the balance of.\n * @param token - The token to check the balance of.\n * @param response - The balance transaction response.\n * @returns The value of the balance transaction.\n */\nfunction getValueFromBalanceTransaction(\n from: Hex,\n token: SimulationToken,\n response: SimulationResponseTransaction,\n): Hex {\n const normalizedReturn = normalizeReturnValue(response.return);\n\n if (token.standard === SimulationTokenStandard.erc721) {\n return normalizedReturn === from ? '0x1' : '0x0';\n }\n\n return normalizedReturn;\n}\n\n/**\n * Generate the balance transaction data for a token.\n * @param tokenStandard - The token standard.\n * @param from - The address to check the balance of.\n * @param tokenId - The token ID to check the balance of.\n * @returns The balance transaction data.\n */\nfunction getBalanceTransactionData(\n tokenStandard: SimulationTokenStandard,\n from: Hex,\n tokenId?: Hex,\n): Hex {\n switch (tokenStandard) {\n case SimulationTokenStandard.erc721:\n return new Interface(abiERC721).encodeFunctionData('ownerOf', [\n tokenId,\n ]) as Hex;\n\n case SimulationTokenStandard.erc1155:\n return new Interface(abiERC1155).encodeFunctionData('balanceOf', [\n from,\n tokenId,\n ]) as Hex;\n\n default:\n return new Interface(abiERC20).encodeFunctionData('balanceOf', [\n from,\n ]) as Hex;\n }\n}\n\n/**\n * Parse a raw event log using known ABIs.\n * @param eventLog - The raw event log.\n * @param interfaces - The contract interfaces.\n * @returns The parsed event log or undefined if it could not be parsed.\n */\nfunction parseLog(\n eventLog: SimulationResponseLog,\n interfaces: Map<SupportedToken, Interface>,\n):\n | (LogDescription & { abi: ABI; standard: SimulationTokenStandard })\n | undefined {\n const supportedTokens = Object.values(SupportedToken);\n\n for (const token of supportedTokens) {\n try {\n const contractInterface = interfaces.get(token) as Interface;\n const { abi, standard } = SUPPORTED_TOKEN_ABIS[token];\n\n return {\n ...contractInterface.parseLog(eventLog),\n abi,\n standard,\n };\n } catch (e) {\n continue;\n }\n }\n\n return undefined;\n}\n\n/**\n * Extract all logs from a call trace tree.\n * @param call - The root call trace.\n * @returns An array of logs.\n */\nfunction extractLogs(\n call: SimulationResponseCallTrace,\n): SimulationResponseLog[] {\n /* istanbul ignore next */\n const logs = call.logs ?? [];\n\n /* istanbul ignore next */\n const nestedCalls = call.calls ?? [];\n\n return [\n ...logs,\n ...nestedCalls.map((nestedCall) => extractLogs(nestedCall)).flat(),\n ];\n}\n\n/**\n * Generate balance change data from previous and new balances.\n * @param previousBalance - The previous balance.\n * @param newBalance - The new balance.\n * @returns The balance change data or undefined if unchanged.\n */\nfunction getSimulationBalanceChange(\n previousBalance: Hex,\n newBalance: Hex,\n): SimulationBalanceChange | undefined {\n const differenceBN = hexToBN(newBalance).sub(hexToBN(previousBalance));\n const isDecrease = differenceBN.isNeg();\n const difference = toHex(differenceBN.abs());\n\n if (differenceBN.isZero()) {\n log('Balance change is zero');\n return undefined;\n }\n\n return {\n previousBalance,\n newBalance,\n difference,\n isDecrease,\n };\n}\n\n/**\n * Normalize a return value.\n * @param value - The return value to normalize.\n * @returns The normalized return value.\n */\nfunction normalizeReturnValue(value: Hex): Hex {\n return toHex(hexToBN(value));\n}\n\n/**\n * Get the contract interfaces for all supported tokens.\n * @returns A map of supported tokens to their contract interfaces.\n */\nfunction getContractInterfaces(): Map<SupportedToken, Interface> {\n const supportedTokens = Object.values(SupportedToken);\n\n return new Map(\n supportedTokens.map((tokenType) => {\n const { abi } = SUPPORTED_TOKEN_ABIS[tokenType];\n const contractInterface = new Interface(abi);\n return [tokenType, contractInterface];\n }),\n );\n}\n"]}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
var _chunkPRUNMTRDjs = require('./chunk-PRUNMTRD.js');
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
var
|
|
7
|
+
var _chunkNNCUD3QFjs = require('./chunk-NNCUD3QF.js');
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
var _chunkSD6CWFDFjs = require('./chunk-SD6CWFDF.js');
|
|
@@ -2465,7 +2465,7 @@ updateSimulationData_fn = async function(transactionMeta) {
|
|
|
2465
2465
|
_chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _updateTransactionInternal, updateTransactionInternal_fn).call(this, { transactionId, skipHistory: true }, (txMeta) => {
|
|
2466
2466
|
txMeta.simulationData = void 0;
|
|
2467
2467
|
});
|
|
2468
|
-
simulationData = await
|
|
2468
|
+
simulationData = await _chunkNNCUD3QFjs.getSimulationData.call(void 0, {
|
|
2469
2469
|
chainId,
|
|
2470
2470
|
from,
|
|
2471
2471
|
to,
|
|
@@ -2563,4 +2563,4 @@ getSelectedAccount_fn = function() {
|
|
|
2563
2563
|
|
|
2564
2564
|
|
|
2565
2565
|
exports.HARDFORK = HARDFORK; exports.CANCEL_RATE = CANCEL_RATE; exports.SPEED_UP_RATE = SPEED_UP_RATE; exports.ApprovalState = ApprovalState; exports.TransactionController = TransactionController;
|
|
2566
|
-
//# sourceMappingURL=chunk-
|
|
2566
|
+
//# sourceMappingURL=chunk-PHSSZPCU.js.map
|
package/dist/index.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var _chunkPHSSZPCUjs = require('./chunk-PHSSZPCU.js');
|
|
6
6
|
require('./chunk-PRUNMTRD.js');
|
|
7
|
-
require('./chunk-
|
|
7
|
+
require('./chunk-NNCUD3QF.js');
|
|
8
8
|
require('./chunk-KT6UAKBB.js');
|
|
9
9
|
|
|
10
10
|
|
|
@@ -67,5 +67,5 @@ require('./chunk-Z4BLTVTB.js');
|
|
|
67
67
|
|
|
68
68
|
|
|
69
69
|
|
|
70
|
-
exports.CANCEL_RATE =
|
|
70
|
+
exports.CANCEL_RATE = _chunkPHSSZPCUjs.CANCEL_RATE; exports.GasFeeEstimateLevel = _chunkAYTU4HU5js.GasFeeEstimateLevel; exports.GasFeeEstimateType = _chunkAYTU4HU5js.GasFeeEstimateType; exports.HARDFORK = _chunkPHSSZPCUjs.HARDFORK; exports.SimulationErrorCode = _chunkAYTU4HU5js.SimulationErrorCode; exports.SimulationTokenStandard = _chunkAYTU4HU5js.SimulationTokenStandard; exports.TransactionController = _chunkPHSSZPCUjs.TransactionController; exports.TransactionEnvelopeType = _chunkAYTU4HU5js.TransactionEnvelopeType; exports.TransactionStatus = _chunkAYTU4HU5js.TransactionStatus; exports.TransactionType = _chunkAYTU4HU5js.TransactionType; exports.UserFeeLevel = _chunkAYTU4HU5js.UserFeeLevel; exports.WalletDevice = _chunkAYTU4HU5js.WalletDevice; exports.determineTransactionType = _chunkSD6CWFDFjs.determineTransactionType; exports.isEIP1559Transaction = _chunkOZ6UB42Cjs.isEIP1559Transaction; exports.mergeGasFeeEstimates = _chunk76FONEDAjs.mergeGasFeeEstimates; exports.normalizeTransactionParams = _chunkOZ6UB42Cjs.normalizeTransactionParams;
|
|
71
71
|
//# sourceMappingURL=index.js.map
|
package/dist/index.mjs
CHANGED
|
@@ -2,9 +2,9 @@ import {
|
|
|
2
2
|
CANCEL_RATE,
|
|
3
3
|
HARDFORK,
|
|
4
4
|
TransactionController
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-J2OIT7FN.mjs";
|
|
6
6
|
import "./chunk-6DDVVUJC.mjs";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-3AVRGHUO.mjs";
|
|
8
8
|
import "./chunk-K4KOSAGM.mjs";
|
|
9
9
|
import {
|
|
10
10
|
determineTransactionType
|