diff --git a/README.md b/README.md index 86d977e..4849930 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,12 @@ import createLnRpc, { [All lnrpc methods documentation can be found here](http://api.lightning.community). +### Usage With BTCPayServer + +By default lnrpc assumes SSl certificate pinning. +In order to use lnrpc with a service (like BTCPayServer) which manages your certification, +you'll have to opt to disable certificate pinning by passing `{ tls: false }` within your lnrpc configuration. + ### Contributors To develop on the project please run: diff --git a/lib/lnrpc.js b/lib/lnrpc.js index 4f1119b..160d576 100644 --- a/lib/lnrpc.js +++ b/lib/lnrpc.js @@ -17,6 +17,7 @@ const DEFAULTS = { grpcLoader: protoLoader, server: 'localhost:10001', macaroonPath: '', + certEncoding: 'utf8', tls: /^darwin/.test(process.platform) // is macOS? ? `${HOME_DIR}/Library/Application Support/Lnd/tls.cert` : `${HOME_DIR}/.lnd/tls.cert`, @@ -61,8 +62,18 @@ module.exports = async function createLnRpc(config = {}) { let credentials; try { - // Use SSL cert string or fallback to file path - let cert = config.cert || (await readFile(tlsPath)); + // Use any SSL cert + let {cert, certEncoding} = config; + + // Fallback optional .tls file path + if (!cert && tlsPath) { + cert = await readFile(tlsPath); + } + + // Convert `cert` string to Buffer + if (cert && !Buffer.isBuffer(cert)) { + cert = Buffer.from(cert, certEncoding); + } /* Convert `cert` string to Buffer @@ -80,6 +91,9 @@ module.exports = async function createLnRpc(config = {}) { process.env.GRPC_SSL_CIPHER_SUITES = 'HIGH+ECDSA'; } + // NOTE: cert may be undefined at this point + // which is desirable for when certificate pinning + // is not necessary (i.e. BTCPayServer connection) credentials = grpc.credentials.createSsl(cert); } catch (e) { if (!e.code) e.code = 'INVALID_SSL_CERT'; diff --git a/test/lnrpc.test.js b/test/lnrpc.test.js index 3f2aeb9..06df19c 100644 --- a/test/lnrpc.test.js +++ b/test/lnrpc.test.js @@ -80,6 +80,27 @@ describe('Lnrpc Factory', () => { .catch(() => done()); }); + it('should allow opting out of certificate pinning', (done) => { + createLnrpc({ + tls: false, // opt out + grpc: grpcStub({ + credentials: { + createSsl: (cert) => { + assert( + typeof cert === 'undefined', + 'opted out of SSL cert pinning' + ); + }, + }, + loadPackageDefinition: () => { + throw new Error('force error'); + }, + }), + }) + .then(fail) + .catch(() => done()); + }); + it('should combine credentials when macaroon present', async () => { let tests = 0; const expSslCreds = {};