diff --git a/src/components/TransactionSettings/index.tsx b/src/components/TransactionSettings/index.tsx index 918ce4f3342..9a5f94ac3fc 100644 --- a/src/components/TransactionSettings/index.tsx +++ b/src/components/TransactionSettings/index.tsx @@ -1,13 +1,14 @@ -import React, { useState, useRef, useContext } from 'react' +import { CeloContract } from '@celo/contractkit' +import Toggle from 'components/Toggle' +import { darken } from 'polished' +import React, { useContext, useRef, useState } from 'react' +import { useUserFeeCurrency } from 'state/user/hooks' import styled, { ThemeContext } from 'styled-components' - -import QuestionHelper from '../QuestionHelper' import { TYPE } from '../../theme' import { AutoColumn } from '../Column' +import QuestionHelper from '../QuestionHelper' import { RowBetween, RowFixed } from '../Row' -import { darken } from 'polished' - enum SlippageError { InvalidInput = 'InvalidInput', RiskyLow = 'RiskyLow', @@ -99,6 +100,7 @@ export default function SlippageTabs({ rawSlippage, setRawSlippage, deadline, se const [slippageInput, setSlippageInput] = useState('') const [deadlineInput, setDeadlineInput] = useState('') + const [feeCurrency, setFeeCurrency] = useUserFeeCurrency() const slippageInputIsValid = slippageInput === '' || (rawSlippage / 100).toFixed(2) === Number.parseFloat(slippageInput).toFixed(2) @@ -247,6 +249,24 @@ export default function SlippageTabs({ rawSlippage, setRawSlippage, deadline, se + + + + + Use Celo as fee currency + + + + setFeeCurrency(CeloContract.GoldToken) + : () => setFeeCurrency(CeloContract.StableToken) + } + /> + ) } diff --git a/src/state/user/actions.ts b/src/state/user/actions.ts index ee171b8bf35..1ad49d6bdbe 100644 --- a/src/state/user/actions.ts +++ b/src/state/user/actions.ts @@ -1,3 +1,4 @@ +import { CeloToken } from '@celo/contractkit' import { createAction } from '@reduxjs/toolkit' export interface SerializedToken { @@ -17,6 +18,7 @@ export const updateMatchesDarkMode = createAction<{ matchesDarkMode: boolean }>( export const updateUserDarkMode = createAction<{ userDarkMode: boolean }>('user/updateUserDarkMode') export const updateUserExpertMode = createAction<{ userExpertMode: boolean }>('user/updateUserExpertMode') export const updateUserSingleHopOnly = createAction<{ userSingleHopOnly: boolean }>('user/updateUserSingleHopOnly') +export const updateUserFeeCurrency = createAction<{ userFeeCurrency: CeloToken }>('user/updateUserFeeCurrency') export const updateUserSlippageTolerance = createAction<{ userSlippageTolerance: number }>( 'user/updateUserSlippageTolerance' ) diff --git a/src/state/user/hooks.tsx b/src/state/user/hooks.tsx index e28fb87a439..c9a350fbdcb 100644 --- a/src/state/user/hooks.tsx +++ b/src/state/user/hooks.tsx @@ -1,3 +1,4 @@ +import { CeloToken } from '@celo/contractkit' import { Pair, Token } from '@ubeswap/sdk' import { IValoraAccount } from 'connectors/valora/valoraUtils' import flatMap from 'lodash.flatmap' @@ -20,6 +21,7 @@ import { updateUserDarkMode, updateUserDeadline, updateUserExpertMode, + updateUserFeeCurrency, updateUserSingleHopOnly, updateUserSlippageTolerance, } from './actions' @@ -129,6 +131,25 @@ export function useUserSingleHopOnly(): [boolean, (newSingleHopOnly: boolean) => return [singleHopOnly, setSingleHopOnly] } +export function useUserFeeCurrency(): [CeloToken, (newFeeCurrency: CeloToken) => void] { + const dispatch = useDispatch() + + const feeCurrency = useSelector((state) => state.user.userFeeCurrency) + + const setFeeCurrency = useCallback( + (newFeeCurrency: CeloToken) => { + ReactGA.event({ + category: 'Routing', + action: `fees in ${newFeeCurrency}`, + }) + dispatch(updateUserFeeCurrency({ userFeeCurrency: newFeeCurrency })) + }, + [dispatch] + ) + + return [feeCurrency, setFeeCurrency] +} + export function useUserSlippageTolerance(): [number, (slippage: number) => void] { const dispatch = useDispatch() const userSlippageTolerance = useSelector((state) => { diff --git a/src/state/user/reducer.ts b/src/state/user/reducer.ts index 4d70ddef350..3040adde3c5 100644 --- a/src/state/user/reducer.ts +++ b/src/state/user/reducer.ts @@ -1,3 +1,4 @@ +import { CeloContract, CeloToken } from '@celo/contractkit' import { createReducer } from '@reduxjs/toolkit' import { DEFAULT_DEADLINE_FROM_NOW, INITIAL_ALLOWED_SLIPPAGE } from '../../constants' import { updateVersion } from '../global/actions' @@ -15,6 +16,7 @@ import { updateUserDarkMode, updateUserDeadline, updateUserExpertMode, + updateUserFeeCurrency, updateUserSingleHopOnly, updateUserSlippageTolerance, } from './actions' @@ -32,6 +34,8 @@ export interface UserState { userSingleHopOnly: boolean // only allow swaps on direct pairs + userFeeCurrency: CeloToken + // user defined slippage tolerance in bips, used in all txns userSlippageTolerance: number @@ -70,6 +74,7 @@ export const initialState: UserState = { matchesDarkMode: false, userExpertMode: false, userSingleHopOnly: false, + userFeeCurrency: CeloContract.StableToken, userSlippageTolerance: INITIAL_ALLOWED_SLIPPAGE, userDeadline: DEFAULT_DEADLINE_FROM_NOW, tokens: {}, @@ -119,6 +124,9 @@ export default createReducer(initialState, (builder) => .addCase(updateUserSingleHopOnly, (state, action) => { state.userSingleHopOnly = action.payload.userSingleHopOnly }) + .addCase(updateUserFeeCurrency, (state, action) => { + state.userFeeCurrency = action.payload.userFeeCurrency + }) .addCase(addSerializedToken, (state, { payload: { serializedToken } }) => { state.tokens[serializedToken.chainId] = state.tokens[serializedToken.chainId] || {} state.tokens[serializedToken.chainId][serializedToken.address] = serializedToken