Skip to content

Commit

Permalink
feat(neuron-ui): use real cycles
Browse files Browse the repository at this point in the history
  • Loading branch information
Keith-CY committed Aug 20, 2019
1 parent 01d02e0 commit 874e781
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 37 deletions.
17 changes: 10 additions & 7 deletions packages/neuron-ui/src/components/Send/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { calculateCycles } from 'services/remote/wallets'

import { Message } from 'utils/const'
import { verifyAddress, verifyAmountRange } from 'utils/validators'
import { CKBToShannonFormatter } from 'utils/formatters'
import { outputsToTotalCapacity } from 'utils/formatters'
import { TransactionOutput } from '.'

let cyclesTimer: ReturnType<typeof setTimeout>
Expand Down Expand Up @@ -97,10 +97,7 @@ const useOnTransactionChange = (walletID: string, items: TransactionOutput[], di
if (validateTransactionParams({ items })) {
calculateCycles({
walletID,
items: items.map(item => ({
address: item.address,
capacity: CKBToShannonFormatter(item.amount, item.unit),
})),
capacities: outputsToTotalCapacity(items),
})
.then(response => {
if (response.status) {
Expand Down Expand Up @@ -153,7 +150,12 @@ const useOnItemChange = (updateTransactionOutput: Function) =>
value?: string
) => {
if (undefined !== value) {
updateTransactionOutput(field)(idx)(value)
if (field === 'amount') {
const amount = value.replace(/[^\d.]/g, '')
updateTransactionOutput(field)(idx)(amount)
} else {
updateTransactionOutput(field)(idx)(value)
}
}
},
[updateTransactionOutput]
Expand All @@ -173,9 +175,10 @@ const useUpdateTransactionPrice = (dispatch: StateDispatch) =>
useCallback(
(_e: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, value?: string) => {
if (undefined !== value) {
const price = value.replace(/[^\d]/g, '')
dispatch({
type: AppActions.UpdateSendPrice,
payload: value.trim(),
payload: price,
})
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ const TransactionFee: React.FunctionComponent<TransactionFee> = ({
<Label>{t('send.price')}</Label>
</Stack.Item>
<Stack.Item grow>
<TextField type="number" value={price} onChange={onPriceChange} />
<TextField value={price} onChange={onPriceChange} />
</Stack.Item>
{actionSpacer}
</Stack>
Expand Down
5 changes: 4 additions & 1 deletion packages/neuron-ui/src/services/remote/wallets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ const CONTROLLER_NAME = 'wallets'
export const updateWallet = controllerMethodWrapper(CONTROLLER_NAME)(
controller => (params: Controller.UpdateWalletParams) => controller.update(params)
)

export const getCurrentWallet = controllerMethodWrapper(CONTROLLER_NAME)(controller => () => controller.getCurrent())

export const getWalletList = controllerMethodWrapper(CONTROLLER_NAME)(controller => () => controller.getAll())

export const createWallet = controllerMethodWrapper(CONTROLLER_NAME)(
controller => (params: Controller.CreateWalletParams) => controller.create(params)
)

export const importMnemonic = controllerMethodWrapper(CONTROLLER_NAME)(
controller => (params: Controller.ImportMnemonicParams) => controller.importMnemonic(params)
)
Expand Down Expand Up @@ -43,7 +46,7 @@ export const updateAddressDescription = controllerMethodWrapper(CONTROLLER_NAME)
)

export const calculateCycles = controllerMethodWrapper(CONTROLLER_NAME)(
controller => (params: Controller.CalculateCycles) => controller.calculateCycles(params)
controller => (params: Controller.ComputeCycles) => controller.computeCycles(params)
)

export default {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { getNeuronWalletState } from 'services/remote'
import initStates from 'states/initStates'
import { Routes } from 'utils/const'
import { WalletWizardPath } from 'components/WalletWizard'
import addressesToBalance from 'utils/addressesToBalance'
import { addressesToBalance } from 'utils/formatters'
import {
wallets as walletsCache,
addresses as addressesCache,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { WalletWizardPath } from 'components/WalletWizard'
import i18n from 'utils/i18n'
import { wallets as walletsCache, currentWallet as currentWalletCache } from 'utils/localCache'
import { Routes } from 'utils/const'
import addressesToBalance from 'utils/addressesToBalance'
import { addressesToBalance } from 'utils/formatters'
import { NeuronWalletActions } from '../reducer'
import { addNotification, addPopup } from './app'

Expand Down
73 changes: 72 additions & 1 deletion packages/neuron-ui/src/tests/formatters.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import { CapacityUnit } from 'utils/const'
import { currencyFormatter, currencyCode, CKBToShannonFormatter, shannonToCKBFormatter } from 'utils/formatters'
import {
currencyFormatter,
currencyCode,
CKBToShannonFormatter,
shannonToCKBFormatter,
addressesToBalance,
outputsToTotalCapacity,
} from 'utils/formatters'

describe(`formatters`, () => {
it(`currencyFormatter`, () => {
Expand Down Expand Up @@ -201,5 +208,69 @@ describe(`formatters`, () => {
expect(shannonToCKBFormatter(fixture.source)).toBe(fixture.target)
})
})

it('addresses to balance', () => {
const fixture = [
{
address: 'ckt1q9gry5zg8stq8ruq5wfz3lm5wn2k7qw3ulsfmdhe98f2j1',
identifier: '4040ba0ed8a361c59c30bb92f46128f95eaa9bcb',
description: 'description',
type: 0 as 0 | 1,
txCount: 0,
balance: '100',
index: 0,
},
{
address: 'ckt1q9gry5zg8stq8ruq5wfz3lm5wn2k7qw3ulsfmdhe98f2j3',
identifier: '4040ba0ed8a361c59c30bb92f46128f95eaa9bcb',
description: 'description',
type: 0 as 0 | 1,
txCount: 123,
balance: '10000',
index: 1,
},
{
address: 'ckt1q9gry5zg8stq8ruq5wfz3lm5wn2k7qw3ulsfmdhe98f2j2',
identifier: '4040ba0ed8a361c59c30bb92f46128f95eaa9bcd',
description: 'description',
type: 1 as 0 | 1,
txCount: 0,
balance: '200',
index: 2,
},
{
address: 'ckt1q9gry5zg8stq8ruq5wfz3lm5wn2k7qw3ulsfmdhe98f2jd',
identifier: '4040ba0ed8a361c59c30bb92f46128f95eaa9bcd',
description: 'description',
type: 1 as 0 | 1,
txCount: 123,
balance: '10000',
index: 3,
},
]
expect(addressesToBalance(fixture)).toBe('20300')
})

it('outputsToTotalCapacity', () => {
const fixture: any = [
{
amount: '100',
unit: 'CKB',
},
{
amount: '10000',
unit: 'CKB',
},
{
amount: '200',
unit: 'CKB',
},
{
amount: '10000',
unit: 'CKB',
},
]
expect(outputsToTotalCapacity(fixture)).toBe('20300')
})
})
})
7 changes: 2 additions & 5 deletions packages/neuron-ui/src/types/Controller/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,9 @@ declare namespace Controller {
description: string
}

interface CalculateCycles {
interface ComputeCycles {
walletID: string
items: {
address: string
capacity: string
}
capacities: string
}

type GetAddressesByWalletIDParams = string
Expand Down
5 changes: 0 additions & 5 deletions packages/neuron-ui/src/utils/addressesToBalance.ts

This file was deleted.

61 changes: 57 additions & 4 deletions packages/neuron-ui/src/utils/formatters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ import { CapacityUnit } from './const'

const base = 10e9
const numberParser = (value: string, exchange: string) => {
if (Number.isNaN(+value)) {
throw new TypeError('Value is not a valid number')
}
if (Number.isNaN(+exchange)) {
throw new TypeError('Exchange is not a valid number')
}
const res = (BigInt(value) * BigInt(+exchange * base)).toString()
const integer = res.slice(0, res.length - 10)
const decimal = res.slice(res.length - 10).replace(/0+$/, '')
Expand Down Expand Up @@ -41,10 +47,18 @@ export type currencyCode = 'CKB' | 'CNY' | 'USD'
* @returns
*/
export const currencyFormatter = (
shannons: string,
shannons: string = '0',
unit: currencyCode = 'CKB',
exchange: string = '0.000000001'
): string => {
if (Number.isNaN(+shannons)) {
throw new TypeError(`Shannons is not a valid number`)
}

if (Number.isNaN(+exchange)) {
throw new TypeError(`Exchange is not a valid number`)
}

const [integer, decimal] = numberParser(shannons, exchange)
const dot = '.'
const delimiter = ','
Expand All @@ -60,12 +74,16 @@ export const currencyFormatter = (
return `${integer.replace(/\B(?=(\d{3})+(?!\d))/g, delimiter)}${dot}${decimal} ${unit}`
}

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

switch (uint) {
switch (unit) {
case CapacityUnit.CKB: {
return (BigInt(num) * BigInt(1e8 / decimalLength)).toString()
}
Expand All @@ -81,7 +99,11 @@ export const CKBToShannonFormatter = (amount: string, uint: CapacityUnit) => {
}
}

export const shannonToCKBFormatter = (shannon: string) => {
export const shannonToCKBFormatter = (shannon: string = '0') => {
if (Number.isNaN(+shannon)) {
console.warn(`Shannon is not a valid number`)
return shannon
}
const sign = shannon.startsWith('-') ? '-' : ''
const unsignedShannon = shannon.replace(/^-?0*/, '')
let unsignedCKB = ''
Expand All @@ -106,6 +128,10 @@ export const shannonToCKBFormatter = (shannon: string) => {
}

export const localNumberFormatter = (num: string | number = 0) => {
if (Number.isNaN(+num)) {
console.warn(`Nuumber is not a valid number`)
return num
}
return numberFormatter.format(+num)
}

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

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

export const addressesToBalance = (addresses: State.Address[] = []) => {
return addresses
.reduce((total, addr) => {
if (Number.isNaN(+addr.balance)) {
return total
}
return total + BigInt(addr.balance || 0)
}, BigInt(0))
.toString()
}

export const outputsToTotalCapacity = (outputs: { amount: string; unit: CapacityUnit }[]) => {
const totalCapacity = outputs.reduce((total, cur) => {
if (Number.isNaN(+cur.amount)) {
return total
}
return total + BigInt(CKBToShannonFormatter(cur.amount, cur.unit))
}, BigInt(0))
return totalCapacity.toString()
}

export default {
queryFormatter,
currencyFormatter,
Expand All @@ -125,4 +176,6 @@ export default {
localNumberFormatter,
uniformTimeFormatter,
priceToFee,
addressesToBalance,
outputsToTotalCapacity,
}
12 changes: 1 addition & 11 deletions packages/neuron-wallet/src/controllers/wallets/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ export default class WalletsController {
}

@CatchControllerError
public static async computeCycles(params: { id: string; walletID: string; capacities: string }) {
public static async computeCycles(params: { walletID: string; capacities: string }) {
if (!params) {
throw new IsRequired('Parameters')
}
Expand All @@ -392,16 +392,6 @@ export default class WalletsController {
}
}

@CatchControllerError
public static async calculateCycles(params: { walletID: string; items: { address: string; capacity: string }[] }) {
// TODO: This is a mock cycles
const cycles = params.items.filter(item => +item.capacity > 0).length.toString()
return {
status: ResponseCode.Success,
result: cycles,
}
}

@CatchControllerError
public static async updateAddressDescription({
walletID,
Expand Down

0 comments on commit 874e781

Please sign in to comment.