+));
+
+configure(require.context('../packages', true, /\.stories\.tsx?$/), module)
diff --git a/pioneer/.storybook/style.css b/pioneer/.storybook/style.css
new file mode 100644
index 0000000000..ed3151fd12
--- /dev/null
+++ b/pioneer/.storybook/style.css
@@ -0,0 +1,4 @@
+.StorybookRoot {
+ background-color: #fafafa;
+ padding: 1rem 5rem;
+}
\ No newline at end of file
diff --git a/pioneer/.storybook/webpack.config.js b/pioneer/.storybook/webpack.config.js
new file mode 100644
index 0000000000..6c02952773
--- /dev/null
+++ b/pioneer/.storybook/webpack.config.js
@@ -0,0 +1,81 @@
+const path = require('path')
+const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
+module.exports = ({ config }) => {
+
+// Post CSS loader for sources:
+config.module.rules.push({
+ test: /\.css$/,
+ include: path.resolve(__dirname, '../packages'),
+ exclude: /(node_modules)/,
+ use: [
+ {
+ loader: require.resolve('postcss-loader'),
+ options: {
+ // Set postcss.config.js config path && ctx
+ config: {
+ path: '../postcss.config.js',
+ },
+ ident: 'postcss',
+ plugins: () => [
+ require('precss'),
+ require('autoprefixer'),
+ require('postcss-simple-vars'),
+ require('postcss-nested'),
+ require('postcss-import'),
+ require('postcss-clean')(),
+ require('postcss-flexbugs-fixes')
+ ]
+ }
+ }
+ ]
+});
+
+// TypeScript loader (via Babel to match polkadot/apps)
+config.module.rules.push({
+ test: /\.(js|ts|tsx)$/,
+ exclude: /(node_modules)/,
+ use: [
+ {
+ loader: require.resolve('babel-loader'),
+ options: require('@polkadot/dev-react/config/babel')
+ },
+ ],
+});
+config.resolve.extensions.push('.js', '.ts', '.tsx');
+
+// TSConfig, uses the same file as packages
+config.resolve.plugins = config.resolve.plugins || [];
+config.resolve.plugins.push(
+ new TsconfigPathsPlugin({
+ configFile: path.resolve(__dirname, '../tsconfig.json'),
+ })
+);
+
+// Stories parser
+config.module.rules.push({
+ test: /\.stories\.tsx?$/,
+ loaders: [require.resolve('@storybook/source-loader')],
+ enforce: 'pre',
+});
+
+// CSS preprocessors
+config.module.rules.push(
+ {
+ test: /\.s[ac]ss$/i,
+ use: [
+ // Creates `style` nodes from JS strings
+ 'style-loader',
+ // Translates CSS into CommonJS
+ 'css-loader',
+ // Compiles Sass to CSS
+ 'sass-loader',
+ ],
+ },
+ {
+ test: /\.less$/,
+ loaders: [ 'style-loader', 'css-loader', 'less-loader' ]
+ }
+);
+
+return config;
+};
diff --git a/pioneer/.travis.yml b/pioneer/.travis.yml
new file mode 100644
index 0000000000..2a9e336eff
--- /dev/null
+++ b/pioneer/.travis.yml
@@ -0,0 +1,13 @@
+language: node_js
+node_js:
+ - "12"
+cache:
+ yarn: true
+ directories:
+ - node_modules
+before_install:
+ - curl -o- -L https://yarnpkg.com/install.sh | bash
+ - export PATH=$HOME/.yarn/bin:$PATH
+script:
+ - yarn
+ - yarn build
diff --git a/pioneer/BOUNTIES.md b/pioneer/BOUNTIES.md
new file mode 100644
index 0000000000..bb6d10db13
--- /dev/null
+++ b/pioneer/BOUNTIES.md
@@ -0,0 +1,19 @@
+# Bounties
+
+From time-to-time we will add bounties for features.
+
+These are generously provided by the [Web3 Foundation](https://web3.foundation/) and as such employees of Parity or those of the W3F are ineligible for them. (This includes people being by either Party for development or community work, related or un-related to polkadot-js).
+
+The idea is that these bounties should be left open to community participation, so only if there is no outside interest for a specific issue, should those directly or indirectly paid by the W3F for work, attempt to close an issue. (in which case it will be "un-bountied")
+
+Current bounties are tracked by the [!bounty](https://github.com/polkadot-js/apps/labels/%21bounty) label.
+
+## Process
+
+Once listed, the normal [Gitcoin](https://gitcoin.co/) process kicks in. This means application, work and payment is managed by this tool. The values for bounties are determined by the size estimation done by the team.
+
+## Some small requests
+
+Please don't start work on an issue until you have been approved via the gitcoin interface. We generally love enthusiasm and code in the repo, however short-cutting the process does create some issues for the management of the bounties. We certainly don't want to be playing favorites if 2 PRs for the same issue are created at the same time. And in cases where somebody else has been approved and an unapproved PR comes in... well, it gets really murky.
+
+When making changes, please do not force push in your PRs, especially not after a review has been started. We will clone your repo and work from that, doing a simple `pull` on a force-pushed branch ends up being, well, less than simple. We squash merge all PRs, so you do not clutter up the history by using stock-standard pushes to your branch.
diff --git a/pioneer/CHANGELOG.md b/pioneer/CHANGELOG.md
new file mode 100644
index 0000000000..07acbeb0ef
--- /dev/null
+++ b/pioneer/CHANGELOG.md
@@ -0,0 +1,124 @@
+# 0.36.1
+
+- Api 0.95.1, Util 1.6.1, Extension 0.13.1
+- Support latest contracts ABI (via API), incl. rework of contracts UI
+- Support for Kusama CC2
+- Support for Edgeware mainnet
+- Experimental Ledger support
+- Display forks on explorer (limited to Babe)
+- Change settings to have Save as well as Save & Reload (depending on changes made)
+- Updates to struct & enum rendering (as per extrinsic app)
+- Backup, Password change & Delete don't show for built-in dev accounts
+- Add commissions to the staking overview
+- UI theme update
+- A large number of components refactored for React functional components
+- Allow dismiss of all notifications (via bounty)
+- Migrate all buttons to have icons (via bounty)
+- Proposal submission via modal (via bounty)
+- i18n string extraction (via bounty)
+- adjust signature validity (via bounty)
+- Make the network selection clickable on network name (via bounty)
+- ... and a number of cleanups all around
+
+# 0.35.1
+
+- Api 0.91.1, Util 1.2.1, Extension 0.10.1
+- Support for accounts added via Qr (for instance, the Parity Signer)
+- Support for accounts tied to specific chains (instead of just available to all)
+- GenericAsset app transfers
+- Support for Edgeware with default types
+- Display received heartbeats for validators
+- Allow optional params (really as optional) in RPC toolbox
+- Add Polkascan for Kusama
+- Fix account derivation with `///password`
+- Lots of component & maintainability cleanups
+
+# 0.34.1
+
+- Kusama support
+- Full support for Substrate 2.x & Polkadot 0.5.0 networks
+- Lots of UI updated to support both Substrate 1.x & 2.x chains
+- Add of claims app for Kusama (and Polkadot)
+- Basic Council, Parachains & Treasury apps
+- Moved ui-* packages to react-*
+
+# 0.33.1
+
+- Allow for externally injected accounts (i.e. via extension, polkadot-js & SingleSource)
+- Links to extrnisics & addresses on Polkascan
+- Rework Account & Address layouts with cards
+- Transfer can happen from any point (via Transfer modal)
+- Use new api.derive functions
+- Introduce multi support (most via api.derive.*)
+- Update all account and address modals
+- Add seconding of proposals
+- Staking updates, including un-bonding & withdrawals
+- Update explorer with global query on hash/blocks
+- Add filters on the staking page
+- Vanitygen now supports sr25519 as well
+- Fixes for importing of old JSON
+- Latest @polkadot/util & @polkadot/api
+- A large number of optimizations and smaller fixes
+
+# 0.32.1
+
+- Support for Substrate 1.0 release & metadata v4
+- @polkadot/api 0.77.1
+
+# 0.31.1
+
+- Cleanups, fixes and features around the poc-4 staking module
+- Number of UI enhancements
+
+# 0.30.1
+
+- Staking page indicator for offline nodes (count & block)
+- Rework page tabs and content layouts
+- Cleanup of all UI summary headers
+- Emberic Elem support (replaces Dried Danta)
+
+# 0.29.1
+
+- @polkadot/util & @polkadot/api 0.75.1
+
+# 0.28.1
+
+- Support for substrate 1.0-rc
+
+# 0.27.1
+
+- Bring in new staking & nominating functions
+- Swap default keyring accounts (on creation) to sr25519
+- New faster crypto algorithms
+- Misc. bug fixes all around
+
+# 0.26.1
+
+- Swap keyring to HDKD derivation, mnemonic keys are now not backwards compatible with those created earlier. (Defaults are still for ed25519)
+- Swap crypto to new WASM-backed version (and remove libsodium dependency)
+- UI to allow for derived keys for ed25519 and sr25519
+- New mobile-friendly sidebar
+- Fix issues with nominating (old non-bonds interface)
+
+# 0.25.1
+
+- Swap to publishing -beta.x on merge (non-breaking testing)
+
+ # 0.24.1
+
+ Storage now handles Option type properly
+
+ # 0.23.1
+
+ JavaScript console introduced
+
+# 0.22.1
+
+- Use new Compact transaction format - this requires the latest binaries from either Polkadot or Substrate
+
+# 0.21.1
+
+- PoC-3 support with latest Substrate master & Polkadot master
+- Add support for Charred Cherry (Substrate) and Alexander (Polkadot) testnets
+- Too many changes to mention, master now only supports latest PoC-3 iteration
+- Use https://poc-2.polkadot.io if access is required to PoC-2 era networks
diff --git a/pioneer/CONTRIBUTING.md b/pioneer/CONTRIBUTING.md
new file mode 100644
index 0000000000..947952e851
--- /dev/null
+++ b/pioneer/CONTRIBUTING.md
@@ -0,0 +1,45 @@
+# Contributing
+
+## What?
+
+Individuals making significant and valuable contributions are given commit-access to a project to contribute as they see fit.
+A project is more like an open wiki than a standard guarded open source project.
+
+## Rules
+
+There are a few basic ground-rules for contributors (including the maintainer(s) of the project):
+
+1. **No `--force` pushes** or modifying the Git history in any way. If you need to rebase, ensure you do it in your own repo.
+2. **Non-master branches**, prefixed with a short name moniker (e.g. `-`) must be used for ongoing work.
+3. **All modifications** must be made in a **pull-request** to solicit feedback from other contributors.
+4. A pull-request *must not be merged until CI* has finished successfully.
+
+#### Merging pull requests once CI is successful:
+- A pull request with no large change to logic that is an urgent fix may be merged after a non-author contributor has reviewed it well.
+- No PR should be merged until all reviews' comments are addressed.
+
+#### Reviewing pull requests:
+When reviewing a pull request, the end-goal is to suggest useful changes to the author. Reviews should finish with approval unless there are issues that would result in:
+
+- Buggy behaviour.
+- Undue maintenance burden.
+- Breaking with house coding style.
+- Pessimisation (i.e. reduction of speed as measured in the projects benchmarks).
+- Feature reduction (i.e. it removes some aspect of functionality that a significant minority of users rely on).
+- Uselessness (i.e. it does not strictly add a feature or fix a known issue).
+
+#### Reviews may not be used as an effective veto for a PR because:
+- There exists a somewhat cleaner/better/faster way of accomplishing the same feature/fix.
+- It does not fit well with some other contributors' longer-term vision for the project.
+
+## Releases
+
+Declaring formal releases remains the prerogative of the project maintainer(s).
+
+## Changes to this arrangement
+
+This is an experiment and feedback is welcome! This document may also be subject to pull-requests or changes by contributors where you believe you have something valuable to add or change.
+
+## Heritage
+
+These contributing guidelines are modified from the "OPEN Open Source Project" guidelines for the Level project: [https://github.com/Level/community/blob/master/CONTRIBUTING.md](https://github.com/Level/community/blob/master/CONTRIBUTING.md)
diff --git a/pioneer/Dockerfile b/pioneer/Dockerfile
new file mode 100644
index 0000000000..e728afda0c
--- /dev/null
+++ b/pioneer/Dockerfile
@@ -0,0 +1,26 @@
+FROM ubuntu:18.04 as builder
+
+# Install any needed packages
+RUN apt-get update && apt-get install -y curl git gnupg
+
+# install nodejs
+RUN curl -sL https://deb.nodesource.com/setup_10.x | bash -
+RUN apt-get install -y nodejs
+
+WORKDIR /app
+RUN git clone https://github.com/polkadot-js/apps
+
+WORKDIR /app/apps
+RUN npm install yarn -g
+RUN yarn
+RUN NODE_ENV=production yarn build
+
+FROM ubuntu:18.04
+
+RUN apt-get update && apt-get -y install nginx
+
+COPY --from=builder /app/apps/packages/apps/build /var/www/html
+
+EXPOSE 80
+
+CMD ["nginx", "-g", "daemon off;"]
diff --git a/pioneer/LICENSE b/pioneer/LICENSE
new file mode 100644
index 0000000000..0d381b2e97
--- /dev/null
+++ b/pioneer/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/pioneer/README.md b/pioneer/README.md
new file mode 100644
index 0000000000..2e54f5f110
--- /dev/null
+++ b/pioneer/README.md
@@ -0,0 +1,54 @@
+
+
+
+
+A Portal into the Joystream network. Provides a view and interaction layer from a browser.
+
+This can be accessed as a hosted application via [https://testnet.joystream.org](https://testnet.joystream.org).
+
+## overview
+
+The repo is split into a number of packages, each representing an application. These are -
+
+- [apps](packages/apps/) This is the main entry point. It handles the selection sidebar and routing to the specific application being displayed.
+- [app-accounts](packages/app-accounts/) A basic account management app.
+- [app-address-book](packages/app-address-book/) A basic address management app.
+- [app-explorer](packages/app-explorer/) A simple block explorer. It only shows the most recent blocks, updating as they become available.
+- [app-extrinsics](packages/app-extrinsics/) Submission of extrinsics to a node.
+- [app-js](packages/app-js/) An online code editor with [@polkadot-js/api](https://github.com/polkadot-js/api/tree/master/packages/api) access to the currently connected node.
+- [app-settings](packages/app-settings/) A basic settings management app, allowing choice of language, node to connect to, and theme
+- [app-staking](packages/app-staking/) A basic staking management app, allowing staking and nominations.
+- [app-storage](packages/app-storage/) A simple node storage query application. Multiple queries can be queued and updates as new values become available.
+- [app-toolbox](packages/app-toolbox/) Submission of raw data to RPC endpoints and utility hashing functions.
+- [app-transfer](packages/app-transfer/) A basic account management app, allowing transfer of Units/DOTs between accounts.
+
+In addition the following libraries are also included in the repo. These are to be moved to the [@polkadot/ui](https://github.com/polkadot-js/ui/) repository once it reaches a base level of stability and usability. (At this point with the framework being tested on the apps above, it makes development easier having it close)
+
+- [react-components](packages/react-components/) A reactive (using RxJS) application framework with a number of useful shared components.
+- [react-signer](packages/react-signer/) Signer implementation for apps.
+- [react-query](packages/react-query) Base components that use the RxJS Observable APIs
+
+## development
+
+Contributions are welcome!
+
+To start off, this repo (along with others in the [@polkadot](https://github.com/polkadot-js/) family) uses yarn workspaces to organise the code. As such, after cloning dependencies _should_ be installed via `yarn`, not via npm, the latter will result in broken dependencies.
+
+To get started -
+
+1. Clone the repo locally, via `git clone https://github.com/joystream/apps `
+2. Ensure that you have a recent LTS version of Node.js, for development purposes [Node >=10.13.0](https://nodejs.org/en/) is recommended.
+3. Ensure that you have a recent version of Yarn, for development purposes [Yarn >=1.10.1](https://yarnpkg.com/docs/install) is required.
+4. Install the dependencies by running `yarn`
+5. Ready! Now you can launch the UI (assuming you have a local Polkadot Node running), via `yarn run start`
+6. Access the UI via [http://localhost:3000](http://localhost:3000)
+
+### Storybook
+
+There is a [StoryBook](https://storybook.js.org) implementation, the UI for which can be started with `yarn storybook` and then accessed in a browser via http://localhost:3001 (and the server will open a new browser tab by default when it starts).
+
+Story code can be placed anywhere in the `packages` directory, and will be detected as long as the file name ends in `.stories.tsx. Stories should be defined in the [Component Story Format (CSF)](https://storybook.js.org/docs/formats/component-story-format) for consistency.
+
+There are several StoryBook addons available, the most useful of which is [Knobs](https://www.npmjs.com/package/@storybook/addon-knobs), which allows props to be altered in real time.
+
+Note that currently StoryBook only allows for stateless components; it has no connection to polkadot.js or any Substrate node. This means that existing components, which are often tightly coupled with the Polkadot API, cannot be used in storybook.
diff --git a/pioneer/babel.config.js b/pioneer/babel.config.js
new file mode 100644
index 0000000000..07e6884f20
--- /dev/null
+++ b/pioneer/babel.config.js
@@ -0,0 +1,4 @@
+module.exports = {
+ extends: '@polkadot/dev-react/config/babel',
+ sourceType: 'unambiguous',
+};
diff --git a/pioneer/deployment.extras.yml b/pioneer/deployment.extras.yml
new file mode 100644
index 0000000000..6372814aeb
--- /dev/null
+++ b/pioneer/deployment.extras.yml
@@ -0,0 +1,33 @@
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+ name: production-ingress-substrate-ui
+ namespace: poc3-122
+ annotations:
+ kubernetes.io/ingress.class: traefik
+ traefik.frontend.entryPoints: "https,http"
+spec:
+ rules:
+ - host: substrate-ui.parity.io
+ http:
+ paths:
+ - backend:
+ serviceName: production-service
+ servicePort: 80
+---
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+ name: production-ingress-substrate-ui-light
+ namespace: poc3-122
+ annotations:
+ kubernetes.io/ingress.class: traefik
+ traefik.frontend.entryPoints: "https,http"
+spec:
+ rules:
+ - host: substrate-ui-light.parity.io
+ http:
+ paths:
+ - backend:
+ serviceName: production-service
+ servicePort: 80
diff --git a/pioneer/deployment.template.yml b/pioneer/deployment.template.yml
new file mode 100644
index 0000000000..e1be2eacef
--- /dev/null
+++ b/pioneer/deployment.template.yml
@@ -0,0 +1,60 @@
+---
+apiVersion: v1
+data:
+# AZURE_DOCKER_REGISTRY_CONFIG is base64 of this:
+# {"auths":{"parity.azurecr.io":{"username":"parity","password":"","email":"admin@parity.io","auth":""}}}
+ .dockerconfigjson: $AZURE_DOCKER_REGISTRY_CONFIG
+kind: Secret
+metadata:
+ name: azure-docker-registry-key
+type: kubernetes.io/dockerconfigjson
+---
+apiVersion: extensions/v1beta1
+kind: Deployment
+metadata:
+ name: $CI_ENVIRONMENT_SLUG-backend
+spec:
+ replicas: $REPLICAS
+ template:
+ metadata:
+ labels:
+ app: $CI_ENVIRONMENT_SLUG
+ component: backend
+ spec:
+ containers:
+ - name: $CI_ENVIRONMENT_SLUG-backend
+ image: $DOCKER_IMAGE_FULL_NAME
+ imagePullPolicy: Always
+ ports:
+ - containerPort: 80
+ imagePullSecrets:
+ - name: azure-docker-registry-key
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: $CI_ENVIRONMENT_SLUG-service
+spec:
+ selector:
+ app: $CI_ENVIRONMENT_SLUG
+ ports:
+ - name: http
+ port: 80
+ targetPort: 80
+ protocol: TCP
+---
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+ name: $CI_ENVIRONMENT_SLUG-ingress
+ annotations:
+ kubernetes.io/ingress.class: traefik
+ traefik.frontend.entryPoints: "https,http"
+spec:
+ rules:
+ - host: $AUTODEVOPS_HOST
+ http:
+ paths:
+ - backend:
+ serviceName: $CI_ENVIRONMENT_SLUG-service
+ servicePort: 80
diff --git a/pioneer/gh-pages-refresh.sh b/pioneer/gh-pages-refresh.sh
new file mode 100755
index 0000000000..b4aac5b4c8
--- /dev/null
+++ b/pioneer/gh-pages-refresh.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+exit 0
+
+# checkout latest
+git fetch
+git checkout gh-pages
+git pull
+git checkout --orphan gh-pages-temp
+
+# cleanup
+rm -rf node_modules
+rm -rf coverage
+rm -rf packages
+rm -rf test
+
+# add
+git add -A
+git commit -am "refresh history"
+
+# danger, force new
+git branch -D gh-pages
+git branch -m gh-pages
+git push -f origin gh-pages
diff --git a/pioneer/i18next-scanner.config.js b/pioneer/i18next-scanner.config.js
new file mode 100644
index 0000000000..fedbd1b1a4
--- /dev/null
+++ b/pioneer/i18next-scanner.config.js
@@ -0,0 +1,89 @@
+const fs = require('fs');
+const path = require('path');
+const typescript = require('typescript');
+
+module.exports = {
+ input: [
+ 'packages/*/src/**/*.{ts,tsx}',
+ // Use ! to filter out files or directories
+ '!packages/*/src/**/*.spec.{ts,tsx}',
+ '!packages/*/src/i18n/**',
+ '!**/node_modules/**'
+ ],
+ output: './',
+ options: {
+ debug: true,
+ func: {
+ list: ['t', 'i18next.t', 'i18n.t'],
+ extensions: ['.tsx']
+ },
+ trans: {
+ component: 'Trans'
+ },
+ lngs: ['en'],
+ defaultLng: 'en',
+ ns: [
+ 'app-123code',
+ 'app-accounts',
+ 'app-address-book',
+ 'app-claims',
+ 'app-contracts',
+ 'app-council',
+ 'app-dashboard',
+ 'app-democracy',
+ 'app-explorer',
+ 'app-extrinsics',
+ 'app-generic-asset',
+ 'app-js',
+ 'app-parachains',
+ 'app-settings',
+ 'app-staking',
+ 'app-storage',
+ 'app-sudo',
+ 'app-toolbox',
+ 'app-transfer',
+ 'app-treasury',
+ 'apps',
+ 'apps-routing',
+ 'react-api',
+ 'react-components',
+ 'react-params',
+ 'react-query',
+ 'react-signer',
+ 'ui'
+ ],
+ defaultNs: 'ui',
+ resource: {
+ loadPath: 'packages/apps/public/locales/{{lng}}/{{ns}}.json',
+ savePath: 'packages/apps/public/locales/{{lng}}/{{ns}}.json',
+ jsonIndent: 2,
+ lineEnding: '\n'
+ },
+ nsSeparator: false, // namespace separator
+ keySeparator: false // key separator
+ },
+ transform: function transform (file, enc, done) {
+ const { ext } = path.parse(file.path);
+
+ if (ext === '.tsx') {
+ const content = fs.readFileSync(file.path, enc);
+
+ const { outputText } = typescript.transpileModule(content, {
+ compilerOptions: {
+ target: 'es2018'
+ },
+ fileName: path.basename(file.path)
+ });
+
+ const parserHandler = (key, options) => {
+ options.defaultValue = key;
+ options.ns = /packages\/(.*?)\/src/g.exec(file.path)[1];
+ this.parser.set(key, options);
+ };
+
+ this.parser.parseFuncFromString(outputText, parserHandler);
+ }
+
+ done();
+ }
+};
diff --git a/pioneer/img/pioneer_new.svg b/pioneer/img/pioneer_new.svg
new file mode 100644
index 0000000000..550f529e35
--- /dev/null
+++ b/pioneer/img/pioneer_new.svg
@@ -0,0 +1,106 @@
+
+
\ No newline at end of file
diff --git a/pioneer/jest.config.js b/pioneer/jest.config.js
new file mode 100644
index 0000000000..643163e06d
--- /dev/null
+++ b/pioneer/jest.config.js
@@ -0,0 +1,17 @@
+/* eslint-disable @typescript-eslint/no-var-requires */
+const config = require('@polkadot/dev-react/config/jest');
+const findPackages = require('./scripts/findPackages');
+
+const internalModules = findPackages().reduce((modules, { dir, name }) => {
+ modules[`${name}(.*)$`] = `/packages/${dir}/src/$1`;
+
+ return modules;
+}, {});
+
+module.exports = Object.assign({}, config, {
+ moduleNameMapper: {
+ ...internalModules,
+ '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': 'empty/object',
+ '\\.(css|less)$': 'empty/object'
+ }
+});
diff --git a/pioneer/lerna.json b/pioneer/lerna.json
new file mode 100644
index 0000000000..717f6b57c5
--- /dev/null
+++ b/pioneer/lerna.json
@@ -0,0 +1,14 @@
+{
+ "lerna": "2.11.0",
+ "npmClient": "yarn",
+ "useWorkspaces": true,
+ "command": {
+ "publish": {
+ "allowBranch": "master"
+ }
+ },
+ "packages": [
+ "packages/*"
+ ],
+ "version": "0.37.0-beta.63"
+}
diff --git a/pioneer/package.json b/pioneer/package.json
new file mode 100644
index 0000000000..3eecddcce6
--- /dev/null
+++ b/pioneer/package.json
@@ -0,0 +1,85 @@
+{
+ "version": "0.37.0-beta.63",
+ "private": true,
+ "engines": {
+ "node": ">=10.13.0",
+ "yarn": "^1.10.1"
+ },
+ "homepage": ".",
+ "name": "pioneer",
+ "scripts": {
+ "analyze": "yarn run build && cd packages/apps && yarn run source-map-explorer build/main.*.js",
+ "build": "yarn run build:code && yarn run build:i18n",
+ "build:code": "NODE_ENV=production polkadot-dev-build-ts",
+ "build:i18n": "i18next-scanner --config i18next-scanner.config.js",
+ "docs": "echo \"skipping docs\"",
+ "clean": "polkadot-dev-clean-build",
+ "clean:i18n": "rm -rf packages/apps/public/locales/en && mkdir -p packages/apps/public/locales/en",
+ "lint": "eslint --ext .js,.jsx,.ts,.tsx . && tsc --noEmit --pretty",
+ "postinstall": "polkadot-dev-yarn-only",
+ "test": "echo \"skipping tests\"",
+ "vanitygen": "node packages/app-accounts/scripts/vanitygen.js",
+ "start": "cd packages/apps && webpack --config webpack.config.js",
+ "generate-schemas": "json2ts -i packages/joy-types/src/schemas/role.schema.json -o packages/joy-types/src/schemas/role.schema.ts",
+ "build-storybook": "build-storybook -c .storybook",
+ "storybook": "start-storybook -s ./packages/apps/public -p 3001"
+ },
+ "devDependencies": {
+ "@babel/core": "^7.7.0",
+ "@babel/runtime": "^7.7.1",
+ "@babel/cli": "^7.7.4",
+ "@polkadot/dev-react": "^0.32.0-beta.13",
+ "@polkadot/ts": "^0.1.84",
+ "@polkadot/dev": "^0.32.0-beta.15",
+ "@storybook/addon-knobs": "^5.2.5",
+ "@storybook/addon-storysource": "^5.2.5",
+ "@types/jest": "^24.0.22",
+ "@types/react-router-dom": "^5.1.4",
+ "@types/yup": "^0.26.36",
+ "autoprefixer": "^9.7.1",
+ "empty": "^0.10.1",
+ "html-loader": "^0.5.5",
+ "i18next-scanner": "^2.10.3",
+ "json-schema-to-typescript": "^7.1.0",
+ "markdown-loader": "^5.1.0",
+ "postcss": "^7.0.21",
+ "postcss-clean": "^1.1.0",
+ "postcss-flexbugs-fixes": "^4.1.0",
+ "postcss-import": "^12.0.0",
+ "postcss-loader": "^3.0.0",
+ "postcss-nested": "^4.2.1",
+ "postcss-sass": "^0.4.1",
+ "postcss-simple-vars": "^5.0.0",
+ "precss": "^4.0.0",
+ "source-map-explorer": "^2.0.1",
+ "storybook-react-router": "^1.0.8",
+ "ts-jest": "^24.1.0",
+ "tsconfig-paths-webpack-plugin": "^3.2.0",
+ "webpack": "^4.33.0",
+ "typescript": "3.7.2",
+ "cpx": "^1.5.0",
+ "eslint-config-semistandard": "^15.0.0",
+ "eslint-config-standard": "^14.1.1",
+ "eslint-plugin-import": "^2.20.2",
+ "eslint-plugin-node": "^11.1.0",
+ "eslint-plugin-promise": "^4.2.1",
+ "eslint-plugin-standard": "^4.0.1"
+ },
+ "dependencies": {
+ "@polkadot/ui-settings": "^0.47.0-beta.3",
+ "@storybook/addon-actions": "^5.2.5",
+ "@storybook/addon-console": "^1.2.1",
+ "@storybook/react": "^5.2.5",
+ "@types/lodash": "^4.14.138",
+ "@types/marked": "^0.7.0",
+ "ajv": "^6.10.2",
+ "css-loader": "^3.2.0",
+ "less": "^3.10.3",
+ "less-loader": "^5.0.0",
+ "lodash": "^4.17.15",
+ "node-sass": "^4.13.0",
+ "sass-loader": "^8.0.0",
+ "style-loader": "^1.0.0",
+ "@joystream/types": "^0.9.1"
+ }
+}
diff --git a/pioneer/packages/app-123code/LICENSE b/pioneer/packages/app-123code/LICENSE
new file mode 100644
index 0000000000..0d381b2e97
--- /dev/null
+++ b/pioneer/packages/app-123code/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/pioneer/packages/app-123code/README.md b/pioneer/packages/app-123code/README.md
new file mode 100644
index 0000000000..fe01a1661a
--- /dev/null
+++ b/pioneer/packages/app-123code/README.md
@@ -0,0 +1,22 @@
+# @polkadot/app-123code
+
+A simple template to get started with adding an "app" to this UI. It contains the bare minimum for a nicely hackable app (if you just want to code _somewhere_) and the steps needed to create, add and register an new app that appears in the UI.
+
+## adding an app
+
+If you want to add a new app to the UI, this is the place to start.
+
+1. Duplicate this `app-123code` folder and give it an appropriate name, in this case we will select `app-example` to keep things clear.
+2. Edit the `apps-example/package.json` app description, i.e. the name, author and relevant overview.
+
+And we have the basic app source setup, time to get the tooling correct.
+
+3. Add the new app to the TypeScript config in root, `tsconfig.json`, i.e. an entry such as `"@polkadot/app-example/*": [ "packages/app-example/src/*" ],`
+
+At this point the app should be buildable, but not quite reachable. The final step is to add it to the actual sidebar in `apps`.
+
+4. In `apps-routing/src` duplicate the `123code.ts` file to `example.ts` and edit it with the appropriate information, including the hash link, name and icon (any icon name from semantic-ui-react/font-awesome 4 should be appropriate).
+5. In the above description file, the `isHidden` field needs to be toggled to make it appear - the base template is hidden by default.
+6. Finally add the `template` to the `apps-routing/src/index.ts` file at the appropriate place for both full and light mode (either optional)
+
+Yes. After all that we have things hooked up. Run `yarn start` and your new app (non-coded) should show up. Now start having fun and building something great.
diff --git a/pioneer/packages/app-123code/package.json b/pioneer/packages/app-123code/package.json
new file mode 100644
index 0000000000..35ab2dfe86
--- /dev/null
+++ b/pioneer/packages/app-123code/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "@polkadot/app-123code",
+ "version": "0.37.0-beta.63",
+ "description": "A basic app that shows the ropes on customisation",
+ "main": "index.js",
+ "scripts": {},
+ "author": "Jaco Greeff ",
+ "maintainers": [
+ "Jaco Greeff "
+ ],
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@babel/runtime": "^7.7.1",
+ "@polkadot/react-components": "^0.37.0-beta.63"
+ }
+}
diff --git a/pioneer/packages/app-123code/src/AccountSelector.tsx b/pioneer/packages/app-123code/src/AccountSelector.tsx
new file mode 100644
index 0000000000..289b60b869
--- /dev/null
+++ b/pioneer/packages/app-123code/src/AccountSelector.tsx
@@ -0,0 +1,49 @@
+// Copyright 2017-2019 @polkadot/app-123code authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+import React, { useEffect, useState } from 'react';
+import styled from 'styled-components';
+import { Bubble, InputAddress } from '@polkadot/react-components';
+import { AccountIndex, Balance, Nonce } from '@polkadot/react-query';
+
+interface Props {
+ className?: string;
+ onChange: (accountId: string | null) => void;
+}
+
+function AccountSelector ({ className, onChange }: Props): React.ReactElement {
+ const [accountId, setAccountId] = useState(null);
+
+ useEffect((): void => onChange(accountId), [accountId]);
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default styled(AccountSelector)`
+ align-items: flex-end;
+
+ .summary {
+ text-align: center;
+ }
+`;
diff --git a/pioneer/packages/app-123code/src/Summary.tsx b/pioneer/packages/app-123code/src/Summary.tsx
new file mode 100644
index 0000000000..3bd84f13db
--- /dev/null
+++ b/pioneer/packages/app-123code/src/Summary.tsx
@@ -0,0 +1,28 @@
+// Copyright 2017-2019 @polkadot/app-123code authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+import { BareProps } from '@polkadot/react-components/types';
+
+import React from 'react';
+import styled from 'styled-components';
+
+interface Props extends BareProps {
+ children: React.ReactNode;
+}
+
+function Summary ({ children, className, style }: Props): React.ReactElement {
+ return (
+
+ {children}
+
+ );
+}
+
+export default styled(Summary)`
+ opacity: 0.5;
+ padding: 1rem 1.5rem;
+`;
diff --git a/pioneer/packages/app-123code/src/SummaryBar.tsx b/pioneer/packages/app-123code/src/SummaryBar.tsx
new file mode 100644
index 0000000000..9242644597
--- /dev/null
+++ b/pioneer/packages/app-123code/src/SummaryBar.tsx
@@ -0,0 +1,65 @@
+/* eslint-disable @typescript-eslint/camelcase */
+// Copyright 2017-2019 @polkadot/app-123code authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+import { AccountId } from '@polkadot/types/interfaces';
+import { BareProps, I18nProps } from '@polkadot/react-components/types';
+
+import BN from 'bn.js';
+import React, { useContext } from 'react';
+import { ApiContext, withCalls } from '@polkadot/react-api';
+import { Bubble, IdentityIcon } from '@polkadot/react-components';
+import { formatBalance, formatNumber } from '@polkadot/util';
+
+import translate from './translate';
+
+interface Props extends BareProps, I18nProps {
+ balances_totalIssuance?: BN;
+ chain_bestNumber?: BN;
+ chain_bestNumberLag?: BN;
+ staking_validators?: AccountId[];
+}
+
+function SummaryBar ({ balances_totalIssuance, chain_bestNumber, chain_bestNumberLag, staking_validators }: Props): React.ReactElement {
+ const { api, systemChain, systemName, systemVersion } = useContext(ApiContext);
+
+ return (
+
+
+
+ );
+}
+
+// inject the actual API calls automatically into props
+export default translate(
+ withCalls(
+ 'derive.chain.bestNumber',
+ 'derive.chain.bestNumberLag',
+ 'derive.staking.validators',
+ 'query.balances.totalIssuance'
+ )(SummaryBar)
+);
diff --git a/pioneer/packages/app-123code/src/Transfer.tsx b/pioneer/packages/app-123code/src/Transfer.tsx
new file mode 100644
index 0000000000..35ccce6f8b
--- /dev/null
+++ b/pioneer/packages/app-123code/src/Transfer.tsx
@@ -0,0 +1,47 @@
+// Copyright 2017-2019 @polkadot/app-123code authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+import BN from 'bn.js';
+import React, { useState } from 'react';
+import { Button, InputAddress, InputBalance, TxButton } from '@polkadot/react-components';
+
+import Summary from './Summary';
+
+interface Props {
+ accountId?: string | null;
+}
+
+export default function Transfer ({ accountId }: Props): React.ReactElement {
+ const [amount, setAmount] = useState(null);
+ const [recipientId, setRecipientId] = useState(null);
+
+ return (
+
+
transfer
+
+
+
+
+
+
+
+
+ Make a transfer from any account you control to another account. Transfer fees and per-transaction fees apply and will be calculated upon submission.
+
+
+ );
+}
diff --git a/pioneer/packages/app-123code/src/index.tsx b/pioneer/packages/app-123code/src/index.tsx
new file mode 100644
index 0000000000..de0de71b2c
--- /dev/null
+++ b/pioneer/packages/app-123code/src/index.tsx
@@ -0,0 +1,38 @@
+// Copyright 2017-2019 @polkadot/app-123code authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+// some types, AppProps for the app and I18nProps to indicate
+// translatable strings. Generally the latter is quite "light",
+// `t` is inject into props (see the HOC export) and `t('any text')
+// does the translation
+import { AppProps, I18nProps } from '@polkadot/react-components/types';
+
+// external imports (including those found in the packages/*
+// of this repo)
+import React, { useState } from 'react';
+
+// local imports and components
+import AccountSelector from './AccountSelector';
+import SummaryBar from './SummaryBar';
+import Transfer from './Transfer';
+import translate from './translate';
+
+// define our internal types
+interface Props extends AppProps, I18nProps {}
+
+function App ({ className }: Props): React.ReactElement {
+ const [accountId, setAccountId] = useState(null);
+
+ return (
+ // in all apps, the main wrapper is setup to allow the padding
+ // and margins inside the application. (Just from a consistent pov)
+
+
+
+
+
+ );
+}
+
+export default translate(App);
diff --git a/pioneer/packages/app-123code/src/translate.ts b/pioneer/packages/app-123code/src/translate.ts
new file mode 100644
index 0000000000..417da6ef17
--- /dev/null
+++ b/pioneer/packages/app-123code/src/translate.ts
@@ -0,0 +1,7 @@
+// Copyright 2017-2019 @polkadot/app-123code authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+import { withTranslation } from 'react-i18next';
+
+export default withTranslation(['app-123code']);
diff --git a/pioneer/packages/app-accounts/LICENSE b/pioneer/packages/app-accounts/LICENSE
new file mode 100644
index 0000000000..0d381b2e97
--- /dev/null
+++ b/pioneer/packages/app-accounts/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/pioneer/packages/app-accounts/README.md b/pioneer/packages/app-accounts/README.md
new file mode 100644
index 0000000000..6adfe80b58
--- /dev/null
+++ b/pioneer/packages/app-accounts/README.md
@@ -0,0 +1,5 @@
+# @polkadot/app-accounts
+
+## vanity
+
+Running `yarn run vanitygen --match ` runs the generator as a Node CLI app. (Orders of a magnitude faster due to the use of libsoldium bindings)
diff --git a/pioneer/packages/app-accounts/package.json b/pioneer/packages/app-accounts/package.json
new file mode 100644
index 0000000000..b878755133
--- /dev/null
+++ b/pioneer/packages/app-accounts/package.json
@@ -0,0 +1,23 @@
+{
+ "name": "@polkadot/app-accounts",
+ "version": "0.37.0-beta.63",
+ "main": "index.js",
+ "repository": "https://github.com/polkadot-js/apps.git",
+ "author": "Jaco Greeff ",
+ "maintainers": [
+ "Jaco Greeff "
+ ],
+ "contributors": [],
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@babel/runtime": "^7.7.1",
+ "@polkadot/react-components": "^0.37.0-beta.63",
+ "@polkadot/react-qr": "^0.47.0-beta.3",
+ "@types/file-saver": "^2.0.0",
+ "@types/yargs": "^13.0.2",
+ "babel-plugin-module-resolver": "^3.1.1",
+ "detect-browser": "^4.8.0",
+ "file-saver": "^2.0.0",
+ "yargs": "^14.2.0"
+ }
+}
diff --git a/pioneer/packages/app-accounts/scripts/vanitygen.js b/pioneer/packages/app-accounts/scripts/vanitygen.js
new file mode 100755
index 0000000000..32fc07b1d3
--- /dev/null
+++ b/pioneer/packages/app-accounts/scripts/vanitygen.js
@@ -0,0 +1,26 @@
+#!/usr/bin/env node
+/* eslint-disable @typescript-eslint/no-var-requires */
+// Copyright 2017-2019 @polkadot/app-accounts authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+const fs = require('fs');
+const path = require('path');
+
+const [compiled] = ['../vanitygen/cli.js']
+ .map((file) => path.join(__dirname, file))
+ .filter((file) => fs.existsSync(file));
+
+if (compiled) {
+ require(compiled);
+} else {
+ require('@babel/register')({
+ extensions: ['.js', '.ts'],
+ plugins: [
+ ['module-resolver', {
+ alias: {}
+ }]
+ ]
+ });
+ require('../src/vanitygen/cli.ts');
+}
diff --git a/pioneer/packages/app-accounts/src/Account.tsx b/pioneer/packages/app-accounts/src/Account.tsx
new file mode 100644
index 0000000000..91529679a9
--- /dev/null
+++ b/pioneer/packages/app-accounts/src/Account.tsx
@@ -0,0 +1,227 @@
+// Copyright 2017-2019 @polkadot/app-staking authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+import { ActionStatus } from '@polkadot/react-components/Status/types';
+import { I18nProps } from '@polkadot/react-components/types';
+
+import React, { useState, useEffect } from 'react';
+import { Popup } from 'semantic-ui-react';
+import styled from 'styled-components';
+import { AddressCard, AddressInfo, Button, ChainLock, Forget, Menu } from '@polkadot/react-components';
+import keyring from '@polkadot/ui-keyring';
+
+import Backup from './modals/Backup';
+import ChangePass from './modals/ChangePass';
+import Derive from './modals/Derive';
+import Transfer from './modals/Transfer';
+import translate from './translate';
+
+interface Props extends I18nProps {
+ address: string;
+ className?: string;
+}
+
+function Account ({ address, className, t }: Props): React.ReactElement {
+ const [genesisHash, setGenesisHash] = useState(null);
+ const [isBackupOpen, setIsBackupOpen] = useState(false);
+ const [{ isDevelopment, isEditable, isExternal }, setFlags] = useState({ isDevelopment: false, isEditable: false, isExternal: false });
+ const [isDeriveOpen, setIsDeriveOpen] = useState(false);
+ const [isForgetOpen, setIsForgetOpen] = useState(false);
+ const [isPasswordOpen, setIsPasswordOpen] = useState(false);
+ const [isSettingPopupOpen, setIsSettingPopupOpen] = useState(false);
+ const [isTransferOpen, setIsTransferOpen] = useState(false);
+
+ useEffect((): void => {
+ const account = keyring.getAccount(address);
+
+ setGenesisHash((account && account.meta.genesisHash) || null);
+ setFlags({
+ isDevelopment: (account && account.meta.isTesting) || false,
+ isEditable: (account && !(account.meta.isInjected || account.meta.isHardware)) || false,
+ isExternal: (account && account.meta.isExternal) || false
+ });
+ }, [address]);
+
+ const _toggleBackup = (): void => setIsBackupOpen(!isBackupOpen);
+ const _toggleDerive = (): void => setIsDeriveOpen(!isDeriveOpen);
+ const _toggleForget = (): void => setIsForgetOpen(!isForgetOpen);
+ const _togglePass = (): void => setIsPasswordOpen(!isPasswordOpen);
+ const _toggleTransfer = (): void => setIsTransferOpen(!isTransferOpen);
+ const _toggleSettingPopup = (): void => setIsSettingPopupOpen(!isSettingPopupOpen);
+ const _onForget = (): void => {
+ if (!address) {
+ return;
+ }
+
+ const status: Partial = {
+ account: address,
+ action: 'forget'
+ };
+
+ try {
+ keyring.forgetAccount(address);
+ status.status = 'success';
+ status.message = t('account forgotten');
+ } catch (error) {
+ status.status = 'error';
+ status.message = error.message;
+ }
+ };
+ const _onGenesisChange = (genesisHash: string | null): void => {
+ const account = keyring.getPair(address);
+
+ account && keyring.saveAccountMeta(account, { ...account.meta, genesisHash });
+
+ setGenesisHash(genesisHash);
+ };
+
+ // FIXME It is a bit heavy-handled switching of being editable here completely
+ // (and removing the tags, however the keyring cannot save these)
+ return (
+
+
+ )}
+
+ }
+ className={className}
+ isEditable={isEditable}
+ type='account'
+ value={address}
+ withExplorer
+ withIndexOrAddress={false}
+ withTags
+ >
+ {address && (
+ <>
+ {isBackupOpen && (
+
+ )}
+ {isDeriveOpen && (
+
+ )}
+ {isForgetOpen && (
+
+ )}
+ {isPasswordOpen && (
+
+ )}
+ {isTransferOpen && (
+
+ )}
+ >
+ )}
+
+
+ );
+}
+
+export default translate(
+ styled(Account)`
+ .accounts--Account-buttons {
+ text-align: right;
+
+ .others {
+ margin-right: 0.125rem;
+ margin-top: 0.25rem;
+ }
+ }
+ `
+);
diff --git a/pioneer/packages/app-accounts/src/Banner.tsx b/pioneer/packages/app-accounts/src/Banner.tsx
new file mode 100644
index 0000000000..d2dad1eeb9
--- /dev/null
+++ b/pioneer/packages/app-accounts/src/Banner.tsx
@@ -0,0 +1,105 @@
+// Copyright 2017-2019 @polkadot/app-accounts authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+import { I18nProps } from '@polkadot/react-components/types';
+
+import { detect } from 'detect-browser';
+import React from 'react';
+import styled from 'styled-components';
+import { isWeb3Injected } from '@polkadot/extension-dapp';
+import { stringUpperFirst } from '@polkadot/util';
+
+import translate from './translate';
+
+// it would have been really good to import this from detect, however... not exported
+type Browser = 'chrome' | 'firefox';
+
+interface Extension {
+ desc: string;
+ link: string;
+ name: string;
+}
+
+interface Props extends I18nProps {
+ className?: string;
+}
+
+const available: Record = {
+ chrome: [],
+ firefox: []
+};
+
+[
+ {
+ browsers: {
+ chrome: 'https://chrome.google.com/webstore/detail/polkadot%7Bjs%7D-extension/mopnmbcafieddcagagdcbnhejhlodfdd',
+ firefox: 'https://addons.mozilla.org/en-US/firefox/addon/polkadot-js-extension/'
+ },
+ desc: 'Basic account injection and signer',
+ name: 'polkadot-js extension'
+ }
+].forEach(({ browsers, desc, name }): void => {
+ Object.entries(browsers).forEach(([browser, link]): void => {
+ available[browser as Browser].push({ link, desc, name });
+ });
+});
+
+const browserInfo = detect();
+const browserName: Browser | null = (browserInfo && (browserInfo.name as Browser)) || null;
+const isSupported = browserName && Object.keys(available).includes(browserName);
+
+function Banner ({ className, t }: Props): React.ReactElement | null {
+ if (isWeb3Injected || !isSupported || !browserName) {
+ return null;
+ }
+
+ return (
+
+
+
+
{t('It is recommended that you create/store your accounts securely and externally from the app. On {{yourBrowser}} the following browser extensions are available for use -', {
+ replace: {
+ yourBrowser: stringUpperFirst(browserName)
+ }
+ })}
+
{available[browserName].map(({ desc, name, link }): React.ReactNode => (
+
{t('Accounts injected from any of these extensions will appear in this application and be available for use. The above list is updated as more extensions with external signing capability become available.')} {t('Learn more...')}
+ );
+ }
+
+ private checkMatches (): void {
+ const results = this.results;
+
+ this.results = [];
+
+ if (results.length === 0 || !this._isActive) {
+ return;
+ }
+
+ this.setState(
+ ({ keyCount, keyTime, matches, startAt }: State): Pick => {
+ let newKeyCount = keyCount;
+ let newKeyTime = keyTime;
+ const newMatches = results
+ .reduce((result, { elapsed, found }): GeneratorMatch[] => {
+ newKeyCount += found.length;
+ newKeyTime += elapsed;
+
+ return result.concat(found);
+ }, matches)
+ .sort(generatorSort)
+ .slice(0, 25);
+ const elapsed = Date.now() - startAt;
+
+ return {
+ elapsed,
+ matches: newMatches,
+ keyCount: newKeyCount,
+ keyTime: newKeyTime
+ };
+ }
+ );
+ }
+
+ private executeGeneration = (): void => {
+ if (!this.state.isRunning) {
+ this.checkMatches();
+
+ return;
+ }
+
+ setTimeout((): void => {
+ if (this._isActive) {
+ if (this.results.length === 25) {
+ this.checkMatches();
+ }
+
+ const { match, type, withCase, withHex } = this.state;
+
+ this.results.push(
+ generator({
+ match,
+ runs: 10,
+ type,
+ withCase,
+ withHex
+ })
+ );
+
+ this.executeGeneration();
+ }
+ }, 0);
+ }
+
+ private onCreateToggle = (createSeed: string): void => {
+ this.setState({ createSeed });
+ }
+
+ private onChangeCase = (withCase: boolean): void => {
+ this.setState({ withCase });
+ }
+
+ private onChangeMatch = (match: string): void => {
+ this.setState({
+ isMatchValid:
+ matchRegex.test(match) &&
+ (match.length !== 0) &&
+ (match.length < 31),
+ match
+ });
+ }
+
+ private onChangeType = (type: KeypairType): void => {
+ this.setState({ type });
+ }
+
+ private onRemove = (address: string): void => {
+ this.setState(
+ ({ matches }: State): Pick => ({
+ matches: matches.filter((item): boolean =>
+ item.address !== address
+ )
+ })
+ );
+ }
+
+ private toggleStart = (): void => {
+ this.setState(
+ ({ isRunning, keyCount, keyTime, startAt }: State): Pick => {
+ this._isActive = !isRunning;
+
+ return {
+ isRunning: this._isActive,
+ keyCount: this._isActive ? 0 : keyCount,
+ keyTime: this._isActive ? 0 : keyTime,
+ startAt: this._isActive ? Date.now() : startAt
+ };
+ },
+ this.executeGeneration
+ );
+ }
+
+ private closeCreate = (): void => {
+ this.setState({ createSeed: null });
+ }
+}
+
+export default translate(
+ styled(VanityApp)`
+ .vanity--App-matches {
+ padding: 1em 0;
+ }
+
+ .vanity--App-stats {
+ padding: 1em 0 0 0;
+ opacity: 0.45;
+ text-align: center;
+ }
+ `
+);
diff --git a/pioneer/packages/app-accounts/src/Vanity/translate.ts b/pioneer/packages/app-accounts/src/Vanity/translate.ts
new file mode 100644
index 0000000000..196d037c1e
--- /dev/null
+++ b/pioneer/packages/app-accounts/src/Vanity/translate.ts
@@ -0,0 +1,7 @@
+// Copyright 2017-2019 @polkadot/app-accounts authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+import { withTranslation } from 'react-i18next';
+
+export default withTranslation(['app-accounts']);
diff --git a/pioneer/packages/app-accounts/src/bipWorker.ts b/pioneer/packages/app-accounts/src/bipWorker.ts
new file mode 100644
index 0000000000..a4bf5c1ac0
--- /dev/null
+++ b/pioneer/packages/app-accounts/src/bipWorker.ts
@@ -0,0 +1,26 @@
+// Copyright 2017-2019 @polkadot/app-accounts authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+import { cryptoWaitReady, mnemonicGenerate, mnemonicToMiniSecret, naclKeypairFromSeed, schnorrkelKeypairFromSeed } from '@polkadot/util-crypto';
+
+const ctx: Worker = self as unknown as Worker;
+
+cryptoWaitReady().catch((): void => {
+ // ignore
+});
+
+ctx.onmessage = async ({ data: { pairType } }): Promise => {
+ await cryptoWaitReady();
+
+ const seed = mnemonicGenerate();
+ const miniSecret = mnemonicToMiniSecret(seed);
+ const { publicKey } = pairType === 'sr25519'
+ ? schnorrkelKeypairFromSeed(miniSecret)
+ : naclKeypairFromSeed(miniSecret);
+
+ ctx.postMessage({
+ publicKey,
+ seed
+ });
+};
diff --git a/pioneer/packages/app-accounts/src/index.tsx b/pioneer/packages/app-accounts/src/index.tsx
new file mode 100644
index 0000000000..b06159767c
--- /dev/null
+++ b/pioneer/packages/app-accounts/src/index.tsx
@@ -0,0 +1,89 @@
+// Copyright 2017-2019 @polkadot/app-accounts authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+import { AppProps, I18nProps } from '@polkadot/react-components/types';
+import { ComponentProps, LocationProps } from './types';
+import { SubjectInfo } from '@polkadot/ui-keyring/observable/types';
+
+import React, { useEffect, useState } from 'react';
+import { Route, Switch } from 'react-router';
+import accountObservable from '@polkadot/ui-keyring/observable/accounts';
+import { HelpOverlay, Tabs } from '@polkadot/react-components';
+import { withMulti, withObservable } from '@polkadot/react-api';
+
+import basicMd from './md/basic.md';
+import Overview from './Overview';
+import translate from './translate';
+import Vanity from './Vanity';
+
+import MemoForm from './MemoForm';
+
+interface Props extends AppProps, I18nProps {
+ allAccounts?: SubjectInfo;
+ location: any;
+}
+
+function AccountsApp ({ allAccounts = {}, basePath, location, onStatusChange, t }: Props): React.ReactElement {
+ const [hidden, setHidden] = useState(['vanity']);
+
+ useEffect((): void => {
+ setHidden(
+ Object.keys(allAccounts).length !== 0
+ ? []
+ : ['vanity']
+ );
+ }, [allAccounts]);
+
+ const _renderComponent = (Component: React.ComponentType): (props: LocationProps) => React.ReactNode => {
+ // eslint-disable-next-line react/display-name
+ return ({ match }: LocationProps): React.ReactNode => {
+ return (
+
+ );
+ };
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default withMulti(
+ AccountsApp,
+ translate,
+ withObservable(accountObservable.subject, { propName: 'allAccounts' })
+);
diff --git a/pioneer/packages/app-accounts/src/md/basic.md b/pioneer/packages/app-accounts/src/md/basic.md
new file mode 100644
index 0000000000..4386aad6d7
--- /dev/null
+++ b/pioneer/packages/app-accounts/src/md/basic.md
@@ -0,0 +1,44 @@
+# Account
+
+An account is identified by its public address on the network. It is totally fine to give away this address, this is also the only information needed to receive funds. The network will **not** know about the name you give to this account in this application.
+
+# Balances
+
+The balances for each account is broken down into a number of areas, giving an overview of the totals, transferable and bonded funds as well as the funds currently being unbonded or redeemable. These are -
+
+- **total**: The overall amount of funds in the account, this includes the vested balance, available for transfer and locked.
+- **available**: The funds that can be transferred or bonded, i.e. the funds that are available for any transaction.
+- **bonded**: The funds bonded for validating or nominating. They are locked and cannot be transferred, although it can be unlocked for future actions.
+- **redeemable**: The funds that can get redeemed, e.g made available for withdrawal, by clicking on the "lock" icon.
+- **unbonding**: The funds that are being unbonded. The funds will be redeemable after the bonding period has passed. These funds can still be slashed. The information icon tells the amount of blocks left before the funds can be redeemed.
+
+# Security
+
+The public address is generated from a private key, itself generated from a seed or a mnemonic phrase. The seed or the mnemonic phrase should **never be shared with anybody** as they give access to your funds. It must be stored securely.
+The password needed to create an account is used to encrypt your private key. You must choose a strong and unique password.
+This password is also used to encrypt the private key in the backup file downloaded upon account creation. Thanks to this file together with your account password, you can recover your account.
+
+# Account recovery
+
+You can recover an account from its:
+- seed or mnemonic:
+ Click on the "Add account" button, type your seed or mnemonic in the associated field.
+
+- backup file (also called JSON keystore file) and the account's password:
+ Click on "Restore JSON" button. Upload your backup file and type in the password associated.
+
+# Minimum allowed balance
+
+Accounts with a balance lower than the minimal amount, 100 milliUnits (miliDOTs for Polkadot) as of writing are considered as nonexistent for the network. If an account's balance ever drops below this amount, it is removed from the network. In this application, it will still be visible, but with a balance of 0.
+
+For a fund transfer to a **new account** (read an account with a balance of 0), if the amount transferred is less than the minimum allowed balance, then the transfer will "succeed" but the destination account will not be created (read its balance will remain 0); this essentially burns the transfer balance from the sender, because the receiver's balance never exceed the minimum allowed balance.
+
+If the receiver already exists (read it has a balance greater than 0), it is perfectly possible to transfer very low amounts.
+
+# Cryptography
+
+Substrate and Polkadot use Schnorrkel/Ristretto x25519 ("sr25519") as its key derivation and signing algorithm.
+
+Sr25519 is based on the same underlying Curve25519 as its EdDSA counterpart, Ed25519. However, it uses Schnorr signatures instead of the EdDSA scheme. Schnorr signatures bring some noticeable benefits over the ECDSA/EdDSA schemes. For one, it is more efficient and still retains the same feature set and security assumptions. Additionally, it allows for native multisignature through signature aggregation.
+
+If you wish to validate, the `session` account needs to use "ed25519" cryptography.
diff --git a/pioneer/packages/app-accounts/src/modals/Backup.tsx b/pioneer/packages/app-accounts/src/modals/Backup.tsx
new file mode 100644
index 0000000000..2df60c3ae2
--- /dev/null
+++ b/pioneer/packages/app-accounts/src/modals/Backup.tsx
@@ -0,0 +1,144 @@
+// Copyright 2017-2019 @polkadot/app-accounts authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+import { I18nProps } from '@polkadot/react-components/types';
+
+import FileSaver from 'file-saver';
+import React from 'react';
+import { AddressRow, Button, Modal, Password, TxComponent } from '@polkadot/react-components';
+import { ActionStatus } from '@polkadot/react-components/Status/types';
+import keyring from '@polkadot/ui-keyring';
+import { isPasswordValid } from '@polkadot/joy-utils/accounts';
+
+import translate from '../translate';
+
+interface Props extends I18nProps {
+ onClose: () => void;
+ address: string;
+}
+
+interface State {
+ isPassValid: boolean;
+ password: string;
+}
+
+class Backup extends TxComponent {
+ public state: State = {
+ isPassValid: true,
+ password: ''
+ };
+
+ public render (): React.ReactNode {
+ const { t } = this.props;
+
+ return (
+
+ {t('Backup account')}
+ {this.renderContent()}
+ {this.renderButtons()}
+
+ );
+ }
+
+ private renderButtons (): React.ReactNode {
+ const { onClose, t } = this.props;
+ const { isPassValid } = this.state;
+
+ return (
+
+
+
+
+
+
+
+ );
+ }
+
+ private renderContent (): React.ReactNode {
+ const { address, t } = this.props;
+ const { isPassValid, password } = this.state;
+
+ return (
+
+
+
{t('An encrypted backup file will be created once you have pressed the "Download" button. This can be used to re-import your account on any other machine.')}
+
{t('Save this backup file in a secure location. Additionally, the password associated with this account is needed together with this backup file in order to restore your account.')}
{t('This will apply to any future use of this account as stored on this browser. Ensure that you securely store this new password and that it is strong and unique to the account.')}
{t('We will provide you with a generated backup file after your account is created. As long as you have access to your account you can always download this file later by clicking on "Backup" button from the Accounts section.')}
+
{t('Please make sure to save this file in a secure location as it is required, together with your password, to restore your account.')}
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default translate(
+ styled(Transfer)`
+ article.padded {
+ box-shadow: none;
+ margin-left: 2rem;
+ }
+
+ .balance {
+ margin-bottom: 0.5rem;
+ text-align: right;
+ padding-right: 1rem;
+
+ .label {
+ opacity: 0.7;
+ }
+ }
+
+ label.with-help {
+ flex-basis: 10rem;
+ }
+ `
+);
diff --git a/pioneer/packages/app-accounts/src/translate.ts b/pioneer/packages/app-accounts/src/translate.ts
new file mode 100644
index 0000000000..196d037c1e
--- /dev/null
+++ b/pioneer/packages/app-accounts/src/translate.ts
@@ -0,0 +1,7 @@
+// Copyright 2017-2019 @polkadot/app-accounts authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+import { withTranslation } from 'react-i18next';
+
+export default withTranslation(['app-accounts']);
diff --git a/pioneer/packages/app-accounts/src/types.ts b/pioneer/packages/app-accounts/src/types.ts
new file mode 100644
index 0000000000..81962b9590
--- /dev/null
+++ b/pioneer/packages/app-accounts/src/types.ts
@@ -0,0 +1,29 @@
+// Copyright 2017-2019 @polkadot/app-accounts authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+import { AppProps } from '@polkadot/react-components/types';
+import { ActionStatus } from '@polkadot/react-components/Status/types';
+
+import { WithTranslation } from 'react-i18next';
+
+export interface LocationProps {
+ location: any;
+ match: {
+ params: Record;
+ };
+}
+
+export interface BareProps {
+ className?: string;
+ style?: Record;
+}
+
+export type I18nProps = BareProps & WithTranslation;
+
+export type ComponentProps = AppProps & LocationProps;
+
+export interface ModalProps {
+ onClose: () => void;
+ onStatusChange: (status: ActionStatus) => void;
+}
diff --git a/pioneer/packages/app-accounts/src/vanitygen/calculate.ts b/pioneer/packages/app-accounts/src/vanitygen/calculate.ts
new file mode 100644
index 0000000000..cfaaa92b88
--- /dev/null
+++ b/pioneer/packages/app-accounts/src/vanitygen/calculate.ts
@@ -0,0 +1,66 @@
+// Copyright 2017-2019 @polkadot/app-accounts authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+import { GeneratorCalculation, GeneratorOptions } from './types';
+
+const MAX_OFFSET = 5;
+
+function calculateAtOne (atOffset: number, test: string[], address: string): GeneratorCalculation {
+ return {
+ count: test.reduce((count, c, index): number => {
+ if (index === count) {
+ count += (c === '?' || c === address.charAt(index + atOffset)) ? 1 : 0;
+ }
+
+ return count;
+ }, 0),
+ offset: atOffset
+ };
+}
+
+function calculateAt (atOffset: number, test: string[][], address: string): GeneratorCalculation {
+ let bestCount = 0;
+ let bestOffset = 1;
+
+ for (let i = 0; i < test.length; i++) {
+ const { count, offset } = calculateAtOne(atOffset, test[i], address);
+
+ if (count > bestCount) {
+ bestCount = count;
+ bestOffset = offset;
+ }
+ }
+
+ return {
+ count: bestCount,
+ offset: bestOffset
+ };
+}
+
+export default function calculate (test: string[][], _address: string, { atOffset = -1, withCase = false }: GeneratorOptions): GeneratorCalculation {
+ const address = withCase
+ ? _address
+ : _address.toLowerCase();
+
+ if (atOffset > 0) {
+ return calculateAt(atOffset, test, address);
+ }
+
+ let bestCount = 0;
+ let bestOffset = 1;
+
+ for (let index = 0; index < MAX_OFFSET; index++) {
+ const { count, offset } = calculateAt(index, test, address);
+
+ if (count > bestCount) {
+ bestCount = count;
+ bestOffset = offset;
+ }
+ }
+
+ return {
+ count: bestCount,
+ offset: bestOffset
+ };
+}
diff --git a/pioneer/packages/app-accounts/src/vanitygen/cli.ts b/pioneer/packages/app-accounts/src/vanitygen/cli.ts
new file mode 100644
index 0000000000..736e3a83d4
--- /dev/null
+++ b/pioneer/packages/app-accounts/src/vanitygen/cli.ts
@@ -0,0 +1,133 @@
+#!/usr/bin/env node
+// Copyright 2017-2019 @polkadot/app-accounts authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+import { KeypairType } from '@polkadot/util-crypto/types';
+import { GeneratorOptions } from './types';
+
+import yargs from 'yargs';
+import chalk from 'chalk';
+import { u8aToHex } from '@polkadot/util';
+import { cryptoWaitReady, setSS58Format } from '@polkadot/util-crypto';
+
+import generator from '.';
+import matchRegex from './regex';
+
+interface Best {
+ address: string;
+ count: number;
+ mnemonic?: string;
+ offset: number;
+ seed?: Uint8Array;
+ withCase?: boolean;
+}
+
+const { match, mnemonic, network, type, withCase } = yargs
+ .option('match', {
+ default: 'Test',
+ type: 'string'
+ })
+ .option('mnemonic', {
+ default: false,
+ type: 'boolean'
+ })
+ .option('network', {
+ choices: ['substrate', 'polkadot', 'kusama'],
+ default: 'substrate'
+ })
+ .option('type', {
+ choices: ['ed25519', 'sr25519'],
+ default: 'sr25519'
+ })
+ .option('withCase', {
+ default: false,
+ type: 'boolean'
+ })
+ .argv;
+
+const INDICATORS = ['|', '/', '-', '\\'];
+const NUMBER_REGEX = new RegExp('(\\d+?)(?=(\\d{3})+(?!\\d)|$)', 'g');
+
+const options: GeneratorOptions = {
+ match,
+ network,
+ runs: 50,
+ type: type as KeypairType,
+ withCase,
+ withHex: !mnemonic
+};
+const startAt = Date.now();
+let best: Best = {
+ address: '',
+ count: -1,
+ offset: 65536
+};
+let total = 0;
+let indicator = -1;
+const tests = options.match.split(',');
+
+tests.forEach((test): void => {
+ if (!matchRegex.test(test)) {
+ console.error("Invalid character found in match string, allowed is '1-9' (no '0'), 'A-H, J-N & P-Z' (no 'I' or 'O'), 'a-k & m-z' (no 'l') and '?' (wildcard)");
+ process.exit(-1);
+ }
+});
+
+switch (network) {
+ case 'kusama':
+ setSS58Format(2);
+ break;
+
+ case 'polkadot':
+ setSS58Format(0);
+ break;
+
+ default:
+ setSS58Format(42);
+ break;
+}
+
+console.log(options);
+
+function showProgress (): void {
+ const elapsed = (Date.now() - startAt) / 1000;
+
+ indicator++;
+
+ if (indicator === INDICATORS.length) {
+ indicator = 0;
+ }
+
+ process.stdout.write(`\r[${INDICATORS[indicator]}] ${(total.toString().match(NUMBER_REGEX) || []).join(',')} keys in ${(elapsed).toFixed(2)}s (${(total / elapsed).toFixed(0)} keys/s)`);
+}
+
+function showBest (): void {
+ const { address, count, mnemonic, offset, seed } = best;
+
+ console.log(`\r::: ${address.slice(0, offset)}${chalk.cyan(address.slice(offset, count + offset))}${address.slice(count + offset)} <= ${u8aToHex(seed)} (count=${count}, offset=${offset})${mnemonic ? '\n ' + mnemonic : ''}`);
+}
+
+cryptoWaitReady()
+ .then((): void => {
+ while (true) {
+ const nextBest = generator(options).found.reduce((best, match): Best => {
+ if ((match.count > best.count) || ((match.count === best.count) && (match.offset <= best.offset))) {
+ return match;
+ }
+
+ return best;
+ }, best);
+
+ total += options.runs;
+
+ if (nextBest.address !== best.address) {
+ best = nextBest;
+ showBest();
+ showProgress();
+ } else if ((total % (options.withHex ? 1000 : 100)) === 0) {
+ showProgress();
+ }
+ }
+ })
+ .catch((error: Error): void => console.error(error));
diff --git a/pioneer/packages/app-accounts/src/vanitygen/generate.ts b/pioneer/packages/app-accounts/src/vanitygen/generate.ts
new file mode 100644
index 0000000000..617552aa45
--- /dev/null
+++ b/pioneer/packages/app-accounts/src/vanitygen/generate.ts
@@ -0,0 +1,31 @@
+// Copyright 2017-2019 @polkadot/app-accounts authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+import { GeneratorMatch, GeneratorOptions } from './types';
+
+import { encodeAddress, mnemonicGenerate, naclKeypairFromSeed, randomAsU8a, schnorrkelKeypairFromSeed, mnemonicToMiniSecret } from '@polkadot/util-crypto';
+
+import calculate from './calculate';
+
+export default function generator (test: string[][], options: GeneratorOptions): GeneratorMatch {
+ const mnemonic = options.withHex
+ ? undefined
+ : mnemonicGenerate(12);
+ const seed = mnemonic
+ ? mnemonicToMiniSecret(mnemonic)
+ : randomAsU8a();
+ const pair = options.type === 'sr25519'
+ ? schnorrkelKeypairFromSeed(seed)
+ : naclKeypairFromSeed(seed);
+ const address = encodeAddress(pair.publicKey);
+ const { count, offset } = calculate(test, address, options);
+
+ return {
+ address,
+ count,
+ mnemonic,
+ offset,
+ seed
+ };
+}
diff --git a/pioneer/packages/app-accounts/src/vanitygen/index.ts b/pioneer/packages/app-accounts/src/vanitygen/index.ts
new file mode 100644
index 0000000000..269b3dab5f
--- /dev/null
+++ b/pioneer/packages/app-accounts/src/vanitygen/index.ts
@@ -0,0 +1,23 @@
+// Copyright 2017-2019 @polkadot/app-accounts authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+import { GeneratorMatches, GeneratorResult, GeneratorOptions } from './types';
+
+import generate from './generate';
+
+export default function generator (options: GeneratorOptions): GeneratorResult {
+ const { match, runs = 10, withCase = false } = options;
+ const test = (withCase ? match : match.toLowerCase()).split(',').map((c): string[] => c.split(''));
+ const startAt = Date.now();
+ const found: GeneratorMatches = [];
+
+ while (found.length !== runs) {
+ found.push(generate(test, options));
+ }
+
+ return {
+ elapsed: Date.now() - startAt,
+ found
+ };
+}
diff --git a/pioneer/packages/app-accounts/src/vanitygen/regex.ts b/pioneer/packages/app-accounts/src/vanitygen/regex.ts
new file mode 100644
index 0000000000..65cd0b7f56
--- /dev/null
+++ b/pioneer/packages/app-accounts/src/vanitygen/regex.ts
@@ -0,0 +1,7 @@
+// Copyright 2017-2019 @polkadot/app-accounts authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+const regex = new RegExp('^[1-9A-HJ-NP-Za-km-z]*$', '');
+
+export default regex;
diff --git a/pioneer/packages/app-accounts/src/vanitygen/sort.ts b/pioneer/packages/app-accounts/src/vanitygen/sort.ts
new file mode 100644
index 0000000000..ca44f72813
--- /dev/null
+++ b/pioneer/packages/app-accounts/src/vanitygen/sort.ts
@@ -0,0 +1,31 @@
+// Copyright 2017-2019 @polkadot/app-accounts authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+import { GeneratorMatch } from './types';
+
+function numberSort (a: number, b: number): number {
+ if (a > b) {
+ return -1;
+ } else if (a < b) {
+ return 1;
+ }
+
+ return 0;
+}
+
+export default function sort (a: GeneratorMatch, b: GeneratorMatch): number {
+ const countResult = numberSort(a.count, b.count);
+
+ if (countResult !== 0) {
+ return countResult;
+ }
+
+ const positionResult = numberSort(b.offset, a.offset);
+
+ if (positionResult !== 0) {
+ return positionResult;
+ }
+
+ return a.address.localeCompare(b.address);
+}
diff --git a/pioneer/packages/app-accounts/src/vanitygen/types.d.ts b/pioneer/packages/app-accounts/src/vanitygen/types.d.ts
new file mode 100644
index 0000000000..9ecc8f1f80
--- /dev/null
+++ b/pioneer/packages/app-accounts/src/vanitygen/types.d.ts
@@ -0,0 +1,33 @@
+// Copyright 2017-2019 @polkadot/app-accounts authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+import { KeypairType } from '@polkadot/util-crypto/types';
+
+export interface GeneratorCalculation {
+ count: number;
+ offset: number;
+}
+
+export interface GeneratorMatch extends GeneratorCalculation {
+ address: string;
+ mnemonic?: string;
+ seed: Uint8Array;
+}
+
+export type GeneratorMatches = GeneratorMatch[];
+
+export interface GeneratorOptions {
+ atOffset?: number;
+ match: string;
+ network?: string;
+ runs: number;
+ type: KeypairType;
+ withCase?: boolean;
+ withHex?: boolean;
+}
+
+export interface GeneratorResult {
+ elapsed: number;
+ found: GeneratorMatches;
+}
diff --git a/pioneer/packages/app-address-book/LICENSE b/pioneer/packages/app-address-book/LICENSE
new file mode 100644
index 0000000000..0d381b2e97
--- /dev/null
+++ b/pioneer/packages/app-address-book/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/pioneer/packages/app-address-book/README.md b/pioneer/packages/app-address-book/README.md
new file mode 100644
index 0000000000..096a780148
--- /dev/null
+++ b/pioneer/packages/app-address-book/README.md
@@ -0,0 +1 @@
+# @polkadot/app-address-book
diff --git a/pioneer/packages/app-address-book/package.json b/pioneer/packages/app-address-book/package.json
new file mode 100644
index 0000000000..ca862705f4
--- /dev/null
+++ b/pioneer/packages/app-address-book/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "@polkadot/app-address-book",
+ "version": "0.37.0-beta.63",
+ "main": "index.js",
+ "repository": "https://github.com/polkadot-js/apps.git",
+ "author": "Jaco Greeff ",
+ "maintainers": [
+ "Jaco Greeff "
+ ],
+ "contributors": [],
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@babel/runtime": "^7.7.1",
+ "@polkadot/react-components": "^0.37.0-beta.63"
+ }
+}
diff --git a/pioneer/packages/app-address-book/src/Address.tsx b/pioneer/packages/app-address-book/src/Address.tsx
new file mode 100644
index 0000000000..8ae133d642
--- /dev/null
+++ b/pioneer/packages/app-address-book/src/Address.tsx
@@ -0,0 +1,153 @@
+// Copyright 2017-2019 @polkadot/app-staking authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+import { KeyringAddress } from '@polkadot/ui-keyring/types';
+import { ActionStatus } from '@polkadot/react-components/Status/types';
+import { I18nProps } from '@polkadot/react-components/types';
+
+import React, { useEffect, useState } from 'react';
+import styled from 'styled-components';
+import { AddressCard, AddressInfo, Button, ChainLock, Forget } from '@polkadot/react-components';
+import keyring from '@polkadot/ui-keyring';
+
+import Transfer from '@polkadot/app-accounts/modals/Transfer';
+
+import translate from './translate';
+
+interface Props extends I18nProps {
+ address: string;
+ className?: string;
+}
+
+const WITH_BALANCE = { available: true, bonded: true, free: true, locked: true, reserved: true, total: true };
+const WITH_EXTENDED = { nonce: true };
+
+const isEditable = true;
+
+function Address ({ address, className, t }: Props): React.ReactElement {
+ const [current, setCurrent] = useState(null);
+ const [genesisHash, setGenesisHash] = useState(null);
+ const [isForgetOpen, setIsForgetOpen] = useState(false);
+ const [isTransferOpen, setIsTransferOpen] = useState(false);
+
+ useEffect((): void => {
+ const current = keyring.getAddress(address);
+
+ setCurrent(current || null);
+ setGenesisHash((current && current.meta.genesisHash) || null);
+ }, []);
+
+ const _toggleForget = (): void => setIsForgetOpen(!isForgetOpen);
+ const _toggleTransfer = (): void => setIsTransferOpen(!isTransferOpen);
+ const _onForget = (): void => {
+ if (address) {
+ const status: Partial = {
+ account: address,
+ action: 'forget'
+ };
+
+ try {
+ keyring.forgetAddress(address);
+ status.status = 'success';
+ status.message = t('address forgotten');
+ } catch (error) {
+ status.status = 'error';
+ status.message = error.message;
+ }
+ }
+ };
+ const _onGenesisChange = (genesisHash: string | null): void => {
+ setGenesisHash(genesisHash);
+
+ const account = keyring.getAddress(address);
+
+ account && keyring.saveAddress(address, { ...account.meta, genesisHash });
+
+ setGenesisHash(genesisHash);
+ };
+
+ return (
+
+
+ {isEditable && (
+
+ )}
+
+
+ {isEditable && (
+
+
+
+ )}
+
+ }
+ className={className}
+ isEditable={isEditable}
+ type='address'
+ value={address}
+ withExplorer
+ withIndexOrAddress={false}
+ withTags
+ >
+ {address && current && (
+ <>
+ {isForgetOpen && (
+
+ )}
+ {isTransferOpen && (
+
+ )}
+ >
+ )}
+
+
+ );
+}
+
+export default translate(
+ styled(Address)`
+ .addresses--Address-buttons {
+ text-align: right;
+
+ .others {
+ margin-right: 0.125rem;
+ margin-top: 0.25rem;
+ }
+ }
+ `
+);
diff --git a/pioneer/packages/app-address-book/src/MemoByAccount.tsx b/pioneer/packages/app-address-book/src/MemoByAccount.tsx
new file mode 100644
index 0000000000..2e6526b18d
--- /dev/null
+++ b/pioneer/packages/app-address-book/src/MemoByAccount.tsx
@@ -0,0 +1,62 @@
+import React from 'react';
+import { Form } from 'semantic-ui-react';
+import { History } from 'history';
+
+import MemoView from '@polkadot/joy-utils/memo/MemoView';
+import { RouteComponentProps } from 'react-router';
+
+type Props = RouteComponentProps & {
+ history: History,
+ match: {
+ params: {
+ accountId?: string
+ }
+ }
+};
+
+type State = {
+ loaded: boolean,
+ accountInput?: string
+};
+
+export default class Component extends React.PureComponent {
+
+ static getDerivedStateFromProps (props: Props, currentState: State): State | null {
+ const { match: { params: { accountId } } } = props;
+ const { loaded } = currentState;
+ // console.log('getDerivedStateFromProps', props);
+ if (!loaded && accountId) {
+ return { loaded: true, accountInput: accountId };
+ }
+ return null;
+ }
+
+ state: State = {
+ loaded: false,
+ accountInput: ''
+ };
+
+ render () {
+ const { match: { params: { accountId } } } = this.props;
+ const { accountInput } = this.state;
+ return <>
+ this.onChangeAccount(e.target.value)}
+ action={{ icon: 'search', content: 'Find memo', onClick: this.findMemo }}
+ />
+
+ {accountId && }
+ >;
+ }
+
+ private onChangeAccount = (accountInput: string): void => {
+ this.setState({ accountInput });
+ }
+
+ private findMemo = () => {
+ this.props.history.push('/addressbook/memo/' + this.state.accountInput);
+ }
+}
diff --git a/pioneer/packages/app-address-book/src/Overview.tsx b/pioneer/packages/app-address-book/src/Overview.tsx
new file mode 100644
index 0000000000..b54cf8209e
--- /dev/null
+++ b/pioneer/packages/app-address-book/src/Overview.tsx
@@ -0,0 +1,63 @@
+// Copyright 2017-2019 @polkadot/app-address-book authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+import { I18nProps } from '@polkadot/react-components/types';
+import { SubjectInfo } from '@polkadot/ui-keyring/observable/types';
+import { ComponentProps } from './types';
+
+import React, { useState } from 'react';
+import { Button, CardGrid } from '@polkadot/react-components';
+import addressObservable from '@polkadot/ui-keyring/observable/addresses';
+import { withMulti, withObservable } from '@polkadot/react-api';
+
+import CreateModal from './modals/Create';
+import Address from './Address';
+import translate from './translate';
+
+interface Props extends ComponentProps, I18nProps {
+ addresses?: SubjectInfo[];
+}
+
+function Overview ({ addresses, onStatusChange, t }: Props): React.ReactElement {
+ const [isCreateOpen, setIsCreateOpen] = useState(false);
+ const emptyScreen = !isCreateOpen && (!addresses || Object.keys(addresses).length === 0);
+
+ const _toggleCreate = (): void => setIsCreateOpen(!isCreateOpen);
+
+ return (
+
+
+
+ }
+ isEmpty={emptyScreen}
+ emptyText={t('No contacts found.')}
+ >
+ {isCreateOpen && (
+
+ )}
+ {addresses && Object.keys(addresses).map((address): React.ReactNode => (
+
+ ))}
+
+ );
+}
+
+export default withMulti(
+ Overview,
+ translate,
+ withObservable(addressObservable.subject, { propName: 'addresses' })
+);
diff --git a/pioneer/packages/app-address-book/src/index.tsx b/pioneer/packages/app-address-book/src/index.tsx
new file mode 100644
index 0000000000..0bf80288af
--- /dev/null
+++ b/pioneer/packages/app-address-book/src/index.tsx
@@ -0,0 +1,62 @@
+// Copyright 2017-2019 @polkadot/app-address-book authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+import { AppProps, I18nProps } from '@polkadot/react-components/types';
+import { SubjectInfo } from '@polkadot/ui-keyring/observable/types';
+import { ComponentProps } from './types';
+
+import React from 'react';
+import { Route, Switch } from 'react-router';
+import { HelpOverlay } from '@polkadot/react-components';
+import Tabs from '@polkadot/react-components/Tabs';
+
+import basicMd from './md/basic.md';
+import Overview from './Overview';
+import translate from './translate';
+import MemoByAccount from './MemoByAccount';
+
+interface Props extends AppProps, I18nProps {
+ allAddresses?: SubjectInfo;
+ location: any;
+}
+
+function AddressBookApp ({ basePath, onStatusChange, t }: Props): React.ReactElement {
+ const _renderComponent = (Component: React.ComponentType): () => React.ReactNode => {
+ // eslint-disable-next-line react/display-name
+ return (): React.ReactNode =>
+ ;
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default translate(AddressBookApp);
diff --git a/pioneer/packages/app-address-book/src/md/basic.md b/pioneer/packages/app-address-book/src/md/basic.md
new file mode 100644
index 0000000000..88a17043c2
--- /dev/null
+++ b/pioneer/packages/app-address-book/src/md/basic.md
@@ -0,0 +1,6 @@
+# Address book
+
+You can store and get quick access to the most commonly used address, such as a friends' account.
+Any contact you create in this interface will be reflected in the application.
+
+You can edit the name of a contact by clicking on it. To remove a contact from the list, click on the trash icon to "Forget" it.
\ No newline at end of file
diff --git a/pioneer/packages/app-address-book/src/modals/Create.tsx b/pioneer/packages/app-address-book/src/modals/Create.tsx
new file mode 100644
index 0000000000..5c4570a834
--- /dev/null
+++ b/pioneer/packages/app-address-book/src/modals/Create.tsx
@@ -0,0 +1,135 @@
+// Copyright 2017-2019 @polkadot/app-address-book authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+import { I18nProps } from '@polkadot/react-components/types';
+import { ActionStatus } from '@polkadot/react-components/Status/types';
+import { ModalProps } from '../types';
+
+import React, { useState } from 'react';
+
+import { AddressRow, Button, Input, InputAddress, Modal } from '@polkadot/react-components';
+import keyring from '@polkadot/ui-keyring';
+
+import translate from '../translate';
+
+interface Props extends ModalProps, I18nProps {}
+
+function Create ({ onClose, onStatusChange, t }: Props): React.ReactElement {
+ const [{ isNameValid, name }, setName] = useState<{ isNameValid: boolean; name: string }>({ isNameValid: false, name: '' });
+ const [{ address, isAddressExisting, isAddressValid }, setAddress] = useState<{ address: string; isAddressExisting: boolean; isAddressValid: boolean }>({ address: '', isAddressExisting: false, isAddressValid: false });
+ const isValid = isAddressValid && isNameValid;
+
+ const _onChangeAddress = (input: string): void => {
+ let address = '';
+ let isAddressValid = true;
+ let isAddressExisting = false;
+
+ try {
+ address = keyring.encodeAddress(
+ keyring.decodeAddress(input)
+ );
+ isAddressValid = keyring.isAvailable(address);
+
+ if (!isAddressValid) {
+ const old = keyring.getAddress(address);
+
+ if (old) {
+ const newName = old.meta.name || name;
+
+ isAddressExisting = true;
+ isAddressValid = true;
+
+ setName({ isNameValid: !!(newName || '').trim(), name: newName });
+ }
+ }
+ } catch (error) {
+ isAddressValid = false;
+ }
+
+ setAddress({ address: address || input, isAddressExisting, isAddressValid });
+ };
+ const _onChangeName = (name: string): void => setName({ isNameValid: !!name.trim(), name });
+ const _onCommit = (): void => {
+ const status = { action: 'create' } as ActionStatus;
+
+ if (!isValid) {
+ return;
+ }
+
+ try {
+ keyring.saveAddress(address, { name: name.trim(), genesisHash: keyring.genesisHash, tags: [] });
+
+ status.account = address;
+ status.status = address ? 'success' : 'error';
+ status.message = isAddressExisting
+ ? t('address edited')
+ : t('address created');
+
+ InputAddress.setLastValue('address', address);
+ } catch (error) {
+ status.status = 'error';
+ status.message = error.message;
+ }
+
+ onStatusChange(status);
+ onClose();
+ };
+
+ return (
+
+ {t('Add an address')}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default translate(Create);
diff --git a/pioneer/packages/app-address-book/src/translate.ts b/pioneer/packages/app-address-book/src/translate.ts
new file mode 100644
index 0000000000..a0baa8dbf7
--- /dev/null
+++ b/pioneer/packages/app-address-book/src/translate.ts
@@ -0,0 +1,7 @@
+// Copyright 2017-2019 @polkadot/app-address-book authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+import { withTranslation } from 'react-i18next';
+
+export default withTranslation(['app-address-book']);
diff --git a/pioneer/packages/app-address-book/src/types.ts b/pioneer/packages/app-address-book/src/types.ts
new file mode 100644
index 0000000000..e9d25f094f
--- /dev/null
+++ b/pioneer/packages/app-address-book/src/types.ts
@@ -0,0 +1,15 @@
+// Copyright 2017-2019 @polkadot/app-address-book authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+import { AppProps } from '@polkadot/react-components/types';
+import { ActionStatus } from '@polkadot/react-components/Status/types';
+
+export interface ComponentProps extends AppProps {
+ location: any;
+}
+
+export interface ModalProps {
+ onClose: () => void;
+ onStatusChange: (status: ActionStatus) => void;
+}
diff --git a/pioneer/packages/app-claims/LICENSE b/pioneer/packages/app-claims/LICENSE
new file mode 100644
index 0000000000..0d381b2e97
--- /dev/null
+++ b/pioneer/packages/app-claims/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/pioneer/packages/app-claims/README.md b/pioneer/packages/app-claims/README.md
new file mode 100644
index 0000000000..0da50d6462
--- /dev/null
+++ b/pioneer/packages/app-claims/README.md
@@ -0,0 +1 @@
+# @polkadot/app-claims
diff --git a/pioneer/packages/app-claims/package.json b/pioneer/packages/app-claims/package.json
new file mode 100644
index 0000000000..5c7e3671b8
--- /dev/null
+++ b/pioneer/packages/app-claims/package.json
@@ -0,0 +1,17 @@
+{
+ "name": "@polkadot/app-claims",
+ "version": "0.37.0-beta.63",
+ "description": "An app for claiming Polkadot tokens",
+ "main": "index.js",
+ "scripts": {},
+ "author": "Keith Ingram ",
+ "maintainers": [
+ "Keith Ingram ",
+ "Jaco Greeff "
+ ],
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@babel/runtime": "^7.7.1",
+ "@polkadot/react-components": "^0.37.0-beta.63"
+ }
+}
diff --git a/pioneer/packages/app-claims/src/Claim.tsx b/pioneer/packages/app-claims/src/Claim.tsx
new file mode 100644
index 0000000000..7e46c5fff9
--- /dev/null
+++ b/pioneer/packages/app-claims/src/Claim.tsx
@@ -0,0 +1,107 @@
+// Copyright 2017-2019 @polkadot/app-123code authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+import { Option } from '@polkadot/types';
+import { BalanceOf, EthereumAddress } from '@polkadot/types/interfaces';
+import { I18nProps } from '@polkadot/react-components/types';
+
+import React, { useContext, useEffect, useState } from 'react';
+import styled from 'styled-components';
+import { ApiContext } from '@polkadot/react-api';
+import { Button, Card } from '@polkadot/react-components';
+import { formatBalance } from '@polkadot/util';
+
+import translate from './translate';
+import { addrToChecksum } from './util';
+
+interface Props extends I18nProps {
+ button: React.ReactNode;
+ ethereumAddress: EthereumAddress | null;
+}
+
+function Claim ({ button, className, ethereumAddress, t }: Props): React.ReactElement | null {
+ const { api } = useContext(ApiContext);
+ const [claimValue, setClaimValue] = useState(null);
+ const [claimAddress, setClaimAddress] = useState(null);
+ const [isBusy, setIsBusy] = useState(false);
+
+ const _fetchClaim = (address: EthereumAddress): void => {
+ setIsBusy(true);
+
+ api.query.claims
+ .claims