diff --git a/packages/app-extrinsics/src/Account.js b/packages/app-extrinsics/src/Account.js index bbc176792a..ef8b859a7f 100644 --- a/packages/app-extrinsics/src/Account.js +++ b/packages/app-extrinsics/src/Account.js @@ -15,7 +15,7 @@ import InputAddress from './InputAddress'; type Props = BaseProps & { label: string, - subject: rxjs$BehaviorSubject<*> + subject: rxjs$BehaviorSubject }; function Account ({ className, label, subject, style, t }: Props): React$Node { diff --git a/packages/app-extrinsics/src/App.js b/packages/app-extrinsics/src/App.js index e2d9100386..0eb5586af7 100644 --- a/packages/app-extrinsics/src/App.js +++ b/packages/app-extrinsics/src/App.js @@ -3,30 +3,33 @@ // of the ISC license. See the LICENSE file for details. // @flow -import type { BaseProps } from './types'; +import type { BaseProps, QueueTx } from './types'; import React from 'react'; +import { BehaviorSubject } from 'rxjs/BehaviorSubject'; +import withObservable from '@polkadot/rx-react/with/observable'; -import CallDisplay from './CallDisplay'; -import CallSelect from './CallSelect'; -import Nonce from './Nonce'; -import Sender from './Sender'; +import Submission from './Submission'; import Signer from './Signer'; import translate from './translate'; type Props = BaseProps & {}; +const queue: rxjs$BehaviorSubject = new BehaviorSubject(({ + isValid: false, + status: 'incomplete' +}: $Shape)); + +const QueuedSigner = withObservable(queue)(Signer); + function App ({ className, style }: Props): React$Node { return (
- - - - - + +
); } diff --git a/packages/app-extrinsics/src/CallDisplay/CallDisplay.css b/packages/app-extrinsics/src/CallDisplay/CallDisplay.css deleted file mode 100644 index 4888ec57f9..0000000000 --- a/packages/app-extrinsics/src/CallDisplay/CallDisplay.css +++ /dev/null @@ -1,18 +0,0 @@ -/* Copyright 2017-2018 Jaco Greeff -/* This software may be modified and distributed under the terms -/* of the ISC license. See the LICENSE file for details. */ - -.extrinsics--CallDisplay { - margin-top: 1.5rem; -} - -.extrinsics--CallDisplay-error { - color: red; - opacity: 0.75; -} - -.extrinsics--CallDisplay-Component { - margin: 1.5rem 0; -} - -.extrinsics--CallDisplay-Button {} diff --git a/packages/app-extrinsics/src/CallDisplay/Error.js b/packages/app-extrinsics/src/CallDisplay/Error.js deleted file mode 100644 index 90fba70c6a..0000000000 --- a/packages/app-extrinsics/src/CallDisplay/Error.js +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2017-2018 Jaco Greeff -// This software may be modified and distributed under the terms -// of the ISC license. See the LICENSE file for details. -// @flow - -import type { BaseProps } from '../types'; - -import './CallDisplay.css'; - -import React from 'react'; - -import translate from '../translate'; - -function ErrorDisplay ({ className, style, t }: BaseProps): React$Node { - return ( -
- {t('calldisplay.error', { - defaultValue: 'ERROR: Invalid or unimplemented extrinsic function' - })} -
- ); -} - -export default translate(ErrorDisplay); diff --git a/packages/app-extrinsics/src/CallDisplay/index.js b/packages/app-extrinsics/src/CallDisplay/index.js deleted file mode 100644 index accd818c0c..0000000000 --- a/packages/app-extrinsics/src/CallDisplay/index.js +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2017-2018 Jaco Greeff -// This software may be modified and distributed under the terms -// of the ISC license. See the LICENSE file for details. -// @flow - -import type { BaseProps } from '../types'; - -import './CallDisplay.css'; - -import React from 'react'; -import Button from 'semantic-ui-react/dist/es/elements/Button'; -import withObservable from '@polkadot/rx-react/with/observable'; - -import translate from '../translate'; -import StakingStake from '../Staking/Stake'; -import StakingTransfer from '../Staking/Transfer'; -import StakingUnstake from '../Staking/Unstake'; -import { extrinsicName } from '../subjects'; -import ErrorComponent from './Error'; -import queueExtrinsic from './queue'; - -type ValueGetter = { - getValues: () => Array -} - -type Props = BaseProps & { - value?: string; -}; - -const COMPONENTS = { - 'staking_stake': StakingStake, - 'staking_transfer': StakingTransfer, - 'staking_unstake': StakingUnstake -}; - -function CallDisplay ({ className, style, t, value }: Props): React$Node { - // flowlint-next-line sketchy-null-string:off - if (!value) { - return null; - } - - const Component = COMPONENTS[value] || ErrorComponent; - const onSubmit = () => { - // flowlint-next-line unclear-type:off - queueExtrinsic(value, ((Component: any): ValueGetter).getValues()); - }; - - return ( -
- - -
- ); -} - -export default translate( - withObservable(extrinsicName)(CallDisplay) -); diff --git a/packages/app-extrinsics/src/CallDisplay/queue.js b/packages/app-extrinsics/src/CallDisplay/queue.js deleted file mode 100644 index 19ff693031..0000000000 --- a/packages/app-extrinsics/src/CallDisplay/queue.js +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2017-2018 Jaco Greeff -// This software may be modified and distributed under the terms -// of the ISC license. See the LICENSE file for details. -// @flow - -import encode from '../encode'; -import extrinsics from '../extrinsics'; -import { senderAddr, senderIndex, queueTx } from '../subjects'; - -export default function queue (method: string, values: Array): void { - // flowlint-next-line unclear-type:off - const publicKey = ((senderAddr.getValue(): any): Uint8Array); - const message = encode( - extrinsics.get(method), - publicKey, - senderIndex.getValue() || 0, - values - ); - - queueTx.next({ - message, - method, - publicKey - }); -} diff --git a/packages/app-extrinsics/src/CallSelect/index.js b/packages/app-extrinsics/src/CallSelect/index.js deleted file mode 100644 index 57a5a85a66..0000000000 --- a/packages/app-extrinsics/src/CallSelect/index.js +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2017-2018 Jaco Greeff -// This software may be modified and distributed under the terms -// of the ISC license. See the LICENSE file for details. -// @flow - -import type { BaseProps } from '../types'; - -import './CallSelect.css'; - -import React from 'react'; -import Dropdown from 'semantic-ui-react/dist/es/modules/Dropdown'; -import Label from 'semantic-ui-react/dist/es/elements/Label'; - -import translate from '../translate'; -import { extrinsicName } from '../subjects'; -import extrinsics from '../extrinsics'; - -type Props = BaseProps & {}; - -// eslint-disable-next-line no-unused-vars -const onChange = (event: SyntheticEvent<*>, { value }): void => { - extrinsicName.next(value); -}; - -const options = []; - -extrinsics.sections.forEach(({ description, methods, name }) => { - options.push({ - disabled: true, - text: description, - value: name - }); - - methods.forEach(({ description, name }) => { - options.push({ - className: 'extrinsics--CallSelect-indent', - text: description, - value: name - }); - }); -}); - -function CallSelect ({ className, style, t }: Props): React$Node { - return ( -
-
- - -
-
- ); -} - -export default translate(CallSelect); diff --git a/packages/app-extrinsics/src/Extrinsic/index.js b/packages/app-extrinsics/src/Extrinsic/index.js new file mode 100644 index 0000000000..5576241cdd --- /dev/null +++ b/packages/app-extrinsics/src/Extrinsic/index.js @@ -0,0 +1,43 @@ +// Copyright 2017-2018 Jaco Greeff +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +import type { BareProps, EncodedParams } from '../types'; + +import React from 'react'; +import Label from 'semantic-ui-react/dist/es/elements/Label'; +import withObservable from '@polkadot/rx-react/with/observable'; + +import InputExtrinsic from '../InputExtrinsic'; +import Params from '../Params'; +import createSubjects from './subjects'; + +type Props = BareProps & { + isPrivate?: boolean, + label: string, + subject: rxjs$BehaviorSubject +}; + +export default function ExtrinsicMethod ({ className, isPrivate, label, style, subject }: Props): React$Node { + const subjects = createSubjects(subject); + const MethodParams = withObservable(subjects.method)(Params); + + return ( +
+
+ + +
+ +
+ ); +} diff --git a/packages/app-extrinsics/src/Extrinsic/subjects.js b/packages/app-extrinsics/src/Extrinsic/subjects.js new file mode 100644 index 0000000000..8272a65434 --- /dev/null +++ b/packages/app-extrinsics/src/Extrinsic/subjects.js @@ -0,0 +1,45 @@ +// Copyright 2017-2018 Jaco Greeff +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +import type { Extrinsic } from '../extrinsics/types'; +import type { EncodedParams, RawParam } from '../types'; + +import { BehaviorSubject } from 'rxjs/BehaviorSubject'; +import isUndefined from '@polkadot/util/is/undefined'; + +import encodeExtrinsic from '../encode/extrinsic'; + +type Subjects = { + method: rxjs$BehaviorSubject, + params: rxjs$BehaviorSubject> +}; + +export default function subjects (subject: rxjs$BehaviorSubject): Subjects { + const subjects = { + method: new BehaviorSubject(({}: $Shape)), + params: new BehaviorSubject([]) + }; + + const onChange = (): void => { + const extrinsic = subjects.method.getValue(); + const values = subjects.params.getValue(); + const isValid = !!extrinsic.params && extrinsic.params.reduce((isValid, param, index) => { + return isValid && !isUndefined(values[index]) && !isUndefined(values[index].value) && values[index].isValid; + }, !!values); + const raw = values.map((param) => param && param.value); + const data = extrinsic.params && encodeExtrinsic(extrinsic, raw); + + subject.next({ + data, + extrinsic, + isValid + }); + }; + + subjects.method.subscribe(onChange); + subjects.params.subscribe(onChange); + + return subjects; +} diff --git a/packages/app-extrinsics/src/InputAddress/PairDisplay.css b/packages/app-extrinsics/src/InputAddress/PairDisplay.css index 753c8a8093..9e38cb7048 100644 --- a/packages/app-extrinsics/src/InputAddress/PairDisplay.css +++ b/packages/app-extrinsics/src/InputAddress/PairDisplay.css @@ -3,6 +3,9 @@ /* of the ISC license. See the LICENSE file for details. */ .ui--InputyAddress-PairDisplay { + display: flex; + flex-wrap: nowrap; + justify-content: space-between; position: relative; white-space: nowrap; } @@ -19,14 +22,19 @@ } .ui--InputyAddress-PairDisplay-address { + flex: 1; font-family: monospace; margin-left: 1rem; opacity: 0.5; - position: absolute; - right: 0; + overflow: hidden; + text-align: right; + text-overflow: ellipsis; } .ui--InputyAddress-PairDisplay-name { + flex: 1 0; margin-left: 3rem; + overflow: hidden; text-transform: uppercase; + text-overflow: ellipsis; } diff --git a/packages/app-extrinsics/src/InputAddress/index.js b/packages/app-extrinsics/src/InputAddress/index.js index 72a8c0aa10..1918bf1521 100644 --- a/packages/app-extrinsics/src/InputAddress/index.js +++ b/packages/app-extrinsics/src/InputAddress/index.js @@ -3,6 +3,8 @@ // of the ISC license. See the LICENSE file for details. // @flow +// TODO: This is a useful, shared component, move out + import './InputAddress.css'; import React from 'react'; @@ -44,9 +46,9 @@ export default function InputAddress (props: Props): React$Node { return ( diff --git a/packages/app-extrinsics/src/InputExtrinsic/InputExtrinsic.css b/packages/app-extrinsics/src/InputExtrinsic/InputExtrinsic.css new file mode 100644 index 0000000000..e48f780182 --- /dev/null +++ b/packages/app-extrinsics/src/InputExtrinsic/InputExtrinsic.css @@ -0,0 +1,40 @@ +/* Copyright 2017-2018 Jaco Greeff +/* This software may be modified and distributed under the terms +/* of the ISC license. See the LICENSE file for details. */ + +.ui--InputExtrinsic {} + +.ui--InputExtrinsic-Header {} + +.ui--InputExtrinsic .text { + box-sizing: border-box; + display: flex !important; + flex-wrap: nowrap; + justify-content: space-between; + position: relative; + width: 100%; + white-space: nowrap; +} + +.ui--InputExtrinsic-Item > .text { + padding-left: 1em; +} + +.ui--InputExtrinsic-Item-text, +.ui--InputExtrinsic-Item-call { + display: inline-block; +} + +.ui--InputExtrinsic-Item-call { + flex: 1; + font-family: monospace; + margin-left: 1rem; + opacity: 0.5; + overflow: hidden; + text-align: right; + text-overflow: ellipsis; +} + +.ui--InputExtrinsic-Item-text { + flex: 1 0; +} diff --git a/packages/app-extrinsics/src/InputExtrinsic/index.js b/packages/app-extrinsics/src/InputExtrinsic/index.js new file mode 100644 index 0000000000..3c3dff7b51 --- /dev/null +++ b/packages/app-extrinsics/src/InputExtrinsic/index.js @@ -0,0 +1,60 @@ +// Copyright 2017-2018 Jaco Greeff +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +// TODO: This is a useful, shared component, move out + +import type { Extrinsic } from '../extrinsics/types'; + +import './InputExtrinsic.css'; + +import React from 'react'; +import Dropdown from 'semantic-ui-react/dist/es/modules/Dropdown'; + +import extrinsics from '../extrinsics'; +import options from './options'; + +type Props = { + className?: string, + isPrivate?: boolean, + onChange?: (event: SyntheticEvent<*>, value: Extrinsic) => void, + style?: { + [string]: string + }, + subject?: rxjs$Subject +}; + +export default function InputExtrinsic (props: Props): React$Node { + // eslint-disable-next-line no-unused-vars + const onChange = (event: SyntheticEvent<*>, { value }): void => { + const extrinsic = extrinsics.get(value); + + if (props.subject) { + props.subject.next(extrinsic); + } + + if (props.onChange) { + props.onChange(event, extrinsic); + } + }; + + const _props = Object.assign({}, props); + + delete _props.isPrivate; + + return ( + + ); +} diff --git a/packages/app-extrinsics/src/InputExtrinsic/options.js b/packages/app-extrinsics/src/InputExtrinsic/options.js new file mode 100644 index 0000000000..ef764cd9af --- /dev/null +++ b/packages/app-extrinsics/src/InputExtrinsic/options.js @@ -0,0 +1,44 @@ +// Copyright 2017-2018 Jaco Greeff +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +import React from 'react'; + +import extrinsics from '../extrinsics'; + +const options = { + private: [], + public: [] +}; + +extrinsics.sections.forEach(({ description, hasPrivate, hasPublic, methods, name }) => { + const header = { + className: 'ui--InputExtrinsic-Header', + disabled: true, + text: description, + value: name + }; + + hasPublic && options.public.push(header); + hasPrivate && options.private.push(header); + + methods.forEach(({ description, name, params, isPrivate }) => { + const inputs = params.map(({ name }) => name).join(', '); + + options[isPrivate ? 'private' : 'public'].push({ + className: 'ui--InputExtrinsic-Item', + text: [ +
+ {description} +
, +
+ {name}({inputs}) +
+ ], + value: name + }); + }); +}); + +export default options; diff --git a/packages/app-extrinsics/src/Params/Account.js b/packages/app-extrinsics/src/Params/Account.js new file mode 100644 index 0000000000..8c309a4f0d --- /dev/null +++ b/packages/app-extrinsics/src/Params/Account.js @@ -0,0 +1,29 @@ +// Copyright 2017-2018 Jaco Greeff +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +import type { Props } from './types'; + +import React from 'react'; +import { BehaviorSubject } from 'rxjs/BehaviorSubject'; + +import BaseAccount from '../Account'; + +export default function Account ({ label, subject }: Props): React$Node { + const account: rxjs$BehaviorSubject = new BehaviorSubject(new Uint8Array([])); + + account.subscribe((value: Uint8Array) => { + subject.next({ + isValid: !!(value && value.length), + value + }); + }); + + return ( + + ); +} diff --git a/packages/app-extrinsics/src/Params/Amount.js b/packages/app-extrinsics/src/Params/Amount.js new file mode 100644 index 0000000000..4160309f98 --- /dev/null +++ b/packages/app-extrinsics/src/Params/Amount.js @@ -0,0 +1,40 @@ +// Copyright 2017-2018 Jaco Greeff +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +import type { Props } from './types'; + +import BN from 'bn.js'; +import React from 'react'; +import Input from 'semantic-ui-react/dist/es/elements/Input'; + +import Base from './Base'; + +export default function Amount ({ label, subject, t, value: { options: { initValue = 0, maxValue, minValue = 0 } = {} }, type }: Props): React$Node { + // flowlint-next-line sketchy-null-mixed:off, sketchy-null-number:off + const defaultValue = initValue || minValue; + // eslint-disable-next-line no-unused-vars + const onChange = (event: SyntheticEvent<*>, { value }): void => { + subject.next({ + isValid: true, + // flowlint-next-line sketchy-null-mixed:off, sketchy-null-number:off + value: new BN(value || minValue || 0) + }); + }; + + return ( + + + + ); +} diff --git a/packages/app-extrinsics/src/Params/Base.js b/packages/app-extrinsics/src/Params/Base.js new file mode 100644 index 0000000000..e5868f68be --- /dev/null +++ b/packages/app-extrinsics/src/Params/Base.js @@ -0,0 +1,31 @@ +// Copyright 2017-2018 Jaco Greeff +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +import React from 'react'; +import Label from 'semantic-ui-react/dist/es/elements/Label'; + +type Props = { + className?: string, + children: React$Node, + label?: string, + size?: 'full' | 'large' | 'medium' | 'small', + style?: { + [string]: string + } +}; + +export default function Base ({ children, className, label, size = 'medium', style }: Props): React$Node { + return ( +
+
+ + {children} +
+
+ ); +} diff --git a/packages/app-extrinsics/src/Params/Param.js b/packages/app-extrinsics/src/Params/Param.js new file mode 100644 index 0000000000..d4ea2225a5 --- /dev/null +++ b/packages/app-extrinsics/src/Params/Param.js @@ -0,0 +1,43 @@ +// Copyright 2017-2018 Jaco Greeff +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +import type { BaseProps } from './types'; + +import React from 'react'; + +import Account from './Account'; +import Amount from './Amount'; +import Proposal from './Proposal'; +import Unknown from './Unknown'; + +type Props = BaseProps & { + label?: string; +} + +const Components = { + 'AccountId': Account, + 'Balance': Amount, + 'BlockNumber': Amount, + 'Bytes': Unknown, + 'Proposal': Proposal, + 'u32': Amount, + 'u64': Amount +}; + +export default function Param ({ className, label, style, subject, value }: Props): React$Node { + // flowlint-next-line sketchy-null-string:off + const defaultLabel = label || `${value.name}: ${value.type}`; + const Component = Components[value.type]; + + return ( + + ); +} diff --git a/packages/app-extrinsics/src/CallSelect/CallSelect.css b/packages/app-extrinsics/src/Params/Params.css similarity index 55% rename from packages/app-extrinsics/src/CallSelect/CallSelect.css rename to packages/app-extrinsics/src/Params/Params.css index c1c75f6e1a..c864266eb9 100644 --- a/packages/app-extrinsics/src/CallSelect/CallSelect.css +++ b/packages/app-extrinsics/src/Params/Params.css @@ -2,8 +2,11 @@ /* This software may be modified and distributed under the terms /* of the ISC license. See the LICENSE file for details. */ -.extrinsics--CallSelect {} +.extrinsics--Params {} -.extrinsics--CallSelect-indent > span.text { - padding-left: 1.25em; +.extrinsics--Params-Content { + box-sizing: border-box; + padding-left: 2em; } + +.extrinsics--Params-Param {} diff --git a/packages/app-extrinsics/src/Params/Proposal.js b/packages/app-extrinsics/src/Params/Proposal.js new file mode 100644 index 0000000000..f1f6da63da --- /dev/null +++ b/packages/app-extrinsics/src/Params/Proposal.js @@ -0,0 +1,31 @@ +// Copyright 2017-2018 Jaco Greeff +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +import type { EncodedParams } from '../types'; +import type { Props } from './types'; + +import React from 'react'; +import { BehaviorSubject } from 'rxjs/BehaviorSubject'; + +import Extrinsic from '../Extrinsic'; + +export default function Proposal ({ label, subject }: Props): React$Node { + const extrinsic: rxjs$BehaviorSubject = new BehaviorSubject(({ isValid: false }: $Shape)); + + extrinsic.subscribe(({ data, isValid }: EncodedParams) => { + subject.next({ + isValid, + value: data + }); + }); + + return ( + + ); +} diff --git a/packages/app-extrinsics/src/Params/Unknown.js b/packages/app-extrinsics/src/Params/Unknown.js new file mode 100644 index 0000000000..e38e5805e7 --- /dev/null +++ b/packages/app-extrinsics/src/Params/Unknown.js @@ -0,0 +1,35 @@ +// Copyright 2017-2018 Jaco Greeff +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +import type { Props as BaseProps } from './types'; + +import React from 'react'; + +import translate from '../translate'; +import Base from './Base'; + +type Props = BaseProps & { + t: I18Next$Translate +}; + +function Unknown ({ label, t, value: { type } }: Props): React$Node { + return ( + +
+ {t('param.unknown', { + defaultValue: `ERROR: Unknown input of type '{{type}}' found. No renderer exists`, + replace: { + type + } + })} +
+ + ); +} + +export default translate(Unknown); diff --git a/packages/app-extrinsics/src/Params/index.js b/packages/app-extrinsics/src/Params/index.js new file mode 100644 index 0000000000..a21cebe1c8 --- /dev/null +++ b/packages/app-extrinsics/src/Params/index.js @@ -0,0 +1,56 @@ +// Copyright 2017-2018 Jaco Greeff +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +import type { Extrinsic } from '../extrinsics/types'; +import type { BaseProps, RawParam } from '../types'; + +import './Params.css'; + +import React from 'react'; +import Label from 'semantic-ui-react/dist/es/elements/Label'; + +import translate from '../translate'; +import Param from './Param'; +import createSubscriber from './subscriber'; + +type Props = BaseProps & { + subject: rxjs$BehaviorSubject>, + value: Extrinsic; +}; + +function Params ({ className, style, subject, t, value: { name, params } }: Props): React$Node { + if (!params || !params.length) { + return null; + } + + const subjects = createSubscriber(params, subject); + + return ( +
+
+ +
+ {params.map((param, index) => ( + + ))} +
+
+
+ ); +} + +export default translate(Params); diff --git a/packages/app-extrinsics/src/Params/initValue.js b/packages/app-extrinsics/src/Params/initValue.js new file mode 100644 index 0000000000..903f3557de --- /dev/null +++ b/packages/app-extrinsics/src/Params/initValue.js @@ -0,0 +1,25 @@ +// Copyright 2017-2018 Jaco Greeff +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +import type { Extrinsic$Param } from '../extrinsics/types'; + +import BN from 'bn.js'; + +export default function getInitValue ({ options: { initValue, minValue } = {}, type }: Extrinsic$Param): mixed { + // flowlint-next-line sketchy-null-mixed:off + const defaultValue = initValue || minValue; + + switch (type) { + case 'Balance': + case 'BlockNumber': + case 'u32': + case 'u64': + // flowlint-next-line sketchy-null-mixed:off + return new BN(defaultValue || 0); + + default: + return defaultValue; + } +} diff --git a/packages/app-extrinsics/src/Params/subjects.js b/packages/app-extrinsics/src/Params/subjects.js new file mode 100644 index 0000000000..53ed8f0900 --- /dev/null +++ b/packages/app-extrinsics/src/Params/subjects.js @@ -0,0 +1,23 @@ +// Copyright 2017-2018 Jaco Greeff +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +import type { Extrinsic$Params } from '../extrinsics/types'; +import type { RawParam } from '../types'; + +import { BehaviorSubject } from 'rxjs/BehaviorSubject'; +import isUndefined from '@polkadot/util/is/undefined'; + +import getInitValue from './initValue'; + +export default function createSubjects (params: Extrinsic$Params): Array> { + return params.map((param) => { + const value = getInitValue(param); + + return new BehaviorSubject({ + isValid: !isUndefined(value), + value + }); + }); +} diff --git a/packages/app-extrinsics/src/Params/subscriber.js b/packages/app-extrinsics/src/Params/subscriber.js new file mode 100644 index 0000000000..bb05f5d864 --- /dev/null +++ b/packages/app-extrinsics/src/Params/subscriber.js @@ -0,0 +1,23 @@ +// Copyright 2017-2018 Jaco Greeff +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +import type { Extrinsic$Params } from '../extrinsics/types'; +import type { RawParam } from '../types'; + +import createSubjects from './subjects'; + +export default function subscriber (params: Extrinsic$Params, subject: rxjs$BehaviorSubject>): Array> { + const subjects = createSubjects(params); + + if (subject) { + const onChange = (): void => { + subject.next(subjects.map((s) => s.getValue())); + }; + + subjects.forEach((s) => s.subscribe(onChange)); + } + + return subjects; +} diff --git a/packages/app-extrinsics/src/Params/types.js b/packages/app-extrinsics/src/Params/types.js new file mode 100644 index 0000000000..9a74727a47 --- /dev/null +++ b/packages/app-extrinsics/src/Params/types.js @@ -0,0 +1,16 @@ +// Copyright 2017-2018 Jaco Greeff +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +import type { Extrinsic$Param } from '../extrinsics/types'; +import type { BareProps, RawParam } from '../types'; + +export type BaseProps = BareProps & { + subject: rxjs$BehaviorSubject, + value: Extrinsic$Param +}; + +export type Props = BaseProps & { + label: string +}; diff --git a/packages/app-extrinsics/src/Recipient.js b/packages/app-extrinsics/src/Recipient.js deleted file mode 100644 index c018d187bd..0000000000 --- a/packages/app-extrinsics/src/Recipient.js +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2017-2018 Jaco Greeff -// This software may be modified and distributed under the terms -// of the ISC license. See the LICENSE file for details. -// @flow - -import type { BaseProps } from './types'; - -import React from 'react'; - -import translate from './translate'; -import Account from './Account'; -import { recipientAddr } from './subjects'; - -type Props = BaseProps & {}; - -function Recipient (props: Props): React$Node { - return ( - - ); -} - -export default translate(Recipient); diff --git a/packages/app-extrinsics/src/Sender.js b/packages/app-extrinsics/src/Sender.js deleted file mode 100644 index 51e4dfbf47..0000000000 --- a/packages/app-extrinsics/src/Sender.js +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2017-2018 Jaco Greeff -// This software may be modified and distributed under the terms -// of the ISC license. See the LICENSE file for details. -// @flow - -import type { BaseProps } from './types'; - -import React from 'react'; - -import Account from './Account'; -import { senderAddr } from './subjects'; -import translate from './translate'; - -type Props = BaseProps & {}; - -function Sender (props: Props): React$Node { - return ( - - ); -} - -export default translate(Sender); diff --git a/packages/app-extrinsics/src/Signer/Extrinsic.js b/packages/app-extrinsics/src/Signer/Decoded.js similarity index 70% rename from packages/app-extrinsics/src/Signer/Extrinsic.js rename to packages/app-extrinsics/src/Signer/Decoded.js index 28722f6a43..7f80a96520 100644 --- a/packages/app-extrinsics/src/Signer/Extrinsic.js +++ b/packages/app-extrinsics/src/Signer/Decoded.js @@ -18,7 +18,7 @@ type Props = BaseProps & { value: QueueTx }; -function Extrinsic ({ className, style, t, value: { message, method, publicKey } }: Props): React$Node { +function Decoded ({ className, style, t, value: { data, extrinsic, index, publicKey } }: Props): React$Node { const from = u8aToHexShort(publicKey); return ( @@ -33,20 +33,20 @@ function Extrinsic ({ className, style, t, value: { message, method, publicKey } />

