Asset transfer (#5130)

This commit is contained in:
Jaco 2021-04-23 16:23:44 +03:00 committed by GitHub
parent a345ca82f2
commit 10bfd86e30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 124 additions and 7 deletions

View File

@ -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);

View 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);

View File

@ -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}

View File

@ -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
};