ln-service 53.19.0 → 53.22.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,19 @@
1
1
  # Versions
2
2
 
3
+ ## 53.22.0
4
+
5
+ - `parsePaymentRequest`: Add support for parsing payment request metadata
6
+
7
+ ## 53.21.0
8
+
9
+ - `getLockedUtxos`: Add support for locked UTXO `output_script`, `tokens`
10
+
11
+ ## 53.20.0
12
+
13
+ - `closeChannel`: Add support for `max_tokens_per_vbyte` to set max fee rate
14
+ - `getChainTransactions`: Add `inputs` support for previous outpoints
15
+ - `subscribeToTransactions`: Add `inputs` support for previous outpoints
16
+
3
17
  ## 53.19.0
4
18
 
5
19
  - `signBytes`: Add `type` and support for specifying `schnorr` type signing
package/README.md CHANGED
@@ -9,11 +9,10 @@ through npm.
9
9
 
10
10
  Supported LND versions:
11
11
 
12
- - v0.15.0-beta
12
+ - v0.15.0-beta to v0.15.1-beta
13
13
  - v0.14.0-beta to v0.14.3-beta
14
14
  - v0.13.0-beta to v0.13.4-beta
15
15
  - v0.12.0-beta to v0.12.1-beta
16
- - v0.11.0-beta to v0.11.1-beta
17
16
 
18
17
  For typescript-ready methods, check out https://github.com/alexbosworth/lightning#readme
19
18
 
@@ -529,17 +528,23 @@ Either an id or a transaction id / transaction output index is required
529
528
 
530
529
  If cooperatively closing, pass a public key and socket to connect
531
530
 
532
- Requires `info:read`, `offchain:write`, `onchain:write`, `peers:write` permissions
531
+ `max_tokens_per_vbyte` will be ignored when closing a peer initiated channel
532
+
533
+ Requires `info:read`, `offchain:write`, `onchain:write`, `peers:write`
534
+ permissions
535
+
536
+ `max_tokens_per_vbyte` is not supported in LND 0.15.0 and below
533
537
 
534
538
  {
535
539
  [address]: <Request Sending Local Channel Funds To Address String>
536
540
  [id]: <Standard Format Channel Id String>
537
541
  [is_force_close]: <Is Force Close Bool>
538
542
  lnd: <Authenticated LND API Object>
543
+ [max_tokens_per_vbyte]: <Fail Cooperative Close Above Fee Rate Number>
539
544
  [public_key]: <Peer Public Key String>
540
545
  [socket]: <Peer Socket String>
541
546
  [target_confirmations]: <Confirmation Target Number>
542
- [tokens_per_vbyte]: <Tokens Per Virtual Byte Number>
547
+ [tokens_per_vbyte]: <Target Tokens Per Virtual Byte Number>
543
548
  [transaction_id]: <Transaction Id Hex String>
544
549
  [transaction_vout]: <Transaction Output Index Number>
545
550
  }
@@ -1486,10 +1491,12 @@ Get chain transactions.
1486
1491
 
1487
1492
  Requires `onchain:read` permission
1488
1493
 
1494
+ `inputs` are not supported on LND 0.15.0 and below
1495
+
1489
1496
  {
1490
1497
  [after]: <Confirmed After Current Best Chain Block Height Number>
1491
1498
  [before]: <Confirmed Before Current Best Chain Block Height Number>
1492
- lnd: <Authenticated LND Object>
1499
+ lnd: <Authenticated LND API Object>
1493
1500
  }
1494
1501
 
1495
1502
  @returns via cbk or Promise
@@ -1502,6 +1509,11 @@ Requires `onchain:read` permission
1502
1509
  [description]: <Transaction Label String>
1503
1510
  [fee]: <Fees Paid Tokens Number>
1504
1511
  id: <Transaction Id String>
1512
+ inputs: [{
1513
+ is_local: <Spent Outpoint is Local Bool>
1514
+ transaction_id: <Transaction Id Hex String>
1515
+ transaction_vout: <Transaction Output Index Number>
1516
+ }]
1505
1517
  is_confirmed: <Is Confirmed Bool>
