From 3c4a65176456f769cc24ee9567b7ecb00e6ab336 Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Thu, 22 Mar 2018 15:49:12 +0100 Subject: [PATCH] feature(lnd-config): add connection type onboarding screen Add a new set of screens into the connection onboarding flow that allow the user to select wether to connect to a local or remote LND node. Fix #326 --- app/components/Onboarding/Autopilot.js | 24 +--- app/components/Onboarding/Autopilot.scss | 4 +- .../Onboarding/ConnectionDetails.js | 57 ++++++++++ .../Onboarding/ConnectionDetails.scss | 29 +++++ app/components/Onboarding/ConnectionType.js | 35 ++++++ app/components/Onboarding/ConnectionType.scss | 40 +++++++ .../Onboarding/NewAezeedPassword.js | 1 - .../Onboarding/NewWalletPassword.js | 1 - app/components/Onboarding/Onboarding.js | 67 +++++++++-- app/containers/Root.js | 28 ++++- app/lnd/config/index.js | 29 ++++- app/lnd/index.js | 7 +- app/lnd/lib/lightning.js | 5 +- app/lnd/lib/walletUnlocker.js | 3 +- app/main.dev.js | 106 +++++++++--------- app/reducers/onboarding.js | 57 ++++++++-- package.json | 1 + yarn.lock | 30 +++++ 18 files changed, 416 insertions(+), 108 deletions(-) create mode 100644 app/components/Onboarding/ConnectionDetails.js create mode 100644 app/components/Onboarding/ConnectionDetails.scss create mode 100644 app/components/Onboarding/ConnectionType.js create mode 100644 app/components/Onboarding/ConnectionType.scss diff --git a/app/components/Onboarding/Autopilot.js b/app/components/Onboarding/Autopilot.js index 225fb0cb..aa40e41d 100644 --- a/app/components/Onboarding/Autopilot.js +++ b/app/components/Onboarding/Autopilot.js @@ -7,28 +7,14 @@ const Autopilot = ({ autopilot, setAutopilot }) => (
setAutopilot(true)}> - { - autopilot ? - - : - - } - - Enable Autopilot - + {autopilot ? : } + Enable Autopilot
-
+
setAutopilot(false)}> - { - !autopilot && autopilot !== null ? - - : - - } - - Disable Autopilot - + {!autopilot && autopilot !== null ? : } + Disable Autopilot
diff --git a/app/components/Onboarding/Autopilot.scss b/app/components/Onboarding/Autopilot.scss index df5000b2..580bf73e 100644 --- a/app/components/Onboarding/Autopilot.scss +++ b/app/components/Onboarding/Autopilot.scss @@ -5,7 +5,7 @@ section { margin: 20px 0; - + &.enable { &.active { div { @@ -50,4 +50,4 @@ margin-left: 15px; } } -} \ No newline at end of file +} diff --git a/app/components/Onboarding/ConnectionDetails.js b/app/components/Onboarding/ConnectionDetails.js new file mode 100644 index 00000000..ff897630 --- /dev/null +++ b/app/components/Onboarding/ConnectionDetails.js @@ -0,0 +1,57 @@ +import React from 'react' +import PropTypes from 'prop-types' +import styles from './ConnectionDetails.scss' + +const ConnectionDetails = ({ + connectionHost, connectionCert, connectionMacaroon, setConnectionHost, setConnectionCert, setConnectionMacaroon +}) => ( +
+
+ + input} + value={connectionHost} + onChange={event => setConnectionHost(event.target.value)} + /> +
+
+ + input} + value={connectionCert} + onChange={event => setConnectionCert(event.target.value)} + /> +
+
+ + input} + value={connectionMacaroon} + onChange={event => setConnectionMacaroon(event.target.value)} + /> +
+
+) + +ConnectionDetails.propTypes = { + connectionHost: PropTypes.string.isRequired, + connectionCert: PropTypes.string.isRequired, + connectionMacaroon: PropTypes.string.isRequired, + setConnectionHost: PropTypes.func.isRequired, + setConnectionCert: PropTypes.func.isRequired, + setConnectionMacaroon: PropTypes.func.isRequired +} + +export default ConnectionDetails diff --git a/app/components/Onboarding/ConnectionDetails.scss b/app/components/Onboarding/ConnectionDetails.scss new file mode 100644 index 00000000..e278beb8 --- /dev/null +++ b/app/components/Onboarding/ConnectionDetails.scss @@ -0,0 +1,29 @@ +@import '../../variables.scss'; + +.container { + color: $white; + + label { + font-size: 12px; + line-height: 14px; + padding: 10px 0px; + min-height: 14px; + } + + input { + background: transparent; + outline: none; + border: 0; + color: $gold; + -webkit-text-fill-color: $white; + font-size: 22px; + width: 100%; + // font-weight: 200; + margin-bottom: 25px; + } + + input::-webkit-input-placeholder { + text-shadow: none; + -webkit-text-fill-color: initial; + } +} diff --git a/app/components/Onboarding/ConnectionType.js b/app/components/Onboarding/ConnectionType.js new file mode 100644 index 00000000..2a1a8a2c --- /dev/null +++ b/app/components/Onboarding/ConnectionType.js @@ -0,0 +1,35 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { FaCircle, FaCircleThin } from 'react-icons/lib/fa' +import styles from './ConnectionType.scss' + +const ConnectionType = ({ connectionType, setConnectionType }) => ( +
+
+
setConnectionType('local')}> + {connectionType === 'local' ? : } + Automatic +
+
+ In automatic mode, we will check your local machine to see if you already have a Lightning node running. + If so, we will try to use it. If not, we will start up a light-weight neutrino node for you. +
+
+
+
setConnectionType('custom')}> + {connectionType === 'custom' ? : } + Custom +
+
+ Connect to a remote Lightning node or a node running in a non-standard location (advanced users only). +
+
+
+) + +ConnectionType.propTypes = { + connectionType: PropTypes.string.isRequired, + setConnectionType: PropTypes.func.isRequired +} + +export default ConnectionType diff --git a/app/components/Onboarding/ConnectionType.scss b/app/components/Onboarding/ConnectionType.scss new file mode 100644 index 00000000..5d8f8503 --- /dev/null +++ b/app/components/Onboarding/ConnectionType.scss @@ -0,0 +1,40 @@ +@import '../../variables.scss'; + +.container { + color: $white; + + section { + margin: 30px 0; + + &.option { + .button { + width: 150px; + text-align: center; + display: inline-block; + padding: 20px; + border: 1px solid $white; + border-radius: 5px; + font-weight: 200; + cursor: pointer; + transition: all 0.25s; + margin-bottom: 20px; + } + + &.active { + .button { + color: $gold; + border-color: $gold; + } + } + + .button:hover { + color: $gold; + border-color: $gold; + } + + .label { + margin-left: 15px; + } + } + } +} diff --git a/app/components/Onboarding/NewAezeedPassword.js b/app/components/Onboarding/NewAezeedPassword.js index bf4412f9..3c3e72a0 100644 --- a/app/components/Onboarding/NewAezeedPassword.js +++ b/app/components/Onboarding/NewAezeedPassword.js @@ -42,4 +42,3 @@ NewAezeedPassword.propTypes = { } export default NewAezeedPassword - diff --git a/app/components/Onboarding/NewWalletPassword.js b/app/components/Onboarding/NewWalletPassword.js index 38bb69b7..37635168 100644 --- a/app/components/Onboarding/NewWalletPassword.js +++ b/app/components/Onboarding/NewWalletPassword.js @@ -6,7 +6,6 @@ const NewWalletPassword = ({ createWalletPassword, createWalletPasswordConfirmation, showCreateWalletPasswordConfirmationError, - updateCreateWalletPassword, updateCreateWalletPasswordConfirmation }) => ( diff --git a/app/components/Onboarding/Onboarding.js b/app/components/Onboarding/Onboarding.js index 0d63f431..dfece9e7 100644 --- a/app/components/Onboarding/Onboarding.js +++ b/app/components/Onboarding/Onboarding.js @@ -4,6 +4,8 @@ import PropTypes from 'prop-types' import LoadingBolt from 'components/LoadingBolt' import FormContainer from './FormContainer' +import ConnectionType from './ConnectionType' +import ConnectionDetails from './ConnectionDetails' import Alias from './Alias' import Autopilot from './Autopilot' import Login from './Login' @@ -18,6 +20,10 @@ import styles from './Onboarding.scss' const Onboarding = ({ onboarding: { step, + connectionType, + connectionHost, + connectionCert, + connectionMacaroon, alias, autopilot, startingLnd, @@ -26,6 +32,8 @@ const Onboarding = ({ aezeedPassword, fetchingSeed }, + connectionTypeProps, + connectionDetailProps, changeStep, startLnd, submitNewWallet, @@ -40,12 +48,43 @@ const Onboarding = ({ }) => { const renderStep = () => { switch (step) { + case 0.1: + return ( + changeStep(connectionType === 'local' ? 1 : 0.2)} + > + + + ) + + case 0.2: + return ( + changeStep(0.1)} + next={() => + startLnd({ + connectionType, + connectionHost, + connectionCert, + connectionMacaroon + }) + } + > + + + ) + case 1: return ( changeStep(0.1)} next={() => changeStep(2)} > @@ -57,7 +96,7 @@ const Onboarding = ({ title='Autopilot' description='Autopilot is an automatic network manager. Instead of manually adding people to build your network to make payments, enable autopilot to automatically connect you to the Lightning Network using 60% of your balance.' // eslint-disable-line back={() => changeStep(1)} - next={() => startLnd(alias, autopilot)} + next={() => startLnd({ connectionType, alias, autopilot })} > @@ -81,7 +120,9 @@ const Onboarding = ({ back={null} next={() => { // dont allow the user to move on if the confirmation password doesnt match the original password - if (newWalletPasswordProps.showCreateWalletPasswordConfirmationError) { return } + if (newWalletPasswordProps.showCreateWalletPasswordConfirmationError) { + return + } changeStep(5) }} @@ -145,7 +186,9 @@ const Onboarding = ({ back={() => changeStep(6)} next={() => { // don't allow them to move on if they havent re-entered the seed correctly - if (!reEnterSeedProps.reEnterSeedChecker) { return } + if (!reEnterSeedProps.reEnterSeedChecker) { + return + } changeStep(8) }} @@ -174,18 +217,20 @@ const Onboarding = ({ } } - if (startingLnd) { return } - if (fetchingSeed) { return } + if (startingLnd) { + return + } + if (fetchingSeed) { + return + } - return ( -
- {renderStep()} -
- ) + return
{renderStep()}
} Onboarding.propTypes = { onboarding: PropTypes.object.isRequired, + connectionTypeProps: PropTypes.object.isRequired, + connectionDetailProps: PropTypes.object.isRequired, aliasProps: PropTypes.object.isRequired, autopilotProps: PropTypes.object.isRequired, initWalletProps: PropTypes.object.isRequired, diff --git a/app/containers/Root.js b/app/containers/Root.js index b3f0da11..f63cf777 100644 --- a/app/containers/Root.js +++ b/app/containers/Root.js @@ -8,6 +8,10 @@ import LoadingBolt from '../components/LoadingBolt' import Onboarding from '../components/Onboarding' import Syncing from '../components/Onboarding/Syncing' import { + setConnectionType, + setConnectionHost, + setConnectionCert, + setConnectionMacaroon, updateAlias, updatePassword, setAutopilot, @@ -29,6 +33,10 @@ import { fetchBlockHeight, lndSelectors } from '../reducers/lnd' import Routes from '../routes' const mapDispatchToProps = { + setConnectionType, + setConnectionHost, + setConnectionCert, + setConnectionMacaroon, updateAlias, updatePassword, updateCreateWalletPassword, @@ -65,6 +73,20 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { syncPercentage: stateProps.syncPercentage } + const connectionTypeProps = { + connectionType: stateProps.onboarding.connectionType, + setConnectionType: dispatchProps.setConnectionType + } + + const connectionDetailProps = { + connectionHost: stateProps.onboarding.connectionHost, + connectionCert: stateProps.onboarding.connectionCert, + connectionMacaroon: stateProps.onboarding.connectionMacaroon, + setConnectionHost: dispatchProps.setConnectionHost, + setConnectionCert: dispatchProps.setConnectionCert, + setConnectionMacaroon: dispatchProps.setConnectionMacaroon + } + const aliasProps = { updateAlias: dispatchProps.updateAlias, alias: stateProps.onboarding.alias @@ -135,6 +157,8 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { changeStep: dispatchProps.changeStep, startLnd: dispatchProps.startLnd, submitNewWallet: dispatchProps.submitNewWallet, + connectionTypeProps, + connectionDetailProps, aliasProps, autopilotProps, initWalletProps, @@ -174,7 +198,9 @@ const Root = ({ } // Don't launch the app without gRPC connection - if (!lnd.grpcStarted) { return } + if (!lnd.grpcStarted) { + return + } return ( diff --git a/app/lnd/config/index.js b/app/lnd/config/index.js index 523dd0d6..e07a64c6 100644 --- a/app/lnd/config/index.js +++ b/app/lnd/config/index.js @@ -4,29 +4,48 @@ // Windows: TODO find out where cert is located for windows machine import { userInfo, platform } from 'os' import { join } from 'path' +import Store from 'electron-store' + +const store = new Store({ name: 'connection' }) +const plat = platform() let loc let macaroonPath -switch (platform()) { +let lndBin +let lndPath + +switch (plat) { case 'darwin': loc = 'Library/Application Support/Lnd/tls.cert' macaroonPath = 'Library/Application Support/Lnd/admin.macaroon' + lndBin = 'lnd' break case 'linux': loc = '.lnd/tls.cert' macaroonPath = '.lnd/admin.macaroon' + lndBin = 'lnd' break case 'win32': loc = join('Appdata', 'Local', 'Lnd', 'tls.cert') macaroonPath = join('Appdata', 'Local', 'Lnd', 'admin.macaroon') + lndBin = 'lnd.exe' break default: break } +if (process.env.NODE_ENV === 'development') { + lndPath = join(__dirname, '..', '..', '..', 'resources', 'bin', plat, lndBin) +} else { + lndPath = join(__dirname, '..', '..', '..', 'bin', lndBin) +} + export default { - lightningRpc: `${__dirname}/rpc.proto`, - lightningHost: 'localhost:10009', - cert: join(userInfo().homedir, loc), - macaroon: join(userInfo().homedir, macaroonPath) + lnd: () => ({ + lndPath, + lightningRpc: `${__dirname}/rpc.proto`, + lightningHost: store.get('host') || 'localhost:10009', + cert: store.get('cert') || join(userInfo().homedir, loc), + macaroon: store.get('macaroon') || join(userInfo().homedir, macaroonPath) + }) } diff --git a/app/lnd/index.js b/app/lnd/index.js index 02b39fcc..58dc7af8 100644 --- a/app/lnd/index.js +++ b/app/lnd/index.js @@ -6,7 +6,8 @@ import methods from './methods' import walletUnlockerMethods from './walletUnlockerMethods' const initLnd = (callback) => { - const lnd = lightning(config.lightningRpc, config.lightningHost) + const lndConfig = config.lnd() + const lnd = lightning(lndConfig.lightningRpc, lndConfig.lightningHost) const lndSubscribe = mainWindow => subscribe(mainWindow, lnd) const lndMethods = (event, msg, data) => methods(lnd, event, msg, data) @@ -15,7 +16,9 @@ const initLnd = (callback) => { } const initWalletUnlocker = (callback) => { - const walletUnlockerObj = walletUnlocker(config.lightningRpc, config.lightningHost) + const lndConfig = config.lnd() + + const walletUnlockerObj = walletUnlocker(lndConfig.lightningRpc, lndConfig.lightningHost) const walletUnlockerMethodsCallback = (event, msg, data) => walletUnlockerMethods(walletUnlockerObj, event, msg, data) callback(walletUnlockerMethodsCallback) diff --git a/app/lnd/lib/lightning.js b/app/lnd/lib/lightning.js index 8805d8ca..b8095d3c 100644 --- a/app/lnd/lib/lightning.js +++ b/app/lnd/lib/lightning.js @@ -19,12 +19,13 @@ process.env.GRPC_SSL_CIPHER_SUITES = process.env.GRPC_SSL_CIPHER_SUITES || [ ].join(':') const lightning = (rpcpath, host) => { - const lndCert = fs.readFileSync(config.cert) + const lndConfig = config.lnd() + const lndCert = fs.readFileSync(lndConfig.cert) const sslCreds = grpc.credentials.createSsl(lndCert) const rpc = grpc.load(path.join(__dirname, 'rpc.proto')) const metadata = new grpc.Metadata() - const macaroonHex = fs.readFileSync(config.macaroon).toString('hex') + const macaroonHex = fs.readFileSync(lndConfig.macaroon).toString('hex') metadata.add('macaroon', macaroonHex) const macaroonCreds = grpc.credentials.createFromMetadataGenerator((params, callback) => callback(null, metadata)) diff --git a/app/lnd/lib/walletUnlocker.js b/app/lnd/lib/walletUnlocker.js index 55ddef4f..46a8036c 100644 --- a/app/lnd/lib/walletUnlocker.js +++ b/app/lnd/lib/walletUnlocker.js @@ -19,7 +19,8 @@ process.env.GRPC_SSL_CIPHER_SUITES = process.env.GRPC_SSL_CIPHER_SUITES || [ ].join(':') const walletUnlocker = (rpcpath, host) => { - const lndCert = fs.readFileSync(config.cert) + const lndConfig = config.lnd() + const lndCert = fs.readFileSync(lndConfig.cert) const credentials = grpc.credentials.createSsl(lndCert) const rpc = grpc.load(path.join(__dirname, 'rpc.proto')) diff --git a/app/main.dev.js b/app/main.dev.js index 698f0f71..92e189e3 100644 --- a/app/main.dev.js +++ b/app/main.dev.js @@ -15,12 +15,11 @@ import path from 'path' import fs from 'fs' import { spawn } from 'child_process' import { lookup } from 'ps-node' -import os from 'os' +import Store from 'electron-store' import MenuBuilder from './menu' import lnd from './lnd' +import config from './lnd/config' -const plat = os.platform() -const homedir = os.homedir() let mainWindow = null let didFinishLoad = false @@ -28,8 +27,6 @@ let didFinishLoad = false let startedSync = false let sentGrpcDisconnect = false -let certPath - if (process.env.NODE_ENV === 'production') { const sourceMapSupport = require('source-map-support') sourceMapSupport.install() @@ -44,17 +41,12 @@ if (process.env.NODE_ENV === 'development' || process.env.DEBUG_PROD === 'true') const installExtensions = async () => { const installer = require('electron-devtools-installer') const forceDownload = !!process.env.UPGRADE_EXTENSIONS - const extensions = [ - 'REACT_DEVELOPER_TOOLS', - 'REDUX_DEVTOOLS' - ] + const extensions = ['REACT_DEVELOPER_TOOLS', 'REDUX_DEVTOOLS'] - return Promise - .all(extensions.map(name => installer.default(installer[name], forceDownload))) - .catch(console.log) + return Promise.all(extensions.map(name => installer.default(installer[name], forceDownload))).catch(console.log) } -// Send the front end event letting them know the gRPC connection has started +// Send the front end event letting them know the gRPC connection is disconnected const sendGrpcDisconnected = () => { const sendGrpcDisonnectedInterval = setInterval(() => { if (didFinishLoad) { @@ -152,13 +144,8 @@ const sendLndSynced = () => { // Starts the LND node const startLnd = (alias, autopilot) => { - let lndPath - - if (process.env.NODE_ENV === 'development') { - lndPath = path.join(__dirname, '..', 'resources', 'bin', plat, plat === 'win32' ? 'lnd.exe' : 'lnd') - } else { - lndPath = path.join(__dirname, '..', 'bin', plat === 'win32' ? 'lnd.exe' : 'lnd') - } + const lndConfig = config.lnd() + console.log('lndConfig', lndConfig) const neutrinoArgs = [ '--bitcoin.active', @@ -171,7 +158,7 @@ const startLnd = (alias, autopilot) => { `${alias ? `--alias=${alias}` : ''}` ] - const neutrino = spawn(lndPath, neutrinoArgs) + const neutrino = spawn(lndConfig.lndPath, neutrinoArgs) .on('error', error => console.log(`lnd error: ${error}`)) .on('close', code => console.log(`lnd shutting down ${code}`)) @@ -180,12 +167,15 @@ const startLnd = (alias, autopilot) => { // Data stored in variable line, log line to the console const line = data.toString('utf8') - if (process.env.NODE_ENV === 'development') { console.log(line) } + if (process.env.NODE_ENV === 'development') { + console.log(line) + } // If the gRPC proxy has started we can start ours if (line.includes('gRPC proxy started')) { const certInterval = setInterval(() => { - if (fs.existsSync(certPath)) { + console.log('lndConfig', lndConfig) + if (fs.existsSync(lndConfig.cert)) { clearInterval(certInterval) console.log('CERT EXISTS, STARTING WALLET UNLOCKER') @@ -233,7 +223,6 @@ app.on('window-all-closed', () => { } }) - app.on('ready', async () => { if (process.env.NODE_ENV === 'development' || process.env.DEBUG_PROD === 'true') { await installExtensions() @@ -275,40 +264,49 @@ app.on('ready', async () => { menuBuilder.buildMenu() sendGrpcDisconnected() - // Check to see if an LND process is running - lookup({ command: 'lnd' }, (err, results) => { - // There was an error checking for the LND process - if (err) { throw new Error(err) } - - // No LND process was found - if (!results.length) { - // let the application know onboarding has started - sendStartOnboarding() - - // Assign path to certs to certPath - switch (os.platform()) { - case 'darwin': - certPath = path.join(homedir, 'Library/Application Support/Lnd/tls.cert') - break - case 'linux': - certPath = path.join(homedir, '.lnd/tls.cert') - break - case 'win32': - certPath = path.join(homedir, 'AppData', 'Local', 'Lnd', 'tls.cert') - break - default: - break - } - // Start LND - // once the onboarding has finished we wanna let the application we have started syncing and start LND - ipcMain.on('startLnd', (event, { alias, autopilot }) => { - startLnd(alias, autopilot) + // Let the application know onboarding has started. + sendStartOnboarding() + + // Start LND + // once the onboarding has enough information, start or connect to LND. + ipcMain.on('startLnd', (event, options = {}) => { + console.log('STARTING LND', options) + + const store = new Store({ name: 'connection' }) + store.store = { + type: options.connectionType, + host: options.connectionHost, + cert: options.connectionCert, + macaroon: options.connectionMacaroon, + alias: options.alias, + autopilot: options.autopilot + } + + console.log('SAVED CONFIG TO:', store.pathm, 'AS', store.store) + + if (options.connectionType === 'local') { + console.log('LOOKING FOR LOCAL LND') + // Check to see if an LND process is running. + lookup({ command: 'lnd' }, (err, results) => { + // There was an error checking for the LND process. + if (err) { + throw new Error(err) + } + + // No LND process was found. + if (!results.length) { + startLnd(options.alias, options.autopilot) + } else { + // An LND process was found, no need to start our own. + console.log('LND ALREADY RUNNING') + startGrpc() + } }) } else { - // An LND process was found, no need to start our own - console.log('LND ALREADY RUNNING') + console.log('USING CUSTOM LND') startGrpc() + mainWindow.webContents.send('successfullyCreatedWallet') } }) }) diff --git a/app/reducers/onboarding.js b/app/reducers/onboarding.js index f3a7a442..8d4d413d 100644 --- a/app/reducers/onboarding.js +++ b/app/reducers/onboarding.js @@ -1,9 +1,17 @@ import { createSelector } from 'reselect' import { ipcRenderer } from 'electron' +import Store from 'electron-store' + +const store = new Store({ name: 'connection' }) // ------------------------------------ // Constants // ------------------------------------ +export const SET_CONNECTION_TYPE = 'SET_CONNECTION_TYPE' +export const SET_CONNECTION_HOST = 'SET_CONNECTION_HOST' +export const SET_CONNECTION_CERT = 'SET_CONNECTION_CERT' +export const SET_CONNECTION_MACAROON = 'SET_CONNECTION_MACAROON' + export const UPDATE_ALIAS = 'UPDATE_ALIAS' export const UPDATE_PASSWORD = 'UPDATE_PASSWORD' export const UPDATE_CREATE_WALLET_PASSWORD = 'UPDATE_CREATE_WALLET_PASSWORD' @@ -37,6 +45,32 @@ export const SET_SIGNUP_IMPORT = 'SET_SIGNUP_IMPORT' // ------------------------------------ // Actions // ------------------------------------ +export function setConnectionType(connectionType) { + return { + type: SET_CONNECTION_TYPE, + connectionType + } +} + +export function setConnectionHost(connectionHost) { + return { + type: SET_CONNECTION_HOST, + connectionHost + } +} +export function setConnectionCert(connectionCert) { + return { + type: SET_CONNECTION_CERT, + connectionCert + } +} +export function setConnectionMacaroon(connectionMacaroon) { + return { + type: SET_CONNECTION_MACAROON, + connectionMacaroon + } +} + export function updateAlias(alias) { return { type: UPDATE_ALIAS, @@ -112,9 +146,9 @@ export function changeStep(step) { } } -export function startLnd(alias, autopilot) { +export function startLnd(options) { // once the user submits the data needed to start LND we will alert the app that it should start LND - ipcRenderer.send('startLnd', { alias, autopilot }) + ipcRenderer.send('startLnd', options) return { type: STARTING_LND @@ -177,6 +211,10 @@ export const unlockWalletError = () => (dispatch) => { // Action Handlers // ------------------------------------ const ACTION_HANDLERS = { + [SET_CONNECTION_TYPE]: (state, { connectionType }) => ({ ...state, connectionType }), + [SET_CONNECTION_HOST]: (state, { connectionHost }) => ({ ...state, connectionHost }), + [SET_CONNECTION_CERT]: (state, { connectionCert }) => ({ ...state, connectionCert }), + [SET_CONNECTION_MACAROON]: (state, { connectionMacaroon }) => ({ ...state, connectionMacaroon }), [UPDATE_ALIAS]: (state, { alias }) => ({ ...state, alias }), [UPDATE_PASSWORD]: (state, { password }) => ({ ...state, password }), [UPDATE_CREATE_WALLET_PASSWORD]: (state, { createWalletPassword }) => ({ ...state, createWalletPassword }), @@ -223,10 +261,7 @@ const aezeedPasswordConfirmationSelector = state => state.onboarding.aezeedPassw const seedSelector = state => state.onboarding.seed const seedInputSelector = state => state.onboarding.seedInput -onboardingSelectors.passwordIsValid = createSelector( - passwordSelector, - password => password.length >= 8 -) +onboardingSelectors.passwordIsValid = createSelector(passwordSelector, password => password.length >= 8) onboardingSelectors.showCreateWalletPasswordConfirmationError = createSelector( createWalletPasswordSelector, @@ -253,8 +288,12 @@ export { onboardingSelectors } // ------------------------------------ const initialState = { onboarded: true, - step: 1, - alias: '', + step: 0.1, + connectionType: store.get('type', ''), + connectionHost: store.get('host', ''), + connectionCert: store.get('cert', ''), + connectionMacaroon: store.get('macaroon', ''), + alias: store.get('alias', ''), password: '', startingLnd: false, @@ -287,7 +326,7 @@ const initialState = { import: false }, - autopilot: null + autopilot: store.get('autopilot', null) } // ------------------------------------ diff --git a/package.json b/package.json index f64ad116..3c6cee8a 100644 --- a/package.json +++ b/package.json @@ -213,6 +213,7 @@ "devtron": "^1.4.0", "electron": "1.8.4", "electron-debug": "^1.2.0", + "electron-store": "^1.3.0", "font-awesome": "^4.7.0", "history": "^4.6.3", "lodash": "^4.17.4", diff --git a/yarn.lock b/yarn.lock index 00915582..a1ce277b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2469,6 +2469,16 @@ concurrently@^3.5.0: supports-color "^3.2.3" tree-kill "^1.1.0" +conf@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/conf/-/conf-1.4.0.tgz#1ea66c9d7a9b601674a5bb9d2b8dc3c726625e67" + dependencies: + dot-prop "^4.1.0" + env-paths "^1.0.0" + make-dir "^1.0.0" + pkg-up "^2.0.0" + write-file-atomic "^2.3.0" + configstore@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.0.tgz#45df907073e26dfa1cf4b2d52f5b60545eaa11d1" @@ -3405,6 +3415,12 @@ electron-releases@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/electron-releases/-/electron-releases-2.1.0.tgz#c5614bf811f176ce3c836e368a0625782341fd4e" +electron-store@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/electron-store/-/electron-store-1.3.0.tgz#ee488a28a61fb982fd35b658fb9cb6331eb201f8" + dependencies: + conf "^1.3.0" + electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.11: version "1.3.14" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.14.tgz#64af0f9efd3c3c6acd57d71f83b49ca7ee9c4b43" @@ -7324,6 +7340,12 @@ pkg-dir@^2.0.0: dependencies: find-up "^2.1.0" +pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" + dependencies: + find-up "^2.1.0" + plist@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/plist/-/plist-2.1.0.tgz#57ccdb7a0821df21831217a3cad54e3e146a1025" @@ -10266,6 +10288,14 @@ write-file-atomic@^2.0.0: imurmurhash "^0.1.4" slide "^1.1.5" +write-file-atomic@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + write@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757"