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 |