Staking updates (#1815)
* Staking updates * Bump API * So currentElected first in next up * Linting * Remove unused state entries
This commit is contained in:
parent
cc4c193497
commit
df095c2829
@ -10,10 +10,10 @@
|
||||
"packages/*"
|
||||
],
|
||||
"resolutions": {
|
||||
"@polkadot/api": "^0.96.0-beta.14",
|
||||
"@polkadot/api-contract": "^0.96.0-beta.14",
|
||||
"@polkadot/api": "^0.96.0-beta.15",
|
||||
"@polkadot/api-contract": "^0.96.0-beta.15",
|
||||
"@polkadot/keyring": "^1.6.1",
|
||||
"@polkadot/types": "^0.96.0-beta.14",
|
||||
"@polkadot/types": "^0.96.0-beta.15",
|
||||
"@polkadot/util": "^1.6.1",
|
||||
"@polkadot/util-crypto": "^1.6.1",
|
||||
"babel-core": "^7.0.0-bridge.0",
|
||||
|
||||
@ -142,7 +142,7 @@ function Create ({ className, onClose, onStatusChange, seed: propsSeed, t, type:
|
||||
setAddress(generateSeed(null, derivePath, newSeedType, pairType));
|
||||
}
|
||||
};
|
||||
const _onChangeName = (name: string): void => setName({ isNameValid: name.trim().length !== 0, name });
|
||||
const _onChangeName = (name: string): void => setName({ isNameValid: !!name.trim(), name });
|
||||
const _toggleConfirmation = (): void => setIsConfirmationOpen(!isConfirmationOpen);
|
||||
|
||||
const _onCommit = (): void => {
|
||||
|
||||
@ -23,11 +23,10 @@ interface Props extends I18nProps, ModalProps {
|
||||
}
|
||||
|
||||
function QrModal ({ className, onClose, onStatusChange, t }: Props): React.ReactElement<Props> {
|
||||
const [name, setName] = useState('');
|
||||
const [{ isNameValid, name }, setName] = useState({ isNameValid: false, name: '' });
|
||||
const [scanned, setScanned] = useState<Scanned | null>(null);
|
||||
const isNameValid = !!name;
|
||||
|
||||
const _onNameChange = (name: string): void => setName(name.trim());
|
||||
const _onNameChange = (name: string): void => setName({ isNameValid: !!name.trim(), name });
|
||||
const _onSave = (): void => {
|
||||
if (!scanned || !isNameValid) {
|
||||
return;
|
||||
@ -35,7 +34,7 @@ function QrModal ({ className, onClose, onStatusChange, t }: Props): React.React
|
||||
|
||||
const { address, genesisHash } = scanned;
|
||||
|
||||
keyring.addExternal(address, { genesisHash, name });
|
||||
keyring.addExternal(address, { genesisHash, name: name.trim() });
|
||||
InputAddress.setLastValue('account', address);
|
||||
|
||||
onStatusChange({
|
||||
|
||||
@ -40,7 +40,7 @@ function Create ({ onClose, onStatusChange, t }: Props): React.ReactElement<Prop
|
||||
isAddressExisting = true;
|
||||
isAddressValid = true;
|
||||
|
||||
setName({ isNameValid: (newName || '').trim().length !== 0, name: newName });
|
||||
setName({ isNameValid: !!(newName || '').trim(), name: newName });
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.6.3",
|
||||
"@polkadot/api-contract": "^0.96.0-beta.14",
|
||||
"@polkadot/api-contract": "^0.96.0-beta.15",
|
||||
"@polkadot/react-components": "^0.37.0-beta.24"
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,6 +70,14 @@ const DEFAULT_BALANCES = {
|
||||
unlocking: false
|
||||
};
|
||||
|
||||
const CONTROLLER_BALANCES = {
|
||||
available: true,
|
||||
bonded: false,
|
||||
free: false,
|
||||
redeemable: false,
|
||||
unlocking: false
|
||||
};
|
||||
|
||||
function toIdString (id?: AccountId | null): string | null {
|
||||
return id
|
||||
? id.toString()
|
||||
@ -133,7 +141,7 @@ class Account extends React.PureComponent<Props, State> {
|
||||
|
||||
public render (): React.ReactNode {
|
||||
const { className, isSubstrateV2, t } = this.props;
|
||||
const { controllerId, hexSessionId, isBondExtraOpen, isInjectOpen, isStashValidating, isUnbondOpen, nominees, sessionIds, stashId } = this.state;
|
||||
const { controllerId, hexSessionId, isBondExtraOpen, isInjectOpen, isStashValidating, isUnbondOpen, nominees, onlineStatus, sessionIds, stashId } = this.state;
|
||||
|
||||
if (!stashId) {
|
||||
return null;
|
||||
@ -146,7 +154,12 @@ class Account extends React.PureComponent<Props, State> {
|
||||
return (
|
||||
<AddressCard
|
||||
buttons={this.renderButtons()}
|
||||
iconInfo={this.renderOnlineStatus()}
|
||||
iconInfo={onlineStatus && (
|
||||
<OnlineStatus
|
||||
isTooltip
|
||||
value={onlineStatus}
|
||||
/>
|
||||
)}
|
||||
label={t('stash')}
|
||||
type='account'
|
||||
value={stashId}
|
||||
@ -176,7 +189,16 @@ class Account extends React.PureComponent<Props, State> {
|
||||
{this.renderValidate()}
|
||||
<div className={className}>
|
||||
<div className='staking--Accounts'>
|
||||
{this.renderControllerAccount()}
|
||||
{controllerId && (
|
||||
<div className='staking--Account-detail actions'>
|
||||
<AddressRow
|
||||
label={t('controller')}
|
||||
value={controllerId}
|
||||
withAddressOrName
|
||||
withBalance={CONTROLLER_BALANCES}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{!isSubstrateV2 && !!sessionIds.length && (
|
||||
<div className='staking--Account-detail actions'>
|
||||
<AddressRow
|
||||
@ -229,49 +251,6 @@ class Account extends React.PureComponent<Props, State> {
|
||||
);
|
||||
}
|
||||
|
||||
private renderOnlineStatus (): React.ReactNode {
|
||||
const { onlineStatus, controllerId } = this.state;
|
||||
|
||||
if (!controllerId || !onlineStatus) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<OnlineStatus
|
||||
accountId={controllerId}
|
||||
value={onlineStatus}
|
||||
tooltip
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
private renderControllerAccount (): React.ReactNode {
|
||||
const { t } = this.props;
|
||||
const { controllerId } = this.state;
|
||||
|
||||
if (!controllerId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='staking--Account-detail actions'>
|
||||
<AddressRow
|
||||
label={t('controller')}
|
||||
value={controllerId}
|
||||
withAddressOrName
|
||||
withBalance={{
|
||||
available: true,
|
||||
bonded: false,
|
||||
free: false,
|
||||
redeemable: false,
|
||||
unlocking: false
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
private renderNominate (): React.ReactNode {
|
||||
const { stashOptions } = this.props;
|
||||
const { controllerId, isNominateOpen, nominees, stashId } = this.state;
|
||||
|
||||
@ -11,10 +11,10 @@ import BN from 'bn.js';
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { ApiContext, withCalls, withMulti } from '@polkadot/react-api';
|
||||
import { AddressCard, AddressMini, OnlineStatus } from '@polkadot/react-components';
|
||||
import { AddressCard, AddressMini, Badge, Icon, OnlineStatus } from '@polkadot/react-components';
|
||||
import { classes } from '@polkadot/react-components/util';
|
||||
import keyring from '@polkadot/ui-keyring';
|
||||
import { formatBalance, formatNumber } from '@polkadot/util';
|
||||
import { formatNumber } from '@polkadot/util';
|
||||
import { updateOnlineStatus } from '../util';
|
||||
|
||||
import translate from '../translate';
|
||||
@ -23,6 +23,7 @@ interface Props extends I18nProps {
|
||||
address: string;
|
||||
authorsMap: Record<string, string>;
|
||||
className?: string;
|
||||
currentElected: string[];
|
||||
defaultName: string;
|
||||
filter: ValidatorFilter;
|
||||
lastAuthor?: string;
|
||||
@ -36,9 +37,11 @@ interface StakingState {
|
||||
balanceOpts: { bonded: boolean | BN[] };
|
||||
controllerId?: string;
|
||||
hasNominators: boolean;
|
||||
isNominatorMe: boolean;
|
||||
isSelected: boolean;
|
||||
nominators: [AccountId, Balance][];
|
||||
stashActive: string | null;
|
||||
stashTotal: string | null;
|
||||
// stashActive: string | null;
|
||||
// stashTotal: string | null;
|
||||
sessionId?: string;
|
||||
stashId?: string;
|
||||
}
|
||||
@ -50,20 +53,21 @@ interface OnlineState {
|
||||
|
||||
const WITH_VALIDATOR_PREFS = { validatorPayment: true };
|
||||
|
||||
function Address ({ authorsMap, className, defaultName, filter, lastAuthor, points, recentlyOnline, stakingInfo, t, withNominations }: Props): React.ReactElement<Props> | null {
|
||||
function Address ({ address, authorsMap, className, currentElected, defaultName, filter, lastAuthor, points, recentlyOnline, stakingInfo, t, withNominations }: Props): React.ReactElement<Props> | null {
|
||||
const { isSubstrateV2 } = useContext(ApiContext);
|
||||
const [extraInfo, setExtraInfo] = useState<[React.ReactNode, React.ReactNode][] | undefined>();
|
||||
const [isNominatorMe, seIsNominatorMe] = useState(false);
|
||||
const [{ hasOfflineWarnings, onlineStatus }, setOnlineStatus] = useState<OnlineState>({
|
||||
hasOfflineWarnings: false,
|
||||
onlineStatus: {}
|
||||
});
|
||||
const [{ balanceOpts, controllerId, hasNominators, nominators, sessionId, stashId }, setStakingState] = useState<StakingState>({
|
||||
const [{ balanceOpts, controllerId, hasNominators, isNominatorMe, isSelected, nominators, sessionId, stashId }, setStakingState] = useState<StakingState>({
|
||||
balanceOpts: { bonded: true },
|
||||
hasNominators: false,
|
||||
nominators: [],
|
||||
stashActive: null,
|
||||
stashTotal: null
|
||||
isNominatorMe: false,
|
||||
isSelected: false,
|
||||
nominators: []
|
||||
// stashActive: null,
|
||||
// stashTotal: null
|
||||
});
|
||||
|
||||
useEffect((): void => {
|
||||
@ -78,15 +82,13 @@ function Address ({ authorsMap, className, defaultName, filter, lastAuthor, poin
|
||||
|
||||
useEffect((): void => {
|
||||
if (stakingInfo) {
|
||||
const { controllerId, nextSessionId, stakers, stakingLedger, stashId } = stakingInfo;
|
||||
const { controllerId, nextSessionId, stakers, stashId } = stakingInfo;
|
||||
const nominators = stakers
|
||||
? stakers.others.map(({ who, value }): [AccountId, Balance] => [who, value.unwrap()])
|
||||
: [];
|
||||
const myAccounts = keyring.getAccounts().map(({ address }): string => address);
|
||||
const _stashId = stashId && stashId.toString();
|
||||
|
||||
seIsNominatorMe(nominators.some(([who]): boolean =>
|
||||
myAccounts.includes(who.toString())
|
||||
));
|
||||
setStakingState({
|
||||
balanceOpts: {
|
||||
bonded: stakers && !stakers.own.isEmpty
|
||||
@ -95,18 +97,22 @@ function Address ({ authorsMap, className, defaultName, filter, lastAuthor, poin
|
||||
},
|
||||
controllerId: controllerId && controllerId.toString(),
|
||||
hasNominators: nominators.length !== 0,
|
||||
isNominatorMe: nominators.some(([who]): boolean =>
|
||||
myAccounts.includes(who.toString())
|
||||
),
|
||||
isSelected: !!(_stashId && currentElected && currentElected.includes(_stashId)),
|
||||
nominators,
|
||||
sessionId: nextSessionId && nextSessionId.toString(),
|
||||
stashActive: stakingLedger
|
||||
? formatBalance(stakingLedger.active)
|
||||
: null,
|
||||
stashId: stashId && stashId.toString(),
|
||||
stashTotal: stakingLedger
|
||||
? formatBalance(stakingLedger.total)
|
||||
: null
|
||||
// stashActive: stakingLedger
|
||||
// ? formatBalance(stakingLedger.active)
|
||||
// : null,
|
||||
// stashTotal: stakingLedger
|
||||
// ? formatBalance(stakingLedger.total)
|
||||
// : null,
|
||||
stashId: _stashId
|
||||
});
|
||||
}
|
||||
}, [stakingInfo]);
|
||||
}, [currentElected, stakingInfo]);
|
||||
|
||||
useEffect((): void => {
|
||||
if (stakingInfo) {
|
||||
@ -120,14 +126,27 @@ function Address ({ authorsMap, className, defaultName, filter, lastAuthor, poin
|
||||
}
|
||||
}, [recentlyOnline, stakingInfo]);
|
||||
|
||||
if (!stashId || (filter === 'hasNominators' && !hasNominators) ||
|
||||
if ((filter === 'hasNominators' && !hasNominators) ||
|
||||
(filter === 'noNominators' && hasNominators) ||
|
||||
(filter === 'hasWarnings' && !hasOfflineWarnings) ||
|
||||
(filter === 'noWarnings' && hasOfflineWarnings) ||
|
||||
(filter === 'iNominated' && !isNominatorMe)) {
|
||||
(filter === 'iNominated' && !isNominatorMe) ||
|
||||
(filter === 'nextSet' && !isSelected)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!stashId) {
|
||||
return (
|
||||
<AddressCard
|
||||
className={className}
|
||||
defaultName={defaultName}
|
||||
isDisabled
|
||||
value={address}
|
||||
withBalance={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const lastBlockNumber = authorsMap[stashId];
|
||||
const isAuthor = lastAuthor === stashId;
|
||||
// isDisabled={!!points && points.isEmpty}
|
||||
@ -156,14 +175,24 @@ function Address ({ authorsMap, className, defaultName, filter, lastAuthor, poin
|
||||
className={className}
|
||||
defaultName={defaultName}
|
||||
extraInfo={extraInfo}
|
||||
iconInfo={controllerId && onlineStatus && (
|
||||
<OnlineStatus
|
||||
accountId={controllerId}
|
||||
value={onlineStatus}
|
||||
tooltip
|
||||
/>
|
||||
)}
|
||||
key={stashId}
|
||||
iconInfo={
|
||||
<>
|
||||
{controllerId && onlineStatus && (
|
||||
<OnlineStatus
|
||||
value={onlineStatus}
|
||||
isTooltip
|
||||
/>
|
||||
)}
|
||||
{isSelected && (
|
||||
<Badge
|
||||
hover={t('Selected for the next session')}
|
||||
info={<Icon name='check' />}
|
||||
isTooltip
|
||||
type='next'
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
value={stashId}
|
||||
withBalance={balanceOpts}
|
||||
withValidatorPrefs={WITH_VALIDATOR_PREFS}
|
||||
|
||||
@ -15,6 +15,7 @@ import Address from './Address';
|
||||
|
||||
interface Props extends I18nProps {
|
||||
authorsMap: Record<string, string>;
|
||||
currentElected: string[];
|
||||
currentValidators: string[];
|
||||
eraPoints?: EraPoints;
|
||||
lastAuthor?: string;
|
||||
@ -22,11 +23,12 @@ interface Props extends I18nProps {
|
||||
recentlyOnline?: DerivedHeartbeats;
|
||||
}
|
||||
|
||||
function renderColumn (addresses: string[], defaultName: string, withExpanded: boolean, filter: string, { authorsMap, eraPoints, lastAuthor, recentlyOnline }: Props): React.ReactNode {
|
||||
return addresses.map((address, index): React.ReactNode => (
|
||||
function renderColumn (addresses: string[], defaultName: string, withExpanded: boolean, filter: string, without: string[], { authorsMap, currentElected, eraPoints, lastAuthor, recentlyOnline }: Props): React.ReactNode {
|
||||
return addresses.filter((address): boolean => !without.includes(address)).map((address, index): React.ReactNode => (
|
||||
<Address
|
||||
address={address}
|
||||
authorsMap={authorsMap}
|
||||
currentElected={currentElected}
|
||||
defaultName={defaultName}
|
||||
filter={filter}
|
||||
lastAuthor={lastAuthor}
|
||||
@ -44,7 +46,7 @@ function renderColumn (addresses: string[], defaultName: string, withExpanded: b
|
||||
|
||||
function CurrentList (props: Props): React.ReactElement<Props> {
|
||||
const [filter, setFilter] = useState<ValidatorFilter>('all');
|
||||
const { currentValidators, next, t } = props;
|
||||
const { currentElected, currentValidators, next, t } = props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
@ -57,7 +59,8 @@ function CurrentList (props: Props): React.ReactElement<Props> {
|
||||
{ text: t('Show only with nominators'), value: 'hasNominators' },
|
||||
{ text: t('Show only without nominators'), value: 'noNominators' },
|
||||
{ text: t('Show only with warnings'), value: 'hasWarnings' },
|
||||
{ text: t('Show only without warnings'), value: 'noWarnings' }
|
||||
{ text: t('Show only without warnings'), value: 'noWarnings' },
|
||||
{ text: t('Show only elected for next session'), value: 'nextSet' }
|
||||
]}
|
||||
value={filter}
|
||||
withLabel={false}
|
||||
@ -68,13 +71,14 @@ function CurrentList (props: Props): React.ReactElement<Props> {
|
||||
emptyText={t('No addresses found')}
|
||||
headerText={t('validators')}
|
||||
>
|
||||
{renderColumn(currentValidators, t('validator'), true, filter, props)}
|
||||
{renderColumn(currentValidators, t('validator'), true, filter, [], props)}
|
||||
</Column>
|
||||
<Column
|
||||
emptyText={t('No addresses found')}
|
||||
headerText={t('next up')}
|
||||
>
|
||||
{renderColumn(next, t('intention'), false, filter, props)}
|
||||
{renderColumn(currentElected, t('intention'), false, filter, currentValidators, props)}
|
||||
{renderColumn(next, t('intention'), false, filter, currentElected || [], props)}
|
||||
</Column>
|
||||
</Columar>
|
||||
</div>
|
||||
|
||||
@ -18,14 +18,13 @@ interface Props extends BareProps, ComponentProps {
|
||||
eraPoints?: EraPoints;
|
||||
}
|
||||
|
||||
export default function Overview (props: Props): React.ReactElement<Props> {
|
||||
export default function Overview ({ allControllers, allStashes, currentElected, currentValidators, eraPoints, recentlyOnline }: Props): React.ReactElement<Props> {
|
||||
const { isSubstrateV2 } = useContext(ApiContext);
|
||||
const { byAuthor, lastBlockAuthor, lastBlockNumber } = useContext(BlockAuthorsContext);
|
||||
const [nextSorted, setNextSorted] = useState<string[]>([]);
|
||||
const { allControllers, allStashes, currentValidators, eraPoints, recentlyOnline } = props;
|
||||
const [next, setNext] = useState<string[]>([]);
|
||||
|
||||
useEffect((): void => {
|
||||
setNextSorted(
|
||||
setNext(
|
||||
isSubstrateV2
|
||||
// this is a V2 node currentValidators is a list of stashes
|
||||
? allStashes.filter((address): boolean => !currentValidators.includes(address))
|
||||
@ -38,17 +37,19 @@ export default function Overview (props: Props): React.ReactElement<Props> {
|
||||
<div className='staking--Overview'>
|
||||
<Summary
|
||||
allControllers={allControllers}
|
||||
currentElected={currentElected}
|
||||
currentValidators={currentValidators}
|
||||
lastBlock={lastBlockNumber}
|
||||
lastAuthor={lastBlockAuthor}
|
||||
next={nextSorted}
|
||||
next={next}
|
||||
/>
|
||||
<CurrentList
|
||||
authorsMap={byAuthor}
|
||||
currentElected={currentElected}
|
||||
currentValidators={currentValidators}
|
||||
eraPoints={eraPoints}
|
||||
lastAuthor={lastBlockAuthor}
|
||||
next={nextSorted}
|
||||
next={next}
|
||||
recentlyOnline={recentlyOnline}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -27,6 +27,7 @@ interface Props extends AppProps, ApiProps, I18nProps {
|
||||
allAccounts?: SubjectInfo;
|
||||
allStashesAndControllers?: [string[], string[]];
|
||||
bestNumber?: BlockNumber;
|
||||
currentElected?: string[];
|
||||
currentValidators?: string[];
|
||||
eraPoints?: EraPoints;
|
||||
recentlyOnline?: DerivedHeartbeats;
|
||||
@ -35,7 +36,7 @@ interface Props extends AppProps, ApiProps, I18nProps {
|
||||
const EMPY_ACCOUNTS: string[] = [];
|
||||
const EMPTY_ALL: [string[], string[]] = [EMPY_ACCOUNTS, EMPY_ACCOUNTS];
|
||||
|
||||
function App ({ allAccounts, allStashesAndControllers: [allStashes, allControllers] = EMPTY_ALL, className, currentValidators = EMPY_ACCOUNTS, basePath, eraPoints, recentlyOnline, t }: Props): React.ReactElement<Props> {
|
||||
function App ({ allAccounts, allStashesAndControllers: [allStashes, allControllers] = EMPTY_ALL, className, currentElected, currentValidators, basePath, eraPoints, recentlyOnline, t }: Props): React.ReactElement<Props> {
|
||||
const _renderComponent = (Component: React.ComponentType<ComponentProps>): () => React.ReactNode => {
|
||||
// eslint-disable-next-line react/display-name
|
||||
return (): React.ReactNode => {
|
||||
@ -48,7 +49,8 @@ function App ({ allAccounts, allStashesAndControllers: [allStashes, allControlle
|
||||
allAccounts={allAccounts}
|
||||
allControllers={allControllers}
|
||||
allStashes={allStashes}
|
||||
currentValidators={currentValidators}
|
||||
currentElected={currentElected || EMPY_ACCOUNTS}
|
||||
currentValidators={currentValidators || EMPY_ACCOUNTS}
|
||||
eraPoints={eraPoints}
|
||||
recentlyOnline={recentlyOnline}
|
||||
/>
|
||||
@ -111,6 +113,11 @@ export default withMulti(
|
||||
transform: (validators: AccountId[]): string[] =>
|
||||
validators.map((accountId): string => accountId.toString())
|
||||
}],
|
||||
['query.staking.currentElected', {
|
||||
propName: 'currentElected',
|
||||
transform: (elected: AccountId[]): string[] =>
|
||||
elected.map((accountId): string => accountId.toString())
|
||||
}],
|
||||
['query.staking.currentEra', { propName: 'currentEra' }],
|
||||
['query.staking.currentEraPointsEarned', { paramName: 'currentEra', propName: 'eraPoints' }]
|
||||
),
|
||||
|
||||
@ -14,6 +14,7 @@ export interface ComponentProps {
|
||||
allAccounts?: SubjectInfo;
|
||||
allControllers: string[];
|
||||
allStashes: string[];
|
||||
currentElected: string[];
|
||||
currentValidators: string[];
|
||||
eraPoints?: EraPoints;
|
||||
recentlyOnline?: DerivedHeartbeats;
|
||||
@ -27,4 +28,4 @@ export interface CalculateBalanceProps {
|
||||
|
||||
export type AccountFilter = 'all' | 'controller' | 'session' | 'stash' | 'unbonded';
|
||||
|
||||
export type ValidatorFilter = 'all' | 'hasNominators' | 'noNominators' | 'hasWarnings' | 'noWarnings' | 'iNominated';
|
||||
export type ValidatorFilter = 'all' | 'hasNominators' | 'noNominators' | 'hasWarnings' | 'noWarnings' | 'iNominated' | 'nextSet';
|
||||
|
||||
@ -11,6 +11,7 @@ import { BareProps as Props } from '@polkadot/react-components/types';
|
||||
import React, { useState } from 'react';
|
||||
import store from 'store';
|
||||
import styled from 'styled-components';
|
||||
import { withCalls } from '@polkadot/react-api';
|
||||
import GlobalStyle from '@polkadot/react-components/styles';
|
||||
import Signer from '@polkadot/react-signer';
|
||||
|
||||
@ -27,6 +28,24 @@ interface SidebarState {
|
||||
transition: SideBarTransition;
|
||||
}
|
||||
|
||||
function Placeholder (): React.ReactElement {
|
||||
return (
|
||||
<div className='api-warm' />
|
||||
);
|
||||
}
|
||||
|
||||
const WarmUp = withCalls<{}>(
|
||||
'derive.accounts.indexes',
|
||||
'derive.balances.fees',
|
||||
'query.session.validators'
|
||||
// This are very ineffective queries that
|
||||
// (a) adds load to the RPC node when activated globally
|
||||
// (b) is used in additional information (next-up)
|
||||
// 'derive.staking.all'
|
||||
// 'derive.staking.controllers'
|
||||
// 'query.staking.nominators'
|
||||
)(Placeholder);
|
||||
|
||||
function Apps ({ className }: Props): React.ReactElement<Props> {
|
||||
const [sidebar, setSidebar] = useState<SidebarState>({
|
||||
isCollapsed: false,
|
||||
@ -77,6 +96,7 @@ function Apps ({ className }: Props): React.ReactElement<Props> {
|
||||
<ConnectingOverlay />
|
||||
<AccountsOverlay />
|
||||
</div>
|
||||
<WarmUp />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@ -3,20 +3,19 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { I18nProps } from '@polkadot/react-components/types';
|
||||
import { ApiProps } from '@polkadot/react-api/types';
|
||||
|
||||
import React, { useContext } from 'react';
|
||||
import { withRouter, RouteComponentProps } from 'react-router';
|
||||
import styled from 'styled-components';
|
||||
import routing from '@polkadot/apps-routing';
|
||||
import { withCalls, withMulti } from '@polkadot/react-api';
|
||||
import { ApiContext } from '@polkadot/react-api';
|
||||
import { StatusContext } from '@polkadot/react-components';
|
||||
|
||||
import Status from './Status';
|
||||
import translate from '../translate';
|
||||
import NotFound from './NotFound';
|
||||
|
||||
interface Props extends I18nProps, ApiProps, RouteComponentProps {}
|
||||
interface Props extends I18nProps, RouteComponentProps {}
|
||||
|
||||
const unknown = {
|
||||
display: {
|
||||
@ -26,7 +25,8 @@ const unknown = {
|
||||
name: ''
|
||||
};
|
||||
|
||||
function Content ({ isApiConnected, isApiReady, className, location, t }: Props): React.ReactElement<Props> {
|
||||
function Content ({ className, location, t }: Props): React.ReactElement<Props> {
|
||||
const { isApiConnected, isApiReady } = useContext(ApiContext);
|
||||
const { queueAction, stqueue, txqueue } = useContext(StatusContext);
|
||||
const app = location.pathname.slice(1) || '';
|
||||
const { Component, display: { needsApi }, name } = routing.routes.find((route): boolean =>
|
||||
@ -57,7 +57,7 @@ function Content ({ isApiConnected, isApiReady, className, location, t }: Props)
|
||||
}
|
||||
|
||||
// React-router needs to be first, otherwise we have blocked updates
|
||||
export default withMulti(
|
||||
export default translate(
|
||||
withRouter(
|
||||
styled(Content)`
|
||||
background: #fafafa;
|
||||
@ -79,18 +79,5 @@ export default withMulti(
|
||||
padding: 1rem 0;
|
||||
}
|
||||
`
|
||||
),
|
||||
translate,
|
||||
// These API queries are used in a number of places, warm them up
|
||||
// to avoid constant un-/re-subscribe on these
|
||||
withCalls<Props>(
|
||||
'derive.accounts.indexes',
|
||||
'derive.balances.fees',
|
||||
'query.session.validators'
|
||||
// This are very ineffective queries that
|
||||
// (a) adds load to the RPC node when activated globally
|
||||
// (b) is used in additional information (next-up)
|
||||
// 'derive.staking.controllers'
|
||||
// 'query.staking.nominators'
|
||||
)
|
||||
);
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
"homepage": "https://github.com/polkadot-js/ui/tree/master/packages/ui-reactive#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.6.3",
|
||||
"@polkadot/api": "^0.96.0-beta.14",
|
||||
"@polkadot/api": "^0.96.0-beta.15",
|
||||
"@polkadot/extension-dapp": "^0.14.0-beta.1",
|
||||
"edgeware-node-types": "^1.0.10",
|
||||
"rxjs-compat": "^6.5.3"
|
||||
|
||||
104
packages/react-components/src/Badge.tsx
Normal file
104
packages/react-components/src/Badge.tsx
Normal file
@ -0,0 +1,104 @@
|
||||
// Copyright 2017-2019 @polkadot/app-staking authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import Tooltip from './Tooltip';
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
hover: React.ReactNode;
|
||||
info: React.ReactNode;
|
||||
isTooltip?: boolean;
|
||||
type: 'online' | 'offline' | 'next';
|
||||
}
|
||||
|
||||
let badgeId = 0;
|
||||
|
||||
function Badge ({ className, hover, info, isTooltip, type }: Props): React.ReactElement<Props> | null {
|
||||
const [key] = useState(`${Date.now()}-${badgeId++}`);
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
const _toggleOpen = (): void => setIsOpen(!isOpen);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`ui--Badge ${isOpen && 'expand'} ${isTooltip && 'tooltip'} ${type} ${className}`}
|
||||
onClick={
|
||||
isTooltip
|
||||
? _toggleOpen
|
||||
: undefined
|
||||
}
|
||||
data-for={`badge-status-${key}`}
|
||||
data-tip={true}
|
||||
data-tip-disable={!isTooltip}
|
||||
>
|
||||
<div className='badge'>
|
||||
{info}
|
||||
</div>
|
||||
<div className='detail'>
|
||||
{hover}
|
||||
</div>
|
||||
<Tooltip
|
||||
trigger={`badge-status-${key}`}
|
||||
text={hover}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default styled(Badge)`
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 3px 3px rgba(0, 0, 0, 0.2);
|
||||
color: #eee;
|
||||
cursor: help;
|
||||
display: flex;
|
||||
font-size: 12px;
|
||||
height: 22px;
|
||||
justify-content: center;
|
||||
margin-bottom: 0.25rem;
|
||||
padding: 0 4px;
|
||||
text-align: center;
|
||||
width: 22px;
|
||||
|
||||
&.next {
|
||||
background: steelblue;
|
||||
}
|
||||
|
||||
&.offline {
|
||||
background: red;
|
||||
}
|
||||
|
||||
&.online {
|
||||
background: green;
|
||||
}
|
||||
|
||||
& > * {
|
||||
line-height: 22px;
|
||||
overflow: hidden;
|
||||
transition: all ease 0.25;
|
||||
}
|
||||
|
||||
.badge {
|
||||
font-weight: bold;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.detail {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
&.expand {
|
||||
width: 300px;
|
||||
|
||||
.badge {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.detail {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
`;
|
||||
@ -3,156 +3,73 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { DerivedStakingOnlineStatus } from '@polkadot/api-derive/types';
|
||||
import { AccountId } from '@polkadot/types/interfaces';
|
||||
import { I18nProps } from './types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { formatNumber } from '@polkadot/util';
|
||||
|
||||
import Badge from './Badge';
|
||||
import Icon from './Icon';
|
||||
import Tooltip from './Tooltip';
|
||||
|
||||
import translate from './translate';
|
||||
import { classes } from './util';
|
||||
|
||||
interface Props extends I18nProps {
|
||||
accountId: AccountId | string;
|
||||
tooltip?: boolean;
|
||||
isTooltip?: boolean;
|
||||
value: DerivedStakingOnlineStatus;
|
||||
}
|
||||
|
||||
function OnlineStatus ({ accountId, className, value, tooltip = false, t }: Props): React.ReactElement<Props> | null {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [version, setVersion] = useState<string | null>(null);
|
||||
|
||||
const _toggleOpen = (): void => setIsOpen(!isOpen);
|
||||
function OnlineStatus ({ className, value, isTooltip = false, t }: Props): React.ReactElement<Props> | null {
|
||||
const [{ hover, info, type }, setType] = useState<{ hover: React.ReactNode; info: React.ReactNode; type: 'online' | 'offline' | null }>({ hover: '', info: '', type: null });
|
||||
|
||||
useEffect((): void => {
|
||||
const { online, offline } = value;
|
||||
let hover: React.ReactNode = '';
|
||||
let info: React.ReactNode = '';
|
||||
let type: 'online' | 'offline' | null = null;
|
||||
|
||||
if (offline) {
|
||||
setVersion('offline');
|
||||
} else if (online && online.isOnline) {
|
||||
setVersion('online');
|
||||
} else {
|
||||
setVersion(null);
|
||||
}
|
||||
}, [value]);
|
||||
const count = offline.reduce((total, { count }): BN => total.add(count), new BN(0));
|
||||
const blockNumbers = offline.map(({ blockNumber }): string => `#${formatNumber(blockNumber)}`);
|
||||
|
||||
const key = accountId.toString();
|
||||
const classNames: (string | false | undefined)[] = ['ui--OnlineStatus', isOpen && 'expand', tooltip && 'tooltip', className];
|
||||
let text: string;
|
||||
let contents: React.ReactNode;
|
||||
let offline;
|
||||
let count;
|
||||
let blockNumbers;
|
||||
let blockNumber;
|
||||
|
||||
switch (version) {
|
||||
case 'offline':
|
||||
offline = value.offline || [];
|
||||
count = offline.reduce((total, { count }): BN => total.add(count), new BN(0));
|
||||
blockNumbers = offline.map(({ blockNumber }): string => `#${formatNumber(blockNumber)}`);
|
||||
|
||||
classNames.push('offline');
|
||||
contents = count.toString();
|
||||
text = t('Reported offline {{count}} times, last at {{blockNumber}}', {
|
||||
info = count.toString();
|
||||
hover = t('Reported offline {{count}} times, last at {{blockNumber}}', {
|
||||
replace: {
|
||||
count,
|
||||
blockNumber: blockNumbers[blockNumbers.length - 1]
|
||||
}
|
||||
});
|
||||
break;
|
||||
type = 'offline';
|
||||
} else if (online && online.isOnline) {
|
||||
const blockNumber = value.online ? value.online.blockNumber : null;
|
||||
|
||||
case 'online':
|
||||
classNames.push('online');
|
||||
blockNumber = value.online ? value.online.blockNumber : null;
|
||||
contents = <Icon name='check' />;
|
||||
text = blockNumber
|
||||
info = <Icon name='check' />;
|
||||
hover = blockNumber
|
||||
? t('Reported online at #{{blockNumber}}', {
|
||||
replace: {
|
||||
blockNumber: formatNumber(blockNumber)
|
||||
}
|
||||
})
|
||||
: t('Reported online in the current session');
|
||||
break;
|
||||
type = 'online';
|
||||
}
|
||||
|
||||
default:
|
||||
return null;
|
||||
setType({ hover, info, type });
|
||||
}, [value]);
|
||||
|
||||
if (!type) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classes(...classNames)}
|
||||
{...(!tooltip ? { onClick: _toggleOpen } : {})}
|
||||
data-for={`online-status-${key}`}
|
||||
data-tip={true}
|
||||
data-tip-disable={!tooltip}
|
||||
>
|
||||
<div className='badge'>
|
||||
{contents}
|
||||
</div>
|
||||
<div className='detail'>
|
||||
{text}
|
||||
</div>
|
||||
<Tooltip
|
||||
trigger={`online-status-${key}`}
|
||||
text={text}
|
||||
/>
|
||||
</div>
|
||||
<Badge
|
||||
className={`ui--OnlineStatus ${className}`}
|
||||
hover={hover}
|
||||
info={info}
|
||||
isTooltip={isTooltip}
|
||||
type={type}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default translate(
|
||||
styled(OnlineStatus)`
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 3px 3px rgba(0, 0, 0, 0.2);
|
||||
color: #eee;
|
||||
cursor: help;
|
||||
display: flex;
|
||||
font-size: 12px;
|
||||
height: 22px;
|
||||
justify-content: center;
|
||||
padding: 0 4px;
|
||||
text-align: center;
|
||||
transition: all ease .2s;
|
||||
width: 22px;
|
||||
|
||||
&.offline {
|
||||
background: red;
|
||||
}
|
||||
|
||||
&.online {
|
||||
background: green;
|
||||
}
|
||||
|
||||
& > * {
|
||||
line-height: 22px;
|
||||
overflow: hidden;
|
||||
transition: all ease 0.25;
|
||||
}
|
||||
|
||||
.badge {
|
||||
font-weight: bold;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.detail {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
&.expand {
|
||||
width: 300px;
|
||||
|
||||
.badge {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.detail {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
`
|
||||
);
|
||||
export default translate(OnlineStatus);
|
||||
|
||||
@ -8,6 +8,7 @@ export { default as AddressInfo } from './AddressInfo';
|
||||
export { default as AddressMini } from './AddressMini';
|
||||
export { default as AddressRow } from './AddressRow';
|
||||
export { default as Available } from './Available';
|
||||
export { default as Badge } from './Badge';
|
||||
export { default as Balance } from './Balance';
|
||||
export { default as Bonded } from './Bonded';
|
||||
export { default as Bubble } from './Bubble';
|
||||
|
||||
90
yarn.lock
90
yarn.lock
@ -2016,45 +2016,45 @@
|
||||
once "^1.4.0"
|
||||
universal-user-agent "^4.0.0"
|
||||
|
||||
"@polkadot/api-contract@^0.96.0-beta.14":
|
||||
version "0.96.0-beta.14"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/api-contract/-/api-contract-0.96.0-beta.14.tgz#26587385589cd5a351cfc4a5694ddde8a9033a26"
|
||||
integrity sha512-78c1YR2YTqAden9APlu40noELrSR/dOHhGRFmk7zkoyeAaHgPH65An2lQBcEU4fzBUhjorWjb1Pd7IBbW/GK7Q==
|
||||
"@polkadot/api-contract@^0.96.0-beta.15":
|
||||
version "0.96.0-beta.15"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/api-contract/-/api-contract-0.96.0-beta.15.tgz#25c910de8535a52daf7a08dc8c19cb4c74985a21"
|
||||
integrity sha512-QXQANhO2BrtORbQgIHEhEhM8JIMwo30Axhug5xKa9SQQ/FnHWt0dslU9qutGfqJngGFE0HSyn1WSrPoBXgZSzA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.6.3"
|
||||
"@polkadot/types" "^0.96.0-beta.14"
|
||||
"@polkadot/types" "^0.96.0-beta.15"
|
||||
|
||||
"@polkadot/api-derive@^0.96.0-beta.14":
|
||||
version "0.96.0-beta.14"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/api-derive/-/api-derive-0.96.0-beta.14.tgz#ae7faf61965f5934a683ecae23f46fb6243dc793"
|
||||
integrity sha512-w92geU6JQDCoKJ/pPKIUitYNNcdgsDj2NLH5I1JBtMBhu6JGb5YZKDwyKH1Q4fmBk7gLD1ibyU/i1NiY945xEg==
|
||||
"@polkadot/api-derive@^0.96.0-beta.15":
|
||||
version "0.96.0-beta.15"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/api-derive/-/api-derive-0.96.0-beta.15.tgz#a0bb19445eccee7f480d87724e5b31d398c59bab"
|
||||
integrity sha512-0Dg9QJUapk4GAJIHIYCw9hgpeZNBYiI797rtv1njWu6Pcpqv2TwrrHFiSZT6uC7Xz2r7k+prkjNhf42Q74T1Jg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.6.3"
|
||||
"@polkadot/api" "^0.96.0-beta.14"
|
||||
"@polkadot/types" "^0.96.0-beta.14"
|
||||
"@polkadot/api" "^0.96.0-beta.15"
|
||||
"@polkadot/types" "^0.96.0-beta.15"
|
||||
|
||||
"@polkadot/api-metadata@^0.96.0-beta.14":
|
||||
version "0.96.0-beta.14"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/api-metadata/-/api-metadata-0.96.0-beta.14.tgz#5eb4054b943e8af8ee2d39379b7695ac8301a107"
|
||||
integrity sha512-g1tqyan014T9qZdLSi6lNeOozQ0gfJFS6SPx3TDqTbFm4ITVoviq+53n/+7VDf4HrRmC28Yp5Aku3pvUfPjSWA==
|
||||
"@polkadot/api-metadata@^0.96.0-beta.15":
|
||||
version "0.96.0-beta.15"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/api-metadata/-/api-metadata-0.96.0-beta.15.tgz#4d94e41e681f4bd68d4dab22bbbedbd89b23c29e"
|
||||
integrity sha512-SFjoMRtQzxE35y39Rw0+ujvVif6gC015rKcjPsZbRTbbrleJsNNvwSm0OuqEUVRmnQShkafConM6AFv1Cbyigw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.6.3"
|
||||
"@polkadot/types" "^0.96.0-beta.14"
|
||||
"@polkadot/types" "^0.96.0-beta.15"
|
||||
"@polkadot/util" "^1.6.1"
|
||||
"@polkadot/util-crypto" "^1.6.1"
|
||||
|
||||
"@polkadot/api@^0.96.0-beta.14":
|
||||
version "0.96.0-beta.14"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-0.96.0-beta.14.tgz#e9979c874549a876b388dd476eccd1a4870f11db"
|
||||
integrity sha512-WmQMwhwyF6ymhOwpyiymOAlLByb1rkew+OkCaZqF3N2sSy9E15XFJR5MjnrqN/Yz64GRqrCrFGKAgVl14zaxgA==
|
||||
"@polkadot/api@^0.96.0-beta.15":
|
||||
version "0.96.0-beta.15"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-0.96.0-beta.15.tgz#e12ac1ff2dd5136bbbeb8e7c9695c16ca965b31d"
|
||||
integrity sha512-9D5je8yQxQl/tbNU5vdF4FLCFH5in0XDaxdmhOd2E8/HN/JyEhISL+t/S0x787VcoOcch6GI4P4Qpb0a3BXEDg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.6.3"
|
||||
"@polkadot/api-derive" "^0.96.0-beta.14"
|
||||
"@polkadot/api-metadata" "^0.96.0-beta.14"
|
||||
"@polkadot/api-derive" "^0.96.0-beta.15"
|
||||
"@polkadot/api-metadata" "^0.96.0-beta.15"
|
||||
"@polkadot/keyring" "^1.6.1"
|
||||
"@polkadot/rpc-core" "^0.96.0-beta.14"
|
||||
"@polkadot/rpc-provider" "^0.96.0-beta.14"
|
||||
"@polkadot/types" "^0.96.0-beta.14"
|
||||
"@polkadot/rpc-core" "^0.96.0-beta.15"
|
||||
"@polkadot/rpc-provider" "^0.96.0-beta.15"
|
||||
"@polkadot/types" "^0.96.0-beta.15"
|
||||
"@polkadot/util-crypto" "^1.6.1"
|
||||
|
||||
"@polkadot/dev-react@^0.32.0-beta.12":
|
||||
@ -2156,10 +2156,10 @@
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.6.3"
|
||||
|
||||
"@polkadot/jsonrpc@^0.96.0-beta.14":
|
||||
version "0.96.0-beta.14"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/jsonrpc/-/jsonrpc-0.96.0-beta.14.tgz#c68db9f3cffec7dc0dc103c2f13ef91a35293dc1"
|
||||
integrity sha512-pg9S+Pjl/IQAYanvz6hMEDUzujnqbcPzzhQIKIfY6dl1y1iQBWSqGqV/tKhWjK41VEqZYdmhG6R+kIL9yQUfLA==
|
||||
"@polkadot/jsonrpc@^0.96.0-beta.15":
|
||||
version "0.96.0-beta.15"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/jsonrpc/-/jsonrpc-0.96.0-beta.15.tgz#d885b1b17386a8e87dbc5951e8be88ca775a962f"
|
||||
integrity sha512-db08i+S45Gy8c8apM2DtXZVN4bV3pWOmnoKxFxsW7fFatQ0lAeAe2xMdyMSdoU7UiU7OzMO/BIdwLkJe4o3Jnw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.6.3"
|
||||
|
||||
@ -2197,25 +2197,25 @@
|
||||
qrcode-generator "^1.4.4"
|
||||
react-qr-reader "^2.2.1"
|
||||
|
||||
"@polkadot/rpc-core@^0.96.0-beta.14":
|
||||
version "0.96.0-beta.14"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/rpc-core/-/rpc-core-0.96.0-beta.14.tgz#285dc0109f949df1f2a273b15818faf9dbf2cdec"
|
||||
integrity sha512-K6EYCNMFdAtkAicMeN8/HMDIXWE9eELCzKX5LrdKVcJhnI8lAY2WL1fiWbkfYLmUyV1+30JYC2B6nFmnakO9Nw==
|
||||
"@polkadot/rpc-core@^0.96.0-beta.15":
|
||||
version "0.96.0-beta.15"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/rpc-core/-/rpc-core-0.96.0-beta.15.tgz#a1ca1fb0d37c68a0107313d9bfd67bf1c2e3ac01"
|
||||
integrity sha512-aLRlfe1tOyMhJ5A2BCX82qHAJs4Nl/x8AIlvLs5Wme/Jl5eo+N3Y+R3p+uF99JIosrzJmdcdjBG8qGY3Cj4PvQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.6.3"
|
||||
"@polkadot/jsonrpc" "^0.96.0-beta.14"
|
||||
"@polkadot/rpc-provider" "^0.96.0-beta.14"
|
||||
"@polkadot/types" "^0.96.0-beta.14"
|
||||
"@polkadot/jsonrpc" "^0.96.0-beta.15"
|
||||
"@polkadot/rpc-provider" "^0.96.0-beta.15"
|
||||
"@polkadot/types" "^0.96.0-beta.15"
|
||||
"@polkadot/util" "^1.6.1"
|
||||
rxjs "^6.5.3"
|
||||
|
||||
"@polkadot/rpc-provider@^0.96.0-beta.14":
|
||||
version "0.96.0-beta.14"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/rpc-provider/-/rpc-provider-0.96.0-beta.14.tgz#7565cf4fe2138bbe4e984fa0b88ed2925e497b7f"
|
||||
integrity sha512-9t9xmj3Zy+0lOd4iZirkUsUB/5bDlHFTTAcuwgB2MtqLi9m63JJaXjcWWa1HaYmg9u+gycbwMOg7jFSlf6RjjQ==
|
||||
"@polkadot/rpc-provider@^0.96.0-beta.15":
|
||||
version "0.96.0-beta.15"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/rpc-provider/-/rpc-provider-0.96.0-beta.15.tgz#d540ed73dd2299eccd4fb53793fbd1addbe33890"
|
||||
integrity sha512-A2QGImrRMRmZXZLgaNjqayIrerx8fi1+74KO4yx3wcMx7V7kEvZ/B7X00vEO4eg9ysRw/INcfZD67eWu0yjRbg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.6.3"
|
||||
"@polkadot/api-metadata" "^0.96.0-beta.14"
|
||||
"@polkadot/api-metadata" "^0.96.0-beta.15"
|
||||
"@polkadot/util" "^1.6.1"
|
||||
"@polkadot/util-crypto" "^1.6.1"
|
||||
"@types/nock" "^11.1.0"
|
||||
@ -2230,10 +2230,10 @@
|
||||
dependencies:
|
||||
"@types/chrome" "^0.0.91"
|
||||
|
||||
"@polkadot/types@^0.96.0-beta.14":
|
||||
version "0.96.0-beta.14"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-0.96.0-beta.14.tgz#88a3899d6f3a96eab4d7abc66cc903023ad0c88b"
|
||||
integrity sha512-7icPtEkZXoukKqN2hTBEyZH9shwV7At2xVqLjEx8j4r6IP+gDL2UbvcQ2WevCsIeWfsnaN13pEMSbClEuWOuVQ==
|
||||
"@polkadot/types@^0.96.0-beta.15":
|
||||
version "0.96.0-beta.15"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-0.96.0-beta.15.tgz#8b9acea0acb10e708f5ac8f5fa47450fb6e6ffb5"
|
||||
integrity sha512-ufWNAkz7fy4HlsHzJuBkLbIHMXjZaskaGwoBAT0HOBJ7wI3NSz78ScF69beVY5KwG+9Qc0dSYvYWFDOmDJTJCQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.6.3"
|
||||
"@polkadot/util" "^1.6.1"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user