Show minimum balance on asset mint/transfer (#5134)
* Show minimum blanace on asset mint/transfer * Bump API
This commit is contained in:
parent
082a270dd0
commit
d00c562e70
@ -12,13 +12,13 @@
|
||||
"packages/*"
|
||||
],
|
||||
"resolutions": {
|
||||
"@polkadot/api": "^4.6.3-9",
|
||||
"@polkadot/api-contract": "^4.6.3-9",
|
||||
"@polkadot/api": "^4.6.3-10",
|
||||
"@polkadot/api-contract": "^4.6.3-10",
|
||||
"@polkadot/hw-ledger": "^6.2.2-7",
|
||||
"@polkadot/keyring": "^6.2.2-7",
|
||||
"@polkadot/networks": "^6.2.2-7",
|
||||
"@polkadot/phishing": "^0.6.104",
|
||||
"@polkadot/types": "^4.6.3-9",
|
||||
"@polkadot/types": "^4.6.3-10",
|
||||
"@polkadot/util": "^6.2.2-7",
|
||||
"@polkadot/util-crypto": "^6.2.2-7",
|
||||
"@polkadot/wasm-crypto": "^4.0.2",
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Copyright 2017-2021 @polkadot/app-assets authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { AssetBalance, AssetId } from '@polkadot/types/interfaces';
|
||||
import type { AssetBalance, AssetId, TAssetBalance } from '@polkadot/types/interfaces';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
@ -16,10 +16,11 @@ interface Props {
|
||||
assetId: AssetId;
|
||||
balance: AssetBalance;
|
||||
className?: string;
|
||||
minBalance: TAssetBalance;
|
||||
siFormat: [number, string];
|
||||
}
|
||||
|
||||
function Account ({ accountId, assetId, balance: { balance, isFrozen, isSufficient }, className, siFormat }: Props): React.ReactElement<Props> {
|
||||
function Account ({ accountId, assetId, balance: { balance, isFrozen, isSufficient }, className, minBalance, siFormat }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
@ -43,6 +44,7 @@ function Account ({ accountId, assetId, balance: { balance, isFrozen, isSufficie
|
||||
<Transfer
|
||||
accountId={accountId}
|
||||
assetId={assetId}
|
||||
minBalance={minBalance}
|
||||
siFormat={siFormat}
|
||||
/>
|
||||
</td>
|
||||
|
||||
@ -2,9 +2,9 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type BN from 'bn.js';
|
||||
import type { AssetId } from '@polkadot/types/interfaces';
|
||||
import type { AssetId, TAssetBalance } from '@polkadot/types/interfaces';
|
||||
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import { Button, InputAddress, InputBalance, Modal, Toggle, TxButton } from '@polkadot/react-components';
|
||||
import { useApi, useToggle } from '@polkadot/react-hooks';
|
||||
@ -15,10 +15,11 @@ interface Props {
|
||||
accountId: string;
|
||||
assetId: AssetId;
|
||||
className?: string;
|
||||
minBalance: TAssetBalance;
|
||||
siFormat: [number, string];
|
||||
}
|
||||
|
||||
function Transfer ({ accountId, assetId, className, siFormat: [siDecimals, siSymbol] }: Props): React.ReactElement<Props> {
|
||||
function Transfer ({ accountId, assetId, className, minBalance, siFormat: [siDecimals, siSymbol] }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const [isOpen, toggleOpen] = useToggle();
|
||||
@ -26,11 +27,6 @@ function Transfer ({ accountId, assetId, className, siFormat: [siDecimals, siSym
|
||||
const [recipientId, setRecipientId] = useState<string | null>(null);
|
||||
const [isProtected, setIsProtected] = useState(true);
|
||||
|
||||
const isAmountValid = useMemo(
|
||||
() => !!amount && !amount.isZero(),
|
||||
[amount]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
@ -59,17 +55,24 @@ function Transfer ({ accountId, assetId, className, siFormat: [siDecimals, siSym
|
||||
type='allPlus'
|
||||
/>
|
||||
</Modal.Columns>
|
||||
<Modal.Columns hint={t<string>('The amount of tokens to issue to the account.')}>
|
||||
<Modal.Columns hint={t<string>('The amount of tokens to transfer to the account.')}>
|
||||
<InputBalance
|
||||
autoFocus
|
||||
isError={!isAmountValid}
|
||||
isZeroable={false}
|
||||
label={t<string>('amount to transfer')}
|
||||
onChange={setAmount}
|
||||
siDecimals={siDecimals}
|
||||
siSymbol={siSymbol}
|
||||
/>
|
||||
</Modal.Columns>
|
||||
<Modal.Columns hint={t<string>('The minimum balance allowed for the asset.')}>
|
||||
<InputBalance
|
||||
defaultValue={minBalance}
|
||||
isDisabled
|
||||
label={t<string>('minimum balance')}
|
||||
siDecimals={siDecimals}
|
||||
siSymbol={siSymbol}
|
||||
/>
|
||||
</Modal.Columns>
|
||||
<Modal.Columns hint={t('With the keep-alive option set, the account is protected against removal due to low balances.')}>
|
||||
<Toggle
|
||||
className='typeToggle'
|
||||
@ -87,7 +90,7 @@ function Transfer ({ accountId, assetId, className, siFormat: [siDecimals, siSym
|
||||
<TxButton
|
||||
accountId={accountId}
|
||||
icon='paper-plane'
|
||||
isDisabled={!recipientId || !isAmountValid}
|
||||
isDisabled={!recipientId || !amount}
|
||||
label={t<string>('Send')}
|
||||
onStart={toggleOpen}
|
||||
params={[assetId, recipientId, amount]}
|
||||
|
||||
@ -85,6 +85,7 @@ function Balances ({ className, infos = [] }: Props): React.ReactElement<Props>
|
||||
assetId={info.id}
|
||||
balance={balance}
|
||||
key={accountId}
|
||||
minBalance={info.details.minBalance}
|
||||
siFormat={siFormat}
|
||||
/>
|
||||
))}
|
||||
|
||||
@ -3,48 +3,35 @@
|
||||
|
||||
import type { AssetBalance, AssetId } from '@polkadot/types/interfaces';
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useAccounts, useApi, useCall } from '@polkadot/react-hooks';
|
||||
|
||||
import { useAccounts, useApi, useCall, useIsMountedRef } from '@polkadot/react-hooks';
|
||||
|
||||
interface Result {
|
||||
interface BalanceResult {
|
||||
accountId: string;
|
||||
balance: AssetBalance;
|
||||
}
|
||||
|
||||
interface Result {
|
||||
assetId: AssetId;
|
||||
balances: BalanceResult[];
|
||||
}
|
||||
|
||||
const queryOptions = {
|
||||
transform: ([[params], balances]: [[[AssetId, string][]], AssetBalance[]]): Result[] =>
|
||||
params
|
||||
transform: ([[params], balances]: [[[AssetId, string][]], AssetBalance[]]): Result => ({
|
||||
assetId: params[0][0],
|
||||
balances: params
|
||||
.map(([, accountId], index) => ({
|
||||
accountId,
|
||||
balance: balances[index]
|
||||
}))
|
||||
.filter(({ balance: { balance } }) => !balance.isZero()),
|
||||
.filter(({ balance: { balance } }) => !balance.isZero())
|
||||
}),
|
||||
withParamsTransform: true
|
||||
};
|
||||
|
||||
export default function useBalances (id?: AssetId | null): Result[] | null {
|
||||
export default function useBalances (id?: AssetId | null): BalanceResult[] | null {
|
||||
const { api } = useApi();
|
||||
const { allAccounts } = useAccounts();
|
||||
const mountedRef = useIsMountedRef();
|
||||
const [state, setState] = useState<Result[] | null>(null);
|
||||
const query = useCall(id && api.query.assets.account.multi, [allAccounts.map((a) => [id, a])], queryOptions);
|
||||
const query = useCall(id && api.query.assets.account.multi, id && [allAccounts.map((a) => [id, a])], queryOptions);
|
||||
|
||||
useEffect((): void => {
|
||||
if (mountedRef.current) {
|
||||
setState(null);
|
||||
|
||||
if (id) {
|
||||
// dummy
|
||||
}
|
||||
}
|
||||
}, [id, mountedRef]);
|
||||
|
||||
useEffect((): void => {
|
||||
if (mountedRef.current && query) {
|
||||
setState(query);
|
||||
}
|
||||
}, [query, mountedRef]);
|
||||
|
||||
return state;
|
||||
return (query && id && (query.assetId === id) && query.balances) || null;
|
||||
}
|
||||
|
||||
@ -67,6 +67,15 @@ function Mint ({ className, details: { issuer, minBalance }, id, metadata, onClo
|
||||
siSymbol={siSymbol}
|
||||
/>
|
||||
</Modal.Columns>
|
||||
<Modal.Columns hint={t<string>('The minimum balance allowed for the asset.')}>
|
||||
<InputBalance
|
||||
defaultValue={minBalance}
|
||||
isDisabled
|
||||
label={t<string>('minimum balance')}
|
||||
siDecimals={siDecimals}
|
||||
siSymbol={siSymbol}
|
||||
/>
|
||||
</Modal.Columns>
|
||||
</Modal.Content>
|
||||
<Modal.Actions onCancel={onClose}>
|
||||
<TxButton
|
||||
|
||||
@ -5,6 +5,6 @@
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.13.17",
|
||||
"@polkadot/api-contract": "^4.6.3-9"
|
||||
"@polkadot/api-contract": "^4.6.3-10"
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.13.17",
|
||||
"@polkadot/api": "^4.6.3-9",
|
||||
"@polkadot/api": "^4.6.3-10",
|
||||
"@polkadot/extension-dapp": "^0.37.3-16",
|
||||
"@polkadot/x-rxjs": "^6.2.2-7",
|
||||
"fflate": "^0.6.9"
|
||||
|
||||
@ -8,7 +8,7 @@ import React, { useMemo } from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { BitLengthOption } from '@polkadot/react-components/constants';
|
||||
import { BN_TEN, formatBalance, isBn } from '@polkadot/util';
|
||||
import { BN_TEN, formatBalance, isBn, isUndefined } from '@polkadot/util';
|
||||
|
||||
import InputNumber from './InputNumber';
|
||||
|
||||
@ -41,12 +41,16 @@ interface Props {
|
||||
const BN_TEN_THOUSAND = new BN(10_000);
|
||||
const DEFAULT_BITLENGTH = BitLengthOption.CHAIN_SPEC as BitLength;
|
||||
|
||||
function reformat (value: string | BN, isDisabled?: boolean): string {
|
||||
function reformat (value: string | BN, isDisabled?: boolean, siDecimals?: number): string {
|
||||
const decimals = isUndefined(siDecimals)
|
||||
? formatBalance.getDefaults().decimals
|
||||
: siDecimals;
|
||||
|
||||
if (isBn(value)) {
|
||||
// format for 4 decimals (align with util)
|
||||
const valStr = value
|
||||
.mul(BN_TEN_THOUSAND)
|
||||
.div(BN_TEN.pow(new BN(formatBalance.getDefaults().decimals)))
|
||||
.div(BN_TEN.pow(new BN(decimals)))
|
||||
.toString()
|
||||
.padStart(5, '0'); // 4 after decimal, 1 before, min 5
|
||||
|
||||
@ -67,13 +71,13 @@ function reformat (value: string | BN, isDisabled?: boolean): string {
|
||||
return fmt;
|
||||
}
|
||||
|
||||
return formatBalance(value, { forceUnit: '-', withSi: false }).replace(',', isDisabled ? ',' : '');
|
||||
return formatBalance(value, { decimals, forceUnit: '-', withSi: false }).replace(',', isDisabled ? ',' : '');
|
||||
}
|
||||
|
||||
function InputBalance ({ autoFocus, children, className = '', defaultValue: inDefault, help, isDisabled, isError, isFull, isWarning, isZeroable, label, labelExtra, maxValue, onChange, onEnter, onEscape, placeholder, siDecimals, siSymbol, value, withEllipsis, withLabel, withMax }: Props): React.ReactElement<Props> {
|
||||
const defaultValue = useMemo(
|
||||
() => inDefault ? reformat(inDefault, isDisabled) : undefined,
|
||||
[inDefault, isDisabled]
|
||||
() => inDefault ? reformat(inDefault, isDisabled, siDecimals) : undefined,
|
||||
[inDefault, isDisabled, siDecimals]
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@ -137,7 +137,8 @@ export default React.memo(styled(Head)`
|
||||
}
|
||||
|
||||
&.filter {
|
||||
.ui.input {
|
||||
.ui.input,
|
||||
.ui.selection.dropdown {
|
||||
background: transparent;
|
||||
|
||||
&:first-child {
|
||||
|
||||
10
yarn.lock
10
yarn.lock
@ -2145,7 +2145,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@polkadot/api-contract@npm:^4.6.3-9":
|
||||
"@polkadot/api-contract@npm:^4.6.3-10":
|
||||
version: 4.6.3-10
|
||||
resolution: "@polkadot/api-contract@npm:4.6.3-10"
|
||||
dependencies:
|
||||
@ -2175,7 +2175,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@polkadot/api@npm:^4.6.3-9":
|
||||
"@polkadot/api@npm:^4.6.3-10":
|
||||
version: 4.6.3-10
|
||||
resolution: "@polkadot/api@npm:4.6.3-10"
|
||||
dependencies:
|
||||
@ -2265,7 +2265,7 @@ __metadata:
|
||||
resolution: "@polkadot/app-contracts@workspace:packages/page-contracts"
|
||||
dependencies:
|
||||
"@babel/runtime": ^7.13.17
|
||||
"@polkadot/api-contract": ^4.6.3-9
|
||||
"@polkadot/api-contract": ^4.6.3-10
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
@ -2725,7 +2725,7 @@ __metadata:
|
||||
resolution: "@polkadot/react-api@workspace:packages/react-api"
|
||||
dependencies:
|
||||
"@babel/runtime": ^7.13.17
|
||||
"@polkadot/api": ^4.6.3-9
|
||||
"@polkadot/api": ^4.6.3-10
|
||||
"@polkadot/extension-dapp": ^0.37.3-16
|
||||
"@polkadot/x-rxjs": ^6.2.2-7
|
||||
fflate: ^0.6.9
|
||||
@ -2921,7 +2921,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@polkadot/types@npm:^4.6.3-9":
|
||||
"@polkadot/types@npm:^4.6.3-10":
|
||||
version: 4.6.3-10
|
||||
resolution: "@polkadot/types@npm:4.6.3-10"
|
||||
dependencies:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user