From 357936eafc1a533905c49c8c945ddbb590726fca Mon Sep 17 00:00:00 2001 From: kwingram25 Date: Mon, 17 Jun 2019 12:51:09 +0200 Subject: [PATCH] Add checks for contract fees (#1299) * new checks * contracts checks * contract checks * rv yarn.lock * fixes --- packages/app-contracts/src/Deploy.tsx | 7 ++- .../ui-signer/src/Checks/ContractCall.tsx | 48 +++++++++++++++++ .../ui-signer/src/Checks/ContractDeploy.tsx | 49 +++++++++++++++++ packages/ui-signer/src/Checks/constants.ts | 19 ++++++- packages/ui-signer/src/Checks/index.tsx | 52 +++++++++++++++++-- 5 files changed, 165 insertions(+), 10 deletions(-) create mode 100644 packages/ui-signer/src/Checks/ContractCall.tsx create mode 100644 packages/ui-signer/src/Checks/ContractDeploy.tsx diff --git a/packages/app-contracts/src/Deploy.tsx b/packages/app-contracts/src/Deploy.tsx index 1ee3f7fdc6..5134c8812e 100644 --- a/packages/app-contracts/src/Deploy.tsx +++ b/packages/app-contracts/src/Deploy.tsx @@ -164,8 +164,7 @@ class Deploy extends ContractModal { ); } - private getAbiState = (abi: string | null | undefined, contractAbi: Abi | null = null): State => { - + private getContractAbiState = (abi: string | null | undefined, contractAbi: Abi | null = null): State => { if (contractAbi) { const args = contractAbi.deploy.args.map(({ name, type }) => name + ': ' + type); const text = `deploy(${args.join(', ')})`; @@ -211,7 +210,7 @@ class Deploy extends ContractModal { name: `${json.name} (instance)`, isHashValid: true, isNameValid: true, - ...this.getAbiState(json.abi, contractAbi) + ...this.getContractAbiState(json.abi, contractAbi) } as State; } } @@ -231,7 +230,7 @@ class Deploy extends ContractModal { protected onAddAbi = (abi: string | null | undefined, contractAbi?: Abi | null): void => { this.setState({ - ...this.getAbiState(abi, contractAbi) + ...this.getContractAbiState(abi, contractAbi) }); } diff --git a/packages/ui-signer/src/Checks/ContractCall.tsx b/packages/ui-signer/src/Checks/ContractCall.tsx new file mode 100644 index 0000000000..623699823c --- /dev/null +++ b/packages/ui-signer/src/Checks/ContractCall.tsx @@ -0,0 +1,48 @@ +// Copyright 2017-2019 @polkadot/ui-signer authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +import { DerivedContractFees } from '@polkadot/api-derive/types'; +import { ExtraFees } from './types'; + +import BN from 'bn.js'; +import React from 'react'; +import { Compact } from '@polkadot/types'; + +type Props = { + endowment: BN | Compact, + fees: DerivedContractFees, + onChange: (fees: ExtraFees) => void +}; + +type State = ExtraFees & {}; + +export default class ContractCall extends React.PureComponent { + state: State = { + extraFees: new BN(0), + extraAmount: new BN(0), + extraWarn: false + }; + + static getDerivedStateFromProps ({ endowment, fees, onChange }: Props, state: State) { + let extraFees = new BN(fees.callBaseFee); + + const extraAmount = endowment instanceof Compact ? endowment.toBn() : new BN(endowment || 0); + + const update = { + extraAmount, + extraFees, + extraWarn: false + }; + + if (!update.extraAmount.eq(state.extraAmount) || !update.extraFees.eq(state.extraFees)) { + onChange(update); + } + + return update; + } + + render () { + return null; + } +} diff --git a/packages/ui-signer/src/Checks/ContractDeploy.tsx b/packages/ui-signer/src/Checks/ContractDeploy.tsx new file mode 100644 index 0000000000..5fe29324bb --- /dev/null +++ b/packages/ui-signer/src/Checks/ContractDeploy.tsx @@ -0,0 +1,49 @@ +// Copyright 2017-2019 @polkadot/ui-signer authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +import { DerivedContractFees } from '@polkadot/api-derive/types'; +import { ExtraFees } from './types'; + +import BN from 'bn.js'; +import React from 'react'; +import { Compact } from '@polkadot/types'; + +type Props = { + endowment: BN | Compact, + fees: DerivedContractFees, + onChange: (fees: ExtraFees) => void +}; + +type State = ExtraFees & {}; + +export default class ContractDeploy extends React.PureComponent { + state: State = { + extraFees: new BN(0), + extraAmount: new BN(0), + extraWarn: false + }; + + static getDerivedStateFromProps ({ endowment, fees, onChange }: Props, state: State) { + let extraFees = new BN(fees.createBaseFee) + .add(fees.contractFee); + + const extraAmount = endowment instanceof Compact ? endowment.toBn() : new BN(endowment || 0); + + const update = { + extraAmount, + extraFees, + extraWarn: false + }; + + if (!update.extraAmount.eq(state.extraAmount) || !update.extraFees.eq(state.extraFees)) { + onChange(update); + } + + return update; + } + + render () { + return null; + } +} diff --git a/packages/ui-signer/src/Checks/constants.ts b/packages/ui-signer/src/Checks/constants.ts index 578e313950..f5b5b91d0a 100644 --- a/packages/ui-signer/src/Checks/constants.ts +++ b/packages/ui-signer/src/Checks/constants.ts @@ -2,7 +2,7 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { DerivedFees, DerivedBalances } from '@polkadot/api-derive/types'; +import { DerivedFees, DerivedBalances, DerivedContractFees } from '@polkadot/api-derive/types'; import BN from 'bn.js'; @@ -15,7 +15,7 @@ export const ZERO_BALANCE = { votingBalance: new BN(0) } as DerivedBalances; -export const ZERO_FEES = { +export const ZERO_FEES_BALANCES = { transactionBaseFee: new BN(0), transactionByteFee: new BN(0), creationFee: new BN(0), @@ -23,5 +23,20 @@ export const ZERO_FEES = { transferFee: new BN(0) } as DerivedFees; +export const ZERO_FEES = ZERO_FEES_BALANCES; + +export const ZERO_FEES_CONTRACT = { + callBaseFee: new BN(0), + contractFee: new BN(0), + createBaseFee: new BN(0), + creationFee: new BN(0), + rentByteFee: new BN(0), + rentDepositOffset: new BN(0), + transactionBaseFee: new BN(0), + transactionByteFee: new BN(0), + transferFee: new BN(0), + tombstoneDeposit: new BN(0) +} as DerivedContractFees; + export const MAX_SIZE_MB = 10; export const MAX_SIZE_BYTES = MAX_SIZE_MB * 1024 * 1024; diff --git a/packages/ui-signer/src/Checks/index.tsx b/packages/ui-signer/src/Checks/index.tsx index 57909a45f9..825722e192 100644 --- a/packages/ui-signer/src/Checks/index.tsx +++ b/packages/ui-signer/src/Checks/index.tsx @@ -3,21 +3,23 @@ // of the Apache-2.0 license. See the LICENSE file for details. import { I18nProps } from '@polkadot/ui-app/types'; -import { DerivedFees, DerivedBalances } from '@polkadot/api-derive/types'; +import { DerivedFees, DerivedBalances, DerivedContractFees } from '@polkadot/api-derive/types'; import { IExtrinsic } from '@polkadot/types/types'; import { ExtraFees } from './types'; import BN from 'bn.js'; import React from 'react'; -import { Method } from '@polkadot/types'; +import { Compact, Method } from '@polkadot/types'; import { withCalls } from '@polkadot/ui-api'; import { Icon } from '@polkadot/ui-app'; import { compactToU8a, formatBalance } from '@polkadot/util'; import translate from '../translate'; +import ContractCall from './ContractCall'; +import ContractDeploy from './ContractDeploy'; import Proposal from './Proposal'; import Transfer from './Transfer'; -import { MAX_SIZE_BYTES, MAX_SIZE_MB, ZERO_BALANCE, ZERO_FEES } from './constants'; +import { MAX_SIZE_BYTES, MAX_SIZE_MB, ZERO_BALANCE, ZERO_FEES_BALANCES, ZERO_FEES_CONTRACT } from './constants'; type State = ExtraFees & { allFees: BN, @@ -34,6 +36,7 @@ type State = ExtraFees & { type Props = I18nProps & { balances_fees?: DerivedFees, balances_all?: DerivedBalances, + contract_fees?: DerivedContractFees, accountId?: string | null, extrinsic?: IExtrinsic | null, isSendable: boolean, @@ -66,7 +69,7 @@ export class FeeDisplay extends React.PureComponent { overLimit: false }; - static getDerivedStateFromProps ({ accountId, balances_all = ZERO_BALANCE, extrinsic, balances_fees = ZERO_FEES, system_accountNonce = new BN(0) }: Props, prevState: State): State | null { + static getDerivedStateFromProps ({ accountId, balances_all = ZERO_BALANCE, extrinsic, balances_fees = ZERO_FEES_BALANCES, system_accountNonce = new BN(0) }: Props, prevState: State): State | null { if (!accountId || !extrinsic) { return null; } @@ -173,6 +176,8 @@ export class FeeDisplay extends React.PureComponent { } {this.renderTransfer()} {this.renderProposal()} + {this.renderCall()} + {this.renderDeploy()} { isReserved ?
{t('This account does have a reserved/locked balance, not taken into account')}
@@ -232,6 +237,44 @@ export class FeeDisplay extends React.PureComponent { ); } + private renderCall () { + const { extrinsic, contract_fees = ZERO_FEES_CONTRACT } = this.props; + const { extMethod, extSection } = this.state; + + if (!contract_fees || !extrinsic || extSection !== 'contract' || extMethod !== 'call') { + return null; + } + + const [, endowment] = extrinsic.args; + + return ( + + ); + } + + private renderDeploy () { + const { extrinsic, contract_fees = ZERO_FEES_CONTRACT } = this.props; + const { extMethod, extSection } = this.state; + + if (!contract_fees || !extrinsic || extSection !== 'contract' || extMethod !== 'create') { + return null; + } + + const [endowment] = extrinsic.args; + + return ( + + ); + } + private onExtraUpdate = (extra: ExtraFees) => { this.setState({ ...extra }); } @@ -241,6 +284,7 @@ export default translate( withCalls( 'derive.balances.fees', ['derive.balances.all', { paramName: 'accountId' }], + 'derive.contract.fees', ['query.system.accountNonce', { paramName: 'accountId' }] )(FeeDisplay) );