From ac7c38e40ed9bf028866ebb01f2e2a01aae43bb1 Mon Sep 17 00:00:00 2001 From: samsamtrum Date: Mon, 1 Jun 2026 23:57:39 +0700 Subject: [PATCH] fix network id response parsing --- .../contracts/contracts.repository.ts | 3 ++- lib/repositories/response.ts | 15 +++++++++++++++ lib/repositories/wallets/wallets.repository.ts | 3 ++- test/network-id.test.ts | 15 +++++++++++++++ 4 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 lib/repositories/response.ts create mode 100644 test/network-id.test.ts diff --git a/lib/repositories/contracts/contracts.repository.ts b/lib/repositories/contracts/contracts.repository.ts index 2aa91a2..c261b40 100644 --- a/lib/repositories/contracts/contracts.repository.ts +++ b/lib/repositories/contracts/contracts.repository.ts @@ -21,11 +21,12 @@ import { BytecodeMismatchError, UnexpectedVerificationError, } from '../../errors'; +import { getNetworkFromResponse } from '../response'; function mapContractResponseToContractModel(contractResponse: ContractResponse): TenderlyContract { const retVal: TenderlyContract = { address: contractResponse.contract.address, - network: Number.parseInt(contractResponse.contract.network_id) as unknown as Network, + network: getNetworkFromResponse(contractResponse.contract.network_id), }; if (contractResponse.display_name) { diff --git a/lib/repositories/response.ts b/lib/repositories/response.ts new file mode 100644 index 0000000..0f263c1 --- /dev/null +++ b/lib/repositories/response.ts @@ -0,0 +1,15 @@ +import { Network } from '../types'; +import { InvalidResponseError } from '../errors'; + +export function getNetworkFromResponse(networkId: string): Network { + if (!/^\d+$/.test(networkId)) { + throw new InvalidResponseError('Invalid network_id in Tenderly response'); + } + + const network = Number.parseInt(networkId, 10); + if (!Number.isSafeInteger(network)) { + throw new InvalidResponseError('Invalid network_id in Tenderly response'); + } + + return network as unknown as Network; +} diff --git a/lib/repositories/wallets/wallets.repository.ts b/lib/repositories/wallets/wallets.repository.ts index 7e532e8..ef1c9da 100644 --- a/lib/repositories/wallets/wallets.repository.ts +++ b/lib/repositories/wallets/wallets.repository.ts @@ -11,13 +11,14 @@ import { import { handleError, InvalidResponseError, NotFoundError } from '../../errors'; import { GetByParams } from '../contracts/contracts.types'; import { ApiClientProvider } from '../../core/ApiClientProvider'; +import { getNetworkFromResponse } from '../response'; function getContractFromResponse(contractResponse: WalletResponse): Wallet { const walletDetails = contractResponse.account || contractResponse.contract; return { address: walletDetails.address, - network: Number.parseInt(walletDetails.network_id) as unknown as Network, + network: getNetworkFromResponse(walletDetails.network_id), }; } diff --git a/test/network-id.test.ts b/test/network-id.test.ts new file mode 100644 index 0000000..960fb5a --- /dev/null +++ b/test/network-id.test.ts @@ -0,0 +1,15 @@ +import { getNetworkFromResponse } from '../lib/repositories/response'; + +const message = 'Invalid network_id in Tenderly response'; + +describe('getNetworkFromResponse', () => { + test('returns a valid numeric network id', () => { + expect(getNetworkFromResponse('1')).toBe(1); + }); + + test('rejects malformed network ids', () => { + expect(() => getNetworkFromResponse('1abc')).toThrow(message); + expect(() => getNetworkFromResponse('abc')).toThrow(message); + expect(() => getNetworkFromResponse('')).toThrow(message); + }); +});