BuildRoute
BuildRoute builds a fully specified route based on a list of hop public keys. It retrieves the relevant channel policies from the graph in order to calculate the correct fees and time locks. Note that LND will use its default final_cltv_delta if no value is supplied. Make sure to add the correct final_cltv_delta depending on the invoice restriction. Moreover the caller has to make sure to provide the payment_addr if the route is paying an invoice which signaled it.
Source: routerrpc/router.proto
gRPC
rpc BuildRoute (BuildRouteRequest) returns (BuildRouteResponse);
REST
HTTP Method | Path |
---|---|
POST | /v2/router/route |
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', 'routerrpc/router.proto'], loaderOptions);
const routerrpc = grpc.loadPackageDefinition(packageDefinition).routerrpc;
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 routerrpc.Router(GRPC_HOST, creds);
let request = {
amt_msat: <int64>,
final_cltv_delta: <int32>,
outgoing_chan_id: <uint64>,
hop_pubkeys: <bytes>,
payment_addr: <bytes>,
first_hop_custom_records: <FirstHopCustomRecordsEntry>,
};
client.buildRoute(request, function(err, response) {
console.log(response);
});
// Console output:
// {
// "route": <Route>,
// }
import codecs, grpc, os
# Generate the following 2 modules by compiling the routerrpc/router.proto with the grpcio-tools.
# See https://github.com/lightningnetwork/lnd/blob/master/docs/grpc/python.md for instructions.
import router_pb2 as routerrpc, router_pb2_grpc as routerstub
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 = routerstub.RouterStub(channel)
request = routerrpc.BuildRouteRequest(
amt_msat=<int64>,
final_cltv_delta=<int32>,
outgoing_chan_id=<uint64>,
hop_pubkeys=<bytes>,
payment_addr=<bytes>,
first_hop_custom_records=<FirstHopCustomRecordsEntry>,
)
response = stub.BuildRoute(request)
print(response)
# {
# "route": <Route>,
# }
- 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 = {
amt_msat: <string>, // <int64>
final_cltv_delta: <integer>, // <int32>
outgoing_chan_id: <string>, // <uint64>
hop_pubkeys: <array>, // <bytes> (base64 encoded)
payment_addr: <string>, // <bytes> (base64 encoded)
first_hop_custom_records: <object>, // <FirstHopCustomRecordsEntry>
};
let options = {
url: `https://${REST_HOST}/v2/router/route`,
// 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:
// {
// "route": <object>, // <Route>
// }
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/router/route'
macaroon = codecs.encode(open(MACAROON_PATH, 'rb').read(), 'hex')
headers = {'Grpc-Metadata-macaroon': macaroon}
data = {
'amt_msat': <int64>,
'final_cltv_delta': <int32>,
'outgoing_chan_id': <uint64>,
'hop_pubkeys': base64.b64encode(<bytes>),
'payment_addr': base64.b64encode(<bytes>),
'first_hop_custom_records': <FirstHopCustomRecordsEntry>,
}
r = requests.post(url, headers=headers, data=json.dumps(data), verify=TLS_PATH)
print(r.json())
# {
# "route": <Route>,
# }
$ lncli buildroute --help
NAME:
lncli buildroute - Build a route from a list of hop pubkeys.
USAGE:
lncli buildroute [command options] [arguments...]
CATEGORY:
Payments
DESCRIPTION:
Builds a sphinx route for the supplied hops (public keys). Make sure to
use a custom final_cltv_delta to create the route depending on the
restrictions in the invoice otherwise LND will use its default specified
via the bitcoin.timelockdelta setting (default 80).
If the final_cltv_delta mismatch you will likely see the error
INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS returned by the receiving node.
Moreover a payment_addr has to be provided if the invoice supplied it as
well otherwise the payment will be rejected by the receiving node.
OPTIONS:
--amt value the amount to send expressed in satoshis. Ifnot set, the minimum routable amount is used (default: 0)
--final_cltv_delta value number of blocks the last hop has to reveal the preimage; if not set the default lnd final_cltv_delta is used (default: 0)
--hops value comma separated hex pubkeys
--outgoing_chan_id value short channel id of the outgoing channel to use for the first hop of the payment (default: 0)
--payment_addr value hex encoded payment address to set in the last hop's mpp record
Messages
routerrpc.BuildRouteRequest
Source: routerrpc/router.proto
Field | gRPC Type | REST Type | REST Placement |
---|---|---|---|
amt_msat | int64 | string | body |
final_cltv_delta | int32 | integer | body |
outgoing_chan_id | uint64 | string | body |
hop_pubkeys | bytes[] | array | body |
payment_addr | bytes | string | body |
first_hop_custom_records | FirstHopCustomRecordsEntry[] | object | body |
routerrpc.BuildRouteResponse
Source: routerrpc/router.proto
Field | gRPC Type | REST Type |
---|---|---|
route | Route | object |
Nested Messages
lnrpc.AMPRecord
Field | gRPC Type | REST Type |
---|---|---|
root_share | bytes | string |
set_id | bytes | string |
child_index | uint32 | integer |
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.MPPRecord
Field | gRPC Type | REST Type |
---|---|---|
payment_addr | bytes | string |
total_amt_msat | int64 | string |
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 |
routerrpc.BuildRouteRequest.FirstHopCustomRecordsEntry
Field | gRPC Type | REST Type |
---|---|---|
key | uint64 | unknown |
value | bytes | unknown |