diff --git a/packages/relay/src/lib/debug.ts b/packages/relay/src/lib/debug.ts index 42b4d1d5d3..403e222c69 100644 --- a/packages/relay/src/lib/debug.ts +++ b/packages/relay/src/lib/debug.ts @@ -471,8 +471,40 @@ export class DebugImpl implements Debug { throw predefined.RESOURCE_NOT_FOUND(`Failed to retrieve contract results for transaction ${transactionHash}`); } - // return empty array if no actions - if (actionsResponse.length === 0) return null; + // If there are no actions, return a root transaction object with empty calls + if (actionsResponse.length === 0) { + const { + from, + to, + amount, + gas_limit: gas, + gas_used: gasUsed, + function_parameters: input, + call_result: output, + error_message: error, + result, + } = transactionsResponse; + + const { resolvedFrom, resolvedTo } = await this.resolveMultipleAddresses(from, to, requestDetails); + + const value = amount === 0 ? DebugImpl.zeroHex : numberTo0x(amount); + const errorResult = result !== constants.SUCCESS ? result : undefined; + const type = resolvedTo ? 'CALL' : 'CREATE'; + + return { + type, + from: resolvedFrom, + to: resolvedTo, + value, + gas: numberTo0x(gas), + gasUsed: numberTo0x(gasUsed), + input, + output: result !== constants.SUCCESS ? error : output, + ...(result !== constants.SUCCESS && { error: errorResult }), + ...(result !== constants.SUCCESS && { revertReason: decodeErrorMessage(error) }), + calls: [], + }; + } const { call_type: type } = actionsResponse[0]; const formattedActions = await this.formatActionsResult(actionsResponse, requestDetails); diff --git a/packages/relay/tests/lib/debug.spec.ts b/packages/relay/tests/lib/debug.spec.ts index f58f418290..0ae6c5f359 100644 --- a/packages/relay/tests/lib/debug.spec.ts +++ b/packages/relay/tests/lib/debug.spec.ts @@ -284,7 +284,7 @@ describe('Debug API Test Suite', async function () { }); this.beforeEach(() => { - cacheService.clear(requestDetails); + cacheService.clear(); }); describe('debug_traceTransaction', async function () { @@ -422,7 +422,7 @@ describe('Debug API Test Suite', async function () { expect(result).to.deep.equal(expectedResult); }); - it('Should return empty array if no actions found', async function () { + it('Should return root transaction with empty calls if no actions found', async function () { restMock.onGet(CONTARCTS_RESULTS_ACTIONS).reply(200, JSON.stringify({ actions: [] })); const result = await debugService.traceTransaction( @@ -431,7 +431,19 @@ describe('Debug API Test Suite', async function () { requestDetails, ); - expect(result).to.be.null; + const expectedRoot = { + type: 'CALL', + from: accountsResult.evm_address, + to: contractResult.evm_address, + value: '0x0', + gas: '0x493e0', + gasUsed: '0x3a980', + input: '0x1', + output: '0x2', + calls: [], + }; + + expect(result).to.deep.equal(expectedRoot); }); }); @@ -710,7 +722,7 @@ describe('Debug API Test Suite', async function () { sinon.restore(); restMock.reset(); web3Mock.reset(); - cacheService.clear(requestDetails); + cacheService.clear(); }); withOverriddenEnvsInMochaTest({ DEBUG_API_ENABLED: undefined }, () => { @@ -999,7 +1011,7 @@ describe('Debug API Test Suite', async function () { sinon.restore(); restMock.reset(); web3Mock.reset(); - cacheService.clear(requestDetails); + cacheService.clear(); }); withOverriddenEnvsInMochaTest({ DEBUG_API_ENABLED: true }, () => {