feat: update queries to use window length
This commit is contained in:
@@ -1,23 +1,32 @@
|
||||
query Fees($partyId: ID!, $volumeDiscountStatsEpochs: Int!) {
|
||||
epoch {
|
||||
id
|
||||
}
|
||||
query DiscountPrograms {
|
||||
currentReferralProgram {
|
||||
benefitTiers {
|
||||
minimumEpochs
|
||||
minimumRunningNotionalTakerVolume
|
||||
referralDiscountFactor
|
||||
}
|
||||
windowLength
|
||||
}
|
||||
currentVolumeDiscountProgram {
|
||||
benefitTiers {
|
||||
minimumRunningNotionalTakerVolume
|
||||
volumeDiscountFactor
|
||||
}
|
||||
windowLength
|
||||
}
|
||||
}
|
||||
|
||||
query Fees(
|
||||
$partyId: ID!
|
||||
$volumeDiscountEpochs: Int!
|
||||
$referralDiscountEpochs: Int!
|
||||
) {
|
||||
epoch {
|
||||
id
|
||||
}
|
||||
volumeDiscountStats(
|
||||
partyId: $partyId
|
||||
pagination: { last: $volumeDiscountStatsEpochs }
|
||||
pagination: { last: $volumeDiscountEpochs }
|
||||
) {
|
||||
edges {
|
||||
node {
|
||||
@@ -27,16 +36,20 @@ query Fees($partyId: ID!, $volumeDiscountStatsEpochs: Int!) {
|
||||
}
|
||||
}
|
||||
}
|
||||
referralSetReferees(referee: $partyId, aggregationDays: 7) {
|
||||
referralSetReferees(referee: $partyId) {
|
||||
edges {
|
||||
node {
|
||||
atEpoch
|
||||
}
|
||||
}
|
||||
}
|
||||
referralSetStats(partyId: $partyId) {
|
||||
referralSetStats(
|
||||
partyId: $partyId
|
||||
pagination: { last: $referralDiscountEpochs }
|
||||
) {
|
||||
edges {
|
||||
node {
|
||||
atEpoch
|
||||
discountFactor
|
||||
referralSetRunningNotionalTakerVolume
|
||||
}
|
||||
|
||||
+52
-11
@@ -3,36 +3,75 @@ import * as Types from '@vegaprotocol/types';
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type DiscountProgramsQueryVariables = Types.Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type DiscountProgramsQuery = { __typename?: 'Query', currentReferralProgram?: { __typename?: 'CurrentReferralProgram', windowLength: number, benefitTiers: Array<{ __typename?: 'BenefitTier', minimumEpochs: number, minimumRunningNotionalTakerVolume: string, referralDiscountFactor: string }> } | null, currentVolumeDiscountProgram?: { __typename?: 'VolumeDiscountProgram', windowLength: number, benefitTiers: Array<{ __typename?: 'VolumeBenefitTier', minimumRunningNotionalTakerVolume: string, volumeDiscountFactor: string }> } | null };
|
||||
|
||||
export type FeesQueryVariables = Types.Exact<{
|
||||
partyId: Types.Scalars['ID'];
|
||||
volumeDiscountStatsEpochs: Types.Scalars['Int'];
|
||||
volumeDiscountEpochs: Types.Scalars['Int'];
|
||||
referralDiscountEpochs: Types.Scalars['Int'];
|
||||
}>;
|
||||
|
||||
|
||||
export type FeesQuery = { __typename?: 'Query', epoch: { __typename?: 'Epoch', id: string }, currentReferralProgram?: { __typename?: 'CurrentReferralProgram', benefitTiers: Array<{ __typename?: 'BenefitTier', minimumEpochs: number, minimumRunningNotionalTakerVolume: string, referralDiscountFactor: string }> } | null, currentVolumeDiscountProgram?: { __typename?: 'VolumeDiscountProgram', benefitTiers: Array<{ __typename?: 'VolumeBenefitTier', minimumRunningNotionalTakerVolume: string, volumeDiscountFactor: string }> } | null, volumeDiscountStats: { __typename?: 'VolumeDiscountStatsConnection', edges: Array<{ __typename?: 'VolumeDiscountStatsEdge', node: { __typename?: 'VolumeDiscountStats', atEpoch: number, discountFactor: string, runningVolume: string } } | null> }, referralSetReferees: { __typename?: 'ReferralSetRefereeConnection', edges: Array<{ __typename?: 'ReferralSetRefereeEdge', node: { __typename?: 'ReferralSetReferee', atEpoch: number } } | null> }, referralSetStats: { __typename?: 'ReferralSetStatsConnection', edges: Array<{ __typename?: 'ReferralSetStatsEdge', node: { __typename?: 'ReferralSetStats', discountFactor: string, referralSetRunningNotionalTakerVolume: string } } | null> } };
|
||||
export type FeesQuery = { __typename?: 'Query', epoch: { __typename?: 'Epoch', id: string }, volumeDiscountStats: { __typename?: 'VolumeDiscountStatsConnection', edges: Array<{ __typename?: 'VolumeDiscountStatsEdge', node: { __typename?: 'VolumeDiscountStats', atEpoch: number, discountFactor: string, runningVolume: string } } | null> }, referralSetReferees: { __typename?: 'ReferralSetRefereeConnection', edges: Array<{ __typename?: 'ReferralSetRefereeEdge', node: { __typename?: 'ReferralSetReferee', atEpoch: number } } | null> }, referralSetStats: { __typename?: 'ReferralSetStatsConnection', edges: Array<{ __typename?: 'ReferralSetStatsEdge', node: { __typename?: 'ReferralSetStats', atEpoch: number, discountFactor: string, referralSetRunningNotionalTakerVolume: string } } | null> } };
|
||||
|
||||
|
||||
export const FeesDocument = gql`
|
||||
query Fees($partyId: ID!, $volumeDiscountStatsEpochs: Int!) {
|
||||
epoch {
|
||||
id
|
||||
}
|
||||
export const DiscountProgramsDocument = gql`
|
||||
query DiscountPrograms {
|
||||
currentReferralProgram {
|
||||
benefitTiers {
|
||||
minimumEpochs
|
||||
minimumRunningNotionalTakerVolume
|
||||
referralDiscountFactor
|
||||
}
|
||||
windowLength
|
||||
}
|
||||
currentVolumeDiscountProgram {
|
||||
benefitTiers {
|
||||
minimumRunningNotionalTakerVolume
|
||||
volumeDiscountFactor
|
||||
}
|
||||
windowLength
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useDiscountProgramsQuery__
|
||||
*
|
||||
* To run a query within a React component, call `useDiscountProgramsQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `useDiscountProgramsQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||
* you can use to render your UI.
|
||||
*
|
||||
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||
*
|
||||
* @example
|
||||
* const { data, loading, error } = useDiscountProgramsQuery({
|
||||
* variables: {
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useDiscountProgramsQuery(baseOptions?: Apollo.QueryHookOptions<DiscountProgramsQuery, DiscountProgramsQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<DiscountProgramsQuery, DiscountProgramsQueryVariables>(DiscountProgramsDocument, options);
|
||||
}
|
||||
export function useDiscountProgramsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<DiscountProgramsQuery, DiscountProgramsQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<DiscountProgramsQuery, DiscountProgramsQueryVariables>(DiscountProgramsDocument, options);
|
||||
}
|
||||
export type DiscountProgramsQueryHookResult = ReturnType<typeof useDiscountProgramsQuery>;
|
||||
export type DiscountProgramsLazyQueryHookResult = ReturnType<typeof useDiscountProgramsLazyQuery>;
|
||||
export type DiscountProgramsQueryResult = Apollo.QueryResult<DiscountProgramsQuery, DiscountProgramsQueryVariables>;
|
||||
export const FeesDocument = gql`
|
||||
query Fees($partyId: ID!, $volumeDiscountEpochs: Int!, $referralDiscountEpochs: Int!) {
|
||||
epoch {
|
||||
id
|
||||
}
|
||||
volumeDiscountStats(
|
||||
partyId: $partyId
|
||||
pagination: {last: $volumeDiscountStatsEpochs}
|
||||
pagination: {last: $volumeDiscountEpochs}
|
||||
) {
|
||||
edges {
|
||||
node {
|
||||
@@ -42,16 +81,17 @@ export const FeesDocument = gql`
|
||||
}
|
||||
}
|
||||
}
|
||||
referralSetReferees(referee: $partyId, aggregationDays: 7) {
|
||||
referralSetReferees(referee: $partyId) {
|
||||
edges {
|
||||
node {
|
||||
atEpoch
|
||||
}
|
||||
}
|
||||
}
|
||||
referralSetStats(partyId: $partyId) {
|
||||
referralSetStats(partyId: $partyId, pagination: {last: $referralDiscountEpochs}) {
|
||||
edges {
|
||||
node {
|
||||
atEpoch
|
||||
discountFactor
|
||||
referralSetRunningNotionalTakerVolume
|
||||
}
|
||||
@@ -73,7 +113,8 @@ export const FeesDocument = gql`
|
||||
* const { data, loading, error } = useFeesQuery({
|
||||
* variables: {
|
||||
* partyId: // value for 'partyId'
|
||||
* volumeDiscountStatsEpochs: // value for 'volumeDiscountStatsEpochs'
|
||||
* volumeDiscountEpochs: // value for 'volumeDiscountEpochs'
|
||||
* referralDiscountEpochs: // value for 'referralDiscountEpochs'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
|
||||
@@ -3,7 +3,7 @@ import maxBy from 'lodash/maxBy';
|
||||
import minBy from 'lodash/minBy';
|
||||
import classNames from 'classnames';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { useFeesQuery } from './__generated__/Fees';
|
||||
import { useDiscountProgramsQuery, useFeesQuery } from './__generated__/Fees';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import {
|
||||
useNetworkParams,
|
||||
@@ -27,41 +27,53 @@ import { Splash } from '@vegaprotocol/ui-toolkit';
|
||||
* - Remove hardcoded partyId
|
||||
*/
|
||||
|
||||
const VOLUME_EPOCHS = 7;
|
||||
|
||||
export const FeesContainer = () => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
const { params } = useNetworkParams([
|
||||
NetworkParams.market_fee_factors_makerFee,
|
||||
NetworkParams.market_fee_factors_infrastructureFee,
|
||||
]);
|
||||
|
||||
const { data: markets } = useMarketList();
|
||||
|
||||
const {
|
||||
data: programData,
|
||||
loading: programLoading,
|
||||
error: programError,
|
||||
} = useDiscountProgramsQuery();
|
||||
|
||||
const volumeDiscountEpochs =
|
||||
programData?.currentVolumeDiscountProgram?.windowLength || 1;
|
||||
const referralDiscountEpochs =
|
||||
programData?.currentReferralProgram?.windowLength || 1;
|
||||
|
||||
const { data, loading, error } = useFeesQuery({
|
||||
variables: {
|
||||
partyId:
|
||||
// TODO: change for pubkey
|
||||
'9e2445e0e98c0e0ca1c260baaab1e7a2f1b9c7256c27196be6e614ee44d1a1e7',
|
||||
volumeDiscountStatsEpochs: VOLUME_EPOCHS,
|
||||
volumeDiscountEpochs,
|
||||
referralDiscountEpochs,
|
||||
},
|
||||
skip: !pubKey,
|
||||
skip: !pubKey || !programData,
|
||||
});
|
||||
const { data: markets } = useMarketList();
|
||||
|
||||
const { volumeDiscount, volumeTierIndex, volumeLastEpoch, volumeTiers } =
|
||||
const { volumeDiscount, volumeTierIndex, volumeInWindow, volumeTiers } =
|
||||
useVolumeStats(
|
||||
data?.volumeDiscountStats,
|
||||
data?.currentVolumeDiscountProgram
|
||||
programData?.currentVolumeDiscountProgram
|
||||
);
|
||||
|
||||
const {
|
||||
referralDiscount,
|
||||
referralVolume,
|
||||
referralVolumeInWindow,
|
||||
referralTierIndex,
|
||||
referralTiers,
|
||||
epochsInSet,
|
||||
} = useReferralStats(
|
||||
data?.referralSetStats,
|
||||
data?.referralSetReferees,
|
||||
data?.currentReferralProgram,
|
||||
programData?.currentReferralProgram,
|
||||
data?.epoch
|
||||
);
|
||||
|
||||
@@ -82,7 +94,7 @@ export const FeesContainer = () => {
|
||||
}
|
||||
|
||||
// TODO: skeleton loading states
|
||||
if (loading || !data) {
|
||||
if (loading || programLoading) {
|
||||
return <p>Loading...</p>;
|
||||
}
|
||||
|
||||
@@ -103,13 +115,15 @@ export const FeesContainer = () => {
|
||||
<CurrentVolume
|
||||
tiers={volumeTiers}
|
||||
tierIndex={volumeTierIndex}
|
||||
lastEpochVolume={volumeLastEpoch}
|
||||
windowLengthVolume={volumeInWindow}
|
||||
epochs={volumeDiscountEpochs}
|
||||
/>
|
||||
</FeeCard>
|
||||
<FeeCard title={t('Referral benefits')} className="sm:col-span-2">
|
||||
<ReferralBenefits
|
||||
setRunningNotionalTakerVolume={referralVolume}
|
||||
setRunningNotionalTakerVolume={referralVolumeInWindow}
|
||||
epochsInSet={epochsInSet}
|
||||
epochs={referralDiscountEpochs}
|
||||
/>
|
||||
</FeeCard>
|
||||
<FeeCard
|
||||
@@ -119,7 +133,7 @@ export const FeesContainer = () => {
|
||||
<VolumeTiers
|
||||
tiers={volumeTiers}
|
||||
tierIndex={volumeTierIndex}
|
||||
lastEpochVolume={volumeLastEpoch}
|
||||
lastEpochVolume={volumeInWindow}
|
||||
/>
|
||||
</FeeCard>
|
||||
<FeeCard
|
||||
@@ -234,24 +248,31 @@ const TradingFees = ({
|
||||
const CurrentVolume = ({
|
||||
tiers,
|
||||
tierIndex,
|
||||
lastEpochVolume,
|
||||
windowLengthVolume,
|
||||
epochs,
|
||||
}: {
|
||||
tiers?: Array<{ minimumRunningNotionalTakerVolume: string }>;
|
||||
tierIndex: number;
|
||||
lastEpochVolume: number;
|
||||
windowLengthVolume: number;
|
||||
epochs: number;
|
||||
}) => {
|
||||
// TODO sum windowLength volume
|
||||
|
||||
let requiredForNextTier = 0;
|
||||
|
||||
if (tiers && tierIndex) {
|
||||
const nextTier = tiers[tierIndex - 1];
|
||||
requiredForNextTier = nextTier
|
||||
? Number(nextTier.minimumRunningNotionalTakerVolume) - lastEpochVolume
|
||||
? Number(nextTier.minimumRunningNotionalTakerVolume) - windowLengthVolume
|
||||
: 0;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Stat value={formatNumber(lastEpochVolume)} text={t('Past 7 epochs')} />
|
||||
<Stat
|
||||
value={formatNumber(windowLengthVolume)}
|
||||
text={t('Past %s epochs', epochs.toString())}
|
||||
/>
|
||||
{requiredForNextTier > 0 && (
|
||||
<Stat
|
||||
value={formatNumber(requiredForNextTier)}
|
||||
@@ -265,16 +286,21 @@ const CurrentVolume = ({
|
||||
const ReferralBenefits = ({
|
||||
epochsInSet,
|
||||
setRunningNotionalTakerVolume,
|
||||
epochs,
|
||||
}: {
|
||||
epochsInSet: number;
|
||||
setRunningNotionalTakerVolume: number;
|
||||
epochs: number;
|
||||
}) => {
|
||||
return (
|
||||
<div>
|
||||
<Stat
|
||||
// all sets volume (not just current party)
|
||||
value={formatNumber(setRunningNotionalTakerVolume)}
|
||||
text={'Combined running notional over the last epoch'}
|
||||
text={t(
|
||||
'Combined running notional over the %s epochs',
|
||||
epochs.toString()
|
||||
)}
|
||||
/>
|
||||
<Stat value={epochsInSet} text={t('epochs in referral set')} />
|
||||
</div>
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
import compact from 'lodash/compact';
|
||||
import maxBy from 'lodash/maxBy';
|
||||
import { getReferralBenefitTier } from './utils';
|
||||
import type { FeesQuery } from './__generated__/Fees';
|
||||
import type { DiscountProgramsQuery, FeesQuery } from './__generated__/Fees';
|
||||
|
||||
export const useReferralStats = (
|
||||
setStats?: FeesQuery['referralSetStats'],
|
||||
setReferees?: FeesQuery['referralSetReferees'],
|
||||
program?: FeesQuery['currentReferralProgram'],
|
||||
program?: DiscountProgramsQuery['currentReferralProgram'],
|
||||
epoch?: FeesQuery['epoch']
|
||||
) => {
|
||||
if (!setStats || !setReferees || !program || !epoch) {
|
||||
return {
|
||||
referralDiscount: 0,
|
||||
referralVolume: 0,
|
||||
referralVolumeInWindow: 0,
|
||||
referralTierIndex: -1,
|
||||
referralTiers: [],
|
||||
epochsInSet: 0,
|
||||
@@ -21,31 +22,29 @@ export const useReferralStats = (
|
||||
const referralSetsStats = compact(setStats.edges).map((e) => e.node);
|
||||
const referralSets = compact(setReferees.edges).map((e) => e.node);
|
||||
|
||||
if (referralSets.length > 1 || referralSetsStats.length > 1) {
|
||||
throw new Error('more than one referral set for user');
|
||||
}
|
||||
const referralSet = maxBy(referralSets, (s) => s.atEpoch);
|
||||
const referralStats = maxBy(referralSetsStats, (s) => s.atEpoch);
|
||||
|
||||
const referralSet = referralSets[0];
|
||||
const referralStats = referralSetsStats[0];
|
||||
const epochsInSet = referralSet ? Number(epoch.id) - referralSet.atEpoch : 0;
|
||||
|
||||
const epochsInSet = Number(epoch.id) - referralSet.atEpoch;
|
||||
const referralDiscount = Number(referralStats.discountFactor || 0);
|
||||
const referralDiscount = Number(referralStats?.discountFactor || 0);
|
||||
const referralVolumeInWindow = Number(
|
||||
referralStats?.referralSetRunningNotionalTakerVolume || 0
|
||||
);
|
||||
|
||||
const referralTiers = [...program.benefitTiers].reverse();
|
||||
|
||||
const referralTierIndex = getReferralBenefitTier(
|
||||
epochsInSet,
|
||||
Number(referralStats.referralSetRunningNotionalTakerVolume),
|
||||
referralTiers
|
||||
);
|
||||
|
||||
const referralVolume = Number(
|
||||
referralStats.referralSetRunningNotionalTakerVolume
|
||||
);
|
||||
const referralTierIndex = referralStats
|
||||
? getReferralBenefitTier(
|
||||
epochsInSet,
|
||||
Number(referralStats.referralSetRunningNotionalTakerVolume),
|
||||
referralTiers
|
||||
)
|
||||
: -1;
|
||||
|
||||
return {
|
||||
referralDiscount,
|
||||
referralVolume,
|
||||
referralVolumeInWindow,
|
||||
referralTierIndex,
|
||||
referralTiers,
|
||||
epochsInSet,
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import compact from 'lodash/compact';
|
||||
import maxBy from 'lodash/maxBy';
|
||||
import { getVolumeTier } from './utils';
|
||||
import type { FeesQuery } from './__generated__/Fees';
|
||||
import type { DiscountProgramsQuery, FeesQuery } from './__generated__/Fees';
|
||||
|
||||
export const useVolumeStats = (
|
||||
stats?: FeesQuery['volumeDiscountStats'],
|
||||
program?: FeesQuery['currentVolumeDiscountProgram']
|
||||
program?: DiscountProgramsQuery['currentVolumeDiscountProgram']
|
||||
) => {
|
||||
if (!stats || !program) {
|
||||
return {
|
||||
volumeDiscount: 0,
|
||||
volumeTierIndex: -1,
|
||||
volumeLastEpoch: 0,
|
||||
volumeInWindow: 0,
|
||||
volumeTiers: [],
|
||||
};
|
||||
}
|
||||
@@ -20,20 +20,17 @@ export const useVolumeStats = (
|
||||
|
||||
const volumeDiscount = Number(volumeStats[0].discountFactor || 0);
|
||||
|
||||
const lastEpochVolumeStats = stats
|
||||
? maxBy(volumeStats, (s) => s.atEpoch)
|
||||
: undefined;
|
||||
|
||||
const volumeLastEpoch = Number(lastEpochVolumeStats?.runningVolume || 0);
|
||||
const lastEpochStats = maxBy(volumeStats, (s) => s.atEpoch);
|
||||
const volumeInWindow = Number(lastEpochStats?.runningVolume || 0);
|
||||
|
||||
const volumeTiers = [...program.benefitTiers].reverse();
|
||||
|
||||
const volumeTierIndex = getVolumeTier(volumeLastEpoch, volumeTiers);
|
||||
const volumeTierIndex = getVolumeTier(volumeInWindow, volumeTiers);
|
||||
|
||||
return {
|
||||
volumeDiscount,
|
||||
volumeTierIndex,
|
||||
volumeLastEpoch,
|
||||
volumeInWindow,
|
||||
volumeTiers,
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user