packages/synapse-interface/slices/poolDataSlice.ts
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'
import { Token } from '@types'
import { POOL_BY_ROUTER_INDEX } from '@/constants/tokens'
import { getPoolTokenInfoArr, getTokenBalanceInfo } from '@/utils/poolDataFuncs'
import { getPoolApyData } from '@/utils/actions/getPoolApyData'
import { getBalanceData } from '@/utils/actions/getPoolData'
import { getCorePoolData } from '@/utils/actions/getCorePoolData'
import { getAvaxPrice, getEthPrice } from '@/utils/actions/getPrices'
export interface PoolDataState {
pool: Token | undefined
// poolData: {
// name: string
// tokens: Token[]
// totalLocked: number
// totalLockedUSD: number
// virtualPrice: string
// swapFee: string
// }
poolData: any
poolAPYData: any
isLoading: boolean
}
const initialState: PoolDataState = {
pool: undefined,
poolData: {
name: undefined,
tokens: undefined,
totalLocked: undefined,
totalLockedUSD: undefined,
virtualPrice: undefined,
swapFee: undefined,
},
poolAPYData: {
fullCompoundedApyStr: undefined,
weeklyAPR: undefined,
yearlyAPRUnvested: undefined,
},
isLoading: true,
}
export const fetchPoolData = createAsyncThunk(
'poolData/fetch',
async ({ poolName }: { poolName: string }) => {
const pool = POOL_BY_ROUTER_INDEX[poolName]
const chainId = pool.chainId
const poolAddress = pool?.swapAddresses[chainId]
if (!pool || !poolAddress) {
return null
}
const lpTokenAddress = pool?.addresses[chainId]
const { tokenBalances } = await getBalanceData({
pool,
chainId,
address: poolAddress,
lpTokenAddress,
})
const { swapFee, virtualPrice } = await getCorePoolData(
poolAddress,
chainId
)
const ethPrice = await getEthPrice()
const avaxPrice = await getAvaxPrice()
const {
tokenBalancesSum,
tokenBalancesUSD,
}: { tokenBalancesSum: number; tokenBalancesUSD: number } =
getTokenBalanceInfo({
tokenBalances: tokenBalances
.filter((t) => !t.isLP)
.map((t) => t.balance),
prices: {
ethPrice,
avaxPrice,
},
poolType: pool?.poolType,
})
const poolTokensMatured = getPoolTokenInfoArr({
tokenBalances: tokenBalances.filter((t) => !t.isLP),
tokenBalancesSum,
})
const poolAPYData = await getPoolApyData(chainId, pool)
// prob should split into multiple thunks to handle loading
// separately
return {
pool,
poolAPYData,
poolData: {
name: pool.name,
tokens: poolTokensMatured,
totalLocked: tokenBalancesSum,
totalLockedUSD: tokenBalancesUSD,
virtualPrice,
swapFee,
},
}
}
)
export const poolDataSlice = createSlice({
name: 'poolData',
initialState,
reducers: {
resetPoolData: () => initialState,
},
extraReducers: (builder) => {
builder
.addCase(fetchPoolData.pending, (state) => {
state.isLoading = true
})
.addCase(fetchPoolData.fulfilled, (state, action) => {
state.isLoading = false
state.pool = action.payload.pool
state.poolData = action.payload.poolData
state.poolAPYData = action.payload.poolAPYData
})
.addCase(fetchPoolData.rejected, (state) => {
state.isLoading = false
})
},
})
export const { resetPoolData } = poolDataSlice.actions
export const selectPool = (state) => state.poolData.pool
export default poolDataSlice.reducer