From fa26b35e83c1fc65289f034a6498a21b2c7de754 Mon Sep 17 00:00:00 2001 From: Matthew Russell Date: Wed, 18 Oct 2023 11:40:24 -0700 Subject: [PATCH] feat: update queries to use window length --- .../components/fees-container/Fees.graphql | 27 ++++++-- .../fees-container/__generated__/Fees.ts | 63 ++++++++++++++---- .../fees-container/fees-container.tsx | 64 +++++++++++++------ .../fees-container/use-referral-stats.ts | 39 ++++++----- .../fees-container/use-volume-stats.ts | 17 ++--- 5 files changed, 143 insertions(+), 67 deletions(-) diff --git a/apps/trading/components/fees-container/Fees.graphql b/apps/trading/components/fees-container/Fees.graphql index 6649f6d84..0b058637d 100644 --- a/apps/trading/components/fees-container/Fees.graphql +++ b/apps/trading/components/fees-container/Fees.graphql @@ -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 } diff --git a/apps/trading/components/fees-container/__generated__/Fees.ts b/apps/trading/components/fees-container/__generated__/Fees.ts index a4a9392b9..064f75229 100644 --- a/apps/trading/components/fees-container/__generated__/Fees.ts +++ b/apps/trading/components/fees-container/__generated__/Fees.ts @@ -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) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useQuery(DiscountProgramsDocument, options); + } +export function useDiscountProgramsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useLazyQuery(DiscountProgramsDocument, options); + } +export type DiscountProgramsQueryHookResult = ReturnType; +export type DiscountProgramsLazyQueryHookResult = ReturnType; +export type DiscountProgramsQueryResult = Apollo.QueryResult; +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' * }, * }); */ diff --git a/apps/trading/components/fees-container/fees-container.tsx b/apps/trading/components/fees-container/fees-container.tsx index a5622307a..10c18b59e 100644 --- a/apps/trading/components/fees-container/fees-container.tsx +++ b/apps/trading/components/fees-container/fees-container.tsx @@ -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

Loading...

; } @@ -103,13 +115,15 @@ export const FeesContainer = () => { { ; 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 (
- + {requiredForNextTier > 0 && ( { return (
diff --git a/apps/trading/components/fees-container/use-referral-stats.ts b/apps/trading/components/fees-container/use-referral-stats.ts index 96e930f24..91acc746b 100644 --- a/apps/trading/components/fees-container/use-referral-stats.ts +++ b/apps/trading/components/fees-container/use-referral-stats.ts @@ -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, diff --git a/apps/trading/components/fees-container/use-volume-stats.ts b/apps/trading/components/fees-container/use-volume-stats.ts index 5dcb061af..8ed780e3d 100644 --- a/apps/trading/components/fees-container/use-volume-stats.ts +++ b/apps/trading/components/fees-container/use-volume-stats.ts @@ -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, }; };