Skip to content

Commit

Permalink
feat: ask for login with clicking buy with crypto and there is no wal…
Browse files Browse the repository at this point in the history
…let connected
  • Loading branch information
juanmahidalgo committed Nov 27, 2023
1 parent 59b1241 commit 382c0b6
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { connect } from 'react-redux'
import { replace } from 'connected-react-router'
import { Order } from '@dcl/schemas'
import { openModal } from 'decentraland-dapps/dist/modules/modal/actions'
import {
Expand All @@ -11,9 +12,12 @@ import { buyItemWithCardRequest } from '../../../../modules/item/actions'
import { Asset } from '../../../../modules/asset/types'
import { RootState } from '../../../../modules/reducer'
import { getIsBuyCrossChainEnabled } from '../../../../modules/features/selectors'
import { getWallet, isConnecting } from '../../../../modules/wallet/selectors'
import BuyNFTButtons from './BuyNFTButtons'

const mapState = (state: RootState): MapStateProps => ({
wallet: getWallet(state),
isConnecting: isConnecting(state),
isBuyCrossChainEnabled: getIsBuyCrossChainEnabled(state)
})

Expand All @@ -26,7 +30,8 @@ const mapDispatch = (dispatch: MapDispatch): MapDispatchProps => ({
order
})
),
onBuyItemWithCard: item => dispatch(buyItemWithCardRequest(item))
onBuyItemWithCard: item => dispatch(buyItemWithCardRequest(item)),
onRedirect: path => dispatch(replace(path))
})

export default connect(mapState, mapDispatch)(BuyNFTButtons)
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { memo, useCallback } from 'react'
import { Link } from 'react-router-dom'
import { memo, useCallback, useMemo } from 'react'
import { Link, useLocation } from 'react-router-dom'
import { Button, Icon, Mana } from 'decentraland-ui'
import { t } from 'decentraland-dapps/dist/modules/translation/utils'
import { getAnalytics } from 'decentraland-dapps/dist/modules/analytics/utils'
Expand All @@ -12,16 +12,25 @@ import styles from './BuyNFTButtons.module.css'
import { Props } from './BuyNFTButtons.types'

