Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SERVICES-2427] Search by token (ID/ticker/name) for pairs and tokens queries #1362

Merged
merged 5 commits into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
17 changes: 17 additions & 0 deletions src/modules/pair/mocks/pair.service.mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { EsdtToken } from 'src/modules/tokens/models/esdtToken.model';
import { PairsData } from './pair.constants';
import { PairService } from '../services/pair.service';

export class PairServiceMock {
async getFirstToken(pairAddress: string): Promise<EsdtToken> {
return PairsData(pairAddress).firstToken;
}
async getSecondToken(pairAddress: string): Promise<EsdtToken> {
return PairsData(pairAddress).secondToken;
}
}

export const PairServiceProvider = {
provide: PairService,
useClass: PairServiceMock,
};
43 changes: 43 additions & 0 deletions src/modules/pair/services/pair.filtering.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ import {
PairsFilter,
} from 'src/modules/router/models/filter.args';
import BigNumber from 'bignumber.js';
import { PairService } from './pair.service';

@Injectable()
export class PairFilteringService {
constructor(
private readonly pairAbi: PairAbiService,
private readonly pairCompute: PairComputeService,
private readonly pairService: PairService,
) {}

async pairsByIssuedLpToken(
Expand Down Expand Up @@ -82,6 +84,47 @@ export class PairFilteringService {
return await Promise.resolve(pairsMetadata);
}

async pairsByWildcardToken(
pairFilter: PairsFilter,
pairsMetadata: PairMetadata[],
): Promise<PairMetadata[]> {
if (!pairFilter.searchToken || pairFilter.searchToken.trim() === '') {
return pairsMetadata;
}

const searchTerm = pairFilter.searchToken.toUpperCase().trim();

const pairsFirstToken = await Promise.all(
pairsMetadata.map((pairMetadata) =>
this.pairService.getFirstToken(pairMetadata.address),
),
);
const pairsSecondToken = await Promise.all(
pairsMetadata.map((pairMetadata) =>
this.pairService.getSecondToken(pairMetadata.address),
),
);

const filteredPairs: PairMetadata[] = [];
for (const [index, pair] of pairsMetadata.entries()) {
const firstToken = pairsFirstToken[index];
const secondToken = pairsSecondToken[index];

if (
firstToken.name.toUpperCase().includes(searchTerm) ||
firstToken.identifier.toUpperCase().includes(searchTerm) ||
firstToken.ticker.toUpperCase().includes(searchTerm) ||
secondToken.name.toUpperCase().includes(searchTerm) ||
secondToken.identifier.toUpperCase().includes(searchTerm) ||
secondToken.ticker.toUpperCase().includes(searchTerm)
) {
filteredPairs.push(pair);
}
}

return filteredPairs;
}

async pairsByState(
pairFilter: PairFilterArgs | PairsFilter,
pairsMetadata: PairMetadata[],
Expand Down
8 changes: 8 additions & 0 deletions src/modules/pair/services/pair.metadata.builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ export class PairsMetadataBuilder {
}

async filterByTokens(): Promise<PairsMetadataBuilder> {
if (this.filters.searchToken) {
this.pairsMetadata =
await this.filteringService.pairsByWildcardToken(
this.filters,
this.pairsMetadata,
);
}

this.pairsMetadata = await this.filteringService.pairsByTokens(
this.filters,
this.pairsMetadata,
Expand Down
2 changes: 2 additions & 0 deletions src/modules/router/models/filter.args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ export class PairsFilter {
hasDualFarms: boolean;
@Field({ nullable: true })
minDeployedAt: number;
@Field({ nullable: true })
searchToken: string;
}

@InputType()
Expand Down
2 changes: 2 additions & 0 deletions src/modules/router/specs/router.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import winston from 'winston';
import { DynamicModuleUtils } from 'src/utils/dynamic.module.utils';
import { PairComputeServiceProvider } from 'src/modules/pair/mocks/pair.compute.service.mock';
import { PairFilteringService } from 'src/modules/pair/services/pair.filtering.service';
import { PairServiceProvider } from 'src/modules/pair/mocks/pair.service.mock';

describe('RouterService', () => {
let module: TestingModule;
Expand All @@ -32,6 +33,7 @@ describe('RouterService', () => {
RouterService,
ApiConfigService,
PairFilteringService,
PairServiceProvider,
],
}).compile();
});
Expand Down
2 changes: 2 additions & 0 deletions src/modules/tokens/models/tokens.filter.args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ export class TokensFilter {
type?: string;
@Field(() => Boolean, { defaultValue: false })
enabledSwaps: boolean;
@Field({ nullable: true })
searchToken?: string;
}

@InputType()
Expand Down
28 changes: 28 additions & 0 deletions src/modules/tokens/services/token.filtering.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Inject, Injectable, forwardRef } from '@nestjs/common';
import { TokenService } from './token.service';
import { TokensFilter } from '../models/tokens.filter.args';
import { EsdtToken } from '../models/esdtToken.model';

@Injectable()
export class TokenFilteringService {
Expand Down Expand Up @@ -43,4 +44,31 @@ export class TokenFilteringService {
}
return filteredIDs;
}

async tokensBySearchTerm(
tokensFilter: TokensFilter,
tokens: EsdtToken[],
): Promise<EsdtToken[]> {
if (
!tokensFilter.searchToken ||
tokensFilter.searchToken.trim() === ''
) {
return tokens;
}

const searchTerm = tokensFilter.searchToken.toUpperCase().trim();

const filteredTokens: EsdtToken[] = [];
for (const token of tokens) {
if (
token.name.toUpperCase().includes(searchTerm) ||
token.identifier.toUpperCase().includes(searchTerm) ||
token.ticker.toUpperCase().includes(searchTerm)
) {
filteredTokens.push(token);
}
}

return filteredTokens;
}
}
13 changes: 9 additions & 4 deletions src/modules/tokens/services/token.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,19 @@ export class TokenService {
tokenIDs,
);

let tokens = await Promise.all(
tokenIDs.map((tokenID) => this.getTokenMetadata(tokenID)),
);

tokens = await this.tokenFilteringService.tokensBySearchTerm(
filters,
tokens,
);

if (sorting) {
tokenIDs = await this.sortTokens(tokenIDs, sorting);
}

const tokens = await Promise.all(
tokenIDs.map((tokenID) => this.getTokenMetadata(tokenID)),
);

return new CollectionType({
count: tokens.length,
items: tokens.slice(
Expand Down
Loading