Move TxButton to ui-app (#799)

* Move TxButton to ui-app (re-usable)

* Add txFailed, txSuccess & txUpdate callbacks to queue

* Linting

* Update Modal.tsx
This commit is contained in:
Jaco Greeff 2019-03-12 13:02:04 +01:00 committed by GitHub
parent 105205fb46
commit e7eb08851f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 66 additions and 28 deletions

View File

@ -4,9 +4,7 @@
import BN from 'bn.js';
import React from 'react';
import { Button, InputAddress, InputBalance } from '@polkadot/ui-app/index';
import TxButton from './TxButton';
import { Button, InputAddress, InputBalance, TxButton } from '@polkadot/ui-app/index';
type Props = {
accountId?: string

View File

@ -155,13 +155,16 @@ export default class Queue extends React.Component<Props, State> {
return id;
}
queueExtrinsic = ({ accountId, extrinsic, signerCallback, signerOptions, isUnsigned }: PartialQueueTx$Extrinsic): number => {
queueExtrinsic = ({ accountId, extrinsic, signerCb, signerOptions, txFailedCb, txSuccessCb, txUpdateCb, isUnsigned }: PartialQueueTx$Extrinsic): number => {
return this.queueAdd({
accountId,
extrinsic,
isUnsigned,
signerCallback,
signerOptions
signerCb,
signerOptions,
txFailedCb,
txSuccessCb,
txUpdateCb
});
}

View File

@ -2,6 +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 { SubmittableResult } from '@polkadot/api/SubmittableExtrinsic';
import { SubmittableExtrinsic } from '@polkadot/api/promise/types';
import { RpcMethod } from '@polkadot/jsonrpc/types';
import { AccountId, Address } from '@polkadot/types';
@ -24,6 +25,8 @@ export type QueueTx$Status = 'future' | 'ready' | 'finalised' | 'usurped' | 'dro
export type SignerCallback = (id: number, isSigned: boolean) => void;
export type TxCallback = (status: SubmittableResult) => void;
export type QueueTx = AccountInfo & {
error?: Error,
extrinsic?: SubmittableExtrinsic,
@ -31,8 +34,11 @@ export type QueueTx = AccountInfo & {
isUnsigned?: boolean,
result?: any,
rpc: RpcMethod,
signerCallback?: SignerCallback,
signerCb?: SignerCallback,
signerOptions?: SignatureOptions,
txFailedCb?: TxCallback,
txSuccessCb?: TxCallback,
txUpdateCb?: TxCallback,
values?: Array<any>,
status: QueueTx$Status
};
@ -63,8 +69,11 @@ export type PartialAccountInfo = {
export type PartialQueueTx$Extrinsic = PartialAccountInfo & {
extrinsic: SubmittableExtrinsic,
signerCallback?: SignerCallback,
signerCb?: SignerCallback,
signerOptions?: SignatureOptions,
txFailedCb?: TxCallback,
txSuccessCb?: TxCallback,
txUpdateCb?: TxCallback,
isUnsigned?: boolean
};

View File

@ -3,14 +3,15 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { ApiProps } from '@polkadot/ui-api/types';
import { QueueTx$ExtrinsicAdd } from '@polkadot/ui-app/Status/types';
import { QueueTx$ExtrinsicAdd, TxCallback } from './Status/types';
import React from 'react';
import { Button } from '@polkadot/ui-app/index';
import { QueueConsumer } from '@polkadot/ui-app/Status/Context';
import { withApi } from '@polkadot/ui-api/index';
import { assert } from '@polkadot/util';
import { QueueConsumer } from './Status/Context';
import Button from './Button';
type InjectedProps = {
queueExtrinsic: QueueTx$ExtrinsicAdd;
};
@ -19,6 +20,9 @@ type Props = ApiProps & {
accountId?: string,
isDisabled?: boolean,
label: React.ReactNode,
onFailed?: TxCallback,
onSuccess?: TxCallback,
onUpdate?: TxCallback,
params: Array<any>,
tx: string
};
@ -38,14 +42,17 @@ class TxButtonInner extends React.PureComponent<Props & InjectedProps> {
}
private send = (): void => {
const { accountId, api, params, queueExtrinsic, tx } = this.props;
const { accountId, api, onFailed, onSuccess, onUpdate, params, queueExtrinsic, tx } = this.props;
const [section, method] = tx.split('.');
assert(api.tx[section] && api.tx[section][method], `Unable to find api.tx.${section}.${method}`);
queueExtrinsic({
accountId,
extrinsic: api.tx[section][method](...params) as any // ???
extrinsic: api.tx[section][method](...params) as any, // ???
txFailedCb: onFailed,
txSuccessCb: onSuccess,
txUpdateCb: onUpdate
});
}
}

View File

@ -35,3 +35,4 @@ export { default as Progress } from './Progress';
export { default as Static } from './Static';
export { default as Status } from './Status';
export { default as Tabs } from './Tabs';
export { default as TxButton } from './TxButton';

View File

@ -25,7 +25,7 @@ export default class ApiSigner implements Signer {
accountId,
extrinsic,
signerOptions,
signerCallback: (id: number, isSigned: boolean): void => {
signerCb: (id: number, isSigned: boolean): void => {
if (isSigned) {
resolve(id);
} else {

View File

@ -8,16 +8,15 @@ import { ApiProps } from '@polkadot/ui-api/types';
import { I18nProps, BareProps } from '@polkadot/ui-app/types';
import { RpcMethod } from '@polkadot/jsonrpc/types';
import { KeyringPair } from '@polkadot/keyring/types';
import { SignatureOptions } from '@polkadot/types/types';
import { SubjectInfo } from '@polkadot/ui-keyring/observable/types';
import { QueueTx, QueueTx$MessageSetStatus, QueueTx$Result, QueueTx$Status, SignerCallback } from '@polkadot/ui-app/Status/types';
import { QueueTx, QueueTx$MessageSetStatus, QueueTx$Result, QueueTx$Status } from '@polkadot/ui-app/Status/types';
import React from 'react';
import { Button, Modal } from '@polkadot/ui-app/index';
import keyring from '@polkadot/ui-keyring';
import { withApi, withMulti, withObservable } from '@polkadot/ui-api/index';
import accountObservable from '@polkadot/ui-keyring/observable/accounts';
import { assert } from '@polkadot/util';
import { assert, isFunction } from '@polkadot/util';
import { format } from '@polkadot/util/logger';
import Transaction from './Transaction';
@ -230,10 +229,13 @@ class Signer extends React.PureComponent<Props, State> {
return;
}
const { id, signerCallback } = currentItem;
const { id, signerCb } = currentItem;
queueSetTxStatus(id, 'cancelled');
signerCallback && signerCallback(id, false);
if (isFunction(signerCb)) {
signerCb(id, false);
}
}
private onSend = async (): Promise<void> => {
@ -261,7 +263,9 @@ class Signer extends React.PureComponent<Props, State> {
queueSetTxStatus(id, status, result, error);
}
private async sendExtrinsic ({ accountId, extrinsic, id, signerCallback, signerOptions, isUnsigned }: QueueTx, password?: string): Promise<void> {
private async sendExtrinsic (queueTx: QueueTx, password?: string): Promise<void> {
const { accountId, extrinsic, id, signerOptions, isUnsigned } = queueTx;
assert(extrinsic, 'Expected an extrinsic to be supplied to sendExtrinsic');
if (!isUnsigned) {
@ -281,12 +285,12 @@ class Signer extends React.PureComponent<Props, State> {
queueSetTxStatus(id, 'sending');
if (isUnsigned) {
return this.makeExtrinsicCall(submittable, id, submittable.send);
return this.makeExtrinsicCall(submittable, queueTx, submittable.send);
} else if (signerOptions) {
return this.makeExtrinsicSignature(submittable, id, keyring.getPair(accountId as string), signerOptions, signerCallback);
return this.makeExtrinsicSignature(submittable, queueTx, keyring.getPair(accountId as string));
}
return this.makeExtrinsicCall(submittable, id, submittable.signAndSend, keyring.getPair(accountId as string));
return this.makeExtrinsicCall(submittable, queueTx, submittable.signAndSend, keyring.getPair(accountId as string));
}
private async submitRpc ({ method, section }: RpcMethod, values: Array<any>): Promise<QueueTx$Result> {
@ -311,7 +315,7 @@ class Signer extends React.PureComponent<Props, State> {
}
}
private async makeExtrinsicCall (extrinsic: SubmittableExtrinsic, id: number, extrinsicCall: (...params: Array<any>) => any, ..._params: Array<any>): Promise<void> {
private async makeExtrinsicCall (extrinsic: SubmittableExtrinsic, { id, txFailedCb, txSuccessCb, txUpdateCb }: QueueTx, extrinsicCall: (...params: Array<any>) => any, ..._params: Array<any>): Promise<void> {
const { queueSetTxStatus } = this.props;
console.log('makeExtrinsicCall: extrinsic ::', extrinsic.toHex());
@ -328,22 +332,38 @@ class Signer extends React.PureComponent<Props, State> {
queueSetTxStatus(id, status, result);
if (isFunction(txUpdateCb)) {
txUpdateCb(result);
}
if (status === 'finalised') {
unsubscribe();
result.events
.filter(({ event: { section } }) => section === 'system')
.forEach(({ event: { method } }) => {
if (isFunction(txFailedCb) && method === 'ExtrinsicFailed') {
txFailedCb(result);
} else if (isFunction(txSuccessCb) && method === 'ExtrinsicSuccess') {
txSuccessCb(result);
}
});
}
}]);
} catch (error) {
console.error('error.message', error.message);
console.error('makeExtrinsicCall: error:', error.message);
queueSetTxStatus(id, 'error', {}, error);
}
}
private async makeExtrinsicSignature (extrinsic: SubmittableExtrinsic, id: number, pair: KeyringPair, options: SignatureOptions, signerCallback?: SignerCallback): Promise<void> {
private async makeExtrinsicSignature (extrinsic: SubmittableExtrinsic, { id, signerCb, signerOptions }: QueueTx, pair: KeyringPair): Promise<void> {
console.log('makeExtrinsicSignature: extrinsic ::', extrinsic.toHex());
extrinsic.sign(pair, options);
extrinsic.sign(pair, signerOptions || {});
signerCallback && signerCallback(id, true);
if (isFunction(signerCb)) {
signerCb(id, true);
}
}
}