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

[3] feat(twap): add generic trade form validation to TWAP #2592

Merged
merged 31 commits into from
Jun 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
cf0074e
chore: group trade form states
shoom3301 May 31, 2023
cd8d21f
feat(trade-form-validation): validate basic trade form states
shoom3301 Jun 1, 2023
8a9845c
feat(trade-form-validation): component TradeFormButton
shoom3301 Jun 1, 2023
128dcf0
fix(trade-form-validation): extract primary validation from Limit orders
shoom3301 Jun 2, 2023
c5acec8
refactor(wrap-native-flow): narrow down WrapUnwrapContext
shoom3301 Jun 2, 2023
903c39b
feat(trade): add wrap native flow to TradeWidget
shoom3301 Jun 2, 2023
6570cab
feat(twap): add general trade form validation
shoom3301 Jun 2, 2023
16830fd
refactor: remove code duplicates by useTradeFormButtonContext
shoom3301 Jun 2, 2023
372a8b8
refactor: rename TradeFormButtons
shoom3301 Jun 2, 2023
6b91e98
Merge branch 'feat/2417' of https://github.com/cowprotocol/cowswap in…
shoom3301 Jun 2, 2023
bdf83fd
Merge branch 'feat/2417-1' of https://github.com/cowprotocol/cowswap …
shoom3301 Jun 2, 2023
d70b570
fix: fix performance issues
shoom3301 Jun 2, 2023
63a2dd9
refactor: refactor
shoom3301 Jun 2, 2023
7423946
Merge branch 'feat/2417' of https://github.com/cowprotocol/cowswap in…
shoom3301 Jun 2, 2023
9b1d871
refactor: refactor
shoom3301 Jun 2, 2023
c88e03f
Merge branch 'feat/2417-1' of https://github.com/cowprotocol/cowswap …
shoom3301 Jun 2, 2023
2382f45
refactor: refactor
shoom3301 Jun 2, 2023
d52111e
Merge branch 'develop' of https://github.com/cowprotocol/cowswap into…
shoom3301 Jun 2, 2023
4e55ed9
Merge branch 'feat/2417' of https://github.com/cowprotocol/cowswap in…
shoom3301 Jun 2, 2023
e9b1d83
chore: fix style errors
shoom3301 Jun 2, 2023
ce25f41
Merge branch 'feat/2417-1' of https://github.com/cowprotocol/cowswap …
shoom3301 Jun 2, 2023
f9b0a61
chore: fix e2e test
shoom3301 Jun 2, 2023
3266be7
Merge branch 'feat/2417' of https://github.com/cowprotocol/cowswap in…
shoom3301 Jun 2, 2023
e91513d
Merge branch 'feat/2417-1' of https://github.com/cowprotocol/cowswap …
shoom3301 Jun 2, 2023
2177b62
Merge branch 'develop' of https://github.com/cowprotocol/cowswap into…
shoom3301 Jun 5, 2023
ac8fbeb
refactor: align imports and fix namings
shoom3301 Jun 5, 2023
d1d0f78
Merge branch 'feat/2417' of https://github.com/cowprotocol/cowswap in…
shoom3301 Jun 5, 2023
486611b
fix(trade): change tokens places for wrap eth flow
shoom3301 Jun 5, 2023
5a7d5bd
Merge branch 'feat/2417-1' of https://github.com/cowprotocol/cowswap …
shoom3301 Jun 5, 2023
718a0a6
chore: merge changes
shoom3301 Jun 5, 2023
b382b45
Merge branch 'develop' of https://github.com/cowprotocol/cowswap into…
shoom3301 Jun 6, 2023
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
32 changes: 6 additions & 26 deletions src/modules/limitOrders/containers/TradeButtons/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,18 @@ import React from 'react'
import { Trans } from '@lingui/macro'

import { PriceImpact } from 'legacy/hooks/usePriceImpact'
import { useToggleWalletModal } from 'legacy/state/application/hooks'