1506
1518
  is_outgoing: <Transaction Outbound Bool>
1507
1519
  output_addresses: [<Address String>]
@@ -2241,6 +2253,8 @@ Requires LND built with `walletrpc` build tag
2241
2253
 
2242
2254
  This method is not supported on LND 0.12.1 and below
2243
2255
 
2256
+ `output_script`, `tokens` are not supported on LND 0.15.0 and below
2257
+
2244
2258
  {
2245
2259
  lnd: <Authenticated LND API Object>
2246
2260
  }
@@ -2250,6 +2264,8 @@ This method is not supported on LND 0.12.1 and below
2250
2264
  utxos: [{
2251
2265
  lock_expires_at: <Lock Expires At ISO 8601 Date String>
2252
2266
  lock_id: <Locking Id Hex String>
2267
+ [output_script]: <Outpoint Output Script Hex String>
2268
+ [tokens]: <Token Value of Outpoint Number>
2253
2269
  transaction_id: <Transaction Id Hex String>
2254
2270
  transaction_vout: <Transaction Output Index Number>
2255
2271
  }]
@@ -3679,6 +3695,7 @@ Note: either description or description_hash will be returned
3679
3695
  }]
3680
3696
  id: <Payment Request Hash String>
3681
3697
  is_expired: <Invoice is Expired Bool>
3698
+ [metadata]: <Payment Metadata Hex String>
3682
3699
  [mtokens]: <Requested Milli-Tokens Value String> (can exceed Number limit)
3683
3700
  network: <Network Name String>
3684
3701
  [payment]: <Payment Identifier Hex Encoded String>
@@ -6615,6 +6632,8 @@ Subscribe to transactions
6615
6632
 
6616
6633
  Requires `onchain:read` permission
6617
6634
 
6635
+ `inputs` are not supported on LND 0.15.0 and below
6636
+
6618
6637
  {
6619
6638
  lnd: <Authenticated LND API Object>
6620
6639
  }
@@ -6633,6 +6652,11 @@ Requires `onchain:read` permission
6633
6652
  created_at: <Created ISO 8601 Date String>
6634
6653
  [fee]: <Fees Paid Tokens Number>
6635
6654
  id: <Transaction Id String>
6655
+ inputs: [{
6656
+ is_local: <Spent Outpoint is Local Bool>
6657
+ transaction_id: <Transaction Id Hex String>
6658
+ transaction_vout: <Transaction Output Index Number>
6659
+ }]
6636
6660
  is_confirmed: <Is Confirmed Bool>
6637
6661
  is_outgoing: <Transaction Outbound Bool>
6638
6662
  output_addresses: [<Address String>]
package/package.json CHANGED
@@ -10,8 +10,8 @@
10
10
  "bolt07": "1.8.2",
11
11
  "cors": "2.8.5",
12
12
  "express": "4.18.1",
13
- "invoices": "2.1.0",
14
- "lightning": "5.18.0",
13
+ "invoices": "2.2.0",
14
+ "lightning": "5.20.2",
15
15
  "macaroon": "3.0.4",
16
16
  "morgan": "1.10.0",
17
17
  "ws": "8.8.1"
@@ -28,7 +28,7 @@
28
28
  "bn.js": "5.2.1",
29
29
  "bs58check": "2.1.2",
30
30
  "ecpair": "2.0.1",
31
- "ln-docker-daemons": "2.3.3",
31
+ "ln-docker-daemons": "2.3.6",
32
32
  "p2tr": "1.3.1",
33
33
  "portfinder": "1.0.32",
34
34
  "psbt": "2.7.1",
@@ -56,7 +56,7 @@
56
56
  "url": "https://github.com/alexbosworth/ln-service.git"
57
57
  },
