diff --git a/package.json b/package.json index 5a0c2c7420c28e251a6f41c9805954820c91c418..d8af35c95103cc01ec374b84822a20723bc2e365 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ }, "dependencies": { "@parity/api": "^2.1.22", - "@parity/light.js": "https://github.com/parity-js/light.js#4234c236b0b5782fa96aabe27c651eea9d17faaa", + "@parity/light.js": "https://github.com/parity-js/light.js#f62bb37782ed32eb74a8bb0cc428632d3a8c6d45", "axios": "^0.18.0", "electron": "^2.0.0", "electron-dl": "^1.11.0", diff --git a/src/Accounts/Accounts.js b/src/Accounts/Accounts.js index 732484839feaf3dc27d6e23105c6c509ac062fd1..ba164b9e39ccb3ac4f1ad8a69f51b081df9120c2 100644 --- a/src/Accounts/Accounts.js +++ b/src/Accounts/Accounts.js @@ -4,10 +4,49 @@ // SPDX-License-Identifier: MIT import React, { Component } from 'react'; +import { + allAccountsInfo$, + defaultAccount$, + setDefaultAccount$ +} from '@parity/light.js'; +import { Link } from 'react-router-dom'; +import light from '../hoc'; + +@light({ + allAccountsInfo: allAccountsInfo$, + defaultAccount: defaultAccount$ +}) class Accounts extends Component { + handleChange = ({ target: { value } }) => { + setDefaultAccount$(value); + }; + render () { - return
This is the accounts page.
; + const { allAccountsInfo, defaultAccount } = this.props; + + return ( +
+

Current account:

+ {allAccountsInfo ? ( + + ) : ( +

Loading Accounts...

+ )} + +

+ + + +

+
+ ); } } diff --git a/src/Accounts/CreateAccount/CreateAccount.js b/src/Accounts/CreateAccount/CreateAccount.js new file mode 100644 index 0000000000000000000000000000000000000000..33a2433e364da39b982f46fcbbc2d4caf0c74020 --- /dev/null +++ b/src/Accounts/CreateAccount/CreateAccount.js @@ -0,0 +1,29 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: MIT + +import React, { Component } from 'react'; +import { Route } from 'react-router-dom'; + +import Step1 from './CreateAccountStep1'; +import Step2 from './CreateAccountStep2'; +import Step3 from './CreateAccountStep3'; +import Step4 from './CreateAccountStep4'; +import Step5 from './CreateAccountStep5'; + +class CreateAccount extends Component { + render () { + return ( +
+ + + + + +
+ ); + } +} + +export default CreateAccount; diff --git a/src/Accounts/CreateAccount/CreateAccountStep1/CreateAccountStep1.js b/src/Accounts/CreateAccount/CreateAccountStep1/CreateAccountStep1.js new file mode 100644 index 0000000000000000000000000000000000000000..1e7a653bfab1d1ed2238134d8684515170139400 --- /dev/null +++ b/src/Accounts/CreateAccount/CreateAccountStep1/CreateAccountStep1.js @@ -0,0 +1,57 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: MIT + +import React, { Component } from 'react'; +import { inject, observer } from 'mobx-react'; +import { Link } from 'react-router-dom'; + +@inject('createAccountStore') +@observer +class CreateAccountStep1 extends Component { + componentDidMount () { + this.props.createAccountStore.generateNewAccount(); + } + + handleChange = ({ target: { value } }) => + this.props.createAccountStore.setName(value); + + render () { + const { + createAccountStore: { address, generateNewAccount, name }, + location: { pathname } + } = this.props; + + return ( +
+

Create account

+
+ Your new address:
[BLOCKIE]
{address} 
+ {pathname === '/accounts/new' && ( + + )} +
+ + {pathname === '/accounts/new' && + !!name && ( +
+ + + +
+ )} +
+ ); + } +} + +export default CreateAccountStep1; diff --git a/src/Accounts/CreateAccount/CreateAccountStep1/index.js b/src/Accounts/CreateAccount/CreateAccountStep1/index.js new file mode 100644 index 0000000000000000000000000000000000000000..4d231b669908b198f83cb6dcba6e0745eff48a11 --- /dev/null +++ b/src/Accounts/CreateAccount/CreateAccountStep1/index.js @@ -0,0 +1,8 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: MIT + +import CreateAccountStep1 from './CreateAccountStep1'; + +export default CreateAccountStep1; diff --git a/src/Accounts/CreateAccount/CreateAccountStep2/CreateAccountStep2.js b/src/Accounts/CreateAccount/CreateAccountStep2/CreateAccountStep2.js new file mode 100644 index 0000000000000000000000000000000000000000..03671c91d7697925efed68a3c6484790ad029958 --- /dev/null +++ b/src/Accounts/CreateAccount/CreateAccountStep2/CreateAccountStep2.js @@ -0,0 +1,33 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: MIT + +import React, { Component } from 'react'; +import { inject, observer } from 'mobx-react'; +import { Link } from 'react-router-dom'; + +@inject('createAccountStore') +@observer +class CreateAccountStep2 extends Component { + render () { + const { + createAccountStore: { phrase } + } = this.props; + + return ( +
+

Create account step 2

+
+ Please write your secret phrase on a piece of paper:
+
{phrase}
+
+ + + +
+ ); + } +} + +export default CreateAccountStep2; diff --git a/src/Accounts/CreateAccount/CreateAccountStep2/index.js b/src/Accounts/CreateAccount/CreateAccountStep2/index.js new file mode 100644 index 0000000000000000000000000000000000000000..c9ab4570e3974fbae7c6b0b19491784e9f02c056 --- /dev/null +++ b/src/Accounts/CreateAccount/CreateAccountStep2/index.js @@ -0,0 +1,8 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: MIT + +import CreateAccountStep2 from './CreateAccountStep2'; + +export default CreateAccountStep2; diff --git a/src/Accounts/CreateAccount/CreateAccountStep3/CreateAccountStep3.js b/src/Accounts/CreateAccount/CreateAccountStep3/CreateAccountStep3.js new file mode 100644 index 0000000000000000000000000000000000000000..afc603e1b2d5d861e3055ee30ec65aaff0260577 --- /dev/null +++ b/src/Accounts/CreateAccount/CreateAccountStep3/CreateAccountStep3.js @@ -0,0 +1,46 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: MIT + +import React, { Component } from 'react'; +import { inject, observer } from 'mobx-react'; +import { Link } from 'react-router-dom'; + +@inject('createAccountStore') +@observer +class CreateAccountStep3 extends Component { + state = { + value: '' + }; + + handleChange = ({ target: { value } }) => this.setState({ value }); + + render () { + const { + createAccountStore: { phrase } + } = this.props; + const { value } = this.state; + + return ( +
+

Create account step 3

+
+ Please rewrite your whole phrase here
+ +
+ + @brian maybe tell the user to write the 3rd, 9th and 11th word only? + 3,9,11 being random numbers + + {value === phrase && ( + + + + )} +
+ ); + } +} + +export default CreateAccountStep3; diff --git a/src/Accounts/CreateAccount/CreateAccountStep3/index.js b/src/Accounts/CreateAccount/CreateAccountStep3/index.js new file mode 100644 index 0000000000000000000000000000000000000000..4234552cff1f9e991c39a3ff5b0f54e926fa032b --- /dev/null +++ b/src/Accounts/CreateAccount/CreateAccountStep3/index.js @@ -0,0 +1,8 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: MIT + +import CreateAccountStep3 from './CreateAccountStep3'; + +export default CreateAccountStep3; diff --git a/src/Accounts/CreateAccount/CreateAccountStep4/CreateAccountStep4.js b/src/Accounts/CreateAccount/CreateAccountStep4/CreateAccountStep4.js new file mode 100644 index 0000000000000000000000000000000000000000..6e4a00031c8d51daed0764f8044f9293152c1702 --- /dev/null +++ b/src/Accounts/CreateAccount/CreateAccountStep4/CreateAccountStep4.js @@ -0,0 +1,76 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: MIT + +import React, { Component } from 'react'; +import { inject, observer } from 'mobx-react'; + +@inject('createAccountStore') +@observer +class CreateAccountStep3 extends Component { + state = { + confirm: '', + hint: '', + password: '' + }; + + handleConfirmChange = ({ target: { value } }) => { + this.setState({ confirm: value }); + }; + + handleHintChange = ({ target: { value } }) => { + this.setState({ hint: value }); + }; + + handlePasswordChange = ({ target: { value } }) => { + this.setState({ password: value }); + }; + + handleSubmit = () => { + const { createAccountStore, history } = this.props; + const { hint, password } = this.state; + createAccountStore.setPassword(password); + createAccountStore.setHint(hint); + history.push('/accounts/new/step5'); + }; + + render () { + const { confirm, hint, password } = this.state; + + return ( +
+

Create account step 4

+
+ +
+ +
+ + {password && confirm === password && } +
+
+ ); + } +} + +export default CreateAccountStep3; diff --git a/src/Accounts/CreateAccount/CreateAccountStep4/index.js b/src/Accounts/CreateAccount/CreateAccountStep4/index.js new file mode 100644 index 0000000000000000000000000000000000000000..c959872c57d0cd3e905599966ef7875543c4ea03 --- /dev/null +++ b/src/Accounts/CreateAccount/CreateAccountStep4/index.js @@ -0,0 +1,8 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: MIT + +import CreateAccountStep4 from './CreateAccountStep4'; + +export default CreateAccountStep4; diff --git a/src/Accounts/CreateAccount/CreateAccountStep5/CreateAccountStep5.js b/src/Accounts/CreateAccount/CreateAccountStep5/CreateAccountStep5.js new file mode 100644 index 0000000000000000000000000000000000000000..609f0254f50c4d7dbc1029024b232fa3f26b58ad --- /dev/null +++ b/src/Accounts/CreateAccount/CreateAccountStep5/CreateAccountStep5.js @@ -0,0 +1,38 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: MIT + +import React, { Component } from 'react'; +import { inject, observer } from 'mobx-react'; + +@inject('createAccountStore') +@observer +class CreateAccountStep5 extends Component { + handleSubmit = () => { + const { + createAccountStore: { saveAccountToParity }, + history + } = this.props; + saveAccountToParity().then(() => history.push('/settings')); + }; + + render () { + const { + createAccountStore: { hint } + } = this.props; + + return ( +
+

Create account step 5

+

Confirm account creation?

+

+ Password Hint: {hint} +

+ +
+ ); + } +} + +export default CreateAccountStep5; diff --git a/src/Accounts/CreateAccount/CreateAccountStep5/index.js b/src/Accounts/CreateAccount/CreateAccountStep5/index.js new file mode 100644 index 0000000000000000000000000000000000000000..07ea8a6b582c8bacfb83ade7394a3c39171355e3 --- /dev/null +++ b/src/Accounts/CreateAccount/CreateAccountStep5/index.js @@ -0,0 +1,8 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: MIT + +import CreateAccountStep5 from './CreateAccountStep5'; + +export default CreateAccountStep5; diff --git a/src/Accounts/CreateAccount/index.js b/src/Accounts/CreateAccount/index.js new file mode 100644 index 0000000000000000000000000000000000000000..72a41f200b5a1d702c8cc242a01580c2222f8e21 --- /dev/null +++ b/src/Accounts/CreateAccount/index.js @@ -0,0 +1,8 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: MIT + +import CreateAccount from './CreateAccount'; + +export default CreateAccount; diff --git a/src/App/App.js b/src/App/App.js index f5f0e82d8c75cea37f73f0951a1107052b691830..a8a464b80d60c0b4bbcb2a054efd96c051be3b7f 100644 --- a/src/App/App.js +++ b/src/App/App.js @@ -6,10 +6,12 @@ import React, { Component } from 'react'; import { BrowserRouter, MemoryRouter, Route, Link } from 'react-router-dom'; +import CreateAccount from '../Accounts/CreateAccount'; import Loading from '../Loading'; import ProtectedRoute from './ProtectedRoute'; -import Send from '../Send'; import Receive from '../Receive'; +import Send from '../Send'; +import Settings from '../Settings'; import Tokens from '../Tokens'; import './App.css'; @@ -30,16 +32,19 @@ class App extends Component {
- + + + diff --git a/src/Settings/Settings.js b/src/Settings/Settings.js new file mode 100644 index 0000000000000000000000000000000000000000..5288014247a4965a836fb1523a9a1834bc593335 --- /dev/null +++ b/src/Settings/Settings.js @@ -0,0 +1,21 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: MIT + +import React, { Component } from 'react'; + +import Accounts from '../Accounts'; + +class Settings extends Component { + render () { + return ( +
+

This is the settings page.

+ +
+ ); + } +} + +export default Settings; diff --git a/src/Settings/index.js b/src/Settings/index.js new file mode 100644 index 0000000000000000000000000000000000000000..242a4e2c85ac58d0b8f86ef10fba99ad3ce90cd4 --- /dev/null +++ b/src/Settings/index.js @@ -0,0 +1,8 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: MIT + +import Settings from './Settings'; + +export default Settings; diff --git a/src/Tokens/EthBalance/EthBalance.js b/src/Tokens/EthBalance/EthBalance.js index e0faf5f143d8f95619712735f90c94e3c6071b82..3deb19b35c5133e5a3784c52f528406a49215a4d 100644 --- a/src/Tokens/EthBalance/EthBalance.js +++ b/src/Tokens/EthBalance/EthBalance.js @@ -5,6 +5,7 @@ import React, { Component } from 'react'; import { balanceOf$ } from '@parity/light.js'; +import { Link } from 'react-router-dom'; import BalanceLayout from '../BalanceLayout'; import light from '../../hoc'; @@ -14,7 +15,11 @@ import light from '../../hoc'; }) class EthBalance extends Component { render () { - return ; + return ( + + + + ); } } diff --git a/src/stores/createAccountStore.js b/src/stores/createAccountStore.js new file mode 100644 index 0000000000000000000000000000000000000000..23ff68def5aa2b73e2018a69c83c089b1cad5d7c --- /dev/null +++ b/src/stores/createAccountStore.js @@ -0,0 +1,73 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: MIT + +import { action, observable } from 'mobx'; + +import parityStore from './parityStore'; + +class CreateAccountStore { + @observable address = null; + @observable hint = ''; // Password hint (optional) + @observable name = ''; // Account name + @observable password = ''; + @observable phrase = null; // The 12-word seed phrase + + constructor () { + this.parityStore = parityStore; + } + + generateNewAccount = () => { + const { api } = this.parityStore; + + return api.parity + .generateSecretPhrase() + .then(phrase => { + this.setPhrase(phrase); + return api.parity.phraseToAddress(phrase); + }) + .then(address => this.setAddress(address)); + }; + + saveAccountToParity = () => { + const { api } = this.parityStore; + + return api.parity + .newAccountFromPhrase(this.phrase, this.password) + .then(address => api.parity.setAccountName(this.address, this.name)) + .then(() => + api.parity.setAccountMeta(this.address, { + timestamp: Date.now(), + passwordHint: this.hint + }) + ); + }; + + @action + setAddress = address => { + this.address = address; + }; + + @action + setHint = hint => { + this.hint = hint; + }; + + @action + setName = name => { + this.name = name; + }; + + @action + setPassword = password => { + this.password = password; + }; + + @action + setPhrase = phrase => { + this.phrase = phrase; + }; +} + +export default new CreateAccountStore(); diff --git a/src/stores/index.js b/src/stores/index.js index 80ef51408b9635b92d2a6422a03eda719e9002bb..ae43065f1f2d1083dc02dabf8ae1e8331fd4bcc6 100644 --- a/src/stores/index.js +++ b/src/stores/index.js @@ -3,10 +3,12 @@ // // SPDX-License-Identifier: MIT -import ParityStore from './ParityStore'; -import TokensStore from './TokensStore'; +import createAccountStore from './createAccountStore'; +import parityStore from './parityStore'; +import tokensStore from './tokensStore'; export default { - parityStore: new ParityStore(), - tokensStore: new TokensStore() + createAccountStore, + parityStore, + tokensStore }; diff --git a/src/stores/ParityStore.js b/src/stores/parityStore.js similarity index 96% rename from src/stores/ParityStore.js rename to src/stores/parityStore.js index c80da845338b9de1647bced07f4938f0e87080d8..a62c43780190a465e42e38fdf0c2048f28267030 100644 --- a/src/stores/ParityStore.js +++ b/src/stores/parityStore.js @@ -14,7 +14,7 @@ const electron = isElectron() ? window.require('electron') : null; const LS_PREFIX = '__paritylight::'; const LS_KEY = `${LS_PREFIX}secureToken`; -export default class ParityStore { +class ParityStore { @observable downloadProgress = 0; @observable isApiConnected = false; @observable isParityRunning = false; @@ -70,6 +70,9 @@ export default class ParityStore { // Initialize the light.js lib light.setApi(api); + // Also set api as member for React Components to use it if needed + this.api = api; + // TODO This is not working // api.on('connected', () => console.log('ehdsfa')); // api.on('disconnected', () => console.log('ehdsfa')); @@ -139,3 +142,5 @@ export default class ParityStore { updateLS = () => store.set(LS_KEY, this.token); } + +export default new ParityStore(); diff --git a/src/stores/TokensStore.js b/src/stores/tokensStore.js similarity index 95% rename from src/stores/TokensStore.js rename to src/stores/tokensStore.js index 2588f0c1ba2b6068aca9e1269873860e60afc8a8..f3939a2b2f07e666f8ee5a10aeac502ab8b6abf2 100644 --- a/src/stores/TokensStore.js +++ b/src/stores/tokensStore.js @@ -11,7 +11,7 @@ import ethereumIcon from '../assets/img/tokens/ethereum.png'; const LS_PREFIX = '__paritylight::'; const LS_KEY = `${LS_PREFIX}tokens`; -export default class TokensStore { +class TokensStore { @observable tokens = new Map(); constructor () { @@ -53,3 +53,5 @@ export default class TokensStore { updateLS = () => store.set(LS_KEY, this.tokens); } + +export default new TokensStore(); diff --git a/yarn.lock b/yarn.lock index 7ae966e4f44a44c0d2799dc8e39056372ac261c5..07e4c8565f22241a8c561fcad1e5d51ade4f4493 100644 --- a/yarn.lock +++ b/yarn.lock @@ -46,6 +46,13 @@ esutils "^2.0.2" js-tokens "^3.0.0" +"@babel/runtime@^7.0.0-beta.46": + version "7.0.0-beta.46" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.0.0-beta.46.tgz#466a9c0498f6d12d054a185981eef742d59d4871" + dependencies: + core-js "^2.5.3" + regenerator-runtime "^0.11.1" + "@babel/template@7.0.0-beta.44": version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.44.tgz#f8832f4fdcee5d59bf515e595fc5106c529b394f" @@ -115,10 +122,11 @@ version "2.1.6" resolved "https://registry.yarnpkg.com/@parity/jsonrpc/-/jsonrpc-2.1.6.tgz#260bbe7dfcec18d59f0bf1668dfd6021452d6452" -"@parity/light.js@https://github.com/parity-js/light.js#4234c236b0b5782fa96aabe27c651eea9d17faaa": +"@parity/light.js@https://github.com/parity-js/light.js#f62bb37782ed32eb74a8bb0cc428632d3a8c6d45": version "1.0.0" - resolved "https://github.com/parity-js/light.js#4234c236b0b5782fa96aabe27c651eea9d17faaa" + resolved "https://github.com/parity-js/light.js#f62bb37782ed32eb74a8bb0cc428632d3a8c6d45" dependencies: + "@babel/runtime" "^7.0.0-beta.46" "@parity/api" "^2.1.22" memoizee "^0.4.12" rxjs "^6.1.0" @@ -2149,6 +2157,10 @@ core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.0: version "2.5.5" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.5.tgz#b14dde936c640c0579a6b50cabcc132dd6127e3b" +core-js@^2.5.3: + version "2.5.6" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.6.tgz#0fe6d45bf3cac3ac364a9d72de7576f4eb221b9d" + core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -7508,7 +7520,7 @@ regenerate@^1.2.1: version "1.3.3" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f" -regenerator-runtime@^0.11.0: +regenerator-runtime@^0.11.0, regenerator-runtime@^0.11.1: version "0.11.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"