@polkadot/util#formatNumber TypeScript Examples
The following examples show how to use
@polkadot/util#formatNumber.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Nonce.tsx From subscan-multisig-react with Apache License 2.0 | 6 votes |
function Nonce({ children, className = '', label, params }: Props): React.ReactElement<Props> {
const { api } = useApi();
const allBalances = useCall<DeriveBalancesAll>(api.derive.balances?.all, [params]);
return (
<div className={className}>
{label || ''}
{formatNumber(allBalances?.accountNonce)}
{children}
</div>
);
}
Example #2
Source File: NominatedBy.tsx From crust-apps with Apache License 2.0 | 6 votes |
function NominatedBy ({ nominators, slashingSpans }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { active, chilled } = useMemo(
() => extractChilled(nominators, slashingSpans),
[nominators, slashingSpans]
);
return (
<td className='expand all'>
{active && (
<Expander
renderChildren={active[1]}
summary={t<string>('Nominations ({{count}})', { replace: { count: formatNumber(active[0]) } })}
/>
)}
{chilled && (
<Expander
renderChildren={chilled[1]}
summary={t<string>('Renomination required ({{count}})', { replace: { count: formatNumber(chilled[0]) } })}
/>
)}
</td>
);
}
Example #3
Source File: AddressInfo.tsx From subscan-multisig-react with Apache License 2.0 | 6 votes |
function renderExtended({ address, balancesAll, withExtended }: Props, t: TFunction): React.ReactNode {
const extendedDisplay = withExtended === true ? DEFAULT_EXTENDED : withExtended || undefined;
if (!extendedDisplay) {
return null;
}
return (
<div className="column">
{balancesAll && extendedDisplay.nonce && (
<>
<Label label={t<string>('transactions')} />
<div className="result">{formatNumber(balancesAll.accountNonce)}</div>
</>
)}
{extendedDisplay.crypto && (
<>
<Label label={t<string>('type')} />
<CryptoType accountId={address} className="result" />
</>
)}
</div>
);
}
Example #4
Source File: Events.tsx From crust-apps with Apache License 2.0 | 6 votes |
function Events ({ className = '', emptyLabel, eventClassName, events, label }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const header = useMemo(() => [
[label || t<string>('recent events'), 'start']
], [label, t]);
return (
<Table
className={className}
empty={emptyLabel || t<string>('No events available')}
header={header}
>
{events && events.map(({ blockHash, blockNumber, indexes, key, record }): React.ReactNode => (
<tr
className={eventClassName}
key={key}
>
<td className='overflow'>
<Event value={record} />
{blockNumber && (
<div className='event-link'>
{indexes.length !== 1 && <span>({formatNumber(indexes.length)}x) </span>}
<Link to={`/explorer/query/${blockHash || ''}`}>{formatNumber(blockNumber)}-{indexes[0]}</Link>
</div>
)}
</td>
</tr>
))}
</Table>
);
}
Example #5
Source File: BestFinalized.tsx From subscan-multisig-react with Apache License 2.0 | 6 votes |
function BestFinalized({ children, className = '', label }: Props): React.ReactElement<Props> {
const { api } = useApi();
const bestNumberFinalized = useCall<BlockNumber>(api.derive.chain.bestNumberFinalized);
return (
<div className={className}>
{label || ''}
{bestNumberFinalized ? <Digits value={formatNumber(bestNumberFinalized)} /> : '-'}
{children}
</div>
);
}
Example #6
Source File: DueBlocks.tsx From crust-apps with Apache License 2.0 | 6 votes |
function DueBlocks ({ dueBlocks, endBlock, label }: Props): React.ReactElement<Props> {
return (
<>
{dueBlocks.gtn(0) && (
<>
<BlockToTime value={dueBlocks}>
({label})
</BlockToTime>
#{formatNumber(endBlock)}
</>
)}
</>
);
}
Example #7
Source File: BestNumber.tsx From subscan-multisig-react with Apache License 2.0 | 6 votes |
function BestNumber({ children, className = '', isFinalized, label, withPound }: Props): React.ReactElement<Props> {
const { api, isApiReady } = useApi();
const bestNumber = useCall<BlockNumber>(
isApiReady && (isFinalized ? api.derive.chain.bestNumberFinalized : api.derive.chain.bestNumber)
);
return (
<div className={className}>
{label || ''}
{withPound && '#'}
{bestNumber ? <Digits value={formatNumber(bestNumber)} /> : '-'}
{children}
</div>
);
}
Example #8
Source File: Summary.tsx From crust-apps with Apache License 2.0 | 6 votes |
function Summary ({ className, numAssets }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
return (
<SummaryBox className={className}>
<CardSummary label={t<string>('assets')}>
{formatNumber(numAssets)}
</CardSummary>
</SummaryBox>
);
}
Example #9
Source File: Amount.tsx From subscan-multisig-react with Apache License 2.0 | 5 votes |
function Amount({
className = '',
defaultValue: { value },
isDisabled,
isError,
label,
onChange,
onEnter,
registry,
type,
withLabel,
}: Props): React.ReactElement<Props> {
const defaultValue = useMemo(
() =>
isDisabled
? value instanceof registry.createClass('AccountIndex')
? value.toString()
: formatNumber(value as number)
: bnToBn((value as number) || 0).toString(),
[isDisabled, registry, value]
);
const bitLength = useMemo((): number => {
try {
return registry.createType(type.type as 'u32').bitLength();
} catch (error) {
// eslint-disable-next-line no-magic-numbers
return 32;
}
}, [registry, type]);
const _onChange = useCallback(
(val?: BN) =>
onChange &&
onChange({
isValid: !isUndefined(val),
value: val,
}),
[onChange]
);
return (
<Bare className={className}>
{isDisabled ? (
<Input
className="full"
defaultValue={defaultValue}
isDisabled
label={label}
withEllipsis
withLabel={withLabel}
/>
) : (
<InputNumber
bitLength={bitLength}
className="full"
defaultValue={defaultValue}
isError={isError}
isZeroable
label={label}
onChange={_onChange}
onEnter={onEnter}
withLabel={withLabel}
/>
)}
</Bare>
);
}
Example #10
Source File: Messages.tsx From crust-apps with Apache License 2.0 | 5 votes |
function Messages ({ className = '', contract, contractAbi: { constructors, messages, project: { source } }, isLabelled, isWatching, onSelect, onSelectConstructor, withConstructors, withMessages, withWasm }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { api } = useApi();
const optInfo = useCall<Option<ContractInfo>>(contract && api.query.contracts.contractInfoOf, [contract?.address]);
const [isUpdating, setIsUpdating] = useState(false);
const [lastResults, setLastResults] = useState<(ContractCallOutcome | undefined)[]>([]);
const _onExpander = useCallback(
(isOpen: boolean): void => {
isWatching && setIsUpdating(isOpen);
},
[isWatching]
);
useEffect((): void => {
isUpdating && optInfo && contract && Promise
.all(messages.map((m) =>
m.isMutating || m.args.length !== 0
? Promise.resolve(undefined)
: contract.read(m, 0, -1).send(READ_ADDR).catch(() => undefined)
))
.then(setLastResults)
.catch(console.error);
}, [contract, isUpdating, isWatching, messages, optInfo]);
const _setMessageResult = useCallback(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
(messageIndex: number, result?: ContractCallOutcome): void => {
// ignore... for now
// setLastResults((all) => all.map((r, index) => index === messageIndex ? result : r));
},
[]
);
const _onSelect = useCallback(
(index: number) => onSelect && onSelect(index, _setMessageResult),
[_setMessageResult, onSelect]
);
return (
<div className={`ui--Messages ${className}${isLabelled ? ' isLabelled' : ''}`}>
{withConstructors && (
<Expander summary={t<string>('Constructors ({{count}})', { replace: { count: constructors.length } })}>
{sortMessages(constructors).map(([message, index]) => (
<Message
index={index}
key={index}
message={message}
onSelect={onSelectConstructor}
/>
))}
</Expander>
)}
{withMessages && (
<Expander
onClick={_onExpander}
summary={t<string>('Messages ({{count}})', { replace: { count: messages.length } })}
>
{sortMessages(messages).map(([message, index]) => (
<Message
index={index}
key={index}
lastResult={lastResults[index]}
message={message}
onSelect={_onSelect}
/>
))}
</Expander>
)}
{withWasm && source.wasm.length !== 0 && (
<div>{t<string>('{{size}} WASM bytes', { replace: { size: formatNumber(source.wasm.length) } })}</div>
)}
</div>
);
}
Example #11
Source File: ProposedAction.tsx From subscan-multisig-react with Apache License 2.0 | 5 votes |
function ProposedAction({
className = '',
expandNested,
idNumber,
proposal,
withLinks,
}: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const stringId = isString(idNumber) ? idNumber : formatNumber(idNumber);
if (!proposal) {
return (
<h3>
#{stringId} {t<string>('No execution details available for this proposal')}
</h3>
);
}
const { meta, method, section } = proposal.registry.findMetaCall(proposal.callIndex);
const header = `#${stringId}: ${section}.${method}`;
return (
<div className={`ui--ProposedAction ${className}`}>
<h3>{header}</h3>
<Expander summaryMeta={meta}>
{isTreasuryProposalVote(proposal) && expandNested ? (
<TreasuryProposal
asInset={withLinks}
insetProps={{
withBottomMargin: true,
withTopMargin: true,
...(withLinks ? { href: '/treasury' } : {}),
}}
proposalId={proposal.args[0].toString()}
/>
) : (
<Call value={proposal} />
)}
</Expander>
</div>
);
}
Example #12
Source File: Summary.tsx From crust-apps with Apache License 2.0 | 5 votes |
function Summary ({ bestNumber, className = '', electionsInfo }: Props): React.ReactElement<Props> | null {
const { t } = useTranslation();
if (!electionsInfo) {
return null;
}
const { candidateCount, desiredRunnersUp, desiredSeats, members, runnersUp, termDuration, voteCount } = electionsInfo;
return (
<SummaryBox className={className}>
<section>
<CardSummary label={t<string>('seats')}>
{formatNumber(members.length)} / {formatNumber(desiredSeats)}
</CardSummary>
<CardSummary label={t<string>('runners up')}>
{formatNumber(runnersUp.length)} / {formatNumber(desiredRunnersUp)}
</CardSummary>
<CardSummary label={t<string>('candidates')}>
{formatNumber(candidateCount)}
</CardSummary>
</section>
{voteCount && (
<section>
<CardSummary label={t<string>('voting round')}>
#{formatNumber(voteCount)}
</CardSummary>
</section>
)}
{bestNumber && termDuration?.gtn(0) && (
<section>
<CardSummary
label={t<string>('term progress')}
progress={{
total: termDuration,
value: bestNumber.mod(termDuration),
withTime: true
}}
/>
</section>
)}
</SummaryBox>
);
}
Example #13
Source File: InputFile.tsx From subscan-multisig-react with Apache License 2.0 | 5 votes |
function InputFile({
accept,
className = '',
clearContent,
help,
isDisabled,
isError = false,
isFull,
label,
onChange,
placeholder,
withEllipsis,
withLabel,
}: InputFileProps): React.ReactElement<InputFileProps> {
const { t } = useTranslation();
const dropRef = createRef<DropzoneRef>();
const [file, setFile] = useState<FileState | undefined>();
const _onDrop = useCallback(
(files: File[]): void => {
files.forEach((file): void => {
const reader = new FileReader();
reader.onabort = NOOP;
reader.onerror = NOOP;
reader.onload = ({ target }: ProgressEvent<FileReader>): void => {
if (target && target.result) {
const name = file.name;
const data = convertResult(target.result as ArrayBuffer);
// eslint-disable-next-line
onChange && onChange(data, name);
// eslint-disable-next-line
dropRef &&
setFile({
name,
size: data.length,
});
}
};
reader.readAsArrayBuffer(file);
});
},
[dropRef, onChange]
);
const dropZone = (
<Dropzone accept={accept} disabled={isDisabled} multiple={false} onDrop={_onDrop} ref={dropRef}>
{({ getInputProps, getRootProps }: Record<string, any>): JSX.Element => (
<div {...getRootProps({ className: `ui--InputFile${isError ? ' error' : ''} ${className}` })}>
<input {...getInputProps()} />
<em className="label">
{!file || clearContent
? placeholder || t<string>('click to select or drag and drop the file here')
: placeholder ||
t<string>('{{name}} ({{size}} bytes)', {
replace: {
name: file.name,
size: formatNumber(file.size),
},
})}
</em>
</div>
)}
</Dropzone>
);
return label ? (
<Labelled help={help} isFull={isFull} label={label} withEllipsis={withEllipsis} withLabel={withLabel}>
{dropZone}
</Labelled>
) : (
dropZone
);
}
Example #14
Source File: Summary.tsx From crust-apps with Apache License 2.0 | 5 votes |
function Summary({ info, isLoading }: Props): React.ReactElement<Props> | null {
const { t } = useTranslation();
const daily = info ? 1000 / info.totalEffectiveStakes : 0;
return (!isLoading) ? (
<SummaryBox>
<section>
<CardSummary label={t<string>('providers / guarantors')}>
{info
? <>{formatNumber(info.totalProviders)} / {formatNumber(info.totalGuarantors)}</>
: <Spinner noLabel />
}
</CardSummary>
</section>
<section className='media--800'>
<CardSummary label={t<string>('Total Rewards')}>
{<>{`54,000 CRU`}</>}
</CardSummary>
</section>
<section>
<CardSummary
className='media--1000'
label={t<string>('Issued Rewards')}
>
{ info ? <> {formatNumber(info.calculatedRewards)} CRU </>: (<Spinner noLabel />)}
</CardSummary>
</section>
<section>
<CardSummary
className='media--1100'
label={t<string>('Daily Rewards')}
>
{<>{`0 CRU`}</>}
</CardSummary>
</section>
<section>
<CardSummary
className='media--1100'
label={t<string>('Data Power')}
>
{ info ? <FormatDataPower value={info.dataPower} /> : (<Spinner noLabel />) }
</CardSummary>
</section>
<section>
<CardSummary
className='media--1100'
label={t<string>('Effective stake')}
>
{ info ? <FormatCsmBalance value={UNIT.muln(info.totalEffectiveStakes)} />: (<Spinner noLabel />)}
</CardSummary>
</section>
<section>
<CardSummary
className='media--1100'
label={t<string>('Daily Rewards per 1K CSM')}
>
{ info ? <FormatBalance value={UNIT.muln((daily > 1 ? 1 :daily) * 200)} /> : (<Spinner noLabel />)}
</CardSummary>
</section>
</SummaryBox>
) : <Spinner noLabel />;
}
Example #15
Source File: DemocracyLocks.tsx From subscan-multisig-react with Apache License 2.0 | 5 votes |
// group by header & details
// - all unlockable together
// - all ongoing together
// - unlocks are displayed individually
function groupLocks(t: TFunction, bestNumber: BN, locks: Partial<DeriveDemocracyLock>[] = []): State {
return {
maxBalance: bnMax(...locks.map(({ balance }) => balance).filter((b): b is Balance => !!b)),
sorted: locks
.map((info): [Partial<DeriveDemocracyLock>, BN] => [
info,
info.unlockAt && info.unlockAt.gt(bestNumber) ? info.unlockAt.sub(bestNumber) : BN_ZERO,
])
.sort((a, b) => (a[0].referendumId || BN_ZERO).cmp(b[0].referendumId || BN_ZERO))
.sort((a, b) => a[1].cmp(b[1]))
.sort((a, b) => (a[0].isFinished === b[0].isFinished ? 0 : a[0].isFinished ? -1 : 1))
.reduce(
(sorted: Entry[], [{ balance, isDelegated, isFinished = false, referendumId, vote }, blocks]): Entry[] => {
const isCountdown = blocks.gt(BN_ZERO);
const header =
referendumId && vote ? (
<div>
#{referendumId.toString()} {formatBalance(balance, { forceUnit: '-' })} {vote.conviction.toString()}
{isDelegated && '/d'}
</div>
) : (
<div>{t('Prior locked voting')}</div>
);
const prev = sorted.length ? sorted[sorted.length - 1] : null;
if (!prev || isCountdown || isFinished !== prev.isFinished) {
sorted.push({
details: (
<div className="faded">
{isCountdown ? (
<BlockToTime
label={`${t<string>('{{blocks}} blocks', { replace: { blocks: formatNumber(blocks) } })}, `}
value={blocks}
/>
) : isFinished ? (
t<string>('lock expired')
) : (
t<string>('ongoing referendum')
)}
</div>
),
headers: [header],
isCountdown,
isFinished,
});
} else {
prev.headers.push(header);
}
return sorted;
},
[]
),
};
}
Example #16
Source File: ReferendumVotes.tsx From crust-apps with Apache License 2.0 | 5 votes |
function ReferendumVotes ({ change, className, count, isAye, isWinning, total, votes }: Props): React.ReactElement<Props> | null {
const { t } = useTranslation();
const sorted = useMemo(
() => votes.sort((a, b) => {
const ta = a.balance.muln(LOCKS[a.vote.conviction.toNumber()]).div(BN_TEN);
const tb = b.balance.muln(LOCKS[b.vote.conviction.toNumber()]).div(BN_TEN);
return tb.cmp(ta);
}),
[votes]
);
return (
<Expander
className={className}
help={change.gtn(0) && (
<>
<FormatBalance value={change} />
<p>{isWinning
? t<string>('The amount this total can be reduced by to change the referendum outcome. This assumes changes to the convictions of the existing votes, with no additional turnout.')
: t<string>('The amount this total should be increased by to change the referendum outcome. This assumes additional turnout with new votes at 1x conviction.')
}</p>
</>
)}
helpIcon={isWinning ? 'arrow-circle-down' : 'arrow-circle-up'}
summary={
<>
{isAye
? t<string>('Aye {{count}}', { replace: { count: count ? ` (${formatNumber(count)})` : '' } })
: t<string>('Nay {{count}}', { replace: { count: count ? ` (${formatNumber(count)})` : '' } })
}
<div><FormatBalance value={total} /></div>
</>
}
>
{sorted.map((vote) =>
<ReferendumVote
key={vote.accountId.toString()}
vote={vote}
/>
)}
</Expander>
);
}
Example #17
Source File: CardSummary.tsx From subscan-multisig-react with Apache License 2.0 | 5 votes |
function CardSummary({ children, className = '', help, label, progress }: Props): React.ReactElement<Props> | null {
const value = progress && progress.value;
const total = progress && progress.total;
const left =
progress && !isUndefined(value) && !isUndefined(total) && value.gten(0) && total.gtn(0)
? value.gt(total)
? `>${progress.isPercent ? '100' : formatNumber(total)}`
: progress.isPercent
? value.mul(BN_HUNDRED).div(total).toString()
: formatNumber(value)
: undefined;
if (progress && isUndefined(left)) {
return null;
}
const isTimed = progress && progress.withTime && !isUndefined(progress.total);
return (
<article className={className}>
<Labelled help={help} isSmall label={label}>
{children}
{progress && !progress.hideValue && (
<>
{isTimed && !children && <BlockToTime value={progress.total} />}
<div className={isTimed ? 'isSecondary' : 'isPrimary'}>
{!left || isUndefined(progress.total) ? (
'-'
) : !isTimed || progress.isPercent || !progress.value ? (
`${left}${progress.isPercent ? '' : '/'}${progress.isPercent ? '%' : formatNumber(progress.total)}`
) : (
<BlockToTime className="timer" value={progress.total.sub(progress.value)} />
)}
</div>
</>
)}
</Labelled>
{progress && !progress.hideGraph && <Progress {...progress} />}
</article>
);
}
Example #18
Source File: Summary.tsx From crust-apps with Apache License 2.0 | 5 votes |
function Summary ({ info: { extrinsics, health, peers } = EMPTY_INFO, nextRefresh }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const [peerBest, setPeerBest] = useState(BN_ZERO);
useEffect((): void => {
if (peers) {
const bestPeer = peers.sort((a, b): number => b.bestNumber.cmp(a.bestNumber))[0];
setPeerBest(
bestPeer
? bestPeer.bestNumber
: BN_ZERO
);
}
}, [peers]);
return (
<SummaryBox>
<section>
<CardSummary label={t<string>('refresh in')}>
<Elapsed value={nextRefresh} />
</CardSummary>
{health && (
<>
<CardSummary
className='media--800'
label={t<string>('total peers')}
>
{formatNumber(health.peers)}
</CardSummary>
<CardSummary
className='media--800'
label={t<string>('syncing')}
>
{health.isSyncing.valueOf()
? t<string>('yes')
: t<string>('no')
}
</CardSummary>
</>
)}
</section>
{extrinsics && (extrinsics.length > 0) && (
<section className='media--1200'>
<CardSummary label={t<string>('queued tx')}>
{extrinsics.length}
</CardSummary>
</section>
)}
<section>
{peerBest?.gtn(0) && (
<CardSummary label={t<string>('peer best')}>
{formatNumber(peerBest)}
</CardSummary>
)}
<CardSummary label={t<string>('our best')}>
<BestNumber />
</CardSummary>
</section>
</SummaryBox>
);
}
Example #19
Source File: DryRun.tsx From contracts-ui with GNU General Public License v3.0 | 5 votes |
export function DryRun() {
const { api } = useApi();
const { dryRunResult } = useInstantiate();
const dryRunError =
dryRunResult?.result.isErr && dryRunResult?.result.asErr.isModule
? api.registry.findMetaError(dryRunResult?.result.asErr.asModule)
: null;
return (
<SidePanel className="instantiate-outcome" header="Predicted Outcome">
<div className="body">
<div className="row">
<div>Gas Required:</div>
<div>{dryRunResult?.gasRequired && <>{formatNumber(dryRunResult.gasRequired)}</>}</div>
</div>
<div className="row">
<div>Gas Consumed:</div>
<div>{dryRunResult?.gasConsumed && <>{formatNumber(dryRunResult.gasConsumed)}</>}</div>
</div>
<div className="row">
<div>Storage Deposit:</div>
<div>
{dryRunResult?.storageDeposit &&
(() => {
if (dryRunResult.storageDeposit.isCharge) {
if (dryRunResult.storageDeposit.asCharge.eqn(0)) {
return 'None';
}
return formatBalance(dryRunResult.storageDeposit.asCharge, { decimals: 12 });
}
return 'None';
})()}
</div>
</div>
<div className="row h-8">
<div>Contract Address:</div>
<div>
{dryRunResult?.result.isOk ? (
<Account size={26} value={dryRunResult?.result.asOk.accountId.toString()} />
) : (
'None'
)}
</div>
</div>
<div>
{dryRunResult?.result.isOk && (
<div className="validation success font-bold">
<CheckCircleIcon className="mr-3" />
The instantiation will be successful.
</div>
)}
{dryRunError && dryRunResult && (
<>
<div className="validation error text-mono font-bold items-start">
<ExclamationCircleIcon className="mr-3" style={{ marginTop: 1 }} />
<div>
<p>{dryRunError.name}</p>
<p>{dryRunError.docs}</p>
</div>
</div>
{dryRunResult.debugMessage.length > 0 && (
<div className="validation error block text-mono break-words pl-4 mt-1">
{dryRunResult.debugMessage.toString()}
</div>
)}
</>
)}
</div>
</div>
</SidePanel>
);
}
Example #20
Source File: Bid.tsx From crust-apps with Apache License 2.0 | 5 votes |
function Bid ({ auctionInfo, className, id, ownedIds }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { api } = useApi();
const { hasAccounts } = useAccounts();
const bestNumber = useBestNumber();
const [{ accountId, paraId }, setOwnerInfo] = useState<OwnerInfo>({ accountId: null, paraId: 0 });
const [amount, setAmount] = useState<BN | undefined>(BN_ZERO);
const [range, setRange] = useState(0);
const [isOpen, toggleOpen] = useToggle();
const rangeOpts = useMemo(
(): Option[] => {
const [leasePeriod] = auctionInfo || [null, null];
return leasePeriod
? RANGES.map(([first, last], value): Option => ({
text: `${formatNumber(leasePeriod.addn(first))} - ${formatNumber(leasePeriod.addn(last))}`,
value
}))
: [];
},
[auctionInfo]
);
const [leasePeriod, endBlock] = auctionInfo || [null, null];
return (
<>
<Button
icon='plus'
isDisabled={!ownedIds.length || !hasAccounts || !id || !leasePeriod || !endBlock || bestNumber?.gte(endBlock.add(api.consts.auctions.endingPeriod as BlockNumber))}
label={t<string>('Bid')}
onClick={toggleOpen}
/>
{isOpen && (
<Modal
className={className}
header={t<string>('Place bid')}
size='large'
>
<Modal.Content>
<InputOwner
onChange={setOwnerInfo}
ownedIds={ownedIds}
/>
<Modal.Columns hint={t<string>('The amount to to bid for this parachain slot')}>
<InputBalance
isZeroable={false}
label={t<string>('bid amount')}
onChange={setAmount}
/>
</Modal.Columns>
<Modal.Columns hint={t<string>('The first and last slots for this bid. The last slot should be after the first and a maximum of 3 slots more than the first')}>
<Dropdown
label={t<string>('bid slot range (start slot, end slot)')}
onChange={setRange}
options={rangeOpts}
value={range}
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={toggleOpen}>
<TxButton
accountId={accountId}
icon='plus'
isDisabled={!paraId || !amount?.gt(BN_ZERO) || !leasePeriod}
label={t<string>('Bid')}
onStart={toggleOpen}
params={[paraId, id, leasePeriod?.addn(RANGES[range][0]), leasePeriod?.addn(RANGES[range][1]), amount]}
tx={api.tx.auctions.bid}
/>
</Modal.Actions>
</Modal>
)}
</>
);
}
Example #21
Source File: Statistics.tsx From contracts-ui with GNU General Public License v3.0 | 5 votes |
export function Statistics(): React.ReactElement | null {
const { api } = useApi();
const [blockNumber, setBlockNumber] = useState(0);
const { data: statistics } = useStatistics();
useEffect(() => {
async function listenToBlocks() {
return api?.rpc.chain.subscribeNewHeads(header => {
setBlockNumber(header.number.toNumber());
});
}
let cleanUp: VoidFunction;
listenToBlocks()
.then(unsub => (cleanUp = unsub))
.catch(console.error);
return () => cleanUp();
}, [api]);
const entries = useMemo((): Record<string, React.ReactNode> => {
return {
'Highest Block': `#${formatNumber(blockNumber)}`,
Nodes: 1,
'Code Bundles Uploaded': statistics?.codeBundlesCount || 0,
'Contracts Instantiated': statistics?.contractsCount || 0,
};
}, [blockNumber, statistics]);
return (
<>
<div className="grid grid-cols-4 xl:grid-cols-2 w-full mb-8 pb-8 border-b border-gray-200 dark:border-gray-800">
<div className="text-sm mb-4 col-span-4 xl:col-span-2 w-full">Chain Metrics</div>
{Object.entries(entries).map(([label, value], i) => {
return (
<div key={`entry-${i}`} className="mb-4">
<div className="text-xs mb-1">{label}</div>
<div className="dark:text-gray-400">{value}</div>
</div>
);
})}
</div>
</>
);
}
Example #22
Source File: balances.ts From subsocial-js with GNU General Public License v3.0 | 5 votes |
formatBalanceWithoutDecimals = (balance: BigNumber, symbol: string) =>
`${formatNumber(new BN(balance.toString()))} ${symbol}`
Example #23
Source File: AddressInfo.tsx From subscan-multisig-react with Apache License 2.0 | 4 votes |
function createBalanceItems(
formatIndex: number,
lookup: Record<string, string>,
t: TFunction,
{
address,
balanceDisplay,
balancesAll,
bestNumber,
democracyLocks,
isAllLocked,
otherBonded,
ownBonded,
stakingInfo,
votingOf,
withBalanceToggle,
}: {
address: string;
balanceDisplay: BalanceActiveType;
balancesAll?: DeriveBalancesAll | DeriveBalancesAccountData;
bestNumber: BlockNumber;
democracyLocks?: DeriveDemocracyLock[];
isAllLocked: boolean;
otherBonded: BN[];
ownBonded: BN;
stakingInfo?: DeriveStakingAccount;
votingOf?: Voting;
withBalanceToggle: boolean;
}
): React.ReactNode {
const allItems: React.ReactNode[] = [];
const deriveBalances = balancesAll as DeriveBalancesAll;
// eslint-disable-next-line
!withBalanceToggle &&
balancesAll &&
balanceDisplay.total &&
allItems.push(
<React.Fragment key={0}>
<Label label={t<string>('total')} />
<FormatBalance
className="result"
formatIndex={formatIndex}
value={balancesAll.freeBalance.add(balancesAll.reservedBalance)}
/>
</React.Fragment>
);
// eslint-disable-next-line
balancesAll &&
balanceDisplay.available &&
(balancesAll as DeriveBalancesAll).availableBalance &&
allItems.push(
<React.Fragment key={1}>
<Label label={t<string>('transferrable')} />
<FormatBalance
className="result"
formatIndex={formatIndex}
value={(balancesAll as DeriveBalancesAll).availableBalance}
/>
</React.Fragment>
);
if (balanceDisplay.vested && deriveBalances?.isVesting) {
const allVesting = deriveBalances.vesting.filter(({ endBlock }) => bestNumber.lt(endBlock));
allItems.push(
<React.Fragment key={2}>
<Label label={t<string>('vested')} />
<FormatBalance
className='result'
formatIndex={formatIndex}
labelPost={
<Icon
icon='info-circle'
tooltip={`${address}-vested-trigger`}
/>
}
value={deriveBalances.vestedBalance}
>
<Tooltip
text={
<>
<div>
{formatBalance(deriveBalances.vestedClaimable, { forceUnit: '-' })}
<div className='faded'>{t('available to be unlocked')}</div>
</div>
{allVesting.map(({ endBlock, locked, perBlock, vested }, index) => (
<div
className='inner'
key={`item:${index}`}
>
<div>
{formatBalance(vested, { forceUnit: '-' })}
<div className='faded'>{t('of {{locked}} vested', { replace: { locked: formatBalance(locked, { forceUnit: '-' }) } })}</div>
</div>
<div>
<BlockToTime value={endBlock.sub(bestNumber)} />
<div className='faded'>{t('until block')} {formatNumber(endBlock)}</div>
</div>
<div>
{formatBalance(perBlock)}
<div className='faded'>{t('per block')}</div>
</div>
</div>
))}
</>
}
trigger={`${address}-vested-trigger`}
/>
</FormatBalance>
</React.Fragment>
);
}
balanceDisplay.locked &&
balancesAll &&
(isAllLocked || (balancesAll as DeriveBalancesAll).lockedBalance?.gtn(0)) &&
allItems.push(
<React.Fragment key={3}>
<Label label={t<string>('locked')} />
<FormatBalance
className="result"
formatIndex={formatIndex}
label={<Icon icon="info-circle" tooltip={`${address}-locks-trigger`} />}
value={isAllLocked ? 'all' : (balancesAll as DeriveBalancesAll).lockedBalance}
>
<Tooltip
text={(balancesAll as DeriveBalancesAll).lockedBreakdown.map(
({ amount, id, reasons }, index): React.ReactNode => (
<div key={index}>
{amount?.isMax() ? t<string>('everything') : formatBalance(amount, { forceUnit: '-' })}
{id && <div className="faded">{lookupLock(lookup, id)}</div>}
<div className="faded">{reasons.toString()}</div>
</div>
)
)}
trigger={`${address}-locks-trigger`}
/>
</FormatBalance>
</React.Fragment>
);
balanceDisplay.reserved &&
balancesAll?.reservedBalance?.gtn(0) &&
allItems.push(
<React.Fragment key={4}>
<Label label={t<string>('reserved')} />
<FormatBalance className="result" formatIndex={formatIndex} value={balancesAll.reservedBalance} />
</React.Fragment>
);
balanceDisplay.bonded &&
(ownBonded.gtn(0) || otherBonded.length !== 0) &&
allItems.push(
<React.Fragment key={5}>
<Label label={t<string>('bonded')} />
<FormatBalance className="result" formatIndex={formatIndex} value={ownBonded}>
{otherBonded.length !== 0 && (
<>
(+
{otherBonded.map(
(bonded, index): React.ReactNode => (
<FormatBalance formatIndex={formatIndex} key={index} value={bonded} />
)
)}
)
</>
)}
</FormatBalance>
</React.Fragment>
);
balanceDisplay.redeemable &&
stakingInfo?.redeemable?.gtn(0) &&
allItems.push(
<React.Fragment key={6}>
<Label label={t<string>('redeemable')} />
<StakingRedeemable className="result" stakingInfo={stakingInfo} />
</React.Fragment>
);
if (balanceDisplay.unlocking) {
stakingInfo?.unlocking &&
allItems.push(
<React.Fragment key={7}>
<Label label={t<string>('unbonding')} />
<div className="result">
<StakingUnbonding stakingInfo={stakingInfo} />
</div>
</React.Fragment>
);
if (democracyLocks && democracyLocks.length !== 0) {
allItems.push(
<React.Fragment key={8}>
<Label label={t<string>('democracy')} />
<div className="result">
<DemocracyLocks value={democracyLocks} />
</div>
</React.Fragment>
);
} else if (votingOf && votingOf.isDirect) {
const {
prior: [unlockAt, balance],
} = votingOf.asDirect;
balance.gt(BN_ZERO) &&
unlockAt.gt(BN_ZERO) &&
allItems.push(
<React.Fragment key={8}>
<Label label={t<string>('democracy')} />
<div className="result">
<DemocracyLocks value={[{ balance, isFinished: bestNumber.gt(unlockAt), unlockAt }]} />
</div>
</React.Fragment>
);
}
}
if (withBalanceToggle) {
return (
<React.Fragment key={formatIndex}>
<Expander
summary={
<FormatBalance
formatIndex={formatIndex}
value={balancesAll && balancesAll.freeBalance.add(balancesAll.reservedBalance)}
/>
}
>
{allItems.length !== 0 && <div className="body column">{allItems}</div>}
</Expander>
</React.Fragment>
);
}
return <React.Fragment key={formatIndex}>{allItems}</React.Fragment>;
}
Example #24
Source File: Step3.tsx From contracts-ui with GNU General Public License v3.0 | 4 votes |
export function Step3() {
const apiState = useApi();
const { codeHash: codeHashUrlParam } = useParams<{ codeHash: string }>();
const { data, currentStep, onUnFinalize, tx, onError, onInstantiate } = useInstantiate();
const { accountId, value, metadata, weight, name, constructorIndex } = data;
const isConstructorPayable = metadata?.constructors[constructorIndex].isPayable;
const displayHash = codeHashUrlParam || metadata?.info.source.wasmHash.toHex();
const [onSubmit, onCancel, isValid, isProcessing] = useQueueTx(
tx,
data.accountId,
onInstantiate,
onError,
isResultValid
);
if (currentStep !== 3) return null;
return (
<>
<div className="review">
<div className="field full">
<p className="key">Account</p>
<div className="value">
<Account value={accountId} />
</div>
</div>
<div className="field full">
<p className="key">Name</p>
<p className="value">{name}</p>
</div>
{isConstructorPayable && value && (
<div className="field">
<p className="key">Value</p>
<p className="value">
{formatBalance(value, { decimals: apiState.tokenDecimals, forceUnit: '-' })}
</p>
</div>
)}
<div className="field">
<p className="key">Weight</p>
<p className="value">{formatNumber(weight)}</p>
</div>
{displayHash && (
<div className="field">
<p className="key">Code Hash</p>
<p className="value">{truncate(displayHash)}</p>
</div>
)}
{tx?.args[3] && (
<div className="field">
<p className="key">Data</p>
<p className="value">{truncate(tx?.args[3].toHex())}</p>
</div>
)}
</div>
<Buttons>
<Button
variant="primary"
isDisabled={!isValid}
isLoading={isProcessing}
onClick={onSubmit}
data-cy="submit-btn"
>
Upload and Instantiate
</Button>
<Button
onClick={(): void => {
onCancel();
onUnFinalize && onUnFinalize();
}}
isDisabled={isProcessing}
>
Go Back
</Button>
</Buttons>
</>
);
}
Example #25
Source File: BlockAuthors.tsx From subscan-multisig-react with Apache License 2.0 | 4 votes |
function BlockAuthorsBase({ children }: Props): React.ReactElement<Props> {
const { api, isApiReady } = useApi();
const queryPoints = useCall<EraRewardPoints>(isApiReady && api.derive.staking?.currentPoints);
const [state, setState] = useState<Authors>({ byAuthor, eraPoints, lastBlockAuthors: [], lastHeaders: [] });
const [validators, setValidators] = useState<string[]>([]);
useEffect((): void => {
// No unsub, global context - destroyed on app close
api?.isReady
.then((): void => {
let lastHeaders: HeaderExtendedWithMapping[] = [];
let lastBlockAuthors: string[] = [];
let lastBlockNumber = '';
const isAuthorMapping = isFunction(api.query.authorMapping?.mapping);
// subscribe to all validators
api.query.session &&
api.query.session
.validators((validatorIds: any): void => {
setValidators(validatorIds.map((validatorId: any) => validatorId.toString()));
})
.catch(console.error);
// subscribe to new headers
api.derive.chain
.subscribeNewHeads(async (lastHeader: HeaderExtendedWithMapping): Promise<void> => {
if (lastHeader?.number) {
const blockNumber = lastHeader.number.unwrap();
let thisBlockAuthor = '';
if (lastHeader.author) {
thisBlockAuthor = lastHeader.author.toString();
} else if (
isAuthorMapping &&
lastHeader.digest.logs &&
lastHeader.digest.logs[0] &&
lastHeader.digest.logs[0].isConsensus &&
lastHeader.digest.logs[0].asConsensus[1]
) {
// Some blockchains such as Moonbeam need to fetch the author accountId from a mapping
thisBlockAuthor = (
await api.query.authorMapping.mapping(lastHeader.digest.logs[0].asConsensus[1])
).toString();
lastHeader.authorFromMapping = thisBlockAuthor;
}
const thisBlockNumber = formatNumber(blockNumber);
if (thisBlockAuthor) {
byAuthor[thisBlockAuthor] = thisBlockNumber;
if (thisBlockNumber !== lastBlockNumber) {
lastBlockNumber = thisBlockNumber;
lastBlockAuthors = [thisBlockAuthor];
} else {
lastBlockAuthors.push(thisBlockAuthor);
}
}
lastHeaders = lastHeaders
.filter((old, index) => index < MAX_HEADERS && old.number.unwrap().lt(blockNumber))
.reduce(
(next, header): HeaderExtendedWithMapping[] => {
next.push(header);
return next;
},
[lastHeader]
)
.sort((a, b) => b.number.unwrap().cmp(a.number.unwrap()));
setState({
byAuthor,
eraPoints,
lastBlockAuthors: lastBlockAuthors.slice(),
lastBlockNumber,
lastHeader,
lastHeaders,
});
}
})
.catch(console.error);
})
.catch(console.error);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect((): void => {
if (queryPoints) {
const entries = [...queryPoints.individual.entries()].map(([accountId, points]) => [
accountId.toString(),
formatNumber(points),
]);
const current = Object.keys(eraPoints);
// we have an update, clear all previous
if (current.length !== entries.length) {
current.forEach((accountId): void => {
delete eraPoints[accountId];
});
}
entries.forEach(([accountId, points]): void => {
eraPoints[accountId] = points;
});
}
}, [queryPoints]);
return (
<ValidatorsContext.Provider value={validators}>
<BlockAuthorsContext.Provider value={state}>{children}</BlockAuthorsContext.Provider>
</ValidatorsContext.Provider>
);
}
Example #26
Source File: index.tsx From crust-apps with Apache License 2.0 | 4 votes |
function PollApp ({ basePath, className }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { api } = useApi();
const bestNumber = useBestNumber();
const [totalIssuance, totals] = useCallMulti<MultiResult>([
api.query.balances.totalIssuance,
api.query.poll.totals
], optMulti);
const [accountId, setAccountId] = useState<string | null>(null);
const [turnout, setTurnout] = useState<Turnout | null>(null);
const [opt10m, setOpt10m] = useState(false);
const [opt100m, setOpt100m] = useState(false);
const [opt1b, setOpt1b] = useState(false);
const [opt10b, setOpt10b] = useState(false);
const [progress, setProgress] = useState<BN[] | undefined>();
const itemsRef = useRef([{
isRoot: true,
name: 'poll',
text: t<string>('Denomination poll')
}]);
useEffect((): void => {
if (totalIssuance && totals) {
const max = bnMax(BN_ONE, ...totals);
setProgress(totals.map((total) => total.mul(BN_MILLION).div(max)));
api.query.poll.voteOf
.entries<ITuple<[Approvals, Balance]>>()
.then((entries): void => {
const voted = entries.reduce((voted: BN, [, [, balance]]) => voted.iadd(balance), new BN(0));
const percentage = voted.muln(10_000).div(totalIssuance).toNumber() / 100;
setTurnout({ percentage, voted });
})
.catch(console.log);
}
}, [api, totalIssuance, totals]);
if (!totals || !progress || !bestNumber) {
return (
<main className={className}>
<div className='pollContainer'>
<Spinner label={t<string>('Retrieving totals...')} />
</div>
</main>
);
}
const blocksLeft = (api.consts.poll.end as BlockNumber).sub(bestNumber);
const canVote = blocksLeft.gt(BN_ZERO);
const options: [string, string, boolean, (value: boolean) => void][] = [
[t('No change'), t('No change from the original 2017 sale definitions; will mean a total of 10 million DOT from genesis.'), opt10m, setOpt10m],
[t('Split of 10x'), t('Split of 10x from the original sale; will mean a total of 100 million DOT from genesis. Apparent DOT price would be 10x lower and apparent account balances 10x higher.'), opt100m, setOpt100m],
[t('Split of 100x'), t('Split of 100x from the original sale; will mean a total of 1 billion DOT from genesis. Apparent DOT price would be 100x lower and apparent account balances 100x higher.'), opt1b, setOpt1b],
[t('Split of 1000x'), t('Split of 1000x from the original sale; will mean a total of 10 billion DOT from genesis. Apparent DOT price would be 1000x lower and apparent account balances 1000x higher.'), opt10b, setOpt10b]
];
const hasValue = opt10m || opt100m || opt1b || opt10b;
/* eslint-disable react/jsx-max-props-per-line */
return (
<main className={className}>
<Tabs
basePath={basePath}
items={itemsRef.current}
/>
<div className='pollContainer'>
<div className='pollHeader'>
<h1>{t('denomination vote')}</h1>
<div className='pollBlocksRight'>
{turnout && (
<div>
<div>{t('{{balance}} voted', { replace: { balance: formatBalance(turnout.voted) } })}</div>
<div>{t('{{percentage}}% turnout', { replace: { percentage: turnout.percentage.toFixed(2) } })}</div>
</div>
)}
<div>
{canVote
? <BlockToTime value={blocksLeft} />
: t<string>('Completed')
}
<div>#{formatNumber(api.consts.poll.end as BlockNumber)}</div>
</div>
</div>
</div>
<article className='keepAlive'>
<p><Trans key='poll1'>The Polkadot DOT denomination vote: Seventy-two hours after the DOT token becomes transferable, the most popular option from this poll will decide the denomination used for the DOT token.</Trans></p>
<p><Trans key='poll2'>This is an <a href='https://en.wikipedia.org/wiki/Approval_voting' rel='noreferrer' target='_blank'>approval vote</a>. There are four options and you may select any combination of them. The most popular of the four will be selected as the final DOT denomination three days after DOT token transfers are enabled.</Trans></p>
<p><Trans key='poll3'>Please see the <a href='https://medium.com/polkadot-network/the-first-polkadot-vote-1fc1b8bd357b' rel='noreferrer' target='_blank'>Medium article </a> for more information</Trans></p>
{canVote && (
<p className='pollAll'><Trans key='poll4'><b>Please vote for any combination of options</b></Trans></p>
)}
<div className={`options ${canVote ? 'canVote' : ''}`}>
{options.map(([label, desc, value, onChange], index) =>
<Columar
is60
key={index}
>
<Columar.Column className='option'>
<div className='optionName'>{label}</div>
<div className='optionDesc'>{desc}</div>
{canVote && (
<Toggle
className='pollToggle'
isDisabled={!canVote}
label={
canVote
? value
? t<string>('Aye, I support this')
: t<string>('Nay, I do not support this')
: t<string>('Voting closed')
}
onChange={onChange}
value={canVote && value}
/>
)}
</Columar.Column>
<Columar.Column>
{totals[index].isZero()
? <div className='result' />
: (
<div className='result'>
<FormatBalance value={totals[index]} />
<Progress
isDisabled={!turnout}
total={turnout?.voted}
value={totals[index]}
/>
</div>
)
}
</Columar.Column>
</Columar>
)}
</div>
{canVote && (
<>
<InputAddress
label={t('vote using my account')}
onChange={setAccountId}
type='account'
/>
<Button.Group>
<TxButton
accountId={accountId}
icon='paper-plane'
isDisabled={!hasValue}
label={t('Vote')}
params={[[opt10m, opt100m, opt1b, opt10b]]}
tx={api.tx.poll.vote}
/>
</Button.Group>
</>
)}
</article>
<div className='pollActions'>
<ul>
<li>{t('Any combination of the four options may be approved of by the voter. There is no need to select only one option!')}</li>
<li>{t('Approving of all or none of the options is equivalent and will not affect the outcome of the poll.')}</li>
<li>{t('All voters may alter their votes any number of times prior to the close of the poll.')}</li>
<li>{t('Voting costs nothing other than the transaction fee and can be done from all accounts with a non-zero spendable balance.')}</li>
<li>{t('Locked funds (e.g. for staking) are counted.')}</li>
<li>{t('No discretionary lock-voting is in place; all DOT used to vote counts the same.')}</li>
<li>{t('Voting is made on a per-account basis; a single account must all vote the same way and cannot split its vote.')}</li>
<li>{t('This vote does not affect any economics of the Polkadot platform. Staking rewards, inflation, effective market capitalisation and the underlying balances of every account remain completely unchanged. It is "merely" about what units we use to denominate the balances into "DOT" for the purpose of display.')}</li>
</ul>
</div>
</div>
</main>
);
}