Skip to content

Commit 874e781

Browse files
committed
feat(neuron-ui): use real cycles
1 parent 01d02e0 commit 874e781

10 files changed

Lines changed: 149 additions & 37 deletions

File tree

packages/neuron-ui/src/components/Send/hooks.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { calculateCycles } from 'services/remote/wallets'
66

77
import { Message } from 'utils/const'
88
import { verifyAddress, verifyAmountRange } from 'utils/validators'
9-
import { CKBToShannonFormatter } from 'utils/formatters'
9+
import { outputsToTotalCapacity } from 'utils/formatters'
1010
import { TransactionOutput } from '.'
1111

1212
let cyclesTimer: ReturnType<typeof setTimeout>
@@ -97,10 +97,7 @@ const useOnTransactionChange = (walletID: string, items: TransactionOutput[], di
9797
if (validateTransactionParams({ items })) {
9898
calculateCycles({
9999
walletID,
100-
items: items.map(item => ({
101-
address: item.address,
102-
capacity: CKBToShannonFormatter(item.amount, item.unit),
103-
})),
100+
capacities: outputsToTotalCapacity(items),
104101
})
105102
.then(response => {
106103
if (response.status) {
@@ -153,7 +150,12 @@ const useOnItemChange = (updateTransactionOutput: Function) =>
153150
value?: string
154151
) => {
155152
if (undefined !== value) {
156-
updateTransactionOutput(field)(idx)(value)
153+
if (field === 'amount') {
154+
const amount = value.replace(/[^\d.]/g, '')
155+
updateTransactionOutput(field)(idx)(amount)
156+
} else {
157+
updateTransactionOutput(field)(idx)(value)
158+
}
157159
}
158160
},
159161
[updateTransactionOutput]
@@ -173,9 +175,10 @@ const useUpdateTransactionPrice = (dispatch: StateDispatch) =>
173175
useCallback(
174176
(_e: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, value?: string) => {
175177
if (undefined !== value) {
178+
const price = value.replace(/[^\d]/g, '')
176179
dispatch({
177180
type: AppActions.UpdateSendPrice,
178-
payload: value.trim(),
181+
payload: price,
179182
})
180183
}
181184
},

packages/neuron-ui/src/components/TransactionFeePanel/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ const TransactionFee: React.FunctionComponent<TransactionFee> = ({
7676
<Label>{t('send.price')}</Label>
7777
</Stack.Item>
7878
<Stack.Item grow>
79-
<TextField type="number" value={price} onChange={onPriceChange} />
79+
<TextField value={price} onChange={onPriceChange} />
8080
</Stack.Item>
8181
{actionSpacer}
8282
</Stack>

packages/neuron-ui/src/services/remote/wallets.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@ const CONTROLLER_NAME = 'wallets'
55
export const updateWallet = controllerMethodWrapper(CONTROLLER_NAME)(
66
controller => (params: Controller.UpdateWalletParams) => controller.update(params)
77
)
8+
89
export const getCurrentWallet = controllerMethodWrapper(CONTROLLER_NAME)(controller => () => controller.getCurrent())
10+
911
export const getWalletList = controllerMethodWrapper(CONTROLLER_NAME)(controller => () => controller.getAll())
1012

1113
export const createWallet = controllerMethodWrapper(CONTROLLER_NAME)(
1214
controller => (params: Controller.CreateWalletParams) => controller.create(params)
1315
)
16+
1417
export const importMnemonic = controllerMethodWrapper(CONTROLLER_NAME)(
1518
controller => (params: Controller.ImportMnemonicParams) => controller.importMnemonic(params)
1619
)
@@ -43,7 +46,7 @@ export const updateAddressDescription = controllerMethodWrapper(CONTROLLER_NAME)
4346
)
4447

4548
export const calculateCycles = controllerMethodWrapper(CONTROLLER_NAME)(
46-
controller => (params: Controller.CalculateCycles) => controller.calculateCycles(params)
49+
controller => (params: Controller.ComputeCycles) => controller.computeCycles(params)
4750
)
4851

4952
export default {

packages/neuron-ui/src/states/stateProvider/actionCreators/app.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { getNeuronWalletState } from 'services/remote'
33
import initStates from 'states/initStates'
44
import { Routes } from 'utils/const'
55
import { WalletWizardPath } from 'components/WalletWizard'
6-
import addressesToBalance from 'utils/addressesToBalance'
6+
import { addressesToBalance } from 'utils/formatters'
77
import {
88
wallets as walletsCache,
99
addresses as addressesCache,

packages/neuron-ui/src/states/stateProvider/actionCreators/wallets.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { WalletWizardPath } from 'components/WalletWizard'
1919
import i18n from 'utils/i18n'
2020
import { wallets as walletsCache, currentWallet as currentWalletCache } from 'utils/localCache'
2121
import { Routes } from 'utils/const'
22-
import addressesToBalance from 'utils/addressesToBalance'
22+
import { addressesToBalance } from 'utils/formatters'
2323
import { NeuronWalletActions } from '../reducer'
2424
import { addNotification, addPopup } from './app'
2525

packages/neuron-ui/src/tests/formatters.test.ts

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
import { CapacityUnit } from 'utils/const'
2-
import { currencyFormatter, currencyCode, CKBToShannonFormatter, shannonToCKBFormatter } from 'utils/formatters'
2+
import {
3+
currencyFormatter,
4+
currencyCode,
5+
CKBToShannonFormatter,
6+
shannonToCKBFormatter,
7+
addressesToBalance,
8+
outputsToTotalCapacity,
9+
} from 'utils/formatters'
310

411
describe(`formatters`, () => {
512
it(`currencyFormatter`, () => {
@@ -201,5 +208,69 @@ describe(`formatters`, () => {
201208
expect(shannonToCKBFormatter(fixture.source)).toBe(fixture.target)
202209
})
203210
})
211+
212+
it('addresses to balance', () => {
213+
const fixture = [
214+
{
215+
address: 'ckt1q9gry5zg8stq8ruq5wfz3lm5wn2k7qw3ulsfmdhe98f2j1',
216+
identifier: '4040ba0ed8a361c59c30bb92f46128f95eaa9bcb',
217+
description: 'description',
218+
type: 0 as 0 | 1,
219+
txCount: 0,
220+
balance: '100',
221+
index: 0,
222+
},
223+
{
224+
address: 'ckt1q9gry5zg8stq8ruq5wfz3lm5wn2k7qw3ulsfmdhe98f2j3',
225+
identifier: '4040ba0ed8a361c59c30bb92f46128f95eaa9bcb',
226+
description: 'description',
227+
type: 0 as 0 | 1,
228+
txCount: 123,
229+
balance: '10000',
230+
index: 1,
231+
},
232+
{
233+
address: 'ckt1q9gry5zg8stq8ruq5wfz3lm5wn2k7qw3ulsfmdhe98f2j2',
234+
identifier: '4040ba0ed8a361c59c30bb92f46128f95eaa9bcd',
235+
description: 'description',
236+
type: 1 as 0 | 1,
237+
txCount: 0,
238+
balance: '200',
239+
index: 2,
240+
},
241+
{
242+
address: 'ckt1q9gry5zg8stq8ruq5wfz3lm5wn2k7qw3ulsfmdhe98f2jd',
243+
identifier: '4040ba0ed8a361c59c30bb92f46128f95eaa9bcd',
244+
description: 'description',
245+
type: 1 as 0 | 1,
246+
txCount: 123,
247+
balance: '10000',
248+
index: 3,
249+
},
250+
]
251+
expect(addressesToBalance(fixture)).toBe('20300')
252+
})
253+
254+
it('outputsToTotalCapacity', () => {
255+
const fixture: any = [
256+
{
257+
amount: '100',
258+
unit: 'CKB',
259+
},
260+
{
261+
amount: '10000',
262+
unit: 'CKB',
263+
},
264+
{
265+
amount: '200',
266+
unit: 'CKB',
267+
},
268+
{
269+
amount: '10000',
270+
unit: 'CKB',
271+
},
272+
]
273+
expect(outputsToTotalCapacity(fixture)).toBe('20300')
274+
})
204275
})
205276
})

packages/neuron-ui/src/types/Controller/index.d.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,9 @@ declare namespace Controller {
4545
description: string
4646
}
4747

48-
interface CalculateCycles {
48+
interface ComputeCycles {
4949
walletID: string
50-
items: {
51-
address: string
52-
capacity: string
53-
}
50+
capacities: string
5451
}
5552

5653
type GetAddressesByWalletIDParams = string

packages/neuron-ui/src/utils/addressesToBalance.ts

Lines changed: 0 additions & 5 deletions
This file was deleted.

packages/neuron-ui/src/utils/formatters.ts

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ import { CapacityUnit } from './const'
44

55
const base = 10e9
66
const numberParser = (value: string, exchange: string) => {
7+
if (Number.isNaN(+value)) {
8+
throw new TypeError('Value is not a valid number')
9+
}
10+
if (Number.isNaN(+exchange)) {
11+
throw new TypeError('Exchange is not a valid number')
12+
}
713
const res = (BigInt(value) * BigInt(+exchange * base)).toString()
814
const integer = res.slice(0, res.length - 10)
915
const decimal = res.slice(res.length - 10).replace(/0+$/, '')
@@ -41,10 +47,18 @@ export type currencyCode = 'CKB' | 'CNY' | 'USD'
4147
* @returns
4248
*/
4349
export const currencyFormatter = (
44-
shannons: string,
50+
shannons: string = '0',
4551
unit: currencyCode = 'CKB',
4652
exchange: string = '0.000000001'
4753
): string => {
54+
if (Number.isNaN(+shannons)) {
55+
throw new TypeError(`Shannons is not a valid number`)
56+
}
57+
58+
if (Number.isNaN(+exchange)) {
59+
throw new TypeError(`Exchange is not a valid number`)
60+
}
61+
4862
const [integer, decimal] = numberParser(shannons, exchange)
4963
const dot = '.'
5064
const delimiter = ','
@@ -60,12 +74,16 @@ export const currencyFormatter = (
6074
return `${integer.replace(/\B(?=(\d{3})+(?!\d))/g, delimiter)}${dot}${decimal} ${unit}`
6175
}
6276

63-
export const CKBToShannonFormatter = (amount: string, uint: CapacityUnit) => {
77+
export const CKBToShannonFormatter = (amount: string = '0', unit: CapacityUnit) => {
78+
if (Number.isNaN(+amount)) {
79+
console.warn(`Amount is not a valid number`)
80+
return `${amount} ${unit}`
81+
}
6482
const [integer = '0', decimal = ''] = amount.split('.')
6583
const decimalLength = 10 ** decimal.length
6684
const num = integer + decimal
6785

68-
switch (uint) {
86+
switch (unit) {
6987
case CapacityUnit.CKB: {
7088
return (BigInt(num) * BigInt(1e8 / decimalLength)).toString()
7189
}
@@ -81,7 +99,11 @@ export const CKBToShannonFormatter = (amount: string, uint: CapacityUnit) => {
8199
}
82100
}
83101

84-
export const shannonToCKBFormatter = (shannon: string) => {
102+
export const shannonToCKBFormatter = (shannon: string = '0') => {
103+
if (Number.isNaN(+shannon)) {
104+
console.warn(`Shannon is not a valid number`)
105+
return shannon
106+
}
85107
const sign = shannon.startsWith('-') ? '-' : ''
86108
const unsignedShannon = shannon.replace(/^-?0*/, '')
87109
let unsignedCKB = ''
@@ -106,6 +128,10 @@ export const shannonToCKBFormatter = (shannon: string) => {
106128
}
107129

108130
export const localNumberFormatter = (num: string | number = 0) => {
131+
if (Number.isNaN(+num)) {
132+
console.warn(`Nuumber is not a valid number`)
133+
return num
134+
}
109135
return numberFormatter.format(+num)
110136
}
111137

@@ -114,9 +140,34 @@ export const uniformTimeFormatter = (time: string | number | Date) => {
114140
}
115141

116142
export const priceToFee = (price: string, cycles: string) => {
143+
if (Number.isNaN(+price)) {
144+
console.warn(`Price is not a valid number`)
145+
return `0`
146+
}
117147
return (BigInt(price) * BigInt(cycles)).toString()
118148
}
119149

150+
export const addressesToBalance = (addresses: State.Address[] = []) => {
151+
return addresses
152+
.reduce((total, addr) => {
153+
if (Number.isNaN(+addr.balance)) {
154+
return total
155+
}
156+
return total + BigInt(addr.balance || 0)
157+
}, BigInt(0))
158+
.toString()
159+
}
160+
161+
export const outputsToTotalCapacity = (outputs: { amount: string; unit: CapacityUnit }[]) => {
162+
const totalCapacity = outputs.reduce((total, cur) => {
163+
if (Number.isNaN(+cur.amount)) {
164+
return total
165+
}
166+
return total + BigInt(CKBToShannonFormatter(cur.amount, cur.unit))
167+
}, BigInt(0))
168+
return totalCapacity.toString()
169+
}
170+
120171
export default {
121172
queryFormatter,
122173
currencyFormatter,
@@ -125,4 +176,6 @@ export default {
125176
localNumberFormatter,
126177
uniformTimeFormatter,
127178
priceToFee,
179+
addressesToBalance,
180+
outputsToTotalCapacity,
128181
}

packages/neuron-wallet/src/controllers/wallets/index.ts

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ export default class WalletsController {
373373
}
374374

375375
@CatchControllerError
376-
public static async computeCycles(params: { id: string; walletID: string; capacities: string }) {
376+
public static async computeCycles(params: { walletID: string; capacities: string }) {
377377
if (!params) {
378378
throw new IsRequired('Parameters')
379379
}
@@ -392,16 +392,6 @@ export default class WalletsController {
392392
}
393393
}
394394

395-
@CatchControllerError
396-
public static async calculateCycles(params: { walletID: string; items: { address: string; capacity: string }[] }) {
397-
// TODO: This is a mock cycles
398-
const cycles = params.items.filter(item => +item.capacity > 0).length.toString()
399-
return {
400-
status: ResponseCode.Success,
401-
result: cycles,
402-
}
403-
}
404-
405395
@CatchControllerError
406396
public static async updateAddressDescription({
407397
walletID,

0 commit comments

Comments
 (0)