ln-service 54.5.0 → 54.7.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
+ ## 54.7.0
4
+
5
+ - `getBlock`: add `height` to allow fetching a raw block at a specified height
6
+
7
+ ## 54.6.0
8
+
9
+ - `getBlock`: Add method to retrieve the raw bytes of a block in the chain
10
+
3
11
  ## 54.5.0
4
12
 
5
13
  - `getFailedPayments`, `getInvoices`, `getPayments`, `getPendingPayments`: add
package/README.md CHANGED
@@ -139,6 +139,7 @@ for `unlocker` methods.
139
139
  - [getAutopilot](#getautopilot) - Get autopilot status or node scores
140
140
  - [getBackup](#getbackup) - Get a backup of a channel
141
141
  - [getBackups](#getbackups) - Get a backup for all channels
142
+ - [getBlock](#getblock) - Get the raw block data given a block id in the chain
142
143
  - [getChainBalance](#getchainbalance) - Get the confirmed chain balance
143
144
  - [getChainFeeEstimate](#getchainfeeestimate) - Get a chain fee estimate
144
145
  - [getChainFeeRate](#getchainfeerate) - Get the fee rate for a conf target
@@ -1408,6 +1409,39 @@ const {getBackups} = require('ln-service');
1408
1409
  const {backup} = await getBackups({lnd});
1409
1410
  ```
1410
1411
 
1412
+ ### getBlock
1413
+
1414
+ Get a block in the chain
1415
+
1416
+ This method requires LND built with `chainkit` build tag
1417
+
1418
+ Requires `onchain:read` permission
1419
+
1420
+ This method is not supported on LND 0.15.5 and below
1421
+
1422
+ {
1423
+ [height]: <Block Height Number>
1424
+ [id]: <Block Hash Hex String>
1425
+ lnd: <Authenticated LND API Object>
1426
+ }
1427
+
1428
+ @returns via cbk or Promise
1429
+ {
1430
+ block: <Raw Block Bytes Hex String>
1431
+ }
1432
+
1433
+ Example:
1434
+
1435
+ ```node
1436
+ const {getBlock, getHeight} = require('ln-service');
1437
+
1438
+ const chain = await getHeight({lnd});
1439
+
1440
+ const {block} = await getBlock({lnd, id: chain.current_block_hash});
1441
+
1442
+ const lastBlockSize = Buffer.from(block, 'hex').byteLength();
1443
+ ```
1444
+
1411
1445
  ### getChainBalance
1412
1446
 
1413
1447
  Get balance on the chain.
package/index.js CHANGED
@@ -33,6 +33,7 @@ const {getAccessIds} = require('lightning');
33
33
  const {getAutopilot} = require('lightning');
34
34
  const {getBackup} = require('lightning');
35
35
  const {getBackups} = require('lightning');
36
+ const {getBlock} = require('lightning');
36
37
  const {getChainBalance} = require('lightning');
37
38
  const {getChainFeeEstimate} = require('lightning');
38
39
  const {getChainFeeRate} = require('lightning');
@@ -185,6 +186,7 @@ module.exports = {
185
186
  getAutopilot,
186
187
  getBackup,
187
188
  getBackups,
189
+ getBlock,
188
190
  getChainBalance,
189
191
  getChainFeeEstimate,
190
192
  getChainFeeRate,
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "cors": "2.8.5",
12
12
  "express": "4.18.2",
13
13
  "invoices": "2.2.2",
14
- "lightning": "6.5.0",
14
+ "lightning": "6.7.1",
15
15
  "macaroon": "3.0.4",
16
16
  "morgan": "1.10.0",
17
17
  "ws": "8.11.0"
@@ -28,7 +28,7 @@
28
28
  "bn.js": "5.2.1",
29
29
  "bs58check": "2.1.2",
30
30
  "ecpair": "2.1.0",
31
- "ln-docker-daemons": "4.0.1",
31
+ "ln-docker-daemons": "4.0.2",
32
32
  "p2tr": "1.3.2",
33
33
  "portfinder": "1.0.32",
34
34
  "psbt": "2.7.1",
@@ -64,5 +64,5 @@
64
64
  "integration-test-0.14.4": "DOCKER_LND_VERSION=v0.14.4-beta npm run test",
65
65
  "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"
66
66
  },
67
- "version": "54.5.0"
67
+ "version": "54.7.0"
68
68
  }
@@ -0,0 +1,61 @@
1
+ const asyncRetry = require('async/retry');
2
+ const {Block} = require('bitcoinjs-lib');
3
+ const {spawnLightningCluster} = require('ln-docker-daemons');
4
+ const {test} = require('@alexbosworth/tap');
5
+
6
+ const {getBlock} = require('./../../');
7
+ const {getHeight} = require('./../../');
8
+
9
+ const confirmationCount = 6;
10
+ const {fromHex} = Block;
11
+ const times = 100;
12
+
13
+ // Get height should return height
14
+ test(`Get height`, async ({end, equal, fail}) => {
15
+ const {nodes} = await spawnLightningCluster({});
16
+
17
+ const [{chain, generate, kill, lnd}] = nodes;
18
+
19
+ const blockchain = await getHeight({lnd});
20
+
21
+ const hash = blockchain.current_block_hash;
22
+ const height = blockchain.current_block_height;
23
+
24
+ // Try getting a block by the hash
25
+ try {
26
+ const {block} = await getBlock({lnd, id: blockchain.current_block_hash});
27
+
28
+ equal(fromHex(block).getId(), hash, 'Got block');
29
+ } catch (err) {
30
+ const [code, message] = err;
31
+
32
+ equal(code, 501, 'Got expected code');
33
+ equal(message, 'GetBlockMethodNotSupported', 'Got expected message');
34
+
35
+ await kill({});
36
+
37
+ return end();
38
+ }
39
+
40
+ // Try getting a block by the height
41
+ try {
42
+ const {block} = await getBlock({height, lnd});
43
+
44
+ equal(fromHex(block).getId(), hash, 'Got block for height');
45
+ } catch (err) {
46
+ equal(err, null, 'Expected no error');
47
+ }
48
+
49
+ // Try getting the chain tip block
50
+ try {
51
+ const {block} = await getBlock({lnd});
52
+
53
+ equal(fromHex(block).getId(), hash, 'Got chain tip block');
54
+ } catch (err) {
55
+ equal(err, null, 'Expected no error');
56
+ }
57
+
58
+ await kill({});
59
+
60
+ return end();
61
+ });
@@ -185,23 +185,29 @@ test(`Subscribe to RPC requests`, async ({end, equal, fail, strictSame}) => {
185
185
  }
186
186
  });
187
187
 
188
- try {
189
- // Attempt a channel close with an address
190
- await closeChannel({
191
- lnd,
192
- address: 'address',
193
- transaction_id: Buffer.alloc(32).toString('hex'),
194
- transaction_vout: 0,
195
- });
188
+ await asyncRetry({interval, times}, async () => {
189
+ try {
190
+ // Attempt a channel close with an address
191
+ await closeChannel({
192
+ lnd,
193
+ address: 'address',
194
+ transaction_id: Buffer.alloc(32).toString('hex'),
195
+ transaction_vout: 0,
196
+ });
196
197
 
197
- fail('ExpectedChannelCloseRejected');
198
- } catch (err) {
199
- const [code, message, raw] = err;
198
+ fail('ExpectedChannelCloseRejected');
199
+ } catch (err) {
200
+ const [code, message, raw] = err;
200
201
 
201
- strictSame(code, 503, 'Close fails with server error');
202
- strictSame(message, 'UnexpectedCloseChannelError', 'Close err message');
203
- strictSame(raw.err.details, 'message', 'Custom message received');
204
- }
202
+ if (raw.err.details !== 'message') {
203
+ throw err;
204
+ }
205
+
206
+ strictSame(code, 503, 'Close fails with server error');
207
+ strictSame(message, 'UnexpectedCloseChannelError', 'Close err message');
208
+ strictSame(raw.err.details, 'message', 'Custom message received');
209
+ }
210
+ });
205
211
 
206
212
  subscription.removeAllListeners();
207
213
  }
@@ -122,26 +122,30 @@ test(`Pay with multiple paths`, async ({end, equal, rejects, strictSame}) => {
122
122
 
123
123
  const parsed = parsePaymentRequest({request: controlInvoice.request});
124
124
 
125
- const route1 = await getRouteToDestination({
126
- cltv_delta: parsed.cltv_delta,
127
- destination: parsed.destination,
128
- features: parsed.features,
129
- lnd: target.lnd,
130
- outgoing_channel: channel1.id,
131
- payment: parsed.payment,
132
- tokens: ceil(parsed.tokens / channels.length),
133
- total_mtokens: parsed.mtokens,
125
+ const route1 = await asyncRetry({interval, times}, async () => {
126
+ return await getRouteToDestination({
127
+ cltv_delta: parsed.cltv_delta,
128
+ destination: parsed.destination,
129
+ features: parsed.features,
130
+ lnd: target.lnd,
131
+ outgoing_channel: channel1.id,
132
+ payment: parsed.payment,
133
+ tokens: ceil(parsed.tokens / channels.length),
134
+ total_mtokens: parsed.mtokens,
135
+ });
134
136
  });
135
137
 
136
- const route2 = await getRouteToDestination({
137
- cltv_delta: parsed.cltv_delta,
138
- destination: parsed.destination,
139
- features: parsed.features,
140
- lnd: target.lnd,
141
- outgoing_channel: channel2.id,
142
- payment: parsed.payment,
143
- tokens: ceil(parsed.tokens / channels.length),
144
- total_mtokens: parsed.mtokens,
138
+ const route2 = await asyncRetry({interval, times}, async () => {
139
+ return await getRouteToDestination({
140
+ cltv_delta: parsed.cltv_delta,
141
+ destination: parsed.destination,
142
+ features: parsed.features,
143
+ lnd: target.lnd,
144
+ outgoing_channel: channel2.id,
145
+ payment: parsed.payment,
146
+ tokens: ceil(parsed.tokens / channels.length),
147
+ total_mtokens: parsed.mtokens,
148
+ });
145
149
  });
146
150
 
147
151
  // Pay using routes. Multiple channels must be used to avoid tempChanFail
@@ -149,10 +153,12 @@ test(`Pay with multiple paths`, async ({end, equal, rejects, strictSame}) => {
149
153
  const routes = [route1.route, route2.route];
150
154
 
151
155
  const payRoutes = routes.map(route => {
152
- return payViaRoutes({
153
- id: parsed.id,
154
- lnd: target.lnd,
155
- routes: [route],
156
+ return asyncRetry({interval, times}, async () => {
157
+ return payViaRoutes({
158
+ id: parsed.id,
159
+ lnd: target.lnd,
160
+ routes: [route],
161
+ });
156
162
  });
157
163
  });
158
164