Skip to content

Commit

Permalink
feat(offers): cancel offer successfully
Browse files Browse the repository at this point in the history
  • Loading branch information
plondon committed Dec 27, 2021
1 parent 40feca3 commit 3418025
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 86 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
} from '@core/network/api/nfts/types'
import {
calculateGasFees,
cancelNftListing,
cancelNftOrder,
fulfillNftOrder,
fulfillNftSellOrder,
fulfillTransfer,
Expand Down Expand Up @@ -424,7 +424,7 @@ export default ({ api }: { api: APIType }) => {
try {
const signer = yield call(getEthSigner)
yield put(A.cancelListingLoading())
yield call(cancelNftListing, action.payload.sell_order, signer, action.payload.gasData)
yield call(cancelNftOrder, action.payload.sell_order, signer, action.payload.gasData)
yield put(A.clearAndRefetchAssets())
yield put(A.cancelListingSuccess())
yield put(actions.modals.closeAllModals())
Expand All @@ -439,16 +439,19 @@ export default ({ api }: { api: APIType }) => {
// https://etherscan.io/tx/0x4ba256c46b0aff8b9ee4cc2a7d44649bc31f88ebafd99190bc182178c418c64a
const cancelOffer = function* (action: ReturnType<typeof A.cancelOffer>) {
try {
if (!action.payload.order) {
throw new Error('No offer found. It may have expired already!')
}
const signer = yield call(getEthSigner)
yield put(A.cancelListingLoading())
// yield call(cancelNftOffer, action.payload.offer, signer)
yield put(A.cancelOfferLoading())
yield call(cancelNftOrder, action.payload.order, signer, action.payload.gasData)
yield put(A.clearAndRefetchOffersMade())
yield put(actions.modals.closeAllModals())
yield put(actions.alerts.displaySuccess(`Successfully cancelled offer!`))
} catch (e) {
const error = errorHandler(e)
yield put(actions.alerts.displayError(error))
yield put(A.cancelListingFailure({ error }))
yield put(A.cancelOfferFailure({ error }))
}
}

Expand Down Expand Up @@ -538,8 +541,11 @@ export default ({ api }: { api: APIType }) => {
0,
ethAddr
)
console.log(activeOrders)
debugger
const nonPrefixedEthAddr = ethAddr.replace(/^0x/, '').toLowerCase()
const offer = activeOrders.orders.find((order) =>
order.calldata.toLowerCase().includes(nonPrefixedEthAddr)
)
yield put(A.setActiveOffer({ offer }))
yield put(A.setOrderFlowStep({ step: NftOrderStepEnum.CANCEL_OFFER }))
} else {
// User wants to accept offer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const initialState: NftsStateType = {
page: 0
},
cancelListing: Remote.NotAsked,
cancelOffer: Remote.NotAsked,
collectionSearch: [],
collections: Remote.NotAsked,
marketplace: {
Expand All @@ -50,6 +51,7 @@ const initialState: NftsStateType = {
page: 0
},
orderFlow: {
activeOffer: null,
activeOrder: null,
asset: Remote.NotAsked,
fees: Remote.NotAsked,
Expand Down Expand Up @@ -79,8 +81,17 @@ const nftsSlice = createSlice({
},
cancelOffer: (
state,
action: PayloadAction<{ offer: OfferEventsType['asset_events'][0] }>
action: PayloadAction<{ gasData: GasDataI; order: SellOrder | null }>
) => {},
cancelOfferFailure: (state, action: PayloadAction<{ error: string }>) => {
state.cancelOffer = Remote.Success(action.payload.error)
},
cancelOfferLoading: (state) => {
state.cancelOffer = Remote.Loading
},
cancelOfferSuccess: (state) => {
state.cancelOffer = Remote.Success(true)
},
clearAndRefetchAssets: (state) => {},
clearAndRefetchOffersMade: (state) => {},
clearAndRefetchOrders: (state) => {},
Expand Down Expand Up @@ -309,6 +320,9 @@ const nftsSlice = createSlice({
state,
action: PayloadAction<{ asset_contract_address?: string; search?: string }>
) => {},
setActiveOffer: (state, action: PayloadAction<{ offer: SellOrder }>) => {
state.orderFlow.activeOffer = action.payload.offer
},
setActiveTab: (state, action: PayloadAction<'explore' | 'my-collection' | 'offers'>) => {
state.activeTab = action.payload
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import {
NftAssetsType,
NftOrdersType,
OfferEventsType,
Order
Order,
SellOrder
} from '@core/network/api/nfts/types'
import { calculateGasFees } from '@core/redux/payment/nfts'
import { Await, RemoteDataType } from '@core/types'
Expand All @@ -31,6 +32,7 @@ export type NftsStateType = {
page: number
}
cancelListing: RemoteDataType<string, boolean>
cancelOffer: RemoteDataType<string, boolean>
collectionSearch: ExplorerGatewayNftCollectionType[]
collections: RemoteDataType<string, ExplorerGatewayNftCollectionType[]>
marketplace: {
Expand All @@ -50,6 +52,7 @@ export type NftsStateType = {
page: number
}
orderFlow: {
activeOffer: SellOrder | null
activeOrder: NftOrdersType['orders'][0] | null
asset: RemoteDataType<string, NftAsset>
fees: RemoteDataType<string, Await<ReturnType<typeof calculateGasFees>>>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React, { useEffect } from 'react'
import { FormattedMessage } from 'react-intl'
import BigNumber from 'bignumber.js'

import { GasCalculationOperations, SellOrder } from '@core/network/api/nfts/types'
import { SpinningLoader, TooltipHost, TooltipIcon } from 'blockchain-info-components'
import CoinDisplay from 'components/Display/CoinDisplay'
import FiatDisplay from 'components/Display/FiatDisplay'
import { Title, Value } from 'components/Flyout/model'

import { CTARow } from '../../components'
import { Props as OwnProps } from '..'

const Fees: React.FC<Props> = (props) => {
const { nftActions, orderFlow } = props
const { activeOffer } = orderFlow

useEffect(() => {
if (activeOffer && props.operation === 'cancel') {
nftActions.fetchFees({
operation: GasCalculationOperations.Cancel,
order: activeOffer as unknown as SellOrder
})
}
}, [])

if (!activeOffer) return null

return (
<>
{orderFlow.fees.cata({
Failure: () => null,
Loading: () => (
<CTARow>
<SpinningLoader width='14px' height='14px' borderWidth='3px' />
</CTARow>
),
NotAsked: () => null,
Success: (val) => {
return (
<>
<CTARow>
<Title style={{ display: 'flex' }}>
<FormattedMessage id='copy.fees' defaultMessage='Fees' />
</Title>
<Value>
<div style={{ display: 'flex' }}>
<CoinDisplay size='14px' color='black' weight={600} coin='ETH'>
{new BigNumber(val.totalFees).multipliedBy(val.gasPrice).toString()}
</CoinDisplay>
&nbsp;-&nbsp;
<FiatDisplay size='12px' color='grey600' weight={600} coin='ETH'>
{new BigNumber(val.totalFees).multipliedBy(val.gasPrice).toString()}
</FiatDisplay>
</div>
</Value>
</CTARow>
</>
)
}
})}
</>
)
}

type Props = OwnProps & { operation: 'cancel' | 'accept' }

export default Fees
Original file line number Diff line number Diff line change
@@ -1,29 +1,20 @@
import React from 'react'
import { FormattedMessage } from 'react-intl'
import { connect, ConnectedProps } from 'react-redux'
import { compose } from 'redux'
import { Field, reduxForm } from 'redux-form'

import { Remote } from '@core'
import { convertCoinToCoin } from '@core/exchange'
import { Button, Icon, SpinningLoader, Text } from 'blockchain-info-components'
import CoinDisplay from 'components/Display/CoinDisplay'
import FiatDisplay from 'components/Display/FiatDisplay'
import { Row, Title, Value } from 'components/Flyout/model'
import { Form, NumberBox, SelectBox } from 'components/Form'
import { selectors } from 'data'
import { NftOrderStepEnum } from 'data/components/nfts/types'

import { AssetDesc, FullAssetImage, StickyCTA } from '../../components'
import { Props as OwnProps } from '..'
// import CancelOfferFees from './fees'
import CancelOfferFees from './fees'

const CancelOffer: React.FC<Props> = (props) => {
const { close, formValues, nftActions, orderFlow } = props
const { activeOrder } = orderFlow
const { close, nftActions, orderFlow } = props
const { activeOffer } = orderFlow

const disabled =
!formValues.amount || Remote.Loading.is(orderFlow.order) || Remote.Loading.is(orderFlow.fees)
const disabled = Remote.Loading.is(activeOffer) || Remote.Loading.is(orderFlow.fees)

return (
<>
Expand Down Expand Up @@ -72,74 +63,40 @@ const CancelOffer: React.FC<Props> = (props) => {
)}
</Value>
</Row>
<Form>
<Row>
<Title>
<b>
<FormattedMessage id='copy.select_coin' defaultMessage='Select Coin' />
</b>
</Title>
<Value>
<Field
name='coin'
component={SelectBox}
elements={[
{
group: '',
items: val.collection.payment_tokens
.map((token) => token.symbol)
.filter((symbol) => symbol === 'WETH')
.map((coin) => ({
text: window.coins[coin].coinfig.symbol,
value: window.coins[coin].coinfig.symbol
}))
}
]}
/>
</Value>
</Row>
</Form>
{activeOrder ? (
<StickyCTA>
{/* <CancelOfferFees {...props} /> */}
<Button
jumbo
nature='primary'
fullwidth
data-e2e='makeOfferNft'
disabled={disabled}
// onClick={() => nftActions.createOffer({ order: activeOrder, ...formValues })}
>
<FormattedMessage id='copy.cancel_offer' defaultMessage='Cancel Offer' />
</Button>
</StickyCTA>
) : null}
<StickyCTA>
<CancelOfferFees {...props} operation='cancel' />
{orderFlow.fees.cata({
Failure: () => (
<Text size='14px' weight={600}>
<FormattedMessage
id='copy.no_active_sell_listings'
defaultMessage='Error. You may not have any active offers for this asset.'
/>
</Text>
),
Loading: () => null,
NotAsked: () => null,
Success: (val) => (
<Button
jumbo
nature='primary'
fullwidth
data-e2e='cancelOfferNft'
disabled={disabled}
onClick={() => nftActions.cancelOffer({ gasData: val, order: activeOffer })}
>
<FormattedMessage id='copy.cancel_offer' defaultMessage='Cancel Offer' />
</Button>
)
})}
</StickyCTA>
</>
)
})}
</>
)
}

const mapStateToProps = (state) => ({
formValues: selectors.form.getFormValues('nftCancelOffer')(state) as {
amount: string
coin: string
}
})
type Props = OwnProps

const connector = connect(mapStateToProps)

const enhance = compose(
reduxForm<{}, OwnProps>({
form: 'nftCancelOffer',
initialValues: {
coin: 'WETH'
}
}),
connector
)

type Props = OwnProps & ConnectedProps<typeof connector>

export default enhance(CancelOffer) as React.FC<OwnProps>
export default CancelOffer
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
verifyTransfered
} from './utils'

export const cancelNftListing = async (sellOrder: SellOrder, signer: Signer, gasData: GasDataI) => {
export const cancelNftOrder = async (sellOrder: SellOrder, signer: Signer, gasData: GasDataI) => {
const { gasFees, gasPrice } = gasData
const txnData = {
gasLimit: gasFees,
Expand Down

0 comments on commit 3418025

Please sign in to comment.