Bump UI, HDKD keyring (new substrate crypto) (#813)
* Bump UI, HDKD keyring (new substrate crypto) * Bump ui/* versions * Pull in latest util-crypto, bp39 fix * Bump common * Small enhancements, cleanups (testing WIP) * Bump * Update after merge * Bumps, fix transfer calculation (value may be non-existent) * Bumpo dependencies * Label extrinsic hash * Signature updates * Update deps * Adjust status display * Close status items on click * Update withRouter duplication * API bump, (some) creation fixes * Move bip39 out of the worker (fast enough now via WASM) * Update after master merge * Cleanup deps (re-write yarn.lock)
This commit is contained in:
parent
d6da91ab0e
commit
96615d5957
@ -1,3 +1,7 @@
|
||||
# 0.26.1
|
||||
|
||||
- Swap keyring to HDKD derivation, mnemonic keys are now not backwards compatible with those created earlier. (Defaults are still for ed25519)
|
||||
|
||||
# 0.25.1
|
||||
|
||||
- Swap to publishing -beta.x on merge (non-breaking testing)
|
||||
|
||||
@ -4,8 +4,6 @@
|
||||
[](https://www.npmjs.com/package/@polkadot/apps)
|
||||
[](https://travis-ci.com/polkadot-js/apps)
|
||||
[](https://greenkeeper.io/)
|
||||
[](https://david-dm.org/polkadot-js/apps)
|
||||
[](https://david-dm.org/polkadot-js/apps#info=devDependencies)
|
||||
|
||||
# @polkadot/apps
|
||||
|
||||
|
||||
18
package.json
18
package.json
@ -10,14 +10,14 @@
|
||||
"packages/*"
|
||||
],
|
||||
"resolutions": {
|
||||
"@polkadot/api": "^0.46.12",
|
||||
"@polkadot/keyring": "^0.36.3",
|
||||
"@polkadot/types": "^0.46.12",
|
||||
"@polkadot/util": "^0.36.3",
|
||||
"@polkadot/util-crypto": "^0.36.3",
|
||||
"@polkadot/api": "^0.49.0-beta.1",
|
||||
"@polkadot/keyring": "^0.39.0-beta.2",
|
||||
"@polkadot/types": "^0.49.0-beta.1",
|
||||
"@polkadot/util": "^0.39.0-beta.2",
|
||||
"@polkadot/util-crypto": "^0.39.0-beta.2",
|
||||
"babel-core": "^7.0.0-bridge.0",
|
||||
"rxjs": "^6.4.0",
|
||||
"typescript": "^3.3.3333"
|
||||
"typescript": "^3.3.4000"
|
||||
},
|
||||
"scripts": {
|
||||
"analyze": "yarn run build && cd packages/apps && yarn run source-map-explorer build/main.*.js",
|
||||
@ -30,9 +30,9 @@
|
||||
"start": "cd packages/apps && webpack --config webpack.config.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.3.4",
|
||||
"@babel/runtime": "^7.3.4",
|
||||
"@polkadot/dev-react": "^0.26.1",
|
||||
"@babel/core": "^7.4.0",
|
||||
"@babel/runtime": "^7.4.0",
|
||||
"@polkadot/dev-react": "^0.28.0-beta.1",
|
||||
"@polkadot/ts": "^0.1.56",
|
||||
"autoprefixer": "^9.4.9",
|
||||
"empty": "^0.10.1",
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.4",
|
||||
"@babel/runtime": "^7.4.0",
|
||||
"@polkadot/ui-app": "^0.26.0-beta.6"
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,10 +10,10 @@
|
||||
"contributors": [],
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.4",
|
||||
"@babel/runtime": "^7.4.0",
|
||||
"@polkadot/ui-app": "^0.26.0-beta.6",
|
||||
"@types/file-saver": "^2.0.0",
|
||||
"@types/yargs": "^12.0.9",
|
||||
"@types/yargs": "^12.0.10",
|
||||
"babel-plugin-module-resolver": "^3.1.1",
|
||||
"file-saver": "^2.0.0",
|
||||
"libsodium-wrappers": "^0.7.3",
|
||||
|
||||
@ -4,19 +4,19 @@
|
||||
|
||||
import { I18nProps } from '@polkadot/ui-app/types';
|
||||
import { ActionStatus } from '@polkadot/ui-app/Status/types';
|
||||
import { KeypairType } from '@polkadot/util-crypto/types';
|
||||
import { ComponentProps } from './types';
|
||||
|
||||
import FileSaver from 'file-saver';
|
||||
import React from 'react';
|
||||
import { AddressSummary, Button, Dropdown, Input, Modal, Password } from '@polkadot/ui-app';
|
||||
import { InputAddress } from '@polkadot/ui-app/InputAddress';
|
||||
import { hexToU8a, isHex, stringToU8a, u8aToHex } from '@polkadot/util';
|
||||
import { mnemonicToSeed, mnemonicValidate, naclKeypairFromSeed, randomAsU8a } from '@polkadot/util-crypto';
|
||||
import keyring from '@polkadot/ui-keyring';
|
||||
import uiSettings from '@polkadot/ui-settings';
|
||||
import { hexToU8a, isHex, stringToU8a, u8aToHex } from '@polkadot/util';
|
||||
import { mnemonicGenerate, mnemonicToMiniSecret, mnemonicValidate, naclKeypairFromSeed, randomAsU8a, schnorrkelKeypairFromSeed } from '@polkadot/util-crypto';
|
||||
|
||||
import translate from './translate';
|
||||
import FileSaver from 'file-saver';
|
||||
|
||||
const BipWorker = require('worker-loader?name=[name].[hash:8].js!./bipWorker');
|
||||
|
||||
type Props = ComponentProps & I18nProps & {
|
||||
match: {
|
||||
@ -36,6 +36,7 @@ type State = {
|
||||
isPassValid: boolean,
|
||||
isValid: boolean,
|
||||
name: string,
|
||||
pairType: KeypairType,
|
||||
password: string,
|
||||
seed: string,
|
||||
seedOptions: Array<{ value: SeedType, text: string }>,
|
||||
@ -51,18 +52,17 @@ function rawValidate (seed: string): boolean {
|
||||
return seed.length <= 32 || isHexSeed(seed);
|
||||
}
|
||||
|
||||
function rawToSeed (seed: string): Uint8Array {
|
||||
return isHexSeed(seed)
|
||||
? hexToU8a(seed)
|
||||
: stringToU8a(seed.padEnd(32, ' '));
|
||||
}
|
||||
|
||||
function addressFromSeed (seed: string, seedType: SeedType): string {
|
||||
const keypair = naclKeypairFromSeed(
|
||||
seedType === 'bip'
|
||||
? mnemonicToSeed(seed)
|
||||
: rawToSeed(seed)
|
||||
);
|
||||
function addressFromSeed (phrase: string, pairType: KeypairType, seedType: SeedType): string {
|
||||
const seed = seedType === 'bip'
|
||||
? mnemonicToMiniSecret(phrase)
|
||||
: (
|
||||
isHexSeed(phrase)
|
||||
? hexToU8a(phrase)
|
||||
: stringToU8a(phrase.padEnd(32))
|
||||
);
|
||||
const keypair = pairType === 'sr25519'
|
||||
? schnorrkelKeypairFromSeed(seed)
|
||||
: naclKeypairFromSeed(seed);
|
||||
|
||||
return keyring.encodeAddress(
|
||||
keypair.publicKey
|
||||
@ -70,7 +70,6 @@ function addressFromSeed (seed: string, seedType: SeedType): string {
|
||||
}
|
||||
|
||||
class Creator extends React.PureComponent<Props, State> {
|
||||
bipWorker: any;
|
||||
state: State = { seedType: 'bip' } as State;
|
||||
|
||||
constructor (props: Props) {
|
||||
@ -78,18 +77,8 @@ class Creator extends React.PureComponent<Props, State> {
|
||||
|
||||
const { match: { params: { seed } }, t } = this.props;
|
||||
|
||||
this.bipWorker = new BipWorker();
|
||||
this.bipWorker.onmessage = (event: MessageEvent) => {
|
||||
const { publicKey, seed } = event.data;
|
||||
|
||||
this.setState({
|
||||
address: keyring.encodeAddress(publicKey),
|
||||
isBipBusy: false,
|
||||
seed
|
||||
});
|
||||
};
|
||||
this.state = {
|
||||
...this.emptyState(seed),
|
||||
...this.emptyState('ed25519', seed),
|
||||
seedOptions: [
|
||||
{ value: 'bip', text: t('Mnemonic') },
|
||||
{ value: 'raw', text: t('Raw seed') }
|
||||
@ -141,7 +130,7 @@ class Creator extends React.PureComponent<Props, State> {
|
||||
|
||||
renderInput () {
|
||||
const { t } = this.props;
|
||||
const { isBipBusy, isNameValid, isPassValid, isSeedValid, name, password, seed, seedOptions, seedType, showWarning } = this.state;
|
||||
const { isBipBusy, isNameValid, isPassValid, isSeedValid, name, pairType, password, seed, seedOptions, seedType, showWarning } = this.state;
|
||||
|
||||
return (
|
||||
<div className='grow'>
|
||||
@ -182,6 +171,14 @@ class Creator extends React.PureComponent<Props, State> {
|
||||
/>
|
||||
</Input>
|
||||
</div>
|
||||
<div className='ui--row'>
|
||||
<Dropdown
|
||||
defaultValue={pairType}
|
||||
label={t('keypair crypto type')}
|
||||
onChange={this.onChangePairType}
|
||||
options={uiSettings.availableCryptos}
|
||||
/>
|
||||
</div>
|
||||
<div className='ui--row'>
|
||||
<Password
|
||||
className='full'
|
||||
@ -249,18 +246,11 @@ class Creator extends React.PureComponent<Props, State> {
|
||||
);
|
||||
}
|
||||
|
||||
private generateSeed (seedType: SeedType, _seed?: string | null): State {
|
||||
if (seedType === 'bip') {
|
||||
this.bipWorker.postMessage('create');
|
||||
|
||||
return {
|
||||
isBipBusy: true,
|
||||
seed: ''
|
||||
} as State;
|
||||
}
|
||||
|
||||
const seed = _seed || u8aToHex(randomAsU8a());
|
||||
const address = addressFromSeed(seed, seedType);
|
||||
private generateSeed (seedType: SeedType, pairType: KeypairType, _seed?: string | null): State {
|
||||
const seed = seedType === 'bip'
|
||||
? mnemonicGenerate()
|
||||
: _seed || u8aToHex(randomAsU8a());
|
||||
const address = addressFromSeed(seed, pairType, seedType);
|
||||
|
||||
return {
|
||||
address,
|
||||
@ -269,19 +259,20 @@ class Creator extends React.PureComponent<Props, State> {
|
||||
} as State;
|
||||
}
|
||||
|
||||
private emptyState (seed?: string | null): State {
|
||||
private emptyState (pairType: KeypairType, seed?: string | null): State {
|
||||
const seedType = seed
|
||||
? 'raw'
|
||||
: this.state.seedType;
|
||||
|
||||
return {
|
||||
...this.generateSeed(seedType, seed),
|
||||
...this.generateSeed(seedType, pairType, seed),
|
||||
isNameValid: true,
|
||||
isPassValid: false,
|
||||
isSeedValid: true,
|
||||
isValid: false,
|
||||
name: 'new keypair',
|
||||
password: '',
|
||||
pairType,
|
||||
seedType,
|
||||
showWarning: false
|
||||
};
|
||||
@ -290,7 +281,7 @@ class Creator extends React.PureComponent<Props, State> {
|
||||
private nextState (newState: State): void {
|
||||
this.setState(
|
||||
(prevState: State, props: Props): State => {
|
||||
const { isBipBusy = prevState.isBipBusy, name = prevState.name, password = prevState.password, seed = prevState.seed, seedOptions = prevState.seedOptions, seedType = prevState.seedType, showWarning = prevState.showWarning } = newState;
|
||||
const { isBipBusy = prevState.isBipBusy, name = prevState.name, pairType = prevState.pairType, password = prevState.password, seed = prevState.seed, seedOptions = prevState.seedOptions, seedType = prevState.seedType, showWarning = prevState.showWarning } = newState;
|
||||
let address = prevState.address;
|
||||
const isNameValid = !!name;
|
||||
const isSeedValid = seedType === 'bip'
|
||||
@ -299,7 +290,7 @@ class Creator extends React.PureComponent<Props, State> {
|
||||
const isPassValid = keyring.isPassValid(password);
|
||||
|
||||
if (isSeedValid && seed !== prevState.seed) {
|
||||
address = addressFromSeed(seed, seedType);
|
||||
address = addressFromSeed(seed, pairType, seedType);
|
||||
}
|
||||
|
||||
return {
|
||||
@ -310,6 +301,7 @@ class Creator extends React.PureComponent<Props, State> {
|
||||
isSeedValid,
|
||||
isValid: isNameValid && isPassValid && isSeedValid,
|
||||
name,
|
||||
pairType,
|
||||
password,
|
||||
seed,
|
||||
seedOptions,
|
||||
@ -320,10 +312,6 @@ class Creator extends React.PureComponent<Props, State> {
|
||||
);
|
||||
}
|
||||
|
||||
private onChangeSeed = (seed: string): void => {
|
||||
this.nextState({ seed } as State);
|
||||
}
|
||||
|
||||
private onChangeName = (name: string): void => {
|
||||
this.nextState({ name } as State);
|
||||
}
|
||||
@ -332,6 +320,17 @@ class Creator extends React.PureComponent<Props, State> {
|
||||
this.nextState({ password } as State);
|
||||
}
|
||||
|
||||
private onChangeSeed = (seed: string): void => {
|
||||
this.nextState({ seed } as State);
|
||||
}
|
||||
|
||||
private onChangePairType = (pairType: KeypairType): void => {
|
||||
this.setState(({ seedType }: State) => ({
|
||||
...this.generateSeed(seedType, pairType),
|
||||
pairType
|
||||
}));
|
||||
}
|
||||
|
||||
private onShowWarning = (): void => {
|
||||
this.nextState({ showWarning: true } as State);
|
||||
}
|
||||
@ -342,18 +341,14 @@ class Creator extends React.PureComponent<Props, State> {
|
||||
|
||||
private onCommit = (): void => {
|
||||
const { basePath, onStatusChange, t } = this.props;
|
||||
const { name, password, seed, seedType } = this.state;
|
||||
const { name, pairType, password, seed } = this.state;
|
||||
|
||||
const status = {
|
||||
action: 'create'
|
||||
} as ActionStatus;
|
||||
|
||||
try {
|
||||
const pair = seedType === 'bip'
|
||||
? keyring.createAccountMnemonic(seed, password, { name })
|
||||
: keyring.createAccount(rawToSeed(seed), password, { name });
|
||||
|
||||
const json = pair.toJson(password);
|
||||
const { json, pair } = keyring.createUri(seed, password, { name }, pairType);
|
||||
const blob = new Blob([JSON.stringify(json)], { type: 'application/json; charset=utf-8' });
|
||||
|
||||
FileSaver.saveAs(blob, `${pair.address()}.json`);
|
||||
@ -376,7 +371,9 @@ class Creator extends React.PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
private onDiscard = (): void => {
|
||||
this.setState(this.emptyState());
|
||||
this.setState(({ pairType }) =>
|
||||
this.emptyState(pairType)
|
||||
);
|
||||
}
|
||||
|
||||
private selectSeedType = (seedType: SeedType): void => {
|
||||
@ -384,10 +381,10 @@ class Creator extends React.PureComponent<Props, State> {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
...this.generateSeed(seedType),
|
||||
this.setState(({ pairType }: State) => ({
|
||||
...this.generateSeed(seedType, pairType),
|
||||
seedType
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -9,8 +9,9 @@ import { SubjectInfo } from '@polkadot/ui-keyring/observable/types';
|
||||
import { ComponentProps } from './types';
|
||||
|
||||
import React from 'react';
|
||||
import { AddressSummary, Button, Input, InputAddress } from '@polkadot/ui-app';
|
||||
import { AddressSummary, Button, Dropdown, Input, InputAddress } from '@polkadot/ui-app';
|
||||
import keyring from '@polkadot/ui-keyring';
|
||||
import uiSettings from '@polkadot/ui-settings';
|
||||
|
||||
import Backup from './Backup';
|
||||
import ChangePass from './ChangePass';
|
||||
@ -100,6 +101,9 @@ class Editor extends React.PureComponent<Props, State> {
|
||||
const address = current
|
||||
? current.address()
|
||||
: undefined;
|
||||
const type = current
|
||||
? current.type
|
||||
: 'ed25519';
|
||||
|
||||
return (
|
||||
<div className='ui--grid'>
|
||||
@ -128,6 +132,14 @@ class Editor extends React.PureComponent<Props, State> {
|
||||
value={editedName}
|
||||
/>
|
||||
</div>
|
||||
<div className='ui--row'>
|
||||
<Dropdown
|
||||
defaultValue={type}
|
||||
isDisabled
|
||||
label={t('keypair crypto type')}
|
||||
options={uiSettings.availableCryptos}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -2,15 +2,22 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { mnemonicGenerate, mnemonicToSeed, naclKeypairFromSeed } from '@polkadot/util-crypto';
|
||||
import { cryptoWaitReady, mnemonicGenerate, mnemonicToMiniSecret, naclKeypairFromSeed, schnorrkelKeypairFromSeed } from '@polkadot/util-crypto';
|
||||
|
||||
const ctx: Worker = self as any;
|
||||
|
||||
ctx.onmessage = () => {
|
||||
cryptoWaitReady().catch(() => {
|
||||
// ignore
|
||||
});
|
||||
|
||||
ctx.onmessage = async ({ data: { pairType } }) => {
|
||||
await cryptoWaitReady();
|
||||
|
||||
const seed = mnemonicGenerate();
|
||||
const { publicKey } = naclKeypairFromSeed(
|
||||
mnemonicToSeed(seed)
|
||||
);
|
||||
const miniSecret = mnemonicToMiniSecret(seed);
|
||||
const { publicKey } = pairType === 'sr25519'
|
||||
? schnorrkelKeypairFromSeed(miniSecret)
|
||||
: naclKeypairFromSeed(miniSecret);
|
||||
|
||||
ctx.postMessage({
|
||||
publicKey,
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
"contributors": [],
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.4",
|
||||
"@babel/runtime": "^7.4.0",
|
||||
"@polkadot/ui-app": "^0.26.0-beta.6"
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.4",
|
||||
"@babel/runtime": "^7.4.0",
|
||||
"@polkadot/ui-app": "^0.26.0-beta.6",
|
||||
"@polkadot/ui-reactive": "^0.26.0-beta.6"
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
"contributors": [],
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.4",
|
||||
"@babel/runtime": "^7.4.0",
|
||||
"@polkadot/ui-app": "^0.26.0-beta.6"
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
"contributors": [],
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.4",
|
||||
"@babel/runtime": "^7.4.0",
|
||||
"@polkadot/ui-app": "^0.26.0-beta.6",
|
||||
"@polkadot/ui-params": "^0.26.0-beta.6",
|
||||
"@polkadot/ui-signer": "^0.26.0-beta.6"
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.4",
|
||||
"@babel/runtime": "^7.4.0",
|
||||
"@polkadot/ui-app": "^0.26.0-beta.6",
|
||||
"snappyjs": "^0.6.0"
|
||||
}
|
||||
|
||||
@ -39,6 +39,7 @@ type Injected = {
|
||||
util: typeof util,
|
||||
window: null
|
||||
};
|
||||
|
||||
type Props = ApiProps & AppProps & I18nProps & {
|
||||
match: {
|
||||
params: {
|
||||
@ -48,6 +49,7 @@ type Props = ApiProps & AppProps & I18nProps & {
|
||||
// FIXME wait for proper eslint integration in tslint, then hopefully remove this
|
||||
history: any
|
||||
};
|
||||
|
||||
type State = {
|
||||
animated: boolean,
|
||||
customExamples: Array<Snippet>,
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.4",
|
||||
"@babel/runtime": "^7.4.0",
|
||||
"@polkadot/ui-app": "^0.26.0-beta.6",
|
||||
"@polkadot/ui-reactive": "^0.26.0-beta.6"
|
||||
}
|
||||
|
||||
@ -80,7 +80,6 @@ class General extends React.PureComponent<Props, State> {
|
||||
defaultValue={i18nLang}
|
||||
isDisabled
|
||||
label={t('default interface language')}
|
||||
onChange={this.onChangeLang}
|
||||
options={uiSettings.availableLanguages}
|
||||
/>
|
||||
</div>
|
||||
@ -140,10 +139,6 @@ class General extends React.PureComponent<Props, State> {
|
||||
}));
|
||||
}
|
||||
|
||||
private onChangeLang = (i18nLang: string): void => {
|
||||
// ignore (for now), here to future-proof
|
||||
}
|
||||
|
||||
private onChangeUiMode = (uiMode: string): void => {
|
||||
this.setState(({ settings }: State) => ({
|
||||
settings: {
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.4",
|
||||
"@babel/runtime": "^7.4.0",
|
||||
"@polkadot/app-explorer": "^0.26.0-beta.6",
|
||||
"@polkadot/ui-app": "^0.26.0-beta.6",
|
||||
"@polkadot/ui-reactive": "^0.26.0-beta.6"
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
"contributors": [],
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.4",
|
||||
"@babel/runtime": "^7.4.0",
|
||||
"@polkadot/ui-app": "^0.26.0-beta.6",
|
||||
"@polkadot/ui-params": "^0.26.0-beta.6"
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
"contributors": [],
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.4",
|
||||
"@babel/runtime": "^7.4.0",
|
||||
"@polkadot/ui-app": "^0.26.0-beta.6"
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.4",
|
||||
"@babel/runtime": "^7.4.0",
|
||||
"@polkadot/ui-app": "^0.26.0-beta.6",
|
||||
"@polkadot/ui-reactive": "^0.26.0-beta.6"
|
||||
}
|
||||
|
||||
@ -12,9 +12,9 @@
|
||||
"contributors": [],
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.4",
|
||||
"@babel/runtime": "^7.4.0",
|
||||
"@polkadot/ui-app": "^0.26.0-beta.6",
|
||||
"@polkadot/ui-assets": "^0.30.1",
|
||||
"@polkadot/ui-assets": "^0.32.0-beta.1",
|
||||
"@polkadot/ui-signer": "^0.26.0-beta.6",
|
||||
"@types/react-tooltip": "^3.9.1",
|
||||
"react-tooltip": "^3.9.2"
|
||||
|
||||
@ -5,7 +5,6 @@
|
||||
import { I18nProps } from '@polkadot/ui-app/types';
|
||||
import { ApiProps } from '@polkadot/ui-api/types';
|
||||
import { QueueProps } from '@polkadot/ui-app/Status/types';
|
||||
import { RouteProps } from '../types';
|
||||
|
||||
import React from 'react';
|
||||
import { withRouter } from 'react-router';
|
||||
@ -58,17 +57,12 @@ class Content extends React.Component<Props> {
|
||||
);
|
||||
}
|
||||
|
||||
// inject router into component that we are rendering (in some cases react-router does
|
||||
// not play 100% with styled-components because of the new vs old context usage, this
|
||||
// is a workaround for that)
|
||||
const ComponentRouted = (withRouter(Component as any) as any) as React.ComponentType<RouteProps>;
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<QueueConsumer>
|
||||
{({ queueAction, stqueue, txqueue }: QueueProps) => (
|
||||
<>
|
||||
<ComponentRouted
|
||||
<Component
|
||||
basePath={`/${name}`}
|
||||
location={location}
|
||||
onStatusChange={queueAction}
|
||||
|
||||
@ -8,7 +8,7 @@ import { SubjectInfo } from '@polkadot/ui-keyring/observable/types';
|
||||
import { Route } from '../types';
|
||||
|
||||
import React from 'react';
|
||||
import { withRouter } from 'react-router';
|
||||
// import { withRouter } from 'react-router';
|
||||
import { NavLink } from 'react-router-dom';
|
||||
import { Icon, Menu } from '@polkadot/ui-app';
|
||||
import accountObservable from '@polkadot/ui-keyring/observable/accounts';
|
||||
@ -31,7 +31,6 @@ interface Tooltip {
|
||||
}
|
||||
|
||||
class Item extends React.PureComponent<Props> {
|
||||
|
||||
componentWillUpdate () {
|
||||
ReactTooltip.rebuild();
|
||||
}
|
||||
@ -119,7 +118,6 @@ class Item extends React.PureComponent<Props> {
|
||||
|
||||
export default withMulti(
|
||||
Item,
|
||||
withRouter,
|
||||
withApi,
|
||||
withObservable(accountObservable.subject, { propName: 'allAccounts' })
|
||||
);
|
||||
|
||||
@ -8,9 +8,6 @@ import { SIDEBAR_MENU_THRESHOLD } from '../constants';
|
||||
import './SideBar.css';
|
||||
|
||||
import React from 'react';
|
||||
import { withRouter } from 'react-router';
|
||||
|
||||
import { withMulti } from '@polkadot/ui-api';
|
||||
import { Button, Icon, Menu } from '@polkadot/ui-app';
|
||||
import { classes } from '@polkadot/ui-app/util';
|
||||
|
||||
@ -31,7 +28,6 @@ type Props = I18nProps & {
|
||||
};
|
||||
|
||||
class SideBar extends React.PureComponent<Props> {
|
||||
|
||||
render () {
|
||||
const { isCollapsed } = this.props;
|
||||
|
||||
@ -182,8 +178,4 @@ class SideBar extends React.PureComponent<Props> {
|
||||
}
|
||||
}
|
||||
|
||||
export default withMulti(
|
||||
SideBar,
|
||||
translate,
|
||||
withRouter
|
||||
);
|
||||
export default translate(SideBar);
|
||||
|
||||
@ -30,9 +30,9 @@
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/ui/tree/master/packages/ui-reactive#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.4",
|
||||
"@polkadot/api": "^0.46.12",
|
||||
"@polkadot/ui-util": "^0.28.8",
|
||||
"@babel/runtime": "^7.4.0",
|
||||
"@polkadot/api": "^0.49.0-beta.1",
|
||||
"@polkadot/ui-util": "^0.32.0-beta.1",
|
||||
"rxjs-compat": "^6.3.2"
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,7 +43,7 @@ export default class ApiWrapper extends React.PureComponent<Props, State> {
|
||||
const api = new ApiPromise({ provider, signer });
|
||||
|
||||
this.setState({ api }, () => {
|
||||
this.updateSubscriptions();
|
||||
this.subscribeEvents();
|
||||
});
|
||||
};
|
||||
const setApiUrl = (url: string = defaults.WS_URL): void =>
|
||||
@ -58,32 +58,36 @@ export default class ApiWrapper extends React.PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this.updateSubscriptions();
|
||||
this.subscribeEvents();
|
||||
}
|
||||
|
||||
private updateSubscriptions () {
|
||||
private subscribeEvents () {
|
||||
const { api } = this.state;
|
||||
|
||||
[
|
||||
this.subscribeIsConnected,
|
||||
this.subscribeIsReady,
|
||||
this.subscribeChain
|
||||
].map((fn: Function) => {
|
||||
api.on('connected', () => {
|
||||
this.setState({ isApiConnected: true });
|
||||
});
|
||||
|
||||
api.on('disconnected', () => {
|
||||
this.setState({ isApiConnected: false });
|
||||
});
|
||||
|
||||
api.on('ready', async () => {
|
||||
try {
|
||||
return fn(api);
|
||||
await this.loadOnReady(api);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return null;
|
||||
console.error('Unable to load chain', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private subscribeChain = async (api: ApiPromise) => {
|
||||
private async loadOnReady (api: ApiPromise) {
|
||||
const [properties = new ChainProperties(), value] = await Promise.all([
|
||||
api.rpc.system.properties() as Promise<ChainProperties | undefined>,
|
||||
api.rpc.system.chain() as Promise<any>
|
||||
]);
|
||||
|
||||
const section = Object.keys(api.tx)[0];
|
||||
const method = Object.keys(api.tx[section])[0];
|
||||
const chain = value
|
||||
? value.toString()
|
||||
: null;
|
||||
@ -105,28 +109,11 @@ export default class ApiWrapper extends React.PureComponent<Props, State> {
|
||||
type: 'ed25519'
|
||||
});
|
||||
|
||||
this.setState({ chain, isDevelopment });
|
||||
}
|
||||
|
||||
private subscribeIsConnected = (api: ApiPromise) => {
|
||||
api.on('connected', () => {
|
||||
this.setState({ isApiConnected: true });
|
||||
});
|
||||
|
||||
api.on('disconnected', () => {
|
||||
this.setState({ isApiConnected: false });
|
||||
});
|
||||
}
|
||||
|
||||
private subscribeIsReady = (api: ApiPromise) => {
|
||||
api.on('ready', () => {
|
||||
const section = Object.keys(api.tx)[0];
|
||||
const method = Object.keys(api.tx[section])[0];
|
||||
|
||||
this.setState({
|
||||
isApiReady: true,
|
||||
apiDefaultTx: api.tx[section][method]
|
||||
});
|
||||
this.setState({
|
||||
isApiReady: true,
|
||||
apiDefaultTx: api.tx[section][method],
|
||||
chain,
|
||||
isDevelopment
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
import { ApiProps, CallState, Subtract } from '../types';
|
||||
import { Options } from './types';
|
||||
|
||||
import memoize from 'memoizee';
|
||||
import React from 'react';
|
||||
import { assert, isNull, isUndefined } from '@polkadot/util';
|
||||
|
||||
@ -158,7 +159,7 @@ export default function withCall<P extends ApiProps> (endpoint: string, { at, at
|
||||
await this.unsubscribe();
|
||||
|
||||
if (isSubscription) {
|
||||
this.destroy = await apiMethod(...params, (value?: any) =>
|
||||
this.destroy = await memoize(apiMethod)(...params, (value?: any) =>
|
||||
this.triggerUpdate(this.props, value)
|
||||
);
|
||||
} else {
|
||||
|
||||
@ -10,13 +10,13 @@
|
||||
"contributors": [],
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.4",
|
||||
"@babel/runtime": "^7.4.0",
|
||||
"@polkadot/ui-api": "^0.26.0-beta.6",
|
||||
"@polkadot/ui-identicon": "^0.28.8",
|
||||
"@polkadot/ui-keyring": "^0.28.8",
|
||||
"@polkadot/ui-identicon": "^0.32.0-beta.1",
|
||||
"@polkadot/ui-keyring": "^0.32.0-beta.1",
|
||||
"@polkadot/ui-reactive": "^0.26.0-beta.6",
|
||||
"@polkadot/ui-settings": "^0.28.8",
|
||||
"@polkadot/ui-util": "^0.28.8",
|
||||
"@polkadot/ui-settings": "^0.32.0-beta.1",
|
||||
"@polkadot/ui-util": "^0.32.0-beta.1",
|
||||
"@types/chart.js": "^2.7.45",
|
||||
"@types/classnames": "^2.2.7",
|
||||
"@types/i18next": "^12.1.0",
|
||||
@ -34,8 +34,8 @@
|
||||
"react-dom": "^16.8.2",
|
||||
"react-dropzone": "^7.0.1",
|
||||
"react-i18next": "^10.1.2",
|
||||
"react-router": "^4.3.1",
|
||||
"react-router-dom": "^4.3.1",
|
||||
"react-router": "^5.0.0",
|
||||
"react-router-dom": "^5.0.0",
|
||||
"semantic-ui-css": "^2.3.1",
|
||||
"semantic-ui-react": "^0.85.0",
|
||||
"store": "^2.0.12"
|
||||
|
||||
@ -10,6 +10,7 @@ import styled from 'styled-components';
|
||||
import { Method, getTypeDef } from '@polkadot/types';
|
||||
import Params from '@polkadot/ui-params';
|
||||
|
||||
import Labelled from './Labelled';
|
||||
import { classes } from './util';
|
||||
|
||||
export type Props = BareProps & {
|
||||
@ -21,7 +22,6 @@ const Wrapper = styled.div`
|
||||
.hash {
|
||||
opacity: 0.5;
|
||||
overflow: hidden;
|
||||
padding: 0 0.5rem 0.75rem 1.75rem;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
`;
|
||||
@ -48,9 +48,11 @@ export default class Call extends React.PureComponent<Props> {
|
||||
{
|
||||
hash
|
||||
? (
|
||||
<div className='hash'>
|
||||
{hash.toHex()}
|
||||
</div>
|
||||
<Labelled label='extrinsic hash'>
|
||||
<div className='hash'>
|
||||
{hash.toHex()}
|
||||
</div>
|
||||
</Labelled>
|
||||
)
|
||||
: null
|
||||
}
|
||||
|
||||
@ -58,30 +58,50 @@ export default class Queue extends React.Component<Props, State> {
|
||||
);
|
||||
}
|
||||
|
||||
private clearAction (id: number): () => void {
|
||||
return (): void => {
|
||||
this.setState(
|
||||
(prevState: State): State => ({
|
||||
stqueue: prevState.stqueue.filter((item) => item.id !== id)
|
||||
} as State)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
queueAction = (status: ActionStatus): number => {
|
||||
const id = ++nextId;
|
||||
const removeItem = this.clearAction(id);
|
||||
|
||||
this.setState(
|
||||
(prevState: State): State => ({
|
||||
stqueue: prevState.stqueue.concat({
|
||||
...status,
|
||||
id,
|
||||
isCompleted: false
|
||||
isCompleted: false,
|
||||
removeItem
|
||||
})
|
||||
} as State)
|
||||
);
|
||||
|
||||
setTimeout(() => {
|
||||
this.setState(
|
||||
(prevState: State): State => ({
|
||||
stqueue: prevState.stqueue.filter((item) => item.id !== id)
|
||||
} as State)
|
||||
);
|
||||
}, REMOVE_TIMEOUT);
|
||||
setTimeout(removeItem, REMOVE_TIMEOUT);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
private clearStatus (id: number): () => void {
|
||||
return () => {
|
||||
this.setState(
|
||||
(prevState: State): State => ({
|
||||
txqueue: prevState.txqueue.map((item) =>
|
||||
item.id === id
|
||||
? { ...item, status: 'completed' }
|
||||
: item
|
||||
)
|
||||
} as State)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
queueSetTxStatus = (id: number, status: QueueTx$Status, result?: SubmittableResult, error?: Error): void => {
|
||||
this.setState(
|
||||
(prevState: State): State => ({
|
||||
@ -107,17 +127,7 @@ export default class Queue extends React.Component<Props, State> {
|
||||
this.addResultEvents(result);
|
||||
|
||||
if (STATUS_COMPLETE.includes(status)) {
|
||||
setTimeout(() => {
|
||||
this.setState(
|
||||
(prevState: State): State => ({
|
||||
txqueue: prevState.txqueue.map((item) =>
|
||||
item.id === id
|
||||
? { ...item, status: 'completed' }
|
||||
: item
|
||||
)
|
||||
} as State)
|
||||
);
|
||||
}, REMOVE_TIMEOUT);
|
||||
setTimeout(this.clearStatus(id), REMOVE_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,12 +150,14 @@ export default class Queue extends React.Component<Props, State> {
|
||||
private queueAdd = (value: QueueTx$Extrinsic | QueueTx$Rpc | QueueTx): number => {
|
||||
const id = ++nextId;
|
||||
const rpc: RpcMethod = (value as QueueTx$Rpc).rpc || SUBMIT_RPC;
|
||||
const removeItem = this.clearStatus(id);
|
||||
|
||||
this.setState(
|
||||
(prevState: State): State => ({
|
||||
txqueue: prevState.txqueue.concat([{
|
||||
...value,
|
||||
id,
|
||||
removeItem,
|
||||
rpc,
|
||||
status: 'queued'
|
||||
}])
|
||||
|
||||
@ -38,7 +38,7 @@ class Status extends React.PureComponent<Props> {
|
||||
);
|
||||
}
|
||||
|
||||
private renderStatus = ({ account, action, id, message, status }: QueueStatus) => {
|
||||
private renderStatus = ({ account, action, id, message, removeItem, status }: QueueStatus) => {
|
||||
const addressRendered = account
|
||||
? <AddressMini value={account} />
|
||||
: undefined;
|
||||
@ -46,6 +46,7 @@ class Status extends React.PureComponent<Props> {
|
||||
return (
|
||||
<div
|
||||
className={classes('item', status)}
|
||||
onClick={removeItem}
|
||||
key={id}
|
||||
>
|
||||
<div className='wrapper'>
|
||||
@ -68,7 +69,7 @@ class Status extends React.PureComponent<Props> {
|
||||
);
|
||||
}
|
||||
|
||||
private renderItem = ({ id, extrinsic, error, rpc, status }: QueueTx) => {
|
||||
private renderItem = ({ id, extrinsic, error, removeItem, rpc, status }: QueueTx) => {
|
||||
let { method, section } = rpc;
|
||||
|
||||
if (extrinsic) {
|
||||
@ -85,6 +86,7 @@ class Status extends React.PureComponent<Props> {
|
||||
return (
|
||||
<div
|
||||
className={classes('item', status)}
|
||||
onClick={removeItem}
|
||||
key={id}
|
||||
>
|
||||
<div className='wrapper'>
|
||||
|
||||
@ -33,6 +33,7 @@ export type QueueTx = AccountInfo & {
|
||||
id: number,
|
||||
isUnsigned?: boolean,
|
||||
result?: any,
|
||||
removeItem: () => void,
|
||||
rpc: RpcMethod,
|
||||
signerCb?: SignerCallback,
|
||||
signerOptions?: SignatureOptions,
|
||||
@ -45,7 +46,8 @@ export type QueueTx = AccountInfo & {
|
||||
|
||||
export type QueueStatus = ActionStatus & {
|
||||
id: number,
|
||||
isCompleted: boolean
|
||||
isCompleted: boolean,
|
||||
removeItem: () => void
|
||||
};
|
||||
|
||||
export type QueueTx$Result = {
|
||||
|
||||
@ -5,7 +5,6 @@
|
||||
import { BareProps } from './types';
|
||||
|
||||
import React from 'react';
|
||||
import { withRouter } from 'react-router';
|
||||
import { NavLink } from 'react-router-dom';
|
||||
|
||||
import { classes } from './util';
|
||||
@ -22,7 +21,7 @@ type Props = BareProps & {
|
||||
items: Array<TabItem>
|
||||
};
|
||||
|
||||
class Tabs extends React.PureComponent<Props> {
|
||||
export default class Tabs extends React.PureComponent<Props> {
|
||||
render () {
|
||||
const { className, hidden = [], items, style } = this.props;
|
||||
|
||||
@ -63,5 +62,3 @@ class Tabs extends React.PureComponent<Props> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withRouter(Tabs as React.ComponentType<any>) as any as React.ComponentType<Props>;
|
||||
|
||||
@ -310,6 +310,7 @@ header .ui--Button-Group {
|
||||
position: fixed;
|
||||
right: 0.25rem;
|
||||
top: 0.25rem;
|
||||
width: 20rem;
|
||||
z-index: 1001;
|
||||
|
||||
.ui--IdentityIcon {
|
||||
@ -320,36 +321,35 @@ header .ui--Button-Group {
|
||||
display: block;
|
||||
text-align: right;
|
||||
|
||||
> .wrapper {
|
||||
display: inline-block;
|
||||
> .wrapper > .container {
|
||||
align-items: center;
|
||||
background: #00688b;
|
||||
border-radius: $small-corner;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 0.25rem;
|
||||
padding: 0 0.5rem;
|
||||
text-align: center;
|
||||
opacity: 0.95;
|
||||
vertical-align: middle;
|
||||
|
||||
> .container {
|
||||
align-items: center;
|
||||
background: #00688b;
|
||||
border-radius: $small-corner;
|
||||
color: white;
|
||||
display: flex;
|
||||
margin-bottom: 0.25rem;
|
||||
padding: 0 0.5rem;
|
||||
text-align: center;
|
||||
opacity: 0.95;
|
||||
vertical-align: middle;
|
||||
.desc {
|
||||
flex: 1;
|
||||
padding: 0.5rem 1rem;
|
||||
|
||||
.desc {
|
||||
padding: 0.5rem 1rem;
|
||||
|
||||
.status {
|
||||
font-weight: 700;
|
||||
}
|
||||
.status {
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
|
||||
.short {
|
||||
font-size: 2.5rem;
|
||||
padding: 0.5rem;
|
||||
.short {
|
||||
font-size: 2.5rem;
|
||||
padding: 0.5rem;
|
||||
|
||||
i.icon {
|
||||
line-height: 1;
|
||||
}
|
||||
i.icon {
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -369,8 +369,9 @@ header .ui--Button-Group {
|
||||
background: green;
|
||||
}
|
||||
|
||||
&.dropped > .wrapper > .container ,
|
||||
&.error > .wrapper > .container ,
|
||||
&.dropped > .wrapper > .container,
|
||||
&.error > .wrapper > .container,
|
||||
&.invalid > .wrapper > .container,
|
||||
&.usurped > .wrapper > .container {
|
||||
background: red;
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
"contributors": [],
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.4",
|
||||
"@babel/runtime": "^7.4.0",
|
||||
"@polkadot/ui-app": "^0.26.0-beta.6"
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/ui/tree/master/packages/ui-reactive#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.4",
|
||||
"@babel/runtime": "^7.4.0",
|
||||
"rxjs-compat": "^6.3.2"
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
"contributors": [],
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.4",
|
||||
"@babel/runtime": "^7.4.0",
|
||||
"@polkadot/ui-app": "^0.26.0-beta.6"
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ class Transfer extends React.PureComponent<Props, State> {
|
||||
};
|
||||
|
||||
static getDerivedStateFromProps ({ amount, balances_votingBalance = ZERO_BALANCE, fees, onChange }: Props): State {
|
||||
let extraFees = fees.transferFee;
|
||||
let extraFees = new BN(fees.transferFee);
|
||||
|
||||
if (balances_votingBalance.votingBalance.isZero()) {
|
||||
extraFees = extraFees.add(fees.creationFee);
|
||||
|
||||
@ -328,8 +328,7 @@ class Signer extends React.PureComponent<Props, State> {
|
||||
|
||||
const status = result.type.toLowerCase() as QueueTx$Status;
|
||||
|
||||
console.log('makeExtrinsicCall: updated status ::', result);
|
||||
|
||||
console.log('makeExtrinsicCall: updated status ::', JSON.stringify(result));
|
||||
queueSetTxStatus(id, status, result);
|
||||
|
||||
if (isFunction(txUpdateCb)) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user