feat(extensions): add extension loader infrastructure (#3)
Some checks are pending
Docker Compose Actions Workflow / test (push) Waiting to run

## Summary

- Adds a modular extension system for Lightning.Pub enabling third-party plugins
- Provides isolated SQLite databases per extension for data safety
- Implements ExtensionContext API for accessing Lightning.Pub services (payments, Nostr, storage)
- Supports RPC method registration with automatic namespacing
- Includes HTTP route handling for protocols like LNURL
- Event routing for payment receipts and Nostr events
- Comprehensive documentation with architecture overview and working examples

## Key Components

- `src/extensions/types.ts` - Core extension interfaces
- `src/extensions/loader.ts` - Extension discovery, loading, and lifecycle management
- `src/extensions/context.ts` - Bridge between extensions and Lightning.Pub services
- `src/extensions/database.ts` - SQLite isolation with WAL mode
- `src/extensions/README.md` - Full documentation with examples

## ExtensionContext API

| Method | Description |
|--------|-------------|
| `getApplication()` | Get application info |
| `createInvoice()` | Create Lightning invoice |
| `payInvoice()` | Pay Lightning invoice |
| `getLnurlPayInfo()` | Get LNURL-pay info for a user (enables Lightning Address/zaps) |
| `sendEncryptedDM()` | Send Nostr DM (NIP-44) |
| `publishNostrEvent()` | Publish Nostr event |
| `registerMethod()` | Register RPC method |
| `onPaymentReceived()` | Subscribe to payment callbacks |
| `onNostrEvent()` | Subscribe to Nostr events |

## Test plan

- [x] Review extension loader code for correctness
- [x] Verify TypeScript compilation succeeds
- [x] Test extension discovery from `src/extensions/` directory
- [x] Test RPC method registration and routing
- [x] Test database isolation between extensions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: boufni95 <boufni95@gmail.com>
Co-authored-by: Patrick Mulligan <patjmulligan@protonmail.com>
Reviewed-on: #3
This commit is contained in:
padreug 2026-04-02 18:47:55 +00:00
parent 72c9872b23
commit 77e5772afd
47 changed files with 10187 additions and 4828 deletions

View file

@ -1,11 +1,29 @@
syntax = "proto3";
import "lightning.proto";
package invoicesrpc;
import "lightning.proto";
option go_package = "github.com/lightningnetwork/lnd/lnrpc/invoicesrpc";
/*
* Comments in this file will be directly parsed into the API
* Documentation as descriptions of the associated method, message, or field.
* These descriptions should go right above the definition of the object, and
* can be in either block or // comment format.
*
* An RPC method can be matched to an lncli command by placing a line in the
* beginning of the description in exactly the following format:
* lncli: `methodname`
*
* Failure to specify the exact name of the command will cause documentation
* generation to fail.
*
* More information on how exactly the gRPC documentation is generated from
* this proto file can be found here:
* https://github.com/lightninglabs/lightning-api
*/
// Invoices is a service that can be used to create, accept, settle and cancel
// invoices.
service Invoices {
@ -17,30 +35,39 @@ service Invoices {
rpc SubscribeSingleInvoice (SubscribeSingleInvoiceRequest)
returns (stream lnrpc.Invoice);
/*
/* lncli: `cancelinvoice`
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);
/*
/* lncli: `addholdinvoice`
AddHoldInvoice creates a hold invoice. It ties the invoice to the hash
supplied in the request.
*/
rpc AddHoldInvoice (AddHoldInvoiceRequest) returns (AddHoldInvoiceResp);
/*
/* lncli: `settleinvoice`
SettleInvoice settles an accepted invoice. If the invoice is already
settled, this call will succeed.
*/
rpc SettleInvoice (SettleInvoiceMsg) returns (SettleInvoiceResp);
/*
LookupInvoiceV2 attempts to look up at invoice. An invoice can be refrenced
LookupInvoiceV2 attempts to look up at invoice. An invoice can be referenced
using either its payment hash, payment address, or set ID.
*/
rpc LookupInvoiceV2 (LookupInvoiceMsg) returns (lnrpc.Invoice);
/*
HtlcModifier is a bidirectional streaming RPC that allows a client to
intercept and modify the HTLCs that attempt to settle the given invoice. The
server will send HTLCs of invoices to the client and the client can modify
some aspects of the HTLC in order to pass the invoice acceptance tests.
*/
rpc HtlcModifier (stream HtlcModifyResponse)
returns (stream HtlcModifyRequest);
}
message CancelInvoiceMsg {
@ -84,7 +111,7 @@ message AddHoldInvoiceRequest {
*/
bytes description_hash = 4;
// Payment request expiry time in seconds. Default is 3600 (1 hour).
// Payment request expiry time in seconds. Default is 86400 (24 hours).
int64 expiry = 5;
// Fallback on-chain address.
@ -120,8 +147,9 @@ message AddHoldInvoiceResp {
uint64 add_index = 2;
/*
The payment address of the generated invoice. This value should be used
in all payments for this invoice as we require it for end to end
The payment address of the generated invoice. This is also called
the payment secret in specifications (e.g. BOLT 11). This value should
be used in all payments for this invoice as we require it for end to end
security.
*/
bytes payment_addr = 3;
@ -172,4 +200,52 @@ message LookupInvoiceMsg {
}
LookupModifier lookup_modifier = 4;
}
// CircuitKey is a unique identifier for an HTLC.
message CircuitKey {
// The id of the channel that the is part of this circuit.
uint64 chan_id = 1;
// The index of the incoming htlc in the incoming channel.
uint64 htlc_id = 2;
}
message HtlcModifyRequest {
// The invoice the intercepted HTLC is attempting to settle. The HTLCs in
// the invoice are only HTLCs that have already been accepted or settled,
// not including the current intercepted HTLC.
lnrpc.Invoice invoice = 1;
// The unique identifier of the HTLC of this intercepted HTLC.
CircuitKey exit_htlc_circuit_key = 2;
// The amount in milli-satoshi that the exit HTLC is attempting to pay.
uint64 exit_htlc_amt = 3;
// The absolute expiry height of the exit HTLC.
uint32 exit_htlc_expiry = 4;
// The current block height.
uint32 current_height = 5;
// The wire message custom records of the exit HTLC.
map<uint64, bytes> exit_htlc_wire_custom_records = 6;
}
message HtlcModifyResponse {
// The circuit key of the HTLC that the client wants to modify.
CircuitKey circuit_key = 1;
// The modified amount in milli-satoshi that the exit HTLC is paying. This
// value can be different from the actual on-chain HTLC amount, in case the
// HTLC carries other valuable items, as can be the case with custom channel
// types.
optional uint64 amt_paid = 2;
// This flag indicates whether the HTLCs associated with the invoices should
// be cancelled. The interceptor client may set this field if some
// unexpected behavior is encountered. Setting this will ignore the amt_paid
// field.
bool cancel_set = 3;
}

View file

@ -274,12 +274,14 @@ service Lightning {
}
/*
SendPaymentSync is the synchronous non-streaming version of SendPayment.
This RPC is intended to be consumed by clients of the REST proxy.
Additionally, this RPC expects the destination's public key and the payment
hash (if any) to be encoded as hex strings.
Deprecated, use routerrpc.SendPaymentV2. SendPaymentSync is the synchronous
non-streaming version of SendPayment. This RPC is intended to be consumed by
clients of the REST proxy. Additionally, this RPC expects the destination's
public key and the payment hash (if any) to be encoded as hex strings.
*/
rpc SendPaymentSync (SendRequest) returns (SendResponse);
rpc SendPaymentSync (SendRequest) returns (SendResponse) {
option deprecated = true;
}
/* lncli: `sendtoroute`
Deprecated, use routerrpc.SendToRouteV2. SendToRoute is a bi-directional
@ -293,10 +295,13 @@ service Lightning {
}
/*
SendToRouteSync is a synchronous version of SendToRoute. It Will block
until the payment either fails or succeeds.
Deprecated, use routerrpc.SendToRouteV2. SendToRouteSync is a synchronous
version of SendToRoute. It Will block until the payment either fails or
succeeds.
*/
rpc SendToRouteSync (SendToRouteRequest) returns (SendResponse);
rpc SendToRouteSync (SendToRouteRequest) returns (SendResponse) {
option deprecated = true;
}
/* lncli: `addinvoice`
AddInvoice attempts to add a new invoice to the invoice database. Any
@ -643,6 +648,8 @@ message SendCustomMessageRequest {
}
message SendCustomMessageResponse {
// The status of the send operation.
string status = 1;
}
message Utxo {
@ -755,11 +762,35 @@ message GetTransactionsRequest {
// An optional filter to only include transactions relevant to an account.
string account = 3;
/*
The index of a transaction that will be used in a query to determine which
transaction should be returned in the response.
*/
uint32 index_offset = 4;
/*
The maximal number of transactions returned in the response to this query.
This value should be set to 0 to return all transactions.
*/
uint32 max_transactions = 5;
}
message TransactionDetails {
// The list of transactions relevant to the wallet.
repeated Transaction transactions = 1;
/*
The index of the last item in the set of returned transactions. This can be
used to seek further, pagination style.
*/
uint64 last_index = 2;
/*
The index of the last item in the set of returned transactions. This can be
used to seek backwards, pagination style.
*/
uint64 first_index = 3;
}
message FeeLimit {
@ -1317,6 +1348,8 @@ message ConnectPeerRequest {
uint64 timeout = 3;
}
message ConnectPeerResponse {
// The status of the connect operation.
string status = 1;
}
message DisconnectPeerRequest {
@ -1324,6 +1357,8 @@ message DisconnectPeerRequest {
string pub_key = 1;
}
message DisconnectPeerResponse {
// The status of the disconnect operation.
string status = 1;
}
message HTLC {
@ -1346,6 +1381,13 @@ message HTLC {
// Index identifying the htlc on the forwarding channel.
uint64 forwarding_htlc_index = 7;
/*
Whether the HTLC is locked in. An HTLC is considered locked in when the
remote party has sent us the `revoke_and_ack` to irrevocably commit this
HTLC.
*/
bool locked_in = 8;
}
enum CommitmentType {
@ -1388,8 +1430,14 @@ enum CommitmentType {
A channel that uses musig2 for the funding output, and the new tapscript
features where relevant.
*/
// TODO(roasbeef): need script enforce mirror type for the above as well?
SIMPLE_TAPROOT = 5;
/*
Identical to the SIMPLE_TAPROOT channel type, but with extra functionality.
This channel type also commits to additional meta data in the tapscript
leaves for the scripts in a channel.
*/
SIMPLE_TAPROOT_OVERLAY = 6;
}
message ChannelConstraints {
@ -1592,6 +1640,11 @@ message Channel {
the channel's operation.
*/
string memo = 36;
/*
Custom channel data that might be populated in custom channels.
*/
bytes custom_channel_data = 37;
}
message ListChannelsRequest {
@ -1705,6 +1758,10 @@ message ChannelCloseSummary {
// The confirmed SCID for a zero-conf channel.
uint64 zero_conf_confirmed_scid = 15 [jstype = JS_STRING];
// The TLV encoded custom channel data records for this output, which might
// be set for custom channels.
bytes custom_channel_data = 16;
}
enum ResolutionType {
@ -1955,8 +2012,8 @@ message GetInfoResponse {
bool synced_to_graph = 18;
/*
Whether the current node is connected to testnet. This field is
deprecated and the network field should be used instead
Whether the current node is connected to testnet or testnet4. This field is
deprecated and the network field should be used instead.
*/
bool testnet = 10 [deprecated = true];
@ -2028,10 +2085,38 @@ message ChannelOpenUpdate {
ChannelPoint channel_point = 1;
}
message CloseOutput {
// The amount in satoshi of this close output. This amount is the final
// commitment balance of the channel and the actual amount paid out on chain
// might be smaller due to subtracted fees.
int64 amount_sat = 1;
// The pkScript of the close output.
bytes pk_script = 2;
// Whether this output is for the local or remote node.
bool is_local = 3;
// The TLV encoded custom channel data records for this output, which might
// be set for custom channels.
bytes custom_channel_data = 4;
}
message ChannelCloseUpdate {
bytes closing_txid = 1;
bool success = 2;
// The local channel close output. If the local channel balance was dust to
// begin with, this output will not be set.
CloseOutput local_close_output = 3;
// The remote channel close output. If the remote channel balance was dust
// to begin with, this output will not be set.
CloseOutput remote_close_output = 4;
// Any additional outputs that might be added for custom channel types.
repeated CloseOutput additional_outputs = 5;
}
message CloseChannelRequest {
@ -2072,9 +2157,13 @@ message CloseChannelRequest {
// NOTE: This field is only respected if we're the initiator of the channel.
uint64 max_fee_per_vbyte = 7;
// If true, then the rpc call will not block while it awaits a closing txid.
// Consequently this RPC call will not return a closing txid if this value
// is set.
// If true, then the rpc call will not block while it awaits a closing txid
// to be broadcasted to the mempool. To obtain the closing tx one has to
// listen to the stream for the particular updates. Moreover if a coop close
// is specified and this flag is set to true the coop closing flow will be
// initiated even if HTLCs are active on the channel. The channel will wait
// until all HTLCs are resolved and then start the coop closing process. The
// channel will be disabled in the meantime and will disallow any new HTLCs.
bool no_wait = 8;
}
@ -2089,9 +2178,15 @@ message CloseStatusUpdate {
message PendingUpdate {
bytes txid = 1;
uint32 output_index = 2;
int64 fee_per_vbyte = 3;
bool local_close_tx = 4;
}
message InstantUpdate {
// The number of pending HTLCs that are currently active on the channel.
// These HTLCs need to be resolved before the channel can be closed
// cooperatively.
int32 num_pending_htlcs = 1;
}
message ReadyForPsbtFunding {
@ -2709,6 +2804,11 @@ message PendingChannelsResponse {
impacts the channel's operation.
*/
string memo = 13;
/*
Custom channel data that might be populated in custom channels.
*/
bytes custom_channel_data = 34;
}
message PendingOpenChannel {
@ -2880,6 +2980,7 @@ message ChannelEventUpdate {
ChannelPoint inactive_channel = 4;
PendingUpdate pending_open_channel = 6;
ChannelPoint fully_resolved_channel = 7;
ChannelPoint channel_funding_timeout = 8;
}
enum UpdateType {
@ -2889,6 +2990,7 @@ message ChannelEventUpdate {
INACTIVE_CHANNEL = 3;
PENDING_OPEN_CHANNEL = 4;
FULLY_RESOLVED_CHANNEL = 5;
CHANNEL_FUNDING_TIMEOUT = 6;
}
UpdateType type = 5;
@ -2968,6 +3070,12 @@ message ChannelBalanceResponse {
// Sum of channels pending remote balances.
Amount pending_open_remote_balance = 8;
/*
Custom channel data that might be populated if there are custom channels
present.
*/
bytes custom_channel_data = 9;
}
message QueryRoutesRequest {
@ -3293,6 +3401,20 @@ message Route {
The total amount in millisatoshis.
*/
int64 total_amt_msat = 6;
/*
The actual on-chain amount that was sent out to the first hop. This value is
only different from the total_amt_msat field if this is a custom channel
payment and the value transported in the HTLC is different from the BTC
amount in the HTLC. If this value is zero, then this is an old payment that
didn't have this value yet and can be ignored.
*/
int64 first_hop_amount_msat = 7;
/*
Custom channel data that might be populated in custom channels.
*/
bytes custom_channel_data = 8;
}
message NodeInfoRequest {
@ -3478,6 +3600,8 @@ message NetworkInfo {
message StopRequest {
}
message StopResponse {
// The status of the stop operation.
string status = 1;
}
message GraphTopologySubscription {
@ -3922,6 +4046,11 @@ message InvoiceHTLC {
// Details relevant to AMP HTLCs, only populated if this is an AMP HTLC.
AMP amp = 11;
/*
Custom channel data that might be populated in custom channels.
*/
bytes custom_channel_data = 12;
}
// Details specific to AMP HTLCs.
@ -4162,6 +4291,12 @@ message Payment {
uint64 payment_index = 15;
PaymentFailureReason failure_reason = 16;
/*
The custom TLV records that were sent to the first hop as part of the HTLC
wire message for this payment.
*/
map<uint64, bytes> first_hop_custom_records = 17;
}
message HTLCAttempt {
@ -4291,9 +4426,13 @@ message DeleteAllPaymentsRequest {
}
message DeletePaymentResponse {
// The status of the delete operation.
string status = 1;
}
message DeleteAllPaymentsResponse {
// The status of the delete operation.
string status = 1;
}
message AbandonChannelRequest {
@ -4310,6 +4449,8 @@ message AbandonChannelRequest {
}
message AbandonChannelResponse {
// The status of the abandon operation.
string status = 1;
}
message DebugLevelRequest {
@ -4469,6 +4610,15 @@ message PolicyUpdateRequest {
// Optional inbound fee. If unset, the previously set value will be
// retained [EXPERIMENTAL].
InboundFee inbound_fee = 10;
// Under unknown circumstances a channel can exist with a missing edge in
// the graph database. This can cause an 'edge not found' error when calling
// `getchaninfo` and/or cause the default channel policy to be used during
// forwards. Setting this flag will recreate the edge if not found, allowing
// updating this channel policy and fixing the missing edge problem for this
// channel permanently. For fields not set in this command, the default
// policy will be created.
bool create_missing_edge = 11;
}
enum UpdateFailure {
@ -4562,6 +4712,14 @@ message ForwardingEvent {
// The peer alias of the outgoing channel.
string peer_alias_out = 13;
// The ID of the incoming HTLC in the payment circuit. This field is
// optional and is unset for forwarding events happened before v0.20.
optional uint64 incoming_htlc_id = 14;
// The ID of the outgoing HTLC in the payment circuit. This field is
// optional and may be unset for legacy forwarding events.
optional uint64 outgoing_htlc_id = 15;
// TODO(roasbeef): add settlement latency?
// * use FPE on the chan id?
// * also list failures?
@ -4649,12 +4807,15 @@ message RestoreChanBackupRequest {
}
}
message RestoreBackupResponse {
// The number of channels successfully restored.
uint32 num_restored = 1;
}
message ChannelBackupSubscription {
}
message VerifyChanBackupResponse {
repeated string chan_points = 1;
}
message MacaroonPermission {
@ -4977,6 +5138,22 @@ message RPCMiddlewareRequest {
intercept message.
*/
uint64 msg_id = 7;
/*
The metadata pairs that were sent along with the original gRPC request via
the golang context.Context using explicit [gRPC
metadata](https://grpc.io/docs/guides/metadata/). Context values are not
propagated via gRPC and so we send any pairs along explicitly here so that
the interceptor can access them.
*/
map<string, MetadataValues> metadata_pairs = 9;
}
message MetadataValues {
/*
The set of metadata values that correspond to the metadata key.
*/
repeated string values = 1;
}
message StreamAuth {

View file

@ -1,22 +1,43 @@
syntax = "proto3";
import "lightning.proto";
package routerrpc;
import "lightning.proto";
option go_package = "github.com/lightningnetwork/lnd/lnrpc/routerrpc";
/*
* Comments in this file will be directly parsed into the API
* Documentation as descriptions of the associated method, message, or field.
* These descriptions should go right above the definition of the object, and
* can be in either block or // comment format.
*
* An RPC method can be matched to an lncli command by placing a line in the
* beginning of the description in exactly the following format:
* lncli: `methodname`
*
* Failure to specify the exact name of the command will cause documentation
* generation to fail.
*
* More information on how exactly the gRPC documentation is generated from
* this proto file can be found here:
* https://github.com/lightninglabs/lightning-api
*/
// Router is a service that offers advanced interaction with the router
// subsystem of the daemon.
service Router {
/*
SendPaymentV2 attempts to route a payment described by the passed
PaymentRequest to the final destination. The call returns a stream of
payment updates.
payment updates. When using this RPC, make sure to set a fee limit, as the
default routing fee limit is 0 sats. Without a non-zero fee limit only
routes without fees will be attempted which often fails with
FAILURE_REASON_NO_ROUTE.
*/
rpc SendPaymentV2 (SendPaymentRequest) returns (stream lnrpc.Payment);
/*
/* lncli: `trackpayment`
TrackPaymentV2 returns an update stream for the payment identified by the
payment hash.
*/
@ -57,21 +78,21 @@ service Router {
*/
rpc SendToRouteV2 (SendToRouteRequest) returns (lnrpc.HTLCAttempt);
/*
/* lncli: `resetmc`
ResetMissionControl clears all mission control state and starts with a clean
slate.
*/
rpc ResetMissionControl (ResetMissionControlRequest)
returns (ResetMissionControlResponse);
/*
/* lncli: `querymc`
QueryMissionControl exposes the internal mission control state to callers.
It is a development feature.
*/
rpc QueryMissionControl (QueryMissionControlRequest)
returns (QueryMissionControlResponse);
/*
/* lncli: `importmc`
XImportMissionControl is an experimental API that imports the state provided
to the internal mission control's state, using all results which are more
recent than our existing values. These values will only be imported
@ -80,30 +101,36 @@ service Router {
rpc XImportMissionControl (XImportMissionControlRequest)
returns (XImportMissionControlResponse);
/*
/* lncli: `getmccfg`
GetMissionControlConfig returns mission control's current config.
*/
rpc GetMissionControlConfig (GetMissionControlConfigRequest)
returns (GetMissionControlConfigResponse);
/*
/* lncli: `setmccfg`
SetMissionControlConfig will set mission control's config, if the config
provided is valid.
*/
rpc SetMissionControlConfig (SetMissionControlConfigRequest)
returns (SetMissionControlConfigResponse);
/*
QueryProbability returns the current success probability estimate for a
given node pair and amount.
/* lncli: `queryprob`
Deprecated. QueryProbability returns the current success probability
estimate for a given node pair and amount. The call returns a zero success
probability if no channel is available or if the amount violates min/max
HTLC constraints.
*/
rpc QueryProbability (QueryProbabilityRequest)
returns (QueryProbabilityResponse);
/*
/* lncli: `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.
*/
rpc BuildRoute (BuildRouteRequest) returns (BuildRouteResponse);
@ -141,7 +168,7 @@ service Router {
rpc HtlcInterceptor (stream ForwardHtlcInterceptResponse)
returns (stream ForwardHtlcInterceptRequest);
/*
/* lncli: `updatechanstatus`
UpdateChanStatus attempts to manually set the state of a channel
(enabled, disabled, or auto). A manual "disable" request will cause the
channel to stay disabled until a subsequent manual request of either
@ -149,6 +176,25 @@ service Router {
*/
rpc UpdateChanStatus (UpdateChanStatusRequest)
returns (UpdateChanStatusResponse);
/*
XAddLocalChanAliases is an experimental API that creates a set of new
channel SCID alias mappings. The final total set of aliases in the manager
after the add operation is returned. This is only a locally stored alias,
and will not be communicated to the channel peer via any message. Therefore,
routing over such an alias will only work if the peer also calls this same
RPC on their end. If an alias already exists, an error is returned
*/
rpc XAddLocalChanAliases (AddAliasesRequest) returns (AddAliasesResponse);
/*
XDeleteLocalChanAliases is an experimental API that deletes a set of alias
mappings. The final total set of aliases in the manager after the delete
operation is returned. The deletion will not be communicated to the channel
peer via any message.
*/
rpc XDeleteLocalChanAliases (DeleteAliasesRequest)
returns (DeleteAliasesResponse);
}
message SendPaymentRequest {
@ -162,13 +208,6 @@ message SendPaymentRequest {
*/
int64 amt = 2;
/*
Number of millisatoshis to send.
The fields amt and amt_msat are mutually exclusive.
*/
int64 amt_msat = 12;
// The hash to use within the payment's HTLC
bytes payment_hash = 3;
@ -178,9 +217,6 @@ message SendPaymentRequest {
*/
int32 final_cltv_delta = 4;
// An optional payment addr to be included within the last hop of the route.
bytes payment_addr = 20;
/*
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
@ -191,10 +227,11 @@ message SendPaymentRequest {
string payment_request = 5;
/*
An upper limit on the amount of time we should spend when attempting to
fulfill the payment. This is expressed in seconds. If we cannot make a
successful payment within this time frame, an error will be returned.
This field must be non-zero.
An optional limit, expressed in seconds, on the time to wait before
attempting the first HTLC. Once HTLCs are in flight, the payment will
not be aborted until the HTLCs are either settled or failed. If the field
is not set or is explicitly set to zero, the default value of 60 seconds
will be applied.
*/
int32 timeout_seconds = 6;
@ -208,17 +245,6 @@ message SendPaymentRequest {
*/
int64 fee_limit_sat = 7;
/*
The maximum number of millisatoshis that will be paid as a fee of the
payment. If this field is left to the default value of 0, only zero-fee
routes will be considered. This usually means single hop routes connecting
directly to the destination. To send the payment without a fee limit, use
max int here.
The fields fee_limit_sat and fee_limit_msat are mutually exclusive.
*/
int64 fee_limit_msat = 13;
/*
Deprecated, use outgoing_chan_ids. The channel id of the channel that must
be taken to the first hop. If zero, any channel may be used (unless
@ -227,19 +253,8 @@ message SendPaymentRequest {
uint64 outgoing_chan_id = 8 [jstype = JS_STRING, deprecated = true];
/*
The channel ids of the channels are allowed for the first hop. If empty,
any channel may be used.
*/
repeated uint64 outgoing_chan_ids = 19;
/*
The pubkey of the last hop of the route. If empty, any hop may be used.
*/
bytes last_hop_pubkey = 14;
/*
An optional maximum total time lock for the route. This should not exceed
lnd's `--max-cltv-expiry` setting. If zero, then the value of
An optional maximum total time lock for the route. This should not
exceed lnd's `--max-cltv-expiry` setting. If zero, then the value of
`--max-cltv-expiry` is enforced.
*/
int32 cltv_limit = 9;
@ -258,6 +273,29 @@ message SendPaymentRequest {
*/
map<uint64, bytes> dest_custom_records = 11;
/*
Number of millisatoshis to send.
The fields amt and amt_msat are mutually exclusive.
*/
int64 amt_msat = 12;
/*
The maximum number of millisatoshis that will be paid as a fee of the
payment. If this field is left to the default value of 0, only zero-fee
routes will be considered. This usually means single hop routes connecting
directly to the destination. To send the payment without a fee limit, use
max int here.
The fields fee_limit_sat and fee_limit_msat are mutually exclusive.
*/
int64 fee_limit_msat = 13;
/*
The pubkey of the last hop of the route. If empty, any hop may be used.
*/
bytes last_hop_pubkey = 14;
// If set, circular payments to self are permitted.
bool allow_self_payment = 15;
@ -282,6 +320,18 @@ message SendPaymentRequest {
*/
bool no_inflight_updates = 18;
/*
The channel ids of the channels are allowed for the first hop. If empty,
any channel may be used.
*/
repeated uint64 outgoing_chan_ids = 19;
/*
An optional payment addr to be included within the last hop of the route.
This is also called payment secret in specifications (e.g. BOLT 11).
*/
bytes payment_addr = 20;
/*
The largest payment split that should be attempted when making a payment if
splitting is necessary. Setting this value will effectively cause lnd to
@ -300,6 +350,24 @@ message SendPaymentRequest {
only, to 1 to optimize for reliability only or a value inbetween for a mix.
*/
double time_pref = 23;
/*
If set, the payment loop can be interrupted by manually canceling the
payment context, even before the payment timeout is reached. Note that the
payment may still succeed after cancellation, as in-flight attempts can
still settle afterwards. Canceling will only prevent further attempts from
being sent.
*/
bool cancelable = 24;
/*
An optional field that can be used to pass an arbitrary set of TLV records
to the first hop peer of this payment. This can be used to pass application
specific data during the payment attempt. Record types are required to be in
the custom range >= 65536. When using REST, the values must be encoded as
base64.
*/
map<uint64, bytes> first_hop_custom_records = 25;
}
message TrackPaymentRequest {
@ -323,14 +391,39 @@ message TrackPaymentsRequest {
message RouteFeeRequest {
/*
The destination once wishes to obtain a routing fee quote to.
The destination one wishes to obtain a routing fee quote to. If set, this
parameter requires the amt_sat parameter also to be set. This parameter
combination triggers a graph based routing fee estimation as opposed to a
payment probe based estimate in case a payment request is provided. The
graph based estimation is an algorithm that is executed on the in memory
graph. Hence its runtime is significantly shorter than a payment probe
estimation that sends out actual payments to the network.
*/
bytes dest = 1;
/*
The amount one wishes to send to the target destination.
The amount one wishes to send to the target destination. It is only to be
used in combination with the dest parameter.
*/
int64 amt_sat = 2;
/*
A payment request of the target node that the route fee request is intended
for. Its parameters are input to probe payments that estimate routing fees.
The timeout parameter can be specified to set a maximum time on the probing
attempt. Cannot be used in combination with dest and amt_sat.
*/
string payment_request = 3;
/*
A user preference of how long a probe payment should maximally be allowed to
take, denoted in seconds. The probing payment loop is aborted if this
timeout is reached. Note that the probing process itself can take longer
than the timeout if the HTLC becomes delayed or stuck. Canceling the context
of this call will not cancel the payment loop, the duration is only
controlled by the timeout parameter.
*/
uint32 timeout = 4;
}
message RouteFeeResponse {
@ -346,6 +439,12 @@ message RouteFeeResponse {
value.
*/
int64 time_lock_delay = 2;
/*
An indication whether a probing payment succeeded or whether and why it
failed. FAILURE_REASON_NONE indicates success.
*/
lnrpc.PaymentFailureReason failure_reason = 5;
}
message SendToRouteRequest {
@ -362,6 +461,15 @@ message SendToRouteRequest {
routes, incorrect payment details, or insufficient funds.
*/
bool skip_temp_err = 3;
/*
An optional field that can be used to pass an arbitrary set of TLV records
to the first hop peer of this payment. This can be used to pass application
specific data during the payment attempt. Record types are required to be in
the custom range >= 65536. When using REST, the values must be encoded as
base64.
*/
map<uint64, bytes> first_hop_custom_records = 4;
}
message SendToRouteResponse {
@ -465,6 +573,93 @@ message SetMissionControlConfigResponse {
}
message MissionControlConfig {
/*
Deprecated, use AprioriParameters. The amount of time mission control will
take to restore a penalized node or channel back to 50% success probability,
expressed in seconds. Setting this value to a higher value will penalize
failures for longer, making mission control less likely to route through
nodes and channels that we have previously recorded failures for.
*/
uint64 half_life_seconds = 1 [deprecated = true];
/*
Deprecated, use AprioriParameters. The probability of success mission
control should assign to hop in a route where it has no other information
available. Higher values will make mission control more willing to try hops
that we have no information about, lower values will discourage trying these
hops.
*/
float hop_probability = 2 [deprecated = true];
/*
Deprecated, use AprioriParameters. The importance that mission control
should place on historical results, expressed as a value in [0;1]. Setting
this value to 1 will ignore all historical payments and just use the hop
probability to assess the probability of success for each hop. A zero value
ignores hop probability completely and relies entirely on historical
results, unless none are available.
*/
float weight = 3 [deprecated = true];
/*
The maximum number of payment results that mission control will store.
*/
uint32 maximum_payment_results = 4;
/*
The minimum time that must have passed since the previously recorded failure
before we raise the failure amount.
*/
uint64 minimum_failure_relax_interval = 5;
enum ProbabilityModel {
APRIORI = 0;
BIMODAL = 1;
}
/*
ProbabilityModel defines which probability estimator should be used in
pathfinding. Note that the bimodal estimator is experimental.
*/
ProbabilityModel model = 6;
/*
EstimatorConfig is populated dependent on the estimator type.
*/
oneof EstimatorConfig {
AprioriParameters apriori = 7;
BimodalParameters bimodal = 8;
}
}
message BimodalParameters {
/*
NodeWeight defines how strongly other previous forwardings on channels of a
router should be taken into account when computing a channel's probability
to route. The allowed values are in the range [0, 1], where a value of 0
means that only direct information about a channel is taken into account.
*/
double node_weight = 1;
/*
ScaleMsat describes the scale over which channels statistically have some
liquidity left. The value determines how quickly the bimodal distribution
drops off from the edges of a channel. A larger value (compared to typical
channel capacities) means that the drop off is slow and that channel
balances are distributed more uniformly. A small value leads to the
assumption of very unbalanced channels.
*/
uint64 scale_msat = 2;
/*
DecayTime describes the information decay of knowledge about previous
successes and failures in channels. The smaller the decay time, the quicker
we forget about past forwardings.
*/
uint64 decay_time = 3;
}
message AprioriParameters {
/*
The amount of time mission control will take to restore a penalized node
or channel back to 50% success probability, expressed in seconds. Setting
@ -480,7 +675,7 @@ message MissionControlConfig {
control more willing to try hops that we have no information about, lower
values will discourage trying these hops.
*/
float hop_probability = 2;
double hop_probability = 2;
/*
The importance that mission control should place on historical results,
@ -490,18 +685,15 @@ message MissionControlConfig {
completely and relies entirely on historical results, unless none are
available.
*/
float weight = 3;
double weight = 3;
/*
The maximum number of payment results that mission control will store.
The fraction of a channel's capacity that we consider to have liquidity. For
amounts that come close to or exceed the fraction, an additional penalty is
applied. A value of 1.0 disables the capacity factor. Allowed values are in
[0.75, 1.0].
*/
uint32 maximum_payment_results = 4;
/*
The minimum time that must have passed since the previously recorded failure
before we raise the failure amount.
*/
uint64 minimum_failure_relax_interval = 5;
double capacity_fraction = 4;
}
message QueryProbabilityRequest {
@ -548,8 +740,20 @@ message BuildRouteRequest {
*/
repeated bytes hop_pubkeys = 4;
// An optional payment addr to be included within the last hop of the route.
/*
An optional payment addr to be included within the last hop of the route.
This is also called payment secret in specifications (e.g. BOLT 11).
*/
bytes payment_addr = 5;
/*
An optional field that can be used to pass an arbitrary set of TLV records
to the first hop peer of this payment. This can be used to pass application
specific data during the payment attempt. Record types are required to be in
the custom range >= 65536. When using REST, the values must be encoded as
base64.
*/
map<uint64, bytes> first_hop_custom_records = 6;
}
message BuildRouteResponse {
@ -806,12 +1010,17 @@ message ForwardHtlcInterceptRequest {
// The block height at which this htlc will be auto-failed to prevent the
// channel from force-closing.
int32 auto_fail_height = 10;
// The custom records of the peer's incoming p2p wire message.
map<uint64, bytes> in_wire_custom_records = 11;
}
/**
ForwardHtlcInterceptResponse enables the caller to resolve a previously hold
forward. The caller can choose either to:
- `Resume`: Execute the default behavior (usually forward).
- `ResumeModified`: Execute the default behavior (usually forward) with HTLC
field modifications.
- `Reject`: Fail the htlc backwards.
- `Settle`: Settle this htlc with a given preimage.
*/
@ -842,12 +1051,40 @@ message ForwardHtlcInterceptResponse {
// For backwards-compatibility reasons, TEMPORARY_CHANNEL_FAILURE is the
// default value for this field.
lnrpc.Failure.FailureCode failure_code = 5;
// The amount that was set on the p2p wire message of the incoming HTLC.
// This field is ignored if the action is not RESUME_MODIFIED or the amount
// is zero.
uint64 in_amount_msat = 6;
// The amount to set on the p2p wire message of the resumed HTLC. This field
// is ignored if the action is not RESUME_MODIFIED or the amount is zero.
uint64 out_amount_msat = 7;
// Any custom records that should be set on the p2p wire message message of
// the resumed HTLC. This field is ignored if the action is not
// RESUME_MODIFIED.
//
// This map will merge with the existing set of custom records (if any),
// replacing any conflicting types. Note that there currently is no support
// for deleting existing custom records (they can only be replaced).
map<uint64, bytes> out_wire_custom_records = 8;
}
enum ResolveHoldForwardAction {
// SETTLE is an action that is used to settle an HTLC instead of forwarding
// it.
SETTLE = 0;
// FAIL is an action that is used to fail an HTLC backwards.
FAIL = 1;
// RESUME is an action that is used to resume a forward HTLC.
RESUME = 2;
// RESUME_MODIFIED is an action that is used to resume a hold forward HTLC
// with modifications specified during interception.
RESUME_MODIFIED = 3;
}
message UpdateChanStatusRequest {
@ -863,4 +1100,20 @@ enum ChanStatusAction {
}
message UpdateChanStatusResponse {
}
message AddAliasesRequest {
repeated lnrpc.AliasMap alias_maps = 1;
}
message AddAliasesResponse {
repeated lnrpc.AliasMap alias_maps = 1;
}
message DeleteAliasesRequest {
repeated lnrpc.AliasMap alias_maps = 1;
}
message DeleteAliasesResponse {
repeated lnrpc.AliasMap alias_maps = 1;
}

View file

@ -1172,6 +1172,12 @@ message PendingSweep {
The deadline height used for this output when perform fee bumping.
*/
uint32 deadline_height = 14;
/*
The block height which the input's locktime will expire at. Zero if the
input has no locktime.
*/
uint32 maturity_height = 15;
}
message PendingSweepsRequest {
@ -1188,9 +1194,8 @@ message BumpFeeRequest {
// The input we're attempting to bump the fee of.
lnrpc.OutPoint outpoint = 1;
// Optional. The deadline in number of blocks that the input should be spent
// within. When not set, for new inputs, the default value (1008) is used;
// for existing inputs, their current values will be retained.
// Optional. The conf target the underlying fee estimator will use to
// estimate the starting fee rate for the fee function.
uint32 target_conf = 2;
/*
@ -1217,7 +1222,7 @@ message BumpFeeRequest {
/*
Optional. Whether this input will be swept immediately. When set to true,
the sweeper will sweep this input without waiting for the next batch.
the sweeper will sweep this input without waiting for the next block.
*/
bool immediate = 6;
@ -1230,6 +1235,12 @@ message BumpFeeRequest {
retained.
*/
uint64 budget = 7;
// Optional. The deadline delta in number of blocks that the output
// should be spent within. This translates internally to the width of the
// fee function that the sweeper will use to bump the fee rate. When the
// deadline is reached, ALL the budget will be spent as fees.
uint32 deadline_delta = 8;
}
message BumpFeeResponse {
@ -1243,7 +1254,8 @@ message BumpForceCloseFeeRequest {
lnrpc.ChannelPoint chan_point = 1;
// Optional. The deadline delta in number of blocks that the anchor output
// should be spent within to bump the closing transaction.
// should be spent within to bump the closing transaction. When the
// deadline is reached, ALL the budget will be spent as fees
uint32 deadline_delta = 2;
/*
@ -1270,6 +1282,10 @@ message BumpForceCloseFeeRequest {
transaction of the force closed channel otherwise the fee bumping will fail.
*/
uint64 budget = 5;
// Optional. The conf target the underlying fee estimator will use to
// estimate the starting fee rate for the fee function.
uint32 target_conf = 6;
}
message BumpForceCloseFeeResponse {
@ -1426,6 +1442,16 @@ message FundPsbtRequest {
// The max fee to total output amount ratio that this psbt should adhere to.
double max_fee_ratio = 12;
// The custom lock ID to use for the inputs in the funded PSBT. The value
// if set must be exactly 32 bytes long. If empty, the default lock ID will
// be used.
bytes custom_lock_id = 13;
// If set, then the inputs in the funded PSBT will be locked for the
// specified duration. The lock duration is specified in seconds. If not
// set, the default lock duration will be used.
uint64 lock_expiration_seconds = 14;
}
message FundPsbtResponse {
/*