AddHoldInvoice
AddHoldInvoice creates a hold invoice. It ties the invoice to the hash supplied in the request.
Source: invoicesrpc/invoices.proto
gRPC
rpc AddHoldInvoice (AddHoldInvoiceRequest) returns (AddHoldInvoiceResp);
REST
| HTTP Method | Path | 
|---|---|
| POST | /v2/invoices/hodl | 
Code Samples
- gRPC
 - REST
 - Shell
 
- Javascript
 - Python
 
const fs = require('fs');
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const GRPC_HOST = 'localhost:10009'
const MACAROON_PATH = 'LND_DIR/data/chain/bitcoin/regtest/admin.macaroon'
const TLS_PATH = 'LND_DIR/tls.cert'
const loaderOptions = {
  keepCase: true,
  longs: String,
  enums: String,
  defaults: true,
  oneofs: true,
};
const packageDefinition = protoLoader.loadSync(['lightning.proto', 'invoicesrpc/invoices.proto'], loaderOptions);
const invoicesrpc = grpc.loadPackageDefinition(packageDefinition).invoicesrpc;
process.env.GRPC_SSL_CIPHER_SUITES = 'HIGH+ECDSA';
const tlsCert = fs.readFileSync(TLS_PATH);
const sslCreds = grpc.credentials.createSsl(tlsCert);
const macaroon = fs.readFileSync(MACAROON_PATH).toString('hex');
const macaroonCreds = grpc.credentials.createFromMetadataGenerator(function(args, callback) {
  let metadata = new grpc.Metadata();
  metadata.add('macaroon', macaroon);
  callback(null, metadata);
});
let creds = grpc.credentials.combineChannelCredentials(sslCreds, macaroonCreds);
let client = new invoicesrpc.Invoices(GRPC_HOST, creds);
let request = {
  memo: <string>,
  hash: <bytes>,
  value: <int64>,
  value_msat: <int64>,
  description_hash: <bytes>,
  expiry: <int64>,
  fallback_addr: <string>,
  cltv_expiry: <uint64>,
  route_hints: <RouteHint>,
  private: <bool>,
};
client.addHoldInvoice(request, function(err, response) {
  console.log(response);
});
// Console output:
//  {
//    "payment_request": <string>,
//    "add_index": <uint64>,
//    "payment_addr": <bytes>,
//  }
import codecs, grpc, os
# Generate the following 2 modules by compiling the invoicesrpc/invoices.proto with the grpcio-tools.
# See https://github.com/lightningnetwork/lnd/blob/master/docs/grpc/python.md for instructions.
import invoices_pb2 as invoicesrpc, invoices_pb2_grpc as invoicesstub
GRPC_HOST = 'localhost:10009'
MACAROON_PATH = 'LND_DIR/data/chain/bitcoin/regtest/admin.macaroon'
TLS_PATH = 'LND_DIR/tls.cert'
# create macaroon credentials
macaroon = codecs.encode(open(MACAROON_PATH, 'rb').read(), 'hex')
def metadata_callback(context, callback):
  callback([('macaroon', macaroon)], None)
auth_creds = grpc.metadata_call_credentials(metadata_callback)
# create SSL credentials
os.environ['GRPC_SSL_CIPHER_SUITES'] = 'HIGH+ECDSA'
cert = open(TLS_PATH, 'rb').read()
ssl_creds = grpc.ssl_channel_credentials(cert)
# combine macaroon and SSL credentials
combined_creds = grpc.composite_channel_credentials(ssl_creds, auth_creds)
# make the request
channel = grpc.secure_channel(GRPC_HOST, combined_creds)
stub = invoicesstub.InvoicesStub(channel)
request = invoicesrpc.AddHoldInvoiceRequest(
  memo=<string>,
  hash=<bytes>,
  value=<int64>,
  value_msat=<int64>,
  description_hash=<bytes>,
  expiry=<int64>,
  fallback_addr=<string>,
  cltv_expiry=<uint64>,
  route_hints=<RouteHint>,
  private=<bool>,
)
response = stub.AddHoldInvoice(request)
print(response)
# {
#    "payment_request": <string>,
#    "add_index": <uint64>,
#    "payment_addr": <bytes>,
# }
- Javascript
 - Python
 