const BuyNFTButtons = ({
wallet,
isConnecting,
asset,
assetType,
tokenId,
buyWithCardClassName,
isBuyCrossChainEnabled,
onBuyWithCrypto,
onExecuteOrderWithCard,
onBuyItemWithCard
onBuyItemWithCard,
onRedirect
}: Props) => {
const analytics = getAnalytics()
const location = useLocation()
const shouldOpenBuyWithCryptoModal = useMemo(() => {
const search = new URLSearchParams(location.search)
const shouldOpenModal = search.get('buyWithCrypto')
return shouldOpenModal
}, [location.search])
const assetId = tokenId || asset.itemId

const handleBuyWithCard = useCallback(
Expand All @@ -32,6 +41,17 @@ const BuyNFTButtons = ({
[analytics, onBuyItemWithCard, onExecuteOrderWithCard]
)

const handleBuyWithCrypto = useCallback(
order => {
if (!isConnecting && !wallet) {
onRedirect(locations.signIn(`${location.pathname}?buyWithCrypto=true`))
} else {
onBuyWithCrypto(asset, order)
}
},
[asset, isConnecting, onBuyWithCrypto, onRedirect, location, wallet]
)

return (
<>
<AssetProvider
Expand All @@ -41,11 +61,14 @@ const BuyNFTButtons = ({
>
{(asset, order) => {
if (!asset) return null
if (shouldOpenBuyWithCryptoModal) {
onBuyWithCrypto(asset, order)
}
return (
<>
{isBuyCrossChainEnabled ? (
<Button
onClick={() => onBuyWithCrypto(asset, order)}
onClick={() => handleBuyWithCrypto(order)}
primary
fluid
>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Dispatch } from 'redux'
import { Order } from '@dcl/schemas'
import { OpenModalAction } from 'decentraland-dapps/dist/modules/modal/actions'
import { Wallet } from 'decentraland-dapps/dist/modules/wallet/types'
import { CallHistoryMethodAction } from 'connected-react-router'
import { Asset, AssetType } from '../../../../modules/asset/types'
import {
ExecuteOrderWithCardRequestAction,
Expand All @@ -17,19 +19,29 @@ export type Props = {
tokenId?: string
buyWithCardClassName?: string
isBuyCrossChainEnabled: boolean
wallet: Wallet | null
isConnecting: boolean
onBuyWithCrypto: (asset: Asset, order?: Order | null) => void
onExecuteOrderWithCard: typeof executeOrderWithCardRequest
onBuyItemWithCard: typeof buyItemWithCardRequest
onRedirect: (path: string) => void
}

export type MapStateProps = Pick<Props, 'isBuyCrossChainEnabled'>
export type MapStateProps = Pick<
Props,
'isBuyCrossChainEnabled' | 'wallet' | 'isConnecting'
>

export type MapDispatchProps = Pick<
Props,
'onExecuteOrderWithCard' | 'onBuyItemWithCard' | 'onBuyWithCrypto'
| 'onExecuteOrderWithCard'
| 'onBuyItemWithCard'
| 'onBuyWithCrypto'
| 'onRedirect'
>
export type MapDispatch = Dispatch<
| ExecuteOrderWithCardRequestAction
| BuyItemWithCardRequestAction
| OpenModalAction
| CallHistoryMethodAction
>
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useHistory, useLocation } from 'react-router-dom'
import classNames from 'classnames'
import compact from 'lodash/compact'
import { ethers, BigNumber } from 'ethers'
Expand Down Expand Up @@ -453,7 +454,7 @@ export const BuyWithCryptoModal = (props: Props) => {
wallet.networks[asset.network].mana >=
+ethers.utils.formatEther(price)
}
} else if (selectedTokenBalance) {
} else if (selectedTokenBalance && routeFeeCost) {
const balance = parseFloat(
ethers.utils.formatUnits(
selectedTokenBalance,
Expand All @@ -470,7 +471,7 @@ export const BuyWithCryptoModal = (props: Props) => {
t.address.toLocaleLowerCase() ===
destinyChainMANA.toLocaleLowerCase()
)
if (providerMANA && selectedToken && crossChainProvider) {
if (providerMANA && selectedToken && crossChainProvider && wallet) {
const fromAmountParams = {
fromToken: selectedToken,
toAmount: ethers.utils.formatEther(price),
Expand All @@ -480,7 +481,25 @@ export const BuyWithCryptoModal = (props: Props) => {
fromAmountParams
)
const fromAmount = Number(from).toFixed(6)
canBuy = balance > Number(fromAmount)
// fee is paid with same token selected
if (selectedToken.symbol === routeFeeCost.token.symbol) {
canBuy =
balance > Number(fromAmount) + Number(routeFeeCost.totalCost)
} else {
const networkProvider = await getNetworkProvider(
Number(routeFeeCost.token.chainId)
)
const provider = new ethers.providers.Web3Provider(
networkProvider
)
const balanceNativeTokenWei = await provider.getBalance(
wallet.address
)
const canPayForGas = balanceNativeTokenWei.gte(
ethers.utils.parseEther(routeFeeCost.totalCost)
)
canBuy = canPayForGas && balance > Number(fromAmount)
}
}
}
setCanBuyItem(canBuy)
Expand All @@ -492,6 +511,7 @@ export const BuyWithCryptoModal = (props: Props) => {
order,
price,
providerTokens,
routeFeeCost,
selectedChain,
selectedToken,
selectedTokenBalance,
Expand Down Expand Up @@ -886,8 +906,27 @@ export const BuyWithCryptoModal = (props: Props) => {
'page'
]).join('_')

const location = useLocation()
const history = useHistory()

const handleOnClose = useCallback(() => {
const search = new URLSearchParams(location.search)
const hasModalQueryParam = search.get('buyWithCrypto')
if (hasModalQueryParam) {
search.delete('buyWithCrypto')
history.replace({
search: search.toString()
})
}
onClose()
}, [history, location.search, onClose])

return (
<Modal size="tiny" onClose={onClose} className={styles.buyWithCryptoModal}>
<Modal
size="tiny"
onClose={handleOnClose}
className={styles.buyWithCryptoModal}
>
{renderModalNavigation()}
<Modal.Content>
<>
Expand Down

0 comments on commit 382c0b6

Please sign in to comment.