Skip to content

Commit

Permalink
fix(Coinify): sell limits
Browse files Browse the repository at this point in the history
  • Loading branch information
Philip Welber committed May 30, 2018
1 parent 42f53d0 commit 688f4f8
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -141,39 +141,65 @@ export default ({ coreSagas }) => {

switch (field) {
case 'leftVal':
const leftLimitsError = service.getLimitsError(payload, limits.data, values.currency)
if (leftLimitsError) {
yield put(A.setCoinifyCheckoutError(leftLimitsError))
return
if (type === 'buy') {
const leftLimitsError = service.getLimitsError(payload, limits.data, values.currency, type)
if (leftLimitsError) {
yield put(A.setCoinifyCheckoutError(leftLimitsError))
return
} else {
yield put(A.clearCoinifyCheckoutError())
}
}

const leftResult = yield call(coreSagas.data.coinify.fetchQuote,
{ quote: { amount: payload * 100, baseCurrency: values.currency, quoteCurrency: 'BTC', type } })
const amount = Math.abs(leftResult.quoteAmount)

if (type === 'sell') {
const payment = yield select(sendBtcSelectors.getPayment)
const effectiveBalance = prop('effectiveBalance', payment.getOrElse(undefined))
if (service.isOverEffectiveMax(amount, effectiveBalance)) {
yield put(A.setCoinifyCheckoutError('over_effective_max'))
let btcAmt = (amount / 1e8)
const leftLimitsError = service.getLimitsError(btcAmt, limits.data, values.currency, type)
if (leftLimitsError) {
yield put(A.setCoinifyCheckoutError(leftLimitsError))
} else {
yield put(A.clearCoinifyCheckoutError())
const payment = yield select(sendBtcSelectors.getPayment)
const effectiveBalance = prop('effectiveBalance', payment.getOrElse(undefined))
if (service.isOverEffectiveMax(amount, effectiveBalance)) yield put(A.setCoinifyCheckoutError('over_effective_max'))
else yield put(A.clearCoinifyCheckoutError())
}
}

yield put(actions.form.initialize(form, merge(values, { 'rightVal': amount / 1e8 })))
yield put(A.coinifyCheckoutBusyOff())
break
case 'rightVal':
if (type === 'sell') {
const rightLimitsError = service.getLimitsError(payload, limits.data, values.currency, type)
if (rightLimitsError) {
yield put(A.setCoinifyCheckoutError(rightLimitsError))
return
} else {
yield put(A.clearCoinifyCheckoutError())
}
}

const rightResult = yield call(coreSagas.data.coinify.fetchQuote,
{ quote: { amount: Math.round((payload * 1e8) * -1), baseCurrency: 'BTC', quoteCurrency: values.currency, type } })
const fiatAmount = Math.abs(rightResult.quoteAmount)

const rightLimitsError = service.getLimitsError(fiatAmount, limits.data, values.currency)
let rightLimitsError
if (type === 'sell') rightLimitsError = service.getLimitsError(payload, limits.data, values.currency, type)
if (type === 'buy') rightLimitsError = service.getLimitsError(fiatAmount, limits.data, values.currency, type)

if (rightLimitsError) {
yield put(A.setCoinifyCheckoutError(rightLimitsError))
yield put(actions.form.initialize(form, merge(values, { 'leftVal': fiatAmount })))
return
} else {
const payment = yield select(sendBtcSelectors.getPayment)
const effectiveBalance = prop('effectiveBalance', payment.getOrElse(undefined))
if (service.isOverEffectiveMax(payload * 1e8, effectiveBalance)) yield put(A.setCoinifyCheckoutError('over_effective_max'))
else yield put(A.clearCoinifyCheckoutError())
}

yield put(actions.form.initialize(form, merge(values, { 'leftVal': fiatAmount })))
yield put(A.coinifyCheckoutBusyOff())
break
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import QuoteInput from './QuoteInput'
import { MethodContainer } from 'components/BuySell/styled.js'

const OrderCheckout = ({ quoteR, rateQuoteR, account, onFetchQuote, reason, limits, checkoutError,
type, defaultCurrency, symbol, checkoutBusy, busy, setMax, setEffectiveMax, setMin, increaseLimit, onOrderCheckoutSubmit }) => {
type, defaultCurrency, symbol, checkoutBusy, busy, setMax, setMin, increaseLimit, onOrderCheckoutSubmit }) => {
const quoteInputSpec = {
method: type, // buy or sell
input: defaultCurrency,
Expand Down Expand Up @@ -74,7 +74,6 @@ const OrderCheckout = ({ quoteR, rateQuoteR, account, onFetchQuote, reason, limi
defaultCurrency={defaultCurrency}
symbol={symbol}
setMax={setMax}
setEffectiveMax={setEffectiveMax}
setMin={setMin}
increaseLimit={increaseLimit}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Loading from 'components/BuySell/Loading'

class QuoteInput extends Component {
render () {
const { data, symbol, setMax, setEffectiveMax, setMin, checkoutError, increaseLimit, defaultCurrency, limits, disabled, type } = this.props
const { data, symbol, setMax, setMin, checkoutError, increaseLimit, defaultCurrency, limits, disabled, type } = this.props
return data.cata({
Success: (value) => {
const QuoteInputTemplate = type === 'buy' ? QuoteInputTemplateBuy : QuoteInputTemplateSell
Expand All @@ -23,7 +23,6 @@ class QuoteInput extends Component {
defaultCurrency={defaultCurrency}
symbol={symbol}
setMax={setMax}
setEffectiveMax={setEffectiveMax}
setMin={setMin}
checkoutError={checkoutError}
increaseLimit={increaseLimit}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,25 +76,34 @@ const LimitsHelper = styled.div`
}
`

const getLimitsError = (errorType, limits, symbol, setMin) => {
const getLimitsError = (errorType, limits, curr, setMin) => {
switch (errorType) {
case 'below_min': return `Your limit of ${symbol}${limits.max} is below the minimum allowed amount.`
case 'over_max': return `Enter an amount under your ${symbol}${limits.max.toLocaleString()} limit`
case 'under_min': return <FormattedMessage id='buy.quote_input.under_min' defaultMessage='Enter an amount above the {setMin} minimum' values={{ setMin: <a onClick={() => setMin(limits.min)}>{symbol}{limits.min.toLocaleString()}</a> }} />
case 'below_min': return `Your limit of ${curr}${limits.max} is below the minimum allowed amount.`
case 'over_max': return `Enter an amount under your ${curr}${limits.max} limit`
case 'under_min': return <FormattedMessage id='buy.quote_input.under_min' defaultMessage='Enter an amount above the {setMin} minimum' values={{ setMin: <a onClick={() => setMin(limits.min)}>{curr}{limits.min}</a> }} />
case 'over_effective_max': return `Enter an amount less than your balance minus the priority fee (${limits.effectiveMax / 1e8} BTC)`
}
}

const FiatConvertor = (props) => {
const { val, disabled, setMax, setEffectiveMax, setMin, limits, checkoutError, defaultCurrency, symbol, increaseLimit, form } = props
const { val, disabled, setMax, setMin, limits, checkoutError, defaultCurrency, symbol, increaseLimit, form } = props
const currency = 'BTC'
const level = val.level || { name: 1 }
const kyc = val.kycs.length && head(val.kycs)
const { canTrade, cannotTradeReason, profile } = val
const { canTradeAfter } = profile
const isSell = form === 'coinifyCheckoutSell'
const curr = isSell ? 'BTC' : symbol

const reasonExplanation = cannotTradeReason && getReasonExplanation(cannotTradeReason, canTradeAfter)

const getSellLimits = () => {
let effBal = limits.effectiveMax / 1e8
let max = Math.min(effBal, limits.max)

return <FormattedMessage id='sell.quote_input.remaining_sell_limit' defaultMessage='Your remaining sell limit is {max}' values={{ max: <a onClick={() => setMax(max)}>{max} BTC</a> }} />
}

const renderErrorsAndLimits = () => {
if (!canTrade) {
return (
Expand All @@ -105,16 +114,16 @@ const FiatConvertor = (props) => {
} else if (checkoutError) {
return (
<Error size='13px' weight={300} color='error'>
{ getLimitsError(checkoutError, limits, symbol, setMin) }
{ getLimitsError(checkoutError, limits, curr, setMin) }
</Error>
)
} else {
return (
<LimitsHelper>
{
form === 'coinifyCheckoutBuy'
? <FormattedMessage id='buy.quote_input.remaining_buy_limit' defaultMessage='Your remaining buy limit is {max}' values={{ max: <a onClick={() => setMax(limits.max)}>{symbol}{limits.max}</a> }} />
: <FormattedMessage id='sell.quote_input.remaining_sell_limit' defaultMessage='Your remaining sell limit is {max}' values={{ max: <a onClick={() => setEffectiveMax(limits.effectiveMax)}>{limits.effectiveMax / 1e8} BTC</a> }} />
? <FormattedMessage id='buy.quote_input.remaining_buy_limit' defaultMessage='Your remaining buy limit is {max}' values={{ max: <a onClick={() => setMax(limits.max)}>{curr}{limits.max}</a> }} />
: getSellLimits()
}
{
level.name < 2 && kyc.state !== 'reviewing'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,8 @@ class SellContainer extends React.Component {
fetchSellQuote={(quote) => fetchQuote({ quote, nextAddress: value.nextAddress })}
currency={currency}
checkoutBusy={checkoutBusy}
setMax={(amt) => formActions.change('coinifyCheckoutSell', 'leftVal', amt)}
setEffectiveMax={(btcAmt) => formActions.change('coinifyCheckoutSell', 'rightVal', (btcAmt / 1e8))}
setMin={(amt) => formActions.change('coinifyCheckoutSell', 'leftVal', amt)}
setMax={(btcAmt) => formActions.change('coinifyCheckoutSell', 'rightVal', btcAmt)}
setMin={(btcAmt) => formActions.change('coinifyCheckoutSell', 'rightVal', btcAmt)}
paymentMedium={paymentMedium}
initiateSell={this.startSell}
step={step}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ const Sell = props => {
rateQuoteR,
checkoutBusy,
setMax,
setEffectiveMax,
setMin,
paymentMedium,
initiateSell,
Expand Down Expand Up @@ -75,7 +74,6 @@ const Sell = props => {
symbol={symbol}
checkoutBusy={checkoutBusy}
setMax={setMax}
setEffectiveMax={setEffectiveMax}
setMin={setMin}
onOrderCheckoutSubmit={onOrderCheckoutSubmit}
checkoutError={checkoutError}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,35 @@ import { FormattedMessage } from 'react-intl'
export const getLimits = (limits, curr, effectiveBalance) => {
const getMin = (limits, curr) => Math.min(limits.bank.minimumInAmounts[curr], limits.card.minimumInAmounts[curr])
const getMax = (limits, curr) => Math.max(limits.bank.inRemaining[curr], limits.card.inRemaining[curr])
const getSellMin = (limits, curr) => limits.blockchain.minimumInAmounts[curr]
const getSellMax = (limits, curr) => limits.blockchain.inRemaining[curr]
return {
buy: {
min: getMin(limits, curr),
max: getMax(limits, curr)
},
sell: {
min: getMin(limits, curr),
max: getMax(limits, curr),
min: getSellMin(limits, 'BTC'),
max: getSellMax(limits, 'BTC'),
effectiveMax: effectiveBalance
}
}
}

export const getLimitsError = (amt, userLimits, curr) => {
export const getLimitsError = (amt, userLimits, curr, type) => {
const limits = getLimits(userLimits, curr)
if (limits.buy.max < limits.buy.min) return 'max_below_min'
if (amt > limits.buy.max) return 'over_max'
if (amt < limits.buy.min) return 'under_min'

if (type === 'buy') {
if (limits.buy.max < limits.buy.min) return 'max_below_min'
if (amt > limits.buy.max) return 'over_max'
if (amt < limits.buy.min) return 'under_min'
}
if (type === 'sell') {
if (limits.sell.max < limits.sell.min) return 'max_below_min'
if (amt > limits.sell.max) return 'over_max'
if (amt < limits.sell.min) return 'under_min'
}

return false
}

Expand Down

0 comments on commit 688f4f8

Please sign in to comment.