Fix: default 0 zeroConfLimit for new coins

This commit is contained in:
csrapr 2021-04-09 19:44:08 +01:00 committed by Josh Harvey
parent fafee1a727
commit 65a55a669d
7 changed files with 63 additions and 138 deletions

View file

@ -3,13 +3,27 @@ var db = require('../lib/db')
const settingsLoader = require('../lib/new-settings-loader') const settingsLoader = require('../lib/new-settings-loader')
const configManager = require('../lib/new-config-manager') const configManager = require('../lib/new-config-manager')
const stripl = _.curry((q, str) => _.startsWith(q, str) ? str.slice(q.length) : str)
const filter = namespace => _.pickBy((value, key) => _.startsWith(`${namespace}_`)(key))
const strip = key => _.mapKeys(stripl(`${key}_`))
const fromNamespace = _.curry((key, config) => _.compose(strip(key), filter(key))(config))
const split = _.curry(_.split)
const composed = _.compose(_.head, split('_'))
const getCryptoCodes = (config) => {
const walletKeys = _.keys(fromNamespace('wallets', config))
return _.uniq(_.map(composed, walletKeys))
}
exports.up = function (next) { exports.up = function (next) {
db.tx(async t => { db.tx(async t => {
let min = Infinity let min = Infinity
const sp = settingsLoader.loadLatest() const sp = settingsLoader.loadLatest()
const mp = t.any('SELECT device_id FROM devices') const mp = t.any('SELECT device_id FROM devices')
const [{ config }, machines] = await Promise.all([sp, mp]) const [{ config }, machines] = await Promise.all([sp, mp])
const cryptoCurrencies = config.locale_cryptoCurrencies const cryptoCodes = getCryptoCodes(config)
_.forEach(o => { _.forEach(o => {
const machineId = o.device_id const machineId = o.device_id
@ -29,10 +43,10 @@ exports.up = function (next) {
if (!zeroConfLimit) { if (!zeroConfLimit) {
config[key] = Number(min) config[key] = Number(min)
} }
}, cryptoCurrencies) }, cryptoCodes)
const regexp = /^cashOut_[0-9a-z]+_zeroConfLimit$/ const regexp = /^cashOut_[0-9a-z]+_zeroConfLimit$/
const keysToErase = Object.keys(config).filter(key => key.match(regexp)) const keysToErase = _.keys(config).filter(key => key.match(regexp))
_.forEach(key => { _.forEach(key => {
config[key] = null config[key] = null

View file

@ -149,6 +149,7 @@ const Locales = ({ name: SCREEN_KEY }) => {
if (!coin) return setValue(curr) if (!coin) return setValue(curr)
const namespaced = fromNamespace(coin)(wallets) const namespaced = fromNamespace(coin)(wallets)
console.log(namespaced)
if (!WalletSchema.isValidSync(namespaced)) { if (!WalletSchema.isValidSync(namespaced)) {
setOnChangeFunction(() => () => setValue(curr)) setOnChangeFunction(() => () => setValue(curr))
setWizard(coin) setWizard(coin)

View file

@ -8,7 +8,7 @@ import { toNamespace } from 'src/utils/config'
import WizardSplash from './WizardSplash' import WizardSplash from './WizardSplash'
import WizardStep from './WizardStep' import WizardStep from './WizardStep'
const LAST_STEP = 5 const LAST_STEP = 4
const MODAL_WIDTH = 554 const MODAL_WIDTH = 554
const contains = crypto => R.compose(R.contains(crypto), R.prop('cryptos')) const contains = crypto => R.compose(R.contains(crypto), R.prop('cryptos'))
@ -65,6 +65,7 @@ const Wizard = ({
: accountsToSave : accountsToSave
if (isLastStep) { if (isLastStep) {
newConfig.zeroConfLimit = 0
return save(toNamespace(coin.code, newConfig), newAccounts) return save(toNamespace(coin.code, newConfig), newAccounts)
} }
@ -85,8 +86,6 @@ const Wizard = ({
return { type: 'exchange', ...exchanges } return { type: 'exchange', ...exchanges }
case 4: case 4:
return { type: 'zeroConf', name: 'zero conf', ...zeroConfs } return { type: 'zeroConf', name: 'zero conf', ...zeroConfs }
case 5:
return { type: 'zeroConfLimit' }
default: default:
return null return null
} }

View file

@ -2,13 +2,11 @@ import { makeStyles } from '@material-ui/core'
import classnames from 'classnames' import classnames from 'classnames'
import * as R from 'ramda' import * as R from 'ramda'
import React, { useReducer, useEffect } from 'react' import React, { useReducer, useEffect } from 'react'
import * as Yup from 'yup'
import ErrorMessage from 'src/components/ErrorMessage' import ErrorMessage from 'src/components/ErrorMessage'
import Stepper from 'src/components/Stepper' import Stepper from 'src/components/Stepper'
import { Button } from 'src/components/buttons' import { Button } from 'src/components/buttons'
import { RadioGroup, Autocomplete } from 'src/components/inputs' import { RadioGroup, Autocomplete } from 'src/components/inputs'
import { NumberInput } from 'src/components/inputs/formik'
import { H4, Info2 } from 'src/components/typography' import { H4, Info2 } from 'src/components/typography'
import FormRenderer from 'src/pages/Services/FormRenderer' import FormRenderer from 'src/pages/Services/FormRenderer'
import schema from 'src/pages/Services/schemas' import schema from 'src/pages/Services/schemas'
@ -84,13 +82,6 @@ const WizardStep = ({
onContinue(config, account) onContinue(config, account)
} }
const zeroConfLimitSchema = Yup.object().shape({
zeroConfLimit: Yup.number()
.integer()
.required()
.min(0)
.max(999999999)
})
const label = lastStep ? 'Finish' : 'Next' const label = lastStep ? 'Finish' : 'Next'
const displayName = name ?? type const displayName = name ?? type
const subtitleClass = { const subtitleClass = {
@ -100,83 +91,54 @@ const WizardStep = ({
return ( return (
<> <>
<Info2 className={classes.title}>{startCase(type)}</Info2> <Info2 className={classes.title}>{startCase(type)}</Info2>
<Stepper steps={5} currentStep={step} /> <Stepper steps={4} currentStep={step} />
{step <= 4 && ( <H4 className={classnames(subtitleClass)}>
<> Select a {displayName} or set up a new one
<H4 className={classnames(subtitleClass)}> </H4>
Select a {displayName} or set up a new one <RadioGroup
</H4> options={filled}
value={selected}
className={classes.radioGroup}
onChange={(evt, it) => {
dispatch({ type: 'select', selected: it })
}}
labelClassName={classes.radioLabel}
radioClassName={classes.radio}
/>
<div className={classes.setupNew}>
{!R.isEmpty(unfilled) && !R.isNil(unfilled) && (
<RadioGroup <RadioGroup
options={filled} value={isNew}
value={selected}
className={classes.radioGroup}
onChange={(evt, it) => { onChange={(evt, it) => {
dispatch({ type: 'select', selected: it }) dispatch({ type: 'new' })
}} }}
labelClassName={classes.radioLabel} labelClassName={classes.radioLabel}
radioClassName={classes.radio} radioClassName={classes.radio}
options={[{ display: 'Set up new', code: true }]}
/> />
<div className={classes.setupNew}> )}
{!R.isEmpty(unfilled) && !R.isNil(unfilled) && ( {isNew && (
<RadioGroup <Autocomplete
value={isNew} fullWidth
onChange={(evt, it) => { label={`Select ${displayName}`}
dispatch({ type: 'new' }) className={classes.picker}
}} getOptionSelected={R.eqProps('code')}
labelClassName={classes.radioLabel} labelProp={'display'}
radioClassName={classes.radio} options={unfilled}
options={[{ display: 'Set up new', code: true }]} onChange={(evt, it) => {
/> dispatch({ type: 'form', form: it })
)} }}
{isNew && (
<Autocomplete
fullWidth
label={`Select ${displayName}`}
className={classes.picker}
getOptionSelected={R.eqProps('code')}
labelProp={'display'}
options={unfilled}
onChange={(evt, it) => {
dispatch({ type: 'form', form: it })
}}
/>
)}
</div>
{form && (
<FormRenderer
save={it =>
innerContinue({ [type]: form.code }, { [form.code]: it })
}
elements={schema[form.code].elements}
validationSchema={schema[form.code].validationSchema}
value={getValue(form.code)}
buttonLabel={label}
/>
)}
</>
)}
{step === 5 && (
<>
<H4 className={classnames(subtitleClass)}>Edit 0-conf Limit</H4>
<FormRenderer
save={it =>
innerContinue(
{ [type]: Number(it.zeroConfLimit) },
{ [form.code]: it }
)
}
elements={[
{
code: 'zeroConfLimit',
display: `Choose a ${locale.fiatCurrency} limit`,
component: NumberInput
}
]}
validationSchema={zeroConfLimitSchema}
buttonLabel={label}
value={null}
/> />
</> )}
</div>
{form && (
<FormRenderer
save={it => innerContinue({ [type]: form.code }, { [form.code]: it })}
elements={schema[form.code].elements}
validationSchema={schema[form.code].validationSchema}
value={getValue(form.code)}
buttonLabel={label}
/>
)} )}
{!form && ( {!form && (
<div className={classes.submit}> <div className={classes.submit}>

View file

@ -52,6 +52,8 @@ const AllSet = ({ data: currentData, doContinue }) => {
const accountsConfig = data?.accountsConfig const accountsConfig = data?.accountsConfig
const cryptoCurrencies = data?.cryptoCurrencies ?? [] const cryptoCurrencies = data?.cryptoCurrencies ?? []
currentData.zeroConfLimit = 0
const save = () => { const save = () => {
if (!WalletSchema.isValidSync(currentData)) return setError(true) if (!WalletSchema.isValidSync(currentData)) return setError(true)

View file

@ -12,7 +12,6 @@ import ChooseCoin from './ChooseCoin'
import ChooseExchange from './ChooseExchange' import ChooseExchange from './ChooseExchange'
import ChooseTicker from './ChooseTicker' import ChooseTicker from './ChooseTicker'
import ChooseWallet from './ChooseWallet' import ChooseWallet from './ChooseWallet'
import ZeroConfLimit from './ZeroConfLimit'
const useStyles = makeStyles(styles) const useStyles = makeStyles(styles)
@ -37,10 +36,6 @@ const steps = [
label: 'Blockcypher', label: 'Blockcypher',
component: Blockcypher component: Blockcypher
}, },
{
label: 'Set 0-conf Limit',
component: ZeroConfLimit
},
{ {
label: 'All set', label: 'All set',
component: AllSet component: AllSet

View file

@ -1,48 +0,0 @@
import { makeStyles } from '@material-ui/core'
import React from 'react'
import * as Yup from 'yup'
import { NumberInput } from 'src/components/inputs/formik'
import { H4 } from 'src/components/typography'
import FormRenderer from 'src/pages/Services/FormRenderer'
import styles from './Shared.styles'
const useStyles = makeStyles(styles)
const zeroConfLimitSchema = Yup.object().shape({
zeroConfLimit: Yup.number()
.integer()
.required()
.min(0)
.max(999999999)
})
const ZeroConfLimit = ({ data: currentData, addData }) => {
const classes = useStyles()
const submit = value => {
addData({ zeroConfLimit: value })
}
return (
<div className={classes.mdForm}>
<H4>Set the 0-conf limit</H4>
<FormRenderer
elements={[
{
code: 'zeroConfLimit',
display: `Choose a limit`,
component: NumberInput
}
]}
validationSchema={zeroConfLimitSchema}
buttonLabel={'Continue'}
value={null}
save={it => submit(Number(it.zeroConfLimit))}
/>
</div>
)
}
export default ZeroConfLimit