QueryRoutes
QueryRoutes attempts to query the daemon's Channel Router for a possible route to a target destination capable of carrying a specific amount of satoshis. The returned route contains the full details required to craft and send an HTLC, also including the necessary information that should be present within the Sphinx packet encapsulated within the HTLC.
When using REST, the dest_custom_records
map type can be set by appending
&dest_custom_records[<record_number>]=<record_data_base64_url_encoded>
to the URL. Unfortunately this map type doesn't appear in the REST API
documentation because of a bug in the grpc-gateway library.
Source: lightning.proto
gRPC
rpc QueryRoutes (QueryRoutesRequest) returns (QueryRoutesResponse);
REST
HTTP Method | Path |
---|---|
GET | /v1/graph/routes/{pub_key}/{amt} |
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', loaderOptions);
const lnrpc = grpc.loadPackageDefinition(packageDefinition).lnrpc;
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 lnrpc.Lightning(GRPC_HOST, creds);
let request = {
pub_key: <string>,
amt: <int64>,
amt_msat: <int64>,
final_cltv_delta: <int32>,
fee_limit: <FeeLimit>,
ignored_nodes: <bytes>,
ignored_edges: <EdgeLocator>,
source_pub_key: <string>,
use_mission_control: <bool>,
ignored_pairs: <NodePair>,
cltv_limit: <uint32>,
dest_custom_records: <DestCustomRecordsEntry>,
outgoing_chan_id: <uint64>,
last_hop_pubkey: <bytes>,
route_hints: <RouteHint>,
blinded_payment_paths: <BlindedPaymentPath>,
dest_features: <FeatureBit>,
time_pref: <double>,
};
client.queryRoutes(request, function(err, response) {
console.log(response);
});
// Console output:
// {
// "routes": <Route>,
// "success_prob": <double>,
// }
import codecs, grpc, os
# Generate the following 2 modules by compiling the lightning.proto with the grpcio-tools.
# See https://github.com/lightningnetwork/lnd/blob/master/docs/grpc/python.md for instructions.
import lightning_pb2 as lnrpc, lightning_pb2_grpc as lightningstub
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 = lightningstub.LightningStub(channel)
request = lnrpc.QueryRoutesRequest(
pub_key=<string>,
amt=<int64>,
amt_msat=<int64>,
final_cltv_delta=<int32>,
fee_limit=<FeeLimit>,
ignored_nodes=<bytes>,
ignored_edges=<EdgeLocator>,
source_pub_key=<string>,
use_mission_control=<bool>,
ignored_pairs=<NodePair>,
cltv_limit=<uint32>,
dest_custom_records=<DestCustomRecordsEntry>,
outgoing_chan_id=<uint64>,
last_hop_pubkey=<bytes>,
route_hints=<RouteHint>,
blinded_payment_paths=<BlindedPaymentPath>,
dest_features=<FeatureBit>,
time_pref=<double>,
)
response = stub.QueryRoutes(request)
print(response)
# {
# "routes": <Route>,
# "success_prob": <double>,
# }
- 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 options = {
url: `https://${REST_HOST}/v1/graph/routes/{pub_key}/{amt}`,
// Work-around for self-signed certificates.
rejectUnauthorized: false,
json: true,
headers: {
'Grpc-Metadata-macaroon': fs.readFileSync(MACAROON_PATH).toString('hex'),
},
}
request.get(options, function(error, response, body) {
console.log(body);
});
// Console output:
// {
// "routes": <array>, // <Route>
// "success_prob": <number>, // <double>
// }
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}/v1/graph/routes/{pub_key}/{amt}'
macaroon = codecs.encode(open(MACAROON_PATH, 'rb').read(), 'hex')
headers = {'Grpc-Metadata-macaroon': macaroon}
r = requests.get(url, headers=headers, verify=TLS_PATH)
print(r.json())
# {
# "routes": <Route>,
# "success_prob": <double>,
# }
$ lncli queryroutes --help
NAME:
lncli queryroutes - Query a route to a destination.
USAGE:
lncli queryroutes [command options] dest amt
CATEGORY:
Payments
DESCRIPTION:
Queries the channel router for a potential path to the destination that has sufficient flow for the amount including fees
OPTIONS:
--dest value the 33-byte hex-encoded public key for the payment destination
--amt value the amount to send expressed in satoshis (default: 0)
--fee_limit value maximum fee allowed in satoshis when sending the payment (default: 0)
--fee_limit_percent value percentage of the payment's amount used as the maximum fee allowed when sending the payment (default: 0)
--final_cltv_delta value (optional) number of blocks the last hop has to reveal the preimage. Note that this should not be set in the case where the path includes a blinded path since in that case, the receiver will already have accounted for this value in the blinded_cltv value (default: 0)
--use_mc use mission control probabilities
--outgoing_chan_id value (optional) the channel id of the channel that must be taken to the first hop (default: 0)
--ignore_pair value ignore directional node pair <node1>:<node2>. This flag can be specified multiple times if multiple node pairs are to be ignored
--time_pref value (optional) expresses time preference (range -1 to 1) (default: 0)
--cltv_limit value the maximum time lock that may be used for this payment (default: 0)
--introduction_node value (blinded paths) the hex encoded, cleartext node ID of the node to use for queries to a blinded route
--blinding_point value (blinded paths) the hex encoded blinding point to use if querying a route to a blinded path, this value *must* be set for queries to a blinded path
--blinded_hops value (blinded paths) the blinded hops to include in the query, formatted as <blinded_node_id>:<hex_encrypted_data>. These hops must be provided *in order* starting with the introduction point and ending with the receiving node
--blinded_base_fee value (blinded paths) the aggregate base fee for the blinded portion of the route, expressed in msat (default: 0)
--blinded_ppm_fee value (blinded paths) the aggregate proportional fee for the blinded portion of the route, expressed in parts per million (default: 0)
--blinded_cltv value (blinded paths) the total cltv delay for the blinded portion of the route (default: 0)
Messages
lnrpc.QueryRoutesRequest
Source: lightning.proto
Field | gRPC Type | REST Type | REST Placement |
---|---|---|---|
pub_key | string | string | path |
amt | int64 | string | path |
amt_msat | int64 | string | query |
final_cltv_delta | int32 | integer | query |
fee_limit | FeeLimit | object | query |
ignored_nodes | bytes[] | array | query |
ignored_edges deprecated | EdgeLocator[] | object | unknown |
source_pub_key | string | string | query |
use_mission_control | bool | boolean | query |
ignored_pairs | NodePair[] | object | unknown |
cltv_limit | uint32 | integer | query |
dest_custom_records | DestCustomRecordsEntry[] | object | unknown |
outgoing_chan_id | uint64 | string | query |
last_hop_pubkey | bytes | string | query |
route_hints | RouteHint[] | object | unknown |
blinded_payment_paths | BlindedPaymentPath[] | object | unknown |
dest_features | FeatureBit[] | object | query |
time_pref | double | number | query |
lnrpc.QueryRoutesResponse
Source: lightning.proto
Field | gRPC Type | REST Type |
---|---|---|
routes | Route[] | array |
success_prob | double | number |
Nested Messages
lnrpc.AMPRecord
Field | gRPC Type | REST Type |
---|---|---|
root_share | bytes | string |
set_id | bytes | string |
child_index | uint32 | integer |
lnrpc.BlindedHop
Field | gRPC Type | REST Type |
---|---|---|
blinded_node | bytes | string |
encrypted_data | bytes | string |
lnrpc.BlindedPath
Field | gRPC Type | REST Type |
---|---|---|
introduction_node | bytes | string |
blinding_point | bytes | string |
blinded_hops | BlindedHop[] | array |
lnrpc.BlindedPaymentPath
Field | gRPC Type | REST Type |
---|---|---|
blinded_path | BlindedPath | object |
base_fee_msat | uint64 | string |
proportional_fee_rate | uint32 | integer |
total_cltv_delta | uint32 | integer |
htlc_min_msat | uint64 | string |
htlc_max_msat | uint64 | string |
features | FeatureBit[] | array |
lnrpc.EdgeLocator
Field | gRPC Type | REST Type |
---|---|---|
channel_id | uint64 | string |
direction_reverse | bool | boolean |
lnrpc.FeeLimit
Field | gRPC Type | REST Type |
---|---|---|
fixed | int64 | string |
fixed_msat | int64 | string |
percent | int64 | string |
lnrpc.Hop
Field | gRPC Type | REST Type |
---|---|---|
chan_id | uint64 | string |
chan_capacity | int64 | string |
amt_to_forward | int64 | string |
fee | int64 | string |
expiry | uint32 | integer |
amt_to_forward_msat | int64 | string |
fee_msat | int64 | string |
pub_key | string | string |
tlv_payload | bool | boolean |
mpp_record | MPPRecord | object |
amp_record | AMPRecord | object |
custom_records | CustomRecordsEntry[] | object |
metadata | bytes | string |
blinding_point | bytes | string |
encrypted_data | bytes | string |
total_amt_msat | uint64 | string |
lnrpc.Hop.CustomRecordsEntry
Field | gRPC Type | REST Type |
---|---|---|
key | uint64 | unknown |
value | bytes | unknown |
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.MPPRecord
Field | gRPC Type | REST Type |
---|---|---|
payment_addr | bytes | string |
total_amt_msat | int64 | string |
lnrpc.NodePair
Field | gRPC Type | REST Type |
---|---|---|
from | bytes | string |
to | bytes | string |
lnrpc.QueryRoutesRequest.DestCustomRecordsEntry
Field | gRPC Type | REST Type |
---|---|---|
key | uint64 | unknown |
value | bytes | unknown |
lnrpc.Route
Field | gRPC Type | REST Type |
---|---|---|
total_time_lock | uint32 | integer |
total_fees | int64 | string |
total_amt | int64 | string |
hops | Hop[] | array |
total_fees_msat | int64 | string |
total_amt_msat | int64 | string |
first_hop_amount_msat | int64 | string |
custom_channel_data | bytes | string |
lnrpc.RouteHint
Field | gRPC Type | REST Type |
---|---|---|
hop_hints | HopHint[] | array |
Enums
lnrpc.FeatureBit
Name | Number |
---|---|
DATALOSS_PROTECT_REQ | 0 |
DATALOSS_PROTECT_OPT | 1 |
INITIAL_ROUING_SYNC | 3 |
UPFRONT_SHUTDOWN_SCRIPT_REQ | 4 |
UPFRONT_SHUTDOWN_SCRIPT_OPT | 5 |
GOSSIP_QUERIES_REQ | 6 |
GOSSIP_QUERIES_OPT | 7 |
TLV_ONION_REQ | 8 |
TLV_ONION_OPT | 9 |
EXT_GOSSIP_QUERIES_REQ | 10 |
EXT_GOSSIP_QUERIES_OPT | 11 |
STATIC_REMOTE_KEY_REQ | 12 |
STATIC_REMOTE_KEY_OPT | 13 |
PAYMENT_ADDR_REQ | 14 |
PAYMENT_ADDR_OPT | 15 |
MPP_REQ | 16 |
MPP_OPT | 17 |
WUMBO_CHANNELS_REQ | 18 |
WUMBO_CHANNELS_OPT | 19 |
ANCHORS_REQ | 20 |
ANCHORS_OPT | 21 |
ANCHORS_ZERO_FEE_HTLC_REQ | 22 |
ANCHORS_ZERO_FEE_HTLC_OPT | 23 |
ROUTE_BLINDING_REQUIRED | 24 |
ROUTE_BLINDING_OPTIONAL | 25 |
AMP_REQ | 30 |
AMP_OPT | 31 |