diff --git a/packages/transaction-controller/CHANGELOG.md b/packages/transaction-controller/CHANGELOG.md index a7a5fb27ac0..12d297fd78d 100644 --- a/packages/transaction-controller/CHANGELOG.md +++ b/packages/transaction-controller/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Defaults to 100 if not provided. - Add support for `transactionHistoryLimit` feature flag to configure the maximum number of transactions stored in state ([#7648](https://github.com/MetaMask/core/pull/7648)) - Defaults to 40 if not provided. +- Add callTrace errors in the simulation data ([#7641](https://github.com/MetaMask/core/pull/7641)) ### Changed diff --git a/packages/transaction-controller/src/api/simulation-api.ts b/packages/transaction-controller/src/api/simulation-api.ts index 96a5280dbb2..5e77dab80e4 100644 --- a/packages/transaction-controller/src/api/simulation-api.ts +++ b/packages/transaction-controller/src/api/simulation-api.ts @@ -135,10 +135,13 @@ export type SimulationResponseLog = { /** Call trace of a single simulated transaction. */ export type SimulationResponseCallTrace = { /** Nested calls. */ - calls: SimulationResponseCallTrace[]; + calls?: SimulationResponseCallTrace[] | null; + + /** Error message for the call, if any. */ + error?: string; /** Raw event logs created by the call. */ - logs: SimulationResponseLog[]; + logs?: SimulationResponseLog[] | null; }; /** diff --git a/packages/transaction-controller/src/types.ts b/packages/transaction-controller/src/types.ts index 2d6aaf3d565..acfdcdd5735 100644 --- a/packages/transaction-controller/src/types.ts +++ b/packages/transaction-controller/src/types.ts @@ -1551,6 +1551,9 @@ export type SimulationData = { /** Whether the simulation response changed after a security check triggered a re-simulation. */ isUpdatedAfterSecurityCheck?: boolean; + /** Error messages extracted from call traces, if any. */ + callTraceErrors?: string[]; + /** Data concerning a change to the user's native balance. */ nativeBalanceChange?: SimulationBalanceChange; diff --git a/packages/transaction-controller/src/utils/balance-changes.ts b/packages/transaction-controller/src/utils/balance-changes.ts index 0820e97c369..9b9780820de 100644 --- a/packages/transaction-controller/src/utils/balance-changes.ts +++ b/packages/transaction-controller/src/utils/balance-changes.ts @@ -121,6 +121,8 @@ export async function getBalanceChanges( ): Promise<{ simulationData: SimulationData; gasUsed?: Hex }> { log('Request', request); + let callTraceErrors: string[] | undefined; + try { const response = await baseRequest({ request, @@ -130,7 +132,9 @@ export async function getBalanceChanges( }, }); - const transactionError = response.transactions?.[0]?.error; + const transactionResponse = response.transactions?.[0]; + callTraceErrors = extractCallTraceErrors(transactionResponse?.callTrace); + const transactionError = transactionResponse?.error; if (transactionError) { throw new SimulationError(transactionError); @@ -143,8 +147,9 @@ export async function getBalanceChanges( const tokenBalanceChanges = await getTokenBalanceChanges(request, events); - const gasUsed = response.transactions?.[0]?.gasUsed; + const gasUsed = transactionResponse?.gasUsed; const simulationData = { + ...(callTraceErrors?.length ? { callTraceErrors } : {}), nativeBalanceChange, tokenBalanceChanges, }; @@ -167,6 +172,7 @@ export async function getBalanceChanges( return { simulationData: { + ...(callTraceErrors?.length ? { callTraceErrors } : {}), tokenBalanceChanges: [], error: { code, @@ -632,6 +638,28 @@ function extractLogs( ]; } +/** + * Extract all error messages from a call trace tree. + * + * @param call - The root call trace. + * @returns An array of error messages. + */ +function extractCallTraceErrors(call?: SimulationResponseCallTrace): string[] { + if (!call) { + return []; + } + + const errors = call.error ? [call.error] : []; + const nestedCalls = call.calls ?? []; + + return [ + ...errors, + ...nestedCalls + .map((nestedCall) => extractCallTraceErrors(nestedCall)) + .flat(), + ]; +} + /** * Generate balance change data from previous and new balances. *