Skip to content

Commit

Permalink
Merge pull request #1046 from cowprotocol/refactor/new-swap-form-p4
Browse files Browse the repository at this point in the history
[SWAP REFACTORING #4.4] new swap page, merge develop, code cleanup
  • Loading branch information
shoom3301 authored Sep 19, 2022
2 parents 10695c2 + 084e448 commit 0e04879
Show file tree
Hide file tree
Showing 75 changed files with 815 additions and 568 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/ipfs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ env:
REPO_NAME_SLUG: cowswap
REACT_APP_PINATA_API_KEY: ${{ secrets.REACT_APP_PINATA_API_KEY }}
REACT_APP_PINATA_SECRET_API_KEY: ${{ secrets.REACT_APP_PINATA_SECRET_API_KEY }}
# Duplicated keys as these are required by `ipfs-deploy`
IPFS_DEPLOY_PINATA__API_KEY: ${{ secrets.REACT_APP_PINATA_API_KEY }}
IPFS_DEPLOY_PINATA__SECRET_API_KEY: ${{ secrets.REACT_APP_PINATA_SECRET_API_KEY }}

jobs:
ipfs:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ It allows you to buy and sell tokens using gas-less orders that are settled peer
- Protocol: <https://cow.fi>
- Docs: <https://docs.cow.fi>
- Stats: <https://dune.xyz/gnosis.protocol/Gnosis-Protocol-V2>
- Twitter: [@MEVprotection](https://twitter.com/MEVprotection)
- Twitter: [@CoWSwap](https://twitter.com/CoWSwap)
- Discord: <https://discord.com/invite/cowprotocol>

Please see the:
Expand Down
6 changes: 3 additions & 3 deletions cypress-custom/integration/swap.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ describe('Swap (custom)', () => {
cy.get('#swap-currency-input .token-amount-input').should('be.visible')
cy.get('#swap-currency-input .token-amount-input').type('0.5', { force: true, delay: 200 })
cy.get('#swap-currency-output .token-amount-input').should('not.equal', '')
cy.get('#swap-button').click()
cy.get('#swap-button').should('contain.text', 'Swap').click()
cy.get('#confirm-swap-or-send').should('contain', 'Confirm Swap')
})

Expand All @@ -40,8 +40,8 @@ describe('Swap (custom)', () => {
// cy.get('.token-item-0xc7AD46e0b8a400Bb3C915120d284AafbA8fc4735').click({ force: true })
// input amounts
cy.get('#swap-currency-input .token-amount-input').should('be.visible')
cy.get('#swap-currency-input .token-amount-input').type('0.001', { force: true, delay: 400 })
cy.get('#swap-currency-input .token-amount-input').type('0.0007', { force: true, delay: 400 })
cy.get('#swap-currency-output .token-amount-input').should('not.equal', '')
cy.get('#swap-button').should('contain', 'Switch to WETH')
cy.get('#swap-button').should('contain', 'Swap with WETH')
})
})
10 changes: 5 additions & 5 deletions cypress-custom/integration/swapMod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ describe('Swap (mod)', () => {
cy.visit('/#/swap')
})

it('starts with an Native/USDC swap and quotes it', () => {
cy.get('#swap-currency-input .token-amount-input').should('have.value', '1')
it('starts with wrapped native selected', () => {
cy.get('#swap-currency-input .token-amount-input').should('not.have.value')
cy.get('#swap-currency-input .token-symbol-container').should('contain.text', 'WETH')
cy.get('#swap-currency-output .token-amount-input').should('not.have.value', '')
cy.get('#swap-currency-output .token-symbol-container').should('contain.text', 'USDC')
cy.get('#swap-currency-output .token-amount-input').should('not.have.value')
cy.get('#swap-currency-output .token-symbol-container').should('contain.text', 'Select a token')
})

it('can enter an amount into input', () => {
Expand Down Expand Up @@ -67,7 +67,7 @@ describe('Swap (mod)', () => {
cy.get('#swap-currency-input .token-amount-input').should('be.visible')
cy.get('#swap-currency-input .token-amount-input').type('{selectall}{backspace}{selectall}{backspace}').type('0.5')
cy.get('#swap-currency-output .token-amount-input').should('not.equal', '')
cy.get('#swap-button').click()
cy.get('#swap-button').should('contain.text', 'Swap').click()
cy.get('#confirm-swap-or-send').should('contain', 'Confirm Swap')
})

Expand Down
7 changes: 3 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
},
"types": "./dist/widgets.d.ts",
"private": true,
"version": "1.20.3",
"version": "1.21.0",
"engines": {
"node": ">=14.0.0"
},
Expand Down Expand Up @@ -150,7 +150,7 @@
"build": "yarn i18n:compile && craco build && yarn writeVersion",
"build:analyze": "cross-env REACT_APP_ANALYZE_BUNDLE=true yarn craco build && yarn writeVersion",
"ipfs:build": "cross-env PUBLIC_URL=\".\" yarn build",
"ipfs:publish": "ipfs-deploy build -p infura -O",
"ipfs:publish": "ipfs-deploy build -p pinata -O",
"test": "NODE_PATH=src/custom craco test --env=jsdom",
"test:debug": "NODE_PATH=src/custom craco --inspect-brk test --runInBand --no-cache",
"eject": "react-scripts eject",
Expand Down Expand Up @@ -298,7 +298,6 @@
"workbox-core": "^6.1.0",
"workbox-navigation-preload": "^6.1.0",
"workbox-precaching": "^6.1.0",
"workbox-routing": "^6.1.0",
"xstate": "^4.33.4"
"workbox-routing": "^6.1.0"
}
}
4 changes: 2 additions & 2 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

<!-- Twitter media tags -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@MEVprotection">
<meta name="twitter:site" content="@CoWSwap">
<meta name="twitter:title" content="CoW Swap | The smartest way to trade cryptocurrencies">
<meta name="twitter:image" content="https://cowswap.exchange/images/og-meta-cowswap.png?v=2">

Expand Down Expand Up @@ -64,7 +64,7 @@
<li><a href="https://chat.cowswap.exchange">Chat</a></li>
<li><a href="https://docs.cow.fi">Docs</a></li>
<li><a href="https://dune.xyz/gnosis.protocol/Gnosis-Protocol-V2">Stats</a></li>
<li><a href="https://twitter.com/MEVprotection">Twitter (@MEVprotection)</a></li>
<li><a href="https://twitter.com/CoWSwap">Twitter (@CoWSwap)</a></li>
</ul>
</main>
</noscript>
Expand Down
2 changes: 1 addition & 1 deletion src/components/AddressInputPanel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export default function AddressInputPanel({
<InputContainer>
<AutoColumn gap="md">
<RowBetween>
<ThemedText.Black color={theme.text2} fontWeight={500} fontSize={14}>
<ThemedText.Black color={theme.text1} fontWeight={500} fontSize={14}>
{label ?? <Trans>Recipient</Trans>}
</ThemedText.Black>
{address && chainId && (
Expand Down
8 changes: 1 addition & 7 deletions src/components/swap/SwapHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,7 @@ const StyledSwapHeader = styled.div`
color: ${({ theme }) => theme.text2};
`

export default function SwapHeader({
allowedSlippage,
className = '',
}: {
allowedSlippage: Percent
className?: string
}) {
export default function SwapHeader({ allowedSlippage, className }: { allowedSlippage: Percent; className?: string }) {
return (
<StyledSwapHeader className={className}>
<RowBetween>
Expand Down
5 changes: 4 additions & 1 deletion src/components/swap/confirmPriceImpactWithoutFee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@ export default function confirmPriceImpactWithoutFee(priceImpactWithoutFee: Perc
)}%. Please type the word "confirm" to continue with this swap.`
) === 'confirm'
)
} else if (!priceImpactWithoutFee.lessThan(ALLOWED_PRICE_IMPACT_HIGH)) {
}

if (!priceImpactWithoutFee.lessThan(ALLOWED_PRICE_IMPACT_HIGH)) {
return window.confirm(
`This swap has a price impact of at least ${ALLOWED_PRICE_IMPACT_HIGH.toFixed(
0
)}%. Please confirm that you would like to continue with this swap.`
)
}

return true
}
1 change: 1 addition & 0 deletions src/cosmos.decorator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { MetaMask } from '@web3-react/metamask'
import { BlockNumberProvider } from '@src/lib/hooks/useBlockNumber'

const Wrapper = styled(Flex)`
font-family: 'Inter var', sans-serif;
padding: 1.2rem 0.6rem;
justify-content: center;
align-items: center;
Expand Down
2 changes: 1 addition & 1 deletion src/custom/components/AccountDetails/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ export default function AccountDetails({
</AccountGroupingRow>
</InfoCard>

{!!pendingTransactions.length || !!confirmedTransactions.length ? (
{activityTotalCount ? (
<LowerSection>
<span>
{' '}
Expand Down
2 changes: 1 addition & 1 deletion src/custom/components/Header/HeaderMod.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export const HeaderFrame = styled.div<{ showBackground: boolean }>`
position: relative;
border-bottom: ${({ theme }) => theme.header.border};
padding: 1rem;
z-index: 4;
z-index: 2;
/*position: relative;
/!* Background slide effect on scroll. *!/
background-image: ${({ theme }) => `linear-gradient(to bottom, transparent 50%, ${theme.bg0} 50% )}}`};
Expand Down
47 changes: 29 additions & 18 deletions src/custom/components/Header/NetworkSelector/NetworkSelectorMod.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { getConnection } from 'connection/utils'
import { getChainInfo } from 'constants/chainInfo'
import { CHAIN_IDS_TO_NAMES, SupportedChainId } from 'constants/chains'
import useParsedQueryString from 'hooks/useParsedQueryString'
import usePrevious from 'hooks/usePrevious'
// import usePrevious from 'hooks/usePrevious'
import { ParsedQs } from 'qs'
import { useCallback, useEffect, useRef } from 'react'
import { AlertTriangle, ChevronDown } from 'react-feather'
Expand Down Expand Up @@ -277,21 +277,21 @@ function Row({
<ActiveRowWrapper>
{rowContent}
<ActiveRowLinkList>
{bridge ? (
{bridge && (
<ExternalLink href={bridge}>
<BridgeLabel chainId={chainId} /> <LinkOutCircle />
</ExternalLink>
) : null}
{explorer ? (
)}
{explorer && (
<ExternalLink href={explorer}>
<ExplorerLabel chainId={chainId} /> <LinkOutCircle />
</ExternalLink>
) : null}
{helpCenterUrl ? (
)}
{helpCenterUrl && (
<ExternalLink href={helpCenterUrl}>
<Trans>Help Center</Trans> <LinkOutCircle />
</ExternalLink>
) : null}
)}

{supportedChainId(chainId) && (
<ExternalLink href={getExplorerBaseUrl(chainId)}>
Expand Down Expand Up @@ -336,11 +336,11 @@ export const NETWORK_SELECTOR_CHAINS = [

export default function NetworkSelector() {
const dispatch = useAppDispatch()
const { chainId, provider, connector } = useWeb3React()
const previousChainId = usePrevious(chainId)
const { chainId, provider, connector, account } = useWeb3React()
// const previousChainId = usePrevious(chainId)
const parsedQs = useParsedQueryString()
const { urlChain, urlChainId } = getParsedChainId(parsedQs)
const previousUrlChainId = usePrevious(urlChainId)
// const previousUrlChainId = usePrevious(urlChainId)
const node = useRef<HTMLDivElement>(null)
const isOpen = useModalIsOpen(ApplicationModal.NETWORK_SELECTOR)
const openModal = useOpenModal(ApplicationModal.NETWORK_SELECTOR)
Expand All @@ -350,6 +350,9 @@ export default function NetworkSelector() {
const isSmartContractWallet = useIsSmartContractWallet() // mod
const isUnsupportedNetwork = !supportedChainId(chainId)

// MOD - to keep track of the switching in progress and avoid race conditions
const isSwitching = useRef(false)

const addPopup = useAddPopup()
const removePopup = useRemovePopup()

Expand All @@ -359,11 +362,15 @@ export default function NetworkSelector() {
async (targetChain: SupportedChainId, skipClose?: boolean) => {
if (!connector) return

isSwitching.current = true

const connectionType = getConnection(connector).type

try {
dispatch(updateConnectionError({ connectionType, error: undefined }))
await switchChain(connector, targetChain)
// Update URL right after network change
history.replace({ search: replaceURLParam(history.location.search, 'chain', getChainNameFromId(targetChain)) })
} catch (error) {
console.error('Failed to switch networks', error)

Expand All @@ -374,25 +381,29 @@ export default function NetworkSelector() {
if (!skipClose) {
closeModal()
}

isSwitching.current = false
},
[connector, dispatch, addPopup, closeModal]
[connector, dispatch, history, addPopup, closeModal]
)

useEffect(() => {
if (!chainId || !previousChainId) return

// when network change originates from wallet or dropdown selector, just update URL
if (chainId !== previousChainId && chainId !== urlChainId) {
if (isSwitching.current) {
// if wallet switching is in progress, avoid triggering it again
return
}
if (account && chainId && chainId !== urlChainId) {
// if wallet is connected and chainId already set, keep the url param in sync
history.replace({ search: replaceURLParam(history.location.search, 'chain', getChainNameFromId(chainId)) })
// otherwise assume network change originates from URL
} else if (urlChainId && urlChainId !== previousUrlChainId && urlChainId !== chainId) {
} else if (urlChainId && chainId && urlChainId !== chainId) {
// if chain and url chainId are both set and differ, try to update chainid
onSelectChain(urlChainId, true).catch(() => {
// we want app network <-> chainId param to be in sync, so if user changes the network by changing the URL
// but the request fails, revert the URL back to current chainId
history.replace({ search: replaceURLParam(history.location.search, 'chain', getChainNameFromId(chainId)) })
})
}
}, [chainId, urlChainId, previousChainId, previousUrlChainId, onSelectChain, history])
}, [account, chainId, history, onSelectChain, urlChainId])

// set chain parameter on initial load if not there
useEffect(() => {
Expand Down
2 changes: 1 addition & 1 deletion src/custom/components/SideBanner/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { IS_SIDE_BANNER_VISIBLE_KEY } from '@src/constants/misc'
const WIDTH = 440
const HEIGHT = 440
const ANNIVERSARY_TWEET_TEMPLATE =
'Holy CoW, today @MEVprotection is 1 year old! Check out their UI growth over time to see the CoW-evolution https://youtu.be/nxU11DmBVMk'
'Holy CoW, today @CoWSwap is 1 year old! Check out their UI growth over time to see the CoW-evolution https://youtu.be/nxU11DmBVMk'

// create an enum with the types of banners we want to show
export enum BannerType {
Expand Down
7 changes: 5 additions & 2 deletions src/custom/components/WalletModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import WalletModalMod, { WalletModalProps } from './WalletModalMod'
import { ExternalLink } from 'theme'
import { Trans } from '@lingui/macro'
import { Routes } from 'constants/routes'
import { StyledInternalLink } from 'theme/components'

// export * from '@src/components/WalletModal'

Expand All @@ -16,8 +17,10 @@ function CustomTerms() {
<TermsWrapper>
<Trans>
By connecting a wallet, you agree to GnosisDAO&apos;s{' '}
<ExternalLink href={Routes.TERMS_CONDITIONS}>Terms &amp; Conditions</ExternalLink> and acknowledge that you have
read, understood, and agree to them.{' '}
<StyledInternalLink style={{ marginRight: 5 }} to={Routes.TERMS_CONDITIONS} target="_blank">
Terms &amp; Conditions
</StyledInternalLink>
and acknowledge that you have read, understood, and agree to them.{' '}
</Trans>
</TermsWrapper>
)
Expand Down
3 changes: 3 additions & 0 deletions src/custom/components/swap/EthFlow/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Wrap/unwrap flow

![wrap/unwrap flow](http://www.plantuml.com/plantuml/png/bLHDRzim3BtdLt3f8Oc1fjimO803R0Y6Tjrb1PeEkUmYMtIiLQ44IQuR3FllesGxTJzMO3d4iKG-liT7nWVXmYHVJSW41ATsTSZXfaQej6b1YuRA6ZqOqWTeQoGG49oG2AMX81JrL-StbsTR_e9vwuGzQoW-4iPYDL4LpBzvm7kBBi3US3QIA3JApmi84NH-GB-O05Wceu8o1DFpKNJ4cS9l3W28ODyHfGTXhJDtGZy50SYpR9qk4OAvHSgoLJfF6ZLMB75JcqPBA10a-jAf0YNNSjW5elO8Sp8T799KrUfO_LAm5ZBDheQeqd8cYQ26Ob08BQXariPrlJeI702PtpRsPvmsSEnPzavi427BfjidJPrc6PoUVXfnFMeVaSqt65wco0eKsIP0sJY7L1xwX2lBbxxbAcnlfTnU93FO1A4V6i1UZcEUsnW_9rPet3b4og-R7ZJDr4-EOrbvEhhWawLjzdengFV1s9TCY8YARlDrONWiOkuB6OFsFvE7vD5CFMjZcgcJuZs-hJxcF19jD8oyA5Fyynv0gqBDXjXOYNPSMWHaDwEewLhlZG-n4mxVm8NHKIs_CH4VqFhbSZcDv4wg3zKxBDWTal1r3NY7562MNg-SH3UBKNsZ7zlKkpZkDyotnrMBdUfWnp9wpXAjyIemsL9e3QQ2jB1nZnr7nff3qs3-OxJ0hwB6XtIYVHMsi-KLwMf78-dvMah-do5yR4SmNC-XREuPiOuh9cyUhdrdHhT6-HTjM4eab7ppgNfiwTfXvn08EW0wPvn_Ehx_O7aUWsV0MpsxnbzOXaIscyh_c9rKSqnscD_nl1_FkjRnFASVVm40)
51 changes: 51 additions & 0 deletions src/custom/components/swap/EthFlow/ethFlow.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
@startuml
start
:;
note right: The flow launches only when a trade contains only ETH/WETH (wrap/unwrap flow);
if (Is expert mode enabled?) then (yes)
partition "Expert mode flow" {
if (Needs approval?) then (yes)
:**Approve token**;
note left: Should be described more;
else (no)
endif;
if (Has enough wrapped native token balance for trade?) then (no)
:**Wrap native token**;
note right: See **"Wrap/unwrap flow"** -->
else (yes)
endif;
:Set wrapped native token as input currency;
:Open swap confirmation modal;
if (Is swap confirmed?) then (yes)
#palegreen:Run swap flow \n (See: swapFlow.puml);
stop;
else (no)
#pink:Abort swap;
stop;
endif;
}
else (no)
partition "Wrap/unwrap flow" {
#b2e0f7:Show transaction confirmation modal with **pending state:** \n "Almost there! Follow these steps...";
#f4f1eb:Send GA event 'Send Order';
if (Is input currency native?) then (yes (Wrap flow))
:Send transaction with **deposit** call of WETH contract;
else (no (Unwrap flow))
:Send transaction with **withdraw** call of WETH contract;
endif;

#f4f1eb:Send GA event 'Sign Order';
:Add a new transaction to **redux enhancedTransactions state**;
:Close all modals;

if (Are there any errors?) then (yes)
#f4f1eb:Send GA event 'Error' or 'Reject';
#pink:Show transaction confirmation modal with **error state**;
stop;
else (no)
stop;
endif;
}
endif;
@enduml

Loading

0 comments on commit 0e04879

Please sign in to comment.