diff --git a/packages/backend/src/Aggregator.ts b/packages/backend/src/Aggregator.ts index 45c69ac02..b13d908b4 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 14f04b670..82493d24c 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 15d09a131..2b9a39ea2 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 124a6c8c2..f84ab822a 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 f199ada5a..eb46c76b0 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 0a675b5a6..285fd9cb7 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 7c2e34b3a..47d98200e 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 bed26cdb7..29ad4e73d 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 83d5edafe..b17ec1e7b 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 000000000..d7bec5eab --- /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 +