|
| 1 | +# API Guide |
| 2 | + |
| 3 | +LDK Server exposes a gRPC API over HTTP/2 with TLS. This guide covers transport, authentication, |
| 4 | +and provides an index of all available RPCs. For field-level details on each request and response, |
| 5 | +refer to the proto definitions, which are the canonical reference and include links to the |
| 6 | +underlying LDK Node documentation. |
| 7 | + |
| 8 | +## Transport |
| 9 | + |
| 10 | +- **Protocol:** gRPC over HTTP/2 with TLS (self-signed by default) |
| 11 | +- **Default address:** `127.0.0.1:3536` |
| 12 | +- **Content-Type:** `application/grpc+proto` |
| 13 | +- **Service name:** `api.LightningNode` |
| 14 | +- **Full RPC path format:** `/api.LightningNode/<MethodName>` |
| 15 | + |
| 16 | +## Authentication |
| 17 | + |
| 18 | +Every gRPC request must include an `x-auth` metadata header with an HMAC-SHA256 signature: |
| 19 | + |
| 20 | +``` |
| 21 | +x-auth: HMAC <unix_timestamp>:<hmac_hex> |
| 22 | +``` |
| 23 | + |
| 24 | +Where: |
| 25 | + |
| 26 | +- `unix_timestamp` is the current time in seconds since the Unix epoch |
| 27 | +- `hmac_hex` is the hex-encoded result of `HMAC-SHA256(api_key_bytes, timestamp_be_bytes)` |
| 28 | + - `api_key_bytes` is the API key string encoded as UTF-8 bytes |
| 29 | + - `timestamp_be_bytes` is the timestamp as a big-endian 8-byte unsigned integer |
| 30 | + |
| 31 | +The server rejects requests where the timestamp differs from the server's clock by more than |
| 32 | +**60 seconds**. |
| 33 | + |
| 34 | +## TLS |
| 35 | + |
| 36 | +The server auto-generates a self-signed ECDSA P-256 certificate on first startup, stored at |
| 37 | +`<storage_dir>/tls.crt`. Clients must pin this certificate (not rely on system trust roots) |
| 38 | +since it is self-signed. |
| 39 | + |
| 40 | +For the Rust client library, pass the PEM contents to `LdkServerClient::new()`. For other |
| 41 | +languages, configure your gRPC channel to trust the server's certificate file. |
| 42 | + |
| 43 | +## Proto Definitions |
| 44 | + |
| 45 | +The canonical API definitions live in `ldk-server-grpc/src/proto/`: |
| 46 | + |
| 47 | +| File | Contents | |
| 48 | +|----------------|-----------------------------------------------------| |
| 49 | +| `api.proto` | All RPC request/response messages and documentation | |
| 50 | +| `types.proto` | Shared types (Payment, Channel, Peer, etc.) | |
| 51 | +| `events.proto` | Event envelope and event types for streaming | |
| 52 | +| `error.proto` | Error response definitions | |
| 53 | + |
| 54 | +### Generating Client Stubs |
| 55 | + |
| 56 | +Any standard `protoc` toolchain can generate clients from these proto files. The proto directory |
| 57 | +path is `ldk-server-grpc/src/proto/`. For Rust specifically, the `ldk-server-client` crate |
| 58 | +provides a ready-made async client. |
| 59 | + |
| 60 | +## Error Model |
| 61 | + |
| 62 | +Errors are returned as standard gRPC status codes: |
| 63 | + |
| 64 | +| gRPC Code | Meaning | |
| 65 | +|---------------------------|------------------------------------------------------------------| |
| 66 | +| `INVALID_ARGUMENT` (3) | Malformed request or invalid parameters | |
| 67 | +| `FAILED_PRECONDITION` (9) | Lightning operation error (e.g., insufficient balance, no route) | |
| 68 | +| `INTERNAL` (13) | Server-side bug | |
| 69 | +| `UNAUTHENTICATED` (16) | Missing or invalid `x-auth` header | |
| 70 | + |
| 71 | +The `grpc-message` trailer contains a human-readable error description. |
| 72 | + |
| 73 | +## Endpoint Reference |
| 74 | + |
| 75 | +All RPCs are unary (single request, single response) unless noted otherwise. |
| 76 | + |
| 77 | +### Node Information |
| 78 | + |
| 79 | +| RPC | Description | |
| 80 | +|---------------|-------------------------------------------------------------------------------------| |
| 81 | +| `GetNodeInfo` | Node ID, best block, sync timestamps, listening/announcement addresses, alias, URIs | |
| 82 | +| `GetBalances` | On-chain, Lightning channel, and claimable balance breakdown | |
| 83 | + |
| 84 | +### On-Chain |
| 85 | + |
| 86 | +| RPC | Description | |
| 87 | +|------------------|----------------------------------------------------------------------| |
| 88 | +| `OnchainReceive` | Generate a new on-chain funding address | |
| 89 | +| `OnchainSend` | Send to a Bitcoin address (with optional fee rate and send-all mode) | |
| 90 | + |
| 91 | +### BOLT11 Payments |
| 92 | + |
| 93 | +| RPC | Description | |
| 94 | +|-----------------|-------------------------------------------------------------------| |
| 95 | +| `Bolt11Receive` | Create an invoice (fixed or variable amount) with automatic claim | |
| 96 | +| `Bolt11Send` | Pay a BOLT11 invoice (with optional routing config) | |
| 97 | + |
| 98 | +### BOLT11 Hodl Invoices |
| 99 | + |
| 100 | +These RPCs support a manual claim/fail workflow for held payments. See |
| 101 | +[Hodl Invoice Lifecycle](#hodl-invoice-lifecycle) below. |
| 102 | + |
| 103 | +| RPC | Description | |
| 104 | +|------------------------|--------------------------------------------------------------------| |
| 105 | +| `Bolt11ReceiveForHash` | Create an invoice for a given payment hash (manual claim required) | |
| 106 | +| `Bolt11ClaimForHash` | Claim a held payment by providing the preimage | |
| 107 | +| `Bolt11FailForHash` | Reject a held payment | |
| 108 | + |
| 109 | +### BOLT11 JIT Channels (LSPS2) |
| 110 | + |
| 111 | +Requires an `[liquidity.lsps2_client]` configuration. The LSP opens a channel just-in-time |
| 112 | +when the invoice is paid. |
| 113 | + |
| 114 | +| RPC | Description | |
| 115 | +|--------------------------------------------|-----------------------------------------------------------| |
| 116 | +| `Bolt11ReceiveViaJitChannel` | Create a fixed-amount invoice with JIT channel opening | |
| 117 | +| `Bolt11ReceiveVariableAmountViaJitChannel` | Create a variable-amount invoice with JIT channel opening | |
| 118 | + |
| 119 | +### BOLT12 Offers |
| 120 | + |
| 121 | +| RPC | Description | |
| 122 | +|-----------------|-------------------------------------------------------------------------| |
| 123 | +| `Bolt12Receive` | Create a BOLT12 offer (fixed or variable amount) | |
| 124 | +| `Bolt12Send` | Pay a BOLT12 offer (with optional quantity, payer note, routing config) | |
| 125 | + |
| 126 | +### Spontaneous and Unified Send |
| 127 | + |
| 128 | +| RPC | Description | |
| 129 | +|-------------------|--------------------------------------------------------------------------------| |
| 130 | +| `SpontaneousSend` | Send a keysend payment to a node ID | |
| 131 | +| `UnifiedSend` | Pay a BIP 21 URI, BIP 353 Human-Readable Name, BOLT11 invoice, or BOLT12 offer | |
| 132 | + |
| 133 | +### Channel Management |
| 134 | + |
| 135 | +| RPC | Description | |
| 136 | +|-----------------------|------------------------------------------------------------------------| |
| 137 | +| `OpenChannel` | Open a new outbound channel (with optional push amount and fee config) | |
| 138 | +| `CloseChannel` | Cooperatively close a channel | |
| 139 | +| `ForceCloseChannel` | Force-close a channel unilaterally | |
| 140 | +| `SpliceIn` | Add on-chain funds to an existing channel | |
| 141 | +| `SpliceOut` | Remove funds from a channel back on-chain | |
| 142 | +| `UpdateChannelConfig` | Update forwarding fees and CLTV expiry delta | |
| 143 | +| `ListChannels` | List all channels with balances and configuration | |
| 144 | + |
| 145 | +### Payment History |
| 146 | + |
| 147 | +| RPC | Description | |
| 148 | +|-------------------------|------------------------------------------------| |
| 149 | +| `GetPaymentDetails` | Get details for a specific payment by ID | |
| 150 | +| `ListPayments` | List all payments (paginated) | |
| 151 | +| `ListForwardedPayments` | List all forwarded/routed payments (paginated) | |
| 152 | + |
| 153 | +See [Pagination](#pagination) below for how to page through results. |
| 154 | + |
| 155 | +### Peer Management |
| 156 | + |
| 157 | +| RPC | Description | |
| 158 | +|------------------|----------------------------------------------------------| |
| 159 | +| `ConnectPeer` | Connect to a peer (optionally persist the connection) | |
| 160 | +| `DisconnectPeer` | Disconnect from a peer and remove it from the peer store | |
| 161 | +| `ListPeers` | List all connected peers | |
| 162 | + |
| 163 | +### Cryptography |
| 164 | + |
| 165 | +| RPC | Description | |
| 166 | +|-------------------|-----------------------------------------------------| |
| 167 | +| `SignMessage` | Sign a message with the node's private key | |
| 168 | +| `VerifySignature` | Verify a signature against a message and public key | |
| 169 | + |
| 170 | +### Network Graph |
| 171 | + |
| 172 | +| RPC | Description | |
| 173 | +|---------------------|-------------------------------------------------------| |
| 174 | +| `GraphListChannels` | List all known short channel IDs in the network graph | |
| 175 | +| `GraphGetChannel` | Get channel details by short channel ID | |
| 176 | +| `GraphListNodes` | List all known node IDs in the network graph | |
| 177 | +| `GraphGetNode` | Get node details by node ID | |
| 178 | + |
| 179 | +### Routing |
| 180 | + |
| 181 | +| RPC | Description | |
| 182 | +|---------------------------|------------------------------------------------------| |
| 183 | +| `ExportPathfindingScores` | Export the router's pathfinding score cache | |
| 184 | +| `DecodeInvoice` | Decode a BOLT11 invoice and return its parsed fields | |
| 185 | +| `DecodeOffer` | Decode a BOLT12 offer and return its parsed fields | |
| 186 | + |
| 187 | +### Event Streaming |
| 188 | + |
| 189 | +| RPC | Description | |
| 190 | +|-------------------|-------------------------------------------------------------| |
| 191 | +| `SubscribeEvents` | **Server-streaming.** Subscribe to real-time payment events | |
| 192 | + |
| 193 | +`SubscribeEvents` returns a stream of `EventEnvelope` messages. Each envelope contains one of: |
| 194 | + |
| 195 | +| Event | When | |
| 196 | +|---------------------|-----------------------------------------------------------------------| |
| 197 | +| `PaymentReceived` | An inbound payment was received and auto-claimed | |
| 198 | +| `PaymentSuccessful` | An outbound payment succeeded | |
| 199 | +| `PaymentFailed` | An outbound payment failed | |
| 200 | +| `PaymentClaimable` | A hodl invoice payment arrived and is waiting to be claimed or failed | |
| 201 | +| `PaymentForwarded` | A payment was routed through this node | |
| 202 | + |
| 203 | +Events are broadcast to all connected subscribers. The server uses a bounded broadcast channel |
| 204 | +(capacity 1024). A slow subscriber that falls behind will miss events. |
| 205 | + |
| 206 | +### Metrics |
| 207 | + |
| 208 | +Metrics are served as a plain HTTP GET endpoint (not gRPC): |
| 209 | + |
| 210 | +``` |
| 211 | +GET /metrics |
| 212 | +``` |
| 213 | + |
| 214 | +Returns Prometheus-format text. Requires `[metrics] enabled = true` in the config. Supports |
| 215 | +optional Basic Auth. See [Configuration](configuration.md#metrics) for setup. |
| 216 | + |
| 217 | +## Hodl Invoice Lifecycle |
| 218 | + |
| 219 | +Hodl invoices allow you to inspect and conditionally accept incoming payments: |
| 220 | + |
| 221 | +1. **Create the invoice:** Call `Bolt11ReceiveForHash` with a payment hash you control. |
| 222 | +2. **Wait for payment:** Subscribe to events via `SubscribeEvents` and watch for a |
| 223 | + `PaymentClaimable` event matching your payment hash. |
| 224 | +3. **Decide:** |
| 225 | + - **Accept:** Call `Bolt11ClaimForHash` with the preimage corresponding to the payment hash. |
| 226 | + - **Reject:** Call `Bolt11FailForHash` with the payment hash. |
| 227 | + |
| 228 | +The payment is held in a pending state until you explicitly claim or fail it. **You must |
| 229 | +always call one of these.** If you do neither, the HTLC will eventually time out, which |
| 230 | +can cause a force-closure of the channel. |
| 231 | + |
| 232 | +## Pagination |
| 233 | + |
| 234 | +`ListPayments` and `ListForwardedPayments` support cursor-based pagination: |
| 235 | + |
| 236 | +1. Make the first request with your desired `number_of_payments` page size. |
| 237 | +2. If the response includes a `next_page_token`, pass it as `page_token` in the next request. |
| 238 | +3. When `next_page_token` is absent, you have reached the end of the results. |
| 239 | + |
| 240 | +Results are ordered by creation time (most recent first). |
0 commit comments