Skip to content

Commit

Permalink
Add swap settings and review panel implementation (#5748)
Browse files Browse the repository at this point in the history
  • Loading branch information
walmat committed May 21, 2024
1 parent 68d1956 commit e078620
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 27 deletions.
47 changes: 21 additions & 26 deletions src/__swaps__/screens/Swap/components/ReviewPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,10 @@ import { ChainId } from '@/__swaps__/types/chains';
import { chainNameFromChainIdWorklet } from '@/__swaps__/utils/chains';
import { AnimatedSwitch } from './AnimatedSwitch';
import { GasButton } from '@/__swaps__/screens/Swap/components/GasButton';
import { ButtonPressAnimation } from '@/components/animations';
import { GestureHandlerV1Button } from './GestureHandlerV1Button';
import { StyleSheet, View } from 'react-native';
import { AnimatedChainImage } from './AnimatedChainImage';

const SLIPPAGE_STEP = 0.5;

const RainbowFee = () => {
const { isDarkMode } = useColorMode();

Expand All @@ -34,7 +32,7 @@ const RainbowFee = () => {

export function ReviewPanel() {
const { isDarkMode } = useColorMode();
const { configProgress, SwapInputController, internalSelectedInputAsset, internalSelectedOutputAsset } = useSwapContext();
const { configProgress, SwapSettings, SwapInputController, internalSelectedInputAsset, internalSelectedOutputAsset } = useSwapContext();

const unknown = i18n.t(i18n.l.swap.unknown);

Expand All @@ -44,8 +42,6 @@ export function ReviewPanel() {
: chainNameFromChainIdWorklet(internalSelectedOutputAsset.value?.chainId ?? ChainId.mainnet)
);

const slippageText = useDerivedValue(() => `1.5%`);

const [chain, setChain] = useState(ethereumUtils.getNetworkFromChainId(internalSelectedOutputAsset.value?.chainId ?? ChainId.mainnet));

const minimumReceived = useDerivedValue(() => {
Expand All @@ -55,8 +51,6 @@ export function ReviewPanel() {
return `${SwapInputController.inputValues.value.outputAmount} ${internalSelectedOutputAsset.value.symbol}`;
});

const flashbots = useDerivedValue(() => false);

const updateChainFromNetwork = useCallback((chainId: ChainId) => {
setChain(ethereumUtils.getNetworkFromChainId(chainId));
}, []);
Expand All @@ -70,17 +64,6 @@ export function ReviewPanel() {
}
);

const onSetSlippage = useCallback((operation: 'increment' | 'decrement') => {
'worklet';
const value = operation === 'increment' ? SLIPPAGE_STEP : -SLIPPAGE_STEP;
// SwapInputController.slippage.value = `${Math.max(0.5, Number(SwapInputController.slippage.value) + value)}`;
}, []);

const onSetFlashbots = useCallback(() => {
'worklet';
// SwapInputController.flashbots.value = !SwapInputController.flashbots.value;
}, []);

// TODO: Comes from gas store
const estimatedGasFee = useSharedValue('$2.25');
const estimatedArrivalTime = useSharedValue('~4 sec');
Expand Down Expand Up @@ -180,7 +163,7 @@ export function ReviewPanel() {
</Inline>
</Inline>

<AnimatedSwitch onToggle={onSetFlashbots} value={flashbots} activeLabel="On" inactiveLabel="Off" />
<AnimatedSwitch onToggle={SwapSettings.onToggleFlashbots} value={SwapSettings.flashbots} activeLabel="On" inactiveLabel="Off" />
</Inline>

<Inline horizontalSpace="10px" alignVertical="center" alignHorizontal="justify">
Expand All @@ -199,7 +182,7 @@ export function ReviewPanel() {
</Inline>

<Inline wrap={false} horizontalSpace="8px" alignVertical="center">
<ButtonPressAnimation onPress={() => onSetSlippage('decrement')}>
<GestureHandlerV1Button onPressWorklet={() => SwapSettings.onUpdateSlippage('minus')}>
<Box
style={{
justifyContent: 'center',
Expand All @@ -219,11 +202,23 @@ export function ReviewPanel() {
􀅽
</Text>
</Box>
</ButtonPressAnimation>

<AnimatedText size="15pt" weight="bold" color="labelSecondary" text={slippageText} />
</GestureHandlerV1Button>

<Inline space="2px">
<AnimatedText
align="right"
style={{ minWidth: 26 }}
size="15pt"
weight="bold"
color="labelSecondary"
text={SwapSettings.slippage}
/>
<Text size="15pt" weight="bold" color="labelSecondary">
%
</Text>
</Inline>

<ButtonPressAnimation onPress={() => onSetSlippage('increment')}>
<GestureHandlerV1Button onPressWorklet={() => SwapSettings.onUpdateSlippage('plus')}>
<Box
style={{
justifyContent: 'center',
Expand All @@ -243,7 +238,7 @@ export function ReviewPanel() {
􀅼
</Text>
</Box>
</ButtonPressAnimation>
</GestureHandlerV1Button>
</Inline>
</Inline>

Expand Down
2 changes: 2 additions & 0 deletions src/__swaps__/screens/Swap/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,5 @@ export const springConfig = { damping: 100, mass: 1.2, stiffness: 750 };

export const highPriceImpactThreshold = 0.05;
export const severePriceImpactThreshold = 0.1;

export const slippageStep = 0.5;
47 changes: 47 additions & 0 deletions src/__swaps__/screens/Swap/hooks/useSwapSettings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { ExtendedAnimatedAssetWithColors } from '@/__swaps__/types/assets';

import { SharedValue, runOnJS, useSharedValue } from 'react-native-reanimated';
import { swapsStore } from '@/state/swaps/swapsStore';
import { slippageStep } from '@/__swaps__/screens/Swap/constants';
import { getDefaultSlippageWorklet } from '@/__swaps__/utils/swaps';
import { ChainId } from '@/__swaps__/types/chains';
import { DEFAULT_CONFIG } from '@/model/remoteConfig';

export const useSwapSettings = ({ inputAsset }: { inputAsset: SharedValue<ExtendedAnimatedAssetWithColors | null> }) => {
const flashbots = useSharedValue(swapsStore.getState().flashbots);
const slippage = useSharedValue(getDefaultSlippageWorklet(inputAsset.value?.chainId ?? ChainId.mainnet, DEFAULT_CONFIG));

const setSlippage = swapsStore(state => state.setSlippage);
const setFlashbots = swapsStore(state => state.setFlashbots);

const onToggleFlashbots = () => {
'worklet';

const current = flashbots.value;
flashbots.value = !current;
runOnJS(setFlashbots)(!current);
};

const onUpdateSlippage = (operation: 'plus' | 'minus') => {
'worklet';

const value = operation === 'plus' ? slippageStep : -slippageStep;

// if we're trying to decrement below the minimum, set to the minimum
if (Number(slippage.value) + value <= slippageStep) {
slippage.value = slippageStep.toFixed(1).toString();
} else {
slippage.value = (Number(slippage.value) + value).toFixed(1).toString();
}

runOnJS(setSlippage)(slippage.value);
};

return {
flashbots,
slippage,

onToggleFlashbots,
onUpdateSlippage,
};
};
9 changes: 8 additions & 1 deletion src/__swaps__/screens/Swap/providers/swap-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@ import { useSwapNavigation, NavigationSteps } from '@/__swaps__/screens/Swap/hoo
import { useSwapInputsController } from '@/__swaps__/screens/Swap/hooks/useSwapInputsController';
import { ExtendedAnimatedAssetWithColors, ParsedSearchAsset } from '@/__swaps__/types/assets';
import { useSwapWarning } from '@/__swaps__/screens/Swap/hooks/useSwapWarning';
import { useSwapGas } from '@/__swaps__/screens/Swap/hooks/useSwapGas';
import { useSwapSettings } from '@/__swaps__/screens/Swap/hooks/useSwapSettings';
import { CrosschainQuote, Quote, QuoteError } from '@rainbow-me/swaps';
import { swapsStore } from '@/state/swaps/swapsStore';
import { isSameAsset } from '@/__swaps__/utils/assets';
import { parseAssetAndExtend } from '@/__swaps__/utils/swaps';
import { ChainId } from '@/__swaps__/types/chains';
import { logger } from '@/logger';
import { useSwapGas } from '../hooks/useSwapGas';

interface SwapContextType {
isFetching: SharedValue<boolean>;
Expand All @@ -51,6 +52,7 @@ interface SwapContextType {

quote: SharedValue<Quote | CrosschainQuote | QuoteError | null>;

SwapSettings: ReturnType<typeof useSwapSettings>;
SwapInputController: ReturnType<typeof useSwapInputsController>;
AnimatedSwapStyles: ReturnType<typeof useAnimatedSwapStyles>;
SwapTextStyles: ReturnType<typeof useSwapTextStyles>;
Expand Down Expand Up @@ -92,6 +94,10 @@ export const SwapProvider = ({ children }: SwapProviderProps) => {

const quote = useSharedValue<Quote | CrosschainQuote | QuoteError | null>(null);

const SwapSettings = useSwapSettings({
inputAsset: internalSelectedInputAsset,
});

const SwapGas = useSwapGas({
inputAsset: internalSelectedInputAsset,
outputAsset: internalSelectedOutputAsset,
Expand Down Expand Up @@ -348,6 +354,7 @@ export const SwapProvider = ({ children }: SwapProviderProps) => {

quote,

SwapSettings,
SwapInputController,
AnimatedSwapStyles,
SwapTextStyles,
Expand Down

0 comments on commit e078620

Please sign in to comment.