beignet 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +306 -1
- package/dist/cli/auth.js +238 -0
- package/dist/cli/auth.js.map +1 -0
- package/dist/cli/beignet-node.js +1034 -57
- package/dist/cli/beignet-node.js.map +1 -1
- package/dist/cli/cli.js +1257 -18
- package/dist/cli/cli.js.map +1 -1
- package/dist/cli/config.js +45 -1
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/daemon.js +398 -38
- package/dist/cli/daemon.js.map +1 -1
- package/dist/cli/errors.js +2 -0
- package/dist/cli/errors.js.map +1 -1
- package/dist/cli/index.js +6 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/openapi.js +1343 -89
- package/dist/cli/openapi.js.map +1 -1
- package/dist/cli/restore.js +89 -0
- package/dist/cli/restore.js.map +1 -0
- package/dist/cli/wallet-storage.js +34 -0
- package/dist/cli/wallet-storage.js.map +1 -0
- package/dist/electrum/index.js +107 -12
- package/dist/electrum/index.js.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/lightning/advisor/fee-tuner.js +42 -0
- package/dist/lightning/advisor/fee-tuner.js.map +1 -0
- package/dist/lightning/advisor/index.js +9 -1
- package/dist/lightning/advisor/index.js.map +1 -1
- package/dist/lightning/advisor/rebalance-planner.js +55 -0
- package/dist/lightning/advisor/rebalance-planner.js.map +1 -0
- package/dist/lightning/backup/index.js +18 -0
- package/dist/lightning/backup/index.js.map +1 -0
- package/dist/lightning/backup/scb.js +42 -0
- package/dist/lightning/backup/scb.js.map +1 -0
- package/dist/lightning/chain/chain-monitor.js +27 -0
- package/dist/lightning/chain/chain-monitor.js.map +1 -1
- package/dist/lightning/chain/output-resolver.js +66 -15
- package/dist/lightning/chain/output-resolver.js.map +1 -1
- package/dist/lightning/chain/types.js +1 -0
- package/dist/lightning/chain/types.js.map +1 -1
- package/dist/lightning/channel/channel-manager.js +91 -24
- package/dist/lightning/channel/channel-manager.js.map +1 -1
- package/dist/lightning/channel/channel-state.js.map +1 -1
- package/dist/lightning/channel/channel.js +122 -4
- package/dist/lightning/channel/channel.js.map +1 -1
- package/dist/lightning/channel/commitment-builder.js +4 -7
- package/dist/lightning/channel/commitment-builder.js.map +1 -1
- package/dist/lightning/channel/dual-funding.js +6 -5
- package/dist/lightning/channel/dual-funding.js.map +1 -1
- package/dist/lightning/channel/splice-tx.js.map +1 -1
- package/dist/lightning/channel/types.js +3 -1
- package/dist/lightning/channel/types.js.map +1 -1
- package/dist/lightning/channel/validation.js +3 -3
- package/dist/lightning/channel/validation.js.map +1 -1
- package/dist/lightning/crypto/index.js +1 -0
- package/dist/lightning/crypto/index.js.map +1 -1
- package/dist/lightning/crypto/message-signing.js +116 -0
- package/dist/lightning/crypto/message-signing.js.map +1 -0
- package/dist/lightning/crypto/xchacha20poly1305.js +77 -0
- package/dist/lightning/crypto/xchacha20poly1305.js.map +1 -0
- package/dist/lightning/features/flags.js +1 -0
- package/dist/lightning/features/flags.js.map +1 -1
- package/dist/lightning/gossip/messages.js +37 -1
- package/dist/lightning/gossip/messages.js.map +1 -1
- package/dist/lightning/index.js +2 -1
- package/dist/lightning/index.js.map +1 -1
- package/dist/lightning/keys/signer.js +24 -3
- package/dist/lightning/keys/signer.js.map +1 -1
- package/dist/lightning/keys/wallet-keys.js +1 -0
- package/dist/lightning/keys/wallet-keys.js.map +1 -1
- package/dist/lightning/message/index.js +1 -0
- package/dist/lightning/message/index.js.map +1 -1
- package/dist/lightning/message/peer-storage.js +43 -0
- package/dist/lightning/message/peer-storage.js.map +1 -0
- package/dist/lightning/message/types.js +2 -0
- package/dist/lightning/message/types.js.map +1 -1
- package/dist/lightning/node/lightning-node.js +1593 -236
- package/dist/lightning/node/lightning-node.js.map +1 -1
- package/dist/lightning/node/types.js +18 -1
- package/dist/lightning/node/types.js.map +1 -1
- package/dist/lightning/offer/offer-manager.js +2 -5
- package/dist/lightning/offer/offer-manager.js.map +1 -1
- package/dist/lightning/offer/tlv.js +3 -1
- package/dist/lightning/offer/tlv.js.map +1 -1
- package/dist/lightning/storage/encryption.js +67 -0
- package/dist/lightning/storage/encryption.js.map +1 -0
- package/dist/lightning/storage/index.js +1 -0
- package/dist/lightning/storage/index.js.map +1 -1
- package/dist/lightning/storage/serialization.js +6 -2
- package/dist/lightning/storage/serialization.js.map +1 -1
- package/dist/lightning/storage/sqlite-storage.js +405 -33
- package/dist/lightning/storage/sqlite-storage.js.map +1 -1
- package/dist/lightning/watchtower/blob.js +221 -0
- package/dist/lightning/watchtower/blob.js.map +1 -0
- package/dist/lightning/watchtower/index.js +55 -0
- package/dist/lightning/watchtower/index.js.map +1 -0
- package/dist/lightning/watchtower/justice.js +272 -0
- package/dist/lightning/watchtower/justice.js.map +1 -0
- package/dist/lightning/watchtower/tower-connection.js +208 -0
- package/dist/lightning/watchtower/tower-connection.js.map +1 -0
- package/dist/lightning/watchtower/types.js +3 -0
- package/dist/lightning/watchtower/types.js.map +1 -0
- package/dist/lightning/watchtower/watchtower-client.js +472 -0
- package/dist/lightning/watchtower/watchtower-client.js.map +1 -0
- package/dist/lightning/watchtower/wtwire.js +201 -0
- package/dist/lightning/watchtower/wtwire.js.map +1 -0
- package/dist/logger.js +41 -0
- package/dist/logger.js.map +1 -0
- package/dist/shapes/electrum.js +32 -1
- package/dist/shapes/electrum.js.map +1 -1
- package/dist/shapes/wallet.js +11 -1
- package/dist/shapes/wallet.js.map +1 -1
- package/dist/transaction/index.js +163 -15
- package/dist/transaction/index.js.map +1 -1
- package/dist/types/cli/auth.d.ts +34 -0
- package/dist/types/cli/beignet-node.d.ts +148 -4
- package/dist/types/cli/daemon.d.ts +5 -0
- package/dist/types/cli/errors.d.ts +2 -0
- package/dist/types/cli/index.d.ts +1 -0
- package/dist/types/cli/restore.d.ts +10 -0
- package/dist/types/cli/types.d.ts +235 -1
- package/dist/types/cli/wallet-storage.d.ts +3 -0
- package/dist/types/electrum/index.d.ts +12 -0
- package/dist/types/electrum.js +1 -0
- package/dist/types/electrum.js.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/lightning/advisor/fee-tuner.d.ts +20 -0
- package/dist/types/lightning/advisor/index.d.ts +4 -0
- package/dist/types/lightning/advisor/rebalance-planner.d.ts +12 -0
- package/dist/types/lightning/backup/index.d.ts +1 -0
- package/dist/types/lightning/backup/scb.d.ts +24 -0
- package/dist/types/lightning/chain/chain-monitor.d.ts +1 -0
- package/dist/types/lightning/chain/types.d.ts +1 -0
- package/dist/types/lightning/channel/channel-manager.d.ts +11 -0
- package/dist/types/lightning/channel/channel-state.d.ts +2 -0
- package/dist/types/lightning/channel/channel.d.ts +11 -5
- package/dist/types/lightning/channel/commitment-builder.d.ts +7 -7
- package/dist/types/lightning/channel/dual-funding.d.ts +2 -1
- package/dist/types/lightning/channel/splice-tx.d.ts +2 -2
- package/dist/types/lightning/channel/types.d.ts +2 -0
- package/dist/types/lightning/channel/validation.d.ts +1 -1
- package/dist/types/lightning/crypto/index.d.ts +1 -0
- package/dist/types/lightning/crypto/message-signing.d.ts +9 -0
- package/dist/types/lightning/crypto/xchacha20poly1305.d.ts +3 -0
- package/dist/types/lightning/features/flags.d.ts +1 -0
- package/dist/types/lightning/gossip/messages.d.ts +4 -0
- package/dist/types/lightning/index.d.ts +1 -0
- package/dist/types/lightning/keys/signer.d.ts +18 -1
- package/dist/types/lightning/keys/wallet-keys.d.ts +2 -1
- package/dist/types/lightning/message/index.d.ts +1 -0
- package/dist/types/lightning/message/peer-storage.d.ts +9 -0
- package/dist/types/lightning/message/types.d.ts +2 -0
- package/dist/types/lightning/node/lightning-node.d.ts +120 -4
- package/dist/types/lightning/node/types.d.ts +66 -1
- package/dist/types/lightning/storage/encryption.d.ts +11 -0
- package/dist/types/lightning/storage/index.d.ts +1 -0
- package/dist/types/lightning/storage/serialization.d.ts +2 -0
- package/dist/types/lightning/storage/sqlite-storage.d.ts +43 -3
- package/dist/types/lightning/storage/types.d.ts +62 -0
- package/dist/types/lightning/watchtower/blob.d.ts +46 -0
- package/dist/types/lightning/watchtower/index.d.ts +9 -0
- package/dist/types/lightning/watchtower/justice.d.ts +30 -0
- package/dist/types/lightning/watchtower/tower-connection.d.ts +34 -0
- package/dist/types/lightning/watchtower/types.d.ts +46 -0
- package/dist/types/lightning/watchtower/watchtower-client.d.ts +68 -0
- package/dist/types/lightning/watchtower/wtwire.d.ts +90 -0
- package/dist/types/logger.d.ts +17 -0
- package/dist/types/shapes/electrum.d.ts +3 -1
- package/dist/types/transaction/index.d.ts +6 -0
- package/dist/types/transaction.js.map +1 -1
- package/dist/types/types/electrum.d.ts +3 -2
- package/dist/types/types/transaction.d.ts +1 -1
- package/dist/types/types/wallet.d.ts +80 -4
- package/dist/types/utils/descriptors.d.ts +2 -0
- package/dist/types/utils/fees.d.ts +3 -0
- package/dist/types/utils/helpers.d.ts +3 -1
- package/dist/types/utils/index.d.ts +5 -0
- package/dist/types/utils/multisig.d.ts +29 -0
- package/dist/types/utils/transaction.d.ts +7 -0
- package/dist/types/utils/wallet-storage-encryption.d.ts +3 -0
- package/dist/types/utils/wallet.d.ts +1 -1
- package/dist/types/utils/watch-only.d.ts +12 -0
- package/dist/types/wallet/constants.d.ts +1 -0
- package/dist/types/wallet/index.d.ts +63 -4
- package/dist/types/wallet.js +3 -0
- package/dist/types/wallet.js.map +1 -1
- package/dist/utils/derivation-path.js +8 -7
- package/dist/utils/derivation-path.js.map +1 -1
- package/dist/utils/descriptors.js +56 -0
- package/dist/utils/descriptors.js.map +1 -0
- package/dist/utils/electrum.js +14 -4
- package/dist/utils/electrum.js.map +1 -1
- package/dist/utils/fees.js +19 -0
- package/dist/utils/fees.js.map +1 -0
- package/dist/utils/helpers.js +22 -5
- package/dist/utils/helpers.js.map +1 -1
- package/dist/utils/index.js +5 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/multisig.js +90 -0
- package/dist/utils/multisig.js.map +1 -0
- package/dist/utils/transaction.js +30 -3
- package/dist/utils/transaction.js.map +1 -1
- package/dist/utils/wallet-storage-encryption.js +45 -0
- package/dist/utils/wallet-storage-encryption.js.map +1 -0
- package/dist/utils/wallet.js +3 -1
- package/dist/utils/wallet.js.map +1 -1
- package/dist/utils/watch-only.js +102 -0
- package/dist/utils/watch-only.js.map +1 -0
- package/dist/wallet/constants.js +2 -1
- package/dist/wallet/constants.js.map +1 -1
- package/dist/wallet/index.js +810 -51
- package/dist/wallet/index.js.map +1 -1
- package/docs/ROADMAP.md +365 -0
- package/package.json +1 -1
package/dist/cli/openapi.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getOpenApiSpec = void 0;
|
|
4
|
+
const auth_1 = require("./auth");
|
|
4
5
|
function getOpenApiSpec() {
|
|
5
|
-
|
|
6
|
+
const spec = {
|
|
6
7
|
openapi: '3.0.3',
|
|
7
8
|
info: {
|
|
8
9
|
title: 'Beignet Lightning API',
|
|
@@ -12,6 +13,7 @@ function getOpenApiSpec() {
|
|
|
12
13
|
'When provided, the response is cached for 24 hours — repeated requests with the same key and body return the cached response. ' +
|
|
13
14
|
'If the same key is reused with a different request body, a `409 IDEMPOTENCY_CONFLICT` error is returned.\n\n' +
|
|
14
15
|
'**TLS:** The daemon supports HTTPS when started with `--tls-cert` and `--tls-key` flags (or `BEIGNET_TLS_CERT`/`BEIGNET_TLS_KEY` env vars).\n\n' +
|
|
16
|
+
'**Scoped API keys:** Besides the legacy single `apiToken` (implicit admin scope), the `apiKeys` config defines named keys with `readonly`, `invoice`, and/or `admin` scopes. Each operation lists the scopes it accepts in `x-accepted-scopes`; unclassified routes are admin-only. Requests fail with 401 (bad/absent key) or 403 (valid key, insufficient scope).\n\n' +
|
|
15
17
|
'**Spending Limits:** Configure `dailySpendLimitSats` (or `BEIGNET_DAILY_SPEND_LIMIT_SATS` env var) to enforce a daily budget. Query `GET /spend-limit` for current usage.\n\n' +
|
|
16
18
|
'**Drain Mode:** `POST /stop` accepts `{ "drain": true }` to stop accepting new payments and wait for in-flight ones to settle before shutdown.'
|
|
17
19
|
},
|
|
@@ -160,6 +162,101 @@ function getOpenApiSpec() {
|
|
|
160
162
|
}
|
|
161
163
|
}
|
|
162
164
|
},
|
|
165
|
+
'/forwards': {
|
|
166
|
+
get: {
|
|
167
|
+
summary: 'List settled forwards (fees earned), newest first',
|
|
168
|
+
tags: ['Payments'],
|
|
169
|
+
parameters: [
|
|
170
|
+
{
|
|
171
|
+
name: 'since',
|
|
172
|
+
in: 'query',
|
|
173
|
+
schema: { type: 'integer' },
|
|
174
|
+
description: 'Only events settled at/after this ms timestamp'
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
name: 'until',
|
|
178
|
+
in: 'query',
|
|
179
|
+
schema: { type: 'integer' },
|
|
180
|
+
description: 'Only events settled at/before this ms timestamp'
|
|
181
|
+
},
|
|
182
|
+
{ name: 'limit', in: 'query', schema: { type: 'integer' } },
|
|
183
|
+
{ name: 'offset', in: 'query', schema: { type: 'integer' } },
|
|
184
|
+
{
|
|
185
|
+
name: 'channelId',
|
|
186
|
+
in: 'query',
|
|
187
|
+
schema: { type: 'string' },
|
|
188
|
+
description: 'Match the inbound OR outbound leg'
|
|
189
|
+
}
|
|
190
|
+
],
|
|
191
|
+
responses: {
|
|
192
|
+
'200': {
|
|
193
|
+
description: 'Forwarding events (msat values as strings)',
|
|
194
|
+
content: jsonContent({
|
|
195
|
+
type: 'array',
|
|
196
|
+
items: { $ref: '#/components/schemas/ForwardingEvent' }
|
|
197
|
+
})
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
'/forwards/summary': {
|
|
203
|
+
get: {
|
|
204
|
+
summary: 'Forwarding totals: count, volume out, fees earned',
|
|
205
|
+
tags: ['Payments'],
|
|
206
|
+
parameters: [
|
|
207
|
+
{
|
|
208
|
+
name: 'since',
|
|
209
|
+
in: 'query',
|
|
210
|
+
schema: { type: 'integer' },
|
|
211
|
+
description: 'Only events settled at/after this ms timestamp'
|
|
212
|
+
}
|
|
213
|
+
],
|
|
214
|
+
responses: {
|
|
215
|
+
'200': {
|
|
216
|
+
description: 'Forwarding summary (msat values as strings)',
|
|
217
|
+
content: jsonContent({
|
|
218
|
+
$ref: '#/components/schemas/ForwardingSummary'
|
|
219
|
+
})
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
'/watchtowers': {
|
|
225
|
+
get: {
|
|
226
|
+
summary: 'List configured watchtowers with per-tower session + backlog health',
|
|
227
|
+
tags: ['Node'],
|
|
228
|
+
responses: {
|
|
229
|
+
'200': {
|
|
230
|
+
description: 'Watchtower health',
|
|
231
|
+
content: jsonContent({
|
|
232
|
+
type: 'object',
|
|
233
|
+
properties: {
|
|
234
|
+
towers: {
|
|
235
|
+
type: 'array',
|
|
236
|
+
items: { $ref: '#/components/schemas/WatchtowerInfo' }
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
})
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
'/watchtower/add': {
|
|
245
|
+
post: {
|
|
246
|
+
summary: 'Add a watchtower (pubkey@host:port, LND altruist tower)',
|
|
247
|
+
tags: ['Node'],
|
|
248
|
+
requestBody: bodyContent({ uri: 'string' }),
|
|
249
|
+
responses: { '200': { description: 'Tower added' } }
|
|
250
|
+
}
|
|
251
|
+
},
|
|
252
|
+
'/watchtower/remove': {
|
|
253
|
+
delete: {
|
|
254
|
+
summary: 'Remove a watchtower and drop its sessions + backlog',
|
|
255
|
+
tags: ['Node'],
|
|
256
|
+
requestBody: bodyContent({ uri: 'string' }),
|
|
257
|
+
responses: { '200': { description: 'Tower removed' } }
|
|
258
|
+
}
|
|
259
|
+
},
|
|
163
260
|
'/invoices': {
|
|
164
261
|
get: {
|
|
165
262
|
summary: 'List created invoices',
|
|
@@ -193,6 +290,75 @@ function getOpenApiSpec() {
|
|
|
193
290
|
}
|
|
194
291
|
}
|
|
195
292
|
},
|
|
293
|
+
'/invoice/create-hold': {
|
|
294
|
+
post: {
|
|
295
|
+
summary: 'Create a hold invoice for a caller-supplied payment hash (preimage stays with the caller; the incoming HTLC parks until settle/cancel)',
|
|
296
|
+
tags: ['Invoices'],
|
|
297
|
+
requestBody: bodyContent({
|
|
298
|
+
paymentHash: 'string',
|
|
299
|
+
amountMsat: 'string?',
|
|
300
|
+
amountSats: 'number?',
|
|
301
|
+
description: 'string?',
|
|
302
|
+
expiry: 'number?'
|
|
303
|
+
}),
|
|
304
|
+
responses: {
|
|
305
|
+
'200': {
|
|
306
|
+
description: 'Created hold invoice',
|
|
307
|
+
content: jsonContent({ $ref: '#/components/schemas/InvoiceInfo' })
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
},
|
|
312
|
+
'/invoice/settle-hold': {
|
|
313
|
+
post: {
|
|
314
|
+
summary: 'Settle a hold invoice with its preimage: validates sha256(preimage) and fulfills every parked HTLC (all MPP parts)',
|
|
315
|
+
tags: ['Invoices'],
|
|
316
|
+
requestBody: bodyContent({ preimage: 'string' }),
|
|
317
|
+
responses: {
|
|
318
|
+
'200': {
|
|
319
|
+
description: 'Settled',
|
|
320
|
+
content: jsonContent({
|
|
321
|
+
type: 'object',
|
|
322
|
+
properties: { paymentHash: { type: 'string' } }
|
|
323
|
+
})
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
'/invoice/cancel-hold': {
|
|
329
|
+
post: {
|
|
330
|
+
summary: 'Cancel a hold invoice: fails parked HTLCs back with incorrect_or_unknown_payment_details and rejects future ones',
|
|
331
|
+
tags: ['Invoices'],
|
|
332
|
+
requestBody: bodyContent({ paymentHash: 'string' }),
|
|
333
|
+
responses: {
|
|
334
|
+
'200': {
|
|
335
|
+
description: 'Cancelled',
|
|
336
|
+
content: jsonContent({
|
|
337
|
+
type: 'object',
|
|
338
|
+
properties: {
|
|
339
|
+
paymentHash: { type: 'string' },
|
|
340
|
+
htlcsFailed: { type: 'integer' }
|
|
341
|
+
}
|
|
342
|
+
})
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
},
|
|
347
|
+
'/invoices/held': {
|
|
348
|
+
get: {
|
|
349
|
+
summary: 'List hold invoices with lifecycle state and parked totals',
|
|
350
|
+
tags: ['Invoices'],
|
|
351
|
+
responses: {
|
|
352
|
+
'200': {
|
|
353
|
+
description: 'Hold invoices',
|
|
354
|
+
content: jsonContent({
|
|
355
|
+
type: 'array',
|
|
356
|
+
items: { $ref: '#/components/schemas/HoldInvoiceInfo' }
|
|
357
|
+
})
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
},
|
|
196
362
|
'/invoice': {
|
|
197
363
|
get: {
|
|
198
364
|
summary: 'Get a specific invoice by payment hash',
|
|
@@ -370,15 +536,81 @@ function getOpenApiSpec() {
|
|
|
370
536
|
}
|
|
371
537
|
}
|
|
372
538
|
},
|
|
539
|
+
'/channel/update-commitment-feerate': {
|
|
540
|
+
post: {
|
|
541
|
+
summary: 'Update the channel commitment transaction feerate (BOLT 2 update_fee). Not the routing fee policy.',
|
|
542
|
+
tags: ['Channels'],
|
|
543
|
+
requestBody: bodyContent({
|
|
544
|
+
channelId: 'string',
|
|
545
|
+
feeratePerKw: 'number'
|
|
546
|
+
}),
|
|
547
|
+
responses: { '200': { description: 'Commitment feerate updated' } }
|
|
548
|
+
}
|
|
549
|
+
},
|
|
373
550
|
'/channel/update-fee': {
|
|
374
551
|
post: {
|
|
375
|
-
summary: '
|
|
552
|
+
summary: 'Deprecated alias for /channel/update-commitment-feerate. Sets the commitment feerate, not the routing fee policy.',
|
|
553
|
+
deprecated: true,
|
|
376
554
|
tags: ['Channels'],
|
|
377
555
|
requestBody: bodyContent({
|
|
378
556
|
channelId: 'string',
|
|
379
557
|
feeratePerKw: 'number'
|
|
380
558
|
}),
|
|
381
|
-
responses: { '200': { description: '
|
|
559
|
+
responses: { '200': { description: 'Commitment feerate updated' } }
|
|
560
|
+
}
|
|
561
|
+
},
|
|
562
|
+
'/channel/update-policy': {
|
|
563
|
+
post: {
|
|
564
|
+
summary: 'Set the ROUTING fee policy for one channel (channelId) or all channels (all: true); regenerates and re-broadcasts the channel_update. Msat fields accept number or decimal string.',
|
|
565
|
+
tags: ['Channels'],
|
|
566
|
+
requestBody: bodyContent({
|
|
567
|
+
channelId: 'string?',
|
|
568
|
+
all: 'boolean?',
|
|
569
|
+
feeBaseMsat: 'number?',
|
|
570
|
+
feeProportionalMillionths: 'number?',
|
|
571
|
+
cltvExpiryDelta: 'number?',
|
|
572
|
+
htlcMinimumMsat: 'string?',
|
|
573
|
+
htlcMaximumMsat: 'string?'
|
|
574
|
+
}),
|
|
575
|
+
responses: {
|
|
576
|
+
'200': {
|
|
577
|
+
description: 'Updated count + effective policies',
|
|
578
|
+
content: jsonContent({
|
|
579
|
+
type: 'object',
|
|
580
|
+
properties: {
|
|
581
|
+
updated: { type: 'integer' },
|
|
582
|
+
policies: {
|
|
583
|
+
type: 'array',
|
|
584
|
+
items: { $ref: '#/components/schemas/ChannelPolicy' }
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
})
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
},
|
|
592
|
+
'/channel/policy': {
|
|
593
|
+
get: {
|
|
594
|
+
summary: 'Get the effective routing fee policy for a channel (override or node defaults)',
|
|
595
|
+
tags: ['Channels'],
|
|
596
|
+
parameters: [
|
|
597
|
+
{
|
|
598
|
+
name: 'channelId',
|
|
599
|
+
in: 'query',
|
|
600
|
+
required: true,
|
|
601
|
+
schema: { type: 'string' }
|
|
602
|
+
}
|
|
603
|
+
],
|
|
604
|
+
responses: {
|
|
605
|
+
'200': {
|
|
606
|
+
description: 'Effective channel policy',
|
|
607
|
+
content: jsonContent({
|
|
608
|
+
$ref: '#/components/schemas/ChannelPolicy'
|
|
609
|
+
})
|
|
610
|
+
},
|
|
611
|
+
'400': { description: 'Missing channelId' },
|
|
612
|
+
'404': { description: 'Channel not found' }
|
|
613
|
+
}
|
|
382
614
|
}
|
|
383
615
|
},
|
|
384
616
|
'/channels/ensure-minimum': {
|
|
@@ -466,12 +698,12 @@ function getOpenApiSpec() {
|
|
|
466
698
|
},
|
|
467
699
|
'/peer/connect': {
|
|
468
700
|
post: {
|
|
469
|
-
summary: 'Connect to a peer',
|
|
701
|
+
summary: 'Connect to a peer (omit host+port to resolve the address from the gossip graph / DNS bootstrap)',
|
|
470
702
|
tags: ['Peers'],
|
|
471
703
|
requestBody: bodyContent({
|
|
472
704
|
pubkey: 'string',
|
|
473
|
-
host: 'string',
|
|
474
|
-
port: 'number'
|
|
705
|
+
host: 'string?',
|
|
706
|
+
port: 'number?'
|
|
475
707
|
}),
|
|
476
708
|
responses: {
|
|
477
709
|
'200': {
|
|
@@ -725,96 +957,614 @@ function getOpenApiSpec() {
|
|
|
725
957
|
responses: { '200': { description: 'Probe result' } }
|
|
726
958
|
}
|
|
727
959
|
},
|
|
728
|
-
'/
|
|
729
|
-
post: {
|
|
730
|
-
summary: 'Create database backup',
|
|
731
|
-
tags: ['Node'],
|
|
732
|
-
requestBody: bodyContent({ destPath: 'string' }),
|
|
733
|
-
responses: { '200': { description: 'Backup result' } }
|
|
734
|
-
}
|
|
735
|
-
},
|
|
736
|
-
'/send': {
|
|
737
|
-
post: {
|
|
738
|
-
summary: 'Send on-chain Bitcoin',
|
|
739
|
-
tags: ['Node'],
|
|
740
|
-
requestBody: bodyContent({
|
|
741
|
-
address: 'string',
|
|
742
|
-
amountSats: 'number',
|
|
743
|
-
satsPerVbyte: 'number?'
|
|
744
|
-
}),
|
|
745
|
-
responses: { '200': { description: 'Transaction info' } }
|
|
746
|
-
}
|
|
747
|
-
},
|
|
748
|
-
'/readiness': {
|
|
960
|
+
'/graph/info': {
|
|
749
961
|
get: {
|
|
750
|
-
summary: '
|
|
751
|
-
tags: ['
|
|
962
|
+
summary: 'Network graph summary (node/channel counts, last sync)',
|
|
963
|
+
tags: ['Graph'],
|
|
752
964
|
responses: {
|
|
753
965
|
'200': {
|
|
754
|
-
description: '
|
|
755
|
-
content: jsonContent({
|
|
756
|
-
$ref: '#/components/schemas/ReadinessReport'
|
|
757
|
-
})
|
|
966
|
+
description: 'Graph summary',
|
|
967
|
+
content: jsonContent({ $ref: '#/components/schemas/GraphInfo' })
|
|
758
968
|
}
|
|
759
969
|
}
|
|
760
970
|
}
|
|
761
971
|
},
|
|
762
|
-
'/
|
|
972
|
+
'/graph/node': {
|
|
763
973
|
get: {
|
|
764
|
-
summary: '
|
|
765
|
-
tags: ['
|
|
974
|
+
summary: 'Node announcement info (alias, addresses, features) + its known channels',
|
|
975
|
+
tags: ['Graph'],
|
|
766
976
|
parameters: [
|
|
767
977
|
{
|
|
768
|
-
name: '
|
|
978
|
+
name: 'pubkey',
|
|
769
979
|
in: 'query',
|
|
770
|
-
|
|
771
|
-
|
|
980
|
+
required: true,
|
|
981
|
+
schema: { type: 'string' },
|
|
982
|
+
description: '33-byte node public key (hex)'
|
|
772
983
|
}
|
|
773
984
|
],
|
|
774
985
|
responses: {
|
|
775
986
|
'200': {
|
|
776
|
-
description: '
|
|
777
|
-
content: jsonContent({
|
|
778
|
-
|
|
987
|
+
description: 'Graph node info',
|
|
988
|
+
content: jsonContent({
|
|
989
|
+
$ref: '#/components/schemas/GraphNodeInfo'
|
|
990
|
+
})
|
|
991
|
+
},
|
|
992
|
+
'404': { description: 'Node not found in graph' }
|
|
779
993
|
}
|
|
780
994
|
}
|
|
781
995
|
},
|
|
782
|
-
'/
|
|
996
|
+
'/graph/channel': {
|
|
783
997
|
get: {
|
|
784
|
-
summary: '
|
|
785
|
-
tags: ['
|
|
998
|
+
summary: 'Channel info from gossip: endpoints, capacity and both directions of routing policy',
|
|
999
|
+
tags: ['Graph'],
|
|
1000
|
+
parameters: [
|
|
1001
|
+
{
|
|
1002
|
+
name: 'scid',
|
|
1003
|
+
in: 'query',
|
|
1004
|
+
required: true,
|
|
1005
|
+
schema: { type: 'string' },
|
|
1006
|
+
description: 'Short channel id as <block>x<txIndex>x<output> or 16-char hex'
|
|
1007
|
+
}
|
|
1008
|
+
],
|
|
786
1009
|
responses: {
|
|
787
1010
|
'200': {
|
|
788
|
-
description: '
|
|
1011
|
+
description: 'Graph channel info',
|
|
789
1012
|
content: jsonContent({
|
|
790
|
-
$ref: '#/components/schemas/
|
|
1013
|
+
$ref: '#/components/schemas/GraphChannelInfo'
|
|
791
1014
|
})
|
|
792
|
-
}
|
|
1015
|
+
},
|
|
1016
|
+
'404': { description: 'Channel not found in graph' }
|
|
793
1017
|
}
|
|
794
1018
|
}
|
|
795
1019
|
},
|
|
796
|
-
'/
|
|
1020
|
+
'/graph/describe': {
|
|
797
1021
|
get: {
|
|
798
|
-
summary: '
|
|
799
|
-
tags: ['
|
|
1022
|
+
summary: 'Paged dump of known graph channels (limit defaults to 500 and is capped at 500)',
|
|
1023
|
+
tags: ['Graph'],
|
|
1024
|
+
parameters: [
|
|
1025
|
+
{ name: 'limit', in: 'query', schema: { type: 'integer' } },
|
|
1026
|
+
{ name: 'offset', in: 'query', schema: { type: 'integer' } }
|
|
1027
|
+
],
|
|
800
1028
|
responses: {
|
|
801
1029
|
'200': {
|
|
802
|
-
description: '
|
|
803
|
-
content: jsonContent({
|
|
804
|
-
|
|
805
|
-
|
|
1030
|
+
description: 'Paged channel dump with totalChannels/limit/offset',
|
|
1031
|
+
content: jsonContent({
|
|
1032
|
+
type: 'object',
|
|
1033
|
+
properties: {
|
|
1034
|
+
totalChannels: { type: 'integer' },
|
|
1035
|
+
limit: { type: 'integer' },
|
|
1036
|
+
offset: { type: 'integer' },
|
|
1037
|
+
channels: {
|
|
1038
|
+
type: 'array',
|
|
1039
|
+
items: { $ref: '#/components/schemas/GraphChannelInfo' }
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
})
|
|
1043
|
+
}
|
|
806
1044
|
}
|
|
807
1045
|
}
|
|
808
1046
|
},
|
|
809
|
-
'/
|
|
810
|
-
|
|
811
|
-
summary: '
|
|
812
|
-
tags: ['
|
|
1047
|
+
'/route/query': {
|
|
1048
|
+
post: {
|
|
1049
|
+
summary: 'Compute a route to a destination WITHOUT sending; hops feed /payment/send-to-route',
|
|
1050
|
+
tags: ['Routing'],
|
|
1051
|
+
requestBody: bodyContent({
|
|
1052
|
+
destination: 'string',
|
|
1053
|
+
amountSats: 'number',
|
|
1054
|
+
maxFeeSats: 'number?'
|
|
1055
|
+
}),
|
|
813
1056
|
responses: {
|
|
814
1057
|
'200': {
|
|
815
|
-
description: '
|
|
816
|
-
content: jsonContent({
|
|
817
|
-
|
|
1058
|
+
description: 'Route with per-hop fees and totals',
|
|
1059
|
+
content: jsonContent({
|
|
1060
|
+
$ref: '#/components/schemas/RouteQueryResult'
|
|
1061
|
+
})
|
|
1062
|
+
},
|
|
1063
|
+
'400': { description: 'No route or fee exceeds maximum' }
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
},
|
|
1067
|
+
'/payment/send-to-route': {
|
|
1068
|
+
post: {
|
|
1069
|
+
summary: 'Send a payment along an explicit route (hops from POST /route/query)',
|
|
1070
|
+
tags: ['Payments'],
|
|
1071
|
+
requestBody: {
|
|
1072
|
+
content: {
|
|
1073
|
+
'application/json': {
|
|
1074
|
+
schema: {
|
|
1075
|
+
type: 'object',
|
|
1076
|
+
properties: {
|
|
1077
|
+
paymentHash: { type: 'string' },
|
|
1078
|
+
route: {
|
|
1079
|
+
type: 'object',
|
|
1080
|
+
properties: {
|
|
1081
|
+
hops: {
|
|
1082
|
+
type: 'array',
|
|
1083
|
+
items: { $ref: '#/components/schemas/RouteHop' }
|
|
1084
|
+
}
|
|
1085
|
+
},
|
|
1086
|
+
required: ['hops']
|
|
1087
|
+
},
|
|
1088
|
+
paymentSecret: {
|
|
1089
|
+
type: 'string',
|
|
1090
|
+
description: 'Invoice payment_secret (required by most modern invoices)'
|
|
1091
|
+
}
|
|
1092
|
+
},
|
|
1093
|
+
required: ['paymentHash', 'route']
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
},
|
|
1098
|
+
responses: {
|
|
1099
|
+
'200': {
|
|
1100
|
+
description: 'Payment info',
|
|
1101
|
+
content: jsonContent({
|
|
1102
|
+
$ref: '#/components/schemas/PaymentInfo'
|
|
1103
|
+
})
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
},
|
|
1108
|
+
'/message/sign': {
|
|
1109
|
+
post: {
|
|
1110
|
+
summary: "Sign a message with the node identity key (LND-compatible: double-SHA256 of 'Lightning Signed Message:' + message, compact recoverable ECDSA, zbase32)",
|
|
1111
|
+
tags: ['Node'],
|
|
1112
|
+
requestBody: bodyContent({ message: 'string' }),
|
|
1113
|
+
responses: {
|
|
1114
|
+
'200': {
|
|
1115
|
+
description: 'Signature (zbase32) and our node pubkey',
|
|
1116
|
+
content: jsonContent({
|
|
1117
|
+
type: 'object',
|
|
1118
|
+
properties: {
|
|
1119
|
+
signature: { type: 'string' },
|
|
1120
|
+
pubkey: { type: 'string' }
|
|
1121
|
+
}
|
|
1122
|
+
})
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
},
|
|
1127
|
+
'/message/verify': {
|
|
1128
|
+
post: {
|
|
1129
|
+
summary: 'Verify an LND-style message signature: recovers the signer pubkey and reports whether it is a known graph node. Compare pubkey against the expected signer.',
|
|
1130
|
+
tags: ['Node'],
|
|
1131
|
+
requestBody: bodyContent({ message: 'string', signature: 'string' }),
|
|
1132
|
+
responses: {
|
|
1133
|
+
'200': {
|
|
1134
|
+
description: 'Verification result',
|
|
1135
|
+
content: jsonContent({
|
|
1136
|
+
type: 'object',
|
|
1137
|
+
properties: {
|
|
1138
|
+
valid: { type: 'boolean' },
|
|
1139
|
+
pubkey: { type: 'string', nullable: true },
|
|
1140
|
+
knownNode: { type: 'boolean' }
|
|
1141
|
+
}
|
|
1142
|
+
})
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
},
|
|
1147
|
+
'/gossip/sync': {
|
|
1148
|
+
post: {
|
|
1149
|
+
summary: 'Request a gossip graph sync from one peer (pubkey) or all connected peers',
|
|
1150
|
+
tags: ['Graph'],
|
|
1151
|
+
requestBody: bodyContent({ pubkey: 'string?' }),
|
|
1152
|
+
responses: {
|
|
1153
|
+
'200': {
|
|
1154
|
+
description: 'Pubkeys a sync was initiated with',
|
|
1155
|
+
content: jsonContent({
|
|
1156
|
+
type: 'object',
|
|
1157
|
+
properties: {
|
|
1158
|
+
syncedFrom: {
|
|
1159
|
+
type: 'array',
|
|
1160
|
+
items: { type: 'string' }
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
})
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
},
|
|
1168
|
+
'/gossip/sync-rapid': {
|
|
1169
|
+
post: {
|
|
1170
|
+
summary: 'Download and apply a Rapid Gossip Sync snapshot (mainnet only)',
|
|
1171
|
+
tags: ['Graph'],
|
|
1172
|
+
responses: {
|
|
1173
|
+
'200': {
|
|
1174
|
+
description: 'Ingestion counts',
|
|
1175
|
+
content: jsonContent({
|
|
1176
|
+
type: 'object',
|
|
1177
|
+
properties: {
|
|
1178
|
+
channelsAdded: { type: 'integer' },
|
|
1179
|
+
updatesApplied: { type: 'integer' }
|
|
1180
|
+
}
|
|
1181
|
+
})
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
},
|
|
1186
|
+
'/channel/diagnostics': {
|
|
1187
|
+
get: {
|
|
1188
|
+
summary: 'Routing-readiness diagnostics for a channel (SCID/announcement/peer-connection issues)',
|
|
1189
|
+
tags: ['Channels'],
|
|
1190
|
+
parameters: [
|
|
1191
|
+
{
|
|
1192
|
+
name: 'channelId',
|
|
1193
|
+
in: 'query',
|
|
1194
|
+
required: true,
|
|
1195
|
+
schema: { type: 'string' }
|
|
1196
|
+
}
|
|
1197
|
+
],
|
|
1198
|
+
responses: {
|
|
1199
|
+
'200': { description: 'Diagnostics with an issues list' },
|
|
1200
|
+
'404': { description: 'Channel not found' }
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
},
|
|
1204
|
+
'/address/validate': {
|
|
1205
|
+
post: {
|
|
1206
|
+
summary: 'Validate a Bitcoin address for the active network',
|
|
1207
|
+
tags: ['Node'],
|
|
1208
|
+
requestBody: bodyContent({ address: 'string' }),
|
|
1209
|
+
responses: {
|
|
1210
|
+
'200': {
|
|
1211
|
+
description: 'Validity',
|
|
1212
|
+
content: jsonContent({
|
|
1213
|
+
type: 'object',
|
|
1214
|
+
properties: {
|
|
1215
|
+
address: { type: 'string' },
|
|
1216
|
+
valid: { type: 'boolean' }
|
|
1217
|
+
}
|
|
1218
|
+
})
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
},
|
|
1223
|
+
'/recover-fallback-funds': {
|
|
1224
|
+
post: {
|
|
1225
|
+
summary: 'Sweep UTXOs at the funding-key fallback address into the wallet',
|
|
1226
|
+
tags: ['Node'],
|
|
1227
|
+
requestBody: bodyContent({ feeRatePerVbyte: 'number?' }),
|
|
1228
|
+
responses: {
|
|
1229
|
+
'200': {
|
|
1230
|
+
description: 'Broadcast txid and recovered amount, or { recovered: false } when nothing to recover',
|
|
1231
|
+
content: jsonContent({
|
|
1232
|
+
type: 'object',
|
|
1233
|
+
properties: {
|
|
1234
|
+
txid: { type: 'string' },
|
|
1235
|
+
amountSat: { type: 'integer' },
|
|
1236
|
+
inputCount: { type: 'integer' },
|
|
1237
|
+
recovered: { type: 'boolean' }
|
|
1238
|
+
}
|
|
1239
|
+
})
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
},
|
|
1244
|
+
'/backup/trigger': {
|
|
1245
|
+
post: {
|
|
1246
|
+
summary: 'Trigger an on-demand backup to the configured backupPath (no-op when unset)',
|
|
1247
|
+
tags: ['Node'],
|
|
1248
|
+
responses: {
|
|
1249
|
+
'200': {
|
|
1250
|
+
description: 'Trigger acknowledged',
|
|
1251
|
+
content: jsonContent({
|
|
1252
|
+
type: 'object',
|
|
1253
|
+
properties: { triggered: { type: 'boolean' } }
|
|
1254
|
+
})
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
},
|
|
1259
|
+
'/backup': {
|
|
1260
|
+
post: {
|
|
1261
|
+
summary: 'Create database backup',
|
|
1262
|
+
tags: ['Node'],
|
|
1263
|
+
requestBody: bodyContent({ destPath: 'string' }),
|
|
1264
|
+
responses: { '200': { description: 'Backup result' } }
|
|
1265
|
+
}
|
|
1266
|
+
},
|
|
1267
|
+
'/backup/scb': {
|
|
1268
|
+
get: {
|
|
1269
|
+
summary: 'Export the encrypted static channel backup (seed-encrypted blob)',
|
|
1270
|
+
tags: ['Node'],
|
|
1271
|
+
responses: {
|
|
1272
|
+
'200': {
|
|
1273
|
+
description: 'Encoded SCB blob, channel count, and on-disk path'
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
},
|
|
1278
|
+
'/backup/peer-retrieved': {
|
|
1279
|
+
get: {
|
|
1280
|
+
summary: 'Get the newest valid SCB a peer returned via BOLT 1 peer storage (recovery flow: reinstall with the mnemonic, connect to peers, fetch this, then POST /restore/scb with its encoded blob)',
|
|
1281
|
+
tags: ['Node'],
|
|
1282
|
+
responses: {
|
|
1283
|
+
'200': {
|
|
1284
|
+
description: 'Encoded SCB blob, its creation timestamp, and the peer that returned it'
|
|
1285
|
+
},
|
|
1286
|
+
'404': {
|
|
1287
|
+
description: 'No peer has returned a valid backup this session'
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
},
|
|
1292
|
+
'/restore/scb': {
|
|
1293
|
+
post: {
|
|
1294
|
+
summary: 'Restore channels from a static channel backup (on-chain recovery only: the peer force-closes and our balance is swept from its commitment)',
|
|
1295
|
+
tags: ['Node'],
|
|
1296
|
+
requestBody: bodyContent({ encoded: 'string?', path: 'string?' }),
|
|
1297
|
+
responses: {
|
|
1298
|
+
'200': {
|
|
1299
|
+
description: 'Channel ids now recovering, entries skipped with reasons, and total channel count in the backup'
|
|
1300
|
+
},
|
|
1301
|
+
'400': {
|
|
1302
|
+
description: 'Invalid params (need exactly one of encoded/path), wrong seed, or wrong network'
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
},
|
|
1307
|
+
'/send': {
|
|
1308
|
+
post: {
|
|
1309
|
+
summary: 'Send on-chain Bitcoin',
|
|
1310
|
+
tags: ['Node'],
|
|
1311
|
+
requestBody: bodyContent({
|
|
1312
|
+
address: 'string',
|
|
1313
|
+
amountSats: 'number',
|
|
1314
|
+
satsPerVbyte: 'number?'
|
|
1315
|
+
}),
|
|
1316
|
+
responses: { '200': { description: 'Transaction info' } }
|
|
1317
|
+
}
|
|
1318
|
+
},
|
|
1319
|
+
'/send-max': {
|
|
1320
|
+
post: {
|
|
1321
|
+
summary: 'Sweep the entire spendable on-chain balance to one address (amount = balance minus fee)',
|
|
1322
|
+
tags: ['Node'],
|
|
1323
|
+
requestBody: bodyContent({
|
|
1324
|
+
address: 'string',
|
|
1325
|
+
satsPerVbyte: 'number?'
|
|
1326
|
+
}),
|
|
1327
|
+
responses: {
|
|
1328
|
+
'200': {
|
|
1329
|
+
description: 'Transaction info',
|
|
1330
|
+
content: jsonContent({ $ref: '#/components/schemas/TxInfo' })
|
|
1331
|
+
},
|
|
1332
|
+
'400': { description: 'Invalid address/fee rate or no UTXOs' }
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
},
|
|
1336
|
+
'/tx/bump-fee': {
|
|
1337
|
+
post: {
|
|
1338
|
+
summary: 'Replace an unconfirmed RBF-signalling wallet transaction with a higher-fee version (BIP 125)',
|
|
1339
|
+
tags: ['Node'],
|
|
1340
|
+
requestBody: bodyContent({
|
|
1341
|
+
txid: 'string',
|
|
1342
|
+
satsPerVbyte: 'number'
|
|
1343
|
+
}),
|
|
1344
|
+
responses: {
|
|
1345
|
+
'200': {
|
|
1346
|
+
description: 'Boost result',
|
|
1347
|
+
content: jsonContent({ $ref: '#/components/schemas/BoostResult' })
|
|
1348
|
+
},
|
|
1349
|
+
'400': {
|
|
1350
|
+
description: 'NOT_BOOSTABLE (unknown/confirmed/non-RBF tx; try /tx/boost for CPFP) or invalid params'
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
},
|
|
1355
|
+
'/tx/boost': {
|
|
1356
|
+
post: {
|
|
1357
|
+
summary: 'Fee-bump an unconfirmed wallet transaction: RBF when possible, otherwise CPFP',
|
|
1358
|
+
tags: ['Node'],
|
|
1359
|
+
requestBody: bodyContent({
|
|
1360
|
+
txid: 'string',
|
|
1361
|
+
satsPerVbyte: 'number?'
|
|
1362
|
+
}),
|
|
1363
|
+
responses: {
|
|
1364
|
+
'200': {
|
|
1365
|
+
description: 'Boost result',
|
|
1366
|
+
content: jsonContent({ $ref: '#/components/schemas/BoostResult' })
|
|
1367
|
+
},
|
|
1368
|
+
'400': {
|
|
1369
|
+
description: 'NOT_BOOSTABLE or invalid params'
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
},
|
|
1374
|
+
'/transactions/boostable': {
|
|
1375
|
+
get: {
|
|
1376
|
+
summary: 'List unconfirmed wallet transactions eligible for RBF and/or CPFP fee bumping',
|
|
1377
|
+
tags: ['Node'],
|
|
1378
|
+
responses: {
|
|
1379
|
+
'200': {
|
|
1380
|
+
description: 'Boostable transactions by method',
|
|
1381
|
+
content: jsonContent({
|
|
1382
|
+
$ref: '#/components/schemas/BoostableTransactions'
|
|
1383
|
+
})
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
},
|
|
1388
|
+
'/consolidate': {
|
|
1389
|
+
post: {
|
|
1390
|
+
summary: 'Merge all spendable UTXOs into a single output at a fresh wallet address (send-max-to-self)',
|
|
1391
|
+
tags: ['Node'],
|
|
1392
|
+
requestBody: bodyContent({ satsPerVbyte: 'number?' }),
|
|
1393
|
+
responses: {
|
|
1394
|
+
'200': {
|
|
1395
|
+
description: 'Consolidation result',
|
|
1396
|
+
content: jsonContent({
|
|
1397
|
+
$ref: '#/components/schemas/ConsolidateResult'
|
|
1398
|
+
})
|
|
1399
|
+
},
|
|
1400
|
+
'400': {
|
|
1401
|
+
description: 'NOTHING_TO_CONSOLIDATE (fewer than 2 UTXOs) or invalid params'
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
},
|
|
1406
|
+
'/psbt/build': {
|
|
1407
|
+
post: {
|
|
1408
|
+
summary: 'Build an UNSIGNED PSBT for an external signer (hardware wallet); includes bip32 derivation metadata, nothing is signed or broadcast',
|
|
1409
|
+
tags: ['Node'],
|
|
1410
|
+
requestBody: bodyContent({
|
|
1411
|
+
outputs: 'array',
|
|
1412
|
+
satsPerVbyte: 'number?'
|
|
1413
|
+
}),
|
|
1414
|
+
responses: {
|
|
1415
|
+
'200': {
|
|
1416
|
+
description: 'Unsigned PSBT (base64) with fee, vsize estimate and input/output summary'
|
|
1417
|
+
},
|
|
1418
|
+
'400': { description: 'Invalid outputs/fee rate or no UTXOs' }
|
|
1419
|
+
}
|
|
1420
|
+
}
|
|
1421
|
+
},
|
|
1422
|
+
'/psbt/import-signed': {
|
|
1423
|
+
post: {
|
|
1424
|
+
summary: 'Validate and finalize an externally signed PSBT; returns { txid, txHex } WITHOUT broadcasting',
|
|
1425
|
+
tags: ['Node'],
|
|
1426
|
+
requestBody: bodyContent({ psbtBase64: 'string' }),
|
|
1427
|
+
responses: {
|
|
1428
|
+
'200': { description: 'Finalized transaction (not broadcast)' },
|
|
1429
|
+
'400': {
|
|
1430
|
+
description: 'PSBT_IMPORT_FAILED (missing/invalid signatures)'
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
},
|
|
1435
|
+
'/psbt/combine': {
|
|
1436
|
+
post: {
|
|
1437
|
+
summary: 'Combine partially signed copies of the same PSBT (multi-party signing)',
|
|
1438
|
+
tags: ['Node'],
|
|
1439
|
+
requestBody: bodyContent({ psbts: 'array' }),
|
|
1440
|
+
responses: {
|
|
1441
|
+
'200': { description: 'Combined PSBT (base64)' },
|
|
1442
|
+
'400': { description: 'Fewer than two PSBTs or malformed input' }
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1445
|
+
},
|
|
1446
|
+
'/readiness': {
|
|
1447
|
+
get: {
|
|
1448
|
+
summary: 'Get mainnet readiness report with weighted checks',
|
|
1449
|
+
tags: ['Node'],
|
|
1450
|
+
responses: {
|
|
1451
|
+
'200': {
|
|
1452
|
+
description: 'Readiness report',
|
|
1453
|
+
content: jsonContent({
|
|
1454
|
+
$ref: '#/components/schemas/ReadinessReport'
|
|
1455
|
+
})
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
},
|
|
1460
|
+
'/stats': {
|
|
1461
|
+
get: {
|
|
1462
|
+
summary: 'Get node statistics',
|
|
1463
|
+
tags: ['Node'],
|
|
1464
|
+
parameters: [
|
|
1465
|
+
{
|
|
1466
|
+
name: 'window',
|
|
1467
|
+
in: 'query',
|
|
1468
|
+
schema: { type: 'integer' },
|
|
1469
|
+
description: 'Time window in milliseconds. Only payments created within this window are included.'
|
|
1470
|
+
}
|
|
1471
|
+
],
|
|
1472
|
+
responses: {
|
|
1473
|
+
'200': {
|
|
1474
|
+
description: 'Node stats',
|
|
1475
|
+
content: jsonContent({ $ref: '#/components/schemas/NodeStats' })
|
|
1476
|
+
}
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
},
|
|
1480
|
+
'/liquidity': {
|
|
1481
|
+
get: {
|
|
1482
|
+
summary: 'Get liquidity snapshot with recommendations',
|
|
1483
|
+
tags: ['Node'],
|
|
1484
|
+
responses: {
|
|
1485
|
+
'200': {
|
|
1486
|
+
description: 'Liquidity snapshot',
|
|
1487
|
+
content: jsonContent({
|
|
1488
|
+
$ref: '#/components/schemas/LiquiditySnapshot'
|
|
1489
|
+
})
|
|
1490
|
+
}
|
|
1491
|
+
}
|
|
1492
|
+
}
|
|
1493
|
+
},
|
|
1494
|
+
'/advisor/recommendations': {
|
|
1495
|
+
get: {
|
|
1496
|
+
summary: 'Liquidity analysis (advisor analyze) plus the concrete circular-rebalance plan',
|
|
1497
|
+
tags: ['Node'],
|
|
1498
|
+
responses: {
|
|
1499
|
+
'200': {
|
|
1500
|
+
description: 'Advisor recommendations',
|
|
1501
|
+
content: jsonContent({
|
|
1502
|
+
$ref: '#/components/schemas/AdvisorRecommendations'
|
|
1503
|
+
})
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1507
|
+
},
|
|
1508
|
+
'/advisor/execute-rebalances': {
|
|
1509
|
+
post: {
|
|
1510
|
+
summary: 'Execute the advisor rebalance plan under a strict per-UTC-day routing-fee budget (persisted across restarts)',
|
|
1511
|
+
tags: ['Node'],
|
|
1512
|
+
requestBody: bodyContent({ budgetSatsPerDay: 'number?' }),
|
|
1513
|
+
responses: {
|
|
1514
|
+
'200': {
|
|
1515
|
+
description: 'Execution summary (msat values as strings)',
|
|
1516
|
+
content: jsonContent({
|
|
1517
|
+
$ref: '#/components/schemas/RebalanceExecutionSummary'
|
|
1518
|
+
})
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
},
|
|
1523
|
+
'/rebalance': {
|
|
1524
|
+
post: {
|
|
1525
|
+
summary: 'Circular rebalance: self-payment out over fromChannelId and back in over toChannelId; aborts without paying if the route fee exceeds maxFeeSats',
|
|
1526
|
+
tags: ['Channels'],
|
|
1527
|
+
requestBody: bodyContent({
|
|
1528
|
+
fromChannelId: 'string',
|
|
1529
|
+
toChannelId: 'string',
|
|
1530
|
+
amountSats: 'number',
|
|
1531
|
+
maxFeeSats: 'number'
|
|
1532
|
+
}),
|
|
1533
|
+
responses: {
|
|
1534
|
+
'200': {
|
|
1535
|
+
description: 'Rebalance result',
|
|
1536
|
+
content: jsonContent({
|
|
1537
|
+
$ref: '#/components/schemas/RebalanceResult'
|
|
1538
|
+
})
|
|
1539
|
+
},
|
|
1540
|
+
'400': {
|
|
1541
|
+
description: 'No route, fee exceeds maxFeeSats, or invalid params'
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
},
|
|
1546
|
+
'/fees': {
|
|
1547
|
+
get: {
|
|
1548
|
+
summary: 'Get on-chain fee rate snapshot with trend analysis and channel-open recommendation',
|
|
1549
|
+
tags: ['Node'],
|
|
1550
|
+
responses: {
|
|
1551
|
+
'200': {
|
|
1552
|
+
description: 'Fee snapshot',
|
|
1553
|
+
content: jsonContent({ $ref: '#/components/schemas/FeeSnapshot' })
|
|
1554
|
+
},
|
|
1555
|
+
'400': { description: 'No fee samples recorded yet' }
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
},
|
|
1559
|
+
'/fees/estimates': {
|
|
1560
|
+
get: {
|
|
1561
|
+
summary: 'Get current on-chain fee rate estimates in sats/vbyte',
|
|
1562
|
+
tags: ['Node'],
|
|
1563
|
+
responses: {
|
|
1564
|
+
'200': {
|
|
1565
|
+
description: 'Fee estimates',
|
|
1566
|
+
content: jsonContent({ $ref: '#/components/schemas/OnchainFees' })
|
|
1567
|
+
}
|
|
818
1568
|
}
|
|
819
1569
|
}
|
|
820
1570
|
},
|
|
@@ -931,55 +1681,139 @@ function getOpenApiSpec() {
|
|
|
931
1681
|
}
|
|
932
1682
|
}
|
|
933
1683
|
},
|
|
934
|
-
'/events': {
|
|
935
|
-
get: {
|
|
936
|
-
summary: 'Server-Sent Events stream (payment:received, payment:sent, payment:failed, channel:ready, channel:closed, peer:connect, peer:disconnect, node:ready)',
|
|
1684
|
+
'/events': {
|
|
1685
|
+
get: {
|
|
1686
|
+
summary: 'Server-Sent Events stream (payment:received, payment:sent, payment:failed, invoice:settled, channel:opening, channel:ready, channel:pending-close, channel:force-closing, channel:closed, peer:connect, peer:disconnect, node:ready; plus htlc:forwarded, htlc:fulfilled, htlc:failed when the daemon is started with htlcEvents)',
|
|
1687
|
+
tags: ['Node'],
|
|
1688
|
+
responses: {
|
|
1689
|
+
'200': {
|
|
1690
|
+
description: 'SSE stream',
|
|
1691
|
+
content: { 'text/event-stream': {} }
|
|
1692
|
+
}
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
},
|
|
1696
|
+
'/stop': {
|
|
1697
|
+
post: {
|
|
1698
|
+
summary: 'Gracefully stop the daemon (supports drain mode)',
|
|
1699
|
+
tags: ['Node'],
|
|
1700
|
+
requestBody: bodyContent({
|
|
1701
|
+
'drain?': 'boolean',
|
|
1702
|
+
'drainTimeoutMs?': 'number'
|
|
1703
|
+
}),
|
|
1704
|
+
responses: {
|
|
1705
|
+
'200': {
|
|
1706
|
+
description: 'Stopped',
|
|
1707
|
+
content: jsonContent({
|
|
1708
|
+
type: 'object',
|
|
1709
|
+
properties: {
|
|
1710
|
+
stopped: { type: 'boolean' },
|
|
1711
|
+
drained: { type: 'boolean' }
|
|
1712
|
+
}
|
|
1713
|
+
})
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
}
|
|
1717
|
+
},
|
|
1718
|
+
'/spend-limit': {
|
|
1719
|
+
get: {
|
|
1720
|
+
summary: 'Get combined daily spending limit info (Lightning + external on-chain sends share one budget)',
|
|
1721
|
+
description: 'The daily limit covers Lightning payments AND external on-chain sends (amount + fee). Consolidation, channel funding and fee bumps are excluded. spentSats mirrors totalSats for back-compat.',
|
|
1722
|
+
tags: ['Node'],
|
|
1723
|
+
responses: {
|
|
1724
|
+
'200': {
|
|
1725
|
+
description: 'Spending limit info with LN/onchain breakdown',
|
|
1726
|
+
content: jsonContent({
|
|
1727
|
+
type: 'object',
|
|
1728
|
+
properties: {
|
|
1729
|
+
limitSats: { type: 'integer', nullable: true },
|
|
1730
|
+
spentSats: { type: 'integer' },
|
|
1731
|
+
remainingSats: { type: 'number' },
|
|
1732
|
+
resetsAt: { type: 'integer' },
|
|
1733
|
+
totalSats: { type: 'integer' },
|
|
1734
|
+
lightningSats: { type: 'integer' },
|
|
1735
|
+
onchainSats: { type: 'integer' }
|
|
1736
|
+
}
|
|
1737
|
+
})
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
},
|
|
1742
|
+
'/utxo/freeze': {
|
|
1743
|
+
post: {
|
|
1744
|
+
summary: 'Freeze a UTXO so coin selection cannot spend it until unfrozen',
|
|
1745
|
+
tags: ['Node'],
|
|
1746
|
+
requestBody: bodyContent({ txid: 'string', index: 'integer' }),
|
|
1747
|
+
responses: {
|
|
1748
|
+
'200': {
|
|
1749
|
+
description: 'Frozen outpoint',
|
|
1750
|
+
content: jsonContent({
|
|
1751
|
+
type: 'object',
|
|
1752
|
+
properties: { frozen: { type: 'string' } }
|
|
1753
|
+
})
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
}
|
|
1757
|
+
},
|
|
1758
|
+
'/utxo/unfreeze': {
|
|
1759
|
+
post: {
|
|
1760
|
+
summary: 'Unfreeze a previously frozen UTXO',
|
|
937
1761
|
tags: ['Node'],
|
|
1762
|
+
requestBody: bodyContent({ txid: 'string', index: 'integer' }),
|
|
938
1763
|
responses: {
|
|
939
1764
|
'200': {
|
|
940
|
-
description: '
|
|
941
|
-
content: {
|
|
1765
|
+
description: 'Unfrozen outpoint',
|
|
1766
|
+
content: jsonContent({
|
|
1767
|
+
type: 'object',
|
|
1768
|
+
properties: { unfrozen: { type: 'string' } }
|
|
1769
|
+
})
|
|
942
1770
|
}
|
|
943
1771
|
}
|
|
944
1772
|
}
|
|
945
1773
|
},
|
|
946
|
-
'/
|
|
1774
|
+
'/address/label': {
|
|
947
1775
|
post: {
|
|
948
|
-
summary: '
|
|
1776
|
+
summary: 'Set a user label for an address (empty label clears it)',
|
|
949
1777
|
tags: ['Node'],
|
|
950
|
-
requestBody: bodyContent({
|
|
951
|
-
'drain?': 'boolean',
|
|
952
|
-
'drainTimeoutMs?': 'number'
|
|
953
|
-
}),
|
|
1778
|
+
requestBody: bodyContent({ address: 'string', label: 'string' }),
|
|
954
1779
|
responses: {
|
|
955
1780
|
'200': {
|
|
956
|
-
description: '
|
|
1781
|
+
description: 'Stored label',
|
|
957
1782
|
content: jsonContent({
|
|
958
1783
|
type: 'object',
|
|
959
1784
|
properties: {
|
|
960
|
-
|
|
961
|
-
|
|
1785
|
+
address: { type: 'string' },
|
|
1786
|
+
label: { type: 'string' }
|
|
962
1787
|
}
|
|
963
1788
|
})
|
|
964
1789
|
}
|
|
965
1790
|
}
|
|
966
1791
|
}
|
|
967
1792
|
},
|
|
968
|
-
'/
|
|
1793
|
+
'/address/labels': {
|
|
969
1794
|
get: {
|
|
970
|
-
summary: '
|
|
1795
|
+
summary: 'List all user address labels keyed by address',
|
|
971
1796
|
tags: ['Node'],
|
|
972
1797
|
responses: {
|
|
973
1798
|
'200': {
|
|
974
|
-
description: '
|
|
1799
|
+
description: 'Labels map',
|
|
975
1800
|
content: jsonContent({
|
|
976
1801
|
type: 'object',
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
1802
|
+
additionalProperties: { type: 'string' }
|
|
1803
|
+
})
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1806
|
+
}
|
|
1807
|
+
},
|
|
1808
|
+
'/wallet/descriptors': {
|
|
1809
|
+
get: {
|
|
1810
|
+
summary: 'Export BIP 380 output descriptors for the on-chain wallet (public keys only)',
|
|
1811
|
+
tags: ['Node'],
|
|
1812
|
+
responses: {
|
|
1813
|
+
'200': {
|
|
1814
|
+
description: 'Descriptors',
|
|
1815
|
+
content: jsonContent({
|
|
1816
|
+
$ref: '#/components/schemas/DescriptorsInfo'
|
|
983
1817
|
})
|
|
984
1818
|
}
|
|
985
1819
|
}
|
|
@@ -988,13 +1822,23 @@ function getOpenApiSpec() {
|
|
|
988
1822
|
'/address/new': {
|
|
989
1823
|
post: {
|
|
990
1824
|
summary: 'Generate a new on-chain receiving address',
|
|
1825
|
+
description: 'Pass bip21:true (with optional amountSats/label/message) to also receive the address encoded as a BIP21 payment URI.',
|
|
991
1826
|
tags: ['Node'],
|
|
1827
|
+
requestBody: bodyContent({
|
|
1828
|
+
bip21: 'boolean?',
|
|
1829
|
+
amountSats: 'integer?',
|
|
1830
|
+
label: 'string?',
|
|
1831
|
+
message: 'string?'
|
|
1832
|
+
}),
|
|
992
1833
|
responses: {
|
|
993
1834
|
'200': {
|
|
994
1835
|
description: 'New address',
|
|
995
1836
|
content: jsonContent({
|
|
996
1837
|
type: 'object',
|
|
997
|
-
properties: {
|
|
1838
|
+
properties: {
|
|
1839
|
+
address: { type: 'string' },
|
|
1840
|
+
bip21: { type: 'string' }
|
|
1841
|
+
}
|
|
998
1842
|
})
|
|
999
1843
|
}
|
|
1000
1844
|
}
|
|
@@ -1018,6 +1862,7 @@ function getOpenApiSpec() {
|
|
|
1018
1862
|
'/mnemonic': {
|
|
1019
1863
|
get: {
|
|
1020
1864
|
summary: 'Get wallet mnemonic (requires API token)',
|
|
1865
|
+
description: 'Seed generation is CLI-only: `beignet init` creates the mnemonic; the daemon never generates or replaces a seed. This endpoint only reveals the configured mnemonic, and only when apiToken is set (returns MNEMONIC_REQUIRES_AUTH otherwise).',
|
|
1021
1866
|
tags: ['Node'],
|
|
1022
1867
|
responses: {
|
|
1023
1868
|
'200': {
|
|
@@ -1368,13 +2213,59 @@ function getOpenApiSpec() {
|
|
|
1368
2213
|
}
|
|
1369
2214
|
}
|
|
1370
2215
|
}
|
|
2216
|
+
},
|
|
2217
|
+
'/auth/keys': {
|
|
2218
|
+
get: {
|
|
2219
|
+
summary: 'List named API keys (admin scope; never returns secrets)',
|
|
2220
|
+
tags: ['Auth'],
|
|
2221
|
+
responses: {
|
|
2222
|
+
'200': {
|
|
2223
|
+
description: 'Key names with their scopes and revoked flag',
|
|
2224
|
+
content: jsonContent({
|
|
2225
|
+
type: 'object',
|
|
2226
|
+
properties: {
|
|
2227
|
+
keys: {
|
|
2228
|
+
type: 'array',
|
|
2229
|
+
items: {
|
|
2230
|
+
type: 'object',
|
|
2231
|
+
properties: {
|
|
2232
|
+
name: { type: 'string' },
|
|
2233
|
+
scopes: {
|
|
2234
|
+
type: 'array',
|
|
2235
|
+
items: {
|
|
2236
|
+
type: 'string',
|
|
2237
|
+
enum: ['readonly', 'invoice', 'admin']
|
|
2238
|
+
}
|
|
2239
|
+
},
|
|
2240
|
+
revoked: { type: 'boolean' }
|
|
2241
|
+
}
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
}
|
|
2245
|
+
})
|
|
2246
|
+
}
|
|
2247
|
+
}
|
|
2248
|
+
}
|
|
2249
|
+
},
|
|
2250
|
+
'/auth/keys/revoke': {
|
|
2251
|
+
post: {
|
|
2252
|
+
summary: 'Revoke a named API key for the lifetime of this daemon process (admin scope)',
|
|
2253
|
+
description: 'Runtime revocation only: the durable mechanism is removing the key from the config file and restarting. The legacy apiToken has no name and cannot be revoked here.',
|
|
2254
|
+
tags: ['Auth'],
|
|
2255
|
+
requestBody: bodyContent({ name: 'string' }),
|
|
2256
|
+
responses: {
|
|
2257
|
+
'200': { description: 'Key revoked' },
|
|
2258
|
+
'404': { description: 'No key with that name' }
|
|
2259
|
+
}
|
|
2260
|
+
}
|
|
1371
2261
|
}
|
|
1372
2262
|
},
|
|
1373
2263
|
components: {
|
|
1374
2264
|
securitySchemes: {
|
|
1375
2265
|
bearerAuth: {
|
|
1376
2266
|
type: 'http',
|
|
1377
|
-
scheme: 'bearer'
|
|
2267
|
+
scheme: 'bearer',
|
|
2268
|
+
description: 'Legacy apiToken (implicit admin scope) or the secret of a named scoped API key from the apiKeys config. Routes advertise the scopes they accept via x-accepted-scopes; 401 = bad/absent key, 403 = valid key without a required scope.'
|
|
1378
2269
|
}
|
|
1379
2270
|
},
|
|
1380
2271
|
schemas: {
|
|
@@ -1451,7 +2342,33 @@ function getOpenApiSpec() {
|
|
|
1451
2342
|
vout: { type: 'integer' },
|
|
1452
2343
|
address: { type: 'string' },
|
|
1453
2344
|
valueSats: { type: 'integer' },
|
|
1454
|
-
height: { type: 'integer' }
|
|
2345
|
+
height: { type: 'integer' },
|
|
2346
|
+
frozen: {
|
|
2347
|
+
type: 'boolean',
|
|
2348
|
+
description: 'Frozen UTXOs are excluded from coin selection until unfrozen'
|
|
2349
|
+
}
|
|
2350
|
+
}
|
|
2351
|
+
},
|
|
2352
|
+
DescriptorsInfo: {
|
|
2353
|
+
type: 'object',
|
|
2354
|
+
description: 'BIP 380 output descriptors (with checksums). Public keys only; private keys are never exported.',
|
|
2355
|
+
properties: {
|
|
2356
|
+
fingerprint: { type: 'string' },
|
|
2357
|
+
network: { type: 'string' },
|
|
2358
|
+
account: { type: 'integer' },
|
|
2359
|
+
birthdayHeight: { type: 'integer' },
|
|
2360
|
+
watchOnly: { type: 'boolean' },
|
|
2361
|
+
descriptors: {
|
|
2362
|
+
type: 'array',
|
|
2363
|
+
items: {
|
|
2364
|
+
type: 'object',
|
|
2365
|
+
properties: {
|
|
2366
|
+
addressType: { type: 'string' },
|
|
2367
|
+
external: { type: 'string' },
|
|
2368
|
+
internal: { type: 'string' }
|
|
2369
|
+
}
|
|
2370
|
+
}
|
|
2371
|
+
}
|
|
1455
2372
|
}
|
|
1456
2373
|
},
|
|
1457
2374
|
OnchainFees: {
|
|
@@ -1465,6 +2382,40 @@ function getOpenApiSpec() {
|
|
|
1465
2382
|
timestamp: { type: 'integer' }
|
|
1466
2383
|
}
|
|
1467
2384
|
},
|
|
2385
|
+
ForwardingEvent: {
|
|
2386
|
+
type: 'object',
|
|
2387
|
+
description: 'One settled forward. Msat values are decimal strings (JSON-safe bigint).',
|
|
2388
|
+
properties: {
|
|
2389
|
+
id: { type: 'integer' },
|
|
2390
|
+
settledAt: { type: 'integer' },
|
|
2391
|
+
inChannelId: { type: 'string' },
|
|
2392
|
+
outChannelId: { type: 'string' },
|
|
2393
|
+
inScid: { type: 'string' },
|
|
2394
|
+
outScid: { type: 'string' },
|
|
2395
|
+
amountInMsat: { type: 'string' },
|
|
2396
|
+
amountOutMsat: { type: 'string' },
|
|
2397
|
+
feeMsat: { type: 'string' }
|
|
2398
|
+
}
|
|
2399
|
+
},
|
|
2400
|
+
ForwardingSummary: {
|
|
2401
|
+
type: 'object',
|
|
2402
|
+
properties: {
|
|
2403
|
+
count: { type: 'integer' },
|
|
2404
|
+
volumeOutMsat: { type: 'string' },
|
|
2405
|
+
feesEarnedMsat: { type: 'string' }
|
|
2406
|
+
}
|
|
2407
|
+
},
|
|
2408
|
+
WatchtowerInfo: {
|
|
2409
|
+
type: 'object',
|
|
2410
|
+
properties: {
|
|
2411
|
+
uri: { type: 'string' },
|
|
2412
|
+
pubkey: { type: 'string' },
|
|
2413
|
+
connected: { type: 'boolean' },
|
|
2414
|
+
sessions: { type: 'integer' },
|
|
2415
|
+
pendingBacklog: { type: 'integer' },
|
|
2416
|
+
lastAck: { type: 'integer', nullable: true }
|
|
2417
|
+
}
|
|
2418
|
+
},
|
|
1468
2419
|
HealthInfo: {
|
|
1469
2420
|
type: 'object',
|
|
1470
2421
|
properties: {
|
|
@@ -1519,7 +2470,36 @@ function getOpenApiSpec() {
|
|
|
1519
2470
|
fundingTxid: { type: 'string' },
|
|
1520
2471
|
shortChannelId: { type: 'string' },
|
|
1521
2472
|
feeratePerKw: { type: 'integer' },
|
|
1522
|
-
htlcCount: { type: 'integer' }
|
|
2473
|
+
htlcCount: { type: 'integer' },
|
|
2474
|
+
feeBaseMsat: { type: 'integer' },
|
|
2475
|
+
feeProportionalMillionths: { type: 'integer' },
|
|
2476
|
+
cltvExpiryDelta: { type: 'integer' },
|
|
2477
|
+
htlcMinimumMsat: {
|
|
2478
|
+
type: 'string',
|
|
2479
|
+
description: 'Msat as decimal string'
|
|
2480
|
+
},
|
|
2481
|
+
htlcMaximumMsat: {
|
|
2482
|
+
type: 'string',
|
|
2483
|
+
description: 'Msat as decimal string'
|
|
2484
|
+
}
|
|
2485
|
+
}
|
|
2486
|
+
},
|
|
2487
|
+
ChannelPolicy: {
|
|
2488
|
+
type: 'object',
|
|
2489
|
+
properties: {
|
|
2490
|
+
channelId: { type: 'string' },
|
|
2491
|
+
feeBaseMsat: { type: 'integer' },
|
|
2492
|
+
feeProportionalMillionths: { type: 'integer' },
|
|
2493
|
+
cltvExpiryDelta: { type: 'integer' },
|
|
2494
|
+
htlcMinimumMsat: {
|
|
2495
|
+
type: 'string',
|
|
2496
|
+
description: 'Msat as decimal string'
|
|
2497
|
+
},
|
|
2498
|
+
htlcMaximumMsat: {
|
|
2499
|
+
type: 'string',
|
|
2500
|
+
description: 'Msat as decimal string'
|
|
2501
|
+
},
|
|
2502
|
+
source: { type: 'string', enum: ['override', 'default'] }
|
|
1523
2503
|
}
|
|
1524
2504
|
},
|
|
1525
2505
|
PaymentInfo: {
|
|
@@ -1576,6 +2556,26 @@ function getOpenApiSpec() {
|
|
|
1576
2556
|
status: { type: 'string', enum: ['PENDING', 'PAID', 'EXPIRED'] }
|
|
1577
2557
|
}
|
|
1578
2558
|
},
|
|
2559
|
+
HoldInvoiceInfo: {
|
|
2560
|
+
type: 'object',
|
|
2561
|
+
properties: {
|
|
2562
|
+
paymentHash: { type: 'string' },
|
|
2563
|
+
bolt11: { type: 'string' },
|
|
2564
|
+
state: {
|
|
2565
|
+
type: 'string',
|
|
2566
|
+
enum: ['OPEN', 'ACCEPTED', 'SETTLED', 'CANCELLED']
|
|
2567
|
+
},
|
|
2568
|
+
heldAmountMsat: {
|
|
2569
|
+
type: 'string',
|
|
2570
|
+
description: 'Total msat currently parked'
|
|
2571
|
+
},
|
|
2572
|
+
htlcCount: { type: 'integer' },
|
|
2573
|
+
amountSats: { type: 'integer' },
|
|
2574
|
+
description: { type: 'string' },
|
|
2575
|
+
expiry: { type: 'integer' },
|
|
2576
|
+
createdAt: { type: 'integer' }
|
|
2577
|
+
}
|
|
2578
|
+
},
|
|
1579
2579
|
OfferInfo: {
|
|
1580
2580
|
type: 'object',
|
|
1581
2581
|
properties: {
|
|
@@ -1650,6 +2650,130 @@ function getOpenApiSpec() {
|
|
|
1650
2650
|
cltvDelta: { type: 'integer' }
|
|
1651
2651
|
}
|
|
1652
2652
|
},
|
|
2653
|
+
GraphInfo: {
|
|
2654
|
+
type: 'object',
|
|
2655
|
+
properties: {
|
|
2656
|
+
nodeCount: { type: 'integer' },
|
|
2657
|
+
channelCount: { type: 'integer' },
|
|
2658
|
+
lastSyncAt: {
|
|
2659
|
+
type: 'integer',
|
|
2660
|
+
description: 'Epoch ms of the last gossip/RGS sync this session, if any'
|
|
2661
|
+
}
|
|
2662
|
+
}
|
|
2663
|
+
},
|
|
2664
|
+
GraphChannelPolicy: {
|
|
2665
|
+
type: 'object',
|
|
2666
|
+
description: "One direction's routing policy from a channel_update",
|
|
2667
|
+
properties: {
|
|
2668
|
+
feeBaseMsat: { type: 'integer' },
|
|
2669
|
+
feeProportionalMillionths: { type: 'integer' },
|
|
2670
|
+
cltvExpiryDelta: { type: 'integer' },
|
|
2671
|
+
htlcMinimumMsat: {
|
|
2672
|
+
type: 'string',
|
|
2673
|
+
description: 'Msat as decimal string'
|
|
2674
|
+
},
|
|
2675
|
+
htlcMaximumMsat: {
|
|
2676
|
+
type: 'string',
|
|
2677
|
+
description: 'Msat as decimal string'
|
|
2678
|
+
},
|
|
2679
|
+
disabled: { type: 'boolean' },
|
|
2680
|
+
lastUpdate: {
|
|
2681
|
+
type: 'integer',
|
|
2682
|
+
description: 'channel_update timestamp (seconds)'
|
|
2683
|
+
}
|
|
2684
|
+
}
|
|
2685
|
+
},
|
|
2686
|
+
GraphChannelInfo: {
|
|
2687
|
+
type: 'object',
|
|
2688
|
+
properties: {
|
|
2689
|
+
shortChannelId: {
|
|
2690
|
+
type: 'string',
|
|
2691
|
+
description: '<block>x<txIndex>x<outputIndex>'
|
|
2692
|
+
},
|
|
2693
|
+
node1Pubkey: { type: 'string' },
|
|
2694
|
+
node2Pubkey: { type: 'string' },
|
|
2695
|
+
capacitySats: {
|
|
2696
|
+
type: 'integer',
|
|
2697
|
+
description: 'Best-known lower bound from htlc_maximum_msat (capacity is not gossiped)'
|
|
2698
|
+
},
|
|
2699
|
+
node1Policy: {
|
|
2700
|
+
$ref: '#/components/schemas/GraphChannelPolicy'
|
|
2701
|
+
},
|
|
2702
|
+
node2Policy: {
|
|
2703
|
+
$ref: '#/components/schemas/GraphChannelPolicy'
|
|
2704
|
+
}
|
|
2705
|
+
}
|
|
2706
|
+
},
|
|
2707
|
+
GraphNodeInfo: {
|
|
2708
|
+
type: 'object',
|
|
2709
|
+
properties: {
|
|
2710
|
+
pubkey: { type: 'string' },
|
|
2711
|
+
alias: { type: 'string' },
|
|
2712
|
+
color: { type: 'string' },
|
|
2713
|
+
addresses: {
|
|
2714
|
+
type: 'array',
|
|
2715
|
+
items: {
|
|
2716
|
+
type: 'object',
|
|
2717
|
+
properties: {
|
|
2718
|
+
type: { type: 'integer' },
|
|
2719
|
+
host: { type: 'string' },
|
|
2720
|
+
port: { type: 'integer' }
|
|
2721
|
+
}
|
|
2722
|
+
}
|
|
2723
|
+
},
|
|
2724
|
+
featuresHex: { type: 'string' },
|
|
2725
|
+
lastUpdate: {
|
|
2726
|
+
type: 'integer',
|
|
2727
|
+
description: 'node_announcement timestamp (seconds)'
|
|
2728
|
+
},
|
|
2729
|
+
channelCount: { type: 'integer' },
|
|
2730
|
+
channels: { type: 'array', items: { type: 'string' } }
|
|
2731
|
+
}
|
|
2732
|
+
},
|
|
2733
|
+
RouteHop: {
|
|
2734
|
+
type: 'object',
|
|
2735
|
+
properties: {
|
|
2736
|
+
pubkey: { type: 'string' },
|
|
2737
|
+
shortChannelId: {
|
|
2738
|
+
type: 'string',
|
|
2739
|
+
description: '<block>x<txIndex>x<outputIndex> (16-char hex also accepted on input)'
|
|
2740
|
+
},
|
|
2741
|
+
amountToForwardMsat: {
|
|
2742
|
+
type: 'string',
|
|
2743
|
+
description: 'Msat as decimal string'
|
|
2744
|
+
},
|
|
2745
|
+
outgoingCltvValue: {
|
|
2746
|
+
type: 'integer',
|
|
2747
|
+
description: 'RELATIVE CLTV delta from pathfinding (absolute height added at send)'
|
|
2748
|
+
},
|
|
2749
|
+
feeMsat: {
|
|
2750
|
+
type: 'string',
|
|
2751
|
+
description: 'Fee this hop charges, msat as decimal string'
|
|
2752
|
+
},
|
|
2753
|
+
cltvExpiryDelta: { type: 'integer' }
|
|
2754
|
+
},
|
|
2755
|
+
required: [
|
|
2756
|
+
'pubkey',
|
|
2757
|
+
'shortChannelId',
|
|
2758
|
+
'amountToForwardMsat',
|
|
2759
|
+
'outgoingCltvValue'
|
|
2760
|
+
]
|
|
2761
|
+
},
|
|
2762
|
+
RouteQueryResult: {
|
|
2763
|
+
type: 'object',
|
|
2764
|
+
properties: {
|
|
2765
|
+
destination: { type: 'string' },
|
|
2766
|
+
amountSats: { type: 'integer' },
|
|
2767
|
+
hops: {
|
|
2768
|
+
type: 'array',
|
|
2769
|
+
items: { $ref: '#/components/schemas/RouteHop' }
|
|
2770
|
+
},
|
|
2771
|
+
totalAmountMsat: { type: 'string' },
|
|
2772
|
+
totalFeeMsat: { type: 'string' },
|
|
2773
|
+
totalCltvDelta: { type: 'integer' },
|
|
2774
|
+
finalCltvExpiry: { type: 'integer' }
|
|
2775
|
+
}
|
|
2776
|
+
},
|
|
1653
2777
|
TxInfo: {
|
|
1654
2778
|
type: 'object',
|
|
1655
2779
|
properties: {
|
|
@@ -1657,6 +2781,45 @@ function getOpenApiSpec() {
|
|
|
1657
2781
|
hex: { type: 'string' }
|
|
1658
2782
|
}
|
|
1659
2783
|
},
|
|
2784
|
+
BoostResult: {
|
|
2785
|
+
type: 'object',
|
|
2786
|
+
properties: {
|
|
2787
|
+
txid: {
|
|
2788
|
+
type: 'string',
|
|
2789
|
+
description: 'Replacement (RBF) or child (CPFP) txid'
|
|
2790
|
+
},
|
|
2791
|
+
hex: { type: 'string' },
|
|
2792
|
+
boostType: { type: 'string', enum: ['rbf', 'cpfp'] },
|
|
2793
|
+
feeSats: { type: 'integer' },
|
|
2794
|
+
originalTxid: { type: 'string' }
|
|
2795
|
+
}
|
|
2796
|
+
},
|
|
2797
|
+
BoostableTransactions: {
|
|
2798
|
+
type: 'object',
|
|
2799
|
+
properties: {
|
|
2800
|
+
rbf: {
|
|
2801
|
+
type: 'array',
|
|
2802
|
+
items: { $ref: '#/components/schemas/OnchainTxInfo' }
|
|
2803
|
+
},
|
|
2804
|
+
cpfp: {
|
|
2805
|
+
type: 'array',
|
|
2806
|
+
items: { $ref: '#/components/schemas/OnchainTxInfo' }
|
|
2807
|
+
}
|
|
2808
|
+
}
|
|
2809
|
+
},
|
|
2810
|
+
ConsolidateResult: {
|
|
2811
|
+
type: 'object',
|
|
2812
|
+
properties: {
|
|
2813
|
+
txid: { type: 'string' },
|
|
2814
|
+
hex: { type: 'string' },
|
|
2815
|
+
utxosConsolidated: { type: 'integer' },
|
|
2816
|
+
address: {
|
|
2817
|
+
type: 'string',
|
|
2818
|
+
description: 'Fresh wallet address holding the merged output'
|
|
2819
|
+
},
|
|
2820
|
+
feeSats: { type: 'integer' }
|
|
2821
|
+
}
|
|
2822
|
+
},
|
|
1660
2823
|
SpliceResult: {
|
|
1661
2824
|
type: 'object',
|
|
1662
2825
|
properties: {
|
|
@@ -1717,6 +2880,84 @@ function getOpenApiSpec() {
|
|
|
1717
2880
|
}
|
|
1718
2881
|
}
|
|
1719
2882
|
},
|
|
2883
|
+
RebalancePlan: {
|
|
2884
|
+
type: 'object',
|
|
2885
|
+
properties: {
|
|
2886
|
+
fromChannelId: {
|
|
2887
|
+
type: 'string',
|
|
2888
|
+
description: 'Channel to push liquidity out of'
|
|
2889
|
+
},
|
|
2890
|
+
toChannelId: {
|
|
2891
|
+
type: 'string',
|
|
2892
|
+
description: 'Channel to pull liquidity in on'
|
|
2893
|
+
},
|
|
2894
|
+
amountSats: { type: 'integer' },
|
|
2895
|
+
reason: { type: 'string' }
|
|
2896
|
+
},
|
|
2897
|
+
required: ['fromChannelId', 'toChannelId', 'amountSats', 'reason']
|
|
2898
|
+
},
|
|
2899
|
+
AdvisorRecommendations: {
|
|
2900
|
+
allOf: [
|
|
2901
|
+
{ $ref: '#/components/schemas/LiquiditySnapshot' },
|
|
2902
|
+
{
|
|
2903
|
+
type: 'object',
|
|
2904
|
+
properties: {
|
|
2905
|
+
rebalancePlan: {
|
|
2906
|
+
type: 'array',
|
|
2907
|
+
items: { $ref: '#/components/schemas/RebalancePlan' },
|
|
2908
|
+
description: 'Circular rebalances the executor would run (nothing is executed by this endpoint)'
|
|
2909
|
+
}
|
|
2910
|
+
}
|
|
2911
|
+
}
|
|
2912
|
+
]
|
|
2913
|
+
},
|
|
2914
|
+
RebalanceResult: {
|
|
2915
|
+
type: 'object',
|
|
2916
|
+
properties: {
|
|
2917
|
+
paymentHash: { type: 'string' },
|
|
2918
|
+
amountSats: { type: 'integer' },
|
|
2919
|
+
feeMsat: {
|
|
2920
|
+
type: 'string',
|
|
2921
|
+
description: 'Routing fee paid, msat as decimal string'
|
|
2922
|
+
},
|
|
2923
|
+
feeSats: { type: 'integer' },
|
|
2924
|
+
hops: { type: 'integer' }
|
|
2925
|
+
},
|
|
2926
|
+
required: ['paymentHash', 'amountSats', 'feeMsat', 'feeSats', 'hops']
|
|
2927
|
+
},
|
|
2928
|
+
RebalanceExecutionSummary: {
|
|
2929
|
+
type: 'object',
|
|
2930
|
+
properties: {
|
|
2931
|
+
attempts: {
|
|
2932
|
+
type: 'array',
|
|
2933
|
+
items: {
|
|
2934
|
+
type: 'object',
|
|
2935
|
+
properties: {
|
|
2936
|
+
fromChannelId: { type: 'string' },
|
|
2937
|
+
toChannelId: { type: 'string' },
|
|
2938
|
+
amountSats: { type: 'integer' },
|
|
2939
|
+
status: {
|
|
2940
|
+
type: 'string',
|
|
2941
|
+
enum: ['SUCCEEDED', 'FAILED', 'SKIPPED_BUDGET']
|
|
2942
|
+
},
|
|
2943
|
+
feeMsat: { type: 'string' },
|
|
2944
|
+
error: { type: 'string' }
|
|
2945
|
+
}
|
|
2946
|
+
}
|
|
2947
|
+
},
|
|
2948
|
+
succeeded: { type: 'integer' },
|
|
2949
|
+
failed: { type: 'integer' },
|
|
2950
|
+
skippedBudget: { type: 'integer' },
|
|
2951
|
+
feeSpentMsat: {
|
|
2952
|
+
type: 'string',
|
|
2953
|
+
description: 'Fees spent by this run, msat as decimal string'
|
|
2954
|
+
},
|
|
2955
|
+
budgetRemainingMsat: {
|
|
2956
|
+
type: 'string',
|
|
2957
|
+
description: 'Remaining budget for the current UTC day'
|
|
2958
|
+
}
|
|
2959
|
+
}
|
|
2960
|
+
},
|
|
1720
2961
|
LiquidityRecommendation: {
|
|
1721
2962
|
type: 'object',
|
|
1722
2963
|
properties: {
|
|
@@ -2050,6 +3291,19 @@ function getOpenApiSpec() {
|
|
|
2050
3291
|
},
|
|
2051
3292
|
security: [{ bearerAuth: [] }]
|
|
2052
3293
|
};
|
|
3294
|
+
const paths = spec.paths;
|
|
3295
|
+
for (const [routePath, operations] of Object.entries(paths)) {
|
|
3296
|
+
for (const [method, operation] of Object.entries(operations)) {
|
|
3297
|
+
const routeKey = `${method.toUpperCase()} ${routePath}`;
|
|
3298
|
+
if (!(routeKey in auth_1.ROUTE_SCOPES))
|
|
3299
|
+
continue;
|
|
3300
|
+
operation['x-accepted-scopes'] = [
|
|
3301
|
+
...auth_1.ROUTE_SCOPES[routeKey],
|
|
3302
|
+
'admin'
|
|
3303
|
+
];
|
|
3304
|
+
}
|
|
3305
|
+
}
|
|
3306
|
+
return spec;
|
|
2053
3307
|
}
|
|
2054
3308
|
exports.getOpenApiSpec = getOpenApiSpec;
|
|
2055
3309
|
function jsonContent(schema) {
|