From 97fb265460425ab2161b71c74f00357407774613 Mon Sep 17 00:00:00 2001 From: pedromcunha Date: Mon, 2 Dec 2024 17:24:55 -0500 Subject: [PATCH 1/4] Add onSwapValidating callback to widget --- .../components/common/TransactionModal/SwapModal.tsx | 11 ++++++++++- .../ui/src/components/widgets/SwapWidget/index.tsx | 3 +++ .../ui/src/components/widgets/WidgetContainer.tsx | 3 +++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/ui/src/components/common/TransactionModal/SwapModal.tsx b/packages/ui/src/components/common/TransactionModal/SwapModal.tsx index abb0cea1d..37f3bd5ed 100644 --- a/packages/ui/src/components/common/TransactionModal/SwapModal.tsx +++ b/packages/ui/src/components/common/TransactionModal/SwapModal.tsx @@ -43,6 +43,7 @@ type SwapModalProps = { onAnalyticEvent?: (eventName: string, data?: any) => void onOpenChange: (open: boolean) => void onSuccess?: (data: Execute) => void + onSwapValidating?: (data: Execute) => void } export const SwapModal: FC = (swapModalProps) => { @@ -64,7 +65,8 @@ export const SwapModal: FC = (swapModalProps) => { wallet, invalidateBalanceQueries, onAnalyticEvent, - onSuccess + onSuccess, + onSwapValidating } = swapModalProps return ( = (swapModalProps) => { onAnalyticEvent={onAnalyticEvent} onValidating={(quote) => { const steps = quote?.steps + const details = quote?.details + const fees = quote?.fees onAnalyticEvent?.(EventNames.TRANSACTION_VALIDATING, { quote_id: steps ? extractQuoteId(steps) : undefined }) + onSwapValidating?.({ + steps: steps, + fees: fees, + details: details + }) }} onSuccess={(quote, steps) => { const details = quote?.details diff --git a/packages/ui/src/components/widgets/SwapWidget/index.tsx b/packages/ui/src/components/widgets/SwapWidget/index.tsx index a8332bf99..a447385c5 100644 --- a/packages/ui/src/components/widgets/SwapWidget/index.tsx +++ b/packages/ui/src/components/widgets/SwapWidget/index.tsx @@ -53,6 +53,7 @@ type BaseSwapWidgetProps = { onToTokenChange?: (token?: Token) => void onConnectWallet?: () => void onAnalyticEvent?: (eventName: string, data?: any) => void + onSwapValidating?: (data: Execute) => void onSwapSuccess?: (data: Execute) => void onSwapError?: (error: string, data?: Execute) => void } @@ -97,6 +98,7 @@ const SwapWidget: FC = ({ onConnectWallet, onAnalyticEvent, onSwapSuccess, + onSwapValidating, onSwapError }) => { const relayClient = useRelayClient() @@ -274,6 +276,7 @@ const SwapWidget: FC = ({ }} useExternalLiquidity={useExternalLiquidity} onSwapSuccess={onSwapSuccess} + onSwapValidating={onSwapValidating} onAnalyticEvent={onAnalyticEvent} invalidateBalanceQueries={invalidateBalanceQueries} customToAddress={customToAddress} diff --git a/packages/ui/src/components/widgets/WidgetContainer.tsx b/packages/ui/src/components/widgets/WidgetContainer.tsx index 3d5bc5c9f..fb83ca4ef 100644 --- a/packages/ui/src/components/widgets/WidgetContainer.tsx +++ b/packages/ui/src/components/widgets/WidgetContainer.tsx @@ -21,6 +21,7 @@ export type WidgetContainerProps = { onSwapModalOpenChange: (open: boolean) => void onAnalyticEvent?: (eventName: string, data?: any) => void onSwapSuccess?: (data: Execute) => void + onSwapValidating?: (data: Execute) => void invalidateBalanceQueries: () => void } & Pick< ChildrenProps, @@ -68,6 +69,7 @@ const WidgetContainer: FC = ({ multiWalletSupportEnabled, onSwapModalOpenChange, onSwapSuccess, + onSwapValidating, onAnalyticEvent, invalidateBalanceQueries, setCustomToAddress @@ -99,6 +101,7 @@ const WidgetContainer: FC = ({ timeEstimate={timeEstimate} onAnalyticEvent={onAnalyticEvent} onSuccess={onSwapSuccess} + onSwapValidating={onSwapValidating} invalidateBalanceQueries={invalidateBalanceQueries} wallet={wallet} linkedWallets={linkedWallets} From 8d62614c8c932bd39cb3035b780b4469c74e355a Mon Sep 17 00:00:00 2001 From: pedromcunha Date: Mon, 2 Dec 2024 17:25:27 -0500 Subject: [PATCH 2/4] feat: changeset --- .changeset/fluffy-ducks-smoke.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/fluffy-ducks-smoke.md diff --git a/.changeset/fluffy-ducks-smoke.md b/.changeset/fluffy-ducks-smoke.md new file mode 100644 index 000000000..72aa5b48d --- /dev/null +++ b/.changeset/fluffy-ducks-smoke.md @@ -0,0 +1,5 @@ +--- +'@reservoir0x/relay-kit-ui': patch +--- + +Add onSwapValidating callback From c4e3afa75534a016fb045e14595c74e78658de1f Mon Sep 17 00:00:00 2001 From: pedromcunha Date: Tue, 3 Dec 2024 13:50:12 -0500 Subject: [PATCH 3/4] Use transaction data but fall back to quote data on success screen --- .../common/TransactionModal/SwapModal.tsx | 4 +- .../TransactionModalRenderer.tsx | 6 +- .../steps/SwapSuccessStep.tsx | 86 ++++++++++++++----- 3 files changed, 70 insertions(+), 26 deletions(-) diff --git a/packages/ui/src/components/common/TransactionModal/SwapModal.tsx b/packages/ui/src/components/common/TransactionModal/SwapModal.tsx index 37f3bd5ed..34d489c6e 100644 --- a/packages/ui/src/components/common/TransactionModal/SwapModal.tsx +++ b/packages/ui/src/components/common/TransactionModal/SwapModal.tsx @@ -201,7 +201,8 @@ const InnerSwapModal: FC = ({ multiWalletSupportEnabled, useExternalLiquidity, fromChain, - waitingForSteps + waitingForSteps, + isLoadingTransaction }) => { useEffect(() => { if (!open) { @@ -316,6 +317,7 @@ const InnerSwapModal: FC = ({ timeEstimate={timeEstimate?.formattedTime} isCanonical={isCanonical} details={details} + isLoadingTransaction={isLoadingTransaction} /> ) : null} {progressStep === TransactionProgressStep.Error ? ( diff --git a/packages/ui/src/components/common/TransactionModal/TransactionModalRenderer.tsx b/packages/ui/src/components/common/TransactionModal/TransactionModalRenderer.tsx index 356ab6fa1..cb3688f06 100644 --- a/packages/ui/src/components/common/TransactionModal/TransactionModalRenderer.tsx +++ b/packages/ui/src/components/common/TransactionModal/TransactionModalRenderer.tsx @@ -81,6 +81,7 @@ export type ChildrenProps = { swapImpact?: string } } | null + isLoadingTransaction: boolean } type Props = { @@ -405,7 +406,7 @@ export const TransactionModalRenderer: FC = ({ }, [steps, quoteError, swapError]) // Fetch Success Tx - const { data: transactions } = useRequests( + const { data: transactions, isFetching: isLoadingTransaction } = useRequests( (progressStep === TransactionProgressStep.Success || progressStep === TransactionProgressStep.Error) && allTxHashes[0] @@ -470,7 +471,8 @@ export const TransactionModalRenderer: FC = ({ setStartTimestamp, quoteUpdatedAt, requestId, - feeBreakdown + feeBreakdown, + isLoadingTransaction })} ) diff --git a/packages/ui/src/components/common/TransactionModal/steps/SwapSuccessStep.tsx b/packages/ui/src/components/common/TransactionModal/steps/SwapSuccessStep.tsx index 228c665d5..bf4c31b98 100644 --- a/packages/ui/src/components/common/TransactionModal/steps/SwapSuccessStep.tsx +++ b/packages/ui/src/components/common/TransactionModal/steps/SwapSuccessStep.tsx @@ -7,7 +7,8 @@ import { Pill, Text, ChainTokenIcon, - ChainIcon + ChainIcon, + Skeleton } from '../../../primitives/index.js' import { motion } from 'framer-motion' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' @@ -22,19 +23,21 @@ import { useRelayClient } from '../../../../hooks/index.js' import { faClockFour } from '@fortawesome/free-solid-svg-icons/faClockFour' import type { Execute } from '@reservoir0x/relay-sdk' import { bitcoin } from '../../../../utils/bitcoin.js' +import { formatBN } from '../../../../utils/numbers.js' type SwapSuccessStepProps = { fromToken?: Token toToken?: Token - fromAmountFormatted: string - toAmountFormatted: string + fromAmountFormatted?: string + toAmountFormatted?: string allTxHashes: TxHashes - transaction: ReturnType['data']['0'] + transaction?: ReturnType['data']['0'] seconds: number fillTime: string timeEstimate?: string isCanonical?: boolean details?: Execute['details'] | null + isLoadingTransaction?: boolean onOpenChange: (open: boolean) => void } @@ -50,21 +53,46 @@ export const SwapSuccessStep: FC = ({ timeEstimate, isCanonical, details, + isLoadingTransaction, onOpenChange }) => { const relayClient = useRelayClient() const isWrap = details?.operation === 'wrap' const isUnwrap = details?.operation === 'unwrap' + const _fromAmountFormatted = transaction?.data?.metadata?.currencyIn?.amount + ? formatBN( + transaction?.data?.metadata?.currencyIn?.amount, + 5, + transaction?.data?.metadata?.currencyIn?.currency?.decimals ?? 18 + ) + : fromAmountFormatted + const _fromToken = + transaction?.data?.metadata?.currencyIn?.currency ?? fromToken + const fromTokenLogoUri = + transaction?.data?.metadata?.currencyIn?.currency?.metadata?.logoURI ?? + fromToken?.logoURI + const _toAmountFormatted = transaction?.data?.metadata?.currencyOut?.amount + ? formatBN( + transaction?.data?.metadata?.currencyOut?.amount, + 5, + transaction?.data?.metadata?.currencyOut?.currency?.decimals ?? 18 + ) + : toAmountFormatted + const _toToken = transaction?.data?.metadata?.currencyOut?.currency ?? toToken + const toTokenLogoUri = + transaction?.data?.metadata?.currencyOut?.currency?.metadata?.logoURI ?? + toToken?.logoURI + const actionTitle = isWrap ? 'wrapped' : isUnwrap ? 'unwrapped' : 'swapped' const baseTransactionUrl = relayClient?.baseApiUrl.includes('testnets') ? 'https://testnets.relay.link' : 'https://relay.link' - const fromChain = fromToken - ? relayClient?.chains.find((chain) => chain.id === fromToken?.chainId) + const fromChain = _fromToken + ? relayClient?.chains.find((chain) => chain.id === _fromToken?.chainId) : null - const toChain = toToken - ? relayClient?.chains.find((chain) => chain.id === toToken?.chainId) + const toChain = _toToken + ? relayClient?.chains.find((chain) => chain.id === _toToken?.chainId) : null const delayedTxUrl = transaction?.data?.inTxs?.[0]?.hash ? `${baseTransactionUrl}/transaction/${transaction?.data?.inTxs?.[0]?.hash}` @@ -129,9 +157,9 @@ export const SwapSuccessStep: FC = ({ - Processing the order to swap {fromAmountFormatted} {fromToken?.symbol}{' '} - into {toAmountFormatted} {toToken?.symbol}, this will take ~ - {timeEstimate}. + Processing the order to swap {_fromAmountFormatted}{' '} + {_fromToken?.symbol} into {_toAmountFormatted} {_toToken?.symbol}, + this will take ~{timeEstimate}. @@ -282,19 +310,25 @@ export const SwapSuccessStep: FC = ({ - {fromToken ? ( + {_fromToken ? ( - - {fromAmountFormatted} {fromToken.symbol} - + {isLoadingTransaction ? ( + + ) : ( + + {_fromAmountFormatted} {_fromToken.symbol} + + )} ) : ( ? @@ -302,19 +336,25 @@ export const SwapSuccessStep: FC = ({ to - {toToken ? ( + {_toToken ? ( - - {toAmountFormatted} {toToken.symbol} - + {isLoadingTransaction ? ( + + ) : ( + + {_toAmountFormatted} {_toToken.symbol} + + )} ) : ( ? From 25d17faa800215f8f962e68d4802187c01091734 Mon Sep 17 00:00:00 2001 From: pedromcunha Date: Tue, 3 Dec 2024 13:50:44 -0500 Subject: [PATCH 4/4] feat: changeset --- .changeset/gorgeous-eggs-boil.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/gorgeous-eggs-boil.md diff --git a/.changeset/gorgeous-eggs-boil.md b/.changeset/gorgeous-eggs-boil.md new file mode 100644 index 000000000..999a94aa7 --- /dev/null +++ b/.changeset/gorgeous-eggs-boil.md @@ -0,0 +1,5 @@ +--- +'@reservoir0x/relay-kit-ui': patch +--- + +Use transaction data rather than quote data on success screen