Update fees, mortal & tips (#1590)
* Update fees, mortal & tips * Linting * Revert findCall * Fix fee calculation (take version byte into account) * Remove MAX (weights), add weight note * does not *
This commit is contained in:
parent
b987e33e04
commit
f35b2d4428
@ -14,7 +14,7 @@ import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { Button, InputAddress, InputBalance, Modal, TxButton } from '@polkadot/react-components';
|
||||
import { Available } from '@polkadot/react-query';
|
||||
import Checks, { calcSignatureLength } from '@polkadot/react-signer/Checks';
|
||||
import Checks, { calcTxLength } from '@polkadot/react-signer/Checks';
|
||||
import { withApi, withCalls, withMulti } from '@polkadot/react-api';
|
||||
import { ZERO_FEES } from '@polkadot/react-signer/Checks/constants';
|
||||
import { bnMax } from '@polkadot/util';
|
||||
@ -214,7 +214,7 @@ class Transfer extends React.PureComponent<Props, State> {
|
||||
prevMax = maxBalance;
|
||||
extrinsic = api.tx.balances.transfer(recipientId, prevMax);
|
||||
|
||||
const txLength = calcSignatureLength(extrinsic, accountNonce);
|
||||
const txLength = calcTxLength(extrinsic, accountNonce);
|
||||
const fees = transactionBaseFee
|
||||
.add(transactionByteFee.mul(txLength))
|
||||
.add(transferFee)
|
||||
|
||||
@ -10,7 +10,7 @@ import { CalculateBalanceProps } from '../../types';
|
||||
import BN from 'bn.js';
|
||||
import React from 'react';
|
||||
import { Available, Button, InputAddress, InputBalance, Modal, TxButton, TxComponent } from '@polkadot/react-components';
|
||||
import { calcSignatureLength } from '@polkadot/react-signer/Checks';
|
||||
import { calcTxLength } from '@polkadot/react-signer/Checks';
|
||||
import { SubmittableExtrinsic } from '@polkadot/api/promise/types';
|
||||
import { withCalls, withApi, withMulti } from '@polkadot/react-api';
|
||||
import { ZERO_BALANCE, ZERO_FEES } from '@polkadot/react-signer/Checks/constants';
|
||||
@ -159,7 +159,7 @@ class BondExtra extends TxComponent<Props, State> {
|
||||
? api.tx.staking.bondExtra(maxAdditional)
|
||||
: null;
|
||||
|
||||
const txLength = calcSignatureLength(extrinsic, system_accountNonce);
|
||||
const txLength = calcTxLength(extrinsic, system_accountNonce);
|
||||
const fees = transactionBaseFee.add(transactionByteFee.mul(txLength));
|
||||
|
||||
maxBalance = bnMax(availableBalance.sub(fees), ZERO);
|
||||
|
||||
@ -10,7 +10,7 @@ import BN from 'bn.js';
|
||||
import React from 'react';
|
||||
import { ApiProps } from '@polkadot/react-api/types';
|
||||
import { BitLengthOption } from '@polkadot/react-components/constants';
|
||||
import { calcSignatureLength } from '@polkadot/react-signer/Checks';
|
||||
import { calcTxLength } from '@polkadot/react-signer/Checks';
|
||||
import { InputNumber } from '@polkadot/react-components';
|
||||
import { SubmittableExtrinsic } from '@polkadot/api/promise/types';
|
||||
import { withCalls, withMulti, withApi } from '@polkadot/react-api';
|
||||
@ -124,7 +124,7 @@ class InputBalanceBonded extends React.PureComponent<Props, State> {
|
||||
extrinsic = api.tx.staking.bonExtra(prevMax);
|
||||
}
|
||||
|
||||
const txLength = calcSignatureLength(extrinsic, system_accountNonce);
|
||||
const txLength = calcTxLength(extrinsic, system_accountNonce);
|
||||
const fees = transactionBaseFee.add(transactionByteFee.mul(txLength));
|
||||
|
||||
maxBalance = bnMax(freeBalance.sub(fees), ZERO);
|
||||
|
||||
@ -15,6 +15,8 @@ import Dropdown from './Dropdown';
|
||||
import Input, { KEYS, KEYS_PRE } from './Input';
|
||||
import translate from './translate';
|
||||
|
||||
const ALLOW_MAX = false;
|
||||
|
||||
interface Props extends BareProps, I18nProps {
|
||||
autoFocus?: boolean;
|
||||
bitLength?: BitLength;
|
||||
@ -115,7 +117,7 @@ class InputNumber extends React.PureComponent<Props, State> {
|
||||
type='text'
|
||||
value={value}
|
||||
>
|
||||
{(withMax && !!maxValue) && this.renderMaxButton()}
|
||||
{(ALLOW_MAX && withMax && !!maxValue) && this.renderMaxButton()}
|
||||
{isSi && this.renderSiDropdown()}
|
||||
</Input>
|
||||
);
|
||||
|
||||
@ -6,7 +6,7 @@ import { DerivedContractFees } from '@polkadot/api-derive/types';
|
||||
import { ExtraFees as State } from './types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import React from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Compact, UInt } from '@polkadot/types';
|
||||
|
||||
interface Props {
|
||||
@ -15,14 +15,14 @@ interface Props {
|
||||
onChange: (fees: State) => void;
|
||||
}
|
||||
|
||||
export default class ContractCall extends React.PureComponent<Props, State> {
|
||||
public state: State = {
|
||||
export default function ContractCall ({ endowment, fees, onChange }: Props): React.ReactElement<Props> | null {
|
||||
const [state, setState] = useState<State>({
|
||||
extraFees: new BN(0),
|
||||
extraAmount: new BN(0),
|
||||
extraWarn: false
|
||||
};
|
||||
});
|
||||
|
||||
public static getDerivedStateFromProps ({ endowment, fees, onChange }: Props, state: State): State {
|
||||
useEffect((): void => {
|
||||
const extraFees = new BN(fees.callBaseFee);
|
||||
const extraAmount = endowment instanceof Compact
|
||||
? endowment.toBn()
|
||||
@ -38,10 +38,8 @@ export default class ContractCall extends React.PureComponent<Props, State> {
|
||||
onChange(update);
|
||||
}
|
||||
|
||||
return update;
|
||||
}
|
||||
setState(update);
|
||||
}, [endowment, fees]);
|
||||
|
||||
public render (): React.ReactNode {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ import { DerivedContractFees } from '@polkadot/api-derive/types';
|
||||
import { ExtraFees as State } from './types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import React from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Compact, UInt } from '@polkadot/types';
|
||||
|
||||
interface Props {
|
||||
@ -15,14 +15,14 @@ interface Props {
|
||||
onChange: (fees: State) => void;
|
||||
}
|
||||
|
||||
export default class ContractDeploy extends React.PureComponent<Props, State> {
|
||||
public state: State = {
|
||||
export default function ContractDeploy ({ endowment, fees, onChange }: Props): React.ReactElement<Props> | null {
|
||||
const [state, setState] = useState<State>({
|
||||
extraFees: new BN(0),
|
||||
extraAmount: new BN(0),
|
||||
extraWarn: false
|
||||
};
|
||||
});
|
||||
|
||||
public static getDerivedStateFromProps ({ endowment, fees, onChange }: Props, state: State): State {
|
||||
useEffect((): void => {
|
||||
const extraFees = new BN(fees.createBaseFee).add(fees.contractFee);
|
||||
const extraAmount = endowment instanceof Compact
|
||||
? endowment.toBn()
|
||||
@ -38,10 +38,8 @@ export default class ContractDeploy extends React.PureComponent<Props, State> {
|
||||
onChange(update);
|
||||
}
|
||||
|
||||
return update;
|
||||
}
|
||||
setState(update);
|
||||
}, [endowment, fees]);
|
||||
|
||||
public render (): React.ReactNode {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -44,17 +44,22 @@ interface Props extends ApiProps, I18nProps {
|
||||
isSendable: boolean;
|
||||
onChange?: (hasAvailable: boolean) => void;
|
||||
system_accountNonce?: BN;
|
||||
tip?: BN;
|
||||
}
|
||||
|
||||
const LENGTH_PUBLICKEY = 32 + 1; // publicKey + prefix
|
||||
const LENGTH_SIGNATURE = 64;
|
||||
const LENGTH_ERA = 1;
|
||||
export const SIGNATURE_SIZE = LENGTH_PUBLICKEY + LENGTH_SIGNATURE + LENGTH_ERA;
|
||||
const LENGTH_ADDRESS = 32 + 1; // publicKey + prefix
|
||||
const LENGTH_ERA = 2; // assuming mortals
|
||||
const LENGTH_SIGNATURE = 64; // assuming ed25519 or sr25519
|
||||
const LENGTH_VERSION = 1; // 0x80 & version
|
||||
|
||||
export const calcSignatureLength = (extrinsic?: IExtrinsic | null, accountNonce?: BN): BN => {
|
||||
export const calcTxLength = (extrinsic?: IExtrinsic | null, nonce?: BN, tip?: BN): BN => {
|
||||
return new BN(
|
||||
SIGNATURE_SIZE +
|
||||
(accountNonce ? compactToU8a(accountNonce).length : 0) +
|
||||
LENGTH_VERSION +
|
||||
LENGTH_ADDRESS +
|
||||
LENGTH_SIGNATURE +
|
||||
LENGTH_ERA +
|
||||
compactToU8a(nonce || 0).length +
|
||||
compactToU8a(tip || 0).length +
|
||||
(extrinsic ? extrinsic.encodedLength : 0)
|
||||
);
|
||||
};
|
||||
@ -73,7 +78,7 @@ export class FeeDisplay extends React.PureComponent<Props, State> {
|
||||
overLimit: false
|
||||
};
|
||||
|
||||
public static getDerivedStateFromProps ({ accountId, balances_all = ZERO_BALANCE, api, extrinsic, balances_fees = ZERO_FEES_BALANCES, system_accountNonce = new BN(0) }: Props, prevState: State): State | null {
|
||||
public static getDerivedStateFromProps ({ accountId, balances_all = ZERO_BALANCE, api, extrinsic, balances_fees = ZERO_FEES_BALANCES, system_accountNonce = new BN(0), tip }: Props, prevState: State): State | null {
|
||||
if (!accountId || !extrinsic) {
|
||||
return null;
|
||||
}
|
||||
@ -81,7 +86,7 @@ export class FeeDisplay extends React.PureComponent<Props, State> {
|
||||
const fn = api.findCall(extrinsic.callIndex);
|
||||
const extMethod = fn.method;
|
||||
const extSection = fn.section;
|
||||
const txLength = calcSignatureLength(extrinsic, system_accountNonce);
|
||||
const txLength = calcTxLength(extrinsic, system_accountNonce, tip);
|
||||
|
||||
const isSameExtrinsic = prevState.extMethod === extMethod && prevState.extSection === extSection;
|
||||
const extraAmount = isSameExtrinsic
|
||||
@ -195,11 +200,12 @@ export class FeeDisplay extends React.PureComponent<Props, State> {
|
||||
fees: formatBalance(allFees)
|
||||
}
|
||||
})}</div>
|
||||
<div><Icon name='arrow right' />{t('{{total}} total transaction amount (fees + value)', {
|
||||
<div><Icon name='arrow right' />{t('{{total}} estimated total amount (fees + value)', {
|
||||
replace: {
|
||||
total: formatBalance(allTotal)
|
||||
}
|
||||
})}</div>
|
||||
<div><Icon name='dot circle outline' />{t('Estimation does not account for the transaction weight')}</div>
|
||||
</article>
|
||||
);
|
||||
}
|
||||
|
||||
@ -190,7 +190,7 @@ class Signer extends React.PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
private renderContent (): React.ReactNode {
|
||||
const { currentItem, isQrScanning, isQrVisible, isSendable, qrAddress, qrPayload } = this.state;
|
||||
const { currentItem, isQrScanning, isQrVisible, isSendable, qrAddress, qrPayload, tip } = this.state;
|
||||
|
||||
if (!currentItem) {
|
||||
return null;
|
||||
@ -200,6 +200,7 @@ class Signer extends React.PureComponent<Props, State> {
|
||||
<Transaction
|
||||
hideDetails={isQrVisible}
|
||||
isSendable={isSendable}
|
||||
tip={tip}
|
||||
value={currentItem}
|
||||
>
|
||||
{
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
import { I18nProps } from '@polkadot/react-components/types';
|
||||
import { QueueTx } from '@polkadot/react-components/Status/types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import React from 'react';
|
||||
import { GenericCall } from '@polkadot/types';
|
||||
import { Call, InputAddress, Modal } from '@polkadot/react-components';
|
||||
@ -16,10 +17,11 @@ interface Props extends I18nProps {
|
||||
children?: React.ReactNode;
|
||||
hideDetails?: boolean;
|
||||
isSendable: boolean;
|
||||
tip?: BN;
|
||||
value: QueueTx;
|
||||
}
|
||||
|
||||
function Transaction ({ children, hideDetails, isSendable, value: { accountId, extrinsic, isUnsigned }, t }: Props): React.ReactElement<Props> | null {
|
||||
function Transaction ({ children, hideDetails, isSendable, value: { accountId, extrinsic, isUnsigned }, t, tip }: Props): React.ReactElement<Props> | null {
|
||||
if (!extrinsic) {
|
||||
return null;
|
||||
}
|
||||
@ -55,6 +57,7 @@ function Transaction ({ children, hideDetails, isSendable, value: { accountId, e
|
||||
accountId={accountId}
|
||||
extrinsic={extrinsic}
|
||||
isSendable={isSendable}
|
||||
tip={tip}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
|
||||
@ -3,12 +3,11 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { BareProps } from '@polkadot/react-components/types';
|
||||
import { QueueProps } from '@polkadot/react-components/Status/types';
|
||||
|
||||
import './index.css';
|
||||
|
||||
import React from 'react';
|
||||
import { QueueConsumer } from '@polkadot/react-components/Status/Context';
|
||||
import React, { useContext } from 'react';
|
||||
import QueueContext from '@polkadot/react-components/Status/Context';
|
||||
|
||||
import Modal from './Modal';
|
||||
|
||||
@ -17,20 +16,18 @@ interface Props extends BareProps {
|
||||
}
|
||||
|
||||
export default function Signer ({ children, className, style }: Props): React.ReactElement<Props> {
|
||||
const { txqueue, queueSetTxStatus } = useContext(QueueContext);
|
||||
|
||||
return (
|
||||
<>
|
||||
{children}
|
||||
<QueueConsumer>
|
||||
{({ txqueue, queueSetTxStatus }: QueueProps): React.ReactNode => (
|
||||
<Modal
|
||||
className={className}
|
||||
key='signer-modal'
|
||||
queue={txqueue}
|
||||
queueSetTxStatus={queueSetTxStatus}
|
||||
style={style}
|
||||
/>
|
||||
)}
|
||||
</QueueConsumer>
|
||||
<Modal
|
||||
className={className}
|
||||
key='signer-modal'
|
||||
queue={txqueue}
|
||||
queueSetTxStatus={queueSetTxStatus}
|
||||
style={style}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user