diff --git a/config/defaults.js b/config/defaults.js index c6cce6b3..356edbb1 100644 --- a/config/defaults.js +++ b/config/defaults.js @@ -35,6 +35,7 @@ module.exports = (mainnet = false) => { maxNumRoutesToQuery: 20, lndProto: parsePath(`${__dirname}/rpc.proto`), routerProto: parsePath(`${__dirname}/router.proto`), + invoicesProto: parsePath(`${__dirname}/invoices.proto`), walletUnlockerProto: parsePath(`${__dirname}/walletunlocker.proto`), lndHost: "localhost:10009", lndCertPath: parsePath(`${lndDirectory}/tls.cert`), diff --git a/config/invoices.proto b/config/invoices.proto new file mode 100644 index 00000000..df52b8c8 --- /dev/null +++ b/config/invoices.proto @@ -0,0 +1,122 @@ +syntax = "proto3"; + +import "rpc.proto"; + +package invoicesrpc; + +option go_package = "github.com/lightningnetwork/lnd/lnrpc/invoicesrpc"; + +// Invoices is a service that can be used to create, accept, settle and cancel +// invoices. +service Invoices { + /* + SubscribeSingleInvoice returns a uni-directional stream (server -> client) + to notify the client of state transitions of the specified invoice. + Initially the current invoice state is always sent out. + */ + rpc SubscribeSingleInvoice (SubscribeSingleInvoiceRequest) + returns (stream lnrpc.Invoice); + + /* + CancelInvoice cancels a currently open invoice. If the invoice is already + canceled, this call will succeed. If the invoice is already settled, it will + fail. + */ + rpc CancelInvoice (CancelInvoiceMsg) returns (CancelInvoiceResp); + + /* + AddHoldInvoice creates a hold invoice. It ties the invoice to the hash + supplied in the request. + */ + rpc AddHoldInvoice (AddHoldInvoiceRequest) returns (AddHoldInvoiceResp); + + /* + SettleInvoice settles an accepted invoice. If the invoice is already + settled, this call will succeed. + */ + rpc SettleInvoice (SettleInvoiceMsg) returns (SettleInvoiceResp); +} + +message CancelInvoiceMsg { + // Hash corresponding to the (hold) invoice to cancel. + bytes payment_hash = 1; +} +message CancelInvoiceResp { +} + +message AddHoldInvoiceRequest { + /* + An optional memo to attach along with the invoice. Used for record keeping + purposes for the invoice's creator, and will also be set in the description + field of the encoded payment request if the description_hash field is not + being used. + */ + string memo = 1; + + // The hash of the preimage + bytes hash = 2; + + /* + The value of this invoice in satoshis + + The fields value and value_msat are mutually exclusive. + */ + int64 value = 3; + + /* + The value of this invoice in millisatoshis + + The fields value and value_msat are mutually exclusive. + */ + int64 value_msat = 10; + + /* + Hash (SHA-256) of a description of the payment. Used if the description of + payment (memo) is too long to naturally fit within the description field + of an encoded payment request. + */ + bytes description_hash = 4; + + // Payment request expiry time in seconds. Default is 3600 (1 hour). + int64 expiry = 5; + + // Fallback on-chain address. + string fallback_addr = 6; + + // Delta to use for the time-lock of the CLTV extended to the final hop. + uint64 cltv_expiry = 7; + + /* + Route hints that can each be individually used to assist in reaching the + invoice's destination. + */ + repeated lnrpc.RouteHint route_hints = 8; + + // Whether this invoice should include routing hints for private channels. + bool private = 9; +} + +message AddHoldInvoiceResp { + /* + A bare-bones invoice for a payment within the Lightning Network. With the + details of the invoice, the sender has all the data necessary to send a + payment to the recipient. + */ + string payment_request = 1; +} + +message SettleInvoiceMsg { + // Externally discovered pre-image that should be used to settle the hold + // invoice. + bytes preimage = 1; +} + +message SettleInvoiceResp { +} + +message SubscribeSingleInvoiceRequest { + reserved 1; + + // Hash corresponding to the (hold) invoice to subscribe to. + bytes r_hash = 2; +} diff --git a/services/lnd/lightning.js b/services/lnd/lightning.js index f919ef6b..18237d44 100644 --- a/services/lnd/lightning.js +++ b/services/lnd/lightning.js @@ -10,6 +10,7 @@ const errorConstants = require("../../constants/errors"); * @typedef LightningConfig * @prop {string} lnrpcProtoPath * @prop {string} routerProtoPath + * @prop {string} invoicesProtoPath * @prop {string} walletUnlockerProtoPath * @prop {string} lndHost * @prop {string} lndCertPath @@ -31,10 +32,11 @@ const errorConstants = require("../../constants/errors"); module.exports = async ({ lnrpcProtoPath, routerProtoPath, + invoicesProtoPath, walletUnlockerProtoPath, - lndHost, - lndCertPath, - macaroonPath + lndHost, + lndCertPath, + macaroonPath }) => { try { process.env.GRPC_SSL_CIPHER_SUITES = "HIGH+ECDSA"; @@ -47,9 +49,15 @@ module.exports = async ({ includeDirs: ["node_modules/google-proto-files", "proto", Path.resolve(__dirname, "../../config")] } - const [lnrpcProto, routerProto, walletUnlockerProto] = await Promise.all([protoLoader.load(lnrpcProtoPath, protoLoaderConfig), protoLoader.load(routerProtoPath, protoLoaderConfig), protoLoader.load(walletUnlockerProtoPath, protoLoaderConfig)]); + const [lnrpcProto, routerProto, walletUnlockerProto, invoicesProto] = await Promise.all([ + protoLoader.load(lnrpcProtoPath, protoLoaderConfig), + protoLoader.load(routerProtoPath, protoLoaderConfig), + protoLoader.load(walletUnlockerProtoPath, protoLoaderConfig), + protoLoader.load(invoicesProtoPath, protoLoaderConfig) + ]); const { lnrpc } = grpc.loadPackageDefinition(lnrpcProto); const { routerrpc } = grpc.loadPackageDefinition(routerProto); + const { invoicesrpc } = grpc.loadPackageDefinition(invoicesProto); const { lnrpc: walletunlockerrpc } = grpc.loadPackageDefinition(walletUnlockerProto); const getCredentials = async () => { @@ -94,10 +102,8 @@ module.exports = async ({ const walletUnlocker = new walletunlockerrpc.WalletUnlocker(lndHost, credentials); // @ts-ignore const router = new routerrpc.Router(lndHost, credentials); - // @ts-expect-error - const invoices = new lnrpc.Invoices(lndHost, credentials) - - + // @ts-ignore + const invoices = new invoicesrpc.Invoices(lndHost, credentials); return { lightning, walletUnlocker, diff --git a/utils/lightningServices/lightning-services.js b/utils/lightningServices/lightning-services.js index 5ef7779a..9c198c3b 100644 --- a/utils/lightningServices/lightning-services.js +++ b/utils/lightningServices/lightning-services.js @@ -18,6 +18,7 @@ const lnrpc = require('../../services/lnd/lightning') * @prop {string} macaroonPath * @prop {string} lndProto * @prop {string} routerProto + * @prop {string} invoicesProto * @prop {string} walletUnlockerProto */ @@ -119,6 +120,7 @@ class LightningServices { const lnServices = await lnrpc({ lnrpcProtoPath: this.defaults.lndProto, routerProtoPath: this.defaults.routerProto, + invoicesProtoPath: this.defaults.invoicesProto, walletUnlockerProtoPath: this.defaults.walletUnlockerProto, lndHost, lndCertPath,