Skip to content

Commit

Permalink
feat: Staking V3 Number of Participants (AstarNetwork#1159)
Browse files Browse the repository at this point in the history
* first hops

* getNumberOfParticipants in the store

* refactoring

* move it around

* Handle removal of unregistered dApps from a node storage (AstarNetwork#1155) (AstarNetwork#1161)

* Handle removal of unregistered dApps from a note storage

* Map dapp id

Co-authored-by: Bobo <bobo.kovacevic@gmail.com>

---------

Co-authored-by: Bobo <bobo.kovacevic@gmail.com>
  • Loading branch information
gluneau and bobo-k2 authored Feb 1, 2024
1 parent 40f3912 commit 876710a
Show file tree
Hide file tree
Showing 14 changed files with 95 additions and 9 deletions.
1 change: 1 addition & 0 deletions src/i18n/en-US/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -852,6 +852,7 @@ export default {
era: 'Era',
day: 'Day',
numberOfDapps: 'Number of dApps',
numberOfParticipants: 'Number of participants',
general: 'General',
totalValueLocked: 'Total Value Locked ({token})',
tvl: 'TVL',
Expand Down
12 changes: 10 additions & 2 deletions src/staking-v3/components/data/DataList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
<data-card :title="$t('stakingV3.era')" description="description">
{{ protocolState?.era }}
</data-card>
<data-card :title="$t('stakingV3.numberOfParticipants')" description="description">
{{ numberOfParticipants }}
</data-card>
</div>

<div class="row--title">{{ $t('stakingV3.tvl') }}</div>
Expand Down Expand Up @@ -80,8 +83,12 @@ export default defineComponent({
const { protocolState, currentEraInfo, dAppTiers, tiersConfiguration } = useDappStaking();
const { registeredDapps } = useDapps();
const { periodName, periodDuration, periodCurrentDay } = usePeriod();
const { tvlPercentage, totalVolumeOfVotesPercentage, bonusEligibleTokens } =
useDataCalculations();
const {
tvlPercentage,
totalVolumeOfVotesPercentage,
bonusEligibleTokens,
numberOfParticipants,
} = useDataCalculations();
const { activeInflationConfiguration } = useInflation();

const totalDapps = computed<number>(() => registeredDapps.value?.length ?? 0);
Expand Down Expand Up @@ -110,6 +117,7 @@ export default defineComponent({
totalVolumeOfVotesPercentage,
bonusEligibleTokens,
activeInflationConfiguration,
numberOfParticipants,
nativeTokenSymbol,
};
},
Expand Down
9 changes: 9 additions & 0 deletions src/staking-v3/hooks/useDapps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
DappState,
IDappStakingRepository,
IDappStakingService,
TokenApiProviderRepository,
} from '../logic';
import { Symbols } from 'src/v2/symbols';
import { useNetworkInfo } from 'src/hooks';
Expand All @@ -15,6 +16,9 @@ import { useStore } from 'src/store';
export function useDapps() {
const store = useStore();
const { currentNetworkName } = useNetworkInfo();
const tokenApiProviderRepository = container.get<TokenApiProviderRepository>(
Symbols.TokenApiProviderRepository
);

const registeredDapps = computed<CombinedDappInfo[]>(
() => store.getters['stakingV3/getRegisteredDapps']
Expand All @@ -39,6 +43,11 @@ export function useDapps() {
store.commit('stakingV3/addNewDapps', dApps.chainInfo);
// Memo: this can a heavy operations since we are querying all dapps stakes for a chain.
await fetchStakeAmountsToStore();

const numberOfParticipants = await tokenApiProviderRepository.getNumberOfParticipants(
currentNetworkName.value.toLowerCase()
);
store.commit('stakingV3/setNumberOfParticipants', numberOfParticipants);
} finally {
aggregator.publish(new BusyMessage(false));
}
Expand Down
8 changes: 7 additions & 1 deletion src/staking-v3/hooks/useDataCalculations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import { computed } from 'vue';
import { useDappStaking } from './useDappStaking';
import { useTokenCirculation } from 'src/hooks/useTokenCirculation';
import { ethers } from 'ethers';
import { useStore } from 'src/store';

export function useDataCalculations() {
const { totalSupply } = useTokenCirculation();
const { currentEraInfo } = useDappStaking();
const store = useStore();

const tvlPercentage = computed<number>(() => {
if (!currentEraInfo.value || !totalSupply.value) {
Expand Down Expand Up @@ -44,5 +46,9 @@ export function useDataCalculations() {
: currentEraInfo.value.currentStakeAmount.voting;
});

return { tvlPercentage, totalVolumeOfVotesPercentage, bonusEligibleTokens };
const numberOfParticipants = computed<number>(
() => store.getters['stakingV3/getNumberOfParticipants']
);

return { tvlPercentage, totalVolumeOfVotesPercentage, bonusEligibleTokens, numberOfParticipants };
}
2 changes: 1 addition & 1 deletion src/staking-v3/hooks/useLeaderboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export function useLeaderboard() {
);

const sortedDapps = computed<CombinedDappInfo[]>(() =>
registeredDapps.value.sort((a, b) => {
[...registeredDapps.value].sort((a, b) => {
const valueA = a.chain?.totalStake ?? BigInt(0);
const valueB = b.chain?.totalStake ?? BigInt(0);

Expand Down
1 change: 0 additions & 1 deletion src/staking-v3/logic/interfaces/DappStakingV3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ export interface PalletDappStakingV3ProtocolState extends Struct {
export interface PalletDappStakingV3DAppInfo extends Struct {
readonly owner: AccountId32;
readonly id: Compact<u16>;
readonly state: PalletDappStakingV3DAppState;
readonly rewardBeneficiary: Option<AccountId32>;
}

Expand Down
11 changes: 10 additions & 1 deletion src/staking-v3/logic/models/DappStaking.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DappInfo, ProtocolState } from './Node';
import { DappInfo, DappState, ProtocolState } from './Node';
import { Community } from '@astar-network/astar-sdk-core';

/**
Expand Down Expand Up @@ -198,6 +198,15 @@ export interface ProviderDappData {
registrationBlockNumber: number;
unregisteredAt?: number;
unregistrationBlockNumber?: number;
owner: string;
beneficiary?: string;
state: DappState;
dappId: number;
}

export interface NumberOfParticipantsData {
timestamp: string;
participants: number;
}

export interface StakerRewards {
Expand Down
2 changes: 1 addition & 1 deletion src/staking-v3/logic/repositories/DappStakingRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,7 @@ export class DappStakingRepository implements IDappStakingRepository {
address,
owner: dapp.owner.toString(),
id: dapp.id.toNumber(),
state: dapp.state.isUnregistered ? DappState.Unregistered : DappState.Registered,
state: DappState.Registered, // All dApss from integratedDApps are registered.
rewardDestination: dapp.rewardBeneficiary.unwrapOr(undefined)?.toString(),
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ import { ProviderDappData } from '../models';
*/
export interface IDataProviderRepository {
getDapps(network: string): Promise<ProviderDappData[]>;
getNumberOfParticipants(network: string): Promise<number>;
}
26 changes: 25 additions & 1 deletion src/staking-v3/logic/repositories/TokenApiProviderRepository.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { injectable } from 'inversify';
import { IDataProviderRepository } from './IDataProviderRepository';
import { ProviderDappData } from '../models';
import { ProviderDappData, NumberOfParticipantsData } from '../models';
import { TOKEN_API_URL } from '@astar-network/astar-sdk-core';
import { Guard } from 'src/v2/common';
import axios from 'axios';
Expand All @@ -25,4 +25,28 @@ export class TokenApiProviderRepository implements IDataProviderRepository {

return [];
}

async getNumberOfParticipants(network: string): Promise<number> {
Guard.ThrowIfUndefined(network, 'network');

const numberOfParticipantsUrl = `${TOKEN_API_URL}/v3/${network.toLowerCase()}/dapps-staking/stakerscount-total/1 day`;
try {
const numberOfParticipants = await axios.get<Array<Array<string | number>>>(
numberOfParticipantsUrl
);

const transformedData: NumberOfParticipantsData[] = numberOfParticipants.data.map((item) => {
return {
timestamp: item[0] as string,
participants: item[1] as number,
};
});

return transformedData.length > 0 ? transformedData[0].participants : 0;
} catch (error) {
console.error(error);
}

return 0;
}
}
24 changes: 23 additions & 1 deletion src/staking-v3/logic/services/DappStakingService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
CombinedDappInfo,
DappInfo,
DappStakeInfo,
DappState,
SingularStakingInfo,
StakeAmount,
StakerRewards,
Expand Down Expand Up @@ -37,7 +38,7 @@ export class DappStakingService implements IDappStakingService {
this.tokenApiRepository.getDapps(network.toLowerCase()),
]);

// Map on chain and in store dApps
// Map on chain and in store dApps (registered only)
const dApps: CombinedDappInfo[] = [];
const onlyChain: DappInfo[] = [];
chainDapps.forEach((chainDapp) => {
Expand All @@ -58,6 +59,27 @@ export class DappStakingService implements IDappStakingService {
}
});

// Map unregistered dApps
tokenApiDapps
.filter((x) => x.state === 'Unregistered')
.forEach((dapp) => {
const storeDapp = storeDapps.find(
(x) => x.address.toLowerCase() === dapp.contractAddress.toLowerCase()
);
if (storeDapp) {
dApps.push({
basic: storeDapp,
dappDetails: dapp,
chain: {
address: dapp.contractAddress,
id: dapp.dappId,
owner: dapp.owner,
state: DappState.Unregistered,
},
});
}
});

return { fullInfo: dApps, chainInfo: onlyChain };
}

Expand Down
1 change: 1 addition & 0 deletions src/staking-v3/store/getters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const getters: GetterTree<DappStakingState, StateInterface> & DappStakingGetters
getVersion: (state) => state.version,
getDapps: (state) => state.dapps,
getNewDapps: (state) => state.newDapps,
getNumberOfParticipants: (state) => state.numberOfParticipants,
getRegisteredDapps: (state) => state.dapps.filter((x) => x.chain.state === DappState.Registered),
getProtocolState: (state) => state.protocolState,
getLedger: (state) => state.ledger,
Expand Down
4 changes: 4 additions & 0 deletions src/staking-v3/store/mutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export interface DappStakingMutations<S = DappStakingState> {
updateDappExtended(state: DappStakingState, dapp: Dapp): void;
updateDappChain(state: DappStakingState, dapp: DappInfo): void;
updateDappDetails(state: DappStakingState, dapp: ProviderDappData): void;
setNumberOfParticipants(state: DappStakingState, numberOfParticipants: number): void;
setProtocolState(state: DappStakingState, protocolState: ProtocolState): void;
setLedger(state: DappStakingState, ledger: AccountLedger): void;
setStakerInfo(state: DappStakingState, stakerInfo: Map<string, SingularStakingInfo>): void;
Expand Down Expand Up @@ -73,6 +74,9 @@ const mutations: MutationTree<DappStakingState> & DappStakingMutations = {
updateDappDetails(state: DappStakingState, dapp: ProviderDappData): void {
updateDapp(state, dapp.contractAddress, dapp, 'dappDetails');
},
setNumberOfParticipants(state, numberOfParticipants) {
state.numberOfParticipants = numberOfParticipants;
},
setProtocolState(state, protocolState) {
state.protocolState = protocolState;
},
Expand Down
2 changes: 2 additions & 0 deletions src/staking-v3/store/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export interface DappStakingState {
version: string;
dapps: CombinedDappInfo[];
newDapps: DappInfo[];
numberOfParticipants: number;
protocolState: ProtocolState | undefined;
ledger: AccountLedger | undefined;
stakerInfo: Map<string, SingularStakingInfo> | undefined;
Expand All @@ -33,6 +34,7 @@ function state(): DappStakingState {
version: '3.0.0',
dapps: [],
newDapps: [],
numberOfParticipants: 0,
protocolState: undefined,
ledger: undefined,
stakerInfo: undefined,
Expand Down

0 comments on commit 876710a

Please sign in to comment.