diff --git a/src/features/wallet/api/walletApi.ts b/src/features/wallet/api/walletApi.ts index 8f7e874..f5a37ab 100644 --- a/src/features/wallet/api/walletApi.ts +++ b/src/features/wallet/api/walletApi.ts @@ -193,6 +193,50 @@ export async function getRelayQuote(payload: RelayQuotePayload): Promise('/api/relay/quote', payload) } +export interface RelaySwapStep { + id: string + action: string + description: string + kind: string + items: Array<{ + status: string + data: { + from: string + to: string + data: string + value: string + chainId: number + gas: string + maxFeePerGas: string + maxPriorityFeePerGas: string + } + check: { + endpoint: string + method: string + } + }> + requestId: string +} + +export interface RelaySwapResponse { + steps: RelaySwapStep[] + fees: RelayQuoteResponse['fees'] + details: { + operation: string + sender: string + recipient: string + currencyIn: { amount: string; amountFormatted: string; amountUsd: string; currency: unknown } + currencyOut: { amount: string; amountFormatted: string; amountUsd: string; currency: unknown } + totalImpact: { usd: string; percent: string } + rate: string + timeEstimate: number + } +} + +export async function executeRelaySwap(payload: RelayQuotePayload): Promise { + return walletPost('/api/relay/execute/swap', payload) +} + export async function createWallet(): Promise { await walletPost('/api/wallets/create', {}) } diff --git a/src/features/wallet/index.ts b/src/features/wallet/index.ts index 75640f1..603371e 100644 --- a/src/features/wallet/index.ts +++ b/src/features/wallet/index.ts @@ -1,3 +1,3 @@ -export { useAllWalletBalances, usePrices, useSendWallet, useWalletAddresses, useWalletBalance, usePortfolio, useTokensList, useRelayQuote, useCreateWallet, useRevealMnemonic } from './model/useWalletData' -export type { Chain, FormattedAmount, WalletBalanceData, PriceEntry, SendWalletPayload, SendWalletResponse, WalletAddress, PortfolioData, PortfolioChain, PortfolioNative, PortfolioToken, TokenInfo, RelayQuotePayload, RelayQuoteResponse } from './api/walletApi' +export { useAllWalletBalances, usePrices, useSendWallet, useWalletAddresses, useWalletBalance, usePortfolio, useTokensList, useRelayQuote, useExecuteRelaySwap, useCreateWallet, useRevealMnemonic } from './model/useWalletData' +export type { Chain, FormattedAmount, WalletBalanceData, PriceEntry, SendWalletPayload, SendWalletResponse, WalletAddress, PortfolioData, PortfolioChain, PortfolioNative, PortfolioToken, TokenInfo, RelayQuotePayload, RelayQuoteResponse, RelaySwapResponse, RelaySwapStep } from './api/walletApi' export { CHAINS } from './api/walletApi' diff --git a/src/features/wallet/model/useWalletData.ts b/src/features/wallet/model/useWalletData.ts index 518b16a..38f7016 100644 --- a/src/features/wallet/model/useWalletData.ts +++ b/src/features/wallet/model/useWalletData.ts @@ -1,5 +1,5 @@ import { useQuery, useQueries, useMutation } from '@tanstack/react-query' -import { getWalletBalance, getPrices, sendWallet, getWalletAddresses, getPortfolio, getTokensList, getRelayQuote, createWallet, revealMnemonic, CHAINS, type Chain, type SendWalletPayload, type RelayQuotePayload } from '../api/walletApi' +import { getWalletBalance, getPrices, sendWallet, getWalletAddresses, getPortfolio, getTokensList, getRelayQuote, executeRelaySwap, createWallet, revealMnemonic, CHAINS, type Chain, type SendWalletPayload, type RelayQuotePayload } from '../api/walletApi' export function useWalletBalance(chain: Chain) { return useQuery({ @@ -82,3 +82,9 @@ export function useRelayQuote(payload: RelayQuotePayload | null) { staleTime: 10_000, }) } + +export function useExecuteRelaySwap() { + return useMutation({ + mutationFn: (payload: RelayQuotePayload) => executeRelaySwap(payload), + }) +} diff --git a/src/widgets/swap-form/ui/SwapForm.tsx b/src/widgets/swap-form/ui/SwapForm.tsx index 35d28c0..77e7c89 100644 --- a/src/widgets/swap-form/ui/SwapForm.tsx +++ b/src/widgets/swap-form/ui/SwapForm.tsx @@ -1,6 +1,6 @@ import { useState, useEffect } from 'react' import { PrimaryButton } from '@shared/ui' -import { useWalletBalance, useWalletAddresses, useTokensList, useRelayQuote, type Chain } from '@features/wallet' +import { useWalletBalance, useWalletAddresses, useTokensList, useRelayQuote, useExecuteRelaySwap, type Chain } from '@features/wallet' import { useDebounce } from '@shared/lib/hooks/useDebounce' import { TOKENS_LIST, buildTokensFromBalance, useSwapForm } from '../model/useSwapForm' import { SwapCard } from './SwapCard' @@ -61,11 +61,17 @@ export function SwapForm() { : null const { data: quoteData } = useRelayQuote(quotePayload) + const { mutate: executeSwap, isPending: isSwapping } = useExecuteRelaySwap() const displayToAmount = quoteData?.details.currencyOut.amountFormatted ?? '0' const displayToUsd = quoteData?.details.currencyOut.amountUsd const gasFee = quoteData?.fees.gas.amountUsd + function handleSwap() { + if (!quotePayload) return + executeSwap(quotePayload) + } + return (
- +
) } diff --git a/src/widgets/swap-form/ui/SwapInfoPanel.module.css b/src/widgets/swap-form/ui/SwapInfoPanel.module.css index b914aca..c187e52 100644 --- a/src/widgets/swap-form/ui/SwapInfoPanel.module.css +++ b/src/widgets/swap-form/ui/SwapInfoPanel.module.css @@ -4,6 +4,7 @@ border-radius: 20px; padding: 4px 24px; margin-bottom: 24px; + margin-top: 24px; } .row { @@ -39,4 +40,4 @@ .link:hover { text-decoration: underline; -} +} \ No newline at end of file