Skip to content

Commit

Permalink
UIA register - Multi-step exchange
Browse files Browse the repository at this point in the history
  • Loading branch information
1aerostorm committed Jan 8, 2024
1 parent de3c172 commit 558f860
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 65 deletions.
7 changes: 5 additions & 2 deletions config/default.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"rest_api": "https://dev.golos.app",
"rest_api": "http://89.22.173.104:3000",
"allowed_clients": [
"dev.golos.app",
"devnotify.golos.app",
Expand All @@ -14,7 +14,10 @@
"signing_key": "5K67PNheLkmxkgJ5UjvR8Nyt3GVPoLEN1dMZjFuNETzrNyMecPG",
"delegation": "75000.000000 GESTS",
"free_regs_per_day": 10,
"uias": ["YMUSDT", "YMPZM", "YMHIVE", "TESTF"]
"uias": {
"assets": ["YMUSDT", "YMPZM", "YMHIVE", "YMXMR", "TESTF"],
"YMXMR": ["YMXHR/YMPZM", "YMPZM/YMUSDT", "YMUSDT/GOLOS"]
}
},
"server_session_secret": "exiKdyF+IwRIXJDmtGIl4vWUz4i3eVSISpfZoeYc0s4=",
"session_cookie_key": "X-Reg-ISession",
Expand Down
7 changes: 4 additions & 3 deletions src/elements/forms/AmountField.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,19 @@ class AmountField extends React.Component {
const { value, } = field
const { values, setFieldTouched, setFieldValue } = form
return <input type='text' value={value.amountStr} placeholder={placeholder}
{...rest} onChange={(e) => this.onChange(e, values, setFieldTouched, setFieldValue)}
{...rest} onChange={(e) => this.onChange(e, values, form)}
/>
}

