89 lines
2.7 KiB
TypeScript
89 lines
2.7 KiB
TypeScript
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
||
import {
|
||
getPools,
|
||
getLpQuote,
|
||
getLpPositions,
|
||
addLp,
|
||
removeLp,
|
||
type LpDepositInput,
|
||
} from '../api/poolsApi'
|
||
|
||
export function usePools() {
|
||
return useQuery({
|
||
queryKey: ['pools', 'list'],
|
||
queryFn: getPools,
|
||
staleTime: 30_000,
|
||
retry: false,
|
||
})
|
||
}
|
||
|
||
export function useLpPositions() {
|
||
return useQuery({
|
||
queryKey: ['pools', 'positions'],
|
||
queryFn: getLpPositions,
|
||
staleTime: 30_000,
|
||
retry: false,
|
||
})
|
||
}
|
||
|
||
/**
|
||
* Квота депозита. Запрашивается, только когда пул выбран, обе границы диапазона > 0
|
||
* и задана хотя бы одна сумма. Вход дебаунсится на стороне виджета.
|
||
*/
|
||
export function useLpQuote(input: LpDepositInput | null) {
|
||
const ready =
|
||
input != null &&
|
||
input.priceLower > 0 &&
|
||
input.priceUpper > 0 &&
|
||
(parseFloat(input.amount0Human) > 0 || parseFloat(input.amount1Human) > 0)
|
||
|
||
return useQuery({
|
||
queryKey: [
|
||
'pools',
|
||
'quote',
|
||
input?.pool.poolAddress,
|
||
input?.priceLower,
|
||
input?.priceUpper,
|
||
input?.amount0Human,
|
||
input?.amount1Human,
|
||
input?.slippageBps,
|
||
input?.useNativeEth,
|
||
],
|
||
queryFn: () => getLpQuote(input as LpDepositInput),
|
||
enabled: ready,
|
||
staleTime: 15_000,
|
||
retry: false,
|
||
})
|
||
}
|
||
|
||
export function useAddLp() {
|
||
const qc = useQueryClient()
|
||
return useMutation({
|
||
mutationFn: (input: LpDepositInput) => addLp(input),
|
||
// Депозит отражается в сети не мгновенно. Первый рефетч делаем не сразу, а спустя 1.5 с,
|
||
// и повторяем для позиций через 6 с — позиция может ещё не появиться на чейне. Паттерн из useStake.
|
||
onSettled: () => {
|
||
setTimeout(() => {
|
||
qc.invalidateQueries({ queryKey: ['wallet', 'balance', 'ETH'] })
|
||
qc.invalidateQueries({ queryKey: ['pools', 'positions'] })
|
||
}, 1500)
|
||
setTimeout(() => {
|
||
qc.invalidateQueries({ queryKey: ['pools', 'positions'] })
|
||
qc.invalidateQueries({ queryKey: ['wallet', 'balance', 'ETH'] })
|
||
}, 6000)
|
||
},
|
||
})
|
||
}
|
||
|
||
export function useRemoveLp() {
|
||
const qc = useQueryClient()
|
||
return useMutation({
|
||
mutationFn: ({ tokenId, percent }: { tokenId: string; percent: number }) => removeLp(tokenId, percent),
|
||
onSuccess: () => {
|
||
// Ликвидность + накопленные комиссии вернулись на кошелёк.
|
||
qc.invalidateQueries({ queryKey: ['pools', 'positions'] })
|
||
qc.invalidateQueries({ queryKey: ['wallet', 'balance', 'ETH'] })
|
||
},
|
||
})
|
||
}
|