From d589964bf2b9161de1f8686b49f9ad363de9e9e9 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Mon, 23 Apr 2018 17:25:00 +0200 Subject: [PATCH] Simple block exploration app (#2) * Updates * s/app-testing/app-extrinsics/ * Run components as apps using url * Redirect to /home * Expand Portal with NotFound app component * New block numbers & hashes are being shown * Only display best block once * best block -> best * TODO for calcHash * Explorer aligns with blockNumber/hash * Break signing into seperate modal * Cleanups with @flow * Adjust Dropdown for methods * Remove (for now) unused app-home * Update deps --- .flowconfig | 2 +- flow-typed/semantic-ui-react.js | 8 + .../{app-home => app-explorer}/package.json | 10 +- packages/app-explorer/src/App/App.css | 27 ++ .../src/App/index.js | 13 +- packages/app-explorer/src/BestHash.js | 39 +++ .../src/BlockHeader/BlockHeader.css | 56 ++++ .../app-explorer/src/BlockHeader/index.js | 65 +++++ .../app-explorer/src/BlockHeaders/index.js | 48 +++ .../src/BlockHeaders/transform.js | 24 ++ .../{app-home => app-explorer}/src/index.css | 0 .../{app-home => app-explorer}/src/index.js | 0 packages/app-explorer/src/subjects.js | 10 + packages/app-explorer/src/types.js | 11 + .../package.json | 8 +- .../src/Account.js | 4 +- .../src/App.js | 4 +- .../src/CallDisplay/CallDisplay.css | 8 +- .../src/CallDisplay/Error.js | 2 +- .../src/CallDisplay/index.js | 19 +- .../app-extrinsics/src/CallDisplay/queue.js | 25 ++ .../src/CallSelect/CallSelect.css} | 10 +- .../src/CallSelect/index.js} | 31 +- .../src/InputAddress/InputAddress.css | 0 .../src/InputAddress/PairDisplay.css | 0 .../src/InputAddress/PairDisplay.js | 0 .../src/InputAddress/index.js | 4 +- .../src/Nonce.js | 16 +- .../src/Recipient.js | 2 +- .../src/Sender.js | 2 +- .../app-extrinsics/src/Signer/Extrinsic.js | 37 +++ packages/app-extrinsics/src/Signer/Signer.css | 28 ++ packages/app-extrinsics/src/Signer/index.js | 64 ++++ packages/app-extrinsics/src/Signer/sign.js | 21 ++ packages/app-extrinsics/src/Signer/submit.js | 27 ++ .../src/Staking/Stake/getValues.js | 0 .../src/Staking/Stake/index.js | 2 +- .../src/Staking/Transfer/Amount.js | 2 +- .../src/Staking/Transfer/getValues.js | 0 .../src/Staking/Transfer/index.js | 2 +- .../src/Staking/Transfer/subjects.js | 0 .../src/Staking/Unstake/getValues.js | 0 .../src/Staking/Unstake/index.js | 2 +- .../src/encode/index.js | 18 +- .../src/encode/param.js | 0 .../src/encode/params.js | 0 .../src/extrinsics/consensus.js | 2 + .../src/extrinsics/council.js | 2 + .../src/extrinsics/councilVoting.js | 2 + .../src/extrinsics/democracy.js | 2 + .../app-extrinsics/src/extrinsics/index.js | 75 +++++ .../src/extrinsics/session.js | 2 + .../app-extrinsics/src/extrinsics/staking.js | 27 ++ .../src/extrinsics/types.js | 28 +- .../src/index.css | 20 +- .../src/index.js | 0 .../src/keyring.js | 0 packages/app-extrinsics/src/subjects.js | 15 + .../src/types.js | 6 + .../app-testing/src/CallDisplay/submit.js | 32 -- packages/app-testing/src/extrinsics/index.js | 56 ---- .../app-testing/src/extrinsics/staking.js | 21 -- packages/app-testing/src/subjects.js | 13 - packages/portal/package.json | 6 +- packages/portal/src/Content/Content.css | 11 +- packages/portal/src/Content/index.js | 49 ++-- packages/portal/src/NotFound/NotFound.css | 7 + packages/portal/src/NotFound/index.js | 24 ++ packages/portal/src/SideBar/Item.js | 3 +- packages/portal/src/SideBar/index.js | 50 ++-- packages/portal/src/index.css | 2 - packages/portal/src/index.js | 22 +- packages/portal/src/routes/index.js | 16 - .../{routes/home.js => routing/explorer.js} | 10 +- .../testing.js => routing/extrinsics.js} | 11 +- packages/portal/src/routing/index.js | 19 ++ packages/portal/src/semantic.css | 4 + packages/portal/src/types.js | 16 +- packages/portal/src/urlParams.js | 24 ++ yarn.lock | 274 ++++++------------ 80 files changed, 1008 insertions(+), 494 deletions(-) rename packages/{app-home => app-explorer}/package.json (67%) create mode 100644 packages/app-explorer/src/App/App.css rename packages/{app-home => app-explorer}/src/App/index.js (55%) create mode 100644 packages/app-explorer/src/BestHash.js create mode 100644 packages/app-explorer/src/BlockHeader/BlockHeader.css create mode 100644 packages/app-explorer/src/BlockHeader/index.js create mode 100644 packages/app-explorer/src/BlockHeaders/index.js create mode 100644 packages/app-explorer/src/BlockHeaders/transform.js rename packages/{app-home => app-explorer}/src/index.css (100%) rename packages/{app-home => app-explorer}/src/index.js (100%) create mode 100644 packages/app-explorer/src/subjects.js create mode 100644 packages/app-explorer/src/types.js rename packages/{app-testing => app-extrinsics}/package.json (80%) rename packages/{app-testing => app-extrinsics}/src/Account.js (91%) rename packages/{app-testing => app-extrinsics}/src/App.js (85%) rename packages/{app-testing => app-extrinsics}/src/CallDisplay/CallDisplay.css (64%) rename packages/{app-testing => app-extrinsics}/src/CallDisplay/Error.js (86%) rename packages/{app-testing => app-extrinsics}/src/CallDisplay/index.js (70%) create mode 100644 packages/app-extrinsics/src/CallDisplay/queue.js rename packages/{app-home/src/App/App.css => app-extrinsics/src/CallSelect/CallSelect.css} (54%) rename packages/{app-testing/src/CallSelect.js => app-extrinsics/src/CallSelect/index.js} (58%) rename packages/{app-testing => app-extrinsics}/src/InputAddress/InputAddress.css (100%) rename packages/{app-testing => app-extrinsics}/src/InputAddress/PairDisplay.css (100%) rename packages/{app-testing => app-extrinsics}/src/InputAddress/PairDisplay.js (100%) rename packages/{app-testing => app-extrinsics}/src/InputAddress/index.js (92%) rename packages/{app-testing => app-extrinsics}/src/Nonce.js (69%) rename packages/{app-testing => app-extrinsics}/src/Recipient.js (87%) rename packages/{app-testing => app-extrinsics}/src/Sender.js (88%) create mode 100644 packages/app-extrinsics/src/Signer/Extrinsic.js create mode 100644 packages/app-extrinsics/src/Signer/Signer.css create mode 100644 packages/app-extrinsics/src/Signer/index.js create mode 100644 packages/app-extrinsics/src/Signer/sign.js create mode 100644 packages/app-extrinsics/src/Signer/submit.js rename packages/{app-testing => app-extrinsics}/src/Staking/Stake/getValues.js (100%) rename packages/{app-testing => app-extrinsics}/src/Staking/Stake/index.js (87%) rename packages/{app-testing => app-extrinsics}/src/Staking/Transfer/Amount.js (93%) rename packages/{app-testing => app-extrinsics}/src/Staking/Transfer/getValues.js (100%) rename packages/{app-testing => app-extrinsics}/src/Staking/Transfer/index.js (89%) rename packages/{app-testing => app-extrinsics}/src/Staking/Transfer/subjects.js (100%) rename packages/{app-testing => app-extrinsics}/src/Staking/Unstake/getValues.js (100%) rename packages/{app-testing => app-extrinsics}/src/Staking/Unstake/index.js (87%) rename packages/{app-testing => app-extrinsics}/src/encode/index.js (51%) rename packages/{app-testing => app-extrinsics}/src/encode/param.js (100%) rename packages/{app-testing => app-extrinsics}/src/encode/params.js (100%) rename packages/{app-testing => app-extrinsics}/src/extrinsics/consensus.js (85%) rename packages/{app-testing => app-extrinsics}/src/extrinsics/council.js (86%) rename packages/{app-testing => app-extrinsics}/src/extrinsics/councilVoting.js (84%) rename packages/{app-testing => app-extrinsics}/src/extrinsics/democracy.js (85%) create mode 100644 packages/app-extrinsics/src/extrinsics/index.js rename packages/{app-testing => app-extrinsics}/src/extrinsics/session.js (86%) create mode 100644 packages/app-extrinsics/src/extrinsics/staking.js rename packages/{app-testing => app-extrinsics}/src/extrinsics/types.js (56%) rename packages/{app-testing => app-extrinsics}/src/index.css (68%) rename packages/{app-testing => app-extrinsics}/src/index.js (100%) rename packages/{app-testing => app-extrinsics}/src/keyring.js (100%) create mode 100644 packages/app-extrinsics/src/subjects.js rename packages/{app-testing => app-extrinsics}/src/types.js (80%) delete mode 100644 packages/app-testing/src/CallDisplay/submit.js delete mode 100644 packages/app-testing/src/extrinsics/index.js delete mode 100644 packages/app-testing/src/extrinsics/staking.js delete mode 100644 packages/app-testing/src/subjects.js create mode 100644 packages/portal/src/NotFound/NotFound.css create mode 100644 packages/portal/src/NotFound/index.js delete mode 100644 packages/portal/src/routes/index.js rename packages/portal/src/{routes/home.js => routing/explorer.js} (68%) rename packages/portal/src/{routes/testing.js => routing/extrinsics.js} (65%) create mode 100644 packages/portal/src/routing/index.js create mode 100644 packages/portal/src/urlParams.js diff --git a/.flowconfig b/.flowconfig index 94af666f76..051845a5df 100644 --- a/.flowconfig +++ b/.flowconfig @@ -12,5 +12,5 @@ all=warn [options] include_warnings=true -module.name_mapper='^@polkadot/content-\(accounts\|home\|settings\)\(.*\)$' -> '/packages/content-\1/src\2' +module.name_mapper='^@polkadot/app-\(accounts\|explorer\|extrinsics\|home\|settings\)\(.*\)$' -> '/packages/app-\1/src\2' module.name_mapper='^@polkadot/portal\(.*\)$' -> '/packages/portal/src\1' diff --git a/flow-typed/semantic-ui-react.js b/flow-typed/semantic-ui-react.js index cbf05a20cc..53ca9071a4 100644 --- a/flow-typed/semantic-ui-react.js +++ b/flow-typed/semantic-ui-react.js @@ -25,3 +25,11 @@ declare module 'semantic-ui-react/dist/es/elements/Label' { declare module 'semantic-ui-react/dist/es/modules/Dropdown' { declare module.exports: React$StatelessFunctionalComponent<*> } + +declare module 'semantic-ui-react/dist/es/modules/Modal' { + declare module.exports: React$StatelessFunctionalComponent<*> & { + Actions: React$StatelessFunctionalComponent<*>, + Content: React$StatelessFunctionalComponent<*>, + Header: React$StatelessFunctionalComponent<*> + } +} diff --git a/packages/app-home/package.json b/packages/app-explorer/package.json similarity index 67% rename from packages/app-home/package.json rename to packages/app-explorer/package.json index 2da1196dcd..d098d01467 100644 --- a/packages/app-home/package.json +++ b/packages/app-explorer/package.json @@ -1,5 +1,5 @@ { - "name": "@polkadot/app-home", + "name": "@polkadot/app-explorer", "version": "0.1.0", "main": "src/index.js", "repository": "https://github.com/polkadot-js/portal.git", @@ -13,8 +13,12 @@ "test": "react-scripts test --env=jsdom --coverage" }, "devDependencies": { - "@polkadot/rx-react": "^0.2.13", - "@polkadot/util": "^0.19.1", + "@polkadot/primitives": "^0.10.3", + "@polkadot/primitives-codec": "^0.10.3", + "@polkadot/primitives-json": "^0.10.3", + "@polkadot/rx-react": "^0.2.20", + "@polkadot/util": "^0.19.2", + "@polkadot/util-crypto": "^0.19.2", "react": "^16.3.1", "react-dom": "^16.3.1", "semantic-ui-css": "^2.3.1", diff --git a/packages/app-explorer/src/App/App.css b/packages/app-explorer/src/App/App.css new file mode 100644 index 0000000000..d5848637cc --- /dev/null +++ b/packages/app-explorer/src/App/App.css @@ -0,0 +1,27 @@ +/* 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. */ + +.explorer--App { + padding: 1em; +} + +.explorer--App-BestNumber { + font-size: 3rem; + font-weight: 100; + line-height: 3rem; + opacity: 0.5; + text-align: right; +} + +.explorer--App-BestHash { + font-size: 1.5em; + font-weight: 100; + line-height: 1.5em; + margin-bottom: 1em; + opacity: 0.5; + text-align: right; +} + +.explorer--App-BlockHeaders { +} diff --git a/packages/app-home/src/App/index.js b/packages/app-explorer/src/App/index.js similarity index 55% rename from packages/app-home/src/App/index.js rename to packages/app-explorer/src/App/index.js index 20e1d50a9e..3562deea68 100644 --- a/packages/app-home/src/App/index.js +++ b/packages/app-explorer/src/App/index.js @@ -10,18 +10,23 @@ import './App.css'; import React from 'react'; import BestNumber from '@polkadot/rx-react/BestNumber'; +import BestHash from '../BestHash'; +import BlockHeaders from '../BlockHeaders'; + type Props = BaseProps & {}; -export default function App ({ className, style }: Props) { +export default function App ({ className, style }: Props): React$Node { return (
+ +
); } diff --git a/packages/app-explorer/src/BestHash.js b/packages/app-explorer/src/BestHash.js new file mode 100644 index 0000000000..8336f80618 --- /dev/null +++ b/packages/app-explorer/src/BestHash.js @@ -0,0 +1,39 @@ +// 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 { Header } from '@polkadot/primitives/header'; +import type { BaseProps } from './types'; + +import React from 'react'; +import headerHash from '@polkadot/primitives-codec/header/hash'; +import withApiCall from '@polkadot/rx-react/with/apiCall'; +import u8aToHexShort from '@polkadot/util/u8a/toHexShort'; + +type Props = BaseProps & { + value?: Header +}; + +function BestHash ({ className, style, value }: Props): React$Node { + if (!value) { + return null; + } + + return ( +
+ {u8aToHexShort(headerHash(value))} +
+ ); +} + +export default withApiCall( + BestHash, + { + method: 'newHead', + section: 'chain' + } +); diff --git a/packages/app-explorer/src/BlockHeader/BlockHeader.css b/packages/app-explorer/src/BlockHeader/BlockHeader.css new file mode 100644 index 0000000000..ba84ddf578 --- /dev/null +++ b/packages/app-explorer/src/BlockHeader/BlockHeader.css @@ -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. */ + +.explorer--BlockHeader { + display: flex; +} + +.explorer--BlockHeader:nth-child(even) { + background: #f9f9f9; +} + +.explorer--BlockHeader > div { + padding: 0.5em; +} + +.explorer--BlockHeader > .number { + align-items: center; + box-sizing: border-box; + display: flex; + flex: 1 25%; + font-size: 3rem; + font-weight: 100; +} + +.explorer--BlockHeader > .number div { + flex: 1; + text-align: right; +} + +.explorer--BlockHeader > .details { + box-sizing: border-box; + flex: 1 75%; + text-align: left; +} + +.explorer--BlockHeader > .details > .hash { +} + +.explorer--BlockHeader > .details > .contains { + border: 0; + font-size: 0.75em; + opacity: 0.75; +} + +.explorer--BlockHeader > .details > .contains td { + padding: 0 0.25em; +} + +.explorer--BlockHeader > .details > .contains td.type { + opacity: 0.75; + text-align: right; +} + +.explorer--BlockHeader > .details > .contains td.hash { +} diff --git a/packages/app-explorer/src/BlockHeader/index.js b/packages/app-explorer/src/BlockHeader/index.js new file mode 100644 index 0000000000..4d0ddb7dfa --- /dev/null +++ b/packages/app-explorer/src/BlockHeader/index.js @@ -0,0 +1,65 @@ +// 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 { Header } from '@polkadot/primitives/header'; +import type { BaseProps } from '../types'; + +import './BlockHeader.css'; + +import React from 'react'; +import headerHash from '@polkadot/primitives-codec/header/hash'; +import u8aToHex from '@polkadot/util/u8a/toHex'; + +type Props = BaseProps & { + label?: string, + value?: Header +}; + +export default function BlockHeader ({ className, label = '#', value, style }: Props): React$Node { + if (!value) { + return null; + } + + const hash = headerHash(value); + const { extrinsicsRoot, number, parentHash, stateRoot } = value; + + return ( +
+
+
{label}{number.toString()}
+
+
+
+ {u8aToHex(hash)} +
+ + + + + + + + + + + + + + + +
parentHash + {u8aToHex(parentHash)} +
extrinsicsRoot + {u8aToHex(extrinsicsRoot)} +
stateRoot + {u8aToHex(stateRoot)} +
+
+
+ ); +} diff --git a/packages/app-explorer/src/BlockHeaders/index.js b/packages/app-explorer/src/BlockHeaders/index.js new file mode 100644 index 0000000000..164362b70f --- /dev/null +++ b/packages/app-explorer/src/BlockHeaders/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 { Header } from '@polkadot/primitives/header'; +import type { BaseProps } from '../types'; + +import React from 'react'; +import withApiCall from '@polkadot/rx-react/with/apiCall'; + +import BlockHeader from '../BlockHeader'; +import { blockHeaders } from '../subjects'; +import transform from './transform'; + +type Props = BaseProps & { + value: Array
+}; + +function BlockHeaders ({ className, style, value }: Props): React$Node { + return ( +
+ { + (value || []).map((header) => ( + + )) + } +
+ ); +} + +export default withApiCall( + BlockHeaders, + { + method: 'newHead', + section: 'chain' + }, + { + subject: blockHeaders, + transform + } +); diff --git a/packages/app-explorer/src/BlockHeaders/transform.js b/packages/app-explorer/src/BlockHeaders/transform.js new file mode 100644 index 0000000000..3a2ac75f2f --- /dev/null +++ b/packages/app-explorer/src/BlockHeaders/transform.js @@ -0,0 +1,24 @@ +// 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 { Header } from '@polkadot/primitives/header'; + +import { blockHeaders } from '../subjects'; + +export default function transform (header: Header): Array
{ + const prev = blockHeaders.getValue(); + + if (!header) { + return prev; + } + + return prev.reduce((next, value, index) => { + if (index < 9) { + next.push(value); + } + + return next; + }, [header]); +} diff --git a/packages/app-home/src/index.css b/packages/app-explorer/src/index.css similarity index 100% rename from packages/app-home/src/index.css rename to packages/app-explorer/src/index.css diff --git a/packages/app-home/src/index.js b/packages/app-explorer/src/index.js similarity index 100% rename from packages/app-home/src/index.js rename to packages/app-explorer/src/index.js diff --git a/packages/app-explorer/src/subjects.js b/packages/app-explorer/src/subjects.js new file mode 100644 index 0000000000..4e53f74f24 --- /dev/null +++ b/packages/app-explorer/src/subjects.js @@ -0,0 +1,10 @@ +// 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 { Header } from '@polkadot/primitives/header'; + +import { BehaviorSubject } from 'rxjs/BehaviorSubject'; + +export const blockHeaders: rxjs$BehaviorSubject> = new BehaviorSubject([]); diff --git a/packages/app-explorer/src/types.js b/packages/app-explorer/src/types.js new file mode 100644 index 0000000000..0bd6e60296 --- /dev/null +++ b/packages/app-explorer/src/types.js @@ -0,0 +1,11 @@ +// 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 BaseProps = { + className?: string, + style?: { + [string]: string + } +}; diff --git a/packages/app-testing/package.json b/packages/app-extrinsics/package.json similarity index 80% rename from packages/app-testing/package.json rename to packages/app-extrinsics/package.json index 02596fa776..91e45cb136 100644 --- a/packages/app-testing/package.json +++ b/packages/app-extrinsics/package.json @@ -1,5 +1,5 @@ { - "name": "@polkadot/app-testing", + "name": "@polkadot/app-extrinsics", "version": "0.1.0", "main": "src/index.js", "repository": "https://github.com/polkadot-js/portal.git", @@ -13,10 +13,10 @@ "test": "react-scripts test --env=jsdom --coverage" }, "devDependencies": { - "@polkadot/rx-react": "^0.2.13", + "@polkadot/rx-react": "^0.2.20", "@polkadot/ui-react": "^0.9.10", - "@polkadot/util": "^0.19.1", - "@polkadot/util-keyring": "^0.19.1", + "@polkadot/util": "^0.19.2", + "@polkadot/util-keyring": "^0.19.2", "prop-types": "^15.6.1", "react": "^16.3.1", "react-dom": "^16.3.1", diff --git a/packages/app-testing/src/Account.js b/packages/app-extrinsics/src/Account.js similarity index 91% rename from packages/app-testing/src/Account.js rename to packages/app-extrinsics/src/Account.js index 5a166ea3bc..380fb627f4 100644 --- a/packages/app-testing/src/Account.js +++ b/packages/app-extrinsics/src/Account.js @@ -17,12 +17,12 @@ type Props = BaseProps & { subject: rxjs$BehaviorSubject<*> }; -export default function Account ({ className, label, subject, style }: Props) { +export default function Account ({ className, label, subject, style }: Props): React$Node { const AccountBalance = withObservableParams(Balance, subject); return (
diff --git a/packages/app-testing/src/App.js b/packages/app-extrinsics/src/App.js similarity index 85% rename from packages/app-testing/src/App.js rename to packages/app-extrinsics/src/App.js index 309acb1f14..85a8c1f801 100644 --- a/packages/app-testing/src/App.js +++ b/packages/app-extrinsics/src/App.js @@ -11,19 +11,21 @@ import CallDisplay from './CallDisplay'; import CallSelect from './CallSelect'; import Nonce from './Nonce'; import Sender from './Sender'; +import Signer from './Signer'; type Props = BaseProps & {}; export default function App ({ className, style }: Props) { return (
+
); } diff --git a/packages/app-testing/src/CallDisplay/CallDisplay.css b/packages/app-extrinsics/src/CallDisplay/CallDisplay.css similarity index 64% rename from packages/app-testing/src/CallDisplay/CallDisplay.css rename to packages/app-extrinsics/src/CallDisplay/CallDisplay.css index b03e533676..4888ec57f9 100644 --- a/packages/app-testing/src/CallDisplay/CallDisplay.css +++ b/packages/app-extrinsics/src/CallDisplay/CallDisplay.css @@ -2,17 +2,17 @@ /* This software may be modified and distributed under the terms /* of the ISC license. See the LICENSE file for details. */ -.testing--CallDisplay { +.extrinsics--CallDisplay { margin-top: 1.5rem; } -.testing--CallDisplay-error { +.extrinsics--CallDisplay-error { color: red; opacity: 0.75; } -.testing--CallDisplay-Component { +.extrinsics--CallDisplay-Component { margin: 1.5rem 0; } -.testing--CallDisplay-Button {} +.extrinsics--CallDisplay-Button {} diff --git a/packages/app-testing/src/CallDisplay/Error.js b/packages/app-extrinsics/src/CallDisplay/Error.js similarity index 86% rename from packages/app-testing/src/CallDisplay/Error.js rename to packages/app-extrinsics/src/CallDisplay/Error.js index 1c76b7a78e..100201fcc4 100644 --- a/packages/app-testing/src/CallDisplay/Error.js +++ b/packages/app-extrinsics/src/CallDisplay/Error.js @@ -12,7 +12,7 @@ import React from 'react'; export default function Error ({ className, style }: BaseProps): React$Node { return (
ERROR: Invalid or unimplemented extrinsic function diff --git a/packages/app-testing/src/CallDisplay/index.js b/packages/app-extrinsics/src/CallDisplay/index.js similarity index 70% rename from packages/app-testing/src/CallDisplay/index.js rename to packages/app-extrinsics/src/CallDisplay/index.js index eebe4bebd0..40df417a3f 100644 --- a/packages/app-testing/src/CallDisplay/index.js +++ b/packages/app-extrinsics/src/CallDisplay/index.js @@ -3,11 +3,10 @@ // of the ISC license. See the LICENSE file for details. // @flow -import type { BaseProps, BaseContext } from '../types'; +import type { BaseProps } from '../types'; import './CallDisplay.css'; -import PropTypes from 'prop-types'; import React from 'react'; import Button from 'semantic-ui-react/dist/es/elements/Button'; import withObservable from '@polkadot/rx-react/with/observable'; @@ -17,7 +16,7 @@ import StakingTransfer from '../Staking/Transfer'; import StakingUnstake from '../Staking/Unstake'; import { extrinsicName } from '../subjects'; import ErrorComponent from './Error'; -import submitExtrinsic from './submit'; +import queueExtrinsic from './queue'; type ValueGetter = { getValues: () => Array @@ -33,7 +32,7 @@ const COMPONENTS = { 'staking_unstake': StakingUnstake }; -function CallDisplay ({ className, style, value }: Props, { api }: BaseContext) { +function CallDisplay ({ className, style, value }: Props): React$Node { // flowlint-next-line sketchy-null-string:off if (!value) { return null; @@ -42,17 +41,17 @@ function CallDisplay ({ className, style, value }: Props, { api }: BaseContext) const Component = COMPONENTS[value] || ErrorComponent; const onSubmit = () => { // flowlint-next-line unclear-type:off - submitExtrinsic(api, value, ((Component: any): ValueGetter).getValues()); + queueExtrinsic(value, ((Component: any): ValueGetter).getValues()); }; return (
- + + + + + ); +} + +Signer.contextTypes = { + api: PropTypes.object +}; + +export default withObservable(Signer, queueTx); diff --git a/packages/app-extrinsics/src/Signer/sign.js b/packages/app-extrinsics/src/Signer/sign.js new file mode 100644 index 0000000000..0f1fbc5f00 --- /dev/null +++ b/packages/app-extrinsics/src/Signer/sign.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 + +// TODO: Move to portal + +import type { KeyringPair } from '@polkadot/util-keyring/types'; + +const assert = require('@polkadot/util/assert'); +const u8aConcat = require('@polkadot/util/u8a/concat'); + +module.exports = function sign (sender?: ?KeyringPair, message: Uint8Array): Uint8Array { + assert(sender, 'Expected a valid sender to sign'); + + return u8aConcat( + message, + // $FlowFixMe sender has an actual value + sender.sign(message) + ); +}; diff --git a/packages/app-extrinsics/src/Signer/submit.js b/packages/app-extrinsics/src/Signer/submit.js new file mode 100644 index 0000000000..04d927fd56 --- /dev/null +++ b/packages/app-extrinsics/src/Signer/submit.js @@ -0,0 +1,27 @@ +// 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 { RxApiInterface } from '@polkadot/rx-api/types'; + +import keyring from '../keyring'; + +import sign from './sign'; + +export default function submit (api: RxApiInterface, publicKey: Uint8Array, message: Uint8Array): Promise { + return api.author + .submitExtrinsic( + sign( + keyring.getPair(publicKey), + message + ) + ) + .toPromise() + .then((result) => { + console.log('submitExtrinsic: result=', result); + }) + .catch((error) => { + console.error('submitExtrinsic: error=', error); + }); +} diff --git a/packages/app-testing/src/Staking/Stake/getValues.js b/packages/app-extrinsics/src/Staking/Stake/getValues.js similarity index 100% rename from packages/app-testing/src/Staking/Stake/getValues.js rename to packages/app-extrinsics/src/Staking/Stake/getValues.js diff --git a/packages/app-testing/src/Staking/Stake/index.js b/packages/app-extrinsics/src/Staking/Stake/index.js similarity index 87% rename from packages/app-testing/src/Staking/Stake/index.js rename to packages/app-extrinsics/src/Staking/Stake/index.js index 0bf01ba193..136cc3309a 100644 --- a/packages/app-testing/src/Staking/Stake/index.js +++ b/packages/app-extrinsics/src/Staking/Stake/index.js @@ -14,7 +14,7 @@ type Props = BaseProps & {}; function StakingStake ({ className, style }: Props) { return (
); diff --git a/packages/app-testing/src/Staking/Transfer/Amount.js b/packages/app-extrinsics/src/Staking/Transfer/Amount.js similarity index 93% rename from packages/app-testing/src/Staking/Transfer/Amount.js rename to packages/app-extrinsics/src/Staking/Transfer/Amount.js index 943b0df8d6..709b126831 100644 --- a/packages/app-testing/src/Staking/Transfer/Amount.js +++ b/packages/app-extrinsics/src/Staking/Transfer/Amount.js @@ -24,7 +24,7 @@ const onChange = (event: SyntheticEvent<*>, { value }): void => { export default function Amount ({ className, style }: Props) { return (
diff --git a/packages/app-testing/src/Staking/Transfer/getValues.js b/packages/app-extrinsics/src/Staking/Transfer/getValues.js similarity index 100% rename from packages/app-testing/src/Staking/Transfer/getValues.js rename to packages/app-extrinsics/src/Staking/Transfer/getValues.js diff --git a/packages/app-testing/src/Staking/Transfer/index.js b/packages/app-extrinsics/src/Staking/Transfer/index.js similarity index 89% rename from packages/app-testing/src/Staking/Transfer/index.js rename to packages/app-extrinsics/src/Staking/Transfer/index.js index 11c030a463..ed77d94949 100644 --- a/packages/app-testing/src/Staking/Transfer/index.js +++ b/packages/app-extrinsics/src/Staking/Transfer/index.js @@ -16,7 +16,7 @@ type Props = BaseProps & {}; function StakingTransfer ({ className, style }: Props) { return (
diff --git a/packages/app-testing/src/Staking/Transfer/subjects.js b/packages/app-extrinsics/src/Staking/Transfer/subjects.js similarity index 100% rename from packages/app-testing/src/Staking/Transfer/subjects.js rename to packages/app-extrinsics/src/Staking/Transfer/subjects.js diff --git a/packages/app-testing/src/Staking/Unstake/getValues.js b/packages/app-extrinsics/src/Staking/Unstake/getValues.js similarity index 100% rename from packages/app-testing/src/Staking/Unstake/getValues.js rename to packages/app-extrinsics/src/Staking/Unstake/getValues.js diff --git a/packages/app-testing/src/Staking/Unstake/index.js b/packages/app-extrinsics/src/Staking/Unstake/index.js similarity index 87% rename from packages/app-testing/src/Staking/Unstake/index.js rename to packages/app-extrinsics/src/Staking/Unstake/index.js index 45634ade52..2e7c2caf99 100644 --- a/packages/app-testing/src/Staking/Unstake/index.js +++ b/packages/app-extrinsics/src/Staking/Unstake/index.js @@ -14,7 +14,7 @@ type Props = BaseProps & {}; function StakingUnstake ({ className, style }: Props) { return (
); diff --git a/packages/app-testing/src/encode/index.js b/packages/app-extrinsics/src/encode/index.js similarity index 51% rename from packages/app-testing/src/encode/index.js rename to packages/app-extrinsics/src/encode/index.js index fd7cd2e96e..312c974401 100644 --- a/packages/app-testing/src/encode/index.js +++ b/packages/app-extrinsics/src/encode/index.js @@ -6,28 +6,18 @@ // TODO: Move to API import type BN from 'bn.js'; -import type { KeyringPair } from '@polkadot/util-keyring/types'; import type { Extrinsic } from '../extrinsics/types'; -const assert = require('@polkadot/util/assert'); const bnToU8a = require('@polkadot/util/bn/toU8a'); const u8aConcat = require('@polkadot/util/u8a/concat'); const encodeParams = require('./params'); -module.exports = function encode ({ index, params }: Extrinsic, sender?: ?KeyringPair, nonce: number | BN, values: Array): Uint8Array { - assert(sender, 'Expected a valid sender to extrinsic encode'); - - const encodedParams = encodeParams(values, params); - const message = u8aConcat( - // $FlowFixMe sender checked above - sender.publicKey(), +module.exports = function encode ({ index, params }: Extrinsic, publicKey: Uint8Array, nonce: number | BN, values: Array): Uint8Array { + return u8aConcat( + publicKey, bnToU8a(nonce, 64, true), index, - encodedParams + encodeParams(values, params) ); - // $FlowFixMe sender checked above - const signature = sender.sign(message); - - return u8aConcat(message, signature); }; diff --git a/packages/app-testing/src/encode/param.js b/packages/app-extrinsics/src/encode/param.js similarity index 100% rename from packages/app-testing/src/encode/param.js rename to packages/app-extrinsics/src/encode/param.js diff --git a/packages/app-testing/src/encode/params.js b/packages/app-extrinsics/src/encode/params.js similarity index 100% rename from packages/app-testing/src/encode/params.js rename to packages/app-extrinsics/src/encode/params.js diff --git a/packages/app-testing/src/extrinsics/consensus.js b/packages/app-extrinsics/src/extrinsics/consensus.js similarity index 85% rename from packages/app-testing/src/extrinsics/consensus.js rename to packages/app-extrinsics/src/extrinsics/consensus.js index 6a24e2923f..691f79d5c1 100644 --- a/packages/app-testing/src/extrinsics/consensus.js +++ b/packages/app-extrinsics/src/extrinsics/consensus.js @@ -6,4 +6,6 @@ import type { ExtrinsicsBasic } from './types'; module.exports = ({ + description: 'Consensus', + methods: {} }: ExtrinsicsBasic); diff --git a/packages/app-testing/src/extrinsics/council.js b/packages/app-extrinsics/src/extrinsics/council.js similarity index 86% rename from packages/app-testing/src/extrinsics/council.js rename to packages/app-extrinsics/src/extrinsics/council.js index 6a24e2923f..9353f7f0d4 100644 --- a/packages/app-testing/src/extrinsics/council.js +++ b/packages/app-extrinsics/src/extrinsics/council.js @@ -6,4 +6,6 @@ import type { ExtrinsicsBasic } from './types'; module.exports = ({ + description: 'Council', + methods: {} }: ExtrinsicsBasic); diff --git a/packages/app-testing/src/extrinsics/councilVoting.js b/packages/app-extrinsics/src/extrinsics/councilVoting.js similarity index 84% rename from packages/app-testing/src/extrinsics/councilVoting.js rename to packages/app-extrinsics/src/extrinsics/councilVoting.js index 6a24e2923f..cb427869fd 100644 --- a/packages/app-testing/src/extrinsics/councilVoting.js +++ b/packages/app-extrinsics/src/extrinsics/councilVoting.js @@ -6,4 +6,6 @@ import type { ExtrinsicsBasic } from './types'; module.exports = ({ + description: 'Council Voting', + methods: {} }: ExtrinsicsBasic); diff --git a/packages/app-testing/src/extrinsics/democracy.js b/packages/app-extrinsics/src/extrinsics/democracy.js similarity index 85% rename from packages/app-testing/src/extrinsics/democracy.js rename to packages/app-extrinsics/src/extrinsics/democracy.js index 6a24e2923f..504c5f3267 100644 --- a/packages/app-testing/src/extrinsics/democracy.js +++ b/packages/app-extrinsics/src/extrinsics/democracy.js @@ -6,4 +6,6 @@ import type { ExtrinsicsBasic } from './types'; module.exports = ({ + description: 'Democracy', + methods: {} }: ExtrinsicsBasic); diff --git a/packages/app-extrinsics/src/extrinsics/index.js b/packages/app-extrinsics/src/extrinsics/index.js new file mode 100644 index 0000000000..81dc8daf0d --- /dev/null +++ b/packages/app-extrinsics/src/extrinsics/index.js @@ -0,0 +1,75 @@ +// 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 { Extrinsic, Extrinsics, ExtrinsicsBasic, ExtrinsicsMap, ExtrinsicSection } 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 map: { [string]: ExtrinsicsBasic } = { + consensus, // 0 + session, // 1 + staking, // 2 + democracy, // 3 + council, // 4 + councilVoting // 5 +}; +const sectionNames = Object.keys(map); +const extrinsics: Extrinsics = ({ + sections: [] +}: $Shape); +const extrinsicsMap: ExtrinsicsMap = {}; + +sectionNames.reduce((sections: Array, sectionName: string, _index) => { + const sectionSource = map[sectionName]; + const sectionIndex = bnToU8a(_index, 8); + const methodNames = Object.keys(sectionSource.methods); + + if (!methodNames.length) { + return sections; + } + + const section: ExtrinsicSection = { + description: sectionSource.description, + 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); + + 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-testing/src/extrinsics/session.js b/packages/app-extrinsics/src/extrinsics/session.js similarity index 86% rename from packages/app-testing/src/extrinsics/session.js rename to packages/app-extrinsics/src/extrinsics/session.js index 6a24e2923f..97a279fb0c 100644 --- a/packages/app-testing/src/extrinsics/session.js +++ b/packages/app-extrinsics/src/extrinsics/session.js @@ -6,4 +6,6 @@ import type { ExtrinsicsBasic } from './types'; module.exports = ({ + description: 'Session', + methods: {} }: ExtrinsicsBasic); diff --git a/packages/app-extrinsics/src/extrinsics/staking.js b/packages/app-extrinsics/src/extrinsics/staking.js new file mode 100644 index 0000000000..6f082cf38b --- /dev/null +++ b/packages/app-extrinsics/src/extrinsics/staking.js @@ -0,0 +1,27 @@ +// 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 { 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: [] + } + } +}: ExtrinsicsBasic); diff --git a/packages/app-testing/src/extrinsics/types.js b/packages/app-extrinsics/src/extrinsics/types.js similarity index 56% rename from packages/app-testing/src/extrinsics/types.js rename to packages/app-extrinsics/src/extrinsics/types.js index 3567493894..cbc813504d 100644 --- a/packages/app-testing/src/extrinsics/types.js +++ b/packages/app-extrinsics/src/extrinsics/types.js @@ -9,19 +9,35 @@ export type Extrinsic$Params = Array; export type ExtrinsicBasic = { description: string, + index: number, params: Extrinsic$Params } -export type Extrinsic = ExtrinsicBasic & { +export type ExtrinsicsBasic = { + description: string, + methods: { + [string]: ExtrinsicBasic + } +} + +export type Extrinsic = { + description: string, index: Uint8Array, - indexHex: string, + name: string, + params: Extrinsic$Params +}; + +export type ExtrinsicSection = { + description: string, + methods: Array, name: string }; export type Extrinsics = { - [string]: Extrinsic + sections: Array, + get: (sectionMethod: string) => Extrinsic } -export type ExtrinsicsBasic = { - [string]: ExtrinsicBasic -} +export type ExtrinsicsMap = { + [string]: Extrinsic +}; diff --git a/packages/app-testing/src/index.css b/packages/app-extrinsics/src/index.css similarity index 68% rename from packages/app-testing/src/index.css rename to packages/app-extrinsics/src/index.css index 648fe00407..5fb4d78820 100644 --- a/packages/app-testing/src/index.css +++ b/packages/app-extrinsics/src/index.css @@ -2,12 +2,16 @@ /* This software may be modified and distributed under the terms /* of the ISC license. See the LICENSE file for details. */ -.testing--full, -.testing--split { +.extrinsics--App { + padding: 1em; +} + +.extrinsics--full, +.extrinsics--split { width: 100%; } -.testing--split { +.extrinsics--split { display:flex; flex-wrap:wrap; flex-direction:row; @@ -15,27 +19,27 @@ align-items:stretch; } -.testing--split > div { +.extrinsics--split > div { box-sizing: border-box; padding-right: 0.5rem; } -.testing--split > div.full { +.extrinsics--split > div.full { flex: 0 100%; min-width: 0; } -.testing--split > div.large { +.extrinsics--split > div.large { flex: 0 75%; min-width: 0; } -.testing--split > div.medium { +.extrinsics--split > div.medium { flex: 0 50%; min-width: 0; } -.testing--split > div.small { +.extrinsics--split > div.small { flex: 0 25%; min-width: 0; } diff --git a/packages/app-testing/src/index.js b/packages/app-extrinsics/src/index.js similarity index 100% rename from packages/app-testing/src/index.js rename to packages/app-extrinsics/src/index.js diff --git a/packages/app-testing/src/keyring.js b/packages/app-extrinsics/src/keyring.js similarity index 100% rename from packages/app-testing/src/keyring.js rename to packages/app-extrinsics/src/keyring.js diff --git a/packages/app-extrinsics/src/subjects.js b/packages/app-extrinsics/src/subjects.js new file mode 100644 index 0000000000..8f8dad96a4 --- /dev/null +++ b/packages/app-extrinsics/src/subjects.js @@ -0,0 +1,15 @@ +// 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-testing/src/types.js b/packages/app-extrinsics/src/types.js similarity index 80% rename from packages/app-testing/src/types.js rename to packages/app-extrinsics/src/types.js index b76391d084..bcc16e2ca7 100644 --- a/packages/app-testing/src/types.js +++ b/packages/app-extrinsics/src/types.js @@ -15,3 +15,9 @@ export type BaseProps = { export type BaseContext = { api: RxApiInterface }; + +export type QueueTx = { + message: Uint8Array, + method: string, + publicKey: Uint8Array +}; diff --git a/packages/app-testing/src/CallDisplay/submit.js b/packages/app-testing/src/CallDisplay/submit.js deleted file mode 100644 index 6b9f784e81..0000000000 --- a/packages/app-testing/src/CallDisplay/submit.js +++ /dev/null @@ -1,32 +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 { RxApiInterface } from '@polkadot/rx-api/types'; - -import encode from '../encode'; -import extrinsics from '../extrinsics'; -import keyring from '../keyring'; -import { senderAddr, senderIndex } from '../subjects'; - -export default function submit (api: RxApiInterface, method: string, values: Array): void { - // TODO: Display some progress once we have a subscription - api.author - .submitExtrinsic( - encode( - extrinsics[method], - // flowlint-next-line unclear-type:off - keyring.getPair(((senderAddr.getValue(): any): Uint8Array)), - senderIndex.getValue() || 0, - values - ) - ) - .toPromise() - .then((result) => { - console.log('submitExtrinsic: result=', result); - }) - .catch((error) => { - console.error('submitExtrinsic: error=', error); - }); -} diff --git a/packages/app-testing/src/extrinsics/index.js b/packages/app-testing/src/extrinsics/index.js deleted file mode 100644 index 5bbf969063..0000000000 --- a/packages/app-testing/src/extrinsics/index.js +++ /dev/null @@ -1,56 +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 - -// TODO: Move to API - -import type { Extrinsics, ExtrinsicsBasic } from './types'; - -const bnToU8a = require('@polkadot/util/bn/toU8a'); -const u8aConcat = require('@polkadot/util/u8a/concat'); -const u8aToHex = require('@polkadot/util/u8a/toHex'); - -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 all: { [string]: ExtrinsicsBasic } = { - consensus, // 0 - session, // 1 - staking, // 2 - democracy, // 3 - council, // 4 - councilVoting // 5 -}; - -const flattenned: Extrinsics = Object - .keys(all) - .reduce((flat, sectionName, _index) => { - const section = all[sectionName]; - const sectionIndex = bnToU8a(_index, 8); - - return Object - .keys(section) - .reduce((flat, method, _index) => { - const name = `${sectionName}_${method}`; - const methodIndex = bnToU8a(_index, 8); - const index = u8aConcat(sectionIndex, methodIndex); - const indexHex = u8aToHex(index); - - flat[name] = { - index, - indexHex, - name, - // flowlint-next-line inexact-spread:off - ...section[method] - }; - - return flat; - }, flat); - }, ({}: $Shape)); - -module.exports = flattenned; diff --git a/packages/app-testing/src/extrinsics/staking.js b/packages/app-testing/src/extrinsics/staking.js deleted file mode 100644 index 6de9485c73..0000000000 --- a/packages/app-testing/src/extrinsics/staking.js +++ /dev/null @@ -1,21 +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 { ExtrinsicsBasic } from './types'; - -module.exports = ({ - transfer: { - description: 'Staking Transfer', - params: ['AccountId', 'Balance'] - }, - stake: { - description: 'Stake', - params: [] - }, - unstake: { - description: 'Unstake', - params: [] - } -}: ExtrinsicsBasic); diff --git a/packages/app-testing/src/subjects.js b/packages/app-testing/src/subjects.js deleted file mode 100644 index 8661bbd97c..0000000000 --- a/packages/app-testing/src/subjects.js +++ /dev/null @@ -1,13 +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 { BehaviorSubject } from 'rxjs/BehaviorSubject'; - -import BN from 'bn.js'; - -export const extrinsicName = new BehaviorSubject(); -export const recipientAddr = new BehaviorSubject(); -export const senderAddr = new BehaviorSubject(); -export const senderIndex = new BehaviorSubject(new BN(0)); diff --git a/packages/portal/package.json b/packages/portal/package.json index d1ee33a290..7469156be0 100644 --- a/packages/portal/package.json +++ b/packages/portal/package.json @@ -14,9 +14,9 @@ "test": "react-scripts test --env=jsdom --coverage" }, "devDependencies": { - "@polkadot/app-home": "^0.1.0", - "@polkadot/app-testing": "^0.1.0", - "@polkadot/rx-react": "^0.2.13", + "@polkadot/app-explorer": "^0.1.0", + "@polkadot/app-extrinsics": "^0.1.0", + "@polkadot/rx-react": "^0.2.20", "@polkadot/ui-react": "^0.9.10", "i18next": "^11.1.1", "i18next-browser-languagedetector": "^2.2.0", diff --git a/packages/portal/src/Content/Content.css b/packages/portal/src/Content/Content.css index 69b786f33d..19ca726232 100644 --- a/packages/portal/src/Content/Content.css +++ b/packages/portal/src/Content/Content.css @@ -3,7 +3,14 @@ /* of the ISC license. See the LICENSE file for details. */ .portal--Content { - padding: 1em; - text-align: left; + height: 100%; + width: 100%; +} + +.portal--Content-Frame { + border: none; + box-sizing: border-box; + height: 100%; + overflow-y: scroll; width: 100%; } diff --git a/packages/portal/src/Content/index.js b/packages/portal/src/Content/index.js index fc84c92123..c664036de8 100644 --- a/packages/portal/src/Content/index.js +++ b/packages/portal/src/Content/index.js @@ -3,36 +3,37 @@ // of the ISC license. See the LICENSE file for details. // @flow -import type { BaseProps } from '../types'; +import type { BaseContext, BaseProps } from '../types'; import './Content.css'; +import PropTypes from 'prop-types'; import React from 'react'; import { translate } from 'react-i18next'; -import { Route } from 'react-router-dom'; -import routes from '../routes'; +import routing from '../routing'; type Props = BaseProps & {}; -export default translate(['portal'])( - function Content ({ className, style }: Props) { - return ( -
- { - routes.map(({ component, isExact, name, path }) => ( - - )) - } -
- ); - } -); +function Content ({ className, style }: Props, { router: { route: { location } } }: BaseContext) { + const app = location.pathname.slice(1) || routing.default; + + return ( +
+