58
58
  "scripts": {
59
- "integration-test-daily-lnd-build": "DOCKER_LND_VERSION=daily-testing-only npm run test",
59
+ "integration-test-0.15.1": "DOCKER_LND_VERSION=v0.15.1-beta npm run test",
60
60
  "integration-test-0.15.0": "DOCKER_LND_VERSION=v0.15.0-beta npm run test",
61
61
  "integration-test-0.14.3": "DOCKER_LND_VERSION=v0.14.3-beta npm run test",
62
62
  "integration-test-0.14.2": "DOCKER_LND_VERSION=v0.14.2-beta npm run test",
@@ -71,5 +71,5 @@
71
71
  "integration-test-0.12.0": "DOCKER_LND_VERSION=v0.12.0-beta npm run test",
72
72
  "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"
73
73
  },
74
- "version": "53.19.0"
74
+ "version": "53.22.0"
75
75
  }
@@ -8,7 +8,7 @@ const {getPeers} = require('./../../');
8
8
 
9
9
  const interval = 100;
10
10
  const size = 2;
11
- const times = 2000;
11
+ const times = 4000;
12
12
  const timeout = 100;
13
13
 
14
14
  // Adding peers should result in a connected peer
@@ -18,6 +18,7 @@ const {fundPsbt} = require('./../../');
18
18
  const {getChainBalance} = require('./../../');
19
19
  const {getChannels} = require('./../../');
20
20
  const {getLockedUtxos} = require('./../../');
21
+ const {getMasterPublicKeys} = require('./../../');
21
22
  const {getPendingChannels} = require('./../../');
22
23
  const {openChannels} = require('./../../');
23
24
  const {signPsbt} = require('./../../');
