diff --git a/packages/app-home/package.json b/packages/app-home/package.json index 8c3021bec5..c62d3b603c 100644 --- a/packages/app-home/package.json +++ b/packages/app-home/package.json @@ -13,7 +13,7 @@ "test": "react-scripts test --env=jsdom --coverage" }, "devDependencies": { - "@polkadot/rx-react": "^0.2.4", + "@polkadot/rx-react": "^0.2.7", "@polkadot/util": "^0.18.6", "react": "^16.3.1", "react-dom": "^16.3.1", diff --git a/packages/app-testing/package.json b/packages/app-testing/package.json index 69cec0558f..0552a4824d 100644 --- a/packages/app-testing/package.json +++ b/packages/app-testing/package.json @@ -13,7 +13,7 @@ "test": "react-scripts test --env=jsdom --coverage" }, "devDependencies": { - "@polkadot/rx-react": "^0.2.4", + "@polkadot/rx-react": "^0.2.7", "@polkadot/ui-react": "^0.9.10", "@polkadot/util": "^0.18.6", "@polkadot/util-keyring": "^0.18.6", diff --git a/packages/app-testing/src/Account/index.js b/packages/app-testing/src/Account/index.js index 6df5579b3f..9673ca71d2 100644 --- a/packages/app-testing/src/Account/index.js +++ b/packages/app-testing/src/Account/index.js @@ -20,7 +20,7 @@ type Props = BaseProps & { }; export default function Account ({ className, label, subject, style }: Props) { - const AccountBalance = withObservableParams(Balance, subject, ({ publicKey }: KeyringPair): Uint8Array => publicKey()); + const AccountBalance = withObservableParams(Balance, subject); return (
{ +const onChange = (event, { value }) => { extrinsicName.next(value); }; +const options = Object.keys(calls).map((value) => ({ + text: calls[value].description, + value +})); + export default function CallSelect ({ className, style }: Props) { return (
diff --git a/packages/app-testing/src/InputAddress/index.js b/packages/app-testing/src/InputAddress/index.js index 5d4666ee92..8c81020222 100644 --- a/packages/app-testing/src/InputAddress/index.js +++ b/packages/app-testing/src/InputAddress/index.js @@ -29,7 +29,7 @@ const testOptions = Object.keys(keyring).map((name) => ({ })); export default function InputAddress (props: Props): React$Node { - const onChange = (_, { value }) => { + const onChange = (event, { value }) => { if (props.subject) { props.subject.next(keyring[value]); } diff --git a/packages/app-testing/src/Sender/index.js b/packages/app-testing/src/Sender/index.js index bdd3a26e2f..38687829f8 100644 --- a/packages/app-testing/src/Sender/index.js +++ b/packages/app-testing/src/Sender/index.js @@ -8,19 +8,47 @@ import type { BaseProps } from '@polkadot/portal/types'; import './Sender.css'; import React from 'react'; +import Label from 'semantic-ui-react/dist/es/elements/Label'; +import Nonce from '@polkadot/rx-react/Nonce'; +import withObservableParams from '@polkadot/rx-react/with/observableParams'; +import u8aToBn from '@polkadot/util/u8a/toBn'; import Account from '../Account'; import addrSender from '../subject/addrSender'; +import nonceSender from '../subject/nonceSender'; type Props = BaseProps & {}; +const onNonceChange = (value: Uint8Array) => { + if (!value || value.length !== 8) { + return; + } + + const bn = u8aToBn(value, 64, true); + + console.log('next nonce', bn.toString()); + + nonceSender.next(bn); +}; + export default function Sender (props: Props) { - return ( + const SenderNonce = withObservableParams(Nonce, addrSender); + + return [ - ); + />, +
+
+ + +
+
+ ]; } diff --git a/packages/app-testing/src/calls/consensus.js b/packages/app-testing/src/calls/consensus.js new file mode 100644 index 0000000000..d68f00c2f8 --- /dev/null +++ b/packages/app-testing/src/calls/consensus.js @@ -0,0 +1,9 @@ +// 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 { Calls } from './types'; + +module.exports = ({ +}: Calls); diff --git a/packages/app-testing/src/calls/council.js b/packages/app-testing/src/calls/council.js new file mode 100644 index 0000000000..d68f00c2f8 --- /dev/null +++ b/packages/app-testing/src/calls/council.js @@ -0,0 +1,9 @@ +// 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 { Calls } from './types'; + +module.exports = ({ +}: Calls); diff --git a/packages/app-testing/src/calls/councilVoting.js b/packages/app-testing/src/calls/councilVoting.js new file mode 100644 index 0000000000..d68f00c2f8 --- /dev/null +++ b/packages/app-testing/src/calls/councilVoting.js @@ -0,0 +1,9 @@ +// 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 { Calls } from './types'; + +module.exports = ({ +}: Calls); diff --git a/packages/app-testing/src/calls/democracy.js b/packages/app-testing/src/calls/democracy.js new file mode 100644 index 0000000000..d68f00c2f8 --- /dev/null +++ b/packages/app-testing/src/calls/democracy.js @@ -0,0 +1,9 @@ +// 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 { Calls } from './types'; + +module.exports = ({ +}: Calls); diff --git a/packages/app-testing/src/calls/index.js b/packages/app-testing/src/calls/index.js new file mode 100644 index 0000000000..9357a57928 --- /dev/null +++ b/packages/app-testing/src/calls/index.js @@ -0,0 +1,48 @@ +// 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 { Calls } from './types'; + +const bnToU8a = require('@polkadot/util/bn/toU8a'); +const u8aConcat = require('@polkadot/util/u8a/concat'); + +const consensus = require('./consensus'); +const council = require('./council'); +const councilVoting = require('./councilVoting'); +const democracy = require('./democracy'); +const session = require('./session'); +const staking = require('./staking'); + +const calls = { + consensus, // 0 + session, // 1 + staking, // 2 + democracy, // 3 + council, // 4 + councilVoting // 5 +}; + +const flattenned: Calls = Object + .keys(calls) + .reduce((flat, sectionName, index) => { + const section = calls[sectionName]; + const sectionIndex = bnToU8a(index, 8); + + Object + .keys(section) + .reduce((flat, method, index) => { + const name = `${sectionName}_${method}`; + const methodIndex = bnToU8a(index, 8); + + flat[name] = section[method]; + flat[name].index = u8aConcat(sectionIndex, methodIndex); + + return flat; + }, flat); + + return flat; + }, ({}: $Shape)); + +module.exports = flattenned; diff --git a/packages/app-testing/src/calls/session.js b/packages/app-testing/src/calls/session.js new file mode 100644 index 0000000000..d68f00c2f8 --- /dev/null +++ b/packages/app-testing/src/calls/session.js @@ -0,0 +1,9 @@ +// 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 { Calls } from './types'; + +module.exports = ({ +}: Calls); diff --git a/packages/app-testing/src/calls/staking.js b/packages/app-testing/src/calls/staking.js new file mode 100644 index 0000000000..3b325072cb --- /dev/null +++ b/packages/app-testing/src/calls/staking.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 { Calls } from './types'; + +module.exports = ({ + transfer: { + description: 'Staking Transfer', + params: ['AccountId', 'Balance'] + }, + stake: { + description: 'Stake', + params: [] + }, + unstake: { + description: 'Unstake', + params: [] + } +}: Calls); diff --git a/packages/app-testing/src/calls/types.js b/packages/app-testing/src/calls/types.js new file mode 100644 index 0000000000..e2bb50d4d1 --- /dev/null +++ b/packages/app-testing/src/calls/types.js @@ -0,0 +1,18 @@ +// 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 + +export type Call$Type = 'AccountId' | 'Balance' | 'BlockNumber'; + +export type Call$Params = Array; + +export type Call = { + description: string, + index: Uint8Array, + params: Call$Params +}; + +export type Calls = { + [string]: $Shape +} diff --git a/packages/app-testing/src/encode/index.js b/packages/app-testing/src/encode/index.js new file mode 100644 index 0000000000..f574c63851 --- /dev/null +++ b/packages/app-testing/src/encode/index.js @@ -0,0 +1,33 @@ +// 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 BN from 'bn.js'; +import type { Call } from '../calls/types'; + +const bnToU8a = require('@polkadot/util/bn/toU8a'); +const u8aConcat = require('@polkadot/util/u8a/concat'); +const u8aToHex = require('@polkadot/util/u8a/toHex'); + +const encodeParams = require('./params'); + +// flowlint-next-line unclear-type:off +module.exports = function encode (sender: KeyringPair, nonce: number | BN, { index, params }: Call, values: Array) { + const encodedParams = encodeParams(values, params); + const message = u8aConcat( + sender.publicKey(), + bnToU8a(nonce, 64, true), + index, + encodedParams + ); + const signature = sender.sign(message); + + console.log('message', u8aToHex(message)); + console.log('signature', u8aToHex(signature)); + + return { + message, + signature + }; +}; diff --git a/packages/app-testing/src/encode/param.js b/packages/app-testing/src/encode/param.js new file mode 100644 index 0000000000..1ca41ad4b4 --- /dev/null +++ b/packages/app-testing/src/encode/param.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 { Call$Type } from '../../calls/types'; + +const bnToU8a = require('@polkadot/util/bn/toU8a'); + +// flowlint-next-line unclear-type:off +module.exports = function encodeValue (value: any, type: Call$Type): Uint8Array { + switch (type) { + case 'AccountId': + return value; + + case 'Balance': + case 'BlockNumber': + return bnToU8a(value, 64, true); + + default: + throw new Error(`Unable to encode value with type '${type}'`); + } +}; diff --git a/packages/app-testing/src/encode/params.js b/packages/app-testing/src/encode/params.js new file mode 100644 index 0000000000..b1de7a4153 --- /dev/null +++ b/packages/app-testing/src/encode/params.js @@ -0,0 +1,17 @@ +// 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 { Call$Params } from '../../calls/types'; + +const u8aConcat = require('@polkadot/util/u8a/concat'); + +const encodeParam = require('./param'); + +// flowlint-next-line unclear-type:off +module.exports = function encodeParams (values: Array, params: Call$Params): Uint8Array { + return u8aConcat.apply(null, values.map((value, index) => { + return encodeParam(value, params[index]); + })); +}; diff --git a/packages/app-testing/src/index.css b/packages/app-testing/src/index.css index 7a4f92ce21..dcceb38721 100644 --- a/packages/app-testing/src/index.css +++ b/packages/app-testing/src/index.css @@ -21,26 +21,21 @@ } .testing--split > div.full { - flex: 1 100%; + flex: 0 100%; min-width: 0; } .testing--split > div.large { - flex: 1 75%; + flex: 0 75%; min-width: 0; } .testing--split > div.medium { - flex: 1 50%; + flex: 0 50%; min-width: 0; } .testing--split > div.small { - flex: 1 25%; - min-width: 0; -} - -.testing--split > div:only-child { - flex-grow: 0; + flex: 0 25%; min-width: 0; } diff --git a/packages/app-testing/src/subject/addr.js b/packages/app-testing/src/subject/addr.js new file mode 100644 index 0000000000..6ec66373fa --- /dev/null +++ b/packages/app-testing/src/subject/addr.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 { KeyringPair } from '@polkadot/uti-keyring/types'; + +import { map } from 'rxjs/operators/map'; +import { ReplaySubject } from 'rxjs/ReplaySubject'; + +export default function addr (): $rxjs$ReplaySubject { + return new ReplaySubject(1).pipe( + map((pair: KeyringPair) => { + if (!pair) { + return new Uint8Array([]); + } + + return pair.publicKey(); + }) + ); +} diff --git a/packages/app-testing/src/subject/addrRecipient.js b/packages/app-testing/src/subject/addrRecipient.js index 3398f6e882..8dca03239f 100644 --- a/packages/app-testing/src/subject/addrRecipient.js +++ b/packages/app-testing/src/subject/addrRecipient.js @@ -3,8 +3,8 @@ // of the ISC license. See the LICENSE file for details. // @flow -import base from './base'; +import addr from './addr'; -const subject = base(); +const subject = addr(); export default subject; diff --git a/packages/app-testing/src/subject/addrSender.js b/packages/app-testing/src/subject/addrSender.js index 3398f6e882..8dca03239f 100644 --- a/packages/app-testing/src/subject/addrSender.js +++ b/packages/app-testing/src/subject/addrSender.js @@ -3,8 +3,8 @@ // of the ISC license. See the LICENSE file for details. // @flow -import base from './base'; +import addr from './addr'; -const subject = base(); +const subject = addr(); export default subject; diff --git a/packages/app-testing/src/subject/extrinsicName.js b/packages/app-testing/src/subject/extrinsicName.js index 3398f6e882..45630285c3 100644 --- a/packages/app-testing/src/subject/extrinsicName.js +++ b/packages/app-testing/src/subject/extrinsicName.js @@ -3,8 +3,8 @@ // of the ISC license. See the LICENSE file for details. // @flow -import base from './base'; +import { ReplaySubject } from 'rxjs/ReplaySubject'; -const subject = base(); +const subject = new ReplaySubject(1); export default subject; diff --git a/packages/app-testing/src/subject/base.js b/packages/app-testing/src/subject/nonceSender.js similarity index 66% rename from packages/app-testing/src/subject/base.js rename to packages/app-testing/src/subject/nonceSender.js index 8ac681a326..8cbb250a87 100644 --- a/packages/app-testing/src/subject/base.js +++ b/packages/app-testing/src/subject/nonceSender.js @@ -3,8 +3,11 @@ // of the ISC license. See the LICENSE file for details. // @flow +import BN from 'bn.js'; import { ReplaySubject } from 'rxjs/ReplaySubject'; -export default function base () { - return new ReplaySubject(1); -} +const subject = new ReplaySubject(1); + +subject.next(new BN(0)); + +export default subject; diff --git a/packages/portal/package.json b/packages/portal/package.json index de53e69f09..aea0f47b73 100644 --- a/packages/portal/package.json +++ b/packages/portal/package.json @@ -16,7 +16,7 @@ "devDependencies": { "@polkadot/app-home": "^0.1.0", "@polkadot/app-testing": "^0.1.0", - "@polkadot/rx-react": "^0.2.4", + "@polkadot/rx-react": "^0.2.7", "@polkadot/ui-react": "^0.9.10", "i18next": "^11.1.1", "i18next-browser-languagedetector": "^2.2.0", diff --git a/yarn.lock b/yarn.lock index fe96463171..e1a85e47cd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1299,19 +1299,19 @@ "@polkadot/util" "^0.18.4" babel-runtime "^6.26.0" -"@polkadot/rx-api@^0.2.4": - version "0.2.4" - resolved "https://registry.yarnpkg.com/@polkadot/rx-api/-/rx-api-0.2.4.tgz#e49c88d2d68a4e53d9d2ab0e307c564aa2ac5c20" +"@polkadot/rx-api@^0.2.7": + version "0.2.7" + resolved "https://registry.yarnpkg.com/@polkadot/rx-api/-/rx-api-0.2.7.tgz#aef716e7e8d3740746307331d242043c7694a8fd" dependencies: "@polkadot/api" "^0.8.14" "@polkadot/api-provider" "^0.8.14" rxjs "^5.5.10" -"@polkadot/rx-react@^0.2.4": - version "0.2.4" - resolved "https://registry.yarnpkg.com/@polkadot/rx-react/-/rx-react-0.2.4.tgz#fe142b564db5918c5207d8ae1cde86a3091caa84" +"@polkadot/rx-react@^0.2.7": + version "0.2.7" + resolved "https://registry.yarnpkg.com/@polkadot/rx-react/-/rx-react-0.2.7.tgz#5ec876ddf866e1e8ea2a70ddb484c1872102e2ac" dependencies: - "@polkadot/rx-api" "^0.2.4" + "@polkadot/rx-api" "^0.2.7" "@polkadot/util" "^0.18.6" "@polkadot/ui-identicon@^0.9.10":