Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch route ux #306

Merged
merged 4 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/dry-donkeys-cheat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@reservoir0x/relay-kit-ui': patch
---

Fix ux issues with canonical route selector
5 changes: 4 additions & 1 deletion packages/ui/src/components/widgets/FeeBreakdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type Props = Pick<
| 'supportsExternalLiquidity'
| 'useExternalLiquidity'
| 'setUseExternalLiquidity'
| 'canonicalTimeEstimate'
> & {
toChain?: RelayChain
}
Expand All @@ -38,7 +39,8 @@ const FeeBreakdown: FC<Props> = ({
supportsExternalLiquidity,
useExternalLiquidity,
setUseExternalLiquidity,
timeEstimate
timeEstimate,
canonicalTimeEstimate
}) => {
const swapRate = price?.details?.rate
const originGasFee = feeBreakdown?.breakdown?.find(
Expand Down Expand Up @@ -91,6 +93,7 @@ const FeeBreakdown: FC<Props> = ({
onExternalLiquidityChange={(selected) => {
setUseExternalLiquidity(selected)
}}
canonicalTimeEstimate={canonicalTimeEstimate?.formattedTime}
/>
<Box css={{ height: 1, background: 'gray5', width: '100%' }} />
<Flex
Expand Down
13 changes: 8 additions & 5 deletions packages/ui/src/components/widgets/SwapRouteSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,17 @@ type Props = {
externalLiquidtySelected: boolean
onExternalLiquidityChange: (externalLiquiditySelected: boolean) => void
chain?: RelayChain
canonicalTimeEstimate?: string
}

const SwapRouteSelector: FC<Props> = ({
supportsExternalLiquidity,
externalLiquidtySelected,
onExternalLiquidityChange,
chain
chain,
canonicalTimeEstimate
}) => {
const [open, setOpen] = useState(false)
const chainName = chain?.displayName ?? ''
return (
<Dropdown
open={open}
Expand All @@ -29,7 +30,7 @@ const SwapRouteSelector: FC<Props> = ({
}
}}
contentProps={{
sideOffset: 12,
sideOffset: 8,
align: 'end',
css: {
maxWidth: 248,
Expand All @@ -49,12 +50,12 @@ const SwapRouteSelector: FC<Props> = ({
justifyContent: 'space-between',
flexDirection: 'row',
alignItems: 'center',
backgroundColor: 'transparent',
gap: '3',
px: '4',
py: '3',
borderRadius: 'widget-card-border-radius',
border: 'widget-card-border',

'&:disabled': {
cursor: 'default',
backgroundColor: 'transparent',
Expand Down Expand Up @@ -150,7 +151,9 @@ const SwapRouteSelector: FC<Props> = ({
<Flex direction="column">
<Text style="subtitle2">Native</Text>
<Text style="body3" color="subtle">
Standard time (&#62;2m), unlimited transaction capacity
{canonicalTimeEstimate
? `Standard time ~${canonicalTimeEstimate}, unlimited transaction capacity`
: 'Unlimited transaction capacity'}
</Text>
</Flex>
</DropdownMenuItem>
Expand Down
33 changes: 32 additions & 1 deletion packages/ui/src/components/widgets/SwapWidget/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import type { AdaptedWallet } from '@reservoir0x/relay-sdk'
import { evmDeadAddress, solDeadAddress } from '../../../constants/address.js'
import { MultiWalletDropdown } from '../../common/MultiWalletDropdown.js'
import { findSupportedWallet } from '../../../utils/solana.js'
import SwapRouteSelector from '../SwapRouteSelector.js'

type BaseSwapWidgetProps = {
defaultFromToken?: Token
Expand Down Expand Up @@ -156,6 +157,7 @@ const SwapWidget: FC<SwapWidgetProps> = ({
hasInsufficientBalance,
isInsufficientLiquidityError,
isCapacityExceededError,
isCouldNotExecuteError,
maxCapacityFormatted,
ctaCopy,
isFromNative,
Expand All @@ -165,6 +167,7 @@ const SwapWidget: FC<SwapWidgetProps> = ({
isValidToAddress,
supportsExternalLiquidity,
useExternalLiquidity,
canonicalTimeEstimate,
setUseExternalLiquidity,
setDetails,
setSwapError,
Expand Down Expand Up @@ -223,6 +226,10 @@ const SwapWidget: FC<SwapWidgetProps> = ({
isValidFromAddress
])

const promptSwitchRoute =
(isCapacityExceededError || isCouldNotExecuteError) &&
supportsExternalLiquidity

return (
<WidgetContainer
transactionModalOpen={transactionModalOpen}
Expand Down Expand Up @@ -798,6 +805,28 @@ const SwapWidget: FC<SwapWidgetProps> = ({
</Flex>
</Flex>
</TokenSelectorContainer>
{error && !isFetchingPrice ? (
<Box
css={{
borderRadius: 'widget-card-border-radius',
backgroundColor: 'widget-background',
overflow: 'hidden',
mb: '6px'
}}
>
<SwapRouteSelector
chain={toChain}
supportsExternalLiquidity={supportsExternalLiquidity}
externalLiquidtySelected={useExternalLiquidity}
canonicalTimeEstimate={
canonicalTimeEstimate?.formattedTime
}
onExternalLiquidityChange={(selected) => {
setUseExternalLiquidity(selected)
}}
/>
</Box>
) : null}
<FeeBreakdown
feeBreakdown={feeBreakdown}
isFetchingPrice={isFetchingPrice}
Expand All @@ -814,6 +843,7 @@ const SwapWidget: FC<SwapWidgetProps> = ({
route: enabled ? 'canonical' : 'relay'
})
}}
canonicalTimeEstimate={canonicalTimeEstimate}
/>
<WidgetErrorWell
hasInsufficientBalance={hasInsufficientBalance}
Expand All @@ -822,14 +852,15 @@ const SwapWidget: FC<SwapWidgetProps> = ({
currency={toToken}
isHighRelayerServiceFee={highRelayerServiceFee}
isCapacityExceededError={isCapacityExceededError}
isCouldNotExecuteError={isCouldNotExecuteError}
maxCapacity={maxCapacityFormatted}
relayerFeeProportion={relayerFeeProportion}
supportsExternalLiquidity={supportsExternalLiquidity}
containerCss={{
mb: '6px'
}}
/>
{error && supportsExternalLiquidity ? (
{promptSwitchRoute ? (
<Flex css={{ mt: '6px', gap: '3' }}>
{isCapacityExceededError &&
maxCapacityFormatted != '0' ? (
Expand Down
9 changes: 9 additions & 0 deletions packages/ui/src/components/widgets/SwapWidgetRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,15 @@ export type ChildrenProps = {
hasInsufficientBalance: boolean
isInsufficientLiquidityError?: boolean
isCapacityExceededError?: boolean
isCouldNotExecuteError?: boolean
maxCapacityWei?: string
maxCapacityFormatted?: string
ctaCopy: string
isFromNative: boolean
useExternalLiquidity: boolean
supportsExternalLiquidity: boolean
timeEstimate?: { time: number; formattedTime: string }
canonicalTimeEstimate?: { time: number; formattedTime: string }
fetchingExternalLiquiditySupport: boolean
isSvmSwap: boolean
isValidFromAddress: boolean
Expand Down Expand Up @@ -502,9 +504,14 @@ const SwapWidgetRenderer: FC<SwapWidgetRendererProps> = ({
const isCapacityExceededError = fetchQuoteDataErrorMessage?.includes(
'Amount is higher than the available liquidity'
)
const isCouldNotExecuteError =
fetchQuoteDataErrorMessage?.includes('Could not execute')
const highRelayerServiceFee = isHighRelayerServiceFeeUsd(price)
const relayerFeeProportion = calculateRelayerFeeProportionUsd(price)
const timeEstimate = calculatePriceTimeEstimate(price?.details)
const canonicalTimeEstimate = calculatePriceTimeEstimate(
externalLiquiditySupport.data?.details
)

const isFromNative = fromToken?.address === fromChain?.currency?.address

Expand Down Expand Up @@ -639,13 +646,15 @@ const SwapWidgetRenderer: FC<SwapWidgetRendererProps> = ({
hasInsufficientBalance,
isInsufficientLiquidityError,
isCapacityExceededError,
isCouldNotExecuteError,
maxCapacityFormatted,
maxCapacityWei,
ctaCopy,
isFromNative,
useExternalLiquidity,
supportsExternalLiquidity,
timeEstimate,
canonicalTimeEstimate,
fetchingExternalLiquiditySupport: externalLiquiditySupport.isFetching,
isSvmSwap,
isValidFromAddress,
Expand Down
8 changes: 7 additions & 1 deletion packages/ui/src/components/widgets/WidgetErrorWell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type Props = {
relayerFeeProportion?: bigint | 0
isHighRelayerServiceFee?: boolean
isCapacityExceededError?: boolean
isCouldNotExecuteError?: boolean
maxCapacity?: string
supportsExternalLiquidity?: boolean
containerCss?: Styles
Expand All @@ -29,6 +30,7 @@ export const WidgetErrorWell: FC<Props> = ({
relayerFeeProportion,
isHighRelayerServiceFee,
isCapacityExceededError,
isCouldNotExecuteError,
maxCapacity,
supportsExternalLiquidity,
containerCss
Expand Down Expand Up @@ -75,7 +77,11 @@ export const WidgetErrorWell: FC<Props> = ({
</Text>
</Flex>
)
} else if (supportsExternalLiquidity && currency) {
} else if (
supportsExternalLiquidity &&
isCouldNotExecuteError &&
currency
) {
return (
<Flex
align="center"
Expand Down