beignet 0.15.0 → 0.16.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 +25 -13
- package/dist/cli/beignet-node.js +103 -4
- package/dist/cli/beignet-node.js.map +1 -1
- package/dist/cli/cli.js +16 -6
- package/dist/cli/cli.js.map +1 -1
- package/dist/cli/config.js +17 -2
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/daemon.js +19 -4
- package/dist/cli/daemon.js.map +1 -1
- package/dist/cli/openapi.js +56 -11
- package/dist/cli/openapi.js.map +1 -1
- package/dist/cli/webhooks.js +63 -11
- package/dist/cli/webhooks.js.map +1 -1
- package/dist/lightning/node/lightning-node.js +216 -41
- package/dist/lightning/node/lightning-node.js.map +1 -1
- package/dist/lightning/node/types.js.map +1 -1
- package/dist/lightning/swaps/client.js +129 -1
- package/dist/lightning/swaps/client.js.map +1 -1
- package/dist/lightning/swaps/engine-common.js +97 -0
- package/dist/lightning/swaps/engine-common.js.map +1 -0
- package/dist/lightning/swaps/index.js +2 -0
- package/dist/lightning/swaps/index.js.map +1 -1
- package/dist/lightning/swaps/ledger.js +15 -15
- package/dist/lightning/swaps/ledger.js.map +1 -1
- package/dist/lightning/swaps/messages.js +148 -3
- package/dist/lightning/swaps/messages.js.map +1 -1
- package/dist/lightning/swaps/reverse-engine.js +25 -80
- package/dist/lightning/swaps/reverse-engine.js.map +1 -1
- package/dist/lightning/swaps/submarine-engine.js +1606 -0
- package/dist/lightning/swaps/submarine-engine.js.map +1 -0
- package/dist/types/cli/beignet-node.d.ts +9 -1
- package/dist/types/cli/types.d.ts +49 -1
- package/dist/types/cli/webhooks.d.ts +3 -0
- package/dist/types/lightning/node/lightning-node.d.ts +11 -2
- package/dist/types/lightning/node/types.d.ts +19 -0
- package/dist/types/lightning/swaps/client.d.ts +31 -1
- package/dist/types/lightning/swaps/engine-common.d.ts +10 -0
- package/dist/types/lightning/swaps/index.d.ts +2 -0
- package/dist/types/lightning/swaps/ledger.d.ts +14 -1
- package/dist/types/lightning/swaps/messages.d.ts +51 -2
- package/dist/types/lightning/swaps/reverse-engine.d.ts +1 -0
- package/dist/types/lightning/swaps/submarine-engine.d.ts +144 -0
- package/docs/AI_AGENT_GUIDE.md +5 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -497,23 +497,35 @@ node can run for others, each an explicit opt-in switched on with an exact
|
|
|
497
497
|
The SSE stream carries `ffor:state`, `ffor:settled`, `ffor:delegated-failed`,
|
|
498
498
|
`ffor:enforce` and the witness and issuer events.
|
|
499
499
|
|
|
500
|
-
###
|
|
500
|
+
### Swaps (Lightning to on-chain, and on-chain to Lightning)
|
|
501
501
|
|
|
502
|
-
A beignet node can serve
|
|
503
|
-
peer pays a hold invoice, this node funds a P2WSH
|
|
504
|
-
chain with its preimage, and the claim settles
|
|
505
|
-
|
|
506
|
-
own
|
|
502
|
+
A beignet node can serve swaps to any Lightning peer in both directions.
|
|
503
|
+
Reverse (issue #737): the peer pays a hold invoice, this node funds a P2WSH
|
|
504
|
+
contract the peer claims on chain with its preimage, and the claim settles
|
|
505
|
+
the hold. Submarine (issue #743): the peer locks coins in a P2WSH contract,
|
|
506
|
+
this node pays the peer's own invoice under an absolute HTLC expiry ceiling,
|
|
507
|
+
and the preimage that payment reveals claims the coins. Each direction is an
|
|
508
|
+
explicit opt-in switched on with an exact `true`, because it puts this node's
|
|
509
|
+
own funds at risk for peers:
|
|
507
510
|
|
|
508
511
|
| Env | Role |
|
|
509
512
|
|---|---|
|
|
510
513
|
| `BEIGNET_SWAPS` | Serve reverse swaps. `BEIGNET_SWAP_FLAT_FEE_SAT` and `BEIGNET_SWAP_FEE_PPM` price them; `BEIGNET_SWAP_MIN_SAT`, `BEIGNET_SWAP_MAX_SAT`, `BEIGNET_SWAP_MAX_EXPOSURE_SAT` and `BEIGNET_SWAP_MAX_CONCURRENT` cap what is at risk; `BEIGNET_SWAP_REFUND_DELTA_BLOCKS`, `BEIGNET_SWAP_FUNDING_CONFS` and `BEIGNET_SWAP_RESOLUTION_CONFS` set the timing. `GET /swaps/status`, `GET /swaps`, `POST /swaps/cancel`. |
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
514
|
+
| `BEIGNET_SWAP_SUBMARINE` | With `BEIGNET_SWAPS`, also serve submarine swaps (on-chain to Lightning): a peer locks coins in a contract, this node pays the peer's invoice under an absolute HTLC expiry ceiling and claims the coins with the preimage. `BEIGNET_SWAP_CLAIM_SAFETY_BLOCKS`, `BEIGNET_SWAP_PAYMENT_MAX_FEE_PPM`, `BEIGNET_SWAP_CLAIM_BUMP_INTERVAL_BLOCKS` and `BEIGNET_SWAP_SUBMARINE_REFUND_DELTA_BLOCKS` set the direction's margins; the fee and exposure caps above apply to both. |
|
|
515
|
+
|
|
516
|
+
The reverse provider funds only against the complete committed MPP set of
|
|
517
|
+
the hold invoice, settles the hold the moment a claim reveals the preimage
|
|
518
|
+
(mempool included), and cancels the hold only after its own refund has
|
|
519
|
+
confirmed to policy depth; never because the refund height passed. The
|
|
520
|
+
submarine provider pays only once the peer's funding has confirmed to policy
|
|
521
|
+
depth and been re-verified unspent immediately before the dispatch, binds
|
|
522
|
+
every HTLC of the payment to `refundHeight` minus its claim margins, judges
|
|
523
|
+
the payment by the node's own HTLC view (never by a wall clock or a failed
|
|
524
|
+
record while an HTLC is out), and persists its claim before broadcasting it.
|
|
525
|
+
The SSE stream carries `swap:created` through `swap:settled`, `swap:refunded`
|
|
526
|
+
and `swap:exposed` for the reverse direction and `swap:funding-seen`,
|
|
527
|
+
`swap:paying`, `swap:preimage`, `swap:claim-broadcast`,
|
|
528
|
+
`swap:claim-confirmed` and `swap:payment-failed` for the submarine one.
|
|
517
529
|
|
|
518
530
|
## Protocol layer (advanced)
|
|
519
531
|
|
|
@@ -616,7 +628,7 @@ LightningNode High-level API (EventEmitter)
|
|
|
616
628
|
| `recovery/` | Safety transition layer: atomic persistence, the durable outbound-message outbox, the opt-in hash-chained recovery journal, and the peer_storage Recovery Capsule |
|
|
617
629
|
| `liquidity/` | JIT channel receive (LSP role): intercept SCIDs, held HTLCs, zero-conf open or splice, then forward; the opening fee is skimmed off the delivery for wallets that accept it, or charged to the sender through the invoice hint (hop mode) for wallets that cannot settle a short HTLC |
|
|
618
630
|
| `direct-funding/` | Third-party direct funding: the signed payment request envelope, sealed frames, protocol messages, outstanding-request store, the transport registry with its direct-peer, onion and blind-relay lanes, the receiver engine that turns a payer's offered UTXO into channel funding, and the payer engine that verifies and signs it |
|
|
619
|
-
| `swaps/` | Swaps: the P2WSH HTLC contract, claim/refund transactions, preimage extraction, admission policies, the durable swap ledger, the chain resolver, the wire protocol, and the
|
|
631
|
+
| `swaps/` | Swaps: the P2WSH HTLC contract, claim/refund transactions, preimage extraction, admission policies, the durable swap ledger, the chain resolver, the wire protocol, and the swap provider engines (reverse: Lightning to on-chain; submarine: on-chain to Lightning) |
|
|
620
632
|
| `l402/` | L402 (Lightning HTTP 402) client: challenge parsing, macaroon reading, paid credentials |
|
|
621
633
|
| `node/` | LightningNode orchestrator, the main protocol-layer entry point |
|
|
622
634
|
| `wallet/` | WalletFundingProvider, adapts the on-chain Wallet for auto-funded opens |
|
package/dist/cli/beignet-node.js
CHANGED
|
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.BeignetNode = exports.jitInvoiceError = exports.jsonSafeEvent = exports.jitReceiveRefusal = exports.leaseRatesRefusal = exports.clampDirectFundingMinimum = exports.MAX_ASYNC_SPEND_CLAIMS = exports.ASYNC_SPEND_CLAIM_TTL_MS = exports.jsonToRouteHops = exports.routeHopsToJson = exports.spliceRefusalError = exports.decodeOfferInput = exports.paymentSpendSats = exports.spendLimitSats = exports.decodeInvoiceInput = exports.parseScid = exports.formatScid = exports.gossipPrimeLatch = exports.defaultDataDirForMnemonic = exports.parseRecoveryMode = void 0;
|
|
26
|
+
exports.BeignetNode = exports.jitInvoiceError = exports.holdInvoiceEvent = exports.jsonSafeEvent = exports.jitReceiveRefusal = exports.leaseRatesRefusal = exports.clampDirectFundingMinimum = exports.MAX_ASYNC_SPEND_CLAIMS = exports.ASYNC_SPEND_CLAIM_TTL_MS = exports.jsonToRouteHops = exports.routeHopsToJson = exports.spliceRefusalError = exports.decodeOfferInput = exports.paymentSpendSats = exports.spendLimitSats = exports.decodeInvoiceInput = exports.parseScid = exports.formatScid = exports.gossipPrimeLatch = exports.defaultDataDirForMnemonic = exports.parseRecoveryMode = void 0;
|
|
27
27
|
const path = __importStar(require("path"));
|
|
28
28
|
const fs = __importStar(require("fs"));
|
|
29
29
|
const net = __importStar(require("net"));
|
|
@@ -430,6 +430,15 @@ function jsonSafeEvent(value) {
|
|
|
430
430
|
return value;
|
|
431
431
|
}
|
|
432
432
|
exports.jsonSafeEvent = jsonSafeEvent;
|
|
433
|
+
function holdInvoiceEvent(e) {
|
|
434
|
+
return {
|
|
435
|
+
paymentHash: e.paymentHash.toString('hex'),
|
|
436
|
+
state: e.state,
|
|
437
|
+
heldAmountMsat: e.heldAmountMsat.toString(),
|
|
438
|
+
htlcCount: e.htlcCount
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
exports.holdInvoiceEvent = holdInvoiceEvent;
|
|
433
442
|
function jitInvoiceError(err) {
|
|
434
443
|
if (err instanceof errors_1.BeignetError)
|
|
435
444
|
return err;
|
|
@@ -968,6 +977,29 @@ class BeignetNode extends events_1.EventEmitter {
|
|
|
968
977
|
refundDeltaBlocks: opts.swaps.refundDeltaBlocks
|
|
969
978
|
}
|
|
970
979
|
}
|
|
980
|
+
: {}),
|
|
981
|
+
...(opts.swaps.submarine === true
|
|
982
|
+
? {
|
|
983
|
+
submarine: {
|
|
984
|
+
enabled: true,
|
|
985
|
+
...(opts.swaps.claimSafetyBlocks !== undefined
|
|
986
|
+
? { claimSafetyBlocks: opts.swaps.claimSafetyBlocks }
|
|
987
|
+
: {}),
|
|
988
|
+
...(opts.swaps.paymentMaxFeePpm !== undefined
|
|
989
|
+
? { paymentMaxFeePpm: opts.swaps.paymentMaxFeePpm }
|
|
990
|
+
: {}),
|
|
991
|
+
...(opts.swaps.claimBumpIntervalBlocks !== undefined
|
|
992
|
+
? {
|
|
993
|
+
claimBumpIntervalBlocks: opts.swaps.claimBumpIntervalBlocks
|
|
994
|
+
}
|
|
995
|
+
: {}),
|
|
996
|
+
...(opts.swaps.submarineRefundDeltaBlocks !== undefined
|
|
997
|
+
? {
|
|
998
|
+
refundDeltaBlocks: opts.swaps.submarineRefundDeltaBlocks
|
|
999
|
+
}
|
|
1000
|
+
: {})
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
971
1003
|
: {})
|
|
972
1004
|
}
|
|
973
1005
|
: undefined,
|
|
@@ -1151,6 +1183,29 @@ class BeignetNode extends events_1.EventEmitter {
|
|
|
1151
1183
|
});
|
|
1152
1184
|
this.emit('invoice:settled', info);
|
|
1153
1185
|
});
|
|
1186
|
+
this.node.on('hold:accepted', (e) => {
|
|
1187
|
+
const info = holdInvoiceEvent(e);
|
|
1188
|
+
this.emit('hold:accepted', info);
|
|
1189
|
+
this.log('info', 'Hold invoice accepted', {
|
|
1190
|
+
paymentHash: info.paymentHash,
|
|
1191
|
+
heldAmountMsat: info.heldAmountMsat,
|
|
1192
|
+
htlcCount: info.htlcCount
|
|
1193
|
+
});
|
|
1194
|
+
});
|
|
1195
|
+
this.node.on('hold:settled', (e) => {
|
|
1196
|
+
this.emit('hold:settled', holdInvoiceEvent(e));
|
|
1197
|
+
});
|
|
1198
|
+
this.node.on('hold:cancelled', (e) => {
|
|
1199
|
+
this.emit('hold:cancelled', {
|
|
1200
|
+
...holdInvoiceEvent({
|
|
1201
|
+
paymentHash: e.paymentHash,
|
|
1202
|
+
state: 'CANCELLED',
|
|
1203
|
+
heldAmountMsat: e.heldAmountMsat,
|
|
1204
|
+
htlcCount: e.htlcsFailed
|
|
1205
|
+
}),
|
|
1206
|
+
reason: e.reason
|
|
1207
|
+
});
|
|
1208
|
+
});
|
|
1154
1209
|
this.node.on('htlc:forward', (inChannelId, outChannelId, amountMsat, paymentHash) => {
|
|
1155
1210
|
this.log('info', 'HTLC forward', {
|
|
1156
1211
|
paymentHash: paymentHash.toString('hex'),
|
|
@@ -1248,7 +1303,27 @@ class BeignetNode extends events_1.EventEmitter {
|
|
|
1248
1303
|
'ffor:witness-recorded',
|
|
1249
1304
|
'ffor:witness-released',
|
|
1250
1305
|
'ffor:issuer-provisioned',
|
|
1251
|
-
'ffor:issuer-issued'
|
|
1306
|
+
'ffor:issuer-issued',
|
|
1307
|
+
'swap:created',
|
|
1308
|
+
'swap:held',
|
|
1309
|
+
'swap:funding',
|
|
1310
|
+
'swap:funded',
|
|
1311
|
+
'swap:claimed',
|
|
1312
|
+
'swap:settled',
|
|
1313
|
+
'swap:refund-broadcast',
|
|
1314
|
+
'swap:refunded',
|
|
1315
|
+
'swap:hold-cancelled',
|
|
1316
|
+
'swap:exposed',
|
|
1317
|
+
'swap:failed',
|
|
1318
|
+
'swap:funding-seen',
|
|
1319
|
+
'swap:funding-lost',
|
|
1320
|
+
'swap:paying',
|
|
1321
|
+
'swap:payment-unresolved',
|
|
1322
|
+
'swap:preimage',
|
|
1323
|
+
'swap:claim-broadcast',
|
|
1324
|
+
'swap:claim-confirmed',
|
|
1325
|
+
'swap:payment-failed',
|
|
1326
|
+
'swap:cancelled'
|
|
1252
1327
|
]) {
|
|
1253
1328
|
this.node.on(evt, (data) => {
|
|
1254
1329
|
this.emit(evt, jsonSafeEvent(data));
|
|
@@ -4215,7 +4290,26 @@ class BeignetNode extends events_1.EventEmitter {
|
|
|
4215
4290
|
timeouts: status.timeouts,
|
|
4216
4291
|
counts: status.counts,
|
|
4217
4292
|
exposedSat: Number(status.exposedSat),
|
|
4218
|
-
exposedCount: status.exposedCount
|
|
4293
|
+
exposedCount: status.exposedCount,
|
|
4294
|
+
submarine: status.submarine.enabled
|
|
4295
|
+
? {
|
|
4296
|
+
enabled: true,
|
|
4297
|
+
fee: {
|
|
4298
|
+
flatFeeSat: Number(status.submarine.fee.flatFeeSat),
|
|
4299
|
+
feePpm: status.submarine.fee.feePpm
|
|
4300
|
+
},
|
|
4301
|
+
limits: {
|
|
4302
|
+
minSwapSat: Number(status.submarine.limits.minSwapSat),
|
|
4303
|
+
maxSwapSat: Number(status.submarine.limits.maxSwapSat),
|
|
4304
|
+
maxTotalExposureSat: Number(status.submarine.limits.maxTotalExposureSat),
|
|
4305
|
+
maxConcurrentSwaps: status.submarine.limits.maxConcurrentSwaps
|
|
4306
|
+
},
|
|
4307
|
+
timeouts: status.submarine.timeouts,
|
|
4308
|
+
counts: status.submarine.counts,
|
|
4309
|
+
exposedSat: Number(status.submarine.exposedSat),
|
|
4310
|
+
exposedCount: status.submarine.exposedCount
|
|
4311
|
+
}
|
|
4312
|
+
: { enabled: false }
|
|
4219
4313
|
};
|
|
4220
4314
|
}
|
|
4221
4315
|
listSwaps(id) {
|
|
@@ -4422,7 +4516,12 @@ class BeignetNode extends events_1.EventEmitter {
|
|
|
4422
4516
|
description: opts.description || '',
|
|
4423
4517
|
expiry: opts.expiry,
|
|
4424
4518
|
hold: true,
|
|
4425
|
-
paymentHash: Buffer.from(opts.paymentHash, 'hex')
|
|
4519
|
+
paymentHash: Buffer.from(opts.paymentHash, 'hex'),
|
|
4520
|
+
...(opts.minFinalCltvExpiry !== undefined
|
|
4521
|
+
? {
|
|
4522
|
+
minFinalCltvExpiry: requireFinalCltvExpiry(opts.minFinalCltvExpiry)
|
|
4523
|
+
}
|
|
4524
|
+
: {})
|
|
4426
4525
|
});
|
|
4427
4526
|
const info = {
|
|
4428
4527
|
bolt11: result.bolt11,
|