Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions packages/checkout/sdk/src/api/blockscout/blockscout.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { AxiosResponse, HttpStatusCode } from 'axios';
import { Blockscout } from './blockscout';
import {
BlockscoutError,
BlockscoutERC20Response,
BlockscoutTokenType,
} from './blockscoutType';
import { BLOCKSCOUT_CHAIN_URL_MAP, NATIVE } from '../../env';
Expand Down Expand Up @@ -40,16 +41,19 @@ describe('Blockscout', () => {
it('success', async () => {
const mockResponse = {
status: 200,
statusText: 'OK',
headers: {},
config: {} as any,
data:
{
items: [
{
token: {
address: '0xF57e7e7C23978C3cAEC3C3548E3D615c346e79fF',
address_hash: '0xF57e7e7C23978C3cAEC3C3548E3D615c346e79fF',
circulating_market_cap: '639486814.4877648',
decimals: '18',
exchange_rate: '0.568914',
holders: '71451',
holders_count: '71451',
icon_url: 'https://assets.coingecko.com',
name: 'Immutable X',
symbol: 'IMX',
Expand All @@ -62,11 +66,11 @@ describe('Blockscout', () => {
},
{
token: {
address: '',
address_hash: '',
circulating_market_cap: '639486814.4877648',
decimals: '18',
exchange_rate: '0.568914',
holders: '71451',
holders_count: '71451',
icon_url: 'https://assets.coingecko.com',
name: 'Immutable X',
symbol: 'IMX',
Expand All @@ -80,7 +84,7 @@ describe('Blockscout', () => {
],
next_page_params: null,
},
} as AxiosResponse;
} as AxiosResponse<BlockscoutERC20Response>;
mockedHttpClient.get.mockResolvedValueOnce(mockResponse);

const token = BlockscoutTokenType.ERC20;
Expand Down
34 changes: 23 additions & 11 deletions packages/checkout/sdk/src/api/blockscout/blockscout.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import axios, {
AxiosError,
AxiosResponse,
HttpStatusCode,
} from 'axios';
import { ChainId } from '../../types';
import {
BlockscoutERC20Response,
BlockscoutERC20ResponseItem,
BlockscoutNativeTokenData,
BlockscoutToken,
BlockscoutTokenData,
BlockscoutTokenPagination,
BlockscoutTokens,
BlockscoutTokenType,
Expand Down Expand Up @@ -105,17 +109,25 @@ export class Blockscout {
const cached = this.getCache(url);
if (cached) return Promise.resolve(cached);

const response = await this.httpClient.get(url); // success if 2XX response otherwise throw error

// Normalize the data by ensuring address field is always present
// Map address_hash to address if address is not present
const normalizedItems = response.data?.items?.map((item: BlockscoutToken) => {
const normalizedToken = { ...item.token };
if (!normalizedToken.address && (normalizedToken as any).address_hash) {
normalizedToken.address = (normalizedToken as any).address_hash;
}
return { ...item, token: normalizedToken };
}) || [];
// success if 2XX response otherwise throw error
const response: AxiosResponse<BlockscoutERC20Response> = await this.httpClient.get(url);

// blockscout changed their API to return address_hash instead of address
// map the address_hash to address field so that any further consumer is not affected by the change
const normalizedItems: BlockscoutToken[] = response.data?.items?.map(
(item: BlockscoutERC20ResponseItem) => {
const token: BlockscoutTokenData = {
...item.token,
address: item.token.address_hash,
holders: item.token.holders_count,
};

return {
...item,
token,
};
},
) || [];

// To get around an issue with native tokens being an ERC-20, there is the need
// to remove IMX from `resp` and add it back in using getNativeTokenByWalletAddress.
Expand Down
24 changes: 24 additions & 0 deletions packages/checkout/sdk/src/api/blockscout/blockscoutType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,29 @@ export enum BlockscoutTokenType {
ERC20 = 'ERC-20',
}

export interface BlockscoutERC20Response {
items: BlockscoutERC20ResponseItem[]
next_page_params: BlockscoutTokenPagination | null
}

export interface BlockscoutERC20ResponseItem {
token: {
address_hash: string
decimals: string
name: string
symbol: string
holders_count: string
circulating_market_cap: string
exchange_rate: string
total_supply: string
icon_url: string;
type: BlockscoutTokenType
}
value: string
token_id: string | null
token_instance: string | null
}

export interface BlockscoutTokens {
items: BlockscoutToken[]
next_page_params: BlockscoutTokenPagination | null
Expand All @@ -24,6 +47,7 @@ export interface BlockscoutTokenData {
name: string
symbol: string
icon_url: string;
holders: string;
type: BlockscoutTokenType
}

Expand Down