Skip to content

Commit

Permalink
Merge pull request #1479 from multiversx/SERVICES-2592-portfolio-quer…
Browse files Browse the repository at this point in the history
…ies-cache-improvements

[SERVICES-2592] Portfolio queries cache improvements
  • Loading branch information
mad2sm0key authored Nov 6, 2024
2 parents 32441a6 + 0149378 commit cefd568
Show file tree
Hide file tree
Showing 22 changed files with 306 additions and 123 deletions.
11 changes: 11 additions & 0 deletions src/modules/farm/base-module/services/farm.abi.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { Constants } from '@multiversx/sdk-nestjs-common';
import { MXApiService } from 'src/services/multiversx-communication/mx.api.service';
import { IFarmAbiService } from './interfaces';
import { CacheService } from '@multiversx/sdk-nestjs-cache';
import { getAllKeys } from 'src/utils/get.many.utils';

export class FarmAbiService
extends GenericAbiService
Expand Down Expand Up @@ -69,6 +70,16 @@ export class FarmAbiService
return response.firstValue.valueOf().toString();
}

async getAllFarmTokenIds(farmAddresses: string[]): Promise<string[]> {
return await getAllKeys<string>(
this.cacheService,
farmAddresses,
'farm.farmTokenID',
this.farmTokenID.bind(this),
CacheTtlInfo.Token,
);
}

@ErrorLoggerAsync({
logArgs: true,
})
Expand Down
6 changes: 1 addition & 5 deletions src/modules/farm/base-module/services/farm.base.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,8 @@ export abstract class FarmServiceBase {
}

