Skip to content

Commit 5f7cde3

Browse files
authored
feat(api): Filter out unverified assets with unmatched decimals (#1774)
* feat(api): Filter out unverified assets with unmatched decimals * feat(api): Add warning events
1 parent eb7c074 commit 5f7cde3

File tree

4 files changed

+74
-3
lines changed

4 files changed

+74
-3
lines changed

src/assets/assets.service.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@ export class AssetsService {
3939
return record;
4040
}
4141

42+
async findByIdentifier(
43+
identifier: string,
44+
): Promise<AssetWithMetadata | null> {
45+
return this.prisma.asset.findUnique({
46+
where: { identifier },
47+
include: { verified_metadata: true },
48+
});
49+
}
50+
4251
async findByIdentifierOrThrow(
4352
identifier: string,
4453
): Promise<AssetWithMetadata> {

src/bridges/bridges.module.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,20 @@
44
import { HttpModule } from '@nestjs/axios';
55
import { Module } from '@nestjs/common';
66
import { ApiConfigModule } from '../api-config/api-config.module';
7+
import { AssetsModule } from '../assets/assets.module';
8+
import { DatadogModule } from '../datadog/datadog.module';
79
import { LoggerModule } from '../logger/logger.module';
810
import { ChainportService } from './chainport.service';
911

1012
@Module({
1113
exports: [ChainportService],
12-
imports: [ApiConfigModule, HttpModule, LoggerModule],
14+
imports: [
15+
ApiConfigModule,
16+
AssetsModule,
17+
DatadogModule,
18+
HttpModule,
19+
LoggerModule,
20+
],
1321
providers: [ChainportService],
1422
})
1523
export class BridgesModule {}

src/bridges/chainport.service.ts

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import Joi from 'joi';
1212
import { URL } from 'node:url';
1313
import { catchError, firstValueFrom } from 'rxjs';
1414
import { ApiConfigService } from '../api-config/api-config.service';
15+
import { AssetsService } from '../assets/assets.service';
16+
import { DatadogService } from '../datadog/datadog.service';
1517
import { LoggerService } from '../logger/logger.service';
1618

1719
export type ChainportNetwork = {
@@ -130,7 +132,9 @@ export type ChainportPort =
130132
@Injectable()
131133
export class ChainportService {
132134
constructor(
135+
private readonly assetsService: AssetsService,
133136
private readonly config: ApiConfigService,
137+
private readonly datadogService: DatadogService,
134138
private readonly httpService: HttpService,
135139
private readonly logger: LoggerService,
136140
) {}
@@ -220,7 +224,48 @@ export class ChainportService {
220224
`Invalid Chainport response: ${validateResult.error.message}`,
221225
);
222226
}
223-
return validateResult.value;
227+
228+
const verifiedTokens = [];
229+
230+
const chainportTokens = validateResult.value;
231+
for (const token of chainportTokens) {
232+
const asset = await this.assetsService.findByIdentifier(
233+
token.web3_address,
234+
);
235+
if (!asset) {
236+
this.datadogService.event(
237+
'Mismatched asset',
238+
`Could not find asset ${token.web3_address}`,
239+
{ alert_type: 'error' },
240+
);
241+
continue;
242+
}
243+
244+
if (!asset.verified_metadata) {
245+
this.datadogService.event(
246+
'Unverified asset',
247+
`Asset ${asset.identifier} is unverified`,
248+
{ alert_type: 'warning' },
249+
);
250+
continue;
251+
}
252+
253+
if (asset.verified_metadata.decimals !== token.decimals) {
254+
const message = `${asset.identifier}
255+
Iron Fish: ${asset.verified_metadata.decimals ?? 'null'}
256+
Chainport: ${token.decimals}`;
257+
this.datadogService.event(
258+
'Mismatched verified asset decimals',
259+
message,
260+
{ alert_type: 'warning' },
261+
);
262+
continue;
263+
}
264+
265+
verifiedTokens.push(token);
266+
}
267+
268+
return verifiedTokens;
224269
}
225270

226271
async getTokenPaths(tokenId: number): Promise<ChainportNetwork[]> {

src/datadog/datadog.service.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
44
import { Injectable, OnModuleDestroy } from '@nestjs/common';
5-
import { StatsD, Tags } from 'hot-shots';
5+
import { EventOptions, StatsD, Tags } from 'hot-shots';
66
import { ApiConfigService } from '../api-config/api-config.service';
77

88
const DEFAULT_PORT = 8125;
@@ -31,6 +31,15 @@ export class DatadogService implements OnModuleDestroy {
3131
this.datadogClient.increment(stat, value, tags);
3232
}
3333

34+
event(
35+
title: string,
36+
text?: string,
37+
options?: EventOptions,
38+
tags?: Tags,
39+
): void {
40+
this.datadogClient.event(title, text, options, tags);
41+
}
42+
3443
onModuleDestroy(): void {
3544
this.datadogClient.close();
3645
}

0 commit comments

Comments
 (0)