From 5d8225325778cfeca8d749db96a9aa201aa1bd74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Mon, 20 May 2019 13:20:41 +0200 Subject: [PATCH] Display state of Grandpa (#134) * Make it clear that settings apply only to list view Since the consensus view will be added users could mistake the settings as being applied there as well. * Add Jdenticon * Add Grandpa consensus visualisation * Remove fade-in animation * Update packages and yarn.lock * Broadcast only delta of what changed * Minor code improvements * Use NodeId instead of Address in first dimension By using the NodeId instead of the Address in the first dimension of the consensus matrice we save quite some space in the payload which is sent to the browser. The commit also contains some minor refactoring. * Refactoring and improving naming * Display boxes only after size has been detected This look a bit nicer, otherwise the UI will still adapt the box sizes once everything has already been loaded up. * Fix cache * Send consensus info on first subscribe So that frontend can immediately display the current state and doesn't have to aggregate first. * Increase cache size * Send deltas only if block in cache Otherwise the UI will update old blocks which are still visible to an empty shell. * Adjust cache size * Make cache sizes dependent * Ensure authority caches are aligned If only one authority has already submitted consensus info for a new block then the cache of that one is offset by one from all other authorities. * Handle restarts on authority set changes properly * Fix backfill mechanism * Extract function * Display only blocks since last authority set change * Handle authority set sent on connect When nodes lose their connection to telemetry or connect on first time they sent their current authority set for the UI to have something to display. These sets don't contain an explicit block number, because the set didn't change -- it just got resent. In this case the set is `undefined`. * Introduce Authority type This is necessary to cover the case where one node connects, submits its authority set containing another node which has not yet connected to Telemetry. In this case we still want to create a shell object and fill it with the address. * Handle corner case In the case of only one block having been produced, two authorities, and only one authority connected, the UI did not show up. * Display placeholder if name not yet available * Replace with camelCase * Replace with correct types * Replace grandpa icon * Change consensus icon to cube (finalized block icon) * Upgrade dependencies * Implement thin backend instead of thick * Cleanup and minor improvements * Minor refactoring * Extract common code into function * Switch module to class * Remove unused code * Clean markup * Remove unused code * Revert "Upgrade dependencies" This reverts commit bf4d9ea48b3417860ccf40f0c5122027ffc59689. * Update polkadot-identicon in frontend Change version number to `^1.1.45` and run `npm update polkadot-identicon`. * Run yarn install * Update react-measure to 2.3.0 Changed version number, ran cd packages/frontend/ && npm update react-reasure && cd ../../ && yarn install * Improve typing by introducing partial type * Reduce indexing operations * Shorten function * Shorten function * Introduce initialiseConsensusViewByRef * Remove dead conditional branch * Return consensusView ref from initialiseConsensusView * Handle consensusView ref returned from initialiseConsensusView --- packages/backend/src/Aggregator.ts | 18 + packages/backend/src/Chain.ts | 35 +- packages/backend/src/Feed.ts | 60 ++ packages/backend/src/Node.ts | 83 ++- packages/backend/src/message.ts | 40 ++ packages/common/src/feed.ts | 31 +- packages/common/src/types.ts | 32 +- packages/frontend/package-lock.json | 591 +++++++++++++++++- packages/frontend/package.json | 4 +- packages/frontend/public/Jdenticon.min.js | 19 + packages/frontend/public/index.html | 1 + packages/frontend/src/AfgHandling.ts | 228 +++++++ packages/frontend/src/App.tsx | 6 +- packages/frontend/src/Connection.ts | 54 +- .../frontend/src/components/Chain/Chain.tsx | 17 +- .../src/components/Consensus/Consensus.css | 144 +++++ .../src/components/Consensus/Consensus.tsx | 247 ++++++++ .../components/Consensus/ConsensusBlock.css | 201 ++++++ .../components/Consensus/ConsensusBlock.tsx | 230 +++++++ .../src/components/Consensus/Jdenticon.css | 9 + .../src/components/Consensus/Jdenticon.tsx | 43 ++ .../src/components/Consensus/index.ts | 2 + .../src/components/Settings/Settings.tsx | 1 + packages/frontend/src/components/index.ts | 1 + packages/frontend/src/icons/finalized.svg | 9 + packages/frontend/src/icons/hatching.svg | 76 +++ packages/frontend/src/state.ts | 17 +- yarn.lock | 177 +++++- 28 files changed, 2324 insertions(+), 52 deletions(-) create mode 100644 packages/frontend/public/Jdenticon.min.js create mode 100644 packages/frontend/src/AfgHandling.ts create mode 100644 packages/frontend/src/components/Consensus/Consensus.css create mode 100644 packages/frontend/src/components/Consensus/Consensus.tsx create mode 100644 packages/frontend/src/components/Consensus/ConsensusBlock.css create mode 100644 packages/frontend/src/components/Consensus/ConsensusBlock.tsx create mode 100644 packages/frontend/src/components/Consensus/Jdenticon.css create mode 100644 packages/frontend/src/components/Consensus/Jdenticon.tsx create mode 100644 packages/frontend/src/components/Consensus/index.ts create mode 100644 packages/frontend/src/icons/finalized.svg create mode 100644 packages/frontend/src/icons/hatching.svg diff --git a/packages/backend/src/Aggregator.ts b/packages/backend/src/Aggregator.ts index 45c69ac..b13d908 100644 --- a/packages/backend/src/Aggregator.ts +++ b/packages/backend/src/Aggregator.ts @@ -46,6 +46,24 @@ export default class Aggregator { feed.sendMessage(Feed.unsubscribedFrom(label)); } }); + + feed.events.on('subscribe-consensus-info', (label: Types.ChainLabel) => { + const chain = this.chains.get(label); + + if (chain) { + feed.sendMessage(Feed.subscribedTo(label)); + chain.addFeed(feed); + } + }); + + feed.events.on('unsubscribe-consensus-info', (label: Types.ChainLabel) => { + const chain = this.chains.get(label); + + if (chain) { + chain.removeFeed(feed); + feed.sendMessage(Feed.unsubscribedFrom(label)); + } + }); } public getExistingChain(label: Types.ChainLabel) : Maybe { diff --git a/packages/backend/src/Chain.ts b/packages/backend/src/Chain.ts index 14f04b6..82493d2 100644 --- a/packages/backend/src/Chain.ts +++ b/packages/backend/src/Chain.ts @@ -3,7 +3,7 @@ import Node from './Node'; import Feed from './Feed'; import FeedSet from './FeedSet'; import Block from './Block'; -import { Maybe, Types, FeedMessage, NumStats } from '@dotstats/common'; +import { Maybe, Types, NumStats } from '@dotstats/common'; const BLOCK_TIME_HISTORY = 10; @@ -21,6 +21,8 @@ export default class Chain { private blockTimes = new NumStats(BLOCK_TIME_HISTORY); private averageBlockTime: Maybe = null; + public lastBroadcastedAuthoritySetInfo: Maybe = null; + constructor(label: Types.ChainLabel) { this.label = label; } @@ -39,6 +41,33 @@ export default class Chain { node.events.on('block', () => this.updateBlock(node)); node.events.on('finalized', () => this.updateFinalized(node)); + + node.events.on('afg-finalized', (finalizedNumber, finalizedHash) => this.feeds.each( + f => f.sendConsensusMessage(Feed.afgFinalized(node, finalizedNumber, finalizedHash)) + )); + node.events.on('afg-received-prevote', (finalizedNumber, finalizedHash, voter) => this.feeds.each( + f => f.sendConsensusMessage(Feed.afgReceivedPrevote(node, finalizedNumber, finalizedHash, voter)) + )); + node.events.on('afg-received-precommit', (finalizedNumber, finalizedHash, voter) => this.feeds.each( + f => f.sendConsensusMessage(Feed.afgReceivedPrecommit(node, finalizedNumber, finalizedHash, voter)) + )); + node.events.on('authority-set-changed', (authorities, authoritySetId, blockNumber, blockHash) => { + let newSet; + if (this.lastBroadcastedAuthoritySetInfo == null) { + newSet = true; + } else { + const [lastBroadcastedAuthoritySetId] = this.lastBroadcastedAuthoritySetInfo; + newSet = authoritySetId !== lastBroadcastedAuthoritySetId; + } + + if (node.isAuthority() && newSet) { + const addr = node.address != null ? node.address : "" as Types.Address; + const set = [authoritySetId, authorities, addr, blockNumber, blockHash] as Types.AuthoritySetInfo; + this.feeds.broadcast(Feed.afgAuthoritySet(set)); + this.lastBroadcastedAuthoritySetInfo = set; + } + }); + node.events.on('stats', () => this.feeds.broadcast(Feed.stats(node))); node.events.on('hardware', () => this.feeds.broadcast(Feed.hardware(node))); node.events.on('location', (location) => this.feeds.broadcast(Feed.locatedNode(node, location))); @@ -70,6 +99,10 @@ export default class Chain { feed.sendMessage(Feed.bestBlock(this.height, this.blockTimestamp, this.averageBlockTime)); feed.sendMessage(Feed.bestFinalizedBlock(this.finalized)); + if (this.lastBroadcastedAuthoritySetInfo != null) { + feed.sendMessage(Feed.afgAuthoritySet(this.lastBroadcastedAuthoritySetInfo)); + } + for (const node of this.nodes.values()) { feed.sendMessage(Feed.addedNode(node)); feed.sendMessage(Feed.finalized(node)); diff --git a/packages/backend/src/Feed.ts b/packages/backend/src/Feed.ts index 15d09a1..2b9a39e 100644 --- a/packages/backend/src/Feed.ts +++ b/packages/backend/src/Feed.ts @@ -18,6 +18,7 @@ export default class Feed { private socket: WebSocket; private messages: Array = []; private waitingForPong = false; + private sendFinality = false; constructor(socket: WebSocket) { this.id = nextId(); @@ -92,6 +93,49 @@ export default class Feed { }; } + public static afgFinalized(node: Node, finalizedNumber: Types.BlockNumber, finalizedHash: Types.BlockHash): FeedMessage.Message { + const addr = node.address != null ? node.address : "" as Types.Address; + return { + action: Actions.AfgFinalized, + payload: [addr, finalizedNumber, finalizedHash] + }; + } + + public static afgReceivedPrevote( + node: Node, + targetNumber: Types.BlockNumber, + targetHash: Types.BlockHash, + voter: Types.Address + ): FeedMessage.Message { + const addr = node.address != null ? node.address : "" as Types.Address; + return { + action: Actions.AfgReceivedPrevote, + payload: [addr, targetNumber, targetHash, voter] + }; + } + + public static afgReceivedPrecommit( + node: Node, + targetNumber: Types.BlockNumber, + targetHash: Types.BlockHash, + voter: Types.Address + ): FeedMessage.Message { + const addr = node.address != null ? node.address : "" as Types.Address; + return { + action: Actions.AfgReceivedPrecommit, + payload: [addr, targetNumber, targetHash, voter] + }; + } + + public static afgAuthoritySet( + authoritySetInfo: Types.AuthoritySetInfo, + ): FeedMessage.Message { + return { + action: Actions.AfgAuthoritySet, + payload: authoritySetInfo, + }; + } + public static hardware(node: Node): FeedMessage.Message { return { action: Actions.NodeHardware, @@ -155,6 +199,14 @@ export default class Feed { } } + public sendConsensusMessage(message: FeedMessage.Message) { + if (!this.sendFinality) { + return; + } + + this.sendMessage(message); + } + public ping() { if (this.waitingForPong) { this.disconnect(); @@ -188,6 +240,14 @@ export default class Feed { this.events.emit('subscribe', payload as Types.ChainLabel); break; + case 'send-finality': + this.sendFinality = true; + break; + + case 'no-more-finality': + this.sendFinality = false; + break; + case 'ping': this.sendMessage(Feed.pong(payload)); break; diff --git a/packages/backend/src/Node.ts b/packages/backend/src/Node.ts index 124a6c8..f84ab82 100644 --- a/packages/backend/src/Node.ts +++ b/packages/backend/src/Node.ts @@ -2,7 +2,18 @@ import * as WebSocket from 'ws'; import * as EventEmitter from 'events'; import { noop, timestamp, idGenerator, Maybe, Types, NumStats } from '@dotstats/common'; -import { parseMessage, getBestBlock, Message, BestBlock, SystemInterval } from './message'; +import { BlockHash, BlockNumber, ConsensusView } from "@dotstats/common/build/types"; +import { + parseMessage, + getBestBlock, + Message, + BestBlock, + SystemInterval, + AfgFinalized, + AfgReceivedPrecommit, + AfgReceivedPrevote, + AfgAuthoritySet, +} from './message'; import { locate, Location } from './location'; import MeanList from './MeanList'; import Block from './Block'; @@ -57,6 +68,9 @@ export default class Node { private pingStart = 0 as Types.Timestamp; private throttle = false; + private authorities: Types.Authorities = [] as Types.Authorities; + private authoritySetId: Types.AuthoritySetId = 0 as Types.AuthoritySetId; + constructor( ip: string, socket: WebSocket, @@ -182,8 +196,9 @@ export default class Node { public nodeDetails(): Types.NodeDetails { const authority = this.authority ? this.address : null; + const addr = this.address ? this.address : '' as Types.Address; - return [this.name, this.implementation, this.version, authority, this.networkId]; + return [this.name, addr, this.implementation, this.version, authority, this.networkId]; } public nodeStats(): Types.NodeStats { @@ -236,6 +251,19 @@ export default class Node { if (message.msg === 'system.interval') { this.onSystemInterval(message); } + + if (message.msg === 'afg.finalized') { + this.onAfgFinalized(message); + } + if (message.msg === 'afg.received_precommit') { + this.onAfgReceivedPrecommit(message); + } + if (message.msg === 'afg.received_prevote') { + this.onAfgReceivedPrevote(message); + } + if (message.msg === 'afg.authority_set') { + this.onAfgAuthoritySet(message); + } } private onSystemInterval(message: SystemInterval) { @@ -283,6 +311,57 @@ export default class Node { } } + public isAuthority(): boolean { + return this.authority; + } + + private onAfgReceivedPrecommit(message: AfgReceivedPrecommit) { + const { + target_number: targetNumber, + target_hash: targetHash, + } = message; + const voter = this.extractVoter(message.voter); + this.events.emit('afg-received-precommit', targetNumber, targetHash, voter); + } + + private onAfgReceivedPrevote(message: AfgReceivedPrevote) { + const { + target_number: targetNumber, + target_hash: targetHash, + } = message; + const voter = this.extractVoter(message.voter); + this.events.emit('afg-received-prevote', targetNumber, targetHash, voter); + } + + private onAfgAuthoritySet(message: AfgAuthoritySet) { + const { + authority_set_id: authoritySetId, + hash, + number, + } = message; + + // we manually parse the authorities message, because the array was formatted as a + // string by substrate before sending it. + const authorities = JSON.parse(String(message.authorities)) as Types.Authorities; + + if (JSON.stringify(this.authorities) !== String(message.authorities) || + this.authoritySetId !== authoritySetId) { + this.events.emit('authority-set-changed', authorities, authoritySetId, number, hash); + } + } + + private onAfgFinalized(message: AfgFinalized) { + const { + finalized_number: finalizedNumber, + finalized_hash: finalizedHash, + } = message; + this.events.emit('afg-finalized', finalizedNumber, finalizedHash); + } + + private extractVoter(message_voter: String): Types.Address { + return String(message_voter.replace(/"/g, '')) as Types.Address; + } + private updateLatency(now: Types.Timestamp) { // if (this.pingStart) { // console.error(`${this.name} timed out on ping message.`); diff --git a/packages/backend/src/message.ts b/packages/backend/src/message.ts index f199ada..eb46c76 100644 --- a/packages/backend/src/message.ts +++ b/packages/backend/src/message.ts @@ -39,6 +39,41 @@ export interface BestBlock { ts: Date; } +export interface AfgFinalized { + ts: Date; + finalized_number: Types.BlockNumber; + finalized_hash: Types.BlockHash; + msg: 'afg.finalized'; +} + +export interface AfgReceived { + ts: Date; + target_number: Maybe; + target_hash: Maybe; + voter: Types.Address; +} + +export interface AfgReceivedPrecommit extends AfgReceived { + msg: 'afg.received_precommit'; +} + +export interface AfgReceivedPrevote extends AfgReceived { + msg: 'afg.received_prevote'; +} + +export interface AfgReceivedCommit extends AfgReceived { + msg: 'afg.received_commit'; +} + +export interface AfgAuthoritySet { + msg: 'afg.authority_set'; + ts: Date; + authorities: Types.Authorities; + authority_set_id: Types.AuthoritySetId; + number: Types.BlockNumber; + hash: Types.BlockHash; +} + export interface SystemConnected { msg: 'system.connected'; name: Types.NodeName; @@ -79,6 +114,11 @@ export type Message = MessageBase & ( | SystemInterval | NodeStart | BlockImport + | AfgFinalized + | AfgReceivedPrecommit + | AfgReceivedPrevote + | AfgReceivedCommit + | AfgAuthoritySet ); diff --git a/packages/common/src/feed.ts b/packages/common/src/feed.ts index 0a675b5..285fd9c 100644 --- a/packages/common/src/feed.ts +++ b/packages/common/src/feed.ts @@ -17,7 +17,8 @@ import { BlockDetails, Timestamp, Milliseconds, - ChainLabel + ChainLabel, + AuthoritySetInfo, } from './types'; export const Actions = { @@ -37,6 +38,10 @@ export const Actions = { SubscribedTo : 0x0D as 0x0D, UnsubscribedFrom : 0x0E as 0x0E, Pong : 0x0F as 0x0F, + AfgFinalized : 0x10 as 0x10, + AfgReceivedPrevote : 0x11 as 0x11, + AfgReceivedPrecommit : 0x12 as 0x12, + AfgAuthoritySet : 0x13 as 0x13, }; export type Action = typeof Actions[keyof typeof Actions]; @@ -126,6 +131,26 @@ export namespace Variants { action: typeof Actions.Pong; payload: string; // just echo whatever `ping` sent } + + export interface AfgFinalizedMessage extends MessageBase { + action: typeof Actions.AfgFinalized; + payload: [Address, BlockNumber, BlockHash]; + } + + export interface AfgAuthoritySet extends MessageBase { + action: typeof Actions.AfgAuthoritySet; + payload: AuthoritySetInfo; + } + + export interface AfgReceivedPrecommit extends MessageBase { + action: typeof Actions.AfgReceivedPrecommit; + payload: [Address, BlockNumber, BlockHash, Address]; + } + + export interface AfgReceivedPrevote extends MessageBase { + action: typeof Actions.AfgReceivedPrevote; + payload: [Address, BlockNumber, BlockHash, Address]; + } } export type Message = @@ -144,6 +169,10 @@ export type Message = | Variants.RemovedChainMessage | Variants.SubscribedToMessage | Variants.UnsubscribedFromMessage + | Variants.AfgFinalizedMessage + | Variants.AfgReceivedPrevote + | Variants.AfgReceivedPrecommit + | Variants.AfgAuthoritySet | Variants.PongMessage; /** diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index d071130..aa3a825 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -27,7 +27,37 @@ export type NetworkId = Opaque; export type NetworkState = Opaque; export type BlockDetails = [BlockNumber, BlockHash, Milliseconds, Timestamp, Maybe]; -export type NodeDetails = [NodeName, NodeImplementation, NodeVersion, Maybe
, Maybe]; +export type NodeDetails = [NodeName, Address, NodeImplementation, NodeVersion, Maybe
, Maybe]; export type NodeStats = [PeerCount, TransactionCount]; export type NodeHardware = [Array, Array, Array, Array, Array]; export type NodeLocation = [Latitude, Longitude, City]; + +export declare type Authority = { + Address: Address, + NodeId: Maybe, + Name: Maybe, +}; +export declare type Authorities = Array
; +export declare type AuthoritySetId = Opaque; +export declare type AuthoritySetInfo = [AuthoritySetId, Authorities, Address, BlockNumber, BlockHash]; +export declare type ConsensusInfo = Array<[BlockNumber, ConsensusView]>; +export declare type ConsensusView = Map; +export declare type ConsensusState = Map; +export declare type ConsensusDetail = { + Precommit: Precommit; + ImplicitPrecommit: ImplicitPrecommit; + Prevote: Prevote; + ImplicitPrevote: ImplicitPrevote; + ImplicitPointer: ImplicitPointer; + Finalized: ImplicitFinalized; + ImplicitFinalized: Finalized; + FinalizedHash: BlockHash; + FinalizedHeight: BlockNumber; +}; +export declare type Precommit = Opaque; +export declare type Prevote = Opaque; +export declare type Finalized = Opaque; +export declare type ImplicitPrecommit = Opaque; +export declare type ImplicitPrevote = Opaque; +export declare type ImplicitFinalized = Opaque; +export declare type ImplicitPointer = Opaque; diff --git a/packages/frontend/package-lock.json b/packages/frontend/package-lock.json index bed26cd..29ad4e7 100644 --- a/packages/frontend/package-lock.json +++ b/packages/frontend/package-lock.json @@ -39,11 +39,87 @@ } } }, + "@babel/runtime": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.4.tgz", + "integrity": "sha512-w0+uT71b6Yi7i5SE0co4NioIpSYS6lLiXvCzWzGSKvpK5vdQtCbICHMj+gbAKAOtxiV6HsVh/MBdaF9EQ6faSg==", + "requires": { + "regenerator-runtime": "^0.13.2" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz", + "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==" + } + } + }, + "@polkadot/util": { + "version": "0.41.1", + "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-0.41.1.tgz", + "integrity": "sha512-1mFHxxdXyRgeFk0ygfJklzsf6HiEEMikrpUgr+3Dw5S7KromjPD8EbWkpcZQZ3Png5PTwGyjrx7MYY4Ajiu5xQ==", + "requires": { + "@babel/runtime": "^7.4.0", + "@types/bn.js": "^4.11.4", + "@types/deasync": "^0.1.0", + "@types/ip-regex": "^3.0.0", + "bn.js": "^4.11.8", + "camelcase": "^5.2.0", + "chalk": "^2.4.2", + "ip-regex": "^4.0.0", + "moment": "^2.24.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + } + } + }, + "@polkadot/wasm-crypto": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto/-/wasm-crypto-0.5.1.tgz", + "integrity": "sha512-8h7uz85bvLVirtbxLkELr9H25oqAfgnQuDP6FP3QJeag7VfMtVvRF5U2JWGgsiUSiRg+UJnTuCleOSDnageRmg==" + }, + "@polkadot/wasm-schnorrkel": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-schnorrkel/-/wasm-schnorrkel-0.3.1.tgz", + "integrity": "sha512-2J/lNZe7oDWvzUbsEfvKfiiAvBIBbIsppeBGahwSg2Y+cLweQgThXGizPpQoPo0tHxgMKdTi6jhPu7tLzCW/cA==" + }, "@tanem/svg-injector": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@tanem/svg-injector/-/svg-injector-1.2.1.tgz", "integrity": "sha512-mA5Q5ulPoGQ+e08Vts1R6xw2QU0BKEnMH/KcqoYoS7Gk6imvMTpyFPeu1g+NOZObSIoAzA3/kRzY8m96cEBA2A==" }, + "@types/bn.js": { + "version": "4.11.5", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.5.tgz", + "integrity": "sha512-AEAZcIZga0JgVMHNtl1CprA/hXX7/wPt79AgR4XqaDt7jyj3QWYw6LPoOiznPtugDmlubUnAahMs2PFxGcQrng==", + "requires": { + "@types/node": "*" + } + }, + "@types/deasync": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@types/deasync/-/deasync-0.1.0.tgz", + "integrity": "sha512-jxUH53LtGvbIL3TX2hD/XQuAgYJeATtx9kDXq5XtCZrWQABsiCQPjWi/KQXECUF+p9FuR6/tawnEDjXlEr4rFA==" + }, + "@types/ip-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/ip-regex/-/ip-regex-3.0.0.tgz", + "integrity": "sha512-4j26qYCikXbIaypgqdGQhhIvYfTR+40i/05jVQB8oc57RbROEkBocdIUZO7fOhyqJsx7WRY36ySW8hoUZn7Fgw==" + }, "@types/jest": { "version": "23.0.2", "resolved": "https://registry.npmjs.org/@types/jest/-/jest-23.0.2.tgz", @@ -58,8 +134,7 @@ "@types/node": { "version": "10.3.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-10.3.2.tgz", - "integrity": "sha512-9NfEUDp3tgRhmoxzTpTo+lq+KIVFxZahuRX0LHF/9IzKHaWuoWsIrrJ61zw5cnnlGINX8lqJzXYfQTOICS5Q+A==", - "dev": true + "integrity": "sha512-9NfEUDp3tgRhmoxzTpTo+lq+KIVFxZahuRX0LHF/9IzKHaWuoWsIrrJ61zw5cnnlGINX8lqJzXYfQTOICS5Q+A==" }, "@types/react": { "version": "16.3.17", @@ -1368,6 +1443,14 @@ } } }, + "base-x": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.5.tgz", + "integrity": "sha512-C3picSgzPSLE+jW3tcBzJoGwitOtazb5B+5YmAxZm2ybmTi9LNgAtDO/jjVEBZwHoXmDBZ9m/IELj3elJVRBcA==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, "base64-js": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", @@ -1397,6 +1480,42 @@ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=" }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bip39": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-2.6.0.tgz", + "integrity": "sha512-RrnQRG2EgEoqO24ea+Q/fftuPUZLmrEM3qNhhGsA3PbaXaCW791LTzPuVyx/VprXQcTbPJ3K3UeTna8ZnVl2sg==", + "requires": { + "create-hash": "^1.1.0", + "pbkdf2": "^3.0.9", + "randombytes": "^2.0.1", + "safe-buffer": "^5.0.1", + "unorm": "^1.3.3" + } + }, + "blake2js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/blake2js/-/blake2js-1.0.0.tgz", + "integrity": "sha1-tokMOU3blAXQbZp6089lZxHcrYk=", + "requires": { + "bindings": "^1.2.1", + "debug": "^2.2.0", + "nan": "^2.4.0", + "readable-stream": "^2.1.4" + } + }, + "blakejs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", + "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" + }, "bluebird": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", @@ -1627,6 +1746,14 @@ "electron-to-chromium": "^1.3.30" } }, + "bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "requires": { + "base-x": "^3.0.2" + } + }, "bser": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz", @@ -1785,6 +1912,11 @@ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000878.tgz", "integrity": "sha512-/dCGTdLCnjVJno1mFRn7Y6eit3AYaeFzSrMQHCoK0LEQaWl5snuLex1Ky4b8/Qu2ig5NgTX4cJx65hH9546puA==" }, + "canvas-renderer": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/canvas-renderer/-/canvas-renderer-2.1.1.tgz", + "integrity": "sha512-/V0XetN7s1Mk3NO7x2wxPZYv0pLMQtGAhecuOuKR88beiYCUle1AbCcFZNLu+4NVzi9RVHS0rXtIgzPEaKidLw==" + }, "capture-exit": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-1.2.0.tgz", @@ -1841,6 +1973,31 @@ } } }, + "change-case": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-3.1.0.tgz", + "integrity": "sha512-2AZp7uJZbYEzRPsFoa+ijKdvp9zsrnnt6+yFokfwEpeJm0xuJDVoxiRCAaTzyJND8GJkofo2IcKWaUZ/OECVzw==", + "requires": { + "camel-case": "^3.0.0", + "constant-case": "^2.0.0", + "dot-case": "^2.1.0", + "header-case": "^1.0.0", + "is-lower-case": "^1.1.0", + "is-upper-case": "^1.1.0", + "lower-case": "^1.1.1", + "lower-case-first": "^1.0.0", + "no-case": "^2.3.2", + "param-case": "^2.1.0", + "pascal-case": "^2.0.0", + "path-case": "^2.1.0", + "sentence-case": "^2.1.0", + "snake-case": "^2.1.0", + "swap-case": "^1.1.0", + "title-case": "^2.1.0", + "upper-case": "^1.1.1", + "upper-case-first": "^1.1.0" + } + }, "chardet": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", @@ -2123,6 +2280,15 @@ "date-now": "^0.1.4" } }, + "constant-case": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-2.0.0.tgz", + "integrity": "sha1-QXV2TTidP6nI7NKRhu1gBSQ7akY=", + "requires": { + "snake-case": "^2.1.0", + "upper-case": "^1.1.1" + } + }, "constants-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", @@ -2522,6 +2688,11 @@ "integrity": "sha512-G5HnoK8nOiAq3DXIEoY2n/8Vb7Lgrms+jGJl8E4EJpQEeVONEnPFJSl8IK505wPBoxxtrtHhrRm4WX2GgdqarA==", "dev": true }, + "cuint": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz", + "integrity": "sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs=" + }, "currently-unhandled": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", @@ -2857,6 +3028,14 @@ "domelementtype": "1" } }, + "dot-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-2.1.1.tgz", + "integrity": "sha1-NNzzf1Co6TwrO8qLt/uRVcfaO+4=", + "requires": { + "no-case": "^2.2.0" + } + }, "dot-prop": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", @@ -3544,6 +3723,11 @@ "loader-utils": "^1.0.2" } }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, "filename-regex": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", @@ -3766,7 +3950,8 @@ }, "ansi-regex": { "version": "2.1.1", - "bundled": true + "bundled": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -3784,11 +3969,13 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true + "bundled": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3801,15 +3988,18 @@ }, "code-point-at": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "concat-map": { "version": "0.0.1", - "bundled": true + "bundled": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -3912,7 +4102,8 @@ }, "inherits": { "version": "2.0.3", - "bundled": true + "bundled": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -3922,6 +4113,7 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -3934,17 +4126,20 @@ "minimatch": { "version": "3.0.4", "bundled": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "bundled": true + "bundled": true, + "optional": true }, "minipass": { "version": "2.2.4", "bundled": true, + "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -3961,6 +4156,7 @@ "mkdirp": { "version": "0.5.1", "bundled": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -4033,7 +4229,8 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true + "bundled": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -4043,6 +4240,7 @@ "once": { "version": "1.4.0", "bundled": true, + "optional": true, "requires": { "wrappy": "1" } @@ -4118,7 +4316,8 @@ }, "safe-buffer": { "version": "5.1.1", - "bundled": true + "bundled": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -4148,6 +4347,7 @@ "string-width": { "version": "1.0.2", "bundled": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -4165,6 +4365,7 @@ "strip-ansi": { "version": "3.0.1", "bundled": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -4203,11 +4404,13 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true + "bundled": true, + "optional": true }, "yallist": { "version": "3.0.2", - "bundled": true + "bundled": true, + "optional": true } } }, @@ -4221,6 +4424,11 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" }, + "get-node-dimensions": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-node-dimensions/-/get-node-dimensions-1.2.1.tgz", + "integrity": "sha512-2MSPMu7S1iOTL+BOa6K1S62hB2zUAYNF/lV0gSVlOaacd087lc6nR1H1r0e3B1CerTo+RceOmi1iJW+vp21xcQ==" + }, "get-stdin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", @@ -4515,6 +4723,15 @@ "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=" }, + "header-case": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/header-case/-/header-case-1.0.1.tgz", + "integrity": "sha1-lTWXMZfBRLCWE81l0xfvGZY70C0=", + "requires": { + "no-case": "^2.2.0", + "upper-case": "^1.1.3" + } + }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -4983,6 +5200,11 @@ "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" }, + "ip-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.1.0.tgz", + "integrity": "sha512-pKnZpbgCTfH/1NLIlOduP/V+WRXzC2MOz3Qo8xmxk8C5GudJLgK5QyLVXOSWy3ParAH7Eemurl3xjv/WXYFvMA==" + }, "ipaddr.js": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", @@ -5153,6 +5375,14 @@ "is-path-inside": "^1.0.0" } }, + "is-lower-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-lower-case/-/is-lower-case-1.1.3.tgz", + "integrity": "sha1-fhR75HaNxGbbO/shzGCzHmrWk5M=", + "requires": { + "lower-case": "^1.1.0" + } + }, "is-npm": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", @@ -5276,6 +5506,14 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, + "is-upper-case": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-upper-case/-/is-upper-case-1.1.2.tgz", + "integrity": "sha1-jQsfp+eTOh5YSDYA7H2WYcuvdW8=", + "requires": { + "upper-case": "^1.1.0" + } + }, "is-utf8": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", @@ -5315,6 +5553,11 @@ "whatwg-fetch": ">=0.10.0" } }, + "isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==" + }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", @@ -5454,6 +5697,14 @@ "handlebars": "^4.0.3" } }, + "jdenticon": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/jdenticon/-/jdenticon-2.1.1.tgz", + "integrity": "sha512-bFD210JMaK2RMHGSkdDXqdQzasMrVIGDfxUMXD/Uwq2t7g9Njb4T6kms5TrocsLU0CDmQCoB0laGJ6JETiprsg==", + "requires": { + "canvas-renderer": "~2.1.1" + } + }, "jest": { "version": "22.4.2", "resolved": "https://registry.npmjs.org/jest/-/jest-22.4.2.tgz", @@ -6507,6 +6758,14 @@ "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=" }, + "lower-case-first": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/lower-case-first/-/lower-case-first-1.0.2.tgz", + "integrity": "sha1-5dp8JvKacHO+AtUrrJmA5ZIq36E=", + "requires": { + "lower-case": "^1.1.2" + } + }, "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -6769,6 +7028,11 @@ "minimist": "0.0.8" } }, + "moment": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" + }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", @@ -6809,8 +7073,7 @@ "nan": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", - "optional": true + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==" }, "nanomatch": { "version": "1.2.13", @@ -7102,6 +7365,116 @@ "mimic-fn": "^1.0.0" } }, + "oo7": { + "version": "0.7.12", + "resolved": "https://registry.npmjs.org/oo7/-/oo7-0.7.12.tgz", + "integrity": "sha512-nVmxwLIiVCY4Aid6/+p2ujJ2mj3yh15zQ3xSl3UPui7U37DJJfD0KmuMjp+XOWH1HxTkKhIKDgR34eEhFHNxgA==" + }, + "oo7-react": { + "version": "0.8.13", + "resolved": "https://registry.npmjs.org/oo7-react/-/oo7-react-0.8.13.tgz", + "integrity": "sha512-1WoJf/pYDiZAkd+rilH9xs6FR6k4LKck/uCPVzClTnp/uFvsR8pxlbTHvNPvOqspxob76qSbstUv7IVdO/TQ7Q==", + "requires": { + "oo7": "^0.7.12", + "react": "^16.5.2" + }, + "dependencies": { + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + }, + "dependencies": { + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + } + } + }, + "react": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react/-/react-16.8.6.tgz", + "integrity": "sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.13.6" + } + } + } + }, + "oo7-substrate": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/oo7-substrate/-/oo7-substrate-0.8.0.tgz", + "integrity": "sha512-ltglsNXZNmiDsJ5q4LYx0tf0SN0CVjW5fSifwrBRe/objxG2fYXogZ4eiNdsLJrTddvskv+3o5JpvFw/D3PCUA==", + "requires": { + "@polkadot/util": "^0.41.1", + "@polkadot/wasm-crypto": "^0.5.1", + "@polkadot/wasm-schnorrkel": "^0.3.1", + "base-x": "^3.0.4", + "bip39": "^2.5.0", + "blakejs": "^1.1.0", + "bs58": "^4.0.1", + "buffer": "^5.2.1", + "change-case": "^3.0.2", + "isomorphic-fetch": "^2.2.1", + "isomorphic-ws": "^4.0.1", + "jdenticon": "^2.1.1", + "oo7": "^0.7.12", + "pbkdf2": "^3.0.17", + "ss58": "^1.0.2", + "text-encoding": "^0.7.0", + "text-encoding-polyfill": "^0.6.7", + "tweetnacl": "^1.0.0", + "ws": "^6.1.2", + "xxhashjs": "^0.2.2" + }, + "dependencies": { + "buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", + "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "tweetnacl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", + "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" + }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, "opn": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/opn/-/opn-5.2.0.tgz", @@ -7283,6 +7656,15 @@ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" }, + "pascal-case": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-2.0.1.tgz", + "integrity": "sha1-LVeNNFX2YNpl7KGO+VtODekSdh4=", + "requires": { + "camel-case": "^3.0.0", + "upper-case-first": "^1.1.0" + } + }, "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", @@ -7293,6 +7675,14 @@ "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=" }, + "path-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/path-case/-/path-case-2.1.1.tgz", + "integrity": "sha1-lLgDfDctP+KQbkZbtF4l0ibo7qU=", + "requires": { + "no-case": "^2.2.0" + } + }, "path-dirname": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", @@ -7396,6 +7786,52 @@ "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==" }, + "polkadot-identicon": { + "version": "1.1.45", + "resolved": "https://registry.npmjs.org/polkadot-identicon/-/polkadot-identicon-1.1.45.tgz", + "integrity": "sha512-UFdxnfvQPHnbKadKibbCGsFrO6XfOy+OeVf+yAyp24CAnSwVujl7OiIdBxnV1V5BVSU61Cfan96grj8VznZk/w==", + "requires": { + "blake2js": "^1.0.0", + "oo7": "^0.7.12", + "oo7-react": "^0.8.13", + "oo7-substrate": "^0.8.0", + "react": "^16.4.2", + "ss58": "^1.0.0" + }, + "dependencies": { + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + }, + "dependencies": { + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + } + } + }, + "react": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react/-/react-16.8.6.tgz", + "integrity": "sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.13.6" + } + } + } + }, "portfinder": { "version": "1.0.17", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.17.tgz", @@ -8895,6 +9331,42 @@ "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-4.0.1.tgz", "integrity": "sha512-xXUbDAZkU08aAkjtUvldqbvI04ogv+a1XdHxvYuHPYKIVk/42BIOD0zSKTHAWV4+gDy3yGm283z2072rA2gdtw==" }, + "react-is": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz", + "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==" + }, + "react-measure": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/react-measure/-/react-measure-2.3.0.tgz", + "integrity": "sha512-dwAvmiOeblj5Dvpnk8Jm7Q8B4THF/f1l1HtKVi0XDecsG6LXwGvzV5R1H32kq3TW6RW64OAf5aoQxpIgLa4z8A==", + "requires": { + "@babel/runtime": "^7.2.0", + "get-node-dimensions": "^1.2.1", + "prop-types": "^15.6.2", + "resize-observer-polyfill": "^1.5.0" + }, + "dependencies": { + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + } + } + }, "react-scripts-ts": { "version": "2.17.0", "resolved": "https://registry.npmjs.org/react-scripts-ts/-/react-scripts-ts-2.17.0.tgz", @@ -9275,6 +9747,11 @@ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" }, + "resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + }, "resolve": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.6.0.tgz", @@ -9438,6 +9915,15 @@ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, + "scheduler": { + "version": "0.13.6", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.13.6.tgz", + "integrity": "sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, "schema-utils": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", @@ -9499,6 +9985,15 @@ } } }, + "sentence-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-2.1.1.tgz", + "integrity": "sha1-H24t2jnBaL+S0T+G1KkYkz9mftQ=", + "requires": { + "no-case": "^2.2.0", + "upper-case-first": "^1.1.2" + } + }, "serialize-javascript": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.5.0.tgz", @@ -9623,6 +10118,14 @@ "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=" }, + "snake-case": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-2.1.0.tgz", + "integrity": "sha1-Qb2xtz8w7GagTU4srRt2OH1NbZ8=", + "requires": { + "no-case": "^2.2.0" + } + }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -9883,6 +10386,15 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, + "ss58": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ss58/-/ss58-1.0.2.tgz", + "integrity": "sha512-hCpPJ12+GgsYsyVW2dXY6p3KfqZgLFA9zrKp5cgEx3x93JjPG4DDm6lu0Zp87FW0CSRan3gy7jlF4ZCjHqS7Ig==", + "requires": { + "blakejs": "^1.1.0", + "bs58": "^4.0.1" + } + }, "sshpk": { "version": "1.14.2", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", @@ -10153,6 +10665,15 @@ "serviceworker-cache-polyfill": "^4.0.0" } }, + "swap-case": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/swap-case/-/swap-case-1.1.2.tgz", + "integrity": "sha1-w5IDpFhzhfrTyFCgvRvK+ggZdOM=", + "requires": { + "lower-case": "^1.1.1", + "upper-case": "^1.1.1" + } + }, "symbol-tree": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", @@ -10183,6 +10704,16 @@ "require-main-filename": "^1.0.1" } }, + "text-encoding": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.7.0.tgz", + "integrity": "sha512-oJQ3f1hrOnbRLOcwKz0Liq2IcrvDeZRHXhd9RgLrsT+DjWY/nty1Hi7v3dtkaEYbPYe0mUoOfzRrMwfXXwgPUA==" + }, + "text-encoding-polyfill": { + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/text-encoding-polyfill/-/text-encoding-polyfill-0.6.7.tgz", + "integrity": "sha512-/DZ1XJqhbqRkCop6s9ZFu8JrFRwmVuHg4quIRm+ziFkR3N3ec6ck6yBvJ1GYeEQZhLVwRW0rZE+C3SSJpy0RTg==" + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -10230,6 +10761,15 @@ "setimmediate": "^1.0.4" } }, + "title-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/title-case/-/title-case-2.1.1.tgz", + "integrity": "sha1-PhJyFtpY0rxb7PE3q5Ha46fNj6o=", + "requires": { + "no-case": "^2.2.0", + "upper-case": "^1.0.3" + } + }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -10699,6 +11239,11 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" }, + "unorm": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.5.0.tgz", + "integrity": "sha512-sMfSWoiRaXXeDZSXC+YRZ23H4xchQpwxjpw1tmfR+kgbBCaOgln4NI0LXejJIhnBuKINrB3WRn+ZI8IWssirVw==" + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -10784,6 +11329,14 @@ "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=" }, + "upper-case-first": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-1.1.2.tgz", + "integrity": "sha1-XXm+3P8UQZUY/S7bCgUHybaFkRU=", + "requires": { + "upper-case": "^1.1.1" + } + }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", @@ -11649,6 +12202,14 @@ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" }, + "xxhashjs": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.2.tgz", + "integrity": "sha512-AkTuIuVTET12tpsVIQo+ZU6f/qDmKuRUcjaqR+OIvm+aCBsZ95i7UVY5WJ9TMsSaZ0DA2WxoZ4acu0sPH+OKAw==", + "requires": { + "cuint": "^0.2.2" + } + }, "y18n": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 83d5eda..b17ec1e 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -20,9 +20,11 @@ }, "dependencies": { "@fnando/sparkline": "maciejhirsz/sparkline", - "polkadot-identicon": "^1.1.36", + "@types/react-measure": "^2.0.5", + "polkadot-identicon": "^1.1.45", "react": "16.4.0", "react-dom": "16.4.0", + "react-measure": "^2.3.0", "react-scripts-ts": "2.17.0", "react-svg": "^4.1.1", "stable": "^0.1.8" diff --git a/packages/frontend/public/Jdenticon.min.js b/packages/frontend/public/Jdenticon.min.js new file mode 100644 index 0000000..d7bec5e --- /dev/null +++ b/packages/frontend/public/Jdenticon.min.js @@ -0,0 +1,19 @@ +// Jdenticon 2.1.1 | jdenticon.com | MIT licensed | (c) 2014-2018 Daniel Mester Pirttijärvi +(function(q,y,z){var t=z(q,q.jQuery);"undefined"!==typeof module&&"exports"in module?module.exports=t:"function"===typeof define&&define.amd?define([],function(){return t}):q[y]=t})(this,"jdenticon",function(q,y){function z(a,b,c){for(var d=document.createElementNS("http://www.w3.org/2000/svg",b),f=2;f+1>>e&15).toString(16));return b.join("")}(function(a){for(var b= +1732584193,d=4023233417,f=2562383102,e=271733878,h=3285377520,k=[b,d,f,e,h],g=0;gl;l++){var A=u[l-3]^u[l-8]^u[l-14]^u[l-16];u[l]=A<<1|A>>>31}for(l=0;80>l;l++)A=(b<<5|b>>>27)+(20>l?(d&f^~d&e)+1518500249:40>l?(d^f^e)+1859775393:60>l?(d&f^d&e^f&e)+2400959708:(d^f^e)+3395469782)+h+u[l],h=e,e=f,f=d<<30|d>>>2,d=b,b=A|0;k[0]=b=k[0]+b|0;k[1]=d=k[1]+d|0;k[2]=f=k[2]+f|0;k[3]=e=k[3]+e|0;k[4]=h=k[4]+h|0}return k}(function(a){function b(a,b){for(var c=[],d=-1,e=0;e++d;)c[d]=0;return c}var d=encodeURI(a),f=[];a=0;var e,h=[];for(e=0;ea?"00":16>a?"0"+a.toString(16):256>a?a.toString(16):"ff"}function F(a,b,c){c=0>c?c+6:6c?a+(b-a)*c:3>c?b:4>c?a+(b-a)*(4-c):a))}function O(a){"undefined"!=typeof MutationObserver&&(new MutationObserver(function(b){for(var c=0;cf;f++){var q=r(b,8+f,1)%p.length;if(g([0,4])||g([2,3]))q=1;n.push(q)}k(0, +I.I,2,3,[[1,0],[2,0],[2,3],[1,3],[0,1],[3,1],[3,2],[0,2]]);k(1,I.I,4,5,[[0,0],[3,0],[3,3],[0,3]]);k(2,I.M,1,null,[[1,1],[2,1],[2,2],[1,2]]);a.finish()}function J(){function a(a,b){var d=c[a];d&&1a?0:1a.length){var b=a[1],c=a[2],d=a[3];a=a[4]||"";return"#"+b+b+c+c+d+d+a+a}if(7==a.length||8=c?c*(b+1):c+b-c*b;c=2*c-b;return"#"+F(c,b,6*a+2)+F(c,b,6*a)+F(c,b,6*a-2)},i:function(a,b,c){var d=[.55,.5,.5,.46,.6,.55,.55][6*a+.5|0];return m.N(a,b,.5>c?c*d*2:d+(c-.5)*(1-d)*2)}},I={M:[function(a,b){var c=.42*b;a.f([0,0,b,0,b,b-2*c,b-c,b,0,b])},function(a,b){var c=0|.5*b;a.b(b-c,0,c,0|.8*b,2)},function(a,b){var c=0|b/3;a.a(c,c,b-c,b-c)},function(a,b){var c=.1*b,d= +6>b?1:8>b?2:0|.25*b;c=1b?1:6>b?2:0|.35*b;c=8>b?c:0|c;a.a(0,0,b,b);a.a(d,d,b-d-c,b-d-c,!0)},function(a,b){var c=.12* +b,d=3*c;a.a(0,0,b,b);a.g(d,d,b-c-d,!0)},function(a,b){a.b(b/2,b/2,b/2,b/2,3)},function(a,b){var c=.25*b;a.a(0,0,b,b);a.l(c,c,b-c,b-c,!0)},function(a,b,c){var d=.4*b;c||a.g(d,d,1.2*b)}],I:[function(a,b){a.b(0,0,b,b,0)},function(a,b){a.b(0,b/2,b,b/2,0)},function(a,b){a.l(0,0,b,b)},function(a,b){var c=b/6;a.g(c,c,b-2*c)}]};L.prototype={f:function(a){for(var b="M"+p(a[0].x)+" "+p(a[0].y),c=1;c +