onChange = (e, values, setFieldTouched, setFieldValue) => {
onChange = (e, values, form) => {
const { name } = this.props
const newAmount = values[name].withChange(e.target.value)
if (newAmount.hasChange && newAmount.asset.amount >= 0) {
const { setFieldTouched, setFieldValue } = form
setFieldValue(name, newAmount)
setFieldTouched(name, true, false)
if (this.props.onChange) {
this.props.onChange(newAmount.asset)
this.props.onChange(newAmount.asset, form)
}
}
}
Expand Down
7 changes: 6 additions & 1 deletion src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,12 @@
"deposited": "Received ",
"deposited2": ". Placing limit order to exchange it to GOLOS to register your account.",
"cannot_place_order": "Cannot place order: ",
"you_will_receive": "You will receive "
"you_will_receive": "You will receive ",
"cannot_check_orders": "Cannot check exchange ability. Try again later. Or try another currency. Error details: ",
"no_orders": "No orders in ",
"cannot_register_with_it": ", cannot register.",
"too_low_orders": "Too low orders in ",
"unknown_error": " - error in "
},
"invites_jsx": {
"claim_wrong_secret": "Wrong secret",
Expand Down
7 changes: 6 additions & 1 deletion src/locales/ru-RU.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,12 @@
"deposited": "Получено ",
"deposited2": ". Размещаем ордер для обмена их на GOLOS для регистрации вашего аккаунта...",
"cannot_place_order": "Не удается разместить ордер: ",
"you_will_receive": "Вы получите примерно "
"you_will_receive": "Вы получите примерно ",
"cannot_check_orders": "Не удается проверить возможность обмена. Попробуйте позже, или другую валюту. Подробнее об ошибке: ",
"no_orders": "Нет ордеров по направлению ",
"cannot_register_with_it": ", не можем зарегистрировать за такую сумму.",
"too_low_orders": "Слишком мало ордеров по направлению ",
"unknown_error": " - ошибка по направлению "
},
"invites_jsx": {
"claim_wrong_secret": "Неверно указан ключ",
Expand Down
135 changes: 88 additions & 47 deletions src/modules/register/UIARegister.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ class UIARegister extends React.Component {
error: '',
}

constructor(props) {
super(props)
}

async componentDidMount() {
const { clientCfg } = this.props

Expand All @@ -66,17 +70,18 @@ class UIARegister extends React.Component {

const { apidex_service } = clientCfg.config
const { uias } = clientCfg.config.registrar
const syms = uias.assets

const path = this.getPath()
if (path[1]) {
const params = new URLSearchParams(path[1])
const sym = params.get('uia')
if (sym) {
let assets
assets = await golos.api.getAssetsAsync('', uias)
assets = await golos.api.getAssetsAsync('', syms)

let error
if (!uias.includes(sym)) {
if (!syms.includes(sym)) {
error = sym + tt('uia_register_jsx.no_such_asset')
} else {
for (const asset of assets) {
Expand Down Expand Up @@ -188,8 +193,8 @@ class UIARegister extends React.Component {
}

let assets = []
if (uias.length) {
assets = await golos.api.getAssetsAsync('', uias)
if (syms.length) {
assets = await golos.api.getAssetsAsync('', syms)
}
this.setState({
loading: false,
Expand Down Expand Up @@ -392,7 +397,7 @@ class UIARegister extends React.Component {
</div>
}

amountValidate = (values) => {
amountValidate = async (values) => {
const errors = {}
const { minAmount } = this.state
if (values.amount.asset.lt(minAmount)) {
Expand All @@ -401,23 +406,56 @@ class UIARegister extends React.Component {
this.setState({
amountSubmitError: ''
})
return errors
}

_onAmountChange = async (amount) => {
const { clientCfg } = this.props
const { apidex_service } = clientCfg.config
let res
try {
res = await apidexExchange(apidex_service, amount, 'GOLOS')
} catch (err) {
console.error(err)
}
if (res) {
if (!errors.amount) {
const { clientCfg } = this.props
const { apidex_service } = clientCfg.config

const { uias } = clientCfg.config.registrar

const exchanges = uias[this.state.sym]
let exAmount = values.amount.asset.clone()
let error = null
let result = null
for (const ex of exchanges) {
const [ sym1, sym2 ] = ex.split('/')
let resEx
try {
resEx = await apidexExchange(apidex_service, exAmount, sym2)
} catch (err) {
console.error(err)
}
if (!resEx) {
error = tt('uia_register_jsx.cannot_check_orders') + exAmount.symbol + '/' + sym2
}
if (error) break
if (resEx.remain) {
error = tt('uia_register_jsx.too_low_orders') + exAmount.symbol + '/' + sym2 + tt('uia_register_jsx.cannot_register_with_it')
break
}
if (resEx.error === 'no_orders') {
error = tt('uia_register_jsx.no_orders') + exAmount.symbol + '/' + sym2 + tt('uia_register_jsx.cannot_register_with_it')
break
} else if (resEx.error) {
error = resEx.error + tt('uia_register_jsx.unknown_error') + exAmount.symbol + '/' + sym2 + tt('uia_register_jsx.cannot_register_with_it')
break
}
exAmount = resEx.result.clone()
result = exAmount.clone()
}

this.setState({
receive: res
receive: result,
})
if (error) {
errors.amount = error
}
}

return errors
}

_onAmountChange = async (amount, form) => {
}

_onAmountSubmit = async (values) => {
Expand Down Expand Up @@ -449,37 +487,40 @@ class UIARegister extends React.Component {
initialValues={initialForm}
validate={this.amountValidate}
onSubmit={this._onAmountSubmit}
validateOnMount={true}
>
{({
handleSubmit, isSubmitting, isValid, dirty, errors, touched, values, handleChange, setFieldValue,
}) => (
<form
onSubmit={handleSubmit}
autoComplete='off'
>
<div style={{ fontSize: '90%', marginTop: '0.5rem', marginBottom: '0.25rem' }}>
{tt('uia_register_jsx.enter_amount')}
</div>
<div className='input-group'>
<AmountField
name='amount'
className='input-group-field'
onChange={this._onAmountChange}
/>
</div>
<ErrorMessage name='amount' component='div' className='error' />
{amountSubmitError && <div className='error'>{amountSubmitError}</div>}
{!errors.amount && !amountSubmitError && receive ? <div style={{marginBottom:'0.5rem'}}>
{tt('uia_register_jsx.you_will_receive')}<b>~{receive.floatString}.</b>
</div> : null}

{isSubmitting && <LoadingIndicator type='circle' />}
<button className={'button ' + (isSubmitting || !isValid ? ' disabled' : '')}
type='submit' disabled={isSubmitting || !isValid}>
{tt('g.continue')}
</button>
</form>
)}
handleSubmit, isSubmitting, isValid, dirty, errors, touched, values, handleChange, setFieldValue, setFieldError,
}) => {
return (
<form
onSubmit={handleSubmit}
autoComplete='off'
>
<div style={{ fontSize: '90%', marginTop: '0.5rem', marginBottom: '0.25rem' }}>
{tt('uia_register_jsx.enter_amount')}
</div>
<div className='input-group'>
<AmountField
name='amount'
className='input-group-field'
onChange={this._onAmountChange}
/>
</div>
{errors.amount && <div className='error'>{errors.amount}</div>}
{amountSubmitError && <div className='error'>{amountSubmitError}</div>}
{!errors.amount && !amountSubmitError && receive ? <div style={{marginBottom:'0.5rem'}}>
{tt('uia_register_jsx.you_will_receive')}<b>~{receive.floatString}.</b>
</div> : null}

{isSubmitting && <LoadingIndicator type='circle' />}
<button className={'button ' + (isSubmitting || !isValid ? ' disabled' : '')}
type='submit' disabled={isSubmitting || !isValid}>
{tt('g.continue')}
</button>
</form>
)
}}
</Formik>
}

Expand Down
21 changes: 13 additions & 8 deletions src/pages/api/reg/[...all].js
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ let handler = nextConnect({ attachParams: true, })
}
})

.post('/api/reg/place_order/:amount', async (req, res) => {
.post('/api/reg/place_order/:amount/:receive', async (req, res) => {
await slowDownLimitReq(req)

const amountStr = req.params.amount.split('%20').join(' ')
Expand Down Expand Up @@ -558,7 +558,7 @@ let handler = nextConnect({ attachParams: true, })
owner: username,
orderid,
amount_to_sell: amountStr,
min_to_receive: chainProps.create_account_min_golos_fee,
min_to_receive: req.params.receive,
fill_or_kill: true,
expiration: 0xffffffff
}]]
Expand All @@ -585,7 +585,9 @@ let handler = nextConnect({ attachParams: true, })
throwErr(req, 400, ['Blockchain unavailable'])
}

let golos_received
const toReceive = await Asset(req.params.receive)

let received
for (let i = hist.length - 1; i >= 0; --i) {
const timestamp = +new Date(hist[i][1].timestamp + 'Z') / 1000
if (orderid - timestamp > 10) {
Expand All @@ -598,18 +600,21 @@ let handler = nextConnect({ attachParams: true, })
const golosAmount = await Asset(opData.current_orderid == orderid ?
opData.open_pays : opData.current_pays)

golos_received = golos_received || await Asset('0.000 GOLOS')
golos_received = golos_received.plus(golosAmount)
req.session.golos_received = golos_received.toString()
if (!received) {
received = await Asset(0, toReceive.precision, toReceive.symbol)
}
received = received.plus(golosAmount)
req.session.received = req.session.received || {}
req.session.received[toReceive.symbol] = received.toString()
await req.session.save()
}
}
}

if (golos_received) {
if (received) {
res.json({
status: 'ok',
golos_received,
received,
step: 'verified',
verification_way: 'uia'
})
Expand Down
8 changes: 6 additions & 2 deletions src/server/reg.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,12 @@ export function getClientCfg(req, params, locale = '') {
&& config.get('fake_emails_allowed');

cfg.registrar = config.has('registrar') ? config.get('registrar') : {}
if (!cfg.registrar.uias)
cfg.registrar.uias = []
const { registrar } = cfg
if (!registrar.uias) registrar.uias = {}
if (!registrar.uias.assets) registrar.uias.assets = []
for (const sym of registrar.uias.assets) {
if (!registrar.uias[sym]) registrar.uias[sym] = [sym + '/GOLOS']
}

cfg.apidex_service = config.has('apidex_service')
&& config.get('apidex_service')
Expand Down
6 changes: 5 additions & 1 deletion src/utils/ApidexApiClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,11 @@ export async function apidexExchange(apidex_service, sell, buySym) {
try {
let resp = await fetchEx(apidexUrl(apidex_service, `/api/v1/exchange/` + sell.toString() + '/' + buySym), request)
resp = await resp.json()
return await Asset(resp.result)
return {
result: resp.result ? await Asset(resp.result) : null,
remain: resp.remain ? await Asset(resp.remain) : null,
error: resp.error
}
} catch (err) {
console.error('apidexExchange', err)
return null
Expand Down

0 comments on commit 558f860

Please sign in to comment.