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

feat: fiat on ramp integration #7065

Merged
merged 104 commits into from
Jun 22, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
104 commits
Select commit Hold shift + click to select a range
35f2623
update: init push
Jun 6, 2023
b678f86
chore: remove btn
Jun 6, 2023
8ff070b
chore: remove semi-colon
Jun 6, 2023
17fc356
chore: fix linit bug
Jun 6, 2023
384d099
chore: temporary quick fixes for build errors
Jun 6, 2023
b486871
update: start quote generator
Jun 6, 2023
a87a39c
update: start custom hooks for provider fetch
Jun 6, 2023
6d0bbb9
update: optimise quote builder to handle bad resp
Jun 7, 2023
ee13c6f
chore:type issue
Jun 7, 2023
9d42e61
chore: build
Jun 7, 2023
360d1c2
test: test commit for deploy cors error
Jun 7, 2023
8823e0b
chore: import
Jun 7, 2023
6f172a4
fix: mercuryo url
Jun 7, 2023
06fac57
update: optimised provider signature signing
Jun 7, 2023
30ca262
update: added ip-adress filtering
Jun 7, 2023
19c350a
fix: cleanup some things
Jun 7, 2023
a5dae8f
fix: deploy version crash
Jun 7, 2023
8ef4e3f
fix: ui changes
Jun 8, 2023
ac7ab4e
update: refactor
Jun 12, 2023
8ba2d43
update: refactor
Jun 12, 2023
9867c43
fix: image issue
Jun 12, 2023
cb2dc90
fix: translations
Jun 14, 2023
5c8a749
fix transaltions
Jun 14, 2023
6d4c9ad
update buy crypto link on wall page
Jun 14, 2023
cef7455
update: merc quote api fix
Jun 14, 2023
06e50a1
chore: api domain
Jun 14, 2023
ae4f330
update: fix mercuryo hmax method
Jun 14, 2023
d2c331c
Chore: use merc test deployment widget
Jun 14, 2023
b042849
fix: jau widget id change
Jun 14, 2023
f1e8983
update: show providers even no quotes
Jun 14, 2023
7422883
mercuryo prod
Jun 15, 2023
b1ae545
pord widget
Jun 15, 2023
c0e365e
chore: mercuryo debug prod
Jun 15, 2023
87029ac
prod merc iframe creds
Jun 15, 2023
1bfefe6
qa review updates
Jun 17, 2023
029042e
chore: deploy issue rename logo files
Jun 17, 2023
b1ddddc
fix images
Jun 17, 2023
63ba30f
chore deploy
Jun 17, 2023
c40d33f
image deploy bug
Jun 17, 2023
d8baaef
fix: qa updates
Jun 19, 2023
0b39362
chore: eth mercuryo
Jun 19, 2023
c8f9833
chre: mercuryo didnt display
Jun 19, 2023
29f2953
chore: update bsc list
Jun 19, 2023
d394cda
chore: remove eth on bnb
Jun 19, 2023
8a50818
qa fixes
Jun 20, 2023
a074324
chore: qa issues and review comments
Jun 20, 2023
ca3b1c7
fix: only merc provider
Jun 20, 2023
78c8501
chore: fix mercy light logo
Jun 20, 2023
bb4afd9
fix: qa feedback (#7180)
chefilip Jun 20, 2023
507c74d
chore: Update currency
Jun 20, 2023
9bd665d
chore: Update VND flag
Jun 20, 2023
3787671
chore: Set minimum amount
Jun 21, 2023
0105aaf
chore: remove Provider fee
Jun 21, 2023
bb73b22
chore: update maxAmount
Jun 21, 2023
99069f2
chore: Update maxAmount
Jun 21, 2023
d8ac9de
chore: Refactor default amoutn calc
Jun 21, 2023
bf1d5c5
chore: Update reducer type
Jun 21, 2023
491cd01
final refactor
Jun 21, 2023
0eee358
chore: remove log
Jun 21, 2023
ce6c958
chore: revert back to prod merc
Jun 21, 2023
6b92c69
chore: update supported token list
Jun 21, 2023
0e638e9
fix imports
Jun 21, 2023
58ad2e9
chore: fix theme
Jun 21, 2023
acedf8a
env
Jun 21, 2023
c5900cb
fix sonarlint code smell
Jun 21, 2023
bb69453
chore: change buy crypto order
Jun 21, 2023
2a01c42
fix swap page entry point
Jun 21, 2023
971a08b
fiat curr
Jun 21, 2023
ffdb74f
chore: widget id
Jun 22, 2023
4a329bb
chore: fiat search input text
Jun 22, 2023
ca35e2b
fix: Prevent crash when no mercuryWidget
Jun 22, 2023
097c88e
chore: fix mercury widget crop issue
Jun 22, 2023
ae4abdb
Merge branch 'feat--fiat-on-ramp-integration' of https://github.com/p…
Jun 22, 2023
09ddcd5
chore: preload script before open modal
Jun 22, 2023
6e2c765
chore: Update format amount
Jun 22, 2023
41c27d4
chore: Update format
Jun 22, 2023
a5619bb
chore: Update script loaded
Jun 22, 2023
44d2c53
chore: Update script
Jun 22, 2023
d5307b8
fix: wrong amount
Jun 22, 2023
53658c8
chore: Update minAmount
Jun 22, 2023
1fe9eed
fix: FAQs
Jun 22, 2023
4cf23d3
Merge branch 'feat--fiat-on-ramp-integration' of https://github.com/p…
Jun 22, 2023
a0bcfe0
fix: revert widget dimensions
Jun 22, 2023
91922a1
fix: faq
Jun 22, 2023
ffb415e
chore: Refactor code
Jun 22, 2023
58a0942
chore: Update code
Jun 22, 2023
205aa5e
chore: Update swap ui
Jun 22, 2023
c317cb8
fix: last few items
Jun 22, 2023
b597722
fix ticket 10
Jun 22, 2023
4806bc9
chore: chainid useeffect dep
Jun 22, 2023
feb3974
chore: Revert package json
Jun 22, 2023
6884868
Merge remote-tracking branch 'upstream/develop' into feat--fiat-on-ra…
Jun 22, 2023
155b5f9
chore: Update yaml block
Jun 22, 2023
cd18dcc
chore: Update check window object
Jun 22, 2023
b2d7b23
chore: Update eslint
Jun 22, 2023
499edaa
chore: Update menu
Jun 22, 2023
684b5b1
chore: Update line
Jun 22, 2023
eefdd4b
chore: Update snapshot
Jun 22, 2023
368c9e8
fix: only show by-crypto redirect for whitelist
Jun 22, 2023
50ae1c2
Merge branch 'feat--fiat-on-ramp-integration' of https://github.com/p…
Jun 22, 2023
47f4df5
chore: Update env
Jun 22, 2023
c78d40a
chore: Add trans
Jun 22, 2023
1ddd82e
Merge branch 'feat--fiat-on-ramp-integration' of github.com:pancakesw…
Jun 22, 2023
f9ef8af
chore: Update unit test
Jun 22, 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
8 changes: 7 additions & 1 deletion apps/web/.env
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
NEXT_PUBLIC_MM_API_URL=https://linked-pool.pancakeswap.com/quote-service
NEXT_PUBLIC_QUOTING_API=https://swap-quoting.pancakeswap.com/quoting-service
NEXT_PUBLIC_QUOTING_API=https://swap-quoting.pancakeswap.com/quoting-service
MOONPAY_URL=https://buy-sandbox.moonpay.com?apiKey=pk_test_1Ibe44lMglFVL8COOYO7SEKnIBrzrp54
MOONPAY_TEST_SECRET_KEY=sk_test_7zfPNfcZdStyiktn3lOJxOltGttayhC
MOONPAY_TEST_API_KEY=sk_test_7zfPNfcZdStyiktn3lOJxOltGttayhC
chefilip marked this conversation as resolved.
Show resolved Hide resolved
REACT_APP_MOONPAY_API="https://api.moonpay.com"
REACT_APP_MOONPAY_PUBLISHABLE_KEY="pk_test_1Ibe44lMglFVL8COOYO7SEKnIBrzrp54"

1 change: 1 addition & 0 deletions apps/web/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ const config = {
__SENTRY_TRACING__: false,
}),
)
webpackConfig.module.rules.push({ test: /\.svg$/, use: ["@svgr/webpack"] });
chefilip marked this conversation as resolved.
Show resolved Hide resolved
if (!isServer && webpackConfig.optimization.splitChunks) {
// webpack doesn't understand worker deps on quote worker, so we need to manually add them
// https://github.com/webpack/webpack/issues/16895
Expand Down
17 changes: 9 additions & 8 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@
"@pancakeswap/v3-sdk": "workspace:*",
"@pancakeswap/wagmi": "workspace:*",
"@reduxjs/toolkit": "^1.9.1",
"@tanstack/react-query": "^4.28.0",
"@sentry/nextjs": "^7.52.1",
"@snapshot-labs/snapshot.js": "^0.4.40",
"@tanstack/react-query": "^4.28.0",
"@vanilla-extract/next-plugin": "^2.1.1",
"ajv": "^6.12.3",
"bignumber.js": "^9.0.0",
Expand All @@ -67,6 +67,7 @@
"easymde": "^2.16.1",
"ethers": "^5.7.0",
"fast-json-stable-stringify": "^2.1.0",
"geoip-lite": "^1.4.7",
"graphql": "^16.6.0",
"graphql-request": "^5.0.0",
"jotai": "^2.1.0",
Expand All @@ -79,6 +80,7 @@
"next-axiom": "^0.13.0",
"next-seo": "^5.15.0",
"next-themes": "^0.2.0",
"polished": "^4.2.2",
"qs": "^6.0.0",
"react": "^18.2.0",
"react-countup": "^6.4.0",
Expand All @@ -98,16 +100,17 @@
"styled-system": "^5.1.5",
"swiper": "^8.4.2",
"swr": "^2.1.5",
"typescript": "^5.0.4",
"wagmi": "1.0.9",
"zod": "^3.21.4",
"polished": "^4.2.2",
"tiny-invariant": "^1.1.0",
"typescript": "^5.0.4",
"uuid": "^8.0.0",
"viem": "^0.3.39"
"viem": "^0.3.39",
"wagmi": "1.0.9",
"zod": "^3.21.4"
},
"devDependencies": {
"@next/eslint-plugin-next": "13.4.2",
"@pancakeswap/next-config": "workspace:*",
"@pancakeswap/tsconfig": "workspace:*",
"@stylelint/postcss-css-in-js": "^0.37.2",
"@testing-library/jest-dom": "^5.16.2",
"@testing-library/react": "^13.3.0",
Expand Down Expand Up @@ -148,8 +151,6 @@
"stylelint-config-standard": "^25.0.0",
"stylelint-config-styled-components": "^0.1.1",
"tilg": "^0.1.1",
"@pancakeswap/tsconfig": "workspace:*",
"@pancakeswap/next-config": "workspace:*",
"typechain": "^6.1.0",
"vite-tsconfig-paths": "^4.0.3",
"vitest": "^0.30.1"
Expand Down
1 change: 1 addition & 0 deletions apps/web/public/fiatCurrencies/euro.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/web/public/fiatCurrencies/gbp.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/web/public/fiatCurrencies/usd.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions apps/web/src/components/Card/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ export const LightGreyCard = styled(Card)`
background-color: ${({ theme }) => theme.colors.background};
`

export const CryptoCard = styled(Card)`
border: 1px solid ${({ theme }) => theme.colors.cardBorder};
background-color: ${({ theme }) => theme.colors.dropdown};
transition: height 0.4s ease-in-out, background-color 0.1s ease-in-out;
overflow: hidden;
&:hover {
background-color: ${({ theme }) => theme.colors.input};
cursor: pointer;
}
`

export const GreyCard = styled(Card)`
background-color: ${({ theme }) => theme.colors.dropdown};
`
Expand Down
16 changes: 12 additions & 4 deletions apps/web/src/components/CurrencyInputPanel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
Swap as SwapUI,
ArrowDropDownIcon,
} from '@pancakeswap/uikit'
import { useRouter } from 'next/router'
import styled, { css } from 'styled-components'
import { isAddress } from 'utils'
import { useTranslation } from '@pancakeswap/localization'
Expand Down Expand Up @@ -76,7 +77,7 @@ interface CurrencyInputPanelProps {
zapStyle?: ZapStyle
beforeButton?: React.ReactNode
disabled?: boolean
error?: boolean
error?: boolean | string
showUSDPrice?: boolean
tokensToShow?: Token[]
currencyLoading?: boolean
Expand Down Expand Up @@ -115,6 +116,8 @@ const CurrencyInputPanel = memo(function CurrencyInputPanel({
const { address: account } = useAccount()
const selectedCurrencyBalance = useCurrencyBalance(account ?? undefined, currency ?? undefined)
const { t } = useTranslation()
const { pathname } = useRouter()
const mode = id

const token = pair ? pair.liquidityToken : currency?.isToken ? currency : null
const tokenAddress = token ? isAddress(token.address) : null
Expand All @@ -137,6 +140,7 @@ const CurrencyInputPanel = memo(function CurrencyInputPanel({
commonBasesType={commonBasesType}
showSearchInput={showSearchInput}
tokensToShow={tokensToShow}
mode={mode}
/>,
)

Expand Down Expand Up @@ -168,19 +172,23 @@ const CurrencyInputPanel = memo(function CurrencyInputPanel({
const isAtPercentMax = (maxAmount && value === maxAmount.toExact()) || (lpPercent && lpPercent === '100')

const balance = !hideBalance && !!currency && formatAmount(selectedCurrencyBalance, 6)

return (
<SwapUI.CurrencyInputPanel
id={id}
disabled={disabled}
error={error}
error={error as any}
zapStyle={zapStyle}
value={value}
onInputBlur={onInputBlur}
onUserInput={handleUserInput}
loading={inputLoading}
top={
<>
{pathname === '/buy-crypto' ? (
<Text px="4px" bold fontSize="12px" textTransform="uppercase" color="secondary">
{t('I want to spend')}
</Text>
) : null}
<Flex alignItems="center">
{beforeButton}
<CurrencySelectButton
Expand Down Expand Up @@ -235,7 +243,7 @@ const CurrencyInputPanel = memo(function CurrencyInputPanel({
</Flex>
) : null}
</Flex>
{account && (
{account && pathname !== '/buy-crypto' && (
<Text
onClick={!disabled && onMax}
color="textSubtle"
Expand Down
159 changes: 159 additions & 0 deletions apps/web/src/components/FiatOnRampModal/FiatOnRampModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import { Trans, useTranslation } from '@pancakeswap/localization'
import { Button, Flex, InjectedModalProps, Modal, Spinner, useModal } from '@pancakeswap/uikit'
import { LoadingDot } from '@pancakeswap/uikit/src/widgets/Liquidity'
import { useFiatOnrampAvailability } from 'hooks/useCheckAvailability'
import { memo, useCallback, useEffect, useState } from 'react'
import styled, { useTheme } from 'styled-components'
import { ErrorText } from 'views/Swap/components/styleds'
import { useAccount } from 'wagmi'

const StyledIframe = styled.iframe<{ isDark: boolean }>`
// #1c1c1e is the background color for the darkmode moonpay iframe as of 2/16/2023
// background-color: #1c1c1e;
border-bottom-left-radius: 24px;
border-bottom-right-radius: 24px;

height: calc(100% - 75px);
position: absolute;
// right: 0;
width: 100%;
`

const MOONPAY_SUPPORTED_CURRENCY_CODES = [
'eth',
'eth_arbitrum',
'eth_optimism',
'eth_polygon',
'weth',
'wbtc',
'matic_polygon',
'polygon',
'usdc_arbitrum',
'usdc_optimism',
'usdc_polygon',
]

export const FiatOnRampModalButton = () => {
const { t } = useTranslation()
const [shouldCheck, setShouldCheck] = useState<boolean>(false)
const [onPresentConfirmModal] = useModal(<FiatOnRampModal />)

const { fiatOnarampAvailability, availabilityChecked, loading, error } = useFiatOnrampAvailability(
shouldCheck,
onPresentConfirmModal,
)

const handleBuyCryptoClick = useCallback(() => {
if (!availabilityChecked) {
setShouldCheck(true)
} else if (fiatOnarampAvailability) {
onPresentConfirmModal()
setShouldCheck(false)
}
}, [fiatOnarampAvailability, availabilityChecked, onPresentConfirmModal])

const disableBuyCryptoButton = Boolean(error || (!fiatOnarampAvailability && availabilityChecked) || loading)

return (
<>
{!disableBuyCryptoButton ? (
<Button height="35px" onClick={handleBuyCryptoClick} disabled={false} isLoading={false} variant="secondary">
{t('Buy Crypto')}
</Button>
) : null}
</>
)
}

export const FiatOnRampModal = memo<InjectedModalProps>(function ConfirmSwapModalComp({ onDismiss }) {
const [error, setError] = useState<boolean | string | null>(false)
const [signedIframeUrl, setSignedIframeUrl] = useState<string | null>(null)
const [loading, setLoading] = useState<boolean>(true)

const theme = useTheme()
const account = useAccount()
const { t } = useTranslation()

const handleDismiss = useCallback(() => {
onDismiss?.()
}, [onDismiss])

const fetchSignedIframeUrl = useCallback(async () => {
if (!account.address) {
setError(t('Please connect an account before making a purchase.'))
return
}
setLoading(true)
setError(null)
try {
const res = await fetch(`/api/onramp-url-sign/sign-moonpay-url`, {
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
method: 'POST',
body: JSON.stringify({
type: 'MOONPAY',
defaultCurrencyCode: 'eth',
redirectUrl: 'https://pancakeswap.finance',
theme: theme.isDark ? 'dark' : 'light',
walletAddresses: JSON.stringify(
MOONPAY_SUPPORTED_CURRENCY_CODES.reduce(
(acc, currencyCode) => ({
...acc,
[currencyCode]: account.address,
}),
{},
),
),
}),
})
const result = await res.json()
setSignedIframeUrl(result.urlWithSignature)
} catch (e) {
setError(e.toString())
} finally {
setLoading(false)
}
}, [account.address, theme.isDark, t])

useEffect(() => {
fetchSignedIframeUrl()
}, [fetchSignedIframeUrl])

return (
<>
<Modal
title="Buy Crypto In One Click"
onDismiss={handleDismiss}
bodyPadding="0px"
headerBackground="gradientCardHeader"
height="650px" // height has to be overidden
width="350px" // width has to be overidden
>
{error ? (
<Flex justifyContent="center" alignItems="center" alignContent="center">
<ErrorText>
<Trans>something went wrong!</Trans>
</ErrorText>
</Flex>
) : loading ? (
<Flex flexDirection="column" justifyContent="center" alignItems="center" alignContent="center">
<Spinner />
<LoadingDot />
</Flex>
) : (
<StyledIframe
id="moonpayIframe"
src={signedIframeUrl ?? ''}
frameBorder="0"
title="fiat-onramp-iframe"
isDark={theme.isDark}
/>
)}
</Modal>
</>
)
})

export default FiatOnRampModal
44 changes: 44 additions & 0 deletions apps/web/src/components/FiatOnRampModal/MercuryoOnrampModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { useTranslation } from '@pancakeswap/localization'
import { Button, InjectedModalProps, Modal, useModal } from '@pancakeswap/uikit'
import { memo, useCallback, useEffect } from 'react'

export const FiatOnRampModalButtonMercury = () => {
const { t } = useTranslation()
const [onPresentConfirmModal] = useModal(<FiatOnRampModalMecuryo />)

return (
<Button height="35px" onClick={onPresentConfirmModal} disabled={false} isLoading={false} variant="secondary">
{t('Buy Crypto')}
</Button>
)
}

export const FiatOnRampModalMecuryo = memo<InjectedModalProps>(function ConfirmSwapModalComp({ onDismiss }) {
const handleDismiss = useCallback(() => {
onDismiss?.()
}, [onDismiss])

useEffect(() => {
// @ts-ignore
const MC_WIDGET = mercuryoWidget
MC_WIDGET.run({
widgetId: '64d1f9f9-85ee-4558-8168-1dc0e7057ce6',
host: document.getElementById('mercuryo-widget'),
})
}, [])

return (
<Modal
title="Buy Crypto In One Click"
onDismiss={handleDismiss}
bodyPadding="0px"
headerBackground="gradientCardHeader"
height="600px" // height has to be overidden
width="370px" // width has to be overidden
>
<div id="mercuryo-widget" />
</Modal>
)
})

export default FiatOnRampModalMecuryo
Loading