@ -5,7 +5,7 @@ import { loadSync } from '@grpc/proto-loader'
import { BrowserWindow } from 'electron'
import StateMachine from 'javascript-state-machine'
import LndConfig from './config'
import { getDeadline , validateHost , createSslCreds , createMacaroonCreds } from './util'
import { getDeadline , validateHost , createSslCreds , createMacaroonCreds , waitForFile } from './util'
import methods from './methods'
import { mainLog } from '../utils/log'
import subscribeToTransactions from './subscribe/transactions'
@ -63,51 +63,59 @@ class Lightning {
* /
async onBeforeConnect ( ) {
mainLog . info ( 'Connecting to Lightning gRPC service' )
const { rpcProtoPath , host , cert , macaroon } = this . lndConfig
const { rpcProtoPath , host , cert , macaroon , type } = this . lndConfig
// Verify that the host is valid before creating a gRPC client that is connected to it.
return validateHost ( host )
. then ( async ( ) => {
// Load the gRPC proto file.
// The following options object closely approximates the existing behavior of grpc.load.
// See https://github.com/grpc/grpc-node/blob/master/packages/grpc-protobufjs/README.md
const options = {
keepCase : true ,
longs : Number ,
enums : String ,
defaults : true ,
oneofs : true
}
const packageDefinition = loadSync ( rpcProtoPath , options )
// Load gRPC package definition as a gRPC object hierarchy.
const rpc = grpc . loadPackageDefinition ( packageDefinition )
// Create ssl and macaroon credentials to use with the gRPC client.
const [ sslCreds , macaroonCreds ] = await Promise . all ( [
createSslCreds ( cert ) ,
createMacaroonCreds ( macaroon )
] )
const credentials = grpc . credentials . combineChannelCredentials ( sslCreds , macaroonCreds )
// Create a new gRPC client instance.
this . service = new rpc . lnrpc . Lightning ( host , credentials )
// Wait for the gRPC connection to be established.
return new Promise ( ( resolve , reject ) => {
this . service . waitForReady ( getDeadline ( 10 ) , err => {
if ( err ) {
return reject ( err )
}
return resolve ( )
return (
validateHost ( host )
// If we are trying to connect to the internal lnd, wait upto 20 seconds for the macaroon to be generated.
. then ( ( ) => ( type === 'local' ? waitForFile ( macaroon , 20000 ) : Promise . resolve ( ) ) )
// Attempt to connect using the supplied credentials.
. then ( async ( ) => {
// Load the gRPC proto file.
// The following options object closely approximates the existing behavior of grpc.load.
// See https://github.com/grpc/grpc-node/blob/master/packages/grpc-protobufjs/README.md
const options = {
keepCase : true ,
longs : Number ,
enums : String ,
defaults : true ,
oneofs : true
}
const packageDefinition = loadSync ( rpcProtoPath , options )
// Load gRPC package definition as a gRPC object hierarchy.
const rpc = grpc . loadPackageDefinition ( packageDefinition )
// Create ssl and macaroon credentials to use with the gRPC client.
const [ sslCreds , macaroonCreds ] = await Promise . all ( [
createSslCreds ( cert ) ,
createMacaroonCreds ( macaroon )
] )
const credentials = grpc . credentials . combineChannelCredentials ( sslCreds , macaroonCreds )
// Create a new gRPC client instance.
this . service = new rpc . lnrpc . Lightning ( host , credentials )
// Wait upto 20 seconds for the gRPC connection to be established.
return new Promise ( ( resolve , reject ) => {
this . service . waitForReady ( getDeadline ( 20 ) , err => {
if ( err ) {
return reject ( err )
}
return resolve ( )
} )
} )
} )
} )
. then ( ( ) => getInfo ( this . service ) )
. catch ( err => {
this . service . close ( )
throw err
} )
// Once connected, make a call to getInfo to verify that we can make successful calls.
. then ( ( ) => getInfo ( this . service ) )
. catch ( err => {
if ( this . service ) {
this . service . close ( )
}
throw err
} )
)
}
/ * *