Skip to content

Commit 8ddb952

Browse files
authored
feat(1708): mirror node getaccounttokenbalances response validation (#1731)
Signed-off-by: rozekmichal <michal.rozek@blockydevs.com>
1 parent d50e249 commit 8ddb952

File tree

4 files changed

+34
-13
lines changed

4 files changed

+34
-13
lines changed

src/core/services/mirrornode/__tests__/unit/mocks.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,16 +67,14 @@ export const createMockGetAccountsAPIResponse = (
6767
export const createMockTokenBalancesResponse = (
6868
overrides: Partial<TokenBalancesResponse> = {},
6969
): TokenBalancesResponse => ({
70-
account: '0.0.1234',
71-
balance: 0,
7270
tokens: [
7371
{
7472
token_id: '0.0.2000',
7573
balance: 100,
7674
decimals: 6,
7775
},
7876
],
79-
timestamp: '2024-01-01T12:00:00.000Z',
77+
links: { next: null },
8078
...overrides,
8179
});
8280

src/core/services/mirrornode/hedera-mirrornode-service.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import { handleMirrorNodeErrorResponse } from '@/core/utils/handle-mirror-node-e
3838
import {
3939
AccountAPIResponseSchema,
4040
GetAccountsAPIResponseSchema,
41+
TokenBalancesResponseSchema,
4142
TokenInfoSchema,
4243
} from './schemas';
4344
import { NetworkToBaseUrl } from './types';
@@ -135,8 +136,13 @@ export class HederaMirrornodeServiceDefaultImpl implements HederaMirrornodeServi
135136
);
136137
}
137138

138-
return (await response.json()) as TokenBalancesResponse;
139+
return parseWithSchema(
140+
TokenBalancesResponseSchema,
141+
await response.json(),
142+
`Mirror Node GET /accounts/${accountId}/tokens`,
143+
);
139144
} catch (error) {
145+
if (error instanceof CliError) throw error;
140146
if (error instanceof NotFoundError || error instanceof NetworkError)
141147
throw error;
142148
throw new NetworkError(

src/core/services/mirrornode/schemas.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import type {
66
AccountListItemBalance,
77
AccountListItemTokenBalance,
88
GetAccountsAPIResponse,
9+
TokenBalanceInfo,
10+
TokenBalancesResponse,
911
TokenInfo,
1012
} from './types';
1113

@@ -101,3 +103,19 @@ export const GetAccountsAPIResponseSchema: z.ZodType<GetAccountsAPIResponse> =
101103
})
102104
.optional(),
103105
});
106+
107+
export const TokenBalanceInfoSchema: z.ZodType<TokenBalanceInfo> = z.object({
108+
token_id: z.string(),
109+
balance: z.number(),
110+
decimals: z.number().optional(),
111+
});
112+
113+
export const TokenBalancesResponseSchema: z.ZodType<TokenBalancesResponse> =
114+
z.object({
115+
tokens: z.array(TokenBalanceInfoSchema),
116+
links: z
117+
.object({
118+
next: z.string().nullable().optional(),
119+
})
120+
.optional(),
121+
});

src/core/services/mirrornode/types.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,17 @@ export interface AccountResponse {
4949
keyAlgorithm: KeyAlgorithm;
5050
}
5151

52-
// Token Balance Response
53-
export interface TokenBalancesResponse {
54-
account: string;
55-
balance: number;
56-
tokens: TokenBalanceInfo[];
57-
timestamp: string;
58-
}
59-
6052
export interface TokenBalanceInfo {
6153
token_id: string;
6254
balance: number;
63-
decimals: number;
55+
decimals?: number;
56+
}
57+
58+
export interface TokenBalancesResponse {
59+
tokens: TokenBalanceInfo[];
60+
links?: {
61+
next?: string | null;
62+
};
6463
}
6564

6665
export type MirrorNodeTokenKey = {

0 commit comments

Comments
 (0)