14.05.2026 rip
This commit is contained in:
@@ -1,12 +1,18 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { PrimaryButton } from '@shared/ui'
|
||||
import { useWalletBalance, useWalletAddresses, useTokensList, useRelayQuote, useExecuteRelaySwap, useSignSwap, type Chain, type RelaySwapResponse } from '@features/wallet'
|
||||
import {
|
||||
useWalletBalance, useWalletAddresses, useTokensList,
|
||||
useRelayQuote, useExecuteRelaySwap, useSignSwap,
|
||||
useTrxSwapQuote, useFetchTrxQuote, useExecuteTrxSwap,
|
||||
type Chain, type RelaySwapResponse, type TrxSwapQuoteData,
|
||||
} from '@features/wallet'
|
||||
import { useDebounce } from '@shared/lib/hooks/useDebounce'
|
||||
import { TOKENS_LIST, buildTokensFromBalance, useSwapForm } from '../model/useSwapForm'
|
||||
import { SwapCard } from './SwapCard'
|
||||
import { SwapDirectionButton } from './SwapDirectionButton'
|
||||
import { SwapInfoPanel } from './SwapInfoPanel'
|
||||
import { SwapConfirmModal } from './SwapConfirmModal'
|
||||
import { TrxConfirmModal } from './TrxConfirmModal'
|
||||
import styles from './SwapForm.module.css'
|
||||
|
||||
|
||||
@@ -29,6 +35,9 @@ export function SwapForm() {
|
||||
|
||||
const [fromNetwork, setFromNetwork] = useState('ETH')
|
||||
const [modalData, setModalData] = useState<RelaySwapResponse | null>(null)
|
||||
const [trxModalQuote, setTrxModalQuote] = useState<TrxSwapQuoteData | null>(null)
|
||||
|
||||
const isTrxNetwork = fromNetwork === 'TRX'
|
||||
|
||||
const { data: walletData } = useWalletBalance(fromNetwork as Chain)
|
||||
const tokenOptions = walletData ? buildTokensFromBalance(walletData) : TOKENS_LIST
|
||||
@@ -43,13 +52,15 @@ export function SwapForm() {
|
||||
const { data: addresses } = useWalletAddresses()
|
||||
const { data: tokensList } = useTokensList()
|
||||
|
||||
const parsedAmount = parseFloat(debouncedAmount)
|
||||
|
||||
// ── Relay (ETH / BSC / SOL) ─────────────────────────────────────────────
|
||||
const chainId = CHAIN_ID[fromNetwork]
|
||||
const walletAddress = addresses?.find(a => a.chain === fromNetwork)?.address
|
||||
const fromContract = tokensList?.find(t => t.chain === fromNetwork && t.symbol === fromToken.symbol)?.contract ?? nativeAddr(fromNetwork)
|
||||
const toContract = tokensList?.find(t => t.chain === fromNetwork && t.symbol === toToken.symbol)?.contract ?? nativeAddr(fromNetwork)
|
||||
|
||||
const parsedAmount = parseFloat(debouncedAmount)
|
||||
const quotePayload = chainId && walletAddress && parsedAmount > 0
|
||||
const quotePayload = !isTrxNetwork && chainId && walletAddress && parsedAmount > 0
|
||||
? {
|
||||
user: walletAddress,
|
||||
recipient: walletAddress,
|
||||
@@ -66,15 +77,44 @@ export function SwapForm() {
|
||||
const { mutate: executeSwap, isPending: isSwapping } = useExecuteRelaySwap()
|
||||
const { mutate: signSwap } = useSignSwap()
|
||||
|
||||
const displayToAmount = quoteData?.details.currencyOut.amountFormatted ?? '0'
|
||||
const displayToUsd = quoteData?.details.currencyOut.amountUsd
|
||||
const gasFee = quoteData?.fees.gas.amountUsd
|
||||
// ── TRX ─────────────────────────────────────────────────────────────────
|
||||
const trxQuotePayload = isTrxNetwork && parsedAmount > 0
|
||||
? { from: fromToken.symbol, to: toToken.symbol, amountHuman: debouncedAmount }
|
||||
: null
|
||||
|
||||
const { data: trxQuoteData } = useTrxSwapQuote(trxQuotePayload)
|
||||
const { mutate: fetchTrxQuote, isPending: isFetchingTrxQuote } = useFetchTrxQuote()
|
||||
const { mutate: executeTrxSwap } = useExecuteTrxSwap()
|
||||
|
||||
// ── Display values ───────────────────────────────────────────────────────
|
||||
const displayToAmount = isTrxNetwork
|
||||
? (trxQuoteData?.expectedOutFormatted ?? '0')
|
||||
: (quoteData?.details.currencyOut.amountFormatted ?? '0')
|
||||
|
||||
const displayToUsd = isTrxNetwork
|
||||
? undefined
|
||||
: quoteData?.details.currencyOut.amountUsd
|
||||
|
||||
const gasFee = isTrxNetwork
|
||||
? trxQuoteData?.fees.network.amountUsd?.toString()
|
||||
: quoteData?.fees.gas.amountUsd
|
||||
|
||||
const isButtonDisabled = isTrxNetwork
|
||||
? parsedAmount <= 0 || isFetchingTrxQuote
|
||||
: !quotePayload || isSwapping
|
||||
|
||||
function handleSwap() {
|
||||
if (!quotePayload) return
|
||||
executeSwap(quotePayload, {
|
||||
onSuccess: (data) => setModalData(data),
|
||||
})
|
||||
if (isTrxNetwork) {
|
||||
if (!trxQuotePayload) return
|
||||
fetchTrxQuote(trxQuotePayload, {
|
||||
onSuccess: (quote) => setTrxModalQuote(quote),
|
||||
})
|
||||
} else {
|
||||
if (!quotePayload) return
|
||||
executeSwap(quotePayload, {
|
||||
onSuccess: (data) => setModalData(data),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -105,7 +145,7 @@ export function SwapForm() {
|
||||
|
||||
<SwapInfoPanel gasFee={gasFee} />
|
||||
|
||||
<PrimaryButton onClick={handleSwap} disabled={!quotePayload || isSwapping} />
|
||||
<PrimaryButton onClick={handleSwap} disabled={isButtonDisabled} />
|
||||
|
||||
{modalData && (
|
||||
<SwapConfirmModal
|
||||
@@ -118,6 +158,20 @@ export function SwapForm() {
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{trxModalQuote && (
|
||||
<TrxConfirmModal
|
||||
quote={trxModalQuote}
|
||||
fromSymbol={fromToken.symbol}
|
||||
toSymbol={toToken.symbol}
|
||||
amountHuman={fromAmount}
|
||||
onClose={() => setTrxModalQuote(null)}
|
||||
onConfirm={() => {
|
||||
executeTrxSwap(trxModalQuote.quoteId)
|
||||
setTrxModalQuote(null)
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user