const fs = require('fs');
const request = require('request');
const REST_HOST = 'localhost:8080'
const MACAROON_PATH = 'LND_DIR/data/chain/bitcoin/regtest/admin.macaroon'
let requestBody = {
  memo: <string>, // <string> 
  hash: <string>, // <bytes> (base64 encoded)
  value: <string>, // <int64> 
  value_msat: <string>, // <int64> 
  description_hash: <string>, // <bytes> (base64 encoded)
  expiry: <string>, // <int64> 
  fallback_addr: <string>, // <string> 
  cltv_expiry: <string>, // <uint64> 
  route_hints: <array>, // <RouteHint> 
  private: <boolean>, // <bool> 
};
let options = {
  url: `https://${REST_HOST}/v2/invoices/hodl`,
  // Work-around for self-signed certificates.
  rejectUnauthorized: false,
  json: true,
  headers: {
    'Grpc-Metadata-macaroon': fs.readFileSync(MACAROON_PATH).toString('hex'),
  },
  form: JSON.stringify(requestBody),
}
request.post(options, function(error, response, body) {
  console.log(body);
});
// Console output:
//  {
//    "payment_request": <string>, // <string> 
//    "add_index": <string>, // <uint64> 
//    "payment_addr": <string>, // <bytes> 
//  }
import base64, codecs, json, requests
REST_HOST = 'localhost:8080'
MACAROON_PATH = 'LND_DIR/data/chain/bitcoin/regtest/admin.macaroon'
TLS_PATH = 'LND_DIR/tls.cert'
url = f'https://{REST_HOST}/v2/invoices/hodl'
macaroon = codecs.encode(open(MACAROON_PATH, 'rb').read(), 'hex')
headers = {'Grpc-Metadata-macaroon': macaroon}
data = {
  'memo': <string>,
  'hash': base64.b64encode(<bytes>),
  'value': <int64>,
  'value_msat': <int64>,
  'description_hash': base64.b64encode(<bytes>),
  'expiry': <int64>,
  'fallback_addr': <string>,
  'cltv_expiry': <uint64>,
  'route_hints': <RouteHint>,
  'private': <bool>,
}
r = requests.post(url, headers=headers, data=json.dumps(data), verify=TLS_PATH)
print(r.json())
# {
#    "payment_request": <string>,
#    "add_index": <uint64>,
#    "payment_addr": <bytes>,
# }
$ lncli addholdinvoice --help
NAME:
   lncli addholdinvoice - Add a new hold invoice.
USAGE:
   lncli addholdinvoice [command options] hash [amt]
CATEGORY:
   Invoices
DESCRIPTION:
   
  Add a new invoice, expressing intent for a future payment.
  Invoices without an amount can be created by not supplying any
  parameters or providing an amount of 0. These invoices allow the payer
  to specify the amount of satoshis they wish to send.
OPTIONS:
   --memo value               a description of the payment to attach along with the invoice (default="")
   --amt value                the amt of satoshis in this invoice (default: 0)
   --amt_msat value           the amt of millisatoshis in this invoice (default: 0)
   --description_hash value   SHA-256 hash of the description of the payment. Used if the purpose of payment cannot naturally fit within the memo. If provided this will be used instead of the description(memo) field in the encoded invoice.
   --fallback_addr value      fallback on-chain address that can be used in case the lightning payment fails
   --expiry value             the invoice's expiry time in seconds. If not specified, an expiry of 86400 seconds (24 hours) is implied. (default: 0)
   --cltv_expiry_delta value  The minimum CLTV delta to use for the final hop. If this is set to 0, the default value is used. The default value for cltv_expiry_delta is configured by the 'bitcoin.timelockdelta' option. (default: 0)
   --private                  encode routing hints in the invoice with private channels in order to assist the payer in reaching you
   
Messages
invoicesrpc.AddHoldInvoiceRequest
Source: invoicesrpc/invoices.proto
| Field | gRPC Type | REST Type | REST Placement | 
|---|---|---|---|
memo | string | string | body | 
hash | bytes | string | body  | 
value | int64 | string | body | 
value_msat | int64 | string | body | 
description_hash | bytes | string | body  | 
expiry | int64 | string | body | 
fallback_addr | string | string | body | 
cltv_expiry | uint64 | string | body | 
route_hints | RouteHint[] | array | body | 
private | bool | boolean | body | 
invoicesrpc.AddHoldInvoiceResp
Source: invoicesrpc/invoices.proto
| Field | gRPC Type | REST Type | 
|---|---|---|
payment_request | string | string | 
add_index | uint64 | string | 
payment_addr | bytes | string | 
Nested Messages
lnrpc.HopHint
| Field | gRPC Type | REST Type | 
|---|---|---|
node_id | string | string | 
chan_id | uint64 | string | 
fee_base_msat | uint32 | integer | 
fee_proportional_millionths | uint32 | integer | 
cltv_expiry_delta | uint32 | integer | 
lnrpc.RouteHint
| Field | gRPC Type | REST Type | 
|---|---|---|
hop_hints | HopHint[] | array |