- - You are about to sign a message from {from} calling {method} + + You are about to sign a message from {from} calling {extrinsic.name} with an index of {index.toString()}

- {t('extrinsic.data', { - defaultValue: 'The encoded message to be signed contains the data' + {t('decoded.data', { + defaultValue: 'The encoded parameters contains the data' })}

-

{u8aToHex(message)}

+

{u8aToHex(data)}

); } -export default translate(Extrinsic); +export default translate(Decoded); diff --git a/packages/app-extrinsics/src/Signer/index.js b/packages/app-extrinsics/src/Signer/index.js index 05860ad014..9e298dc15e 100644 --- a/packages/app-extrinsics/src/Signer/index.js +++ b/packages/app-extrinsics/src/Signer/index.js @@ -12,27 +12,29 @@ import React from 'react'; import Button from 'semantic-ui-react/dist/es/elements/Button'; import Modal from 'semantic-ui-react/dist/es/modules/Modal'; import withApi from '@polkadot/rx-react/with/api'; -import withObservable from '@polkadot/rx-react/with/observable'; -import { queueTx } from '../subjects'; import translate from '../translate'; -import Extrinsic from './Extrinsic'; +import Decoded from './Decoded'; import submitExtrinsic from './submit'; type Props = BaseProps & ApiProps & { - value?: QueueTx + subject: rxjs$BehaviorSubject, + value: QueueTx }; -function Signer ({ api, className, style, t, value }: Props): React$Node { - if (!value) { +function Signer ({ api, className, subject, style, t, value }: Props): React$Node { + if (value.status !== 'queued') { return null; } - const onClose = () => { - queueTx.next(); + const onClose = (): void => { + subject.next({ + ...value, + status: 'cancelled' + }); }; - const onSign = () => { - submitExtrinsic(api, value.publicKey, value.message).then(onClose); + const onSign = (): void => { + submitExtrinsic(api, value, subject); }; return ( @@ -47,7 +49,7 @@ function Signer ({ api, className, style, t, value }: Props): React$Node { defaultValue: 'Sign and submit' })} - + + ); +} + +export default translate(Submit); diff --git a/packages/app-extrinsics/src/Submission/index.js b/packages/app-extrinsics/src/Submission/index.js new file mode 100644 index 0000000000..bbd67f2afa --- /dev/null +++ b/packages/app-extrinsics/src/Submission/index.js @@ -0,0 +1,59 @@ +// Copyright 2017-2018 Jaco Greeff +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +import type { BaseProps, QueueTx } from '../types'; + +import './Submission.css'; + +import React from 'react'; +import withObservable from '@polkadot/rx-react/with/observable'; + +import Account from '../Account'; +import Extrinsic from '../Extrinsic'; +import translate from '../translate'; +import Nonce from './Nonce'; +import Submit from './Submit'; +import createSubjects from './subjects'; + +type Props = BaseProps & { + subject: rxjs$BehaviorSubject +}; + +function Submission ({ className, subject, style, t }: Props): React$Node { + const subjects = createSubjects(); + const Button = withObservable(subjects.call)(Submit); + + return ( +
+ + + +
+
+
+ ); +} + +export default translate(Submission); diff --git a/packages/app-extrinsics/src/Submission/subjects.js b/packages/app-extrinsics/src/Submission/subjects.js new file mode 100644 index 0000000000..4f091cffc8 --- /dev/null +++ b/packages/app-extrinsics/src/Submission/subjects.js @@ -0,0 +1,46 @@ +// Copyright 2017-2018 Jaco Greeff +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +import type { EncodedParams, QueueTx } from '../types'; + +import BN from 'bn.js'; +import { BehaviorSubject } from 'rxjs/BehaviorSubject'; + +type Subjects = { + call: rxjs$BehaviorSubject, + index: rxjs$BehaviorSubject, + method: rxjs$BehaviorSubject, + sender: rxjs$BehaviorSubject +}; + +export default function createSubjects (): Subjects { + const subjects = { + index: new BehaviorSubject(new BN(0)), + call: new BehaviorSubject(({ isValid: false }: $Shape)), + method: new BehaviorSubject(({ isValid: false }: $Shape)), + sender: new BehaviorSubject(new Uint8Array([])) + }; + + const onChange = (): void => { + const publicKey = subjects.sender.getValue(); + const message = subjects.method.getValue(); + const index = subjects.index.getValue(); + const isValid = !!(publicKey && publicKey.length && message && message.isValid); + + subjects.call.next({ + data: message.data, + extrinsic: message.extrinsic, + isValid, + index, + publicKey, + status: 'incomplete' + }); + }; + + subjects.method.subscribe(onChange); + subjects.sender.subscribe(onChange); + + return subjects; +} diff --git a/packages/app-extrinsics/src/encode/call.js b/packages/app-extrinsics/src/encode/call.js new file mode 100644 index 0000000000..aab06d7d88 --- /dev/null +++ b/packages/app-extrinsics/src/encode/call.js @@ -0,0 +1,19 @@ +// Copyright 2017-2018 Jaco Greeff +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +// TODO: Move to API + +import type BN from 'bn.js'; + +const bnToU8a = require('@polkadot/util/bn/toU8a'); +const u8aConcat = require('@polkadot/util/u8a/concat'); + +module.exports = function encodeCall (publicKey: Uint8Array, nonce: number | BN, data: Uint8Array): Uint8Array { + return u8aConcat( + publicKey, + bnToU8a(nonce, 64, true), + data + ); +}; diff --git a/packages/app-extrinsics/src/encode/extrinsic.js b/packages/app-extrinsics/src/encode/extrinsic.js new file mode 100644 index 0000000000..39bf4c28eb --- /dev/null +++ b/packages/app-extrinsics/src/encode/extrinsic.js @@ -0,0 +1,21 @@ +// Copyright 2017-2018 Jaco Greeff +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +import type { Extrinsic } from '../extrinsics/types'; + +const u8aConcat = require('@polkadot/util/u8a/concat'); + +const encodeParams = require('./params'); + +module.exports = function encodeExtrinsic (extrinsic: Extrinsic, values?: Array): Uint8Array { + if (!extrinsic) { + return new Uint8Array([]); + } + + return u8aConcat( + extrinsic.index, + encodeParams(extrinsic.params, values) + ); +}; diff --git a/packages/app-extrinsics/src/encode/index.js b/packages/app-extrinsics/src/encode/index.js index 312c974401..7b95f49ef1 100644 --- a/packages/app-extrinsics/src/encode/index.js +++ b/packages/app-extrinsics/src/encode/index.js @@ -8,16 +8,13 @@ import type BN from 'bn.js'; import type { Extrinsic } from '../extrinsics/types'; -const bnToU8a = require('@polkadot/util/bn/toU8a'); -const u8aConcat = require('@polkadot/util/u8a/concat'); +const encodeCall = require('./call'); +const encodeExtrinsic = require('./extrinsic'); -const encodeParams = require('./params'); - -module.exports = function encode ({ index, params }: Extrinsic, publicKey: Uint8Array, nonce: number | BN, values: Array): Uint8Array { - return u8aConcat( +module.exports = function encode (extrinsic: Extrinsic, publicKey: Uint8Array, nonce: number | BN, values?: Array): Uint8Array { + return encodeCall( publicKey, - bnToU8a(nonce, 64, true), - index, - encodeParams(values, params) + nonce, + encodeExtrinsic(extrinsic, values) ); }; diff --git a/packages/app-extrinsics/src/encode/param.js b/packages/app-extrinsics/src/encode/param.js index cc1a3088f2..c321f643c6 100644 --- a/packages/app-extrinsics/src/encode/param.js +++ b/packages/app-extrinsics/src/encode/param.js @@ -3,20 +3,31 @@ // of the ISC license. See the LICENSE file for details. // @flow -import type { Extrinsic$Type } from '../extrinsics/types'; +import type { Extrinsic$Param } from '../extrinsics/types'; const bnToU8a = require('@polkadot/util/bn/toU8a'); +const u8aToU8a = require('@polkadot/util/u8a/toU8a'); // flowlint-next-line unclear-type:off -module.exports = function encodeValue (value: any, type: Extrinsic$Type): Uint8Array { +module.exports = function encodeValue ({ type }: Extrinsic$Param, value: any): Uint8Array { switch (type) { case 'AccountId': return value; case 'Balance': case 'BlockNumber': + case 'u64': return bnToU8a(value, 64, true); + case 'Bytes': + return u8aToU8a(value); + + case 'Proposal': + return u8aToU8a(value); + + case 'u32': + return bnToU8a(value, 32, true); + default: throw new Error(`Unable to encode value with type '${type}'`); } diff --git a/packages/app-extrinsics/src/encode/params.js b/packages/app-extrinsics/src/encode/params.js index 10fb0870e1..d85bf2aa78 100644 --- a/packages/app-extrinsics/src/encode/params.js +++ b/packages/app-extrinsics/src/encode/params.js @@ -9,8 +9,8 @@ const u8aConcat = require('@polkadot/util/u8a/concat'); const encodeParam = require('./param'); -module.exports = function encodeParams (values: Array, params: Extrinsic$Params): Uint8Array { - return u8aConcat.apply(null, values.map((value, index) => { - return encodeParam(value, params[index]); +module.exports = function encodeParams (params: Extrinsic$Params, values?: Array = []): Uint8Array { + return u8aConcat.apply(null, params.map((param, index) => { + return encodeParam(param, values[index]); })); }; diff --git a/packages/app-extrinsics/src/extrinsics/consensus.js b/packages/app-extrinsics/src/extrinsics/consensus.js index 691f79d5c1..098796c014 100644 --- a/packages/app-extrinsics/src/extrinsics/consensus.js +++ b/packages/app-extrinsics/src/extrinsics/consensus.js @@ -7,5 +7,8 @@ import type { ExtrinsicsBasic } from './types'; module.exports = ({ description: 'Consensus', - methods: {} + methods: { + public: [], + private: [] + } }: ExtrinsicsBasic); diff --git a/packages/app-extrinsics/src/extrinsics/council.js b/packages/app-extrinsics/src/extrinsics/council.js index 9353f7f0d4..6ddcff378c 100644 --- a/packages/app-extrinsics/src/extrinsics/council.js +++ b/packages/app-extrinsics/src/extrinsics/council.js @@ -7,5 +7,8 @@ import type { ExtrinsicsBasic } from './types'; module.exports = ({ description: 'Council', - methods: {} + methods: { + public: [], + private: [] + } }: ExtrinsicsBasic); diff --git a/packages/app-extrinsics/src/extrinsics/councilVoting.js b/packages/app-extrinsics/src/extrinsics/councilVoting.js index cb427869fd..ef7075dac0 100644 --- a/packages/app-extrinsics/src/extrinsics/councilVoting.js +++ b/packages/app-extrinsics/src/extrinsics/councilVoting.js @@ -7,5 +7,8 @@ import type { ExtrinsicsBasic } from './types'; module.exports = ({ description: 'Council Voting', - methods: {} + methods: { + public: [], + private: [] + } }: ExtrinsicsBasic); diff --git a/packages/app-extrinsics/src/extrinsics/democracy.js b/packages/app-extrinsics/src/extrinsics/democracy.js index 504c5f3267..8e18561f7b 100644 --- a/packages/app-extrinsics/src/extrinsics/democracy.js +++ b/packages/app-extrinsics/src/extrinsics/democracy.js @@ -7,5 +7,18 @@ import type { ExtrinsicsBasic } from './types'; module.exports = ({ description: 'Democracy', - methods: {} + methods: { + public: [ + { + description: 'Propose', + index: 0, + name: 'propose', + params: [ + { name: 'proposal', type: 'Proposal' }, + { name: 'value', type: 'Balance' } + ] + } + ], + private: [] + } }: ExtrinsicsBasic); diff --git a/packages/app-extrinsics/src/extrinsics/index.js b/packages/app-extrinsics/src/extrinsics/index.js index 81dc8daf0d..fa3ac26a60 100644 --- a/packages/app-extrinsics/src/extrinsics/index.js +++ b/packages/app-extrinsics/src/extrinsics/index.js @@ -5,8 +5,9 @@ // TODO: Move to API -import type { Extrinsic, Extrinsics, ExtrinsicsBasic, ExtrinsicsMap, ExtrinsicSection } from './types'; +import type { Extrinsic, Extrinsics, ExtrinsicBasic, ExtrinsicsBasic, ExtrinsicsMap, ExtrinsicSection } from './types'; +const assert = require('@polkadot/util/assert'); const bnToU8a = require('@polkadot/util/bn/toU8a'); const u8aConcat = require('@polkadot/util/u8a/concat'); @@ -25,51 +26,57 @@ const map: { [string]: ExtrinsicsBasic } = { council, // 4 councilVoting // 5 }; -const sectionNames = Object.keys(map); -const extrinsics: Extrinsics = ({ - sections: [] -}: $Shape); const extrinsicsMap: ExtrinsicsMap = {}; +const extrinsics: Extrinsics = { + sections: [], + get: (method: string): Extrinsic => { + const extrinsic = extrinsicsMap[method]; -sectionNames.reduce((sections: Array, sectionName: string, _index) => { - const sectionSource = map[sectionName]; - const sectionIndex = bnToU8a(_index, 8); - const methodNames = Object.keys(sectionSource.methods); + assert(extrinsic, `Unable to retrieve extrinsic with name '${method}'`); - if (!methodNames.length) { - return sections; + return extrinsic; } +}; + +const sectionNames = Object.keys(map); + +function mapMethods (sectionSource: ExtrinsicsBasic, section: ExtrinsicSection, isPrivate: boolean): void { + const methods = sectionSource.methods[isPrivate ? 'private' : 'public']; + + methods.forEach(({ description, index, name, params }: ExtrinsicBasic) => { + const method: Extrinsic = { + description, + index: u8aConcat(section.index, bnToU8a(index, 8)), + isPrivate, + name: `${section.name}_${name}`, + params + }; + + extrinsicsMap[method.name] = method; + section[isPrivate ? 'hasPrivate' : 'hasPublic'] = true; + + section.methods.push(method); + }); +} + +sectionNames.reduce((sections: Array, sectionName: string, index: number) => { + const sectionSource = map[sectionName]; const section: ExtrinsicSection = { description: sectionSource.description, + hasPrivate: false, + hasPublic: false, + index: bnToU8a(index, 8), methods: [], name: sectionName }; - methodNames.reduce((methods: Array, methodName: string) => { - const methodSource = sectionSource.methods[methodName]; - const name = `${sectionName}_${methodName}`; - const index = u8aConcat(sectionIndex, bnToU8a(methodSource.index, 8)); - const method: Extrinsic = { - description: methodSource.description, - index, - name, - params: methodSource.params - }; - - methods.push(method); - extrinsicsMap[name] = method; - - return methods; - }, section.methods); + mapMethods(sectionSource, section, true); + mapMethods(sectionSource, section, false); sections.push(section); return sections; }, extrinsics.sections); -extrinsics.get = function get (sectionMethod: string): Extrinsic { - return extrinsicsMap[sectionMethod]; -}; - module.exports = extrinsics; diff --git a/packages/app-extrinsics/src/extrinsics/session.js b/packages/app-extrinsics/src/extrinsics/session.js index 97a279fb0c..3a4c62d6f5 100644 --- a/packages/app-extrinsics/src/extrinsics/session.js +++ b/packages/app-extrinsics/src/extrinsics/session.js @@ -7,5 +7,8 @@ import type { ExtrinsicsBasic } from './types'; module.exports = ({ description: 'Session', - methods: {} + methods: { + public: [], + private: [] + } }: ExtrinsicsBasic); diff --git a/packages/app-extrinsics/src/extrinsics/staking.js b/packages/app-extrinsics/src/extrinsics/staking.js index 6f082cf38b..6f0f794ffb 100644 --- a/packages/app-extrinsics/src/extrinsics/staking.js +++ b/packages/app-extrinsics/src/extrinsics/staking.js @@ -8,20 +8,60 @@ import type { ExtrinsicsBasic } from './types'; module.exports = ({ description: 'Staking', methods: { - transfer: { - description: 'Transfer', - index: 0, - params: ['AccountId', 'Balance'] - }, - stake: { - description: 'Stake', - index: 1, - params: [] - }, - unstake: { - description: 'Unstake', - index: 2, - params: [] - } + public: [ + { + description: 'Transfer', + index: 0, + name: 'transfer', + params: [ + { name: 'recipient', type: 'AccountId' }, + { name: 'value', type: 'Balance', options: { minValue: 1 } } + ] + }, + { + description: 'Stake', + index: 1, + name: 'stake', + params: [] + }, + { + description: 'Unstake', + index: 2, + name: 'unstake', + params: [] + } + ], + private: [ + { + description: 'Set sessions per era', + index: 0, + name: 'setSessionsPerEra', + params: [ + { name: 'sessions', type: 'u64' } + ] + }, + { + description: 'Set bonding duration', + index: 1, + name: 'setBondingDuration', + params: [ + { name: 'duration', type: 'u64' } + ] + }, + { + description: 'Set validator count', + index: 2, + name: 'setValidatorCount', + params: [ + { name: 'count', type: 'u32' } + ] + }, + { + description: 'Force new era', + index: 3, + name: 'forceNewEra', + params: [] + } + ] } }: ExtrinsicsBasic); diff --git a/packages/app-extrinsics/src/extrinsics/types.js b/packages/app-extrinsics/src/extrinsics/types.js index cbc813504d..95ba9f49f8 100644 --- a/packages/app-extrinsics/src/extrinsics/types.js +++ b/packages/app-extrinsics/src/extrinsics/types.js @@ -3,32 +3,49 @@ // of the ISC license. See the LICENSE file for details. // @flow -export type Extrinsic$Type = 'AccountId' | 'Balance' | 'BlockNumber'; +export type Extrinsic$Type = 'AccountId' | 'Balance' | 'BlockNumber' | 'Bytes' | 'Proposal' | 'u32' | 'u64'; -export type Extrinsic$Params = Array; +export type Extrinsic$Param = { + name: string, + options?: { + initValue?: mixed, + minValue?: mixed, + maxValue?: mixed + }, + type: Extrinsic$Type +}; + +export type Extrinsic$Params = Array; export type ExtrinsicBasic = { description: string, index: number, + isPrivate?: boolean, + name: string, params: Extrinsic$Params } export type ExtrinsicsBasic = { description: string, methods: { - [string]: ExtrinsicBasic + private: Array, + public: Array } } export type Extrinsic = { description: string, index: Uint8Array, + isPrivate: boolean, name: string, params: Extrinsic$Params }; export type ExtrinsicSection = { description: string, + hasPrivate: boolean, + hasPublic: boolean, + index: Uint8Array, methods: Array, name: string }; diff --git a/packages/app-extrinsics/src/index.css b/packages/app-extrinsics/src/index.css index 5fb4d78820..c67a5c0f22 100644 --- a/packages/app-extrinsics/src/index.css +++ b/packages/app-extrinsics/src/index.css @@ -21,7 +21,6 @@ .extrinsics--split > div { box-sizing: border-box; - padding-right: 0.5rem; } .extrinsics--split > div.full { @@ -29,6 +28,12 @@ min-width: 0; } +.extrinsics--split > div.large, +.extrinsics--split > div.medium, +.extrinsics--split > div.small { + padding-right: 0.5rem; +} + .extrinsics--split > div.large { flex: 0 75%; min-width: 0; diff --git a/packages/app-extrinsics/src/subjects.js b/packages/app-extrinsics/src/subjects.js deleted file mode 100644 index 8f8dad96a4..0000000000 --- a/packages/app-extrinsics/src/subjects.js +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2017-2018 Jaco Greeff -// This software may be modified and distributed under the terms -// of the ISC license. See the LICENSE file for details. -// @flow - -import type { QueueTx } from './types'; - -import BN from 'bn.js'; -import { BehaviorSubject } from 'rxjs/BehaviorSubject'; - -export const extrinsicName: rxjs$BehaviorSubject = new BehaviorSubject(); -export const recipientAddr: rxjs$BehaviorSubject = new BehaviorSubject(); -export const queueTx: rxjs$BehaviorSubject = new BehaviorSubject(); -export const senderAddr: rxjs$BehaviorSubject = new BehaviorSubject(); -export const senderIndex: rxjs$BehaviorSubject = new BehaviorSubject(new BN(0)); diff --git a/packages/app-extrinsics/src/types.js b/packages/app-extrinsics/src/types.js index 5e401c8ee8..efb47e35df 100644 --- a/packages/app-extrinsics/src/types.js +++ b/packages/app-extrinsics/src/types.js @@ -3,16 +3,35 @@ // of the ISC license. See the LICENSE file for details. // @flow -export type BaseProps = { +import type BN from 'bn.js'; +import type { Extrinsic } from './extrinsics/types'; + +export type BareProps = { className?: string, style?: { [string]: string - }, + } +}; + +export type BaseProps = BareProps & { t: I18Next$Translate }; -export type QueueTx = { - message: Uint8Array, - method: string, - publicKey: Uint8Array +export type RawParam = { + isValid: boolean, + value: mixed, +} + +export type EncodedParams = { + data: Uint8Array, + extrinsic: Extrinsic, + isValid: boolean +}; + +export type QueueTx$Status = 'incomplete' | 'cancelled' | 'error' | 'queued' | 'sent'; + +export type QueueTx = EncodedParams & { + index: BN, + publicKey: Uint8Array, + status: QueueTx$Status };