Browse Source

refactor: modularize and simplify app startup code

`main.dev.js` was hard to follow and understand the code flow. It housed
code to handle quite a few distinct things. This is a fairly substantial
refactor of the application startup code in which we:

A new `Neutrino` class has been created with 2 public methods. `start`
and `stop`. `start` will launch a new `lnd` process whilst `stop` will
stop it. This class extends the `EventEmitter` class and emits the
following events based on activity detected from the lnd log output.

 - `grpc-proxy-started` - gRPC started
 - `wallet-opened` Wallet opened
 - `fully-synced` - lnd is all caught up to the blockchain
 - `got-block-height` - got updated block height

A new `ZapController` class  has been created which houses all of the
logic for intraprocess communication between the main and renderer
processes.

Previously we had several `setInterval` loops that were checking every
second to see if the application status has changed and trigging the
appropriate action if so. This was pretty hard to follow has been
replaced here with more extensive use of promises. This enables us to
act instantly to relevant changes rather than waiting up to 1 second
for the next interval to fire.

Now, the only stuff that lives in `main.dev.js` now is the top level
`app` listeners, which calls out the other parts mentioned above to
bootstrap the application.
renovate/lint-staged-8.x
Tom Kirkpatrick 7 years ago
parent
commit
becb5ecee9
No known key found for this signature in database GPG Key ID: 72203A8EC5967EA8
  1. 6
      app/lnd/index.js
  2. 85
      app/lnd/lib/neutrino.js
  3. 28
      app/lnd/lib/util.js
  4. 437
      app/main.dev.js
  5. 2
      app/reducers/lnd.js
  6. 217
      app/zap.js

6
app/lnd/index.js

