From e8a02b754bab38398ec7b71996d5534c68592eb1 Mon Sep 17 00:00:00 2001 From: kwingram25 Date: Mon, 29 Jul 2019 11:49:43 +0100 Subject: [PATCH] Add tip to signer (#1448) * Add tip to signer * preserve payload.tip * add tip to block explorer * toBn * caps * deps * greater than zero --- .../app-explorer/src/BlockInfo/Extrinsics.tsx | 1 + packages/ui-app/src/Call.tsx | 17 +++++- packages/ui-signer/src/Modal.tsx | 57 +++++++++++++++++-- 3 files changed, 70 insertions(+), 5 deletions(-) diff --git a/packages/app-explorer/src/BlockInfo/Extrinsics.tsx b/packages/app-explorer/src/BlockInfo/Extrinsics.tsx index 0bcdf8b21b..5c518d1026 100644 --- a/packages/app-explorer/src/BlockInfo/Extrinsics.tsx +++ b/packages/app-explorer/src/BlockInfo/Extrinsics.tsx @@ -83,6 +83,7 @@ class Extrinsics extends React.PureComponent { : t('mortal') : t('immortal') } + tip={extrinsic.tip.toBn()} value={extrinsic} withHash /> diff --git a/packages/ui-app/src/Call.tsx b/packages/ui-app/src/Call.tsx index e3aa8537df..677f9f067b 100644 --- a/packages/ui-app/src/Call.tsx +++ b/packages/ui-app/src/Call.tsx @@ -5,10 +5,12 @@ import { Codec, IExtrinsic, IMethod, TypeDef } from '@polkadot/types/types'; import { BareProps, I18nProps } from './types'; +import BN from 'bn.js'; import React from 'react'; import styled from 'styled-components'; import { GenericCall, getTypeDef } from '@polkadot/types'; import Params from '@polkadot/ui-params'; +import { formatBalance } from '@polkadot/util'; import Static from './Static'; import { classes } from './util'; @@ -19,6 +21,7 @@ export type Props = I18nProps & BareProps & { value: IExtrinsic | IMethod; withHash?: boolean; mortality?: string; + tip?: BN; }; const Wrapper = styled.div` @@ -32,7 +35,7 @@ const Wrapper = styled.div` class Call extends React.PureComponent { public render (): React.ReactNode { - const { children, className, style, mortality, value, withHash, t } = this.props; + const { children, className, style, mortality, tip, value, withHash, t } = this.props; const params = GenericCall.filterOrigin(value.meta).map(({ name, type }): { name: string; type: TypeDef } => ({ name: name.toString(), type: getTypeDef(type.toString()) @@ -75,6 +78,18 @@ class Call extends React.PureComponent { ) : null } + { + (tip && tip.gtn(0)) + ? ( + + {formatBalance(tip)} + + ) + : null + } { unlockError: null }; - public static getDerivedStateFromProps ({ allAccounts, queue }: Props, { currentItem, password, unlockError }: State): State { + public static getDerivedStateFromProps ({ allAccounts, api, queue }: Props, { currentItem, password, unlockError }: State): State { + let isV2: boolean; + try { + isV2 = !!api.tx.session.setKeys; + } catch (e) { + isV2 = false; + } + const nextItem = queue.find(({ status }): boolean => status === 'queued'); const isSame = !!nextItem && @@ -76,6 +86,7 @@ class Signer extends React.PureComponent { return { currentItem: nextItem, isSendable, + isV2, password: isSame ? password : '', unlockError: isSame ? unlockError : null }; @@ -155,11 +166,30 @@ class Signer extends React.PureComponent { isSendable={isSendable} value={currentItem} > + {this.renderTip()} {this.renderUnlock()} ); } + private renderTip (): React.ReactNode { + const { t } = this.props; + const { currentItem, isSendable, isV2 } = this.state; + + if (!isV2 || !isSendable || !currentItem) { + return null; + } + + return ( + + ); + } + private renderUnlock (): React.ReactNode { const { currentItem, isSendable, password, unlockError } = this.state; @@ -219,6 +249,10 @@ class Signer extends React.PureComponent { }); } + private onChangeTip = (tip?: BN): void => { + this.setState({ tip }); + } + private onCancel = (): void => { const { queueSetTxStatus } = this.props; const { currentItem } = this.state; @@ -267,6 +301,8 @@ class Signer extends React.PureComponent { } private async sendExtrinsic (queueTx: QueueTx, password?: string): Promise { + const { isV2, tip } = this.state; + const { accountId, extrinsic, id, payload, isUnsigned } = queueTx; if (!isUnsigned) { @@ -283,7 +319,14 @@ class Signer extends React.PureComponent { const { queueSetTxStatus } = this.props; if (payload) { - return this.makeExtrinsicSignature(payload, queueTx, keyring.getPair(accountId as string)); + return this.makeExtrinsicSignature( + { + ...payload, + ...((isV2 && tip && !payload.tip) ? { tip: tip.toString() } : {}) + }, + queueTx, + keyring.getPair(accountId as string) + ); } const submittable = extrinsic as SubmittableExtrinsic; @@ -320,6 +363,7 @@ class Signer extends React.PureComponent { private async makeExtrinsicCall (extrinsic: SubmittableExtrinsic, { id, txFailedCb, txSuccessCb, txStartCb, txUpdateCb }: QueueTx, extrinsicCall: (...params: any[]) => any, pair?: KeyringPair): Promise { const { api, queueSetTxStatus } = this.props; + const { isV2, tip } = this.state; console.log('makeExtrinsicCall: extrinsic ::', extrinsic.toHex()); @@ -341,6 +385,11 @@ class Signer extends React.PureComponent { } } + if (isV2 && tip) { + const signerOptions: Partial = { tip }; + params.push(signerOptions); + } + if (isFunction(txStartCb)) { txStartCb(); }