@@ -41,6 +42,17 @@ test(`Forfeit pending channel`, async ({end, equal, strictSame}) => {
41
42
 
42
43
  const {generate, lnd} = control;
43
44
 
45
+ try {
46
+ const {keys} = await getMasterPublicKeys({lnd});
47
+ } catch (err) {
48
+ // LND 0.13.3 and below should not be tested
49
+ strictSame(err, [501, 'GetMasterPublicKeysMethodNotSupported'], 'Got err');
50
+
51
+ await kill({});
52
+
53
+ return end();
54
+ }
55
+
44
56
  try {
45
57
  await control.generate({count});
46
58
 
@@ -20,12 +20,16 @@ test(`Get chain transactions`, async ({end, equal, strictSame}) => {
20
20
  // Generate some funds for LND
21
21
  await generate({count});
22
22
 
23
- await asyncRetry({interval: 10, times: 1000}, async () => {
23
+ await asyncRetry({interval: 10, times: 2000}, async () => {
24
24
  const wallet = await getWalletInfo({lnd});
25
25
 
26
26
  if (!wallet.is_synced_to_chain) {
27
27
  throw new Error('ExpectedWalletSyncedToChain');
28
28
  }
29
+
30
+ if (wallet.current_block_height !== count + 1) {
31
+ throw new Error('ExpectedFullySyncedToChain');
32
+ }
29
33
  });
30
34
 
31
35
  // Wait for generation to be over
@@ -219,14 +219,14 @@ test(`Get closed channels`, async ({end, equal}) => {
219
219
  equal(!!settleHtlc.transaction_id, true, 'Output tx id');
220
220
  equal(settleHtlc.transaction_vout !== undefined, true, 'Output tx vout');
221
221
 
222
- const alsoDead = await asyncRetry({interval: 2000, times: 99}, async () => {
222
+ const alsoDead = await asyncRetry({interval: 20, times: 7000}, async () => {
223
223
  const {channels} = await getClosedChannels({lnd: target.lnd});
224
224
 
225
225
  if (channels.length === [toForceClose, channelOpen].length) {
226
226
  return channels;
227
227
  }
228
228
 
229
- await target.generate({count: 100});
229
+ await target.generate({});
230
230
 
231
231
  throw new Error('WaitingForTargetForceClose');
232
232
  });
@@ -25,7 +25,7 @@ const size = 2;
25
25
  const times = 2000;
26
26
 
27
27
  // Opening unconfirmed channels should in immediate channel opening
28
- test(`Open unconfirmed channels`, async ({end, equal, strictSame}) => {
28
+ test(`Open unconfirmed channels`, async ({end, equal, match, strictSame}) => {
29
29
  // Unconfirmed channels are not supported on LND 0.15.0 and below
30
30
  {
31
31
  const {kill, nodes} = await spawnLightningCluster({});
@@ -126,15 +126,15 @@ test(`Open unconfirmed channels`, async ({end, equal, strictSame}) => {
126
126
 
127
127
  // Make sure the channel reflects that it is trusted funding
128
128
  strictSame(channel.other_ids, [], 'Got no ephemeral ids');
129
- equal(channel.id, '16000000x0x0', 'Channel id is faked');
129
+ match(channel.id, /16000000x0/, 'Channel id is faked');
130
130
  equal(channel.is_trusted_funding, true, 'Channel funding is trusted');
131
131
 
132
132
  // Make sure the open channel event reflected that it was trusted funding
133
133
  const [event] = opened;
134
134
 
135
- strictSame(event.other_ids, [], 'Got no ephemeral ids');
136
- equal(event.id, '16000000x0x0', 'Channel id is faked');
137
- equal(event.is_trusted_funding, true, 'Channel funding is trusted');
135
+ strictSame(event.other_ids, [], 'Got no event ephemeral ids');
136
+ match(event.id, /16000000x0/, 'Channel event id is faked');
137
+ equal(event.is_trusted_funding, true, 'Channel event funding is trusted');
138
138
 
139
139
  // Make sure the channel can be used immediately
140
140
  await pay({lnd, request: invoice.request});
@@ -156,7 +156,11 @@ test(`Open unconfirmed channels`, async ({end, equal, strictSame}) => {
156
156
 
157
157
  equal(confirmed.id, '102x1x0', 'Channel id is real now');
158
158
  equal(confirmed.is_trusted_funding, true, 'Channel funding was trusted');
159
- strictSame(confirmed.other_ids, ['16000000x0x0'], 'Got ephemeral ids');
159
+ equal(confirmed.other_ids.length, 1, 'Got ephemeral id');
160
+
161
+ const [otherId] = confirmed.other_ids;
162
+
163
+ match(otherId, /16000000x0/, 'Got ephemeral id');
160
164
 
161
165
  await closeChannel({lnd, id: confirmed.id});
162
166
 
@@ -210,7 +214,11 @@ test(`Open unconfirmed channels`, async ({end, equal, strictSame}) => {
210
214
  return confirmed;
211
215
  });
212
216
 
213
- strictSame(privateConfirmed.other_ids, ['16000000x0x1'], 'Got private id');
217
+ equal(privateConfirmed.other_ids.length, 1, 'Got private ephemeral ids');
218
+
219
+ const [privateOtherId] = privateConfirmed.other_ids;
220
+
221
+ match(privateOtherId, /16000000x0/, 'Got private id');
214
222
 
215
223
  const [closedChannel] = (await getClosedChannels({lnd})).channels;
216
224
 
@@ -224,16 +232,12 @@ test(`Open unconfirmed channels`, async ({end, equal, strictSame}) => {
224
232
 
225
233
  const ephemeralIds = await getEphemeralChannelIds({lnd});
226
234
 
227
- strictSame(
228
- ephemeralIds,
229
- {
230
- channels: [
231
- {other_ids: [], reference_id: '16000000x0x0'},
232
- {other_ids: [], reference_id: '16000000x0x1'},
233
- ],
234
- },
235
- 'Ephemeral ids are returned'
236
- );
235
+ equal(ephemeralIds.channels.length, 2, 'Got ephemeral channel ids');
236
+
237
+ const [firstChannel, secondChannel] = ephemeralIds.channels;
238
+
239
+ match(firstChannel.reference_id, /16000000x0/, 'Got first channel id');
240
+ match(secondChannel.reference_id, /16000000x0/, 'Got second channel id');
237
241
  } catch (err) {
238
242
  equal(err, null, 'No error is reported');
239
243
  } finally {
@@ -1,7 +1,10 @@
1
+ const asyncRetry = require('async/retry');
1
2
  const {spawnLightningCluster} = require('ln-docker-daemons');
2
3
  const {test} = require('@alexbosworth/tap');
3
4
 
4
5
  const {createInvoice} = require('./../../');
6
+ const {getChannelBalance} = require('./../../');
7
+ const {getChannels} = require('./../../');
5
8
  const {getInvoice} = require('./../../');
6
9
  const {getRouteToDestination} = require('./../../');
7
10
  const {parsePaymentRequest} = require('./../../');
@@ -13,8 +16,11 @@ const {waitForRoute} = require('./../macros');
13
16
  const all = promise => Promise.all(promise);
14
17
  const capacity = 1e6;
15
18
  const {ceil} = Math;
19
+ const interval = 10;
20
+ const maturity = 100;
16
21
  const {round} = Math;
17
22
  const size = 2;
23
+ const times = 2000;
18
24
 
19
25
  // Paying using multiple paths should execute the payment across paths
20
26
  test(`Pay with multiple paths`, async ({end, equal, rejects, strictSame}) => {
@@ -22,22 +28,50 @@ test(`Pay with multiple paths`, async ({end, equal, rejects, strictSame}) => {
22
28
 
23
29
  const [{generate, lnd}, target] = nodes;
24
30
 
25
- await generate({count: 400});
31
+ await generate({count: maturity});
26
32
 
27
33
  const channel1 = await setupChannel({
28
34
  capacity,
29
35
  generate,
30
36
  lnd,
37
+ hidden: true,
31
38
  to: target,
32
39
  });
33
40
 
41
+ await asyncRetry({interval, times}, async () => {
42
+ const {channels} = await getChannels({lnd});
43
+
44
+ await generate({});
45
+
46
+ if (!channels.length) {
47
+ throw new Error('ExpectedChannelCreated');
48
+ }
49
+ });
50
+
34
51
  const channel2 = await setupChannel({
35
52
  capacity,
36
53
  generate,
37
54
  lnd,
55
+ hidden: true,
38
56
  to: target,
39
57
  });
40
58
 
59
+ await asyncRetry({interval, times}, async () => {
60
+ const {channels} = await getChannels({lnd, is_active: true});
61
+
62
+ await generate({});
63
+
64
+ if (channels.length < size) {
65
+ throw new Error('ExpectedSecondChannelCreated');
66
+ }
67
+
68
+ const balance = await getChannelBalance({lnd});
69
+
70
+ if (balance.channel_balance < capacity) {
71
+ throw new Error('ExpectedChannelBalancePresent');
72
+ }
73
+ });
74
+
41
75
  const channels = [channel1, channel2];
42
76
 
43
77
  const payParts = [
@@ -50,15 +84,23 @@ test(`Pay with multiple paths`, async ({end, equal, rejects, strictSame}) => {
50
84
  const {request} = await createInvoice({tokens, lnd: target.lnd});
51
85
 
52
86
  // Payment should fail with only 1 path
53
- try {
54
- await payViaPaymentRequest({lnd, request, max_paths: [channel1].length});
55
- } catch (err) {
56
- strictSame(
57
- err,
58
- [503, 'PaymentPathfindingFailedToFindPossibleRoute'],
59
- 'No path'
60
- );
61
- }
87
+ await asyncRetry({interval, times}, async () => {
88
+ try {
89
+ await payViaPaymentRequest({lnd, request, max_paths: [channel1].length});
90
+ } catch (err) {
91
+ const [, message] = err;
92
+
93
+ if (message !== 'PaymentPathfindingFailedToFindPossibleRoute') {
94
+ throw err;
95
+ }
96
+
97
+ strictSame(
98
+ err,
99
+ [503, 'PaymentPathfindingFailedToFindPossibleRoute'],
100
+ 'No path'
101
+ );
102
+ }
103
+ });
62
104
 
63
105
  // Payment should succeed with 2 paths
64
106
  try {
@@ -75,10 +75,15 @@ test(`Subscribe to requests`, async ({end, equal, rejects, strictSame}) => {
75
75
 
76
76
  await once(pay, 'failed');
77
77
 
78
+ equal(failures.length, 1, 'Got a failure');
79
+
80
+ const [failed] = failures;
81
+
82
+ delete failed.channel;
83
+
78
84
  strictSame(
79
- failures,
80
- [{
81
- channel: channel.id,
85
+ failed,
86
+ {
82
87
  index: 1,
83
88
  mtokens: '101000',
84
89
  public_key: target.id,
@@ -114,7 +119,7 @@ test(`Subscribe to requests`, async ({end, equal, rejects, strictSame}) => {
114
119
  tokens: 101,
115
120
  total_mtokens: '100000',
116
121
  },
117
- }],
122
+ },
118
123
  'Failure is emitted'
119
124
  );
120
125
 
@@ -135,10 +140,13 @@ test(`Subscribe to requests`, async ({end, equal, rejects, strictSame}) => {
135
140
  equal(!!pending.created_at, true, 'Has creation date');
136
141
  equal(pending.id, invoice.id, 'Payment id is present');
137
142
  equal(pending.mtokens, invoice.mtokens, 'Pending payment mtokens');
143
+ equal(pending.paths.length, 1, 'Path is present');
144
+
145
+ const [path] = pending.paths;
138
146
 
139
147
  strictSame(
140
- pending.paths,
141
- [{
148
+ path,
149
+ {
142
150
  fee: 1,
143
151
  fee_mtokens: '1000',
144
152
  hops: [
@@ -168,7 +176,7 @@ test(`Subscribe to requests`, async ({end, equal, rejects, strictSame}) => {
168
176
  timeout: height + 40 + 43,
169
177
  tokens: 101,
170
178
  total_mtokens: '100000',
171
- }],
179
+ },
172
180
  'Paths are present'
173
181
  );
174
182
 
@@ -43,6 +43,13 @@ test(`Lock UTXO`, async ({end, equal, rejects, strictSame}) => {
43
43
 
44
44
  const [locked] = (await getLockedUtxos({lnd})).utxos;
45
45
 
46
+ const got = {
47
+ lock_expires_at: locked.lock_expires_at,
48
+ lock_id: locked.lock_id,
49
+ transaction_id: locked.transaction_id,
50
+ transaction_vout: locked.transaction_vout,
51
+ };
52
+
46
53
  const expected = {
47
54
  lock_expires_at: lock.expires_at,
48
55
  lock_id: lock.id,
@@ -50,7 +57,14 @@ test(`Lock UTXO`, async ({end, equal, rejects, strictSame}) => {
50
57
  transaction_vout: utxo.transaction_vout,
51
58
  };
52
59
 
53
- strictSame(locked, expected, 'Got expected UTXO lock');
60
+ strictSame(got, expected, 'Got expected UTXO lock');
61
+
62
+ // LND 0.15.0 and below do not support locked UTXO output script
63
+ if (!!locked.output_script) {
64
+ equal(locked.output_script, utxo.output_script, 'Got output script');
65
+ equal(locked.tokens, utxo.tokens, 'Got output value');
66
+ }
67
+
54
68
  } catch (err) {
55
69
  strictSame(
56
70
  err,
@@ -10,7 +10,6 @@ const {broadcastChainTransaction} = require('./../../');
10
10
  const {createChainAddress} = require('./../../');
11
11
  const {fundPsbt} = require('./../../');
12
12
  const {getChainBalance} = require('./../../');
13
- const {getChainTransactions} = require('./../../');
14
13
  const {getUtxos} = require('./../../');
15
14
  const {sendToChainAddress} = require('./../../');
16
15
  const {signPsbt} = require('./../../');