Browse Source

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
renovate/lint-staged-8.x
Tom Kirkpatrick 7 years ago
parent
commit
3c4a651764
No known key found for this signature in database GPG Key ID: 72203A8EC5967EA8
  1. 24
      app/components/Onboarding/Autopilot.js
  2. 57
      app/components/Onboarding/ConnectionDetails.js
  3. 29
      app/components/Onboarding/ConnectionDetails.scss
  4. 35
      app/components/Onboarding/ConnectionType.js
  5. 40
      app/components/Onboarding/ConnectionType.scss
  6. 1
      app/components/Onboarding/NewAezeedPassword.js
  7. 1
      app/components/Onboarding/NewWalletPassword.js
  8. 67
      app/components/Onboarding/Onboarding.js
  9. 28
      app/containers/Root.js
  10. 27
      app/lnd/config/index.js
  11. 7
      app/lnd/index.js
  12. 5
      app/lnd/lib/lightning.js
  13. 3
      app/lnd/lib/walletUnlocker.js
  14. 98
      app/main.dev.js
  15. 57
      app/reducers/onboarding.js
  16. 1
      package.json
  17. 30
      yarn.lock

24
app/components/Onboarding/Autopilot.js

@ -7,28 +7,14 @@ const Autopilot = ({ autopilot, setAutopilot }) => (
<div className={styles.container}>
<section className={`${styles.enable} ${autopilot && styles.active}`}>
<div onClick={() => setAutopilot(true)}>
{
autopilot ?
<FaCircle />
:
<FaCircleThin />
}
<span className={styles.label}>
Enable Autopilot
</span>
{autopilot ? <FaCircle /> : <FaCircleThin />}
<span className={styles.label}>Enable Autopilot</span>
</div>
</section>
<section className={`${styles.disable} ${(!autopilot && autopilot !== null) && styles.active}`}>
<section className={`${styles.disable} ${!autopilot && autopilot !== null && styles.active}`}>
<div onClick={() => setAutopilot(false)}>
{
!autopilot && autopilot !== null ?
<FaCircle />
:
<FaCircleThin />
}
<span className={styles.label}>
Disable Autopilot
</span>
{!autopilot && autopilot !== null ? <FaCircle /> : <FaCircleThin />}
<span className={styles.label}>Disable Autopilot</span>
</div>
</section>
</div>

57
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
}) => (
<div className={styles.container}>
<div>
<label htmlFor='connectionHost'>Host:</label>
<input
type='text'
id='connectionHost'
placeholder='Hostname / Port of the Lnd gRPC interface'
className={styles.host}
ref={input => input}
value={connectionHost}
onChange={event => setConnectionHost(event.target.value)}
/>
</div>
<div>
<label htmlFor='connectionCert'>TLS Certificate:</label>
<input
type='text'
id='connectionCert'
placeholder='Path to the lnd tls cert'
className={styles.cert}
ref={input => input}
value={connectionCert}
onChange={event => setConnectionCert(event.target.value)}
/>
</div>
<div>
<label htmlFor='connectionMacaroon'>Macaroon:</label>
<input
type='text'
id='connectionMacaroon'
placeholder='Path to the lnd macaroon file'
className={styles.macaroon}
ref={input => input}
value={connectionMacaroon}
onChange={event => setConnectionMacaroon(event.target.value)}
/>
</div>
</div>
)
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

29
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;
}
}

35
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 }) => (
<div className={styles.container}>
<section className={`${styles.option} ${connectionType === 'local' && styles.active}`}>
<div className={`${styles.button}`} onClick={() => setConnectionType('local')}>
{connectionType === 'local' ? <FaCircle /> : <FaCircleThin />}
<span className={styles.label}>Automatic</span>
</div>
<div className={`${styles.description}`}>
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.
</div>
</section>
<section className={`${styles.option} ${connectionType === 'custom' && styles.active}`}>
<div className={`${styles.button}`} onClick={() => setConnectionType('custom')}>
{connectionType === 'custom' ? <FaCircle /> : <FaCircleThin />}
<span className={styles.label}>Custom</span>
</div>
<div className={`${styles.description}`}>
Connect to a remote Lightning node or a node running in a non-standard location (advanced users only).
</div>
</section>
</div>
)
ConnectionType.propTypes = {
connectionType: PropTypes.string.isRequired,
setConnectionType: PropTypes.func.isRequired
}
export default ConnectionType

40
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;
}
}
}
}

1
app/components/Onboarding/NewAezeedPassword.js

@ -42,4 +42,3 @@ NewAezeedPassword.propTypes = {
}
export default NewAezeedPassword

1
app/components/Onboarding/NewWalletPassword.js

@ -6,7 +6,6 @@ const NewWalletPassword = ({
createWalletPassword,
createWalletPasswordConfirmation,
showCreateWalletPasswordConfirmationError,
updateCreateWalletPassword,
updateCreateWalletPasswordConfirmation
}) => (

67
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 (
<FormContainer
title='Lightning Connection'
description='How will you connect to the Lightning Network?'
back={null}
next={() => changeStep(connectionType === 'local' ? 1 : 0.2)}
>
<ConnectionType {...connectionTypeProps} />
</FormContainer>
)
case 0.2:
return (
<FormContainer
title='Connection details'
description='Enter the connection details for your Lightning node.'
back={() => changeStep(0.1)}
next={() =>
startLnd({
connectionType,
connectionHost,
connectionCert,
connectionMacaroon
})
}
>
<ConnectionDetails {...connectionDetailProps} />
</FormContainer>
)
case 1:
return (
<FormContainer
title='What should we call you?'
description='Set your nickname to help others connect with you on the Lightning Network'
back={null}
back={() => changeStep(0.1)}
next={() => changeStep(2)}
>
<Alias {...aliasProps} />
@ -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 })}
>
<Autopilot {...autopilotProps} />
</FormContainer>
@ -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 <LoadingBolt /> }
if (fetchingSeed) { return <LoadingBolt /> }
if (startingLnd) {
return <LoadingBolt />
}
if (fetchingSeed) {
return <LoadingBolt />
}
return (
<div className={styles.container}>
{renderStep()}
</div>
)
return <div className={styles.container}>{renderStep()}</div>
}
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,

28
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 <LoadingBolt /> }
if (!lnd.grpcStarted) {
return <LoadingBolt />
}
return (
<Provider store={store}>

27
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 {
lnd: () => ({
lndPath,
lightningRpc: `${__dirname}/rpc.proto`,
lightningHost: 'localhost:10009',
cert: join(userInfo().homedir, loc),
macaroon: join(userInfo().homedir, macaroonPath)
lightningHost: store.get('host') || 'localhost:10009',
cert: store.get('cert') || join(userInfo().homedir, loc),
macaroon: store.get('macaroon') || join(userInfo().homedir, macaroonPath)
})
}

7
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)

5
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))

3
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'))

98
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,42 +264,51 @@ 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
// 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 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
}
// 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)
})
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
// An LND process was found, no need to start our own.
console.log('LND ALREADY RUNNING')
startGrpc()
}
})
} else {
console.log('USING CUSTOM LND')
startGrpc()
mainWindow.webContents.send('successfullyCreatedWallet')
}
})
})
app.setAsDefaultProtocolClient('lightning')

57
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)
}
// ------------------------------------

1
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",

30
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"

Loading…
Cancel
Save