Browse Source

fix(grpc): show error on connect to locked wallet

When connecting to a remote wallet we assume that the wallet is already
unlocked. In the case where it is not already unlocked, forward the
error message to the UI.

Fix #738
renovate/lint-staged-8.x
Tom Kirkpatrick 6 years ago
parent
commit
71ac6adeff
No known key found for this signature in database GPG Key ID: 72203A8EC5967EA8
  1. 76
      app/lib/lnd/lightning.js
  2. 2
      app/lib/lnd/walletUnlocker.js
  3. 10
      app/lib/zap/controller.js

76
app/lib/lnd/lightning.js

@ -11,6 +11,7 @@ import { mainLog } from '../utils/log'
import subscribeToTransactions from './subscribe/transactions'
import subscribeToInvoices from './subscribe/invoices'
import subscribeToChannelGraph from './subscribe/channelgraph'
import { getInfo } from './methods/networkController'
// Type definition for subscriptions property.
type LightningSubscriptionsType = {
@ -65,43 +66,48 @@ class Lightning {
const { rpcProtoPath, host, cert, macaroon } = this.lndConfig
// Verify that the host is valid before creating a gRPC client that is connected to it.
return await 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(2), err => {
if (err) {
this.service.close()
return reject(err)
}
return resolve()
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(5), err => {
if (err) {
return reject(err)
}
return resolve()
})
})
})
})
.then(() => getInfo(this.service))
.catch(err => {
this.service.close()
throw err
})
}
/**

2
app/lib/lnd/walletUnlocker.js

@ -74,7 +74,7 @@ class WalletUnlocker {
// Wait for the gRPC connection to be established.
return new Promise((resolve, reject) => {
this.service.waitForReady(getDeadline(2), err => {
this.service.waitForReady(getDeadline(5), err => {
if (err) {
this.service.close()
return reject(err)

10
app/lib/zap/controller.js

@ -193,6 +193,16 @@ class ZapController {
else if (e.code === 'LND_GRPC_MACAROON_ERROR') {
errors.macaroon = e.message
}
// The `startLightningWallet` call attempts to call the `getInfo` method on the Lightning service in order to
// verify that it is accessible. If it is not, an error 12 is throw whcih is the gRPC code for `UNIMPLEMENTED`
// which indicates that the requested operation is not implemented or not supported/enabled in the service.
// See https://github.com/grpc/grpc-node/blob/master/packages/grpc-native-core/src/constants.js#L129
if (e.code === 12) {
errors.host =
'Unable to connect to host. Please ensure wallet is unlocked before connecting.'
}
// Other error codes such as UNAVAILABLE most likely indicate that there is a problem with the host.
else {
errors.host = `Unable to connect to host: ${e.details || e.message}`

Loading…
Cancel
Save