Skip to content

Commit feda1f0

Browse files
authored
feat(checkout): Create new types for API response to represent the response structure correctly (#2682)
1 parent 969621e commit feda1f0

File tree

3 files changed

+56
-16
lines changed

3 files changed

+56
-16
lines changed

packages/checkout/sdk/src/api/blockscout/blockscout.test.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { AxiosResponse, HttpStatusCode } from 'axios';
33
import { Blockscout } from './blockscout';
44
import {
55
BlockscoutError,
6+
BlockscoutERC20Response,
67
BlockscoutTokenType,
78
} from './blockscoutType';
89
import { BLOCKSCOUT_CHAIN_URL_MAP, NATIVE } from '../../env';
@@ -40,16 +41,19 @@ describe('Blockscout', () => {
4041
it('success', async () => {
4142
const mockResponse = {
4243
status: 200,
44+
statusText: 'OK',
45+
headers: {},
46+
config: {} as any,
4347
data:
4448
{
4549
items: [
4650
{
4751
token: {
48-
address: '0xF57e7e7C23978C3cAEC3C3548E3D615c346e79fF',
52+
address_hash: '0xF57e7e7C23978C3cAEC3C3548E3D615c346e79fF',
4953
circulating_market_cap: '639486814.4877648',
5054
decimals: '18',
5155
exchange_rate: '0.568914',
52-
holders: '71451',
56+
holders_count: '71451',
5357
icon_url: 'https://assets.coingecko.com',
5458
name: 'Immutable X',
5559
symbol: 'IMX',
@@ -62,11 +66,11 @@ describe('Blockscout', () => {
6266
},
6367
{
6468
token: {
65-
address: '',
69+
address_hash: '',
6670
circulating_market_cap: '639486814.4877648',
6771
decimals: '18',
6872
exchange_rate: '0.568914',
69-
holders: '71451',
73+
holders_count: '71451',
7074
icon_url: 'https://assets.coingecko.com',
7175
name: 'Immutable X',
7276
symbol: 'IMX',
@@ -80,7 +84,7 @@ describe('Blockscout', () => {
8084
],
8185
next_page_params: null,
8286
},
83-
} as AxiosResponse;
87+
} as AxiosResponse<BlockscoutERC20Response>;
8488
mockedHttpClient.get.mockResolvedValueOnce(mockResponse);
8589

8690
const token = BlockscoutTokenType.ERC20;

packages/checkout/sdk/src/api/blockscout/blockscout.ts

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
import axios, {
22
AxiosError,
3+
AxiosResponse,
34
HttpStatusCode,
45
} from 'axios';
56
import { ChainId } from '../../types';
67
import {
8+
BlockscoutERC20Response,
9+
BlockscoutERC20ResponseItem,
710
BlockscoutNativeTokenData,
811
BlockscoutToken,
12+
BlockscoutTokenData,
913
BlockscoutTokenPagination,
1014
BlockscoutTokens,
1115
BlockscoutTokenType,
@@ -105,17 +109,25 @@ export class Blockscout {
105109
const cached = this.getCache(url);
106110
if (cached) return Promise.resolve(cached);
107111

108-
const response = await this.httpClient.get(url); // success if 2XX response otherwise throw error
109-
110-
// Normalize the data by ensuring address field is always present
111-
// Map address_hash to address if address is not present
112-
const normalizedItems = response.data?.items?.map((item: BlockscoutToken) => {
113-
const normalizedToken = { ...item.token };
114-
if (!normalizedToken.address && (normalizedToken as any).address_hash) {
115-
normalizedToken.address = (normalizedToken as any).address_hash;
116-
}
117-
return { ...item, token: normalizedToken };
118-
}) || [];
112+
// success if 2XX response otherwise throw error
113+
const response: AxiosResponse<BlockscoutERC20Response> = await this.httpClient.get(url);
114+
115+
// blockscout changed their API to return address_hash instead of address
116+
// map the address_hash to address field so that any further consumer is not affected by the change
117+
const normalizedItems: BlockscoutToken[] = response.data?.items?.map(
118+
(item: BlockscoutERC20ResponseItem) => {
119+
const token: BlockscoutTokenData = {
120+
...item.token,
121+
address: item.token.address_hash,
122+
holders: item.token.holders_count,
123+
};
124+
125+
return {
126+
...item,
127+
token,
128+
};
129+
},
130+
) || [];
119131

120132
// To get around an issue with native tokens being an ERC-20, there is the need
121133
// to remove IMX from `resp` and add it back in using getNativeTokenByWalletAddress.

packages/checkout/sdk/src/api/blockscout/blockscoutType.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,29 @@ export enum BlockscoutTokenType {
66
ERC20 = 'ERC-20',
77
}
88

9+
export interface BlockscoutERC20Response {
10+
items: BlockscoutERC20ResponseItem[]
11+
next_page_params: BlockscoutTokenPagination | null
12+
}
13+
14+
export interface BlockscoutERC20ResponseItem {
15+
token: {
16+
address_hash: string
17+
decimals: string
18+
name: string
19+
symbol: string
20+
holders_count: string
21+
circulating_market_cap: string
22+
exchange_rate: string
23+
total_supply: string
24+
icon_url: string;
25+
type: BlockscoutTokenType
26+
}
27+
value: string
28+
token_id: string | null
29+
token_instance: string | null
30+
}
31+
932
export interface BlockscoutTokens {
1033
items: BlockscoutToken[]
1134
next_page_params: BlockscoutTokenPagination | null
@@ -24,6 +47,7 @@ export interface BlockscoutTokenData {
2447
name: string
2548
symbol: string
2649
icon_url: string;
50+
holders: string;
2751
type: BlockscoutTokenType
2852
}
2953

0 commit comments

Comments
 (0)