Asset transfer (#5130)
This commit is contained in:
parent
a345ca82f2
commit
10bfd86e30
@ -1,7 +1,7 @@
|
||||
// Copyright 2017-2021 @polkadot/app-assets authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { AssetBalance } from '@polkadot/types/interfaces';
|
||||
import type { AssetBalance, AssetId } from '@polkadot/types/interfaces';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
@ -9,15 +9,17 @@ import { AddressSmall } from '@polkadot/react-components';
|
||||
import { FormatBalance } from '@polkadot/react-query';
|
||||
|
||||
import { useTranslation } from '../translate';
|
||||
import Transfer from './Transfer';
|
||||
|
||||
interface Props {
|
||||
accountId: string;
|
||||
assetId: AssetId;
|
||||
balance: AssetBalance;
|
||||
className?: string;
|
||||
siFormat: [number, string];
|
||||
}
|
||||
|
||||
function Balance ({ accountId, balance: { balance, isFrozen, isSufficient }, className, siFormat }: Props): React.ReactElement<Props> {
|
||||
function Account ({ accountId, assetId, balance: { balance, isFrozen, isSufficient }, className, siFormat }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
@ -37,8 +39,15 @@ function Balance ({ accountId, balance: { balance, isFrozen, isSufficient }, cla
|
||||
value={balance}
|
||||
/>
|
||||
</td>
|
||||
<td className='button'>
|
||||
<Transfer
|
||||
accountId={accountId}
|
||||
assetId={assetId}
|
||||
siFormat={siFormat}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
|
||||
export default React.memo(Balance);
|
||||
export default React.memo(Account);
|
||||
106
packages/page-assets/src/Balances/Transfer.tsx
Normal file
106
packages/page-assets/src/Balances/Transfer.tsx
Normal file
@ -0,0 +1,106 @@
|
||||
// Copyright 2017-2021 @polkadot/app-assets authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type BN from 'bn.js';
|
||||
import type { AssetId } from '@polkadot/types/interfaces';
|
||||
|
||||
import React, { useMemo, useState } from 'react';
|
||||
|
||||
import { Button, InputAddress, InputBalance, Modal, Toggle, TxButton } from '@polkadot/react-components';
|
||||
import { useApi, useToggle } from '@polkadot/react-hooks';
|
||||
|
||||
import { useTranslation } from '../translate';
|
||||
|
||||
interface Props {
|
||||
accountId: string;
|
||||
assetId: AssetId;
|
||||
className?: string;
|
||||
siFormat: [number, string];
|
||||
}
|
||||
|
||||
function Transfer ({ accountId, assetId, className, siFormat: [siDecimals, siSymbol] }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const [isOpen, toggleOpen] = useToggle();
|
||||
const [amount, setAmount] = useState<BN | null>(null);
|
||||
const [recipientId, setRecipientId] = useState<string | null>(null);
|
||||
const [isProtected, setIsProtected] = useState(true);
|
||||
|
||||
const isAmountValid = useMemo(
|
||||
() => !!amount && !amount.isZero(),
|
||||
[amount]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
icon='paper-plane'
|
||||
label={t<string>('send')}
|
||||
onClick={toggleOpen}
|
||||
/>
|
||||
{isOpen && (
|
||||
<Modal
|
||||
className={className}
|
||||
header={t<string>('transfer asset')}
|
||||
size='large'
|
||||
>
|
||||
<Modal.Content>
|
||||
<Modal.Columns hint={t<string>('The account to transfer from. This account should have sufficient assets for this transfer.')}>
|
||||
<InputAddress
|
||||
defaultValue={accountId}
|
||||
isDisabled
|
||||
label={t<string>('send from')}
|
||||
/>
|
||||
</Modal.Columns>
|
||||
<Modal.Columns hint={t<string>('The beneficiary will have access to the transferred asset when the transaction is included in a block.')}>
|
||||
<InputAddress
|
||||
label={t<string>('send to address')}
|
||||
onChange={setRecipientId}
|
||||
type='allPlus'
|
||||
/>
|
||||
</Modal.Columns>
|
||||
<Modal.Columns hint={t<string>('The amount of tokens to issue 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('With the keep-alive option set, the account is protected against removal due to low balances.')}>
|
||||
<Toggle
|
||||
className='typeToggle'
|
||||
label={
|
||||
isProtected
|
||||
? t<string>('Transfer with account keep-alive checks')
|
||||
: t<string>('Normal transfer without keep-alive checks')
|
||||
}
|
||||
onChange={setIsProtected}
|
||||
value={isProtected}
|
||||
/>
|
||||
</Modal.Columns>
|
||||
</Modal.Content>
|
||||
<Modal.Actions onCancel={toggleOpen}>
|
||||
<TxButton
|
||||
accountId={accountId}
|
||||
icon='paper-plane'
|
||||
isDisabled={!recipientId || !isAmountValid}
|
||||
label={t<string>('Send')}
|
||||
onStart={toggleOpen}
|
||||
params={[assetId, recipientId, amount]}
|
||||
tx={
|
||||
isProtected
|
||||
? api.tx.assets.transferKeepAlive
|
||||
: api.tx.assets.transfer}
|
||||
/>
|
||||
</Modal.Actions>
|
||||
</Modal>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default React.memo(Transfer);
|
||||
@ -9,7 +9,7 @@ import { Dropdown, Table } from '@polkadot/react-components';
|
||||
import { formatNumber } from '@polkadot/util';
|
||||
|
||||
import { useTranslation } from '../translate';
|
||||
import Balance from './Balance';
|
||||
import Account from './Account';
|
||||
import useBalances from './useBalances';
|
||||
|
||||
interface Props {
|
||||
@ -27,6 +27,7 @@ function Balances ({ className, infos = [] }: Props): React.ReactElement<Props>
|
||||
[t('accounts'), 'start'],
|
||||
[t('frozen'), 'start'],
|
||||
[t('sufficient'), 'start'],
|
||||
[],
|
||||
[]
|
||||
]);
|
||||
|
||||
@ -79,8 +80,9 @@ function Balances ({ className, infos = [] }: Props): React.ReactElement<Props>
|
||||
header={headerRef.current}
|
||||
>
|
||||
{info && balances?.map(({ accountId, balance }) => (
|
||||
<Balance
|
||||
<Account
|
||||
accountId={accountId}
|
||||
assetId={info.id}
|
||||
balance={balance}
|
||||
key={accountId}
|
||||
siFormat={siFormat}
|
||||
|
||||
@ -16,11 +16,11 @@ interface Result {
|
||||
const queryOptions = {
|
||||
transform: ([[params], results]: [[[AssetId, string][]], AssetBalance[]]): Result[] =>
|
||||
results
|
||||
.filter(({ balance }) => !balance.isZero())
|
||||
.map((balance, index) => ({
|
||||
accountId: params[index][1],
|
||||
balance
|
||||
})),
|
||||
}))
|
||||
.filter(({ balance: { balance } }) => !balance.isZero()),
|
||||
withParamsTransform: true
|
||||
};
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user