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

[ MEX-662 ] Changed input and output token type to Esdt and fix action on TokenTradingActivity #1556

Merged
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
6 changes: 3 additions & 3 deletions src/modules/analytics/models/trading.activity.model.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Field, ObjectType, registerEnumType } from '@nestjs/graphql';
import { EsdtTokenPaymentModel } from 'src/modules/tokens/models/esdt.token.payment.model';
import { EsdtToken } from 'src/modules/tokens/models/esdtToken.model';

export enum TradingActivityAction {
'BUY' = 'BUY',
Expand All @@ -17,9 +17,9 @@ export class TradingActivityModel {
@Field()
action: TradingActivityAction;
@Field()
inputToken: EsdtTokenPaymentModel;
inputToken: EsdtToken;
@Field()
outputToken: EsdtTokenPaymentModel;
outputToken: EsdtToken;

constructor(init?: Partial<TradingActivityModel>) {
Object.assign(this, init);
Expand Down
122 changes: 78 additions & 44 deletions src/modules/analytics/services/analytics.compute.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ import {
import { SwapEvent } from '@multiversx/sdk-exchange';
import { convertEventTopicsAndDataToBase64 } from 'src/utils/elastic.search.utils';
import { ElasticSearchEventsService } from 'src/services/elastic-search/services/es.events.service';
import { RawElasticEventType } from 'src/services/elastic-search/entities/raw.elastic.event';
import { EsdtTokenPaymentModel } from 'src/modules/tokens/models/esdt.token.payment.model';
import { PairMetadata } from 'src/modules/router/models/pair.metadata.model';

@Injectable()
export class AnalyticsComputeService {
Expand Down Expand Up @@ -304,11 +303,11 @@ export class AnalyticsComputeService {
return await this.computeTokenTradingActivity(tokenID);
}

async determineBaseAndQuoteTokens(
private determineBaseAndQuoteTokens(
pairAddress: string,
): Promise<{ baseToken: string; quoteToken: string }> {
const pairsMetadata = await this.routerAbi.pairsMetadata();
const commonTokens = await this.routerAbi.commonTokensForUserPairs();
pairsMetadata: PairMetadata[],
commonTokens: string[],
): { baseToken: string; quoteToken: string } {
const sortedCommonTokens = commonTokens.sort((a, b) => {
const order = ['USD', 'EGLD'];
const indexA = order.findIndex((token) => a.includes(token));
Expand Down Expand Up @@ -346,37 +345,49 @@ export class AnalyticsComputeService {
const events = await this.elasticEventsService.getPairTradingEvents(
pairAddress,
);
const pairsMetadata = await this.routerAbi.pairsMetadata();
const commonTokens = await this.routerAbi.commonTokensForUserPairs();

const { quoteToken } = await this.determineBaseAndQuoteTokens(
const { quoteToken, baseToken } = this.determineBaseAndQuoteTokens(
pairAddress,
pairsMetadata,
commonTokens,
);

const tokens = await this.tokenService.getAllTokensMetadata([
quoteToken,
baseToken,
]);

for (const event of events) {
const eventConverted = convertEventTopicsAndDataToBase64(event);
const swapEvent = new SwapEvent(eventConverted);
const swapEvent = new SwapEvent(eventConverted).toJSON();

const tokenIn = swapEvent.getTokenIn();
const tokenOut = swapEvent.getTokenOut();
const tokenIn = swapEvent.tokenIn;
const tokenOut = swapEvent.tokenOut;
const action =
quoteToken === tokenOut.tokenID
? TradingActivityAction.BUY
: TradingActivityAction.SELL;

results.push({
hash: event.txHash,
inputToken: {
tokenIdentifier: tokenIn.tokenID,
amount: new BigNumber(tokenIn.amount).toFixed(),
tokenNonce: new BigNumber(tokenIn.nonce).toNumber(),
},
outputToken: {
tokenIdentifier: tokenOut.tokenID,
amount: new BigNumber(tokenOut.amount).toFixed(),
tokenNonce: new BigNumber(tokenOut.nonce).toNumber(),
},
timestamp: String(event.timestamp),
action,
});
const inputToken = tokens.find(
(token) => token.identifier === tokenIn.tokenID,
);
inputToken.balance = tokenIn.amount;
const outputToken = tokens.find(
(token) => token.identifier === tokenOut.tokenID,
);
outputToken.balance = tokenOut.amount;

results.push(
new TradingActivityModel({
hash: event.txHash,
inputToken: { ...inputToken },
outputToken: { ...outputToken },
timestamp: String(event.timestamp),
action,
}),
);
}

return results;
Expand All @@ -385,8 +396,9 @@ export class AnalyticsComputeService {
async computeTokenTradingActivity(
tokenID: string,
): Promise<TradingActivityModel[]> {
let filteredEvents: RawElasticEventType[] = [];
const pairsMetadata = await this.routerAbi.pairsMetadata();
const commonTokens = await this.routerAbi.commonTokensForUserPairs();
const pairsTokens = new Set<string>();

const pairsAddresses = pairsMetadata
.filter(
Expand All @@ -396,41 +408,63 @@ export class AnalyticsComputeService {
)
.map((pair) => pair.address);

filteredEvents = await this.elasticEventsService.getTokenTradingEvents(
tokenID,
pairsAddresses,
10,
);
let filteredEvents =
await this.elasticEventsService.getTokenTradingEvents(
tokenID,
pairsAddresses,
10,
);

filteredEvents = filteredEvents.slice(0, 10);

const matchedPairs = pairsMetadata.filter((pair) =>
filteredEvents.some((event) => event.address === pair.address),
);

matchedPairs.forEach((pair) => {
pairsTokens.add(pair.firstTokenID);
pairsTokens.add(pair.secondTokenID);
});

const tokens = await this.tokenService.getAllTokensMetadata(
Array.from(pairsTokens),
);

return filteredEvents.map((event) => {
const eventConverted = convertEventTopicsAndDataToBase64(event);
const swapEvent = new SwapEvent(eventConverted).toJSON();

const tokenIn = swapEvent.tokenIn;
const tokenOut = swapEvent.tokenOut;

const inputToken = tokens.find(
(token) => token.identifier === tokenIn.tokenID,
);

inputToken.balance = tokenIn.amount;
const outputToken = tokens.find(
(token) => token.identifier === tokenOut.tokenID,
);
outputToken.balance = tokenOut.amount;

const { quoteToken } = this.determineBaseAndQuoteTokens(
swapEvent.address,
pairsMetadata,
commonTokens,
);

const action =
tokenID === tokenOut.tokenID
quoteToken === tokenOut.tokenID
? TradingActivityAction.BUY
: TradingActivityAction.SELL;

return {
return new TradingActivityModel({
hash: event.txHash,
inputToken: new EsdtTokenPaymentModel({
tokenIdentifier: tokenIn.tokenID,
tokenNonce: tokenIn.nonce,
amount: tokenIn.amount,
}),
outputToken: new EsdtTokenPaymentModel({
tokenIdentifier: tokenOut.tokenID,
tokenNonce: tokenOut.nonce,
amount: tokenOut.amount,
}),
inputToken: { ...inputToken },
outputToken: { ...outputToken },
timestamp: String(event.timestamp),
action,
};
});
});
}
}
4 changes: 2 additions & 2 deletions src/services/crons/analytics.cache.warmer.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export class AnalyticsCacheWarmerService {
tradingActivity,
);

cachedKeys.push(...pairCachedKeys);
cachedKeys.push(pairCachedKeys);

tokenIDs.add(pair.firstTokenID);
tokenIDs.add(pair.secondTokenID);
Expand All @@ -78,7 +78,7 @@ export class AnalyticsCacheWarmerService {
tradingActivity,
);

cachedKeys.push(...tokenCachedKeys);
cachedKeys.push(tokenCachedKeys);
}

await this.deleteCacheKeys(cachedKeys);
Expand Down
Loading