ln-service 56.11.1 → 56.13.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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Versions
2
2
 
3
+ ## 56.13.0
4
+
5
+ - `openChannels`: Add `is_simplified_taproot` to make a simplified taproot chan
6
+
7
+ ## 56.12.0
8
+
9
+ - `openChannel`: Add `is_simplified_taproot` to make a simplified taproot chan
10
+
3
11
  ## 56.11.1
4
12
 
5
13
  - `openChannel`: Add `inputs` to select inputs for channel open funding
package/README.md CHANGED
@@ -99,6 +99,39 @@ const nodePublicKey = (await lnService.getWalletInfo({lnd})).public_key;
99
99
  An [unauthenticatedLndGrpc](#unauthenticatedLndGrpc) function is also available
100
100
  for `unlocker` methods.
101
101
 
102
+ ## Subscriptions
103
+
104
+ - Besides the events listed in this documentation, all `EventEmitter` objects
105
+ returned by any of the `subscribeTo...` methods also offer an `error`
106
+ event. This event is triggered e.g. when LND is shut down. So, in order to
107
+ detect and correctly handle such a situation, robust client code should
108
+ generally also add a listener for the `error` event. For example, a
109
+ function that will wait for and return the next forward but throw an
110
+ exception when LND is either not reachable or shuts down while waiting for
111
+ the forward would look something like this:
112
+
113
+ ``` node
114
+ const getNextForward = async (lnd) => {
115
+ const emitter = subscribeToForwards({ lnd });
116
+
117
+ try {
118
+ return await new Promise((resolve, reject) => {
119
+ emitter.on("forward", resolve);
120
+ // Without the following line, the function will never throw
121
+ // when the connection is lost after calling subscribeToForwards
122
+ emitter.on("error", reject);
123
+ });
124
+ } finally {
125
+ emitter.removeAllListeners();
126
+ }
127
+ };
128
+ ```
129
+
130
+ - After the last listener has been removed from an `EventEmitter` object, the
131
+ subscription is released and subsequent attempts to add a listener will
132
+ result in an error. Call `subscribeTo...` again and add new listeners to the
133
+ new `EventEmitter` object.
134
+
102
135
  ## All Methods
103
136
 
104
137
  - [addExternalSocket](#addexternalsocket) - Advertise a new p2p host:ip address
@@ -3731,6 +3764,9 @@ Requires `offchain:write`, `onchain:write`, `peers:write` permissions
3731
3764
 
3732
3765
  `inputs` is not supported on LND 0.16.4 and below
3733
3766
 
3767
+ `is_simplified_taproot` is not supported on LND 0.16.4 and below and requires
3768
+ `--protocol.simple-taproot-chans` set on both sides.
3769
+
3734
3770
  {
3735
3771
  [base_fee_mtokens]: <Routing Base Fee Millitokens Charged String>
3736
3772
  [chain_fee_tokens_per_vbyte]: <Chain Fee Tokens Per VByte Number>
@@ -3744,6 +3780,7 @@ Requires `offchain:write`, `onchain:write`, `peers:write` permissions
3744
3780
  }]
3745
3781
  [is_max_funding]: <Use Maximal Chain Funds For Local Funding Bool>
3746
3782
  [is_private]: <Channel is Private Bool> // Defaults to false
3783
+ [is_simplified_taproot]: <Channel is Simplified Taproot Type Bool>
3747
3784
  [is_trusted_funding]: <Accept Funding as Trusted Bool>
3748
3785
  lnd: <Authenticated LND API Object>
3749
3786
  local_tokens: <Total Channel Capacity Tokens Number>
@@ -3793,6 +3830,9 @@ as well as a channel open request listener to accept the trusted funding.
3793
3830
 
3794
3831
  `description` is not supported on LND 0.16.4 and below
3795
3832
 
3833
+ `is_simplified_taproot` is not supported on LND 0.16.4 and below and requires
3834
+ `--protocol.simple-taproot-chans` set on both sides.
3835
+
3796
3836
  {
3797
3837
  channels: [{
3798
3838
  [base_fee_mtokens]: <Routing Base Fee Millitokens Charged String>
@@ -3802,6 +3842,7 @@ as well as a channel open request listener to accept the trusted funding.
3802
3842
  [fee_rate]: <Routing Fee Rate In Millitokens Per Million Number>
3803
3843
  [give_tokens]: <Tokens to Gift To Partner Number> // Defaults to zero
3804
3844
  [is_private]: <Channel is Private Bool> // Defaults to false
3845
+ [is_simplified_taproot]: <Channel is Simplified Taproot Type Bool>
3805
3846
  [is_trusted_funding]: <Peer Should Avoid Waiting For Confirmation Bool>
3806
3847
  [min_htlc_mtokens]: <Minimum HTLC Millitokens String>
3807
3848
  [partner_csv_delay]: <Peer Output CSV Delay Number>
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "cors": "2.8.5",
12
12
  "express": "4.18.2",
13
13
  "invoices": "3.0.0",
14
- "lightning": "9.11.2",
14
+ "lightning": "9.13.0",
15
15
  "macaroon": "3.0.4",
16
16
  "morgan": "1.10.0",
17
17
  "ws": "8.13.0"
@@ -28,7 +28,7 @@
28
28
  "bn.js": "5.2.1",
29
29
  "bs58check": "3.0.1",
30
30
  "ecpair": "2.1.0",
31
- "ln-docker-daemons": "5.1.2",
31
+ "ln-docker-daemons": "5.1.3",
32
32
  "p2tr": "2.0.0",
33
33
  "portfinder": "1.0.32",
34
34
  "psbt": "3.0.0",
@@ -69,5 +69,5 @@
69
69
  "integration-test-0.14.4": "DOCKER_LND_VERSION=v0.14.4-beta npm run test",
70
70
  "test": "echo $DOCKER_LND_VERSION && node test/runner"
71
71
  },
72
- "version": "56.11.1"
72
+ "version": "56.13.0"
73
73
  }
@@ -0,0 +1,174 @@
1
+ const {equal} = require('node:assert').strict;
2
+ const test = require('node:test');
3
+
4
+ const asyncRetry = require('async/retry');
5
+ const {spawnLightningCluster} = require('ln-docker-daemons');
6
+
7
+ const {addPeer} = require('./../../');
8
+ const {broadcastChainTransaction} = require('./../../');
9
+ const {fundPendingChannels} = require('./../../');
10
+ const {fundPsbt} = require('./../../');
11
+ const {getChannels} = require('./../../');
12
+ const {openChannel} = require('./../../');
13
+ const {openChannels} = require('./../../');
14
+ const {signPsbt} = require('./../../');
15
+
16
+ const channelCapacityTokens = 1e6;
17
+ const count = 100;
18
+ const defaultFee = 1e3;
19
+ const description = 'description';
20
+ const interval = 250;
21
+ const size = 2;
22
+ const times = 1000;
23
+
24
+ // Opening a simplified taproot channel should open a simple taproot channel
25
+ test(`Open simplified taproot channel`, async () => {
26
+ // Test for LND 0.16.4 or below to exit early and avoid test
27
+ {
28
+ const {kill, nodes} = await spawnLightningCluster({size});
29
+
30
+ const [{generate, id, lnd}, target] = nodes;
31
+
32
+ await generate({count});
33
+
34
+ const channelOpen = await asyncRetry({interval, times}, async () => {
35
+ await addPeer({lnd, public_key: target.id, socket: target.socket});
36
+
37
+ return await openChannel({
38
+ description,
39
+ lnd,
40
+ chain_fee_tokens_per_vbyte: defaultFee,
41
+ local_tokens: channelCapacityTokens,
42
+ partner_public_key: target.id,
43
+ socket: target.socket,
44
+ });
45
+ });
46
+
47
+ const channel = await asyncRetry({interval, times}, async () => {
48
+ await generate({});
49
+
50
+ const {channels} = await getChannels({lnd});
51
+
52
+ const [channel] = channels;
53
+
54
+ if (!channel) {
55
+ throw new Error('ExpectedChannelOpened');
56
+ }
57
+
58
+ return channel;
59
+ });
60
+
61
+ await kill({});
62
+
63
+ // Exit early when on LND 0.16.4 that do not support simplified taproot
64
+ if (channel.description !== description) {
65
+ return;
66
+ }
67
+ }
68
+
69
+ // Try opening a simplified taproot channel
70
+ {
71
+ const {kill, nodes} = await spawnLightningCluster({
72
+ size,
73
+ lnd_configuration: ['--protocol.simple-taproot-chans'],
74
+ });
75
+
76
+ const [{generate, id, lnd}, target] = nodes;
77
+
78
+ await generate({count});
79
+
80
+ await addPeer({lnd, public_key: target.id, socket: target.socket});
81
+
82
+ const channelOpen = await asyncRetry({interval, times}, async () => {
83
+ await addPeer({lnd, public_key: target.id, socket: target.socket});
84
+
85
+ return await openChannel({
86
+ lnd,
87
+ chain_fee_tokens_per_vbyte: defaultFee,
88
+ is_private: true,
89
+ is_simplified_taproot: true,
90
+ local_tokens: channelCapacityTokens,
91
+ partner_public_key: target.id,
92
+ socket: target.socket,
93
+ });
94
+ });
95
+
96
+ const channel = await asyncRetry({interval, times}, async () => {
97
+ await generate({});
98
+
99
+ const {channels} = await getChannels({lnd});
100
+
101
+ const [channel] = channels;
102
+
103
+ if (!channel) {
104
+ throw new Error('ExpectedChannelOpened');
105
+ }
106
+
107
+ return channel;
108
+ });
109
+
110
+ equal(channel.type, 'simplified_taproot', 'Opened simplified taproot');
111
+
112
+ await kill({});
113
+ }
114
+
115
+ // Try opening a simplified taproot channel via PSBT funding
116
+ {
117
+ const {kill, nodes} = await spawnLightningCluster({
118
+ size,
119
+ lnd_configuration: ['--protocol.simple-taproot-chans'],
120
+ });
121
+
122
+ const [{generate, id, lnd}, target] = nodes;
123
+
124
+ await generate({count});
125
+
126
+ await addPeer({lnd, public_key: target.id, socket: target.socket});
127
+
128
+ const channelOpen = await asyncRetry({interval, times}, async () => {
129
+ await addPeer({lnd, public_key: target.id, socket: target.socket});
130
+
131
+ return await openChannels({
132
+ lnd,
133
+ channels: [{
134
+ capacity: channelCapacityTokens,
135
+ is_private: true,
136
+ is_simplified_taproot: true,
137
+ partner_public_key: target.id,
138
+ }],
139
+ });
140
+ });
141
+
142
+ const funded = await fundPsbt({lnd, outputs: channelOpen.pending});
143
+
144
+ const signed = await signPsbt({lnd, psbt: funded.psbt});
145
+
146
+ await fundPendingChannels({
147
+ lnd,
148
+ channels: channelOpen.pending.map(n => n.id),
149
+ funding: signed.psbt,
150
+ });
151
+
152
+ await broadcastChainTransaction({lnd, transaction: signed.transaction});
153
+
154
+ const channel = await asyncRetry({interval, times}, async () => {
155
+ await generate({});
156
+
157
+ const {channels} = await getChannels({lnd});
158
+
159
+ const [channel] = channels;
160
+
161
+ if (!channel) {
162
+ throw new Error('ExpectedChannelOpened');
163
+ }
164
+
165
+ return channel;
166
+ });
167
+
168
+ equal(channel.type, 'simplified_taproot', 'Opened simplified taproot');
169
+
170
+ await kill({});
171
+ }
172
+
173
+ return;
174
+ });