@ -1,6 +1,7 @@
import config from './config'
import lightning from './lib/lightning'
import walletUnlocker from './lib/walletUnlocker'
import isLndRunning from './lib/util'
import subscribe from './subscribe'
import methods from './methods'
import walletUnlockerMethods from './walletUnlockerMethods'
@ -10,7 +11,6 @@ import { mainLog } from '../utils/log'
const initLnd = () => {
const lndConfig = config.lnd()
const lnd = lightning(lndConfig.lightningRpc, lndConfig.lightningHost)
const lndSubscribe = mainWindow => subscribe(mainWindow, lnd, mainLog)
const lndMethods = (event, msg, data) => methods(lnd, mainLog, event, msg, data)
@ -22,7 +22,6 @@ const initLnd = () => {
const initWalletUnlocker = () => {
const lndConfig = config.lnd()
const walletUnlockerObj = walletUnlocker(lndConfig.lightningRpc, lndConfig.lightningHost)
const walletUnlockerMethodsCallback = (event, msg, data) =>
walletUnlockerMethods(walletUnlockerObj, mainLog, event, msg, data)
@ -32,5 +31,6 @@ const initWalletUnlocker = () => {
export default {
initLnd,
initWalletUnlocker
initWalletUnlocker,
isLndRunning
}

85
app/lnd/lib/neutrino.js

@ -0,0 +1,85 @@
import split2 from 'split2'
import { spawn } from 'child_process'
import EventEmitter from 'events'
import config from '../config'
import { mainLog, lndLog, lndLogGetLevel } from '../../utils/log'
class Neutrino extends EventEmitter {
constructor(alias, autopilot) {
super()
this.alias = alias
this.autopilot = autopilot
this.process = null
}
start() {
if (this.process) {
throw new Error('Neutrino process with PID ${this.process.pid} already exists.')
}
const lndConfig = config.lnd()
mainLog.info('Starting lnd in neutrino mode')
mainLog.debug(' > lndPath', lndConfig.lndPath)
mainLog.debug(' > lightningRpc:', lndConfig.lightningRpc)
mainLog.debug(' > lightningHost:', lndConfig.lightningHost)
mainLog.debug(' > cert:', lndConfig.cert)
mainLog.debug(' > macaroon:', lndConfig.macaroon)
const neutrinoArgs = [
`--configfile=${lndConfig.configPath}`,
`${this.autopilot ? '--autopilot.active' : ''}`,
`${this.alias ? `--alias=${this.alias}` : ''}`
]
this.process = spawn(lndConfig.lndPath, neutrinoArgs)
.on('error', error => this.emit('error', error))
.on('close', code => {
this.emit('close', code)
this.process = null
})
// Listen for when neutrino prints odata to stderr.
this.process.stderr.pipe(split2()).on('data', line => {
if (process.env.NODE_ENV === 'development') {
lndLog[lndLogGetLevel(line)](line)
}
})
// Listen for when neutrino prints data to stdout.
this.process.stdout.pipe(split2()).on('data', line => {
if (process.env.NODE_ENV === 'development') {
lndLog[lndLogGetLevel(line)](line)
}
// gRPC started.
if (line.includes('gRPC proxy started') && line.includes('password')) {
this.emit('grpc-proxy-started')
}
// Wallet opened.
if (line.includes('gRPC proxy started') && !line.includes('password')) {
this.emit('wallet-opened')
}
// LND is all caught up to the blockchain.
if (line.includes('Chain backend is fully synced')) {
this.emit('fully-synced')
}
// Pass current block height progress to front end for loading state UX
if (line.includes('Caught up to height') || line.includes('Catching up block hashes')) {
this.emit('got-block-height', line)
}
})
return this.process
}
stop() {
if (this.process) {
this.process.kill()
this.process = null
}
}
}
export default Neutrino

28
app/lnd/lib/util.js

@ -0,0 +1,28 @@
import { lookup } from 'ps-node'
import { mainLog } from '../../utils/log'
/**
* Check to see if an LND process is running.
* @return {Promise} Boolean indicating wether an existing lnd process was found on the host machine.
*/
const isLndRunning = () => {
return new Promise((resolve, reject) => {
mainLog.info('Looking for existing lnd process')
lookup({ command: 'lnd' }, (err, results) => {
// There was an error checking for the LND process.
if (err) {
return reject(err)
}
if (!results.length) {
// An LND process was found, no need to start our own.
mainLog.info('Existing lnd process not found')
return resolve(false)
}
mainLog.info('Found existing lnd process')
return resolve(true)
})
})
}
export default isLndRunning

437
app/main.dev.js

@ -1,5 +1,3 @@
/* eslint global-require: 1, flowtype-errors/show-errors: 0 */
/**
* This module executes inside of electron's main process. You can start
* electron renderer process from here and communicate with the other processes
@ -7,369 +5,105 @@
*
* When running `npm run build` or `npm run build-main`, this file is compiled to
* `./app/main.prod.js` using webpack. This gives us some performance wins.
*
*
*/
import { app, BrowserWindow, ipcMain, dialog, session } from 'electron'
import path from 'path'
import fs from 'fs'
import split2 from 'split2'
import { spawn } from 'child_process'
import { lookup } from 'ps-node'
import Store from 'electron-store'
import { app, BrowserWindow, session } from 'electron'
import { mainLog } from './utils/log'
import MenuBuilder from './menu'
import ZapController from './zap'
import lnd from './lnd'
import config from './lnd/config'
import { mainLog, lndLog, lndLogGetLevel } from './utils/log'
let mainWindow = null
let didFinishLoad = false
let startedSync = false
let sentGrpcDisconnect = false
let neutrino = null
if (process.env.NODE_ENV === 'production') {
const sourceMapSupport = require('source-map-support')
sourceMapSupport.install()
}
if (process.env.NODE_ENV === 'development' || process.env.DEBUG_PROD === 'true') {
require('electron-debug')()
const p = path.join(__dirname, '..', 'app', 'node_modules')
require('module').globalPaths.push(p)
}
const installExtensions = async () => {
const installer = require('electron-devtools-installer')
const forceDownload = !!process.env.UPGRADE_EXTENSIONS
const extensions = ['REACT_DEVELOPER_TOOLS', 'REDUX_DEVTOOLS']
return Promise.all(
extensions.map(name => installer.default(installer[name], forceDownload))
).catch(mainLog.error)
}
// Send the front end event letting them know the gRPC connection is disconnected
const sendGrpcDisconnected = () => {
const sendGrpcDisonnectedInterval = setInterval(() => {
if (didFinishLoad) {
clearInterval(sendGrpcDisonnectedInterval)
if (mainWindow) {
sentGrpcDisconnect = true
mainWindow.webContents.send('grpcDisconnected')
}
}
}, 1000)
}
// Send the front end event letting them know LND is synced to the blockchain
const sendLndSyncing = () => {
const sendLndSyncingInterval = setInterval(() => {
if (didFinishLoad) {
clearInterval(sendLndSyncingInterval)
if (mainWindow) {
mainLog.info('SENDING SYNCING')
startedSync = true
mainWindow.webContents.send('lndSyncing')
}
}
}, 1000)
}
const sendStartOnboarding = () => {
const sendStartOnboardingInterval = setInterval(() => {
if (didFinishLoad) {
clearInterval(sendStartOnboardingInterval)
if (mainWindow) {
mainLog.timeEnd('Time until onboarding has started')
mainLog.info('STARTING ONBOARDING')
mainWindow.webContents.send('startOnboarding')
}
}
}, 1000)
}
// Send the front end event letting them know the gRPC connection has started
const sendGrpcConnected = () => {
const sendGrpcConnectedInterval = setInterval(() => {
if (didFinishLoad && sentGrpcDisconnect) {
clearInterval(sendGrpcConnectedInterval)
if (mainWindow) {
mainWindow.webContents.send('grpcConnected')
}
}
}, 1000)
}
// Create and subscribe the grpc object
const startGrpc = () => {
mainLog.info('Starting gRPC...')
try {
const { lndSubscribe, lndMethods } = lnd.initLnd()
// Subscribe to bi-directional streams
lndSubscribe(mainWindow)
// Listen for all gRPC restful methods
ipcMain.on('lnd', (event, { msg, data }) => {
lndMethods(event, msg, data)
})
sendGrpcConnected()
} catch (error) {
dialog.showMessageBox({
type: 'error',
message: `Unable to connect to lnd. Please check your lnd node and try again: ${error}`
})
app.quit()
}
}
// Create and subscribe the grpc object
const startWalletUnlocker = () => {
mainLog.info('Starting wallet unlocker...')
try {
const walletUnlockerMethods = lnd.initWalletUnlocker()
// Listen for all gRPC restful methods
ipcMain.on('walletUnlocker', (event, { msg, data }) => {
walletUnlockerMethods(event, msg, data)
})
mainWindow.webContents.send('walletUnlockerStarted')
} catch (error) {
dialog.showMessageBox({
type: 'error',
message: `Unable to start lnd wallet unlocker. Please check your lnd node and try again: ${error}`
})
app.quit()
}
}
// Send the front end event letting them know LND is synced to the blockchain
const sendLndSynced = () => {
const sendLndSyncedInterval = setInterval(() => {
if (didFinishLoad && startedSync) {
clearInterval(sendLndSyncedInterval)
if (mainWindow) {
mainLog.info('SENDING SYNCED')
mainWindow.webContents.send('lndSynced')
}
}
}, 1000)
}
// Starts the LND node
const startLnd = (alias, autopilot) => {
const lndConfig = config.lnd()
mainLog.info('STARTING BUNDLED LND')
mainLog.debug(' > lndPath', lndConfig.lndPath)
mainLog.debug(' > lightningRpc:', lndConfig.lightningRpc)
mainLog.debug(' > lightningHost:', lndConfig.lightningHost)
mainLog.debug(' > cert:', lndConfig.cert)
mainLog.debug(' > macaroon:', lndConfig.macaroon)
const neutrinoArgs = [
`--configfile=${lndConfig.configPath}`,
`${autopilot ? '--autopilot.active' : ''}`,
`${alias ? `--alias=${alias}` : ''}`
]
neutrino = spawn(lndConfig.lndPath, neutrinoArgs)
.on('error', error => {
lndLog.error(`lnd error: ${error}`)
dialog.showMessageBox({
type: 'error',
message: `lnd error: ${error}`
})
})
.on('close', code => {
lndLog.info(`lnd shutting down ${code}`)
app.quit()
})
// Listen for when neutrino prints odata to stderr.
neutrino.stderr.pipe(split2()).on('data', line => {
if (process.env.NODE_ENV === 'development') {
lndLog[lndLogGetLevel(line)](line)
}
// Set up a couple of timers to track the app startup progress.
mainLog.time('Time until app is ready')
mainLog.time('Time until lnd process lookup finished')
// Determine wether we should start our own lnd process or connect to one that is already running.
const zapMode = lnd
.isLndRunning()
.then(res => {
mainLog.debug('lnd already running: %s', res)
mainLog.timeEnd('Time until lnd process lookup finished')
return res ? 'external' : 'internal'
})
// Listen for when neutrino prints data to stdout.
neutrino.stdout.pipe(split2()).on('data', line => {
if (process.env.NODE_ENV === 'development') {
lndLog[lndLogGetLevel(line)](line)
}
// If the gRPC proxy has started we can start ours
if (line.includes('gRPC proxy started')) {
const certInterval = setInterval(() => {
if (fs.existsSync(lndConfig.cert)) {
clearInterval(certInterval)
mainLog.info('CERT EXISTS, STARTING WALLET UNLOCKER')
startWalletUnlocker()
if (mainWindow) {
mainWindow.webContents.send('walletUnlockerStarted')
}
}
}, 1000)
}
if (line.includes('gRPC proxy started') && !line.includes('password')) {
mainLog.info('WALLET OPENED, STARTING LIGHTNING GRPC CONNECTION')
sendLndSyncing()
startGrpc()
}
// Pass current clock height progress to front end for loading state UX
if (
mainWindow &&
(line.includes('Caught up to height') || line.includes('Catching up block hashes to height'))
) {
// const blockHeight = line.slice(line.indexOf('Caught up to height') + 'Caught up to height'.length).trim()
mainWindow.webContents.send('lndStdout', line)
}
// When LND is all caught up to the blockchain
if (line.includes('Chain backend is fully synced')) {
// Log that LND is caught up to the current block height
mainLog.info('NEUTRINO IS SYNCED')
// Let the front end know we have stopped syncing LND
sendLndSynced()
}
})
}
.catch(mainLog.error)
/**
* Add event listeners...
* Initialize Zap as soon as electron is ready.
*/
app.on('ready', () => {
mainLog.timeEnd('Time until app is ready')
app.on('window-all-closed', () => {
// Respect the OSX convention of having the application in memory even
// after all windows have been closed
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('ready', async () => {
// Start a couple more timers to track the app loading time.
mainLog.time('Time until app is visible')
mainLog.time('Time until onboarding has started')
if (process.env.NODE_ENV === 'development' || process.env.DEBUG_PROD === 'true') {
await installExtensions()
}
mainWindow = new BrowserWindow({
// Create the electron browser window.
const mainWindow = new BrowserWindow({
show: false,
titleBarStyle: 'hidden',
width: 950,
height: 600,
minWidth: 950,
minHeight: 425
minHeight: 425,
backgroundColor: '#1c1e26'
})
if (process.env.HOT) {
const port = process.env.PORT || 1212
mainWindow.loadURL(`http://localhost:${port}/dist/index.html`)
} else {
mainWindow.loadURL(`file://${__dirname}/dist/index.html`)
// Initialise the application.
const zap = new ZapController(mainWindow, zapMode)
zap.init()
// Initialise the application menus.
const menuBuilder = new MenuBuilder(mainWindow)
menuBuilder.buildMenu()
/**
* In production mode, enable source map support.
*/
if (process.env.NODE_ENV === 'production') {
const sourceMapSupport = require('source-map-support') // eslint-disable-line global-require
sourceMapSupport.install()
}
/**
* In development mode or when DEBUG_PROD is set, enable debugging tools.
*/
if (process.env.NODE_ENV === 'development' || process.env.DEBUG_PROD === 'true') {
// eslint-disable global-require
require('electron-debug')()
const installer = require('electron-devtools-installer')
const forceDownload = !!process.env.UPGRADE_EXTENSIONS
const extensions = ['REACT_DEVELOPER_TOOLS', 'REDUX_DEVTOOLS']
Promise.all(extensions.map(name => installer.default(installer[name], forceDownload))).catch(
mainLog.error
)
mainWindow.webContents.once('dom-ready', () => {
mainWindow.openDevTools()
})
}
// @TODO: Use 'ready-to-show' event
// https://github.com/electron/electron/blob/master/docs/api/browser-window.md#using-ready-to-show-event
mainWindow.webContents.on('did-finish-load', () => {
if (!mainWindow) {
throw new Error('"mainWindow" is not defined')
/**
* Add application event listener:
* - Kill lnd process is killed when the app quits.
*/
app.on('quit', () => {
mainLog.debug('app.quit')
if (zap.neutrino) {
zap.neutrino.stop()
}
mainLog.timeEnd('Time until app is visible')
mainWindow.show()
mainWindow.focus()
// now sync and grpc events can be fired to the front end
didFinishLoad = true
})
mainWindow.on('closed', () => {
mainWindow = null
// shut down zap when a user closes the window
app.quit()
})
const menuBuilder = new MenuBuilder(mainWindow)
menuBuilder.buildMenu()
sendGrpcDisconnected()
mainLog.info('LOOKING FOR EXISTING LND PROCESS')
// 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)
}
if (!results.length) {
// An LND process was found, no need to start our own.
mainLog.info('EXISTING LND PROCESS NOT FOUND')
// Let the application know onboarding has started.
sendStartOnboarding()
} else {
// An LND process was found, no need to start our own.
mainLog.info('FOUND EXISTING LND PROCESS')
startGrpc()
mainWindow.webContents.send('successfullyCreatedWallet')
}
})
// Start LND
// once the onboarding has enough information, start or connect to LND.
ipcMain.on('startLnd', (event, 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
}
mainLog.info('GOT LND CONFIG')
mainLog.debug(' > connectionType:', options.connectionType)
mainLog.debug(' > connectionHost:', options.connectionHost)
mainLog.debug(' > connectionCert:', options.connectionCert)
mainLog.debug(' > connectionMacaroon:', options.connectionMacaroon)
mainLog.debug(' > alias:', options.alias)
mainLog.debug(' > autopilot:', options.autopilot)
mainLog.info('SAVED LND CONFIG TO:', store.path)
if (options.connectionType === 'local') {
startLnd(options.alias, options.autopilot)
} else {
mainLog.info('CONNECTING TO CUSTOM LND INSTANCE')
startGrpc()
mainWindow.webContents.send('successfullyCreatedWallet')
}
/**
* Add application event listener:
* - Open zap payment form when lightning url is opened
*/
app.setAsDefaultProtocolClient('lightning')
app.on('open-url', (event, url) => {
mainLog.debug('open-url')
event.preventDefault()
const payreq = url.split(':')[1]
zap.sendMessage('lightningPaymentUri', { payreq })
mainWindow.show()
})
// HACK: patch webrequest to fix devtools incompatibility with electron 2.x.
@ -386,27 +120,16 @@ app.on('ready', async () => {
callback({ cancel: false })
}
})
})
app.setAsDefaultProtocolClient('lightning')
app.on('open-url', (event, url) => {
event.preventDefault()
if (!mainWindow) {
throw new Error('"mainWindow" is not defined')
}
const payreq = url.split(':')[1]
mainWindow.webContents.send('lightningPaymentUri', { payreq })
mainWindow.show()
})
// Ensure lnd process is killed when the app quits.
app.on('quit', () => {
if (neutrino) {
neutrino.kill()
}
/**
* Add application event listener:
* - quit app when window is closed
*/
app.on('window-all-closed', () => {
mainLog.debug('app.window-all-closed')
// Respect the OSX convention of having the application in memory even after all windows have been closed
if (process.platform !== 'darwin') {
app.quit()
}
})
})
export default { startLnd }

2
app/reducers/lnd.js

@ -113,7 +113,7 @@ const ACTION_HANDLERS = {
// ------------------------------------
const initialState = {
syncing: false,
grpcStarted: true,
grpcStarted: false,
fetchingBlockHeight: false,
lines: [],
blockHeight: 0,

217
app/zap.js

@ -0,0 +1,217 @@
import { app, ipcMain, dialog } from 'electron'
import Store from 'electron-store'
import lnd from './lnd'
import Neutrino from './lnd/lib/neutrino'
import { mainLog } from './utils/log'
/**
* @class ZapController
*
* The ZapController class coordinates actions between the the main nand renderer processes.
*/
class ZapController {
/**
* Create a new ZapController instance.
* @param {BrowserWindow} mainWindow BrowserWindow instance to interact with
* @param {String|Promise} mode String or Promise that resolves to the desired run mode. Valid options are:
* - 'internal': start a new lnd process.
* - 'external': connect to an existing lnd process.
*/
constructor(mainWindow, mode) {
this.mode = mode
// Variable to hold the main window instance.
this.mainWindow = mainWindow
// Keep a reference any neutrino process started by us.
this.neutrino = null
// Time for the splash screen to remain visible.
this.splashScreenTime = 500
}
/**
* Initialize the application.
*/
init() {
if (process.env.HOT) {
const port = process.env.PORT || 1212
this.mainWindow.loadURL(`http://localhost:${port}/dist/index.html`)
} else {
this.mainWindow.loadURL(`file://${__dirname}/dist/index.html`)
}
// Register IPC listeners so that we can react to instructions coming from the app.
this._registerIpcListeners()
// Show the window as soon as the application has finished loading.
this.mainWindow.webContents.on('did-finish-load', async () => {
this.mainWindow.show()
this.mainWindow.focus()
mainLog.timeEnd('Time until app is visible')
mainLog.time('Time until we know the run mode')
Promise.resolve(this.mode)
.then(mode => {
const timeUntilWeKnowTheRunMode = mainLog.timeEnd('Time until we know the run mode')
return setTimeout(() => {
if (mode === 'external') {
// If lnd is already running, create and subscribe to the Lightning grpc object.
this.startGrpc()
this.sendMessage('successfullyCreatedWallet')
} else {
// Otherwise, start the onboarding process.
this.sendMessage('startOnboarding')
mainLog.timeEnd('Time until onboarding has started')
}
}, timeUntilWeKnowTheRunMode < this.splashScreenTime ? this.splashScreenTime : 0)
})
.catch(mainLog.error)
})
this.mainWindow.on('closed', () => {
this.mainWindow = null
// shut down zap when a user closes the window
app.quit()
})
}
/**
* Send a message to the main window.
* @param {string} msg message to send.
* @param {[type]} data additional data to acompany the message.
*/
sendMessage(msg, data) {
mainLog.info('Sending message to renderer process: %o', { msg, data })
this.mainWindow.webContents.send(msg, data)
}
/**
* Create and subscribe to the Lightning grpc object.
*/
startGrpc() {
mainLog.info('Starting gRPC...')
try {
const { lndSubscribe, lndMethods } = lnd.initLnd()
// Subscribe to bi-directional streams
lndSubscribe(this.mainWindow)
// Listen for all gRPC restful methods
ipcMain.on('lnd', (event, { msg, data }) => {
lndMethods(event, msg, data)
})
this.sendMessage('grpcConnected')
} catch (error) {
dialog.showMessageBox({
type: 'error',
message: `Unable to connect to lnd. Please check your lnd node and try again: ${error}`
})
app.quit()
}
}
/**
* Create and subscribe to the WalletUnlocker grpc object.
*/
startWalletUnlocker() {
mainLog.info('Starting wallet unlocker...')
try {
const walletUnlockerMethods = lnd.initWalletUnlocker()
// Listen for all gRPC restful methods
ipcMain.on('walletUnlocker', (event, { msg, data }) => {
walletUnlockerMethods(event, msg, data)
})
this.sendMessage('walletUnlockerStarted')
} catch (error) {
dialog.showMessageBox({
type: 'error',
message: `Unable to start lnd wallet unlocker. Please check your lnd node and try again: ${error}`
})
app.quit()
}
}
/**
* Starts the LND node and attach event listeners.
* @param {string} alias Alias to assign to the lnd node.
* @param {boolean} autopilot True if autopilot should be enabled.
* @return {Neutrino} Neutrino instance.
*/
startLnd(alias, autopilot) {
this.neutrino = new Neutrino(alias, autopilot)
this.neutrino.on('error', error => {
mainLog.error(`Got error from lnd process: ${error})`)
dialog.showMessageBox({
type: 'error',
message: `lnd error: ${error}`
})
})
this.neutrino.on('close', code => {
mainLog.info(`Lnd process has shut down (code ${code})`)
app.quit()
})
this.neutrino.on('grpc-proxy-started', () => {
mainLog.info('gRPC proxy started')
this.startWalletUnlocker()
})
this.neutrino.on('wallet-opened', () => {
mainLog.info('Wallet opened')
this.startGrpc()
this.sendMessage('lndSyncing')
})
this.neutrino.on('fully-synced', () => {
mainLog.info('Neutrino fully synced')
this.sendMessage('lndSynced')
})
this.neutrino.on('got-block-height', line => {
this.sendMessage('lndStdout', line)
})
this.neutrino.start()
}
/**
* Add IPC event listeners...
*/
_registerIpcListeners() {
ipcMain.on('startLnd', (event, 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
}
mainLog.info('Saved lnd config to:', store.path)
if (options.connectionType === 'local') {
mainLog.info('Starting new lnd instance')
mainLog.debug(' > alias:', options.alias)
mainLog.debug(' > autopilot:', options.autopilot)
this.startLnd(options.alias, options.autopilot)
} else {
mainLog.info('Connecting to custom lnd instance')
mainLog.debug(' > connectionHost:', options.connectionHost)
mainLog.debug(' > connectionCert:', options.connectionCert)
mainLog.debug(' > connectionMacaroon:', options.connectionMacaroon)
this.startGrpc()
this.sendMessage('successfullyCreatedWallet')
}
})
}
}
export default ZapController
Loading…
Cancel
Save