Mp 2182 convert api folder to swr hooks (#758)
* moved api/openingFee to hook * moved api/icns and api/balances to hooks * moved api/assetIncentivesApy to hooks * moved api/incentives to hooks * fix relative import
This commit is contained in:
parent
c4a2a7d913
commit
e763203d15
@ -1,26 +1,20 @@
|
||||
import { CosmWasmClient } from '@cosmjs/cosmwasm-stargate'
|
||||
|
||||
import { ICNSQueryClient } from 'types/classes/ICNSClient.client'
|
||||
import { MarsAccountNftQueryClient } from 'types/generated/mars-account-nft/MarsAccountNft.client'
|
||||
import { MarsCreditManagerQueryClient } from 'types/generated/mars-credit-manager/MarsCreditManager.client'
|
||||
import { MarsIncentivesQueryClient } from 'types/generated/mars-incentives/MarsIncentives.client'
|
||||
import { MarsMockVaultQueryClient } from 'types/generated/mars-mock-vault/MarsMockVault.client'
|
||||
import { MarsOracleOsmosisQueryClient } from 'types/generated/mars-oracle-osmosis/MarsOracleOsmosis.client'
|
||||
import { MarsParamsQueryClient } from 'types/generated/mars-params/MarsParams.client'
|
||||
import { MarsPerpsQueryClient } from 'types/generated/mars-perps/MarsPerps.client'
|
||||
import { MarsRedBankQueryClient } from 'types/generated/mars-red-bank/MarsRedBank.client'
|
||||
import { MarsSwapperOsmosisQueryClient } from 'types/generated/mars-swapper-osmosis/MarsSwapperOsmosis.client'
|
||||
|
||||
let _cosmWasmClient: Map<string, CosmWasmClient> = new Map()
|
||||
let _accountNftQueryClient: Map<string, MarsAccountNftQueryClient> = new Map()
|
||||
let _creditManagerQueryClient: Map<string, MarsCreditManagerQueryClient> = new Map()
|
||||
let _oracleQueryClient: Map<string, MarsOracleOsmosisQueryClient> = new Map()
|
||||
let _redBankQueryClient: Map<string, MarsRedBankQueryClient> = new Map()
|
||||
let _paramsQueryClient: Map<string, MarsParamsQueryClient> = new Map()
|
||||
let _incentivesQueryClient: Map<string, MarsIncentivesQueryClient> = new Map()
|
||||
let _swapperOsmosisClient: Map<string, MarsSwapperOsmosisQueryClient> = new Map()
|
||||
let _perpsClient: Map<string, MarsPerpsQueryClient> = new Map()
|
||||
let _ICNSQueryClient: Map<string, ICNSQueryClient> = new Map()
|
||||
|
||||
const getClient = async (rpc: string) => {
|
||||
try {
|
||||
@ -35,23 +29,6 @@ const getClient = async (rpc: string) => {
|
||||
}
|
||||
}
|
||||
|
||||
const getAccountNftQueryClient = async (chainConfig: ChainConfig) => {
|
||||
try {
|
||||
const contract = chainConfig.contracts.accountNft
|
||||
const rpc = chainConfig.endpoints.rpc
|
||||
const key = rpc + contract
|
||||
|
||||
if (!_accountNftQueryClient.get(key)) {
|
||||
const client = await getClient(rpc)
|
||||
_accountNftQueryClient.set(key, new MarsAccountNftQueryClient(client, contract))
|
||||
}
|
||||
|
||||
return _accountNftQueryClient.get(key)!
|
||||
} catch (error) {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
const getCreditManagerQueryClient = async (chainConfig: ChainConfig) => {
|
||||
try {
|
||||
const contract = chainConfig.contracts.creditManager
|
||||
@ -103,23 +80,6 @@ const getOracleQueryClient = async (chainConfig: ChainConfig) => {
|
||||
}
|
||||
}
|
||||
|
||||
const getRedBankQueryClient = async (chainConfig: ChainConfig) => {
|
||||
try {
|
||||
const contract = chainConfig.contracts.redBank
|
||||
const rpc = chainConfig.endpoints.rpc
|
||||
const key = rpc + contract
|
||||
|
||||
if (!_redBankQueryClient.get(key)) {
|
||||
const client = await getClient(rpc)
|
||||
_redBankQueryClient.set(key, new MarsRedBankQueryClient(client, contract))
|
||||
}
|
||||
|
||||
return _redBankQueryClient.get(key)!
|
||||
} catch (error) {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
const getVaultQueryClient = async (chainConfig: ChainConfig, address: string) => {
|
||||
try {
|
||||
const client = await getClient(chainConfig.endpoints.rpc)
|
||||
@ -177,31 +137,12 @@ const getPerpsQueryClient = async (chainConfig: ChainConfig) => {
|
||||
}
|
||||
}
|
||||
|
||||
const getICNSQueryClient = async (chainConfig: ChainConfig) => {
|
||||
try {
|
||||
const contract = chainConfig.contracts.params
|
||||
const rpc = chainConfig.endpoints.rpc
|
||||
const key = rpc + contract
|
||||
if (!_ICNSQueryClient.get(key)) {
|
||||
const client = await getClient(rpc)
|
||||
_ICNSQueryClient.set(key, new ICNSQueryClient(client))
|
||||
}
|
||||
|
||||
return _ICNSQueryClient.get(key)!
|
||||
} catch (error) {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
getAccountNftQueryClient,
|
||||
getClient,
|
||||
getCreditManagerQueryClient,
|
||||
getICNSQueryClient,
|
||||
getIncentivesQueryClient,
|
||||
getOracleQueryClient,
|
||||
getParamsQueryClient,
|
||||
getRedBankQueryClient,
|
||||
getSwapperQueryClient,
|
||||
getVaultQueryClient,
|
||||
getPerpsQueryClient,
|
||||
|
@ -1,42 +0,0 @@
|
||||
import { cacheFn, emissionsCache } from 'api/cache'
|
||||
import { getIncentivesQueryClient } from 'api/cosmwasm-client'
|
||||
import getPrice from 'api/prices/getPrice'
|
||||
import { BN_ZERO } from 'constants/math'
|
||||
import { byDenom } from 'utils/array'
|
||||
import { BN } from 'utils/helpers'
|
||||
|
||||
export default async function getTotalActiveEmissionValue(
|
||||
chainConfig: ChainConfig,
|
||||
denom: string,
|
||||
): Promise<BigNumber | null> {
|
||||
try {
|
||||
const client = await getIncentivesQueryClient(chainConfig)
|
||||
const activeEmissions = await cacheFn(
|
||||
() =>
|
||||
client.activeEmissions({
|
||||
collateralDenom: denom,
|
||||
}),
|
||||
emissionsCache,
|
||||
`emission/${denom}`,
|
||||
60,
|
||||
)
|
||||
|
||||
if (activeEmissions.length === 0) {
|
||||
throw 'Asset has no active incentive emission.'
|
||||
}
|
||||
|
||||
const prices = await Promise.all(
|
||||
activeEmissions.map((activeEmission) => getPrice(chainConfig, activeEmission.denom)),
|
||||
)
|
||||
|
||||
return activeEmissions.reduce((accumulation, current, index) => {
|
||||
const price = prices[index]
|
||||
const decimals = chainConfig.assets.find(byDenom(current.denom))?.decimals as number
|
||||
const emissionValue = BN(current.emission_rate).shiftedBy(-decimals).multipliedBy(price)
|
||||
|
||||
return accumulation.plus(emissionValue)
|
||||
}, BN_ZERO)
|
||||
} catch (ex) {
|
||||
return null
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
import { cacheFn, unclaimedRewardsCache } from 'api/cache'
|
||||
import { getIncentivesQueryClient } from 'api/cosmwasm-client'
|
||||
import { BNCoin } from 'types/classes/BNCoin'
|
||||
import iterateContractQuery from 'utils/iterateContractQuery'
|
||||
|
||||
export default async function getUnclaimedRewards(
|
||||
chainConfig: ChainConfig,
|
||||
accountId: string,
|
||||
): Promise<BNCoin[]> {
|
||||
try {
|
||||
const client = await getIncentivesQueryClient(chainConfig)
|
||||
const unclaimedRewards = await cacheFn(
|
||||
() =>
|
||||
iterateContractQuery(() =>
|
||||
client.userUnclaimedRewards({
|
||||
user: chainConfig.contracts.creditManager,
|
||||
accountId,
|
||||
}),
|
||||
),
|
||||
unclaimedRewardsCache,
|
||||
`incentives/${accountId}`,
|
||||
60,
|
||||
)
|
||||
|
||||
if (unclaimedRewards.length === 0) return []
|
||||
|
||||
return await Promise.all(
|
||||
unclaimedRewards.map((reward) => new BNCoin({ denom: reward.denom, amount: reward.amount })),
|
||||
)
|
||||
} catch (ex) {
|
||||
return []
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
import { getPerpsQueryClient } from 'api/cosmwasm-client'
|
||||
import { BNCoin } from 'types/classes/BNCoin'
|
||||
|
||||
export default async function getOpeningFee(
|
||||
chainConfig: ChainConfig,
|
||||
denom: string,
|
||||
amount: string,
|
||||
) {
|
||||
const perpsClient = await getPerpsQueryClient(chainConfig)
|
||||
|
||||
return perpsClient
|
||||
.openingFee({ denom, size: amount as any })
|
||||
.then((resp) => BNCoin.fromCoin(resp.fee))
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
import { getICNSQueryClient } from 'api/cosmwasm-client'
|
||||
import { ChainInfoID } from 'types/enums/wallet'
|
||||
|
||||
export default async function getICNS(
|
||||
chainConfig: ChainConfig,
|
||||
address?: string,
|
||||
): Promise<ICNSResult | undefined> {
|
||||
if (!address || chainConfig.id !== ChainInfoID.Osmosis1) return
|
||||
try {
|
||||
const icnsQueryClient = await getICNSQueryClient(chainConfig)
|
||||
return icnsQueryClient.primaryName({ address })
|
||||
} catch (ex) {
|
||||
throw ex
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
export default async function getWalletBalances(
|
||||
chainConfig: ChainConfig,
|
||||
address: string,
|
||||
): Promise<Coin[]> {
|
||||
const uri = '/cosmos/bank/v1beta1/balances/'
|
||||
|
||||
const response = await fetch(`${chainConfig.endpoints.rest}${uri}${address}`)
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json()
|
||||
return data.balances
|
||||
}
|
||||
|
||||
return new Promise((_, reject) => reject('No data'))
|
||||
}
|
@ -1,16 +1,20 @@
|
||||
import BigNumber from 'bignumber.js'
|
||||
import useSWR from 'swr'
|
||||
|
||||
import getOpeningFee from 'api/perps/getOpeningFee'
|
||||
import useChainConfig from 'hooks/useChainConfig'
|
||||
import useClients from 'hooks/useClients'
|
||||
import useDebounce from 'hooks/useDebounce'
|
||||
import { BNCoin } from 'types/classes/BNCoin'
|
||||
|
||||
export default function useOpeningFee(denom: string, amount: BigNumber) {
|
||||
const chainConfig = useChainConfig()
|
||||
const debouncedAmount = useDebounce<string>(amount.toString(), 500)
|
||||
const enabled = !amount.isZero()
|
||||
const clients = useClients()
|
||||
const enabled = !amount.isZero() && clients
|
||||
|
||||
return useSWR(enabled && `${chainConfig.id}/perps/${denom}/openingFee/${debouncedAmount}`, () =>
|
||||
getOpeningFee(chainConfig, denom, amount.toString()),
|
||||
clients!.perps
|
||||
.openingFee({ denom, size: amount as any })
|
||||
.then((resp) => BNCoin.fromCoin(resp.fee)),
|
||||
)
|
||||
}
|
||||
|
@ -1,20 +1,26 @@
|
||||
import useSWR from 'swr'
|
||||
|
||||
import getTotalActiveEmissionValue from 'api/incentives/getTotalActiveEmissionValue'
|
||||
import { BN_ZERO } from 'constants/math'
|
||||
import useAllAssets from 'hooks/assets/useAllAssets'
|
||||
import useMarket from 'hooks/markets/useMarket'
|
||||
import useChainConfig from 'hooks/useChainConfig'
|
||||
import usePrice from 'hooks/usePrice'
|
||||
import useClients from 'hooks/useClients'
|
||||
import usePrices from 'hooks/usePrices'
|
||||
import { byDenom } from 'utils/array'
|
||||
import { SECONDS_IN_A_YEAR } from 'utils/constants'
|
||||
import { BN } from 'utils/helpers'
|
||||
|
||||
export default function useAssetIncentivesApy(denom: string) {
|
||||
const chainConfig = useChainConfig()
|
||||
const market = useMarket(denom)
|
||||
const price = usePrice(denom)
|
||||
const { data: prices } = usePrices()
|
||||
const assets = useAllAssets()
|
||||
const clients = useClients()
|
||||
const enabled = !!market && !!prices.length && !!assets.length && !!clients
|
||||
|
||||
return useSWR(
|
||||
market && `chains/${chainConfig.id}/assets/${denom}/incentives`,
|
||||
() => calculateAssetIncentivesApy(chainConfig, market!, price),
|
||||
enabled && `chains/${chainConfig.id}/assets/${denom}/incentives`,
|
||||
() => calculateAssetIncentivesApy(clients!, assets, prices, market!),
|
||||
{
|
||||
revalidateOnFocus: false,
|
||||
},
|
||||
@ -22,16 +28,20 @@ export default function useAssetIncentivesApy(denom: string) {
|
||||
}
|
||||
|
||||
async function calculateAssetIncentivesApy(
|
||||
chainConfig: ChainConfig,
|
||||
clients: ContractClients,
|
||||
assets: Asset[],
|
||||
prices: BNCoin[],
|
||||
market: Market,
|
||||
price: BigNumber,
|
||||
) {
|
||||
const totalActiveEmissionValue = await getTotalActiveEmissionValue(
|
||||
chainConfig,
|
||||
market.asset.denom,
|
||||
clients,
|
||||
assets,
|
||||
prices,
|
||||
market,
|
||||
)
|
||||
|
||||
if (!totalActiveEmissionValue) return null
|
||||
const price = prices.find(byDenom(market.asset.denom))?.amount ?? BN_ZERO
|
||||
|
||||
const marketLiquidityValue = BN(market.deposits)
|
||||
.shiftedBy(-market.asset.decimals)
|
||||
@ -43,3 +53,30 @@ async function calculateAssetIncentivesApy(
|
||||
const totalAnnualReturnsValue = annualEmission.plus(marketReturns)
|
||||
return totalAnnualReturnsValue.dividedBy(marketLiquidityValue).multipliedBy(100)
|
||||
}
|
||||
|
||||
async function getTotalActiveEmissionValue(
|
||||
clients: ContractClients,
|
||||
assets: Asset[],
|
||||
prices: BNCoin[],
|
||||
market: Market,
|
||||
): Promise<BigNumber | null> {
|
||||
try {
|
||||
const activeEmissions = await clients.incentives.activeEmissions({
|
||||
collateralDenom: market.asset.denom,
|
||||
})
|
||||
|
||||
if (activeEmissions.length === 0) {
|
||||
throw 'Asset has no active incentive emission.'
|
||||
}
|
||||
|
||||
return activeEmissions.reduce((accumulation, current, index) => {
|
||||
const price = prices.find(byDenom(current.denom))?.amount ?? BN_ZERO
|
||||
const decimals = assets.find(byDenom(current.denom))?.decimals as number
|
||||
const emissionValue = BN(current.emission_rate).shiftedBy(-decimals).multipliedBy(price)
|
||||
|
||||
return accumulation.plus(emissionValue)
|
||||
}, BN_ZERO)
|
||||
} catch (ex) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ import { CosmWasmClient } from '@cosmjs/cosmwasm-stargate'
|
||||
import useSWR from 'swr'
|
||||
|
||||
import useChainConfig from 'hooks/useChainConfig'
|
||||
import { ICNSQueryClient } from 'types/classes/ICNSClient.client'
|
||||
import { MarsAccountNftQueryClient } from 'types/generated/mars-account-nft/MarsAccountNft.client'
|
||||
import { MarsCreditManagerQueryClient } from 'types/generated/mars-credit-manager/MarsCreditManager.client'
|
||||
import { MarsIncentivesQueryClient } from 'types/generated/mars-incentives/MarsIncentives.client'
|
||||
@ -31,6 +32,7 @@ export default function useClients() {
|
||||
swapper: new MarsSwapperOsmosisQueryClient(client, chainConfig.contracts.swapper),
|
||||
incentives: new MarsIncentivesQueryClient(client, chainConfig.contracts.incentives),
|
||||
perps: new MarsPerpsQueryClient(client, chainConfig.contracts.perps),
|
||||
icns: new ICNSQueryClient(client),
|
||||
} as ContractClients
|
||||
},
|
||||
{
|
||||
|
@ -1,12 +1,19 @@
|
||||
import useSWR from 'swr'
|
||||
|
||||
import getICNS from 'api/wallets/getICNS'
|
||||
import useChainConfig from 'hooks/useChainConfig'
|
||||
import useClients from 'hooks/useClients'
|
||||
import { ChainInfoID } from 'types/enums/wallet'
|
||||
|
||||
export default function useICNSDomain(address?: string) {
|
||||
const chainConfig = useChainConfig()
|
||||
const clients = useClients()
|
||||
const enabled = !!clients && chainConfig.id === ChainInfoID.Osmosis1 && address
|
||||
|
||||
return useSWR(`ICNS-${address}`, () => getICNS(chainConfig, address), {
|
||||
return useSWR(
|
||||
enabled && `chains/${chainConfig.id}/${address}/icns`,
|
||||
() => clients!.icns.primaryName({ address: address! }),
|
||||
{
|
||||
revalidateOnFocus: false,
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
@ -1,17 +1,21 @@
|
||||
import useSWR from 'swr'
|
||||
|
||||
import getUnclaimedRewards from 'api/incentives/getUnclaimedRewards'
|
||||
import useAccountId from 'hooks/useAccountId'
|
||||
import useChainConfig from 'hooks/useChainConfig'
|
||||
import useClients from 'hooks/useClients'
|
||||
import { BNCoin } from 'types/classes/BNCoin'
|
||||
import iterateContractQuery from 'utils/iterateContractQuery'
|
||||
|
||||
export default function useUserUnclaimedRewards() {
|
||||
const accountId = useAccountId()
|
||||
const chainConfig = useChainConfig()
|
||||
const clients = useClients()
|
||||
|
||||
const enabled = !!accountId && !!clients
|
||||
|
||||
return useSWR(
|
||||
`chains/${chainConfig.id}/accounts/${accountId}/unclaimed-rewards`,
|
||||
() => getUnclaimedRewards(chainConfig, accountId ?? ''),
|
||||
enabled && `chains/${chainConfig.id}/accounts/${accountId}/unclaimed-rewards`,
|
||||
() => getUnclaimedRewards(clients!, accountId!),
|
||||
{
|
||||
fallbackData: [] as BNCoin[],
|
||||
isPaused: () => !accountId,
|
||||
@ -19,3 +23,22 @@ export default function useUserUnclaimedRewards() {
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
async function getUnclaimedRewards(clients: ContractClients, accountId: string): Promise<BNCoin[]> {
|
||||
try {
|
||||
const unclaimedRewards = await iterateContractQuery(() =>
|
||||
clients.incentives.userUnclaimedRewards({
|
||||
user: clients.creditManager.contractAddress,
|
||||
accountId,
|
||||
}),
|
||||
)
|
||||
|
||||
if (unclaimedRewards.length === 0) return []
|
||||
|
||||
return await Promise.all(
|
||||
unclaimedRewards.map((reward) => new BNCoin({ denom: reward.denom, amount: reward.amount })),
|
||||
)
|
||||
} catch (ex) {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
import useSWR from 'swr'
|
||||
|
||||
import getWalletBalances from 'api/wallets/getWalletBalances'
|
||||
import useChainConfig from 'hooks/useChainConfig'
|
||||
|
||||
export default function useWalletBalances(address?: string) {
|
||||
@ -8,10 +7,23 @@ export default function useWalletBalances(address?: string) {
|
||||
|
||||
return useSWR(
|
||||
address && `chains/${chainConfig.id}/wallets/${address}/balances`,
|
||||
() => getWalletBalances(chainConfig, address || ''),
|
||||
() => getWalletBalances(chainConfig, address!),
|
||||
{
|
||||
isPaused: () => !address,
|
||||
fallbackData: [],
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
async function getWalletBalances(chainConfig: ChainConfig, address: string): Promise<Coin[]> {
|
||||
const uri = '/cosmos/bank/v1beta1/balances/'
|
||||
|
||||
const response = await fetch(`${chainConfig.endpoints.rest}${uri}${address}`)
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json()
|
||||
return data.balances
|
||||
}
|
||||
|
||||
return new Promise((_, reject) => reject('No data'))
|
||||
}
|
||||
|
1
src/types/interfaces/chain.d.ts
vendored
1
src/types/interfaces/chain.d.ts
vendored
@ -56,4 +56,5 @@ interface ContractClients {
|
||||
perps: import('types/generated/mars-perps/MarsPerps.client').MarsPerpsQueryClient
|
||||
redBank: import('types/generated/mars-red-bank/MarsRedBank.client').MarsRedBankQueryClient
|
||||
swapper: import('types/generated/mars-swapper-osmosis/MarsSwapperOsmosis.client').MarsSwapperOsmosisQueryClient
|
||||
icns: import('types/classes/ICNSClient.client').ICNSQueryClient
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user