diff --git a/__tests__/integration/nanocontracts/bet.test.ts b/__tests__/integration/nanocontracts/bet.test.ts index 9dc68797e..0b078df03 100644 --- a/__tests__/integration/nanocontracts/bet.test.ts +++ b/__tests__/integration/nanocontracts/bet.test.ts @@ -29,6 +29,7 @@ import { import { NanoContractTransactionError, NanoRequest404Error, + NanoRequestError, PinRequiredError, } from '../../../src/errors'; import { OutputType } from '../../../src/wallet/types'; @@ -517,6 +518,14 @@ describe('full cycle of bet nano contract', () => { expect(txIds).toContain(tx.hash); } + // Get NC logs + const ncLogs = await ncApi.getNanoContractLogs(tx1.hash); + expect(ncLogs.success).toBe(true); + expect(ncLogs.nc_id).toBe(tx1.hash); + expect(ncLogs.nc_execution).toBeDefined(); + expect(ncLogs.logs).toBeDefined(); + expect(typeof ncLogs.logs).toBe('object'); + // Get tx history with success const txHistory = await wallet.getTxHistory(); expect(txHistory).toHaveLength(4); @@ -829,5 +838,11 @@ describe('full cycle of bet nano contract', () => { // Add the pin back in case there are more tests here ocbWallet.pinCode = oldOcbPin; + + // Test getNanoContractLogs with invalid NC ID (should throw error) + await expect(ncApi.getNanoContractLogs('invalid_nc_id')).rejects.toThrow(NanoRequestError); + + // Test getNanoContractLogs with a valid hash but not a nano contract + await expect(ncApi.getNanoContractLogs(fundsTx.hash)).rejects.toThrow(NanoRequestError); }); }); diff --git a/src/api/nano.ts b/src/api/nano.ts index b55c1d4a1..5732fb9ad 100644 --- a/src/api/nano.ts +++ b/src/api/nano.ts @@ -16,6 +16,7 @@ import { NanoContractHistoryAPIResponse, NanoContractStateAPIResponse, NanoContractStateAPIParameters, + NanoContractLogsAPIResponse, } from '../nano_contracts/types'; /** @@ -286,6 +287,38 @@ const ncApi = { throw new NanoRequestError('Error getting nano contract creation list.', error); } }, + + /** + * Call get nano contract logs API + * + * @param id Nano Contract ID + * + * @return {Promise} + * @memberof ApiNanoContracts + * @inner + */ + async getNanoContractLogs(id: string): Promise { + const data = { id }; + const axiosInstance = await createRequestInstance(); + try { + const response = await axiosInstance.get(`nano_contract/logs`, { params: data }); + const responseData = response.data; + if (response.status === 200 && responseData.success) { + return responseData; + } + + throw new NanoRequestError('Error getting nano contract logs.', null, response); + } catch (error: unknown) { + if (axios.isAxiosError(error)) { + const e = error as AxiosError; + if (e.response && e.response.status === 404) { + throw new NanoRequest404Error('Nano contract not found.', e, e.response); + } + } + + throw new NanoRequestError('Error getting nano contract logs.', error); + } + }, }; export default ncApi; diff --git a/src/nano_contracts/types.ts b/src/nano_contracts/types.ts index 9c16f1110..7ea82b17f 100644 --- a/src/nano_contracts/types.ts +++ b/src/nano_contracts/types.ts @@ -269,3 +269,14 @@ export interface NanoContractCreationListAPIResponse { // Has more contracts to fetch has_more: boolean; } + +export interface NanoContractLogsAPIResponse { + // If the request succeeded + success: boolean; + // Nano contract ID + nc_id: string; + // Execution metadata + nc_execution: string | null; + // Logs organized by block ID (hex string keys) + logs: Record; +}