ln-service 53.14.1 → 53.16.1
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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Versions
|
|
2
2
|
|
|
3
|
+
## 53.16.1
|
|
4
|
+
|
|
5
|
+
- `getFailedPayments`, `getPayments`, `getPendingPayments`: Remove
|
|
6
|
+
`confirmed_at` date when a payment is not confirmed, add `created_at` and
|
|
7
|
+
`failed_at` dates for attempt start and attempt failed dates.
|
|
8
|
+
|
|
9
|
+
## 53.16.0
|
|
10
|
+
|
|
11
|
+
- `beginGroupSigningSession`: Add method to start a MuSig2 signing session
|
|
12
|
+
- `endGroupSigningSession`: Add method to complete a MuSig2 signing session
|
|
13
|
+
- `updateGroupSigningSession`: Add method to add nonces to a MuSig2 session
|
|
14
|
+
|
|
15
|
+
## 53.15.0
|
|
16
|
+
|
|
17
|
+
- `getRouteToDestination`, `isDestinationPayable`, `pay`,
|
|
18
|
+
`payViaPaymentDetails`, `payViaPaymentRequest`, `probeForRoute`,
|
|
19
|
+
`subscribeToPayViaDetails`, `subscribeToPayViaRequest`,
|
|
20
|
+
`subscribeToProbeForRoute` - add support for pathfinding `confidence`
|
|
21
|
+
|
|
3
22
|
## 53.14.1
|
|
4
23
|
|
|
5
24
|
- `signTransaction`: Fix multi-input signing for upcoming Taproot API changes
|
package/README.md
CHANGED
|
@@ -105,6 +105,7 @@ for `unlocker` methods.
|
|
|
105
105
|
- [addExternalSocket](#addexternalsocket) - Advertise a new p2p host:ip address
|
|
106
106
|
- [addPeer](#addpeer) - Connect to a peer
|
|
107
107
|
- [authenticatedLndGrpc](#authenticatedlndgrpc) - LND API Object
|
|
108
|
+
- [beginGroupSigningSession](#begingroupsigningsession) - Start MuSig2 session
|
|
108
109
|
- [broadcastChainTransaction](#broadcastchaintransaction) - Push a chain tx
|
|
109
110
|
- [cancelHodlInvoice](#cancelhodlinvoice) - Cancel a held or any open invoice
|
|
110
111
|
- [cancelPendingChannel](#cancelpendingchannel) - Cancel a pending open channel
|
|
@@ -132,6 +133,7 @@ for `unlocker` methods.
|
|
|
132
133
|
- [disableChannel](#disablechannel) - Disable a channel for outgoing payments
|
|
133
134
|
- [disconnectWatchtower](#disconnectwatchtower) - Disconnect a watchtower
|
|
134
135
|
- [enableChannel](#enablechannel) - Enable a channel for outgoing payments
|
|
136
|
+
- [endGroupSigningSession](#endgroupsigningsession) - Complete MuSig2 session
|
|
135
137
|
- [fundPendingChannels](#fundpendingchannels) - Fund pending open channels
|
|
136
138
|
- [fundPsbt](#fundpsbt) - Create an unsigned PSBT with funding inputs and
|
|
137
139
|
spending outputs
|
|
@@ -256,6 +258,7 @@ for `unlocker` methods.
|
|
|
256
258
|
transaction
|
|
257
259
|
- [updateColor](#updatecolor) - Update node graph color value
|
|
258
260
|
- [updateConnectedWatchtower](#updateconnectedwatchtower) - Update watchtower
|
|
261
|
+
- [updateGroupSigningSession](#updategroupsigningsession) - Sign with MuSig2
|
|
259
262
|
- [updatePathfindingSettings](#updatepathfindingsettings) - Update pathfinding
|
|
260
263
|
configuration
|
|
261
264
|
- [updateRoutingFees](#updateroutingfees) - Change routing fees
|
|
@@ -277,7 +280,7 @@ for `unlocker` methods.
|
|
|
277
280
|
- [ln-accounting](https://npmjs.com/package/ln-accounting) - accounting records
|
|
278
281
|
- [ln-docker-daemons](https://github.com/alexbosworth/ln-docker-daemons) -
|
|
279
282
|
run regtest integration tests
|
|
280
|
-
- [ln-pathfinding](https://npmjs.com/package/ln-
|
|
283
|
+
- [ln-pathfinding](https://npmjs.com/package/ln-pathfinding) - pathfinding
|
|
281
284
|
utilities
|
|
282
285
|
- [ln-sync](https://www.npmjs.com/package/ln-sync) - metadata helper methods
|
|
283
286
|
- [probing](https://npmjs.com/package/probing) - payment probing utilities
|
|
@@ -380,6 +383,46 @@ const {lnd} = lnService.authenticatedLndGrpc({
|
|
|
380
383
|
const wallet = await lnService.getWalletInfo({lnd});
|
|
381
384
|
```
|
|
382
385
|
|
|
386
|
+
### beginGroupSigningSession
|
|
387
|
+
|
|
388
|
+
Start a MuSig2 group signing session
|
|
389
|
+
|
|
390
|
+
Requires LND built with `signrpc`, `walletrpc` build tags
|
|
391
|
+
|
|
392
|
+
Requires `address:read`, `signer:generate` permissions
|
|
393
|
+
|
|
394
|
+
This method is not supported in LND 0.14.3 and below
|
|
395
|
+
|
|
396
|
+
{
|
|
397
|
+
lnd: <Authenticated LND API Object>
|
|
398
|
+
[is_key_spend]: <Key Is BIP 86 Key Spend Key Bool>
|
|
399
|
+
key_family: <HD Seed Key Family Number>
|
|
400
|
+
key_index: <Key Index Number>
|
|
401
|
+
public_keys: [<External Public Key Hex String>]
|
|
402
|
+
[root_hash]: <Taproot Script Root Hash Hex String>
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
@returns via cbk or Promise
|
|
406
|
+
{
|
|
407
|
+
external_key: <Final Script or Top Level Public Key Hex String>
|
|
408
|
+
id: <Session Id Hex String>
|
|
409
|
+
[internal_key]: <Internal Top Level Public Key Hex String>
|
|
410
|
+
nonce: <Session Compound Nonces Hex String>
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
Example:
|
|
414
|
+
|
|
415
|
+
```node
|
|
416
|
+
const {beginGroupSigningSession} = require('ln-service');
|
|
417
|
+
|
|
418
|
+
const session = await beginGroupSigningSession({
|
|
419
|
+
lnd,
|
|
420
|
+
key_family: 0,
|
|
421
|
+
key_index: 0,
|
|
422
|
+
public_keys: [externalPublicKey],
|
|
423
|
+
});
|
|
424
|
+
```
|
|
425
|
+
|
|
383
426
|
### broadcastChainTransaction
|
|
384
427
|
|
|
385
428
|
Publish a raw blockchain transaction to Blockchain network peers
|
|
@@ -1118,6 +1161,36 @@ await enableChannel({
|
|
|
1118
1161
|
});
|
|
1119
1162
|
```
|
|
1120
1163
|
|
|
1164
|
+
### endGroupSigningSession
|
|
1165
|
+
|
|
1166
|
+
Complete a MuSig2 signing session
|
|
1167
|
+
|
|
1168
|
+
Requires LND built with `signrpc` build tag
|
|
1169
|
+
|
|
1170
|
+
Requires `signer:generate` permission
|
|
1171
|
+
|
|
1172
|
+
This method is not supported in LND 0.14.3 and below
|
|
1173
|
+
|
|
1174
|
+
{
|
|
1175
|
+
id: <Session Id Hex String>
|
|
1176
|
+
lnd: <Authenticated LND API Object>
|
|
1177
|
+
[signatures]: [<Combine External Partial Signature Hex String>]
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
@returns via cbk or Promise
|
|
1181
|
+
{
|
|
1182
|
+
[signature]: <Combined Signature Hex String>
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
Example:
|
|
1186
|
+
|
|
1187
|
+
```node
|
|
1188
|
+
const {endGroupSigningSession} = require('ln-service');
|
|
1189
|
+
|
|
1190
|
+
// Cancel a group signing session
|
|
1191
|
+
await endGroupSigningSession({id, lnd});
|
|
1192
|
+
```
|
|
1193
|
+
|
|
1121
1194
|
### fundPendingChannels
|
|
1122
1195
|
|
|
1123
1196
|
Fund pending channels
|
|
@@ -1746,7 +1819,9 @@ Requires `offchain:read` permission
|
|
|
1746
1819
|
message: <Error Message String>
|
|
1747
1820
|
}
|
|
1748
1821
|
[index]: <Payment Add Index Number>
|
|
1749
|
-
[confirmed_at]: <Payment
|
|
1822
|
+
[confirmed_at]: <Payment Attempt Succeeded At ISO 8601 Date String>
|
|
1823
|
+
created_at: <Attempt Was Started At ISO 8601 Date String>
|
|
1824
|
+
[failed_at]: <Payment Attempt Failed At ISO 8601 Date String>
|
|
1750
1825
|
is_confirmed: <Payment Attempt Succeeded Bool>
|
|
1751
1826
|
is_failed: <Payment Attempt Failed Bool>
|
|
1752
1827
|
is_pending: <Payment Attempt is Waiting For Resolution Bool>
|
|
@@ -2529,6 +2604,9 @@ Requires `offchain:read` permission
|
|
|
2529
2604
|
}
|
|
2530
2605
|
message: <Error Message String>
|
|
2531
2606
|
}
|
|
2607
|
+
[confirmed_at]: <Payment Attempt Succeeded At ISO 8601 Date String>
|
|
2608
|
+
created_at: <Attempt Was Started At ISO 8601 Date String>
|
|
2609
|
+
[failed_at]: <Payment Attempt Failed At ISO 8601 Date String>
|
|
2532
2610
|
is_confirmed: <Payment Attempt Succeeded Bool>
|
|
2533
2611
|
is_failed: <Payment Attempt Failed Bool>
|
|
2534
2612
|
is_pending: <Payment Attempt is Waiting For Resolution Bool>
|
|
@@ -2744,7 +2822,9 @@ Requires `offchain:read` permission
|
|
|
2744
2822
|
message: <Error Message String>
|
|
2745
2823
|
}
|
|
2746
2824
|
[index]: <Payment Add Index Number>
|
|
2747
|
-
[confirmed_at]: <Payment
|
|
2825
|
+
[confirmed_at]: <Payment Attempt Succeeded At ISO 8601 Date String>
|
|
2826
|
+
created_at: <Attempt Was Started At ISO 8601 Date String>
|
|
2827
|
+
[failed_at]: <Payment Attempt Failed At ISO 8601 Date String>
|
|
2748
2828
|
is_confirmed: <Payment Attempt Succeeded Bool>
|
|
2749
2829
|
is_failed: <Payment Attempt Failed Bool>
|
|
2750
2830
|
is_pending: <Payment Attempt is Waiting For Resolution Bool>
|
|
@@ -2931,8 +3011,11 @@ Call this iteratively after failed route attempts to get new routes
|
|
|
2931
3011
|
|
|
2932
3012
|
Requires `info:read` permission
|
|
2933
3013
|
|
|
3014
|
+
Preferred `confidence` is not supported on LND 0.14.3 and below
|
|
3015
|
+
|
|
2934
3016
|
{
|
|
2935
3017
|
[cltv_delta]: <Final CLTV Delta Number>
|
|
3018
|
+
[confidence]: <Preferred Route Confidence Number Out of One Million Number>
|
|
2936
3019
|
destination: <Final Send Destination Hex Encoded Public Key String>
|
|
2937
3020
|
[features]: [{
|
|
2938
3021
|
bit: <Feature Bit Number>
|
|
@@ -3331,8 +3414,11 @@ Determine if a payment destination is actually payable by probing it
|
|
|
3331
3414
|
|
|
3332
3415
|
Requires `offchain:write` permission
|
|
3333
3416
|
|
|
3417
|
+
Preferred `confidence` is not supported on LND 0.14.3 and below
|
|
3418
|
+
|
|
3334
3419
|
{
|
|
3335
3420
|
[cltv_delta]: <Final CLTV Delta Number>
|
|
3421
|
+
[confidence]: <Preferred Route Confidence Number Out of One Million Number>
|
|
3336
3422
|
destination: <Pay to Node with Public Key Hex String>
|
|
3337
3423
|
[incoming_peer]: <Pay Through Specific Final Hop Public Key Hex String>
|
|
3338
3424
|
lnd: <Authenticated LND API Object>
|
|
@@ -3612,7 +3698,10 @@ Requires `offchain:write` permission
|
|
|
3612
3698
|
|
|
3613
3699
|
`max_path_mtokens` is not supported in LND 0.12.0 or below
|
|
3614
3700
|
|
|
3701
|
+
Preferred `confidence` is not supported on LND 0.14.3 and below
|
|
3702
|
+
|
|
3615
3703
|
{
|
|
3704
|
+
[confidence]: <Preferred Route Confidence Number Out of One Million Number>
|
|
3616
3705
|
[incoming_peer]: <Pay Through Specific Final Hop Public Key Hex String>
|
|
3617
3706
|
lnd: <Authenticated LND API Object>
|
|
3618
3707
|
[max_fee]: <Maximum Additional Fee Tokens To Pay Number>
|
|
@@ -3699,8 +3788,11 @@ Requires `offchain:write` permission
|
|
|
3699
3788
|
|
|
3700
3789
|
`max_path_mtokens` is not supported in LND 0.12.0 or below
|
|
3701
3790
|
|
|
3791
|
+
Preferred `confidence` is not supported on LND 0.14.3 and below
|
|
3792
|
+
|
|
3702
3793
|
{
|
|
3703
3794
|
[cltv_delta]: <Final CLTV Delta Number>
|
|
3795
|
+
[confidence]: <Preferred Route Confidence Number Out of One Million Number>
|
|
3704
3796
|
destination: <Destination Public Key String>
|
|
3705
3797
|
[features]: [{
|
|
3706
3798
|
bit: <Feature Bit Number>
|
|
@@ -3786,7 +3878,10 @@ Requires `offchain:write` permission
|
|
|
3786
3878
|
|
|
3787
3879
|
`max_path_mtokens` is not supported in LND 0.12.0 or below
|
|
3788
3880
|
|
|
3881
|
+
Preferred `confidence` is not supported on LND 0.14.3 and below
|
|
3882
|
+
|
|
3789
3883
|
{
|
|
3884
|
+
[confidence]: <Preferred Route Confidence Number Out of One Million Number>
|
|
3790
3885
|
[incoming_peer]: <Pay Through Specific Final Hop Public Key Hex String>
|
|
3791
3886
|
lnd: <Authenticated LND API Object>
|
|
3792
3887
|
[max_fee]: <Maximum Fee Tokens To Pay Number>
|
|
@@ -3988,8 +4083,11 @@ If `total_mtokens` are specified, a `payment` nonce is required.
|
|
|
3988
4083
|
|
|
3989
4084
|
Requires `offchain:write` permission
|
|
3990
4085
|
|
|
4086
|
+
Preferred `confidence` is not supported on LND 0.14.3 and below
|
|
4087
|
+
|
|
3991
4088
|
{
|
|
3992
4089
|
[cltv_delta]: <Final CLTV Delta Number>
|
|
4090
|
+
[confidence]: <Preferred Route Confidence Number Out of One Million Number>
|
|
3993
4091
|
destination: <Destination Public Key Hex String>
|
|
3994
4092
|
[features]: [{
|
|
3995
4093
|
bit: <Feature Bit Number>
|
|
@@ -5573,8 +5671,11 @@ Requires `offchain:write` permission
|
|
|
5573
5671
|
|
|
5574
5672
|
`max_path_mtokens` is not supported in LND 0.12.0 or below
|
|
5575
5673
|
|
|
5674
|
+
Preferred `confidence` is not supported on LND 0.14.3 and below
|
|
5675
|
+
|
|
5576
5676
|
{
|
|
5577
5677
|
[cltv_delta]: <Final CLTV Delta Number>
|
|
5678
|
+
[confidence]: <Preferred Route Confidence Number Out of One Million Number>
|
|
5578
5679
|
destination: <Destination Public Key String>
|
|
5579
5680
|
[features]: [{
|
|
5580
5681
|
bit: <Feature Bit Number>
|
|
@@ -5736,7 +5837,10 @@ Requires `offchain:write` permission
|
|
|
5736
5837
|
|
|
5737
5838
|
`max_path_mtokens` is not supported in LND 0.12.0 or below
|
|
5738
5839
|
|
|
5840
|
+
Preferred `confidence` is not supported on LND 0.14.3 and below
|
|
5841
|
+
|
|
5739
5842
|
{
|
|
5843
|
+
[confidence]: <Preferred Route Confidence Number Out of One Million Number>
|
|
5740
5844
|
[incoming_peer]: <Pay Through Specific Final Hop Public Key Hex String>
|
|
5741
5845
|
lnd: <Authenticated LND API Object>
|
|
5742
5846
|
[max_fee]: <Maximum Fee Tokens To Pay Number>
|
|
@@ -6144,8 +6248,11 @@ Subscribe to a probe attempt
|
|
|
6144
6248
|
|
|
6145
6249
|
Requires `offchain:write` permission
|
|
6146
6250
|
|
|
6251
|
+
Preferred `confidence` is not supported on LND 0.14.3 and below
|
|
6252
|
+
|
|
6147
6253
|
{
|
|
6148
6254
|
[cltv_delta]: <Final CLTV Delta Number>
|
|
6255
|
+
[confidence]: <Preferred Route Confidence Number Out of One Million Number>
|
|
6149
6256
|
destination: <Destination Public Key Hex String>
|
|
6150
6257
|
[features]: [{
|
|
6151
6258
|
bit: <Feature Bit Number>
|
|
@@ -6734,6 +6841,43 @@ await updateConnectedWatchtower({
|
|
|
6734
6841
|
});
|
|
6735
6842
|
```
|
|
6736
6843
|
|
|
6844
|
+
### updateGroupSigningSession
|
|
6845
|
+
|
|
6846
|
+
Update a MuSig2 signing session with nonces and generate a partial sig
|
|
6847
|
+
|
|
6848
|
+
All remote nonces are expected to be passed
|
|
6849
|
+
|
|
6850
|
+
Requires LND built with `signrpc` build tag
|
|
6851
|
+
|
|
6852
|
+
Requires `signer:generate` permission
|
|
6853
|
+
|
|
6854
|
+
This method is not supported in LND 0.14.3 and below
|
|
6855
|
+
|
|
6856
|
+
{
|
|
6857
|
+
hash: <Hash to Sign Hex String>
|
|
6858
|
+
id: <MuSig2 Session Id Hex String>
|
|
6859
|
+
lnd: <Authenticated LND API Object>
|
|
6860
|
+
nonces: [<Nonce Hex String>]
|
|
6861
|
+
}
|
|
6862
|
+
|
|
6863
|
+
@returns via cbk or Promise
|
|
6864
|
+
{
|
|
6865
|
+
signature: <Partial Signature Hex String>
|
|
6866
|
+
}
|
|
6867
|
+
|
|
6868
|
+
Example:
|
|
6869
|
+
|
|
6870
|
+
```node
|
|
6871
|
+
const {updateGroupSigningSession} = require('ln-service');
|
|
6872
|
+
|
|
6873
|
+
const {signature} = await updateGroupSigningSession({
|
|
6874
|
+
lnd,
|
|
6875
|
+
hash: v1TxDigestHash,
|
|
6876
|
+
id: sessionId,
|
|
6877
|
+
nonces: [externalNonce],
|
|
6878
|
+
});
|
|
6879
|
+
```
|
|
6880
|
+
|
|
6737
6881
|
### updatePathfindingSettings
|
|
6738
6882
|
|
|
6739
6883
|
Update current pathfinding settings
|
package/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const {addExternalSocket} = require('lightning');
|
|
2
2
|
const {addPeer} = require('lightning');
|
|
3
3
|
const {authenticatedLndGrpc} = require('lightning');
|
|
4
|
+
const {beginGroupSigningSession} = require('lightning');
|
|
4
5
|
const {broadcastChainTransaction} = require('lightning');
|
|
5
6
|
const {cancelHodlInvoice} = require('lightning');
|
|
6
7
|
const {cancelPendingChannel} = require('lightning');
|
|
@@ -25,6 +26,7 @@ const {diffieHellmanComputeSecret} = require('lightning');
|
|
|
25
26
|
const {disableChannel} = require('lightning');
|
|
26
27
|
const {disconnectWatchtower} = require('lightning');
|
|
27
28
|
const {enableChannel} = require('lightning');
|
|
29
|
+
const {endGroupSigningSession} = require('lightning');
|
|
28
30
|
const {fundPendingChannels} = require('lightning');
|
|
29
31
|
const {fundPsbt} = require('lightning');
|
|
30
32
|
const {getAccessIds} = require('lightning');
|
|
@@ -135,6 +137,7 @@ const {updateAlias} = require('lightning');
|
|
|
135
137
|
const {updateChainTransaction} = require('lightning');
|
|
136
138
|
const {updateColor} = require('lightning');
|
|
137
139
|
const {updateConnectedWatchtower} = require('lightning');
|
|
140
|
+
const {updateGroupSigningSession} = require('lightning');
|
|
138
141
|
const {updatePathfindingSettings} = require('lightning');
|
|
139
142
|
const {updateRoutingFees} = require('lightning');
|
|
140
143
|
const {verifyAccess} = require('lightning');
|
|
@@ -147,6 +150,7 @@ module.exports = {
|
|
|
147
150
|
addExternalSocket,
|
|
148
151
|
addPeer,
|
|
149
152
|
authenticatedLndGrpc,
|
|
153
|
+
beginGroupSigningSession,
|
|
150
154
|
broadcastChainTransaction,
|
|
151
155
|
cancelHodlInvoice,
|
|
152
156
|
cancelPendingChannel,
|
|
@@ -171,6 +175,7 @@ module.exports = {
|
|
|
171
175
|
disableChannel,
|
|
172
176
|
disconnectWatchtower,
|
|
173
177
|
enableChannel,
|
|
178
|
+
endGroupSigningSession,
|
|
174
179
|
fundPendingChannels,
|
|
175
180
|
fundPsbt,
|
|
176
181
|
getAccessIds,
|
|
@@ -281,6 +286,7 @@ module.exports = {
|
|
|
281
286
|
updateChainTransaction,
|
|
282
287
|
updateColor,
|
|
283
288
|
updateConnectedWatchtower,
|
|
289
|
+
updateGroupSigningSession,
|
|
284
290
|
updatePathfindingSettings,
|
|
285
291
|
updateRoutingFees,
|
|
286
292
|
verifyAccess,
|
package/package.json
CHANGED
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"bolt07": "1.8.1",
|
|
11
11
|
"cors": "2.8.5",
|
|
12
|
-
"express": "4.
|
|
12
|
+
"express": "4.18.1",
|
|
13
13
|
"invoices": "2.0.6",
|
|
14
|
-
"lightning": "5.
|
|
14
|
+
"lightning": "5.15.1",
|
|
15
15
|
"macaroon": "3.0.4",
|
|
16
16
|
"morgan": "1.10.0",
|
|
17
|
-
"ws": "8.
|
|
17
|
+
"ws": "8.6.0"
|
|
18
18
|
},
|
|
19
19
|
"description": "Interaction helper for your Lightning Network daemon",
|
|
20
20
|
"devDependencies": {
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"bn.js": "5.2.0",
|
|
29
29
|
"bs58check": "2.1.2",
|
|
30
30
|
"ecpair": "2.0.1",
|
|
31
|
-
"ln-docker-daemons": "2.2.
|
|
31
|
+
"ln-docker-daemons": "2.2.10",
|
|
32
32
|
"p2tr": "1.3.1",
|
|
33
33
|
"portfinder": "1.0.28",
|
|
34
34
|
"psbt": "2.0.1",
|
|
@@ -70,5 +70,5 @@
|
|
|
70
70
|
"integration-test-0.12.0": "DOCKER_LND_VERSION=v0.12.0-beta npm run test",
|
|
71
71
|
"test": "echo $DOCKER_LND_VERSION && tap -j 2 --branches=1 --functions=1 --lines=1 --statements=1 -t 200 test/autopilotrpc-integration/*.js test/chainrpc-integration/*.js test/integration/*.js test/invoicesrpc-integration/*.js test/peersrpc-integration/*.js test/routerrpc-integration/*.js test/signerrpc-integration/*.js test/tower_clientrpc-integration/*.js test/tower_serverrpc-integration/*.js test/walletrpc-integration/*.js"
|
|
72
72
|
},
|
|
73
|
-
"version": "53.
|
|
73
|
+
"version": "53.16.1"
|
|
74
74
|
}
|
|
@@ -66,7 +66,7 @@ test(`Subscribe to chain transactions`, async ({end, equal, fail}) => {
|
|
|
66
66
|
.filter(n => !!n.is_outgoing);
|
|
67
67
|
|
|
68
68
|
if (!transaction) {
|
|
69
|
-
throw new Error('
|
|
69
|
+
throw new Error('ExpectedTransactionInSubscribeToChainAddressResult');
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
// Wait for generation to be over
|
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
const asyncRetry = require('async/retry');
|
|
2
|
+
const {address} = require('bitcoinjs-lib');
|
|
3
|
+
const {controlBlock} = require('p2tr');
|
|
4
|
+
const {createPsbt} = require('psbt');
|
|
5
|
+
const {hashForTree} = require('p2tr');
|
|
6
|
+
const {leafHash} = require('p2tr');
|
|
7
|
+
const {networks} = require('bitcoinjs-lib');
|
|
8
|
+
const {script} = require('bitcoinjs-lib');
|
|
9
|
+
const {spawnLightningCluster} = require('ln-docker-daemons');
|
|
10
|
+
const {test} = require('@alexbosworth/tap');
|
|
11
|
+
const {Transaction} = require('bitcoinjs-lib');
|
|
12
|
+
const {v1OutputScript} = require('p2tr');
|
|
13
|
+
|
|
14
|
+
const {beginGroupSigningSession} = require('./../../');
|
|
15
|
+
const {broadcastChainTransaction} = require('./../../');
|
|
16
|
+
const {createChainAddress} = require('./../../');
|
|
17
|
+
const {endGroupSigningSession} = require('./../../');
|
|
18
|
+
const {fundPsbt} = require('./../../');
|
|
19
|
+
const {getPublicKey} = require('./../../');
|
|
20
|
+
const {getUtxos} = require('./../../');
|
|
21
|
+
const {signPsbt} = require('./../../');
|
|
22
|
+
const {updateGroupSigningSession} = require('./../../');
|
|
23
|
+
|
|
24
|
+
const {compile} = script;
|
|
25
|
+
const count = 100;
|
|
26
|
+
const defaultInternalKey = '0350929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0';
|
|
27
|
+
const {from} = Buffer;
|
|
28
|
+
const {fromHex} = Transaction;
|
|
29
|
+
const hexAsBuffer = hex => Buffer.from(hex, 'hex');
|
|
30
|
+
const interval = 100;
|
|
31
|
+
const OP_CHECKSIG = 172;
|
|
32
|
+
const smallTokens = 2e5;
|
|
33
|
+
const times = 20;
|
|
34
|
+
const {toOutputScript} = address;
|
|
35
|
+
const tokens = 1e6;
|
|
36
|
+
|
|
37
|
+
// Starting a group signing session should result in a new MuSig2 session
|
|
38
|
+
test(`Begin group signing session`, async ({end, equal}) => {
|
|
39
|
+
const {kill, nodes} = await spawnLightningCluster({size: 2});
|
|
40
|
+
|
|
41
|
+
const [{generate, lnd}, target] = nodes;
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
await beginGroupSigningSession({
|
|
45
|
+
lnd,
|
|
46
|
+
is_key_spend: true,
|
|
47
|
+
key_family: 0,
|
|
48
|
+
key_index: 0,
|
|
49
|
+
public_keys: [Buffer.alloc(33, 2).toString('hex')],
|
|
50
|
+
});
|
|
51
|
+
} catch (err) {
|
|
52
|
+
// On LND 0.14.3 and below, group signing is not supported
|
|
53
|
+
if (err.slice().shift() === 501) {
|
|
54
|
+
await kill({});
|
|
55
|
+
|
|
56
|
+
return end();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
throw err;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// A Taproot script can be funded and spent with MuSig2
|
|
63
|
+
try {
|
|
64
|
+
await generate({count});
|
|
65
|
+
|
|
66
|
+
const controlKey = await getPublicKey({lnd, family: 0});
|
|
67
|
+
const targetKey = await getPublicKey({family: 0, lnd: target.lnd});
|
|
68
|
+
|
|
69
|
+
const controlGroup = await beginGroupSigningSession({
|
|
70
|
+
lnd,
|
|
71
|
+
is_key_spend: true,
|
|
72
|
+
key_family: 0,
|
|
73
|
+
key_index: controlKey.index,
|
|
74
|
+
public_keys: [targetKey.public_key],
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const targetGroup = await beginGroupSigningSession({
|
|
78
|
+
is_key_spend: true,
|
|
79
|
+
key_family: 0,
|
|
80
|
+
key_index: targetKey.index,
|
|
81
|
+
lnd: target.lnd,
|
|
82
|
+
public_keys: [controlKey.public_key],
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
equal(controlGroup.external_key, targetGroup.external_key, 'Equal e-keys');
|
|
86
|
+
equal(controlGroup.internal_key, targetGroup.internal_key, 'Equal i-keys');
|
|
87
|
+
|
|
88
|
+
const script = Buffer.concat([
|
|
89
|
+
Buffer.from([81]),
|
|
90
|
+
Buffer.from([32]),
|
|
91
|
+
hexAsBuffer(controlGroup.external_key),
|
|
92
|
+
]);
|
|
93
|
+
|
|
94
|
+
const [utxo] = (await getUtxos({lnd})).utxos.reverse();
|
|
95
|
+
|
|
96
|
+
// Make a PSBT paying to the Taproot output
|
|
97
|
+
const {psbt} = createPsbt({
|
|
98
|
+
outputs: [{tokens, script: script.toString('hex')}],
|
|
99
|
+
utxos: [{id: utxo.transaction_id, vout: utxo.transaction_vout}],
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Sign the PSBT
|
|
103
|
+
const signed = await signPsbt({
|
|
104
|
+
lnd,
|
|
105
|
+
psbt: (await fundPsbt({lnd, psbt})).psbt,
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// Send the tx to the chain
|
|
109
|
+
await broadcastChainTransaction({lnd, transaction: signed.transaction});
|
|
110
|
+
|
|
111
|
+
// Make a new tx that will spend the output back into the wallet
|
|
112
|
+
const tx = new Transaction();
|
|
113
|
+
|
|
114
|
+
// The new tx spends the Taproot output
|
|
115
|
+
tx.addInput(
|
|
116
|
+
fromHex(signed.transaction).getHash(),
|
|
117
|
+
fromHex(signed.transaction).outs.findIndex(n => n.value === tokens)
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
// Make an output to pay back into the wallet
|
|
121
|
+
const chainOutput = toOutputScript(
|
|
122
|
+
(await createChainAddress({lnd})).address,
|
|
123
|
+
networks.regtest
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
// Add output to the pay back transaction
|
|
127
|
+
tx.addOutput(chainOutput, smallTokens);
|
|
128
|
+
|
|
129
|
+
const [hashToSign] = tx.ins.map((input, i) => {
|
|
130
|
+
return tx.hashForWitnessV1(
|
|
131
|
+
i,
|
|
132
|
+
[script],
|
|
133
|
+
[tokens],
|
|
134
|
+
Transaction.SIGHASH_DEFAULT,
|
|
135
|
+
);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
const controlSign = await updateGroupSigningSession({
|
|
139
|
+
lnd,
|
|
140
|
+
hash: hashToSign.toString('hex'),
|
|
141
|
+
id: controlGroup.id,
|
|
142
|
+
nonces: [targetGroup.nonce],
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
const targetSign = await updateGroupSigningSession({
|
|
146
|
+
hash: hashToSign.toString('hex'),
|
|
147
|
+
id: targetGroup.id,
|
|
148
|
+
lnd: target.lnd,
|
|
149
|
+
nonces: [controlGroup.nonce],
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
await endGroupSigningSession({lnd: target.lnd, id: targetGroup.id});
|
|
153
|
+
|
|
154
|
+
const {signature} = await endGroupSigningSession({
|
|
155
|
+
lnd,
|
|
156
|
+
id: controlGroup.id,
|
|
157
|
+
signatures: [targetSign.signature],
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// Add the signature to the input
|
|
161
|
+
tx.ins.forEach((input, i) => tx.setWitness(i, [hexAsBuffer(signature)]));
|
|
162
|
+
|
|
163
|
+
await broadcastChainTransaction({lnd, transaction: tx.toHex()});
|
|
164
|
+
|
|
165
|
+
await asyncRetry({interval, times}, async () => {
|
|
166
|
+
await generate({});
|
|
167
|
+
|
|
168
|
+
const {utxos} = await getUtxos({lnd});
|
|
169
|
+
|
|
170
|
+
const utxo = utxos.find(n => n.transaction_id === tx.getId());
|
|
171
|
+
|
|
172
|
+
if (!utxo || !utxo.confirmation_count) {
|
|
173
|
+
throw new Error('ExpectedReceivedTaprootSpend');
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
} catch (err) {
|
|
177
|
+
equal(err, null, 'Expected no error');
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// A Taproot script can be funded and spent with MuSig2 for a script output
|
|
181
|
+
try {
|
|
182
|
+
await generate({count});
|
|
183
|
+
|
|
184
|
+
const controlKey = await getPublicKey({lnd, family: 0});
|
|
185
|
+
const targetKey = await getPublicKey({family: 0, lnd: target.lnd});
|
|
186
|
+
const unusedKey = (await getPublicKey({lnd, family: 805})).public_key;
|
|
187
|
+
|
|
188
|
+
const xOnlyUnused = hexAsBuffer(unusedKey.slice(2));
|
|
189
|
+
|
|
190
|
+
const witnessScript = compile([xOnlyUnused, OP_CHECKSIG]);
|
|
191
|
+
|
|
192
|
+
const branches = [{script: witnessScript.toString('hex')}];
|
|
193
|
+
|
|
194
|
+
const {hash} = hashForTree({branches});
|
|
195
|
+
|
|
196
|
+
const controlGroup = await beginGroupSigningSession({
|
|
197
|
+
lnd,
|
|
198
|
+
key_family: 0,
|
|
199
|
+
key_index: controlKey.index,
|
|
200
|
+
public_keys: [targetKey.public_key],
|
|
201
|
+
root_hash: hash,
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
const targetGroup = await beginGroupSigningSession({
|
|
205
|
+
key_family: 0,
|
|
206
|
+
key_index: targetKey.index,
|
|
207
|
+
lnd: target.lnd,
|
|
208
|
+
public_keys: [controlKey.public_key],
|
|
209
|
+
root_hash: hash,
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
equal(controlGroup.external_key, targetGroup.external_key, 'Equal e-keys');
|
|
213
|
+
equal(controlGroup.internal_key, targetGroup.internal_key, 'Equal i-keys');
|
|
214
|
+
|
|
215
|
+
const script = Buffer.concat([
|
|
216
|
+
from([81]),
|
|
217
|
+
from([32]),
|
|
218
|
+
hexAsBuffer(controlGroup.external_key),
|
|
219
|
+
]);
|
|
220
|
+
|
|
221
|
+
const [utxo] = (await getUtxos({lnd})).utxos.reverse();
|
|
222
|
+
|
|
223
|
+
// Make a PSBT paying to the Taproot output
|
|
224
|
+
const {psbt} = createPsbt({
|
|
225
|
+
outputs: [{tokens, script: script.toString('hex')}],
|
|
226
|
+
utxos: [{id: utxo.transaction_id, vout: utxo.transaction_vout}],
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
// Sign the PSBT
|
|
230
|
+
const signed = await signPsbt({
|
|
231
|
+
lnd,
|
|
232
|
+
psbt: (await fundPsbt({lnd, psbt})).psbt,
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
// Send the tx to the chain
|
|
236
|
+
await broadcastChainTransaction({lnd, transaction: signed.transaction});
|
|
237
|
+
|
|
238
|
+
// Make a new tx that will spend the output back into the wallet
|
|
239
|
+
const tx = new Transaction();
|
|
240
|
+
|
|
241
|
+
// The new tx spends the Taproot output
|
|
242
|
+
tx.addInput(
|
|
243
|
+
fromHex(signed.transaction).getHash(),
|
|
244
|
+
fromHex(signed.transaction).outs.findIndex(n => n.value === tokens)
|
|
245
|
+
);
|
|
246
|
+
|
|
247
|
+
// Make an output to pay back into the wallet
|
|
248
|
+
const chainOutput = toOutputScript(
|
|
249
|
+
(await createChainAddress({lnd})).address,
|
|
250
|
+
networks.regtest
|
|
251
|
+
);
|
|
252
|
+
|
|
253
|
+
// Add output to the pay back transaction
|
|
254
|
+
tx.addOutput(chainOutput, smallTokens);
|
|
255
|
+
|
|
256
|
+
const [hashToSign] = tx.ins.map((input, i) => {
|
|
257
|
+
return tx.hashForWitnessV1(
|
|
258
|
+
i,
|
|
259
|
+
[script],
|
|
260
|
+
[tokens],
|
|
261
|
+
Transaction.SIGHASH_DEFAULT,
|
|
262
|
+
);
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
const controlSign = await updateGroupSigningSession({
|
|
266
|
+
lnd,
|
|
267
|
+
hash: hashToSign.toString('hex'),
|
|
268
|
+
id: controlGroup.id,
|
|
269
|
+
nonces: [targetGroup.nonce],
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
const targetSign = await updateGroupSigningSession({
|
|
273
|
+
hash: hashToSign.toString('hex'),
|
|
274
|
+
id: targetGroup.id,
|
|
275
|
+
lnd: target.lnd,
|
|
276
|
+
nonces: [controlGroup.nonce],
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
await endGroupSigningSession({lnd: target.lnd, id: targetGroup.id});
|
|
280
|
+
|
|
281
|
+
const {signature} = await endGroupSigningSession({
|
|
282
|
+
lnd,
|
|
283
|
+
id: controlGroup.id,
|
|
284
|
+
signatures: [targetSign.signature],
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
// Add the signature to the input
|
|
288
|
+
tx.ins.forEach((input, i) => tx.setWitness(i, [hexAsBuffer(signature)]));
|
|
289
|
+
|
|
290
|
+
await broadcastChainTransaction({lnd, transaction: tx.toHex()});
|
|
291
|
+
|
|
292
|
+
await asyncRetry({interval, times}, async () => {
|
|
293
|
+
await generate({});
|
|
294
|
+
|
|
295
|
+
const {utxos} = await getUtxos({lnd});
|
|
296
|
+
|
|
297
|
+
const utxo = utxos.find(n => n.transaction_id === tx.getId());
|
|
298
|
+
|
|
299
|
+
if (!utxo || !utxo.confirmation_count) {
|
|
300
|
+
throw new Error('ExpectedReceivedTaprootSpend');
|
|
301
|
+
}
|
|
302
|
+
});
|
|
303
|
+
} catch (err) {
|
|
304
|
+
equal(err, null, 'Expected no error');
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// A Taproot script can be funded and spent on the script path
|
|
308
|
+
try {
|
|
309
|
+
await generate({count});
|
|
310
|
+
|
|
311
|
+
const controlKey = await getPublicKey({lnd, family: 0});
|
|
312
|
+
const targetKey = await getPublicKey({family: 0, lnd: target.lnd});
|
|
313
|
+
|
|
314
|
+
const controlGroup = await beginGroupSigningSession({
|
|
315
|
+
lnd,
|
|
316
|
+
key_family: 0,
|
|
317
|
+
key_index: controlKey.index,
|
|
318
|
+
public_keys: [targetKey.public_key],
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
const targetGroup = await beginGroupSigningSession({
|
|
322
|
+
key_family: 0,
|
|
323
|
+
key_index: targetKey.index,
|
|
324
|
+
lnd: target.lnd,
|
|
325
|
+
public_keys: [controlKey.public_key],
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
const scriptKey = hexAsBuffer(controlGroup.external_key);
|
|
329
|
+
|
|
330
|
+
const witnessScript = compile([scriptKey, OP_CHECKSIG]);
|
|
331
|
+
|
|
332
|
+
const branches = [{script: witnessScript.toString('hex')}];
|
|
333
|
+
|
|
334
|
+
const {hash} = hashForTree({branches});
|
|
335
|
+
|
|
336
|
+
const output = v1OutputScript({hash, internal_key: defaultInternalKey});
|
|
337
|
+
|
|
338
|
+
const [utxo] = (await getUtxos({lnd})).utxos.reverse();
|
|
339
|
+
|
|
340
|
+
// Make a PSBT paying to the Taproot output
|
|
341
|
+
const {psbt} = createPsbt({
|
|
342
|
+
outputs: [{tokens, script: output.script}],
|
|
343
|
+
utxos: [{id: utxo.transaction_id, vout: utxo.transaction_vout}],
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
// Sign the PSBT
|
|
347
|
+
const signed = await signPsbt({
|
|
348
|
+
lnd,
|
|
349
|
+
psbt: (await fundPsbt({lnd, psbt})).psbt,
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
// Send the tx to the chain
|
|
353
|
+
await broadcastChainTransaction({lnd, transaction: signed.transaction});
|
|
354
|
+
|
|
355
|
+
// Make a new tx that will spend the output back into the wallet
|
|
356
|
+
const tx = new Transaction();
|
|
357
|
+
|
|
358
|
+
// The new tx spends the Taproot output
|
|
359
|
+
tx.addInput(
|
|
360
|
+
fromHex(signed.transaction).getHash(),
|
|
361
|
+
fromHex(signed.transaction).outs.findIndex(n => n.value === tokens)
|
|
362
|
+
);
|
|
363
|
+
|
|
364
|
+
// Make an output to pay back into the wallet
|
|
365
|
+
const chainOutput = toOutputScript(
|
|
366
|
+
(await createChainAddress({lnd})).address,
|
|
367
|
+
networks.regtest
|
|
368
|
+
);
|
|
369
|
+
|
|
370
|
+
// Add output to the pay back transaction
|
|
371
|
+
tx.addOutput(chainOutput, smallTokens);
|
|
372
|
+
|
|
373
|
+
const [hashToSign] = tx.ins.map((input, i) => {
|
|
374
|
+
return tx.hashForWitnessV1(
|
|
375
|
+
i,
|
|
376
|
+
[hexAsBuffer(output.script)],
|
|
377
|
+
[tokens],
|
|
378
|
+
Transaction.SIGHASH_DEFAULT,
|
|
379
|
+
hexAsBuffer(leafHash({script: witnessScript.toString('hex')}).hash),
|
|
380
|
+
);
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
const controlSign = await updateGroupSigningSession({
|
|
384
|
+
lnd,
|
|
385
|
+
hash: hashToSign.toString('hex'),
|
|
386
|
+
id: controlGroup.id,
|
|
387
|
+
nonces: [targetGroup.nonce],
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
const targetSign = await updateGroupSigningSession({
|
|
391
|
+
hash: hashToSign.toString('hex'),
|
|
392
|
+
id: targetGroup.id,
|
|
393
|
+
lnd: target.lnd,
|
|
394
|
+
nonces: [controlGroup.nonce],
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
await endGroupSigningSession({lnd: target.lnd, id: targetGroup.id});
|
|
398
|
+
|
|
399
|
+
const {signature} = await endGroupSigningSession({
|
|
400
|
+
lnd,
|
|
401
|
+
id: controlGroup.id,
|
|
402
|
+
signatures: [targetSign.signature],
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
const {block} = controlBlock({
|
|
406
|
+
external_key: output.external_key,
|
|
407
|
+
leaf_script: witnessScript.toString('hex'),
|
|
408
|
+
script_branches: branches,
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
// Add the signature to the input
|
|
412
|
+
tx.ins.forEach((input, i) => {
|
|
413
|
+
return tx.setWitness(i, [
|
|
414
|
+
hexAsBuffer(signature),
|
|
415
|
+
witnessScript,
|
|
416
|
+
hexAsBuffer(block),
|
|
417
|
+
]);
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
await broadcastChainTransaction({lnd, transaction: tx.toHex()});
|
|
421
|
+
|
|
422
|
+
await asyncRetry({interval, times}, async () => {
|
|
423
|
+
await generate({});
|
|
424
|
+
|
|
425
|
+
const {utxos} = await getUtxos({lnd});
|
|
426
|
+
|
|
427
|
+
const utxo = utxos.find(n => n.transaction_id === tx.getId());
|
|
428
|
+
|
|
429
|
+
if (!utxo || !utxo.confirmation_count) {
|
|
430
|
+
throw new Error('ExpectedReceivedTaprootSpend');
|
|
431
|
+
}
|
|
432
|
+
});
|
|
433
|
+
} catch (err) {
|
|
434
|
+
equal(err, null, 'Expected no error');
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
await kill({});
|
|
438
|
+
|
|
439
|
+
return end();
|
|
440
|
+
});
|