1- import { CurrencyExt , newMonetaryAmount } from '@interlay/interbtc-api' ;
1+ import { CurrencyExt , LiquidityPool , newMonetaryAmount } from '@interlay/interbtc-api' ;
22import { MonetaryAmount } from '@interlay/monetary-js' ;
3+ import Big from 'big.js' ;
34import { subDays } from 'date-fns' ;
4- import { gql , GraphQLClient } from 'graphql-request' ;
5+ import { GraphQLClient } from 'graphql-request' ;
56import { useCallback } from 'react' ;
67import { useErrorHandler } from 'react-error-boundary' ;
78import { useQuery , UseQueryResult } from 'react-query' ;
89
9- import { convertMonetaryAmountToValueInUSD } from '@/common/utils/utils' ;
10+ import { convertMonetaryAmountToBigUSD } from '@/common/utils/utils' ;
1011import { SQUID_URL } from '@/constants' ;
12+ import { getPoolDataId , getPoolsVolumesQuery } from '@/services/queries/pools' ;
13+ import { CurrencySquidFormat } from '@/types/currency' ;
1114import { REFETCH_INTERVAL } from '@/utils/constants/api' ;
1215import { getTokenPrice } from '@/utils/helpers/prices' ;
1316
@@ -21,133 +24,78 @@ const graphQLClient = new GraphQLClient(SQUID_URL, {
2124 }
2225} ) ;
2326
24- // TODO: add this to a dedicated schemas folder
25- const AMOUNT_FIELDS = gql `
26- fragment AmountFields on PooledAmount {
27- amount
28- amountHuman
29- token {
30- ... on NativeToken {
31- __typename
32- token
33- }
34- ... on ForeignAsset {
35- __typename
36- asset
37- }
38- ... on StableLpToken {
39- __typename
40- poolId
41- }
42- }
43- }
44- ` ;
45-
46- // TODO: add this to a dedicated schemas folder
47- const GET_DEX_VOLUMES = gql `
48- ${ AMOUNT_FIELDS }
49- query poolVolumes($start: DateTime, $end: DateTime) {
50- startVolumes: cumulativeDexTradingVolumes(
51- limit: 1
52- orderBy: tillTimestamp_ASC
53- where: { tillTimestamp_gte: $start }
54- ) {
55- tillTimestamp
56- amounts {
57- ...AmountFields
58- }
59- }
60- endVolumes: cumulativeDexTradingVolumes(
61- limit: 1
62- orderBy: tillTimestamp_DESC
63- where: { tillTimestamp_lte: $end, tillTimestamp_gte: $start }
64- ) {
65- tillTimestamp
66- amounts {
67- ...AmountFields
68- }
69- }
70- }
71- ` ;
72-
7327enum DateRangeVolume {
7428 H24 ,
7529 D7
7630}
7731
78- type DexCurrencyVolume = {
79- amount : MonetaryAmount < CurrencyExt > ;
80- usd : number ;
32+ type DexVolumesData = Record < string , Big > ;
33+
34+ type UseGetCurrenciesResult = UseQueryResult < DexVolumesData > & {
35+ getDexVolumeByPool : ( pool : LiquidityPool | undefined ) => number ;
8136} ;
8237
83- type DexVolumesData = Record < string , DexCurrencyVolume > ;
38+ const getVolumes = (
39+ volumes : any ,
40+ dataId : string ,
41+ getCurrencyFromSquidFormat : ( currencySquid : CurrencySquidFormat ) => CurrencyExt
42+ ) : Array < MonetaryAmount < CurrencyExt > > => {
43+ const startVolumes = volumes [ `${ dataId } __startVolumes` ] ;
44+ const endVolumes = volumes [ `${ dataId } __endVolumes` ] ;
45+ if ( startVolumes . length === 0 || endVolumes . length === 0 ) {
46+ return [ ] ;
47+ }
8448
85- type UseGetCurrenciesResult = UseQueryResult < DexVolumesData > & {
86- getDexVolumeByTicker : ( ticker : string ) => DexCurrencyVolume | undefined ;
87- getDexTotalVolumeUSD : ( tickers : string [ ] ) => number ;
49+ return startVolumes [ 0 ] . amounts . map ( ( amount : any , index : number ) => {
50+ const currency = getCurrencyFromSquidFormat ( amount . token ) ;
51+ const endAmount = Big ( endVolumes [ 0 ] . amounts [ index ] . amount ) ;
52+ const amountDelta = endAmount . sub ( Big ( amount . amount ) ) ;
53+
54+ return newMonetaryAmount ( amountDelta , currency ) ;
55+ } ) ;
8856} ;
8957
9058const useGetDexVolumes = ( range : DateRangeVolume ) : UseGetCurrenciesResult => {
91- const { getCurrencyFromTicker , getForeignCurrencyFromId } = useGetCurrencies ( true ) ;
92- const { getStableLiquidityPoolById } = useGetLiquidityPools ( ) ;
59+ const { getCurrencyFromSquidFormat } = useGetCurrencies ( true ) ;
60+ const { data : pools } = useGetLiquidityPools ( ) ;
9361 const prices = useGetPrices ( ) ;
9462
9563 const getDexVolumes = useCallback (
9664 async ( range : DateRangeVolume ) : Promise < DexVolumesData > => {
65+ if ( ! pools ) {
66+ return { } ;
67+ }
68+
9769 const start = subDays ( new Date ( ) , range === DateRangeVolume . D7 ? 7 : 1 ) ;
9870 const end = new Date ( ) ;
9971
100- const data = await graphQLClient . request ( GET_DEX_VOLUMES , { start , end } ) ;
72+ const query = getPoolsVolumesQuery ( pools ) ;
10173
102- if ( ! data . startVolumes . length || ! data . endVolumes . length ) {
103- return { } ;
104- }
74+ const data = await graphQLClient . request ( query , { start, end } ) ;
10575
106- const [ startVolumes ] = data . startVolumes ;
107- const [ endVolumes ] = data . endVolumes ;
108-
109- return startVolumes . amounts . reduce ( ( acc : DexVolumesData , item : any ) => {
110- let currency : CurrencyExt ;
111- let endVolume ;
112-
113- switch ( item . token . __typename ) {
114- case 'NativeToken' : {
115- const { token } = item . token ;
116- currency = getCurrencyFromTicker ( token ) ;
117- endVolume = endVolumes . amounts . find ( ( endAmount : any ) => endAmount . token . token === token ) ;
118- break ;
119- }
120- case 'ForeignAsset' : {
121- const { asset } = item . token ;
122- currency = getForeignCurrencyFromId ( asset ) ;
123- endVolume = endVolumes . amounts . find ( ( endAmount : any ) => endAmount . token . asset === asset ) ;
124- break ;
125- }
126- case 'StableLpToken' : {
127- const { poolId } = item . token ;
128- currency = getStableLiquidityPoolById ( poolId ) . lpToken ;
129- endVolume = endVolumes . amounts . find ( ( endAmount : any ) => endAmount . token . poolId === poolId ) ;
130- break ;
131- }
132- default :
133- return acc ;
134- }
76+ const result = pools . map ( ( pool : LiquidityPool ) => {
77+ const dataId = getPoolDataId ( pool ) ;
13578
136- if ( ! endVolume ) {
137- return acc ;
79+ const volumes = getVolumes ( data , dataId , getCurrencyFromSquidFormat ) ;
80+ if ( volumes . length === 0 ) {
81+ return { [ dataId ] : Big ( 0 ) } ;
13882 }
13983
140- const volumeAmount = newMonetaryAmount ( endVolume . amount - item . amount , currency ) ;
84+ const totalVolumeInUSD = volumes
85+ . reduce (
86+ ( total , amount ) =>
87+ total . add ( convertMonetaryAmountToBigUSD ( amount , getTokenPrice ( prices , amount . currency . ticker ) ?. usd ) ) ,
88+ Big ( 0 )
89+ )
90+ // Divide by amount of pooled currencies.
91+ . div ( pool . pooledCurrencies . length ) ;
14192
142- const volume : DexCurrencyVolume = {
143- amount : volumeAmount ,
144- usd : convertMonetaryAmountToValueInUSD ( volumeAmount , getTokenPrice ( prices , currency . ticker ) ?. usd ) || 0
145- } ;
93+ return { [ dataId ] : totalVolumeInUSD } ;
94+ } ) ;
14695
147- return { ...acc , [ currency . ticker ] : volume } ;
148- } , { } ) ;
96+ return result . reduce ( ( result , pool ) => ( { ...result , ...pool } ) ) ;
14997 } ,
150- [ getCurrencyFromTicker , getForeignCurrencyFromId , getStableLiquidityPoolById , prices ]
98+ [ pools , getCurrencyFromSquidFormat , prices ]
15199 ) ;
152100
153101 const queryResult = useQuery ( {
@@ -156,16 +104,15 @@ const useGetDexVolumes = (range: DateRangeVolume): UseGetCurrenciesResult => {
156104 refetchInterval : REFETCH_INTERVAL . MINUTE
157105 } ) ;
158106
159- const getDexVolumeByTicker = useCallback ( ( ticker : string ) => queryResult . data ?. [ ticker ] , [ queryResult . data ] ) ;
160-
161- const getDexTotalVolumeUSD = useCallback (
162- ( tickers : string [ ] ) => tickers . reduce ( ( sum , ticker ) => sum + ( getDexVolumeByTicker ( ticker ) ?. usd || 0 ) , 0 ) ,
163- [ getDexVolumeByTicker ]
107+ const getDexVolumeByPool = useCallback (
108+ ( pool : LiquidityPool | undefined ) =>
109+ queryResult . data && pool ? queryResult . data [ getPoolDataId ( pool ) ] . toNumber ( ) : 0 ,
110+ [ queryResult ]
164111 ) ;
165112
166113 useErrorHandler ( queryResult . error ) ;
167114
168- return { ...queryResult , getDexTotalVolumeUSD , getDexVolumeByTicker } ;
115+ return { ...queryResult , getDexVolumeByPool } ;
169116} ;
170117
171118export { DateRangeVolume , useGetDexVolumes } ;
0 commit comments