add staking page

This commit is contained in:
2026-06-17 18:10:23 +03:00
parent 7966ef1c52
commit a5bb7abce8
17 changed files with 928 additions and 330 deletions

View File

@@ -0,0 +1,85 @@
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),
// Депозит отражается в сети не мгновенно: баланс обновляем сразу, позиции — с задержкой,
// иначе ранний рефетч «мигнул» бы (позиции ещё нет). Паттерн из useStake.
onSettled: () => {
qc.invalidateQueries({ queryKey: ['wallet', 'balance', 'ETH'] })
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'] })
},
})
}