Skip to content

Commit 893e702

Browse files
committed
feat(api): Return token details in token paths
1 parent 7c801cb commit 893e702

File tree

2 files changed

+52
-67
lines changed

2 files changed

+52
-67
lines changed

src/bridges/chainport.service.spec.ts

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -91,23 +91,7 @@ describe.skip('ChainportService', () => {
9191
});
9292

9393
describe('getTokenPaths', () => {
94-
it('works with v1', async () => {
95-
const originalGet = config.get.bind(config);
96-
jest.spyOn(config, 'get').mockImplementation((val) => {
97-
if (val === 'CHAINPORT_API_VERSION') {
98-
return 1;
99-
}
100-
if (val === 'CHAINPORT_API_URL') {
101-
return 'https://api.chainport.io/';
102-
}
103-
return originalGet(val);
104-
});
105-
const results = await chainport.getTokenPaths(2804);
106-
107-
expect(results.length).toBeGreaterThan(0);
108-
}, 10000);
109-
110-
it('works with v2', async () => {
94+
it('returns token paths', async () => {
11195
const originalGet = config.get.bind(config);
11296
jest.spyOn(config, 'get').mockImplementation((val) => {
11397
if (val === 'CHAINPORT_API_VERSION') {

src/bridges/chainport.service.ts

Lines changed: 51 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { HttpService } from '@nestjs/axios';
55
import {
66
BadGatewayException,
77
Injectable,
8-
NotFoundException,
98
} from '@nestjs/common';
109
import { AxiosError, AxiosResponse } from 'axios';
1110
import Joi from 'joi';
@@ -70,6 +69,34 @@ const chainportTokenSchema = Joi.object<ChainportToken>({
7069
is_lifi: Joi.boolean().required(),
7170
});
7271

72+
export type ChainportTokenWithNetwork = ChainportToken & ChainportNetwork;
73+
74+
const chainportTokenWithNetworkSchema = Joi.object<ChainportTokenWithNetwork>({
75+
// Network
76+
chainport_network_id: Joi.number().positive().integer().required(),
77+
explorer_url: Joi.string().required(),
78+
label: Joi.string().required(),
79+
network_icon: Joi.string().required(),
80+
// Token
81+
id: Joi.number().required(),
82+
decimals: Joi.number().required(),
83+
name: Joi.string().required(),
84+
pinned: Joi.boolean().required(),
85+
web3_address: Joi.string().required(),
86+
symbol: Joi.string().required(),
87+
token_image: Joi.string().required(),
88+
chain_id: Joi.number().allow(null).required(),
89+
network_name: Joi.string().required(),
90+
network_id: Joi.number().required(),
91+
blockchain_type: Joi.string().required(),
92+
is_stable: Joi.boolean().required(),
93+
is_lifi: Joi.boolean().required(),
94+
});
95+
96+
const chainportTokenWithNetworkArraySchema = Joi.array<
97+
ChainportTokenWithNetwork[]
98+
>().items(chainportTokenWithNetworkSchema);
99+
73100
const chainportTokenArraySchema =
74101
Joi.array<ChainportToken[]>().items(chainportTokenSchema);
75102

@@ -269,63 +296,37 @@ Chainport: ${token.decimals}`;
269296
return verifiedTokens;
270297
}
271298

272-
async getTokenPaths(tokenId: number): Promise<ChainportNetwork[]> {
273-
const version = this.config.get<number>('CHAINPORT_API_VERSION');
299+
async getTokenPaths(tokenId: number): Promise<ChainportTokenWithNetwork[]> {
274300
const apiurl = this.config.get<string>('CHAINPORT_API_URL');
275301

276-
const metaResult = await this.getMeta();
302+
const tokenPathUrl = new URL(`/token/paths`, apiurl);
303+
tokenPathUrl.searchParams.append('token_id', tokenId.toString());
277304

278-
let networkList: { label: string }[] = [];
279-
if (version === 1) {
280-
const tokenListUrl = new URL(`/token/list`, apiurl);
281-
tokenListUrl.searchParams.append('network_name', 'IRONFISH');
282-
283-
const tokenListResult = await this.makeChainportRequest<{
284-
verified_tokens: { id: number; target_networks: number[] }[];
285-
}>(tokenListUrl.toString());
286-
const sourceToken = tokenListResult.data.verified_tokens.find(
287-
(t) => t.id === tokenId,
288-
);
305+
const tokenPathResult = await this.makeChainportRequest<ChainportToken[]>(
306+
tokenPathUrl.toString(),
307+
);
308+
const metaResult = await this.getMeta();
289309

290-
if (!sourceToken) {
291-
throw new NotFoundException();
310+
const networkList: ChainportTokenWithNetwork[] = [];
311+
for (const token of tokenPathResult.data) {
312+
const network = metaResult.cp_network_ids[token.network_id.toString()];
313+
if (!network) {
314+
this.logger.error(
315+
`Network ${token.network_id} for token ${tokenId} not found in meta`,
316+
new Error().stack ?? '',
317+
);
318+
continue;
292319
}
293320

294-
networkList = sourceToken.target_networks.flatMap((n) => {
295-
const network = metaResult.cp_network_ids[n.toString()];
296-
if (!network) {
297-
this.logger.error(
298-
`Network ${n} for token ${tokenId} not found in meta`,
299-
new Error().stack ?? '',
300-
);
301-
return [];
302-
}
303-
return [network];
304-
});
305-
} else {
306-
const tokenPathUrl = new URL(`/token/paths`, apiurl);
307-
308-
tokenPathUrl.searchParams.append('token_id', tokenId.toString());
309-
const tokenPathResult = await this.makeChainportRequest<ChainportToken[]>(
310-
tokenPathUrl.toString(),
311-
);
312-
313-
networkList = tokenPathResult.data.flatMap((t) => {
314-
const network = metaResult.cp_network_ids[t.network_id.toString()];
315-
if (!network) {
316-
this.logger.error(
317-
`Network ${t.network_id} for token ${tokenId} not found in meta`,
318-
new Error().stack ?? '',
319-
);
320-
return [];
321-
}
322-
return [network];
323-
});
321+
networkList.push({ ...token, ...network });
324322
}
325323

326-
const validateResult = chainportNetworkArraySchema.validate(networkList, {
327-
stripUnknown: true,
328-
});
324+
const validateResult = chainportTokenWithNetworkArraySchema.validate(
325+
networkList,
326+
{
327+
stripUnknown: true,
328+
},
329+
);
329330

330331
if (validateResult.error) {
331332
throw new BadGatewayException(

0 commit comments

Comments
 (0)