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
This commit is contained in:
parent
f4deeca850
commit
d589964bf2
@ -12,5 +12,5 @@ all=warn
|
||||
|
||||
[options]
|
||||
include_warnings=true
|
||||
module.name_mapper='^@polkadot/content-\(accounts\|home\|settings\)\(.*\)$' -> '<PROJECT_ROOT>/packages/content-\1/src\2'
|
||||
module.name_mapper='^@polkadot/app-\(accounts\|explorer\|extrinsics\|home\|settings\)\(.*\)$' -> '<PROJECT_ROOT>/packages/app-\1/src\2'
|
||||
module.name_mapper='^@polkadot/portal\(.*\)$' -> '<PROJECT_ROOT>/packages/portal/src\1'
|
||||
|
||||
8
flow-typed/semantic-ui-react.js
vendored
8
flow-typed/semantic-ui-react.js
vendored
@ -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<*>
|
||||
}
|
||||
}
|
||||
|
||||
@ -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",
|
||||
27
packages/app-explorer/src/App/App.css
Normal file
27
packages/app-explorer/src/App/App.css
Normal file
@ -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 {
|
||||
}
|
||||
@ -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 (
|
||||
<div
|
||||
className={['home--App', className].join(' ')}
|
||||
className={['explorer--App', className].join(' ')}
|
||||
style={style}
|
||||
>
|
||||
<BestNumber
|
||||
className='home--App-BestNumber'
|
||||
label='#'
|
||||
className='explorer--App-BestNumber'
|
||||
label='best #'
|
||||
/>
|
||||
<BestHash className='explorer--App-BestHash' />
|
||||
<BlockHeaders />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
39
packages/app-explorer/src/BestHash.js
Normal file
39
packages/app-explorer/src/BestHash.js
Normal file
@ -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 (
|
||||
<div
|
||||
className={['explorer--BestHash', className].join(' ')}
|
||||
style={style}
|
||||
>
|
||||
{u8aToHexShort(headerHash(value))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default withApiCall(
|
||||
BestHash,
|
||||
{
|
||||
method: 'newHead',
|
||||
section: 'chain'
|
||||
}
|
||||
);
|
||||
56
packages/app-explorer/src/BlockHeader/BlockHeader.css
Normal file
56
packages/app-explorer/src/BlockHeader/BlockHeader.css
Normal file
@ -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 {
|
||||
}
|
||||
65
packages/app-explorer/src/BlockHeader/index.js
Normal file
65
packages/app-explorer/src/BlockHeader/index.js
Normal file
@ -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 (
|
||||
<div
|
||||
className={['explorer--BlockHeader', className].join(' ')}
|
||||
style={style}
|
||||
>
|
||||
<div className='number'>
|
||||
<div>{label}{number.toString()}</div>
|
||||
</div>
|
||||
<div className='details'>
|
||||
<div className='hash'>
|
||||
{u8aToHex(hash)}
|
||||
</div>
|
||||
<table className='contains'>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className='type'>parentHash</td>
|
||||
<td className='hash'>
|
||||
{u8aToHex(parentHash)}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='type'>extrinsicsRoot</td>
|
||||
<td className='hash'>
|
||||
{u8aToHex(extrinsicsRoot)}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className='type'>stateRoot</td>
|
||||
<td className='hash'>
|
||||
{u8aToHex(stateRoot)}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
48
packages/app-explorer/src/BlockHeaders/index.js
Normal file
48
packages/app-explorer/src/BlockHeaders/index.js
Normal file
@ -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<Header>
|
||||
};
|
||||
|
||||
function BlockHeaders ({ className, style, value }: Props): React$Node {
|
||||
return (
|
||||
<div
|
||||
className={['explorer--BlockHeaders', className].join(' ')}
|
||||
style={style}
|
||||
>
|
||||
{
|
||||
(value || []).map((header) => (
|
||||
<BlockHeader
|
||||
value={header}
|
||||
key={header.number.toString()}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default withApiCall(
|
||||
BlockHeaders,
|
||||
{
|
||||
method: 'newHead',
|
||||
section: 'chain'
|
||||
},
|
||||
{
|
||||
subject: blockHeaders,
|
||||
transform
|
||||
}
|
||||
);
|
||||
24
packages/app-explorer/src/BlockHeaders/transform.js
Normal file
24
packages/app-explorer/src/BlockHeaders/transform.js
Normal file
@ -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<Header> {
|
||||
const prev = blockHeaders.getValue();
|
||||
|
||||
if (!header) {
|
||||
return prev;
|
||||
}
|
||||
|
||||
return prev.reduce((next, value, index) => {
|
||||
if (index < 9) {
|
||||
next.push(value);
|
||||
}
|
||||
|
||||
return next;
|
||||
}, [header]);
|
||||
}
|
||||
10
packages/app-explorer/src/subjects.js
Normal file
10
packages/app-explorer/src/subjects.js
Normal file
@ -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<Array<Header>> = new BehaviorSubject([]);
|
||||
11
packages/app-explorer/src/types.js
Normal file
11
packages/app-explorer/src/types.js
Normal file
@ -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
|
||||
}
|
||||
};
|
||||
@ -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",
|
||||
@ -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 (
|
||||
<div
|
||||
className={['testing--Account', 'testing--split', className].join(' ')}
|
||||
className={['extrinsics--Account', 'extrinsics--split', className].join(' ')}
|
||||
style={style}
|
||||
>
|
||||
<div className='large'>
|
||||
@ -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 (
|
||||
<div
|
||||
className={['testing--App', className].join(' ')}
|
||||
className={['extrinsics--App', className].join(' ')}
|
||||
style={style}
|
||||
>
|
||||
<Sender />
|
||||
<CallSelect />
|
||||
<Nonce />
|
||||
<CallDisplay />
|
||||
<Signer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -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 {}
|
||||
@ -12,7 +12,7 @@ import React from 'react';
|
||||
export default function Error ({ className, style }: BaseProps): React$Node {
|
||||
return (
|
||||
<div
|
||||
className={['testing--CallDisplay-error', className].join(' ')}
|
||||
className={['extrinsics--CallDisplay-error', className].join(' ')}
|
||||
style={style}
|
||||
>
|
||||
ERROR: Invalid or unimplemented extrinsic function
|
||||
@ -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<mixed>
|
||||
@ -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 (
|
||||
<div
|
||||
className={['testing--CallDisplay', className].join(' ')}
|
||||
className={['extrinsics--CallDisplay', className].join(' ')}
|
||||
style={style}
|
||||
>
|
||||
<Component className='testing--CallDisplay-Component' />
|
||||
<Component className='extrinsics--CallDisplay-Component' />
|
||||
<Button
|
||||
className='testing--CallDisplay-Execute'
|
||||
className='extrinsics--CallDisplay-Execute'
|
||||
onClick={onSubmit}
|
||||
primary
|
||||
>
|
||||
@ -62,8 +61,4 @@ function CallDisplay ({ className, style, value }: Props, { api }: BaseContext)
|
||||
);
|
||||
}
|
||||
|
||||
CallDisplay.contextTypes = {
|
||||
api: PropTypes.object
|
||||
};
|
||||
|
||||
export default withObservable(CallDisplay, extrinsicName);
|
||||
25
packages/app-extrinsics/src/CallDisplay/queue.js
Normal file
25
packages/app-extrinsics/src/CallDisplay/queue.js
Normal file
@ -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 encode from '../encode';
|
||||
import extrinsics from '../extrinsics';
|
||||
import { senderAddr, senderIndex, queueTx } from '../subjects';
|
||||
|
||||
export default function queue (method: string, values: Array<mixed>): 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
|
||||
});
|
||||
}
|
||||
@ -2,12 +2,8 @@
|
||||
/* This software may be modified and distributed under the terms
|
||||
/* of the ISC license. See the LICENSE file for details. */
|
||||
|
||||
.home--App {}
|
||||
.extrinsics--CallSelect {}
|
||||
|
||||
.home--App-BestNumber {
|
||||
font-size: 3rem;
|
||||
line-height: 3rem;
|
||||
margin-bottom: 1rem;
|
||||
opacity: 0.5;
|
||||
text-align: right;
|
||||
.extrinsics--CallSelect-indent > span.text {
|
||||
padding-left: 1.25em;
|
||||
}
|
||||
@ -3,14 +3,16 @@
|
||||
// of the ISC license. See the LICENSE file for details.
|
||||
// @flow
|
||||
|
||||
import type { BaseProps } from './types';
|
||||
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 { extrinsicName } from './subjects';
|
||||
import extrinsics from './extrinsics';
|
||||
import { extrinsicName } from '../subjects';
|
||||
import extrinsics from '../extrinsics';
|
||||
|
||||
type Props = BaseProps & {};
|
||||
|
||||
@ -19,15 +21,28 @@ const onChange = (event: SyntheticEvent<*>, { value }): void => {
|
||||
extrinsicName.next(value);
|
||||
};
|
||||
|
||||
const options = Object.keys(extrinsics).map((value) => ({
|
||||
text: extrinsics[value].description,
|
||||
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
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
export default function CallSelect ({ className, style }: Props) {
|
||||
return (
|
||||
<div
|
||||
className={['testing--CallSelect', 'testing--split', className].join(' ')}
|
||||
className={['extrinsics--CallSelect', 'extrinsics--split', className].join(' ')}
|
||||
style={style}
|
||||
>
|
||||
<div className='large'>
|
||||
@ -17,7 +17,7 @@ type Props = BaseProps & {
|
||||
subject: rxjs$Subject<*>
|
||||
};
|
||||
|
||||
const testOptions = keyring.getPairs().map((pair) => {
|
||||
const options = keyring.getPairs().map((pair) => {
|
||||
const publicKey = pair.publicKey();
|
||||
|
||||
return {
|
||||
@ -44,7 +44,7 @@ export default function InputAddress (props: Props): React$Node {
|
||||
{...props}
|
||||
className={['ui--InputAddress', props.className].join(' ')}
|
||||
selection
|
||||
options={testOptions}
|
||||
options={options}
|
||||
onChange={onChange}
|
||||
/>
|
||||
);
|
||||
@ -9,29 +9,17 @@ import React from 'react';
|
||||
import Label from 'semantic-ui-react/dist/es/elements/Label';
|
||||
import RxNonce from '@polkadot/rx-react/Nonce';
|
||||
import withObservableParams from '@polkadot/rx-react/with/observableParams';
|
||||
import u8aToBn from '@polkadot/util/u8a/toBn';
|
||||
|
||||
import { senderAddr, senderIndex } from './subjects';
|
||||
|
||||
type Props = BaseProps & {};
|
||||
|
||||
const SenderNonce = withObservableParams(RxNonce, senderAddr);
|
||||
const onNonceChange = (value): void => {
|
||||
// flowlint-next-line sketchy-null-mixed:off
|
||||
if (!value || value.length !== 8) {
|
||||
return;
|
||||
}
|
||||
|
||||
senderIndex.next(
|
||||
// flowlint-next-line unclear-type:off
|
||||
u8aToBn(((value: any): Uint8Array), true)
|
||||
);
|
||||
};
|
||||
|
||||
export default function Nonce ({ className, style }: Props) {
|
||||
return (
|
||||
<div
|
||||
className={['testing--split', className].join(' ')}
|
||||
className={['extrinsics--split', className].join(' ')}
|
||||
style={style}
|
||||
>
|
||||
<div className='small'>
|
||||
@ -39,7 +27,7 @@ export default function Nonce ({ className, style }: Props) {
|
||||
<SenderNonce
|
||||
className='ui disabled dropdown selection'
|
||||
classNameUpdated='hasUpdated'
|
||||
onChange={onNonceChange}
|
||||
subject={senderIndex}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@ -16,7 +16,7 @@ export default function Recipient (props: Props) {
|
||||
return (
|
||||
<Account
|
||||
{...props}
|
||||
className={['testing--Recipient', props.className].join(' ')}
|
||||
className={['extrinsics--Recipient', props.className].join(' ')}
|
||||
label='to the recipient'
|
||||
subject={recipientAddr}
|
||||
/>
|
||||
@ -16,7 +16,7 @@ export default function Sender (props: Props) {
|
||||
return (
|
||||
<Account
|
||||
{...props}
|
||||
className={['testing--Sender', props.className].join(' ')}
|
||||
className={['extrinsics--Sender', props.className].join(' ')}
|
||||
label='using the selected account'
|
||||
subject={senderAddr}
|
||||
/>
|
||||
37
packages/app-extrinsics/src/Signer/Extrinsic.js
Normal file
37
packages/app-extrinsics/src/Signer/Extrinsic.js
Normal file
@ -0,0 +1,37 @@
|
||||
// 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 React from 'react';
|
||||
import Modal from 'semantic-ui-react/dist/es/modules/Modal';
|
||||
import IdentityIcon from '@polkadot/ui-react/IdentityIcon';
|
||||
import u8aToHex from '@polkadot/util/u8a/toHex';
|
||||
import u8aToHexShort from '@polkadot/util/u8a/toHexShort';
|
||||
|
||||
type Props = BaseProps & {
|
||||
value: QueueTx
|
||||
};
|
||||
|
||||
export default function Extrinsic ({ className, style, value: { message, method, publicKey } }: Props): React$Node {
|
||||
return (
|
||||
<Modal.Content
|
||||
className={['extrinsics--Signer-Extrinsic', className].join(' ')}
|
||||
style={style}
|
||||
>
|
||||
<div className='body'>
|
||||
<IdentityIcon
|
||||
address={publicKey}
|
||||
className='icon'
|
||||
/>
|
||||
<div className='expanded'>
|
||||
<p>You are about to sign a message from <span className='code'>{u8aToHexShort(publicKey)}</span> calling <span className='code'>{method}</span></p>
|
||||
<p>The encoded message to be signed contains the data</p>
|
||||
<p className='code'>{u8aToHex(message)}</p>
|
||||
</div>
|
||||
</div>
|
||||
</Modal.Content>
|
||||
);
|
||||
}
|
||||
28
packages/app-extrinsics/src/Signer/Signer.css
Normal file
28
packages/app-extrinsics/src/Signer/Signer.css
Normal file
@ -0,0 +1,28 @@
|
||||
/* 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--Signer {}
|
||||
|
||||
.extrinsics--Signer-Extrinsic {}
|
||||
|
||||
.extrinsics--Signer-Extrinsic > .body {
|
||||
align-content: center;
|
||||
display: flex;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
.extrinsics--Signer-Extrinsic > .body > .expanded {
|
||||
padding-left: 1.5em;
|
||||
}
|
||||
|
||||
.extrinsics--Signer-Extrinsic > .body > .expanded .code {
|
||||
background: #f5f5f5;
|
||||
font-family: monospace;
|
||||
margin: 0 0.25em;
|
||||
overflow-wrap: break-word;
|
||||
padding: 0.25em 0.5em;
|
||||
word-break: break-all;
|
||||
word-break: break-word;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
64
packages/app-extrinsics/src/Signer/index.js
Normal file
64
packages/app-extrinsics/src/Signer/index.js
Normal file
@ -0,0 +1,64 @@
|
||||
// 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 { BaseContext, BaseProps, QueueTx } from '../types';
|
||||
|
||||
import './Signer.css';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
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 withObservable from '@polkadot/rx-react/with/observable';
|
||||
|
||||
import { queueTx } from '../subjects';
|
||||
import Extrinsic from './Extrinsic';
|
||||
import submitExtrinsic from './submit';
|
||||
|
||||
type Props = BaseProps & {
|
||||
value?: QueueTx
|
||||
};
|
||||
|
||||
function Signer ({ className, style, value }: Props, { api }: BaseContext): React$Node {
|
||||
if (!value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const onClose = () => {
|
||||
queueTx.next();
|
||||
};
|
||||
const onSign = () => {
|
||||
submitExtrinsic(api, value.publicKey, value.message).then(onClose);
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
className={['extrinsics--Signer', className].join(' ')}
|
||||
dimmer='inverted'
|
||||
open
|
||||
style={style}
|
||||
>
|
||||
<Modal.Header>Sign and submit</Modal.Header>
|
||||
<Extrinsic value={value} />
|
||||
<Modal.Actions>
|
||||
<Button onClick={onClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
onClick={onSign}
|
||||
primary
|
||||
>
|
||||
Sign and Submit
|
||||
</Button>
|
||||
</Modal.Actions>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
Signer.contextTypes = {
|
||||
api: PropTypes.object
|
||||
};
|
||||
|
||||
export default withObservable(Signer, queueTx);
|
||||
21
packages/app-extrinsics/src/Signer/sign.js
Normal file
21
packages/app-extrinsics/src/Signer/sign.js
Normal file
@ -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)
|
||||
);
|
||||
};
|
||||
27
packages/app-extrinsics/src/Signer/submit.js
Normal file
27
packages/app-extrinsics/src/Signer/submit.js
Normal file
@ -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<void> {
|
||||
return api.author
|
||||
.submitExtrinsic(
|
||||
sign(
|
||||
keyring.getPair(publicKey),
|
||||
message
|
||||
)
|
||||
)
|
||||
.toPromise()
|
||||
.then((result) => {
|
||||
console.log('submitExtrinsic: result=', result);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('submitExtrinsic: error=', error);
|
||||
});
|
||||
}
|
||||
@ -14,7 +14,7 @@ type Props = BaseProps & {};
|
||||
function StakingStake ({ className, style }: Props) {
|
||||
return (
|
||||
<div
|
||||
className={['testing--StakingStake', className].join(' ')}
|
||||
className={['extrinsics--StakingStake', className].join(' ')}
|
||||
style={style}
|
||||
/>
|
||||
);
|
||||
@ -24,7 +24,7 @@ const onChange = (event: SyntheticEvent<*>, { value }): void => {
|
||||
export default function Amount ({ className, style }: Props) {
|
||||
return (
|
||||
<div
|
||||
className={['testing--split', className].join(' ')}
|
||||
className={['extrinsics--split', className].join(' ')}
|
||||
style={style}
|
||||
>
|
||||
<div className='small'>
|
||||
@ -16,7 +16,7 @@ type Props = BaseProps & {};
|
||||
function StakingTransfer ({ className, style }: Props) {
|
||||
return (
|
||||
<div
|
||||
className={['testing--StakingTransfer', className].join(' ')}
|
||||
className={['extrinsics--StakingTransfer', className].join(' ')}
|
||||
style={style}
|
||||
>
|
||||
<Amount />
|
||||
@ -14,7 +14,7 @@ type Props = BaseProps & {};
|
||||
function StakingUnstake ({ className, style }: Props) {
|
||||
return (
|
||||
<div
|
||||
className={['testing--StakingUnstake', className].join(' ')}
|
||||
className={['extrinsics--StakingUnstake', className].join(' ')}
|
||||
style={style}
|
||||
/>
|
||||
);
|
||||
@ -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<mixed>): 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<mixed>): 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);
|
||||
};
|
||||
@ -6,4 +6,6 @@
|
||||
import type { ExtrinsicsBasic } from './types';
|
||||
|
||||
module.exports = ({
|
||||
description: 'Consensus',
|
||||
methods: {}
|
||||
}: ExtrinsicsBasic);
|
||||
@ -6,4 +6,6 @@
|
||||
import type { ExtrinsicsBasic } from './types';
|
||||
|
||||
module.exports = ({
|
||||
description: 'Council',
|
||||
methods: {}
|
||||
}: ExtrinsicsBasic);
|
||||
@ -6,4 +6,6 @@
|
||||
import type { ExtrinsicsBasic } from './types';
|
||||
|
||||
module.exports = ({
|
||||
description: 'Council Voting',
|
||||
methods: {}
|
||||
}: ExtrinsicsBasic);
|
||||
@ -6,4 +6,6 @@
|
||||
import type { ExtrinsicsBasic } from './types';
|
||||
|
||||
module.exports = ({
|
||||
description: 'Democracy',
|
||||
methods: {}
|
||||
}: ExtrinsicsBasic);
|
||||
75
packages/app-extrinsics/src/extrinsics/index.js
Normal file
75
packages/app-extrinsics/src/extrinsics/index.js
Normal file
@ -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<Extrinsics>);
|
||||
const extrinsicsMap: ExtrinsicsMap = {};
|
||||
|
||||
sectionNames.reduce((sections: Array<ExtrinsicSection>, 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<Extrinsic>, 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;
|
||||
@ -6,4 +6,6 @@
|
||||
import type { ExtrinsicsBasic } from './types';
|
||||
|
||||
module.exports = ({
|
||||
description: 'Session',
|
||||
methods: {}
|
||||
}: ExtrinsicsBasic);
|
||||
27
packages/app-extrinsics/src/extrinsics/staking.js
Normal file
27
packages/app-extrinsics/src/extrinsics/staking.js
Normal file
@ -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);
|
||||
@ -9,19 +9,35 @@ export type Extrinsic$Params = Array<Extrinsic$Type>;
|
||||
|
||||
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<Extrinsic>,
|
||||
name: string
|
||||
};
|
||||
|
||||
export type Extrinsics = {
|
||||
[string]: Extrinsic
|
||||
sections: Array<ExtrinsicSection>,
|
||||
get: (sectionMethod: string) => Extrinsic
|
||||
}
|
||||
|
||||
export type ExtrinsicsBasic = {
|
||||
[string]: ExtrinsicBasic
|
||||
}
|
||||
export type ExtrinsicsMap = {
|
||||
[string]: Extrinsic
|
||||
};
|
||||
@ -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;
|
||||
}
|
||||
15
packages/app-extrinsics/src/subjects.js
Normal file
15
packages/app-extrinsics/src/subjects.js
Normal file
@ -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<?string> = new BehaviorSubject();
|
||||
export const recipientAddr: rxjs$BehaviorSubject<?Uint8Array> = new BehaviorSubject();
|
||||
export const queueTx: rxjs$BehaviorSubject<?QueueTx> = new BehaviorSubject();
|
||||
export const senderAddr: rxjs$BehaviorSubject<?Uint8Array> = new BehaviorSubject();
|
||||
export const senderIndex: rxjs$BehaviorSubject<BN> = new BehaviorSubject(new BN(0));
|
||||
@ -15,3 +15,9 @@ export type BaseProps = {
|
||||
export type BaseContext = {
|
||||
api: RxApiInterface
|
||||
};
|
||||
|
||||
export type QueueTx = {
|
||||
message: Uint8Array,
|
||||
method: string,
|
||||
publicKey: Uint8Array
|
||||
};
|
||||
@ -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<mixed>): 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);
|
||||
});
|
||||
}
|
||||
@ -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<Extrinsics>));
|
||||
|
||||
module.exports = flattenned;
|
||||
@ -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);
|
||||
@ -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));
|
||||
@ -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",
|
||||
|
||||
@ -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%;
|
||||
}
|
||||
|
||||
@ -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 (
|
||||
<div
|
||||
className={['portal--Content', className].join(' ')}
|
||||
style={style}
|
||||
>
|
||||
{
|
||||
routes.map(({ component, isExact, name, path }) => (
|
||||
<Route
|
||||
component={component}
|
||||
exact={isExact}
|
||||
key={name}
|
||||
path={path}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
function Content ({ className, style }: Props, { router: { route: { location } } }: BaseContext) {
|
||||
const app = location.pathname.slice(1) || routing.default;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={['portal--Content', className].join(' ')}
|
||||
style={style}
|
||||
>
|
||||
<iframe
|
||||
className='portal--Content-Frame'
|
||||
src={`index.html?app=${app}`}
|
||||
title={app}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Content.contextTypes = {
|
||||
router: PropTypes.object
|
||||
};
|
||||
|
||||
export default translate(['portal'])(Content);
|
||||
|
||||
7
packages/portal/src/NotFound/NotFound.css
Normal file
7
packages/portal/src/NotFound/NotFound.css
Normal file
@ -0,0 +1,7 @@
|
||||
/* 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. */
|
||||
|
||||
.portal--NotFound {
|
||||
color: red;
|
||||
}
|
||||
24
packages/portal/src/NotFound/index.js
Normal file
24
packages/portal/src/NotFound/index.js
Normal file
@ -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 { BaseProps } from '../types';
|
||||
|
||||
import './NotFound.css';
|
||||
|
||||
import React from 'react';
|
||||
import { translate } from 'react-i18next';
|
||||
|
||||
function NotFound ({ className, style }: BaseProps) {
|
||||
return (
|
||||
<div
|
||||
className={['portal--NotFound', className].join(' ')}
|
||||
style={style}
|
||||
>
|
||||
ERROR: You have tried to access an application that does not exist
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default translate(['portal'])(NotFound);
|
||||
@ -25,7 +25,8 @@ export default function Item ({ className, i18n, icon, isExact, name, path, styl
|
||||
activeClassName='portal--SideBar-Item-NavLink-active'
|
||||
className='portal--SideBar-Item-NavLink'
|
||||
exact={isExact}
|
||||
to={path}
|
||||
// flowlint-next-line sketchy-null-string:off
|
||||
to={path || `/${name}`}
|
||||
>
|
||||
<Icon name={icon} /> {t(`sidebar.${name}`, i18n)}
|
||||
</NavLink>
|
||||
|
||||
@ -11,33 +11,33 @@ import React from 'react';
|
||||
import { translate } from 'react-i18next';
|
||||
import Menu from 'semantic-ui-react/dist/es/collections/Menu';
|
||||
|
||||
import routes from '../routes';
|
||||
import routing from '../routing';
|
||||
import Item from './Item';
|
||||
|
||||
type Props = BaseProps & {};
|
||||
|
||||
export default translate(['portal'])(
|
||||
function SideBar ({ className, style, t }: Props) {
|
||||
return (
|
||||
<div
|
||||
className={['portal--SideBar', className].join(' ')}
|
||||
style={style}
|
||||
function SideBar ({ className, style, t }: Props) {
|
||||
return (
|
||||
<div
|
||||
className={['portal--SideBar', className].join(' ')}
|
||||
style={style}
|
||||
>
|
||||
<Menu
|
||||
secondary
|
||||
vertical
|
||||
>
|
||||
<Menu
|
||||
secondary
|
||||
vertical
|
||||
>
|
||||
{
|
||||
routes.map((props) => (
|
||||
<Item
|
||||
key={props.name}
|
||||
t={t}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</Menu>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
{
|
||||
routing.routes.map((props) => (
|
||||
<Item
|
||||
key={props.name}
|
||||
t={t}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</Menu>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default translate(['portal'])(SideBar);
|
||||
|
||||
@ -9,8 +9,6 @@ html {
|
||||
body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
overflow: hidden; /*makes the body non-scrollable (we will add scrolling to the sidebar and main content containers)*/
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#root {
|
||||
|
||||
@ -14,13 +14,31 @@ import { HashRouter } from 'react-router-dom';
|
||||
import ContextProvider from '@polkadot/rx-react/ContextProvider';
|
||||
|
||||
import i18n from './i18n';
|
||||
import App from './App';
|
||||
|
||||
import Portal from './App';
|
||||
import NotFound from './NotFound';
|
||||
import routing from './routing';
|
||||
import urlParams from './urlParams';
|
||||
|
||||
const Component = (() => {
|
||||
const { app } = urlParams();
|
||||
|
||||
if (app) {
|
||||
const route = routing.routes.find(({ name }) => name === app);
|
||||
|
||||
return route
|
||||
? route.component
|
||||
: NotFound;
|
||||
}
|
||||
|
||||
return Portal;
|
||||
})();
|
||||
|
||||
ReactDOM.render(
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<ContextProvider>
|
||||
<HashRouter>
|
||||
<App />
|
||||
<Component />
|
||||
</HashRouter>
|
||||
</ContextProvider>
|
||||
</I18nextProvider>,
|
||||
|
||||
@ -1,16 +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 { Routes } from '../types';
|
||||
|
||||
// import accounts from './accounts';
|
||||
import home from './home';
|
||||
// import settings from './settings';
|
||||
import testing from './testing';
|
||||
|
||||
export default (([].concat(
|
||||
home, testing
|
||||
// , accounts, settings
|
||||
)): Routes);
|
||||
@ -5,18 +5,18 @@
|
||||
|
||||
import type { Routes } from '../types';
|
||||
|
||||
import Home from '@polkadot/app-home';
|
||||
import Explorer from '@polkadot/app-explorer';
|
||||
|
||||
export default ([
|
||||
{
|
||||
component: Home,
|
||||
component: Explorer,
|
||||
i18n: {
|
||||
defaultValue: 'Home'
|
||||
defaultValue: 'Explorer'
|
||||
},
|
||||
icon: 'home',
|
||||
icon: 'braille',
|
||||
isExact: true,
|
||||
isHidden: false,
|
||||
name: 'home',
|
||||
name: 'explorer',
|
||||
path: '/'
|
||||
}
|
||||
]: Routes);
|
||||
@ -5,18 +5,17 @@
|
||||
|
||||
import type { Routes } from '../types';
|
||||
|
||||
import Testing from '@polkadot/app-testing';
|
||||
import Extrinsics from '@polkadot/app-extrinsics';
|
||||
|
||||
export default ([
|
||||
{
|
||||
component: Testing,
|
||||
component: Extrinsics,
|
||||
i18n: {
|
||||
defaultValue: 'Testing'
|
||||
defaultValue: 'Extrinsics'
|
||||
},
|
||||
icon: 'braille',
|
||||
icon: 'send',
|
||||
isExact: false,
|
||||
isHidden: false,
|
||||
name: 'testing',
|
||||
path: '/testing'
|
||||
name: 'extrinsics'
|
||||
}
|
||||
]: Routes);
|
||||
19
packages/portal/src/routing/index.js
Normal file
19
packages/portal/src/routing/index.js
Normal file
@ -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
|
||||
|
||||
import type { Routing } from '../types';
|
||||
|
||||
// import accounts from './accounts';
|
||||
import explorer from './explorer';
|
||||
import extrinsics from './extrinsics';
|
||||
// import home from './home';
|
||||
// import settings from './settings';
|
||||
|
||||
export default ({
|
||||
default: 'explorer',
|
||||
routes: [].concat(
|
||||
explorer, extrinsics
|
||||
)
|
||||
}: Routing);
|
||||
@ -31,3 +31,7 @@
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.ui.page.modals.transition.visible {
|
||||
display: flex !important;
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
// of the ISC license. See the LICENSE file for details.
|
||||
// @flow
|
||||
|
||||
import type { Location } from 'react-router-dom';
|
||||
import type { RxApiInterface } from '@polkadot/rx-api/types';
|
||||
|
||||
export type BaseProps = {
|
||||
@ -14,7 +15,13 @@ export type BaseProps = {
|
||||
};
|
||||
|
||||
export type BaseContext = {
|
||||
api: RxApiInterface
|
||||
api: RxApiInterface,
|
||||
// TODO: Set the correct/full type
|
||||
router: {
|
||||
route: {
|
||||
location: Location
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export type Route = {
|
||||
@ -24,7 +31,12 @@ export type Route = {
|
||||
isExact: boolean,
|
||||
isHidden: boolean,
|
||||
name: string,
|
||||
path: string
|
||||
path?: string
|
||||
};
|
||||
|
||||
export type Routes = Array<Route>;
|
||||
|
||||
export type Routing = {
|
||||
default: string,
|
||||
routes: Routes
|
||||
}
|
||||
|
||||
24
packages/portal/src/urlParams.js
Normal file
24
packages/portal/src/urlParams.js
Normal file
@ -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
|
||||
|
||||
type Params = {
|
||||
[string]: string
|
||||
};
|
||||
|
||||
export default function urlParams (): Params {
|
||||
if (window.location.search.indexOf('?') !== 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const parts = window.location.search.slice(1).split('&');
|
||||
|
||||
return parts.reduce((params, param) => {
|
||||
const [name, value] = param.split('=');
|
||||
|
||||
params[name] = value;
|
||||
|
||||
return params;
|
||||
}, {});
|
||||
}
|
||||
274
yarn.lock
274
yarn.lock
@ -1177,39 +1177,39 @@
|
||||
call-me-maybe "^1.0.1"
|
||||
glob-to-regexp "^0.3.0"
|
||||
|
||||
"@polkadot/api-format@^0.8.14":
|
||||
version "0.8.14"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/api-format/-/api-format-0.8.14.tgz#9809675ab61b8af443562f7a30447c0c0f6a24e7"
|
||||
"@polkadot/api-format@^0.8.18":
|
||||
version "0.8.18"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/api-format/-/api-format-0.8.18.tgz#0a96d04131edb5fa6ac5ded8108078fff92cd17e"
|
||||
dependencies:
|
||||
"@polkadot/primitives-json" "^0.10.1"
|
||||
"@polkadot/util" "^0.18.6"
|
||||
"@polkadot/primitives-json" "^0.10.3"
|
||||
"@polkadot/util" "^0.19.2"
|
||||
babel-runtime "^6.26.0"
|
||||
|
||||
"@polkadot/api-jsonrpc@^0.8.14":
|
||||
version "0.8.14"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/api-jsonrpc/-/api-jsonrpc-0.8.14.tgz#94be22fcd1802ddbd87c35e52b8916e1f9135dd6"
|
||||
"@polkadot/api-jsonrpc@^0.8.18":
|
||||
version "0.8.18"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/api-jsonrpc/-/api-jsonrpc-0.8.18.tgz#3c752d1257470c2643c8f0d0b6847dcd65007ab7"
|
||||
dependencies:
|
||||
babel-runtime "^6.26.0"
|
||||
|
||||
"@polkadot/api-provider@^0.8.14":
|
||||
version "0.8.14"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/api-provider/-/api-provider-0.8.14.tgz#4226c914c138c9d0ee9638db7ae39480e28cf252"
|
||||
"@polkadot/api-provider@^0.8.18":
|
||||
version "0.8.18"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/api-provider/-/api-provider-0.8.18.tgz#03b58364cc0ed8b64f48a71661727781f4e19bd2"
|
||||
dependencies:
|
||||
"@polkadot/util" "^0.18.6"
|
||||
"@polkadot/util-crypto" "^0.18.6"
|
||||
"@polkadot/util-keyring" "^0.18.6"
|
||||
"@polkadot/util" "^0.19.2"
|
||||
"@polkadot/util-crypto" "^0.19.2"
|
||||
"@polkadot/util-keyring" "^0.19.2"
|
||||
babel-runtime "^6.26.0"
|
||||
isomorphic-fetch "^2.2.1"
|
||||
websocket "^1.0.25"
|
||||
|
||||
"@polkadot/api@^0.8.14":
|
||||
version "0.8.14"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-0.8.14.tgz#91ca51360848bcd76064a2dc1198199d7332c7bb"
|
||||
"@polkadot/api@^0.8.18":
|
||||
version "0.8.18"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-0.8.18.tgz#d8e0e1a58625bdc97b4cf6991a597a0aac2aebb1"
|
||||
dependencies:
|
||||
"@polkadot/api-format" "^0.8.14"
|
||||
"@polkadot/api-jsonrpc" "^0.8.14"
|
||||
"@polkadot/api-provider" "^0.8.14"
|
||||
"@polkadot/util" "^0.18.6"
|
||||
"@polkadot/api-format" "^0.8.18"
|
||||
"@polkadot/api-jsonrpc" "^0.8.18"
|
||||
"@polkadot/api-provider" "^0.8.18"
|
||||
"@polkadot/util" "^0.19.2"
|
||||
babel-runtime "^6.26.0"
|
||||
|
||||
"@polkadot/dev@^0.17.9":
|
||||
@ -1250,69 +1250,69 @@
|
||||
stylelint "^9.1.1"
|
||||
stylelint-config-standard "^18.2.0"
|
||||
|
||||
"@polkadot/primitives-builder@^0.10.1":
|
||||
version "0.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/primitives-builder/-/primitives-builder-0.10.1.tgz#1f930bb3629329bbb0a444c15ded864ef8e9db64"
|
||||
"@polkadot/primitives-builder@^0.10.3":
|
||||
version "0.10.3"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/primitives-builder/-/primitives-builder-0.10.3.tgz#ef4009ddfe8a033d58710d6c3ff286bb935887af"
|
||||
dependencies:
|
||||
"@polkadot/primitives" "^0.10.1"
|
||||
"@polkadot/primitives-codec" "^0.10.1"
|
||||
"@polkadot/util" "^0.18.4"
|
||||
"@polkadot/util-crypto" "^0.18.4"
|
||||
"@polkadot/util-triehash" "^0.18.4"
|
||||
"@polkadot/primitives" "^0.10.3"
|
||||
"@polkadot/primitives-codec" "^0.10.3"
|
||||
"@polkadot/util" "^0.19.2"
|
||||
"@polkadot/util-crypto" "^0.19.2"
|
||||
"@polkadot/util-triehash" "^0.19.2"
|
||||
babel-runtime "^6.26.0"
|
||||
|
||||
"@polkadot/primitives-codec@^0.10.1":
|
||||
version "0.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/primitives-codec/-/primitives-codec-0.10.1.tgz#54f42cbd87bab7af00a63768f845e4f50dc26c2a"
|
||||
"@polkadot/primitives-codec@^0.10.3":
|
||||
version "0.10.3"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/primitives-codec/-/primitives-codec-0.10.3.tgz#4b4f5f48037042e4b7cfcfc065ce7db72bade949"
|
||||
dependencies:
|
||||
"@polkadot/primitives" "^0.10.1"
|
||||
"@polkadot/primitives-builder" "^0.10.1"
|
||||
"@polkadot/primitives-rlp" "^0.10.1"
|
||||
"@polkadot/util" "^0.18.4"
|
||||
"@polkadot/util-keyring" "^0.18.4"
|
||||
"@polkadot/primitives" "^0.10.3"
|
||||
"@polkadot/primitives-builder" "^0.10.3"
|
||||
"@polkadot/primitives-rlp" "^0.10.3"
|
||||
"@polkadot/util" "^0.19.2"
|
||||
"@polkadot/util-keyring" "^0.19.2"
|
||||
babel-runtime "^6.26.0"
|
||||
|
||||
"@polkadot/primitives-json@^0.10.1":
|
||||
version "0.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/primitives-json/-/primitives-json-0.10.1.tgz#39bfec3ed6ddd8aef82bc12b6e3001d3a288af94"
|
||||
"@polkadot/primitives-json@^0.10.3":
|
||||
version "0.10.3"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/primitives-json/-/primitives-json-0.10.3.tgz#44dee86e4a4d53d524c326ace966f154bf7ee9e2"
|
||||
dependencies:
|
||||
"@polkadot/primitives" "^0.10.1"
|
||||
"@polkadot/primitives-builder" "^0.10.1"
|
||||
"@polkadot/util" "^0.18.4"
|
||||
"@polkadot/primitives" "^0.10.3"
|
||||
"@polkadot/primitives-builder" "^0.10.3"
|
||||
"@polkadot/util" "^0.19.2"
|
||||
babel-runtime "^6.26.0"
|
||||
|
||||
"@polkadot/primitives-rlp@^0.10.1":
|
||||
version "0.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/primitives-rlp/-/primitives-rlp-0.10.1.tgz#dd2fb7c9a990dc88132c88bc3128f5e749bbc7e3"
|
||||
"@polkadot/primitives-rlp@^0.10.3":
|
||||
version "0.10.3"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/primitives-rlp/-/primitives-rlp-0.10.3.tgz#7b8deeec0a3784b9fd5f343849c11df5d45bd9e6"
|
||||
dependencies:
|
||||
"@polkadot/primitives" "^0.10.1"
|
||||
"@polkadot/primitives-builder" "^0.10.1"
|
||||
"@polkadot/primitives-json" "^0.10.1"
|
||||
"@polkadot/util" "^0.18.4"
|
||||
"@polkadot/util-crypto" "^0.18.4"
|
||||
"@polkadot/primitives" "^0.10.3"
|
||||
"@polkadot/primitives-builder" "^0.10.3"
|
||||
"@polkadot/primitives-json" "^0.10.3"
|
||||
"@polkadot/util" "^0.19.2"
|
||||
"@polkadot/util-crypto" "^0.19.2"
|
||||
babel-runtime "^6.26.0"
|
||||
|
||||
"@polkadot/primitives@^0.10.1":
|
||||
version "0.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/primitives/-/primitives-0.10.1.tgz#c670f132eaed0cc32bd79177b285f178f3d4fa3d"
|
||||
"@polkadot/primitives@^0.10.3":
|
||||
version "0.10.3"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/primitives/-/primitives-0.10.3.tgz#29ee63f8ba664785dc6059c8bc59327729d382fc"
|
||||
dependencies:
|
||||
"@polkadot/util" "^0.18.4"
|
||||
"@polkadot/util" "^0.19.2"
|
||||
babel-runtime "^6.26.0"
|
||||
|
||||
"@polkadot/rx-api@^0.2.13":
|
||||
version "0.2.13"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/rx-api/-/rx-api-0.2.13.tgz#94004e0e3a134bf75f50e0b22e5fa59c136db0e1"
|
||||
"@polkadot/rx-api@^0.2.20":
|
||||
version "0.2.20"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/rx-api/-/rx-api-0.2.20.tgz#f08a2dcc6b246df1ff4b1b6d3c02b236ea3a6ded"
|
||||
dependencies:
|
||||
"@polkadot/api" "^0.8.14"
|
||||
"@polkadot/api-provider" "^0.8.14"
|
||||
"@polkadot/api" "^0.8.18"
|
||||
"@polkadot/api-provider" "^0.8.18"
|
||||
rxjs "^5.5.10"
|
||||
|
||||
"@polkadot/rx-react@^0.2.13":
|
||||
version "0.2.13"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/rx-react/-/rx-react-0.2.13.tgz#291e7e18eeaeea4dc3d16e50d932ca46da9c492d"
|
||||
"@polkadot/rx-react@^0.2.20":
|
||||
version "0.2.20"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/rx-react/-/rx-react-0.2.20.tgz#8bd5af52e00e20098fce9ba42d05d7b9405abd21"
|
||||
dependencies:
|
||||
"@polkadot/rx-api" "^0.2.13"
|
||||
"@polkadot/util" "^0.19.1"
|
||||
"@polkadot/rx-api" "^0.2.20"
|
||||
"@polkadot/util" "^0.19.2"
|
||||
|
||||
"@polkadot/ui-identicon@^0.9.10":
|
||||
version "0.9.10"
|
||||
@ -1328,9 +1328,9 @@
|
||||
"@polkadot/ui-identicon" "^0.9.10"
|
||||
babel-runtime "^6.26.0"
|
||||
|
||||
"@polkadot/util-crypto@^0.18.4":
|
||||
version "0.18.4"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-0.18.4.tgz#27e443ad46427cde49067a4b8525a99ffaf71df0"
|
||||
"@polkadot/util-crypto@^0.19.2":
|
||||
version "0.19.2"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-0.19.2.tgz#2250cc19c2050ee1661fb336417eb53ea84bc761"
|
||||
dependencies:
|
||||
babel-runtime "^6.26.0"
|
||||
blakejs "^1.1.0"
|
||||
@ -1338,106 +1338,33 @@
|
||||
tweetnacl "^1.0.0"
|
||||
xxhashjs "^0.2.2"
|
||||
|
||||
"@polkadot/util-crypto@^0.18.5":
|
||||
version "0.18.5"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-0.18.5.tgz#59574ff59a488ee5640ecf1862638f3b9647ffa7"
|
||||
"@polkadot/util-keyring@^0.19.2":
|
||||
version "0.19.2"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/util-keyring/-/util-keyring-0.19.2.tgz#ae61a246384d8f57ef585ec9a7e916eb49f36a67"
|
||||
dependencies:
|
||||
babel-runtime "^6.26.0"
|
||||
blakejs "^1.1.0"
|
||||
js-sha3 "^0.7.0"
|
||||
tweetnacl "^1.0.0"
|
||||
xxhashjs "^0.2.2"
|
||||
|
||||
"@polkadot/util-crypto@^0.18.6":
|
||||
version "0.18.6"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-0.18.6.tgz#57735d2056d178a3e741ca402ea1ae43267d81f8"
|
||||
dependencies:
|
||||
babel-runtime "^6.26.0"
|
||||
blakejs "^1.1.0"
|
||||
js-sha3 "^0.7.0"
|
||||
tweetnacl "^1.0.0"
|
||||
xxhashjs "^0.2.2"
|
||||
|
||||
"@polkadot/util-crypto@^0.19.1":
|
||||
version "0.19.1"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-0.19.1.tgz#95927de2f8a4384f05b872132e00bfd34aa1ea77"
|
||||
dependencies:
|
||||
babel-runtime "^6.26.0"
|
||||
blakejs "^1.1.0"
|
||||
js-sha3 "^0.7.0"
|
||||
tweetnacl "^1.0.0"
|
||||
xxhashjs "^0.2.2"
|
||||
|
||||
"@polkadot/util-keyring@^0.18.4":
|
||||
version "0.18.4"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/util-keyring/-/util-keyring-0.18.4.tgz#0e2bdbb3700275025632f42171a3fecacde513e3"
|
||||
dependencies:
|
||||
"@polkadot/util" "^0.18.4"
|
||||
"@polkadot/util-crypto" "^0.18.4"
|
||||
"@polkadot/util" "^0.19.2"
|
||||
"@polkadot/util-crypto" "^0.19.2"
|
||||
babel-runtime "^6.26.0"
|
||||
|
||||
"@polkadot/util-keyring@^0.18.6":
|
||||
version "0.18.6"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/util-keyring/-/util-keyring-0.18.6.tgz#983b58ac371a5866adcc0469d8c03a24a7a77f06"
|
||||
"@polkadot/util-rlp@^0.19.2":
|
||||
version "0.19.2"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/util-rlp/-/util-rlp-0.19.2.tgz#cba435622030a6269e662d12a3d03358c2ec6f2d"
|
||||
dependencies:
|
||||
"@polkadot/util" "^0.18.6"
|
||||
"@polkadot/util-crypto" "^0.18.6"
|
||||
"@polkadot/util" "^0.19.2"
|
||||
babel-runtime "^6.26.0"
|
||||
|
||||
"@polkadot/util-keyring@^0.19.1":
|
||||
version "0.19.1"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/util-keyring/-/util-keyring-0.19.1.tgz#dbf6e9efbe1dd4de982367c279b3193584db414f"
|
||||
"@polkadot/util-triehash@^0.19.2":
|
||||
version "0.19.2"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/util-triehash/-/util-triehash-0.19.2.tgz#012953a5c58e82830147a2e35d64366ac1129c70"
|
||||
dependencies:
|
||||
"@polkadot/util" "^0.19.1"
|
||||
"@polkadot/util-crypto" "^0.19.1"
|
||||
"@polkadot/util" "^0.19.2"
|
||||
"@polkadot/util-crypto" "^0.19.2"
|
||||
"@polkadot/util-rlp" "^0.19.2"
|
||||
babel-runtime "^6.26.0"
|
||||
|
||||
"@polkadot/util-rlp@^0.18.5":
|
||||
version "0.18.5"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/util-rlp/-/util-rlp-0.18.5.tgz#d06a165a1120f293056f81128f93f494ebe7b390"
|
||||
dependencies:
|
||||
"@polkadot/util" "^0.18.5"
|
||||
babel-runtime "^6.26.0"
|
||||
|
||||
"@polkadot/util-triehash@^0.18.4":
|
||||
version "0.18.5"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/util-triehash/-/util-triehash-0.18.5.tgz#85533c8c2d37a6145ef1b1e1a860cf81890f993c"
|
||||
dependencies:
|
||||
"@polkadot/util" "^0.18.5"
|
||||
"@polkadot/util-crypto" "^0.18.5"
|
||||
"@polkadot/util-rlp" "^0.18.5"
|
||||
babel-runtime "^6.26.0"
|
||||
|
||||
"@polkadot/util@^0.18.4":
|
||||
version "0.18.4"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-0.18.4.tgz#b1886a3d4663d302fe1234705f506fae95b371b8"
|
||||
dependencies:
|
||||
babel-runtime "^6.26.0"
|
||||
bn.js "^4.11.8"
|
||||
deasync "^0.1.12"
|
||||
ip-regex "^2.1.0"
|
||||
|
||||
"@polkadot/util@^0.18.5":
|
||||
version "0.18.5"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-0.18.5.tgz#98c04608fceadaaace765eb44253912edc007651"
|
||||
dependencies:
|
||||
babel-runtime "^6.26.0"
|
||||
bn.js "^4.11.8"
|
||||
deasync "^0.1.12"
|
||||
ip-regex "^2.1.0"
|
||||
|
||||
"@polkadot/util@^0.18.6":
|
||||
version "0.18.6"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-0.18.6.tgz#dd3ea07d67d31de02a154dd54665ce9779a73211"
|
||||
dependencies:
|
||||
babel-runtime "^6.26.0"
|
||||
bn.js "^4.11.8"
|
||||
deasync "^0.1.12"
|
||||
ip-regex "^2.1.0"
|
||||
|
||||
"@polkadot/util@^0.19.1":
|
||||
version "0.19.1"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-0.19.1.tgz#e19dc51b3d998b489ed26738a3a1e0cded65c020"
|
||||
"@polkadot/util@^0.19.2":
|
||||
version "0.19.2"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-0.19.2.tgz#5517aaa0a39f01d83c6899e3f41301e0335e6434"
|
||||
dependencies:
|
||||
babel-runtime "^6.26.0"
|
||||
bn.js "^4.11.8"
|
||||
@ -2091,16 +2018,6 @@ babel-plugin-macros@2.0.0:
|
||||
dependencies:
|
||||
cosmiconfig "3.1.0"
|
||||
|
||||
babel-plugin-module-resolver@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-module-resolver/-/babel-plugin-module-resolver-3.1.1.tgz#881cf67e3d4b8400d5eaaefc1be44d2dc1fe404f"
|
||||
dependencies:
|
||||
find-babel-config "^1.1.0"
|
||||
glob "^7.1.2"
|
||||
pkg-up "^2.0.0"
|
||||
reselect "^3.0.1"
|
||||
resolve "^1.4.0"
|
||||
|
||||
babel-plugin-named-asset-import@1.0.0-next.b2fd8db8:
|
||||
version "1.0.0-next.b2fd8db8"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-1.0.0-next.b2fd8db8.tgz#bd32f356288cbab326196b5f75547bc0dedf540a"
|
||||
@ -4930,13 +4847,6 @@ finalhandler@1.1.1:
|
||||
statuses "~1.4.0"
|
||||
unpipe "~1.0.0"
|
||||
|
||||
find-babel-config@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/find-babel-config/-/find-babel-config-1.1.0.tgz#acc01043a6749fec34429be6b64f542ebb5d6355"
|
||||
dependencies:
|
||||
json5 "^0.5.1"
|
||||
path-exists "^3.0.0"
|
||||
|
||||
find-cache-dir@^0.1.1:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9"
|
||||
@ -8083,7 +7993,7 @@ pkg-dir@^2.0.0:
|
||||
dependencies:
|
||||
find-up "^2.1.0"
|
||||
|
||||
pkg-up@2.0.0, pkg-up@^2.0.0:
|
||||
pkg-up@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f"
|
||||
dependencies:
|
||||
@ -9255,10 +9165,6 @@ requires-port@1.0.x, requires-port@1.x.x, requires-port@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
|
||||
|
||||
reselect@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/reselect/-/reselect-3.0.1.tgz#efdaa98ea7451324d092b2b2163a6a1d7a9a2147"
|
||||
|
||||
resolve-cwd@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a"
|
||||
@ -9302,12 +9208,6 @@ resolve@^1.3.2, resolve@^1.3.3, resolve@^1.5.0:
|
||||
dependencies:
|
||||
path-parse "^1.0.5"
|
||||
|
||||
resolve@^1.4.0:
|
||||
version "1.7.1"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.7.1.tgz#aadd656374fd298aee895bc026b8297418677fd3"
|
||||
dependencies:
|
||||
path-parse "^1.0.5"
|
||||
|
||||
restore-cursor@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user