Skip to content
This repository has been archived by the owner on Nov 24, 2022. It is now read-only.

Commit

Permalink
feat: display token amounts with units and hover shows full token amo…
Browse files Browse the repository at this point in the history
…unt (#284)

* feat: adding a hover to show full amount

* feat: updated number to bn and change math options

* feat: on hover shows full number small changes to fix overspending

* feat: added a bn one const removed askiltcoin no longer needed

* refactor: some optimizations

* feat: removed reg exp no needed

* feat: removed check in balance as doing the same thing

Co-authored-by: Timo Welde <tjwelde@gmail.com>
  • Loading branch information
Dudleyneedham and tjwelde authored Sep 1, 2020
1 parent ef3cb09 commit 18ae521
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 68 deletions.
13 changes: 7 additions & 6 deletions src/components/DevTools/DevTools.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react'

import BN from 'bn.js'
import setupAndDelegate from './DevTools.anticov'
import {
ENDOWMENT,
Expand Down Expand Up @@ -133,21 +134,21 @@ class DevTools extends React.Component<Props> {
PersistentStore.store.getState()
)

const balance: number = selectedIdentity
const balance: BN = selectedIdentity
? Balances.getBalance(
PersistentStore.store.getState(),
selectedIdentity.identity.address
)
: 0
: new BN(0)

const minBalanceForBootstrap =
(ENDOWMENT + TRANSACTION_FEE) * Object.keys(identitiesPool).length +
MIN_BALANCE
const minBalanceForBootstrap = ENDOWMENT.add(TRANSACTION_FEE)
.muln(Object.keys(identitiesPool).length)
.add(MIN_BALANCE)

return (
<section className="DevTools">
<h2>Dev Tools</h2>
{selectedIdentity && balance > minBalanceForBootstrap ? (
{selectedIdentity && balance.gt(minBalanceForBootstrap) ? (
<div>
<div>
<h4>Auto Bootstrap</h4>
Expand Down
2 changes: 1 addition & 1 deletion src/components/DevTools/DevTools.wallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class BsIdentity {
BalanceUtilities.makeTransfer(
selectedIdentity,
identity.address,
ENDOWMENT,
ENDOWMENT.toNumber(),
() => {
const newContact: IContact = {
metaData: {
Expand Down
6 changes: 3 additions & 3 deletions src/components/IdentityView/IdentityView.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react'
import { connect, MapStateToProps } from 'react-redux'

import BN from 'bn.js'
import ContactRepository from '../../services/ContactRepository'
import errorService from '../../services/ErrorService'
import { notifySuccess } from '../../services/FeedbackService'
Expand Down Expand Up @@ -147,7 +147,7 @@ class IdentityView extends React.Component<Props, State> {
myContact.publicIdentity.address === myIdentity.identity.address
)

let balance = 0
let balance = new BN(0)
if (contact) {
balance = Balances.getBalance(
PersistentStore.store.getState(),
Expand Down Expand Up @@ -298,7 +298,7 @@ class IdentityView extends React.Component<Props, State> {
</>
)}

{!(balance > 0) && (
{balance && !balance.ltn(0) && (
<button
type="button"
className="requestTokens"
Expand Down
33 changes: 23 additions & 10 deletions src/components/KiltToken/KiltToken.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,42 @@
import React from 'react'
import React, { useState } from 'react'
import { formatBalance } from '@polkadot/util'
import BN from 'bn.js'
import './KiltToken.scss'

type Props = {
amount?: number
amount?: BN
colored?: boolean
}

const KiltToken: React.FC<Props> = ({ amount, colored = false }) => {
const [isShown, setIsShown] = useState(false)

if (amount == null) {
return <section className="KiltToken" />
}

let changeIndicator = ''
if (amount < 0) changeIndicator = 'decreased'
if (amount > 0) changeIndicator = 'increased'
if (amount.ltn(0)) changeIndicator = 'decreased'
if (amount.gtn(0)) changeIndicator = 'increased'

const classes = ['KiltToken', colored ? 'colored' : '', changeIndicator]

return (
<section className={classes.join(' ')} title={`${amount}`}>
{formatBalance(amount, {
withSiFull: true,
withUnit: 'KILT',
})}
<section
className={classes.join(' ')}
title={`${amount}`}
onMouseEnter={() => setIsShown(true)}
onMouseLeave={() => setIsShown(false)}
>
{!isShown &&
formatBalance(
amount,
{
withSiFull: true,
withUnit: 'KILT',
},
15
)}
{isShown && <>{amount.toString()}</>}
</section>
)
}
Expand Down
22 changes: 9 additions & 13 deletions src/containers/Balance/Balance.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Immutable from 'immutable'
import React, { ChangeEvent, ReactNode } from 'react'
import BN from 'bn.js'
import { connect, MapStateToProps } from 'react-redux'
import ContactPresentation from '../../components/ContactPresentation/ContactPresentation'
import KiltToken from '../../components/KiltToken/KiltToken'
Expand All @@ -26,7 +27,7 @@ import {
import './Balance.scss'

type StateProps = {
balances: Immutable.Map<string, number>
balances: Immutable.Map<string, BN>
}

type OwnProps = {
Expand Down Expand Up @@ -97,14 +98,9 @@ class Balance extends React.Component<Props, State> {
return
}

const amountNumber = Number(amount)
const amountNumber = new BN(amount)

if (
amount === '' ||
(Number.isFinite(amountNumber) &&
amountNumber > 0 &&
myBalance - amountNumber >= 0)
) {
if (amount === '' || (amountNumber.gtn(0) && amountNumber.lte(myBalance))) {
this.setState({
transfer: {
...transfer,
Expand All @@ -114,13 +110,13 @@ class Balance extends React.Component<Props, State> {
}
}

private getMyBalance(): number | undefined {
private getMyBalance(): BN | undefined {
const { balances, myIdentity } = this.props
return balances.get(myIdentity.identity.address)
}

private getTokenTransferElement(balance: number | undefined): ReactNode {
if (balance === undefined || balance < TRANSACTION_FEE) {
private getTokenTransferElement(balance: BN | undefined): ReactNode {
if (balance === undefined || balance.lt(TRANSACTION_FEE)) {
return <div>Not available due to insufficient funds.</div>
}

Expand All @@ -133,10 +129,10 @@ class Balance extends React.Component<Props, State> {
<label>Transfer amount</label>
<div>
<input
type="text"
type="number"
onChange={this.onEnterTransferTokens}
value={amount}
placeholder="Whole numbers"
placeholder="Whole KILT tokens"
/>
<KiltToken />
</div>
Expand Down
51 changes: 24 additions & 27 deletions src/services/BalanceUtilities.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,21 @@ import KiltToken from '../components/KiltToken/KiltToken'
import * as Balances from '../state/ducks/Balances'
import * as Wallet from '../state/ducks/Wallet'
import PersistentStore from '../state/PersistentStore'
import errorService from './ErrorService'
import { IContact, IMyIdentity } from '../types/Contact'
import { notify, notifySuccess } from './FeedbackService'
import { notify, notifySuccess, notifyFailure } from './FeedbackService'

const KILT_COIN = 1
const KILT_MICRO_COIN = 1_000_000
const KILT_FEMTO_COIN = '1000000000000000'
const KILT_COIN = new BN(1)
const KILT_FEMTO_COIN = new BN('1000000000000000')

// cost of a chain transaction
const TRANSACTION_FEE = 1 * KILT_COIN
const TRANSACTION_FEE = KILT_COIN.muln(1)

// any balance below this will we purged
const MIN_BALANCE = 1 * KILT_COIN
const MIN_BALANCE = KILT_COIN.muln(1)

// initial endowment for automatically created accounts
const ENDOWMENT = 30 * KILT_COIN
const ENDOWMENT = KILT_COIN.muln(30)

// TODO: do we need to do something upon deleting an identity?
class BalanceUtilities {
Expand All @@ -46,9 +46,9 @@ class BalanceUtilities {
}
}

public static async getMyBalance(identity: IMyIdentity): Promise<number> {
public static async getMyBalance(identity: IMyIdentity): Promise<BN> {
const balance: BN = await sdk.Balance.getBalance(identity.identity.address)
return BalanceUtilities.asKiltCoin(balance)
return balance
}

public static connectMyIdentities(
Expand All @@ -67,11 +67,11 @@ class BalanceUtilities {
amount: number,
successCallback?: () => void
): void {
const transferAmount: BN = BalanceUtilities.asFemtoKilt(amount)
const transferAmount = BalanceUtilities.asFemtoKilt(amount)
notify(
<div>
<span>Transfer of </span>
<KiltToken amount={amount} />
<KiltToken amount={transferAmount} />
<span> to </span>
<ContactPresentation address={receiverAddress} inline /> initiated.
</div>
Expand All @@ -85,7 +85,7 @@ class BalanceUtilities {
notifySuccess(
<div>
<span>Successfully transferred </span>
<KiltToken amount={amount} />
<KiltToken amount={transferAmount} />
<span> to </span>
<ContactPresentation address={receiverAddress} inline />.
</div>
Expand All @@ -98,13 +98,21 @@ class BalanceUtilities {
notify(
<div>
<span>Transfer of </span>
<KiltToken amount={amount} />
<KiltToken amount={transferAmount} />
<span> to </span>
<ContactPresentation address={receiverAddress} inline />
<span> initiated.</span>
</div>
)
})
.catch(error => {
errorService.log({
error,
message: '1010: Invalid Transaction',
origin: 'BalanceUtilities.makeTransfer()',
})
notifyFailure('1010: Invalid Transaction')
})
}

private static listener(
Expand All @@ -118,28 +126,17 @@ class BalanceUtilities {
notify(
<div>
Balance of <ContactPresentation address={account} /> {inDeCreased} by{' '}
<KiltToken amount={BalanceUtilities.asKiltCoin(change)} colored />.
<KiltToken amount={change} colored />.
</div>
)
}
PersistentStore.store.dispatch(
Balances.Store.updateBalance(
account,
BalanceUtilities.asKiltCoin(balance)
)
Balances.Store.updateBalance(account, balance)
)
}

public static asKiltCoin(balance: BN): number {
return balance.div(new BN(KILT_FEMTO_COIN)).toNumber()
}

public static asMicroKilt(balance: number): BN {
return new BN(balance).muln(KILT_MICRO_COIN)
}

public static asFemtoKilt(balance: number): BN {
return new BN(balance).mul(new BN(KILT_FEMTO_COIN))
return new BN(balance).mul(KILT_FEMTO_COIN)
}
}

Expand Down
17 changes: 9 additions & 8 deletions src/state/ducks/Balances.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import Immutable from 'immutable'
import { createSelector } from 'reselect'
import BN from 'bn.js'
import KiltAction from '../../types/Action'
import { IMyIdentity } from '../../types/Contact'
import { State as ReduxState } from '../PersistentStore'

interface IUpdateAction extends KiltAction {
payload: {
address: IMyIdentity['identity']['address']
balance: number
balance: BN
}
}

Expand All @@ -18,7 +19,7 @@ interface IRemoveAction extends KiltAction {
export type Action = IUpdateAction | IRemoveAction

type State = {
balances: Immutable.Map<IMyIdentity['identity']['address'], number>
balances: Immutable.Map<IMyIdentity['identity']['address'], BN>
}

export type ImmutableState = Immutable.Record<State>
Expand All @@ -44,7 +45,7 @@ class Store {

public static updateBalance(
address: IMyIdentity['identity']['address'],
balance: number
balance: BN
): IUpdateAction {
return {
payload: { address, balance },
Expand All @@ -63,7 +64,7 @@ class Store {

public static createState(obj?: State): ImmutableState {
return Immutable.Record({
balances: Immutable.Map<IMyIdentity['identity']['address'], number>(),
balances: Immutable.Map<IMyIdentity['identity']['address'], BN>(),
} as State)(obj)
}

Expand All @@ -73,20 +74,20 @@ class Store {
}
}

const getAllBalances = (state: ReduxState): Immutable.Map<string, number> => {
const getAllBalances = (state: ReduxState): Immutable.Map<string, BN> => {
return state.balances.get('balances')
}

const getBalances = createSelector(
[getAllBalances],
(balances: Immutable.Map<string, number>) => balances
(balances: Immutable.Map<string, BN>) => balances
)

const getStateBalance = (
state: ReduxState,
address: IMyIdentity['identity']['address']
): number | undefined => state.balances.get('balances').get(address)
): BN | undefined => state.balances.get('balances').get(address)

const getBalance = createSelector([getStateBalance], (entry: number) => entry)
const getBalance = createSelector([getStateBalance], (entry: BN) => entry)

export { Store, getBalance, getBalances }

0 comments on commit 18ae521

Please sign in to comment.