Merge pull request #766 from josepfo/feat/crypto-units-selector

feat: advanced wallet settings
This commit is contained in:
Rafael Taranto 2021-11-14 23:13:16 +00:00 committed by GitHub
commit 0881d00594
9 changed files with 222 additions and 47 deletions

View file

@ -3,11 +3,11 @@ const configManager = require('./new-config-manager')
const { utils: coinUtils } = require('lamassu-coins') const { utils: coinUtils } = require('lamassu-coins')
function truncateCrypto (cryptoAtoms, cryptoCode) { function truncateCrypto (cryptoAtoms, cryptoCode) {
const DECIMAL_PLACES = 3 const DECIMAL_PLACES = 6
if (cryptoAtoms.eq(0)) return cryptoAtoms if (cryptoAtoms.eq(0)) return cryptoAtoms
const scale = coinUtils.getCryptoCurrency(cryptoCode).displayScale const scale = coinUtils.getCryptoCurrency(cryptoCode).unitScale
const scaleFactor = new BN(10).pow(scale) const scaleFactor = BN(10).pow(scale)
return new BN(cryptoAtoms).integerValue(BN.ROUND_DOWN).div(scaleFactor) return new BN(cryptoAtoms).integerValue(BN.ROUND_DOWN).div(scaleFactor)
.decimalPlaces(DECIMAL_PLACES).times(scaleFactor) .decimalPlaces(DECIMAL_PLACES).times(scaleFactor)

View file

@ -132,6 +132,10 @@ const getCryptosFromWalletNamespace = config => {
const getCashInSettings = config => fromNamespace(namespaces.CASH_IN)(config) const getCashInSettings = config => fromNamespace(namespaces.CASH_IN)(config)
const getCryptoUnits = (crypto, config) => {
return getWalletSettings(crypto, config).cryptoUnits
}
module.exports = { module.exports = {
getWalletSettings, getWalletSettings,
getCashInSettings, getCashInSettings,
@ -149,5 +153,6 @@ module.exports = {
getTriggers, getTriggers,
getTriggersAutomation, getTriggersAutomation,
getCashOut, getCashOut,
getCryptosFromWalletNamespace getCryptosFromWalletNamespace,
getCryptoUnits
} }

View file

@ -206,6 +206,7 @@ function plugins (settings, deviceId) {
const cashInCommission = new BN(commissions.cashIn) const cashInCommission = new BN(commissions.cashIn)
const cashOutCommission = _.isNumber(commissions.cashOut) ? new BN(commissions.cashOut) : null const cashOutCommission = _.isNumber(commissions.cashOut) ? new BN(commissions.cashOut) : null
const cryptoRec = coinUtils.getCryptoCurrency(cryptoCode) const cryptoRec = coinUtils.getCryptoCurrency(cryptoCode)
const cryptoUnits = configManager.getCryptoUnits(cryptoCode, settings.config)
return { return {
cryptoCode, cryptoCode,
@ -214,13 +215,13 @@ function plugins (settings, deviceId) {
cashInFee, cashInFee,
cashInCommission, cashInCommission,
cashOutCommission, cashOutCommission,
cryptoNetwork cryptoNetwork,
cryptoUnits
} }
} }
function pollQueries (serialNumber, deviceTime, deviceRec, machineVersion, machineModel) { function pollQueries (serialNumber, deviceTime, deviceRec, machineVersion, machineModel) {
const localeConfig = configManager.getLocale(deviceId, settings.config) const localeConfig = configManager.getLocale(deviceId, settings.config)
const fiatCode = localeConfig.fiatCurrency const fiatCode = localeConfig.fiatCurrency
const cryptoCodes = localeConfig.cryptoCurrencies const cryptoCodes = localeConfig.cryptoCurrencies
const timezone = localeConfig.timezone.split(':') const timezone = localeConfig.timezone.split(':')

View file

@ -0,0 +1,28 @@
const { saveConfig, loadLatest } = require('../lib/new-settings-loader')
const { getCryptosFromWalletNamespace } = require('../lib/new-config-manager.js')
const { utils: coinUtils } = require('lamassu-coins')
const _ = require('lodash/fp')
exports.up = function (next) {
loadLatest()
.then(settings => {
const newSettings = {}
const activeCryptos = getCryptosFromWalletNamespace(settings.config)
if (!activeCryptos.length) return Promise.resolve()
_.map(crypto => {
const defaultUnit = _.head(_.keys(coinUtils.getCryptoCurrency(crypto).units))
newSettings[`wallets_${crypto}_cryptoUnits`] = defaultUnit
return newSettings
}, activeCryptos)
return saveConfig(newSettings)
})
.then(() => next())
.catch(err => {
console.log(err.message)
return next(err)
})
}
exports.down = function (next) {
next()
}

View file

@ -0,0 +1,60 @@
import { useQuery, useMutation } from '@apollo/react-hooks'
import gql from 'graphql-tag'
import { utils as coinUtils } from 'lamassu-coins'
import * as R from 'ramda'
import React from 'react'
import { NamespacedTable as EditableTable } from 'src/components/editableTable'
import { fromNamespace, toNamespace, namespaces } from 'src/utils/config'
import { AdvancedWalletSchema, getAdvancedWalletElements } from './helper'
const SAVE_CONFIG = gql`
mutation Save($config: JSONObject, $accounts: JSONObject) {
saveConfig(config: $config)
saveAccounts(accounts: $accounts)
}
`
const GET_INFO = gql`
query getData {
config
accounts
cryptoCurrencies {
code
display
}
}
`
const AdvancedWallet = () => {
const SCREEN_KEY = namespaces.WALLETS
const { data } = useQuery(GET_INFO)
const [saveConfig, { error }] = useMutation(SAVE_CONFIG, {
refetchQueries: () => ['getData']
})
const save = (rawConfig, accounts) => {
const config = toNamespace(SCREEN_KEY)(rawConfig)
return saveConfig({ variables: { config, accounts } })
}
const config = data?.config && fromNamespace(SCREEN_KEY)(data.config)
const cryptoCurrencies = data?.cryptoCurrencies ?? []
return (
<EditableTable
name="advancedWallet"
namespaces={R.map(R.path(['code']))(cryptoCurrencies)}
data={config}
error={error?.message}
enableEdit
editWidth={174}
save={save}
validationSchema={AdvancedWalletSchema}
elements={getAdvancedWalletElements(cryptoCurrencies, coinUtils)}
/>
)
}
export default AdvancedWallet

View file

@ -8,8 +8,11 @@ import { NamespacedTable as EditableTable } from 'src/components/editableTable'
import TitleSection from 'src/components/layout/TitleSection' import TitleSection from 'src/components/layout/TitleSection'
import FormRenderer from 'src/pages/Services/FormRenderer' import FormRenderer from 'src/pages/Services/FormRenderer'
import schemas from 'src/pages/Services/schemas' import schemas from 'src/pages/Services/schemas'
import { ReactComponent as ReverseSettingsIcon } from 'src/styling/icons/circle buttons/settings/white.svg'
import { ReactComponent as SettingsIcon } from 'src/styling/icons/circle buttons/settings/zodiac.svg'
import { fromNamespace, toNamespace } from 'src/utils/config' import { fromNamespace, toNamespace } from 'src/utils/config'
import AdvancedWallet from './AdvancedWallet'
import Wizard from './Wizard' import Wizard from './Wizard'
import { WalletSchema, getElements } from './helper' import { WalletSchema, getElements } from './helper'
@ -48,6 +51,7 @@ const Wallet = ({ name: SCREEN_KEY }) => {
const [editingSchema, setEditingSchema] = useState(null) const [editingSchema, setEditingSchema] = useState(null)
const [onChangeFunction, setOnChangeFunction] = useState(null) const [onChangeFunction, setOnChangeFunction] = useState(null)
const [wizard, setWizard] = useState(false) const [wizard, setWizard] = useState(false)
const [advancedSettings, setAdvancedSettings] = useState(false)
const { data } = useQuery(GET_INFO) const { data } = useQuery(GET_INFO)
const [saveConfig, { error }] = useMutation(SAVE_CONFIG, { const [saveConfig, { error }] = useMutation(SAVE_CONFIG, {
@ -99,7 +103,17 @@ const Wallet = ({ name: SCREEN_KEY }) => {
return ( return (
<> <>
<TitleSection title="Wallet Settings" /> <TitleSection
title="Wallet Settings"
button={{
text: 'Advanced settings',
icon: SettingsIcon,
inverseIcon: ReverseSettingsIcon,
toggle: setAdvancedSettings
}}
/>
{!advancedSettings && (
<>
<EditableTable <EditableTable
name="test" name="test"
namespaces={R.map(R.path(['code']))(cryptoCurrencies)} namespaces={R.map(R.path(['code']))(cryptoCurrencies)}
@ -141,6 +155,9 @@ const Wallet = ({ name: SCREEN_KEY }) => {
</Modal> </Modal>
)} )}
</> </>
)}
{advancedSettings && <AdvancedWallet></AdvancedWallet>}
</>
) )
} }

View file

@ -1,3 +1,4 @@
import { utils as coinUtils } from 'lamassu-coins'
import * as R from 'ramda' import * as R from 'ramda'
import React, { useState } from 'react' import React, { useState } from 'react'
@ -57,7 +58,14 @@ const Wizard = ({ coin, onClose, accountsConfig, accounts, save, error }) => {
: accountsToSave : accountsToSave
if (isLastStep) { if (isLastStep) {
const configToSave = { ...newConfig, zeroConfLimit: 0 } const defaultCryptoUnit = R.head(
R.keys(coinUtils.getCryptoCurrency(coin.code).units)
)
const configToSave = {
...newConfig,
zeroConfLimit: 0,
cryptoUnits: defaultCryptoUnit
}
return save(toNamespace(coin.code, configToSave), newAccounts) return save(toNamespace(coin.code, configToSave), newAccounts)
} }

View file

@ -28,6 +28,48 @@ const WalletSchema = Yup.object().shape({
.transform(transformNumber) .transform(transformNumber)
}) })
const AdvancedWalletSchema = Yup.object().shape({
cryptoUnits: Yup.string().required()
})
const getAdvancedWalletElements = (cryptoCurrencies, coinUtils) => {
const viewCryptoCurrency = it =>
R.compose(
R.prop(['display']),
R.find(R.propEq('code', it))
)(cryptoCurrencies)
const getOptions = R.curry((coinUtils, it) => {
const options = R.keys(coinUtils.getCryptoCurrency(it.id).units)
return R.map(option => {
return { code: option, display: option }
})(options)
})
return [
{
name: 'id',
header: 'Cryptocurrency',
width: 180,
view: viewCryptoCurrency,
size: 'sm',
editable: false
},
{
name: 'cryptoUnits',
size: 'sm',
stripe: true,
width: 190,
input: Autocomplete,
inputProps: {
options: getOptions(coinUtils),
valueProp: 'code',
labelProp: 'display'
}
}
]
}
const getElements = (cryptoCurrencies, accounts, onChange, wizard = false) => { const getElements = (cryptoCurrencies, accounts, onChange, wizard = false) => {
const widthAdjust = wizard ? 11 : 0 const widthAdjust = wizard ? 11 : 0
const viewCryptoCurrency = it => { const viewCryptoCurrency = it => {
@ -134,4 +176,10 @@ const getElements = (cryptoCurrencies, accounts, onChange, wizard = false) => {
] ]
} }
export { WalletSchema, getElements, filterClass } export {
WalletSchema,
AdvancedWalletSchema,
getElements,
filterClass,
getAdvancedWalletElements
}

View file

@ -1,6 +1,7 @@
import { useQuery, useMutation } from '@apollo/react-hooks' import { useQuery, useMutation } from '@apollo/react-hooks'
import { makeStyles } from '@material-ui/core' import { makeStyles } from '@material-ui/core'
import gql from 'graphql-tag' import gql from 'graphql-tag'
import { utils as coinUtils } from 'lamassu-coins'
import * as R from 'ramda' import * as R from 'ramda'
import React, { useState } from 'react' import React, { useState } from 'react'
@ -53,7 +54,14 @@ const AllSet = ({ data: currentData, doContinue }) => {
const cryptoCurrencies = data?.cryptoCurrencies ?? [] const cryptoCurrencies = data?.cryptoCurrencies ?? []
const save = () => { const save = () => {
const adjustedData = { zeroConfLimit: 0, ...currentData } const defaultCryptoUnit = R.head(
R.keys(coinUtils.getCryptoCurrency(coin).units)
)
const adjustedData = {
zeroConfLimit: 0,
...currentData,
cryptoUnits: defaultCryptoUnit
}
if (!WalletSchema.isValidSync(adjustedData)) return setError(true) if (!WalletSchema.isValidSync(adjustedData)) return setError(true)
const withCoin = toNamespace(coin, R.omit('coin', adjustedData)) const withCoin = toNamespace(coin, R.omit('coin', adjustedData))