import { useHandleOrderPlacement } from 'modules/limitOrders/hooks/useHandleOrderPlacement'
import { useLimitOrdersDerivedState } from 'modules/limitOrders/hooks/useLimitOrdersDerivedState'
import { useLimitOrdersWarningsAccepted } from 'modules/limitOrders/hooks/useLimitOrdersWarningsAccepted'
import { TradeFlowContext } from 'modules/limitOrders/services/types'
import { limitOrdersSettingsAtom } from 'modules/limitOrders/state/limitOrdersSettingsAtom'
import { useTradeConfirmActions, useWrapNativeFlow } from 'modules/trade'
import { useTradeConfirmActions } from 'modules/trade'
import {
TradeFormButtons,
useGetTradeFormValidation,
useTradeFormButtonContext,
TradeFormBlankButton,
TradeFormButtonContext,
} from 'modules/tradeFormValidation'
import { useTradeQuote } from 'modules/tradeQuote'
import { useWalletDetails } from 'modules/wallet'

import { limitOrdersTradeButtonsMap } from './limitOrdersTradeButtonsMap'

Expand All @@ -36,32 +32,16 @@ export function TradeButtons(props: TradeButtonsProps) {
const settingsState = useAtomValue(limitOrdersSettingsAtom)
const localFormValidation = useLimitOrdersFormState()
const primaryFormValidation = useGetTradeFormValidation()
const tradeState = useLimitOrdersDerivedState()
const toggleWalletModal = useToggleWalletModal()
const quote = useTradeQuote()
const warningsAccepted = useLimitOrdersWarningsAccepted(false)
const { isSupportedWallet } = useWalletDetails()
const tradeConfirmActions = useTradeConfirmActions()
const wrapNativeFlow = useWrapNativeFlow()

const handleTrade = useHandleOrderPlacement(tradeContext, priceImpact, settingsState, tradeConfirmActions)

const confirmTrade = tradeConfirmActions.onOpen
const isExpertMode = settingsState.expertMode

const tradeFormButtonContext: TradeFormButtonContext = {
defaultText: 'Limit order',
derivedState: tradeState,
doTrade: handleTrade,
quote,
isSupportedWallet,
wrapNativeFlow,
confirmTrade() {
tradeConfirmActions.onOpen()
},
connectWallet() {
toggleWalletModal()
},
}
const tradeFormButtonContext = useTradeFormButtonContext('Limit order', { doTrade: handleTrade, confirmTrade })

if (!tradeFormButtonContext) return null
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are still refactoring trade stuff, I say testing is needed!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, sorry for that :(
There are not so much changes in the existed code, anyway, there are


// Display local form validation errors only when there are no primary errors
if (!primaryFormValidation && localFormValidation) {
Expand Down
42 changes: 42 additions & 0 deletions src/modules/tradeFormValidation/hooks/useTradeFormButtonContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { useMemo } from 'react'

import { useToggleWalletModal } from 'legacy/state/application/hooks'

import { useWrapNativeFlow } from 'modules/trade'
import { useDerivedTradeState } from 'modules/trade/hooks/useDerivedTradeState'
import { useTradeQuote } from 'modules/tradeQuote'
import { useWalletDetails } from 'modules/wallet'

import { TradeFormButtonContext } from '../types'

interface TradeFormCallbacks {
doTrade(): void
confirmTrade(): void
}

export function useTradeFormButtonContext(
defaultText: string,
callbacks: TradeFormCallbacks
): TradeFormButtonContext | null {
const { state: derivedState } = useDerivedTradeState()
const wrapNativeFlow = useWrapNativeFlow()
const { isSupportedWallet } = useWalletDetails()
const quote = useTradeQuote()
const toggleWalletModal = useToggleWalletModal()

return useMemo(() => {
if (!derivedState) return null

return {
defaultText,
derivedState,
quote,
isSupportedWallet,
...callbacks,
wrapNativeFlow,
connectWallet() {
toggleWalletModal()
},
}
}, [defaultText, derivedState, quote, isSupportedWallet, callbacks, wrapNativeFlow, toggleWalletModal])
}
1 change: 1 addition & 0 deletions src/modules/tradeFormValidation/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './updaters/TradeFormValidationUpdater'
export * from './hooks/useGetTradeFormValidation'
export * from './hooks/useTradeFormButtonContext'
export * from './pure/TradeFormButtons'
export * from './pure/TradeFormBlankButton'
export * from './types'
43 changes: 43 additions & 0 deletions src/modules/twap/containers/ActionButtons/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from 'react'

import { useTradeConfirmActions } from 'modules/trade'
import { TradeFormButtons, useGetTradeFormValidation } from 'modules/tradeFormValidation'
import { useTradeFormButtonContext } from 'modules/tradeFormValidation'

import { useSetupFallbackHandler } from '../../hooks/useSetupFallbackHandler'
import { useTwapFormState } from '../../hooks/useTwapFormState'
import { PrimaryActionButton } from '../../pure/PrimaryActionButton'

export function ActionButtons() {
const setFallbackHandler = useSetupFallbackHandler()
const tradeConfirmActions = useTradeConfirmActions()
const localFormValidation = useTwapFormState()
const primaryFormValidation = useGetTradeFormValidation()

const primaryActionContext = {
setFallbackHandler,
openConfirmModal: tradeConfirmActions.onOpen,
}

const confirmTrade = tradeConfirmActions.onOpen

const tradeFormButtonContext = useTradeFormButtonContext('TWAP order', { doTrade: confirmTrade, confirmTrade })

if (!tradeFormButtonContext) return null

if (!primaryFormValidation && localFormValidation) {
return <PrimaryActionButton state={localFormValidation} context={primaryActionContext} />
}

return (
<TradeFormButtons
doTradeText="Place TWAP order"
confirmText="Review TWAP order"
validation={primaryFormValidation}
context={tradeFormButtonContext}
// TODO: bind isExpertMode to settings
isExpertMode={false}
isDisabled={false}
/>
)
}
16 changes: 2 additions & 14 deletions src/modules/twap/containers/TwapFormWidget/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
useAdvancedOrdersRawState,
useUpdateAdvancedOrdersRawState,
} from 'modules/advancedOrders'
import { useTradeConfirmActions } from 'modules/trade'
import { useIsWrapOrUnwrap } from 'modules/trade/hooks/useIsWrapOrUnwrap'
import { TradeNumberInput } from 'modules/trade/pure/TradeNumberInput'
import { TradeTextBox } from 'modules/trade/pure/TradeTextBox'
Expand All @@ -18,15 +17,13 @@ import { useRateInfoParams } from 'common/hooks/useRateInfoParams'
import * as styledEl from './styled'

import { DEFAULT_TWAP_SLIPPAGE, orderDeadlines, defaultNumOfParts } from '../../const'
import { useSetupFallbackHandler } from '../../hooks/useSetupFallbackHandler'
import { useTwapFormState } from '../../hooks/useTwapFormState'
import { AmountParts } from '../../pure/AmountParts'
import { DeadlineSelector } from '../../pure/DeadlineSelector'
import { PrimaryActionButton } from '../../pure/PrimaryActionButton'
import { partsStateAtom } from '../../state/partsStateAtom'
import { twapTimeIntervalAtom } from '../../state/twapOrderAtom'
import { twapOrdersSettingsAtom, updateTwapOrdersSettingsAtom } from '../../state/twapOrdersSettingsAtom'
import { deadlinePartsDisplay } from '../../utils/deadlinePartsDisplay'
import { ActionButtons } from '../ActionButtons'
import { TwapConfirmModal } from '../TwapConfirmModal'

export function TwapFormWidget() {
Expand All @@ -42,17 +39,8 @@ export function TwapFormWidget() {
const updateSettingsState = useUpdateAtom(updateTwapOrdersSettingsAtom)
const isWrapOrUnwrap = useIsWrapOrUnwrap()

const setFallbackHandler = useSetupFallbackHandler()
const tradeConfirmActions = useTradeConfirmActions()
const formState = useTwapFormState()

const rateInfoParams = useRateInfoParams(inputCurrencyAmount, outputCurrencyAmount)

const primaryActionContext = {
setFallbackHandler,
openConfirmModal: tradeConfirmActions.onOpen,
}

const deadlineState = {
deadline,
customDeadline,
Expand Down Expand Up @@ -112,7 +100,7 @@ export function TwapFormWidget() {
</TradeTextBox>
</styledEl.DeadlineRow>

<PrimaryActionButton state={formState} context={primaryActionContext} />
<ActionButtons />
</>
)
}
2 changes: 1 addition & 1 deletion src/modules/twap/hooks/useTwapFormState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { getTwapFormState, TwapFormState } from '../pure/PrimaryActionButton/get
import { verifyExtensibleFallback } from '../services/verifyExtensibleFallback'
import { twapOrderAtom } from '../state/twapOrderAtom'

export function useTwapFormState(): TwapFormState {
export function useTwapFormState(): TwapFormState | null {
const isSafeApp = useIsSafeApp()
const extensibleFallbackContext = useExtensibleFallbackContext()

Expand Down
13 changes: 6 additions & 7 deletions src/modules/twap/pure/PrimaryActionButton/getTwapFormState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,26 @@ export interface TwapFormStateParams {
twapOrder: TWAPOrder | null
}

// TODO: compose with common TradeFormState
export enum TwapFormState {
LOADING,
LOADING_SAFE_INFO,
NOT_SAFE,
ORDER_NOT_SPECIFIED, // TODO: reveal details
NEED_FALLBACK_HANDLER,
CAN_CREATE_ORDER,
}

export function getTwapFormState(props: TwapFormStateParams): TwapFormState {
export function getTwapFormState(props: TwapFormStateParams): TwapFormState | null {
const { isSafeApp, verification, twapOrder } = props

if (!isSafeApp) return TwapFormState.NOT_SAFE

if (verification === null) return TwapFormState.LOADING
if (verification === null) return TwapFormState.LOADING_SAFE_INFO

if (!twapOrder) return TwapFormState.ORDER_NOT_SPECIFIED

if (verification === ExtensibleFallbackVerification.HAS_DOMAIN_VERIFIER) {
return TwapFormState.CAN_CREATE_ORDER
if (verification !== ExtensibleFallbackVerification.HAS_DOMAIN_VERIFIER) {
return TwapFormState.NEED_FALLBACK_HANDLER
}

return TwapFormState.NEED_FALLBACK_HANDLER
return null
}
2 changes: 1 addition & 1 deletion src/modules/twap/pure/PrimaryActionButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export interface PrimaryActionButtonContext {
// TODO: extend with common trade widget states
// TODO: set correct buttons text
const buttonsMap: Record<TwapFormState, (context: PrimaryActionButtonContext) => JSX.Element> = {
[TwapFormState.LOADING]: () => (
[TwapFormState.LOADING_SAFE_INFO]: () => (
<ButtonPrimary disabled={true} buttonSize={ButtonSize.BIG}>
Loading...
</ButtonPrimary>
Expand Down
4 changes: 4 additions & 0 deletions src/pages/AdvancedOrders/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { AdvancedOrdersWidget } from 'modules/advancedOrders'
import { OrdersTableWidget } from 'modules/ordersTable'
import * as styledEl from 'modules/trade/pure/TradePageLayout'
import { TradeFormValidationUpdater } from 'modules/tradeFormValidation'

export default function AdvancedOrdersPage() {
return (
<>
{/*TODO: add isExpertMode value*/}
<TradeFormValidationUpdater isExpertMode={false} />

{/*TODO: add isUnlocked value*/}
<styledEl.PageWrapper isUnlocked={true}>
<styledEl.PrimaryWrapper>
Expand Down