async getAllFarmTokens(farmAddresses: string[]): Promise<NftCollection[]> {
const farmTokenIDs = await getAllKeys<string>(
this.cachingService,
const farmTokenIDs = await this.farmAbi.getAllFarmTokenIds(
farmAddresses,
'farm.farmTokenID',
this.farmAbi.farmTokenID.bind(this.farmAbi),
CacheTtlInfo.Token,
);
return this.tokenService.getAllNftsCollectionMetadata(farmTokenIDs);
}
Expand Down
3 changes: 3 additions & 0 deletions src/modules/farm/farm.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { FarmTransactionFactory } from './farm.transaction.factory';
import { FarmComputeFactory } from './farm.compute.factory';
import { FarmAbiFactory } from './farm.abi.factory';
import { FarmSetterFactory } from './farm.setter.factory';
import { FarmAbiService } from './base-module/services/farm.abi.service';

@Module({
imports: [
Expand All @@ -37,12 +38,14 @@ import { FarmSetterFactory } from './farm.setter.factory';
FarmTransactionFactory,
FarmQueryResolver,
FarmTransactionResolver,
FarmAbiService,
],
exports: [
FarmFactoryService,
FarmAbiFactory,
FarmSetterFactory,
FarmComputeFactory,
FarmAbiService,
],
})
export class FarmModule {}
5 changes: 5 additions & 0 deletions src/modules/farm/mocks/farm.abi.service.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ export class FarmAbiServiceMock implements IFarmAbiService {
async farmTokenID(farmAddress: string): Promise<string> {
return farms.find((f) => f.address === farmAddress).farmTokenID;
}
async getAllFarmTokenIds(farmsAddresses: string[]): Promise<string[]> {
return farms
.filter((farm) => farmsAddresses.includes(farm.address))
.map((farm) => farm.farmTokenID);
}
async farmingTokenID(farmAddress: string): Promise<string> {
return farms.find((f) => f.address === farmAddress).farmingTokenID;
}
Expand Down
5 changes: 5 additions & 0 deletions src/modules/pair/mocks/pair.abi.service.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ export class PairAbiServiceMock implements IPairAbiService {
async pairInfoMetadata(pairAddress: string): Promise<PairInfoModel> {
return PairsData(pairAddress).info;
}
async getAllPairsInfoMetadata(
pairAddresses: string[],
): Promise<PairInfoModel[]> {
return pairAddresses.map((pairAddress) => PairsData(pairAddress).info);
}
async totalFeePercent(pairAddress: string): Promise<number> {
return PairsData(pairAddress).totalFeePercent;
}
Expand Down
14 changes: 14 additions & 0 deletions src/modules/pair/mocks/pair.compute.service.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,20 @@ export class PairComputeServiceMock implements IPairComputeService {
async secondTokenPriceUSD(pairAddress: string): Promise<string> {
return PairsData(pairAddress).secondTokenPriceUSD;
}
async getAllFirstTokensPriceUSD(
pairAddresses: string[],
): Promise<string[]> {
return pairAddresses.map(
(pairAddress) => PairsData(pairAddress).firstTokenPriceUSD,
);
}
async getAllSecondTokensPricesUSD(
pairAddresses: string[],
): Promise<string[]> {
return pairAddresses.map(
(pairAddress) => PairsData(pairAddress).secondTokenPriceUSD,
);
}
async firstTokenLockedValueUSD(pairAddress: string): Promise<string> {
return PairsData(pairAddress).firstTokenLockedValueUSD;
}
Expand Down
8 changes: 1 addition & 7 deletions src/modules/pair/services/pair.abi.loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,7 @@ export class PairAbiLoader {

public readonly infoMetadataLoader = new DataLoader<string, PairInfoModel>(
async (addresses: string[]) => {
return getAllKeys<PairInfoModel>(
this.cacheService,
addresses,
'pair.pairInfoMetadata',
this.pairAbi.pairInfoMetadata.bind(this.pairAbi),
CacheTtlInfo.ContractBalance,
);
return this.pairAbi.getAllPairsInfoMetadata(addresses);
},
{
cache: false,
Expand Down
13 changes: 13 additions & 0 deletions src/modules/pair/services/pair.abi.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { CacheTtlInfo } from 'src/services/caching/cache.ttl.info';
import { Constants } from '@multiversx/sdk-nestjs-common';
import { CacheService } from '@multiversx/sdk-nestjs-cache';
import { IPairAbiService } from '../interfaces';
import { getAllKeys } from 'src/utils/get.many.utils';

@Injectable()
export class PairAbiService
Expand Down Expand Up @@ -204,6 +205,18 @@ export class PairAbiService
});
}

async getAllPairsInfoMetadata(
pairAddresses: string[],
): Promise<PairInfoModel[]> {
return await getAllKeys<PairInfoModel>(
this.cachingService,
pairAddresses,
'pair.pairInfoMetadata',
this.pairInfoMetadata.bind(this),
CacheTtlInfo.ContractBalance,
);
}

@ErrorLoggerAsync({
logArgs: true,
})
Expand Down
14 changes: 2 additions & 12 deletions src/modules/pair/services/pair.compute.loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,7 @@ export class PairComputeLoader {

public readonly firstTokenPriceUSDLoader = new DataLoader<string, string>(
async (addresses: string[]) => {
return await getAllKeys(
this.cacheService,
addresses,
'pair.firstTokenPriceUSD',
this.pairCompute.firstTokenPriceUSD.bind(this.pairCompute),
CacheTtlInfo.Price,
);
return await this.pairCompute.getAllFirstTokensPriceUSD(addresses);
},
{
cache: false,
Expand All @@ -63,12 +57,8 @@ export class PairComputeLoader {

public readonly secondTokenPriceUSDLoader = new DataLoader<string, string>(
async (addresses: string[]) => {
return await getAllKeys(
this.cacheService,
return await this.pairCompute.getAllSecondTokensPricesUSD(
addresses,
'pair.secondTokenPriceUSD',
this.pairCompute.secondTokenPriceUSD.bind(this.pairCompute),
CacheTtlInfo.Price,
);
},
{
Expand Down
24 changes: 24 additions & 0 deletions src/modules/pair/services/pair.compute.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,18 @@ export class PairComputeService implements IPairComputeService {
);
}

async getAllFirstTokensPriceUSD(
pairAddresses: string[],
): Promise<string[]> {
return await getAllKeys<string>(
this.cachingService,
pairAddresses,
'pair.firstTokenPriceUSD',
this.firstTokenPriceUSD.bind(this),
CacheTtlInfo.Price,
);
}

@ErrorLoggerAsync({
logArgs: true,
})
Expand Down Expand Up @@ -256,6 +268,18 @@ export class PairComputeService implements IPairComputeService {
);
}

async getAllSecondTokensPricesUSD(
pairAddresses: string[],
): Promise<string[]> {
return await getAllKeys<string>(
this.cachingService,
pairAddresses,
'pair.secondTokenPriceUSD',
this.secondTokenPriceUSD.bind(this),
CacheTtlInfo.Price,
);
}

@ErrorLoggerAsync({
logArgs: true,
})
Expand Down
59 changes: 55 additions & 4 deletions src/modules/pair/services/pair.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { RouterAbiService } from 'src/modules/router/services/router.abi.service
import { TokenService } from 'src/modules/tokens/services/token.service';
import { getAllKeys } from 'src/utils/get.many.utils';
import { CacheTtlInfo } from 'src/services/caching/cache.ttl.info';
import { PairInfoModel } from '../models/pair-info.model';

@Injectable()
export class PairService {
Expand Down Expand Up @@ -281,6 +282,13 @@ export class PairService {
): Promise<LiquidityPosition> {
const pairInfo = await this.pairAbi.pairInfoMetadata(pairAddress);

return this.computeLiquidityPosition(pairInfo, amount);
}

private computeLiquidityPosition(
pairInfo: PairInfoModel,
amount: string,
): LiquidityPosition {
const firstTokenAmount = getTokenForGivenPosition(
amount,
pairInfo.reserves0,
Expand All @@ -298,6 +306,19 @@ export class PairService {
});
}

async getAllLiquidityPositions(
pairAddresses: string[],
amounts: string[],
): Promise<LiquidityPosition[]> {
const allPairsInfo = await this.pairAbi.getAllPairsInfoMetadata(
pairAddresses,
);

return allPairsInfo.map((pairInfo, index) =>
this.computeLiquidityPosition(pairInfo, amounts[index]),
);
}

async getLiquidityPositionUSD(
pairAddress: string,
amount: string,
Expand Down Expand Up @@ -330,6 +351,38 @@ export class PairService {
.toFixed();
}

async getAllLiquidityPositionsUSD(
pairAddresses: string[],
amounts: string[],
): Promise<string[]> {
const allFirstTokens = await this.getAllFirstTokens(pairAddresses);
const allSecondTokens = await this.getAllSecondTokens(pairAddresses);
const allFirstTokensPriceUSD =
await this.pairCompute.getAllFirstTokensPriceUSD(pairAddresses);
const allSecondTokensPriceUSD =
await this.pairCompute.getAllSecondTokensPricesUSD(pairAddresses);
const allLiquidityPositions = await this.getAllLiquidityPositions(
pairAddresses,
amounts,
);

return pairAddresses.map((_, index) => {
return computeValueUSD(
allLiquidityPositions[index].firstTokenAmount,
allFirstTokens[index].decimals,
allFirstTokensPriceUSD[index],
)
.plus(
computeValueUSD(
allLiquidityPositions[index].secondTokenAmount,
allSecondTokens[index].decimals,
allSecondTokensPriceUSD[index],
),
)
.toFixed();
});
}

async getPairAddressByLpTokenID(tokenID: string): Promise<string | null> {
const cachedValue: string = await this.cachingService.get(
`${tokenID}.pairAddress`,
Expand All @@ -338,10 +391,8 @@ export class PairService {
return cachedValue;
}
const pairsAddress = await this.routerAbi.pairsAddress();
const promises = pairsAddress.map(async (pairAddress) =>
this.pairAbi.lpTokenID(pairAddress),
);
const lpTokenIDs = await Promise.all(promises);
const lpTokenIDs = await this.getAllLpTokensIds(pairsAddress);

let returnedData = null;
for (let index = 0; index < lpTokenIDs.length; index++) {
if (lpTokenIDs[index] === tokenID) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,18 @@ import { ErrorLoggerAsync } from '@multiversx/sdk-nestjs-common';
import { GetOrSetCache } from 'src/helpers/decorators/caching.decorator';
import { CacheTtlInfo } from 'src/services/caching/cache.ttl.info';
import { IPriceDiscoveryAbiService } from './interfaces';
import { CacheService } from '@multiversx/sdk-nestjs-cache';
import { getAllKeys } from 'src/utils/get.many.utils';

@Injectable()
export class PriceDiscoveryAbiService
extends GenericAbiService
implements IPriceDiscoveryAbiService
{
constructor(protected readonly mxProxy: MXProxyService) {
constructor(
protected readonly mxProxy: MXProxyService,
private readonly cachingService: CacheService,
) {
super(mxProxy);
}

Expand Down Expand Up @@ -93,6 +98,18 @@ export class PriceDiscoveryAbiService
return response.firstValue.valueOf().toString();
}

async getAllRedeemTokenIds(
priceDiscoveryAddresses: string[],
): Promise<string[]> {
return await getAllKeys<string>(
this.cachingService,
priceDiscoveryAddresses,
'priceDiscovery.redeemTokenID',
this.redeemTokenID.bind(this),
CacheTtlInfo.Token,
);
}

@ErrorLoggerAsync({
logArgs: true,
})
Expand Down
19 changes: 18 additions & 1 deletion src/modules/staking-proxy/services/staking.proxy.abi.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,18 @@ import { GetOrSetCache } from 'src/helpers/decorators/caching.decorator';
import { CacheTtlInfo } from 'src/services/caching/cache.ttl.info';
import { Constants } from '@multiversx/sdk-nestjs-common';
import { IStakingProxyAbiService } from './interfaces';
import { CacheService } from '@multiversx/sdk-nestjs-cache';
import { getAllKeys } from 'src/utils/get.many.utils';

@Injectable()
export class StakingProxyAbiService
extends GenericAbiService
implements IStakingProxyAbiService
{
constructor(protected readonly mxProxy: MXProxyService) {
constructor(
protected readonly mxProxy: MXProxyService,
private readonly cachingService: CacheService,
) {
super(mxProxy);
}

Expand Down Expand Up @@ -147,6 +152,18 @@ export class StakingProxyAbiService
return response.firstValue.valueOf().toString();
}

async getAllDualYieldTokenIds(
stakingProxyAddresses: string[],
): Promise<string[]> {
return await getAllKeys<string>(
this.cachingService,
stakingProxyAddresses,
'stakeProxy.dualYieldTokenID',
this.dualYieldTokenID.bind(this),
CacheTtlInfo.Token,
);
}

@ErrorLoggerAsync({
logArgs: true,
})
Expand Down
Loading

0 comments on commit cefd568

Please sign in to comment.