Skip to content

Commit

Permalink
[Point System] add support for versions (sora-xor#1593)
Browse files Browse the repository at this point in the history
* point systems query

* update v2 component
  • Loading branch information
Nikita-Polyakov authored Nov 8, 2024
1 parent af1b9b5 commit 1a30331
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 52 deletions.
133 changes: 115 additions & 18 deletions src/indexer/queries/pointSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { getCurrentIndexer, WALLET_CONSTS } from '@soramitsu/soraneo-wallet-web'
import { SubqueryIndexer, SubsquidIndexer } from '@soramitsu/soraneo-wallet-web/lib/services/indexer';
import { gql } from '@urql/core';

import { AccountPointSystems, AccountPointsVersioned, AccountPointsCalculation } from '@/types/pointSystem';

import type {
QueryData,
ConnectionQueryResponse,
Expand Down Expand Up @@ -261,6 +263,21 @@ type AccountMetaEntity = {
deposit: AccountMetaDeposit;
};

type AccountPointSystemEntity = {
id: string;
accountId: string;
version: number;
startedAtBlock: number;
// points
xorFees: AccountMetaAssetVolume;
xorBurned: AccountMetaAssetVolume;
xorStakingValRewards: AccountMetaAssetVolume;
orderBook: AccountMetaEventCounter;
vault: AccountMetaEventCounter;
governance: AccountMetaGovernance;
deposit: AccountMetaDeposit;
};

const SubqueryAccountMetaQuery = gql<QueryData<AccountMetaEntity>>`
query AccountMetaQuery($id: String = "") {
data: accountMeta(id: $id) {
Expand All @@ -277,6 +294,32 @@ const SubqueryAccountMetaQuery = gql<QueryData<AccountMetaEntity>>`
}
`;

const SubqueryAccountPointSystemsQuery = gql<ConnectionQueryResponse<AccountPointSystemEntity>>`
query AccountPointSystemsQuery($id: String = "", $after: Cursor) {
data: accountPointSystems(orderBy: ID_ASC, after: $after, filter: { accountId: { equalTo: $id } }) {
pageInfo {
hasNextPage
endCursor
}
edges {
node {
id
accountId
version
startedAtBlock
xorFees
xorBurned
xorStakingValRewards
orderBook
vault
governance
deposit
}
}
}
}
`;

const parseVolume = (data: AccountMetaAssetVolume | AccountMetaGovernance) => {
return {
amount: new FPNumber(data.amount),
Expand All @@ -292,24 +335,10 @@ const parseCounter = (data: AccountMetaEventCounter) => {
};
};

const parseAccountMeta = (item: QueryData<AccountMetaEntity>) => {
const {
createdAtTimestamp,
createdAtBlock,
xorFees,
xorBurned,
xorStakingValRewards,
orderBook,
vault,
governance,
deposit,
} = item.data;
const parseAccountPoints = (item: AccountMetaEntity | AccountPointSystemEntity): AccountPointsCalculation => {
const { xorFees, xorBurned, xorStakingValRewards, orderBook, vault, governance, deposit } = item;

return {
createdAt: {
block: Number(createdAtBlock),
timestamp: Number(createdAtTimestamp) * 1000,
},
fees: parseVolume(xorFees),
burned: parseVolume(xorBurned),
staking: parseVolume(xorStakingValRewards),
Expand All @@ -326,21 +355,89 @@ const parseAccountMeta = (item: QueryData<AccountMetaEntity>) => {
};
};

export async function fetchAccountMeta(accountAddress: string) {
const parseAccountMeta = (item: AccountMetaEntity): AccountPointSystems => {
const { createdAtTimestamp, createdAtBlock } = item;
const startedAtBlock = Number(createdAtBlock);

return {
createdAt: {
block: startedAtBlock,
timestamp: Number(createdAtTimestamp) * 1000,
},
points: [
{
version: 1,
startedAtBlock,
...parseAccountPoints(item),
},
],
};
};

const parseAccountPointSystem = (item: AccountPointSystemEntity): AccountPointsVersioned => {
const { version, startedAtBlock } = item;

return {
version,
startedAtBlock,
...parseAccountPoints(item),
};
};

export async function fetchAccountMeta(accountAddress: string): Promise<AccountPointSystems | null> {
const indexer = getCurrentIndexer();
const variables = { id: accountAddress };

try {
if (indexer.type === IndexerType.SUBQUERY) {
const subqueryIndexer = indexer as SubqueryIndexer;
const response = await subqueryIndexer.services.explorer.request(SubqueryAccountMetaQuery, variables);

if (!response) return null;

return parseAccountMeta(response.data);
}

return null;
} catch (error) {
console.error(error);
return null;
}
}

export async function fetchAccountPointSystems(accountAddress: string): Promise<AccountPointsVersioned[] | null> {
const indexer = getCurrentIndexer();
const variables = { id: accountAddress };

try {
if (indexer.type === IndexerType.SUBQUERY) {
const subqueryIndexer = indexer as SubqueryIndexer;
const response = await subqueryIndexer.services.explorer.fetchAllEntities(
SubqueryAccountPointSystemsQuery,
variables,
parseAccountPointSystem
);

if (!response) return null;

return parseAccountMeta(response);
return response;
}

return null;
} catch (error) {
console.error(error);
return null;
}
}

export async function fetchAccountPoints(accountAddress: string): Promise<AccountPointSystems | null> {
const meta = await fetchAccountMeta(accountAddress);
const points = await fetchAccountPointSystems(accountAddress);

if (!meta) return null;

return {
createdAt: meta.createdAt,
points: Array.isArray(points) ? points : meta.points,
};
}
14 changes: 13 additions & 1 deletion src/types/pointSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,17 @@ export interface AccountPointsCalculation {
incomingUSD: FPNumber;
outgoingUSD: FPNumber;
};
createdAt: { timestamp: number; block: number };
}

export interface AccountPointsVersioned extends AccountPointsCalculation {
version: number;
startedAtBlock: number;
}

export interface AccountPointSystems {
createdAt: {
timestamp: number;
block: number;
};
points: AccountPointsVersioned[];
}
4 changes: 2 additions & 2 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -357,8 +357,8 @@ export const formatAmountWithSuffix = (value: FPNumber, precision = 2): AmountWi
};
};

export const convertFPNumberToNumber = (fpValue: FPNumber, precision = 2): number => {
return parseFloat(fpValue.toFixed(precision));
export const convertFPNumberToNumber = (fpValue: Nullable<FPNumber>, precision = 2): number => {
return parseFloat((fpValue ?? FPNumber.ZERO).toFixed(precision));
};

export const formatDecimalPlaces = (value: FPNumber | number, asPercent = false): string => {
Expand Down
8 changes: 8 additions & 0 deletions src/utils/pointSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ class PointsService {
};
}

public getEraCoefficient(era: number): number {
if (era === 1) {
return 0.5;
}

return 1;
}

public calculateCategoryPoints(categoryValues: CategoryValues): { [key: string]: CalculateCategoryPointResult } {
const results: { [key: string]: CalculateCategoryPointResult } = {};
const firstTxAccountResult: { [key: string]: CalculateCategoryPointResult } = {};
Expand Down
76 changes: 45 additions & 31 deletions src/views/PointSystemV2.vue
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ import { fetchAccountMeta } from '@/indexer/queries/pointSystem';
import type { ReferrerRewards } from '@/indexer/queries/referrals';
import { lazyComponent } from '@/router';
import { action, getter, state } from '@/store/decorators';
import { AccountPointsCalculation, CalculateCategoryPointResult, CategoryPoints } from '@/types/pointSystem';
import { AccountPointSystems, CalculateCategoryPointResult, CategoryPoints } from '@/types/pointSystem';
import { convertFPNumberToNumber } from '@/utils';
import { pointsService } from '@/utils/pointSystem';
Expand All @@ -124,7 +124,6 @@ export default class PointSystemV2 extends Mixins(
readonly LogoSize = WALLET_CONSTS.LogoSize;
@state.referrals.referralRewards private referralRewards!: Nullable<ReferrerRewards>;
@state.wallet.settings.blockNumber private blockNumber!: number;
@state.wallet.account.accountAssets private accountAssets!: Array<AccountAsset>;
@state.pool.accountLiquidity private accountLiquidity!: Array<AccountLiquidity>;
Expand Down Expand Up @@ -179,41 +178,57 @@ export default class PointSystemV2 extends Mixins(
return fiatBalanceFloat;
}
getPointsForCategories(accountDataForPointsCalculation: AccountPointsCalculation): CategoryPoints {
private getPointsForCategories(pointSystems: AccountPointSystems): CategoryPoints {
const firstTxAccount = pointSystems.createdAt.timestamp ?? 0;
const liquidityProvision = this.getTotalLiquidityFiatValue();
const VXORHoldings = this.getCurrentFiatBalanceForToken(VXOR.symbol);
const referralRewards = convertFPNumberToNumber(this.referralRewards?.rewards ?? this.Zero);
const depositVolumeBridges =
convertFPNumberToNumber(accountDataForPointsCalculation?.bridge.incomingUSD ?? this.Zero) +
convertFPNumberToNumber(accountDataForPointsCalculation?.bridge.outgoingUSD ?? this.Zero);
const networkFeeSpent = convertFPNumberToNumber(accountDataForPointsCalculation?.fees.amountUSD ?? this.Zero);
const XORBurned = convertFPNumberToNumber(accountDataForPointsCalculation?.burned.amountUSD ?? this.Zero);
const XORHoldings = this.getCurrentFiatBalanceForToken(XOR.symbol);
const kensetsuVolumeRepaid = convertFPNumberToNumber(
accountDataForPointsCalculation?.kensetsu.amountUSD ?? this.Zero
);
const VXORHoldings = this.getCurrentFiatBalanceForToken(VXOR.symbol);
const KUSDHoldings = this.getCurrentFiatBalanceForToken(KUSD.symbol);
const orderbookVolume = convertFPNumberToNumber(accountDataForPointsCalculation?.orderBook.amountUSD ?? this.Zero);
const governanceLockedXOR = convertFPNumberToNumber(
accountDataForPointsCalculation?.governance.amountUSD ?? this.Zero
const referralRewards = convertFPNumberToNumber(this.referralRewards?.rewards);
const points = pointSystems.points.reduce(
(acc, era) => {
const eraCoefficient = pointsService.getEraCoefficient(era.version);
const depositVolumeBridges =
convertFPNumberToNumber(era.bridge.incomingUSD) + convertFPNumberToNumber(era.bridge.outgoingUSD);
const networkFeeSpent = convertFPNumberToNumber(era.fees.amountUSD);
const XORBurned = convertFPNumberToNumber(era.burned.amountUSD);
const kensetsuVolumeRepaid = convertFPNumberToNumber(era.kensetsu.amountUSD);
const orderbookVolume = convertFPNumberToNumber(era.orderBook.amountUSD);
const governanceLockedXOR = convertFPNumberToNumber(era.governance.amountUSD);
const nativeXorStaking = convertFPNumberToNumber(era.staking.amountUSD);
acc.depositVolumeBridges += depositVolumeBridges * eraCoefficient;
acc.networkFeeSpent += networkFeeSpent * eraCoefficient;
acc.XORBurned += XORBurned * eraCoefficient;
acc.kensetsuVolumeRepaid += kensetsuVolumeRepaid * eraCoefficient;
acc.orderbookVolume += orderbookVolume * eraCoefficient;
acc.governanceLockedXOR += governanceLockedXOR * eraCoefficient;
acc.nativeXorStaking += nativeXorStaking * eraCoefficient;
return acc;
},
{
depositVolumeBridges: 0,
networkFeeSpent: 0,
XORBurned: 0,
kensetsuVolumeRepaid: 0,
orderbookVolume: 0,
governanceLockedXOR: 0,
nativeXorStaking: 0,
}
);
const nativeXorStaking = convertFPNumberToNumber(accountDataForPointsCalculation?.staking.amountUSD ?? this.Zero);
const firstTxAccount = accountDataForPointsCalculation?.createdAt.timestamp ?? 0;
const pointsForCategories = {
firstTxAccount,
liquidityProvision,
VXORHoldings,
referralRewards,
depositVolumeBridges,
networkFeeSpent,
XORBurned,
XORHoldings,
governanceLockedXOR,
kensetsuVolumeRepaid,
orderbookVolume,
nativeXorStaking,
VXORHoldings,
KUSDHoldings,
firstTxAccount,
referralRewards,
...points,
};
return pointsForCategories;
}
Expand All @@ -222,11 +237,10 @@ export default class PointSystemV2 extends Mixins(
if (this.isLoggedIn) {
// Referral rewards
await this.getAccountReferralRewards();
const account = this.account.address;
const end = this.blockNumber;
if (!(account && end)) return;
const account = this.account.address;
const accountMeta = await fetchAccountMeta(account);
if (accountMeta) {
this.pointsForCards = pointsService.calculateCategoryPoints(this.getPointsForCategories(accountMeta));
}
Expand Down

0 comments on commit 1a30331

Please sign in to comment.