lightning 10.1.2 → 10.1.4

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,6 +1,6 @@
1
1
  # Versions
2
2
 
3
- ## 10.1.2
3
+ ## 10.1.4
4
4
 
5
5
  - `getBlockHeader`: Add method to get the header portion of a block
6
6
 
@@ -11,6 +11,7 @@ const decBase = 10;
11
11
  const defaultOdds = 950000;
12
12
  const fullConfidence = 1e6;
13
13
  const {isArray} = Array;
14
+ const notFoundIndex = -1;
14
15
  const oddsDenominator = BigInt(1e6);
15
16
  const unimplemented = 'QueryProbabilityNotImplemented';
16
17
 
@@ -43,7 +44,7 @@ module.exports = ({from, hops, lnd}, cbk) => {
43
44
  return cbk([400, 'ExpectedArrayOfHopsToCalculateRoutingOdds']);
44
45
  }
45
46
 
46
- if (!!hops.find(n => !n.channel || !n.public_key)) {
47
+ if (hops.findIndex(n => !n.public_key) !== notFoundIndex) {
47
48
  return cbk([400, 'ExpectedHopsWithEdges']);
48
49
  }
49
50
 
@@ -19,6 +19,7 @@
19
19
  "prefAttachType": "preferential",
20
20
  "versions": {
21
21
  "0d5b0fefa4d9082f7964836f5e58c3a6bda8e471": "0.10.2-beta",
22
+ "13aa7f99248c7ee63989d3b62e0cbfe86d7b0964": "0.17.3-beta",
22
23
  "15c1eb13972f86a7c1e8cb084aa6d52700d685ff": "0.14.5-beta",
23
24
  "1a3194d302f33bb52823297d9d7f75cd37516053": "0.10.0-beta",
24
25
  "1e511be523eb8e97c4e2d9c89a7a263963a3929f": "0.14.2-beta",
@@ -32,6 +33,7 @@
32
33
  "5c36d96c9cbe8b27c29f9682dcbdab7928ae870f": "0.15.0-beta",
33
34
  "6042004edaaa5b3cad0a0808ff23dba4716f7178": "0.14.1-beta",
34
35
  "61c34683058f2cc8dc10f49392a0057440d831c4": "0.13.4-beta",
36
+ "6744c64e628b068e59c3a714d0876f70703df91f": "0.17.2-beta",
35
37
  "6bd30047c1b1188029e8af6ee8a135cf86e7dc4b": "0.16.4-beta",
36
38
  "725ff104808f49f0a5247bfdb4b6b5da7f488d38": "0.13.0-beta",
37
39
  "744feb04e28afdcfa3702a78e83977090c471576": "0.17.1-beta",
package/package.json CHANGED
@@ -7,11 +7,11 @@
7
7
  "url": "https://github.com/alexbosworth/lightning/issues"
8
8
  },
9
9
  "dependencies": {
10
- "@grpc/grpc-js": "1.9.9",
10
+ "@grpc/grpc-js": "1.9.12",
11
11
  "@grpc/proto-loader": "0.7.10",
12
- "@types/node": "20.8.10",
12
+ "@types/node": "20.10.3",
13
13
  "@types/request": "2.48.12",
14
- "@types/ws": "8.5.9",
14
+ "@types/ws": "8.5.10",
15
15
  "async": "3.2.5",
16
16
  "asyncjs-util": "1.2.12",
17
17
  "bitcoinjs-lib": "6.1.5",
@@ -22,12 +22,12 @@
22
22
  "invoices": "3.0.0",
23
23
  "psbt": "3.0.0",
24
24
  "tiny-secp256k1": "2.2.3",
25
- "type-fest": "4.7.1"
25
+ "type-fest": "4.8.3"
26
26
  },
27
27
  "description": "Lightning Network client library",
28
28
  "devDependencies": {
29
29
  "tsd": "0.29.0",
30
- "typescript": "5.2.2"
30
+ "typescript": "5.3.3"
31
31
  },
32
32
  "engines": {
33
33
  "node": ">=18"
@@ -53,5 +53,5 @@
53
53
  "directory": "test/typescript"
54
54
  },
55
55
  "types": "index.d.ts",
56
- "version": "10.1.2"
56
+ "version": "10.1.4"
57
57
  }
@@ -0,0 +1,143 @@
1
+ const {deepStrictEqual} = require('node:assert').strict;
2
+ const EventEmitter = require('events');
3
+ const {rejects} = require('node:assert').strict;
4
+ const test = require('node:test');
5
+
6
+ const {getInfoResponse} = require('./../fixtures');
7
+ const {getRouteConfidence} = require('./../../../');
8
+
9
+ const makeLnd = ({err, res}) => {
10
+ return {
11
+ default: {
12
+ getInfo: ({}, cbk) => cbk(err, getInfoResponse),
13
+ },
14
+ router: {
15
+ queryMissionControl: ({}, cbk) => {
16
+ if (!!err) {
17
+ return cbk(err);
18
+ }
19
+
20
+ if (res !== undefined) {
21
+ return cbk(null, res);
22
+ }
23
+
24
+ return cbk(null, {
25
+ pairs: [{
26
+ history: {
27
+ fail_amt_msat: '1000',
28
+ fail_amt_sat: '1',
29
+ fail_time: '1',
30
+ success_amt_msat: '1000',
31
+ success_amt_sat: '1',
32
+ success_time: '1',
33
+ },
34
+ node_from: Buffer.alloc(33, 3),
35
+ node_to: Buffer.alloc(33, 2),
36
+ }],
37
+ });
38
+ },
39
+ queryProbability: ({}, cbk) => {
40
+ if (!!err) {
41
+ return cbk(err);
42
+ }
43
+
44
+ if (res !== undefined) {
45
+ return cbk(null, res);
46
+ }
47
+
48
+ return cbk(null, {history: {}, probability: 0.5});
49
+ },
50
+ },
51
+ wallet: {
52
+ deriveKey: ({}, cbk) => cbk('err'),
53
+ },
54
+ };
55
+ };
56
+
57
+ const tests = [
58
+ {
59
+ args: {},
60
+ description: 'Hops are required',
61
+ error: [400, 'ExpectedArrayOfHopsToCalculateRoutingOdds'],
62
+ },
63
+ {
64
+ args: {hops: [{}]},
65
+ description: 'Valid hops are required',
66
+ error: [400, 'ExpectedHopsWithEdges'],
67
+ },
68
+ {
69
+ args: {
70
+ from: Buffer.alloc(33, 1).toString('hex'),
71
+ hops: [{
72
+ forward_mtokens: '1',
73
+ public_key: Buffer.alloc(33, 2).toString('hex'),
74
+ }],
75
+ lnd: {
76
+ default: {
77
+ getInfo: ({}, cbk) => cbk(null, getInfoResponse),
78
+ },
79
+ router: {
80
+ queryMissionControl: ({}, cbk) => {
81
+ return cbk(null, {
82
+ pairs: [{
83
+ history: {
84
+ fail_amt_msat: '1000',
85
+ fail_amt_sat: '1',
86
+ fail_time: '1',
87
+ success_amt_msat: '1000',
88
+ success_amt_sat: '1',
89
+ success_time: '1',
90
+ },
91
+ node_from: Buffer.alloc(33, 3),
92
+ node_to: Buffer.alloc(33, 2),
93
+ }],
94
+ });
95
+ },
96
+ queryProbability: ({}, cbk) => cbk('err'),
97
+ },
98
+ wallet: {
99
+ deriveKey: ({}, cbk) => cbk('err'),
100
+ },
101
+ },
102
+ },
103
+ description: 'Get route confidence when confidence query returns err',
104
+ error: [503, 'UnexpectedErrorFromQueryProbability', {err: 'err'}],
105
+ },
106
+ {
107
+ args: {
108
+ from: Buffer.alloc(33, 1).toString('hex'),
109
+ hops: [{
110
+ forward_mtokens: '1',
111
+ public_key: Buffer.alloc(33, 2).toString('hex'),
112
+ }],
113
+ lnd: makeLnd({}),
114
+ },
115
+ description: 'Get route confidence from non self',
116
+ expected: {confidence: 950000},
117
+ },
118
+ {
119
+ args: {
120
+ hops: [{
121
+ forward_mtokens: '1',
122
+ public_key: Buffer.alloc(33, 2).toString('hex'),
123
+ }],
124
+ lnd: makeLnd({}),
125
+ },
126
+ description: 'Get route confidence',
127
+ expected: {confidence: 950000},
128
+ },
129
+ ];
130
+
131
+ tests.forEach(({args, description, error, expected}) => {
132
+ return test(description, async () => {
133
+ if (!!error) {
134
+ await rejects(getRouteConfidence(args), error, 'Got expected error');
135
+ } else {
136
+ const got = await getRouteConfidence(args);
137
+
138
+ deepStrictEqual(got, expected, 'Got expected result');
139
+ }
140
+
141
+ return;
142
+ });
143
+ });
@@ -0,0 +1,276 @@
1
+ const {deepStrictEqual} = require('node:assert').strict;
2
+ const EventEmitter = require('node:events');
3
+ const {rejects} = require('node:assert').strict;
4
+ const test = require('node:test');
5
+
6
+ const {isDestinationPayable} = require('./../../../');
7
+
8
+ const makePaymentData = overrides => {
9
+ const data = {
10
+ creation_date: '1',
11
+ creation_time_ns: '0',
12
+ failure_reason: 'FAILURE_REASON_TIMEOUT',
13
+ fee_msat: '1000',
14
+ fee_sat: '1',
15
+ htlcs: [{
16
+ attempt_time_ns: '1000000',
17
+ failure: {
18
+ channel_update: {
19
+ base_fee: '1000',
20
+ chain_hash: Buffer.alloc(32),
21
+ chan_id: '1',
22
+ channel_flags: 1,
23
+ extra_opaque_data: Buffer.alloc(1),
24
+ fee_rate: 1,
25
+ htlc_maximum_msat: '1000',
26
+ htlc_minimum_msat: '1000',
27
+ message_flags: 1,
28
+ signature: Buffer.alloc(71),
29
+ time_lock_delta: 1,
30
+ timestamp: 1,
31
+ },
32
+ code: 'UNREADABLE_FAILURE',
33
+ failure_source_index1: 1,
34
+ height: 1,
35
+ htlc_msat: '1000',
36
+ },
37
+ resolve_time_ns: '1000000',
38
+ route: {
39
+ hops: [{
40
+ amt_to_forward_msat: '1000',
41
+ chan_id: '1',
42
+ chan_capacity: 1,
43
+ expiry: 1,
44
+ fee_msat: '1000',
45
+ mpp_record: {
46
+ payment_addr: Buffer.alloc(32),
47
+ total_amt_msat: '1000',
48
+ },
49
+ pub_key: Buffer.alloc(33).toString('hex'),
50
+ tlv_payload: true,
51
+ }],
52
+ total_amt: '1',
53
+ total_amt_msat: '1000',
54
+ total_fees: '1',
55
+ total_fees_msat: '1000',
56
+ total_time_lock: 1,
57
+ },
58
+ status: 'FAILED',
59
+ }],
60
+ path: [Buffer.alloc(33).toString('hex'), Buffer.alloc(33).toString('hex')],
61
+ payment_hash: Buffer.alloc(32).toString('hex'),
62
+ payment_index: '1',
63
+ payment_preimage: Buffer.alloc(32).toString('hex'),
64
+ payment_request: 'lntb1500n1pdn4czkpp5ugdqer05qrrxuchrzkcue94th9w2xzasp9qm7d0yxcgp4uh4kn4qdpa2fjkzep6yprkcmmzv9kzqsmj09c8gmmrw4e8yetwvdujq5n9va6kcct5d9hkucqzysdlghdpua7uvjjkcfj49psxtlqzkp5pdncffdfk2cp3mp76thrl29qhqgzufm503pjj96586n5w6edgw3n66j4rxxs707y4zdjuhyt6qqe5weu4',
65
+ status: 'FAILED',
66
+ value: '1',
67
+ value_msat: '1000',
68
+ value_sat: '1',
69
+ };
70
+
71
+ Object.keys(overrides).forEach(k => data[k] = overrides[k]);
72
+
73
+ return data;
74
+ };
75
+
76
+ const makeLnd = args => {
77
+ return {
78
+ chain: {
79
+ registerBlockEpochNtfn: ({}) => {
80
+ const emitter = new EventEmitter();
81
+
82
+ emitter.cancel = () => {};
83
+
84
+ process.nextTick(() => emitter.emit('error', 'err'));
85
+
86
+ return emitter;
87
+ },
88
+ },
89
+ default: {
90
+ getInfo: ({}, cbk) => {
91
+ return cbk(null, {
92
+ alias: 'alias',
93
+ best_header_timestamp: 1,
94
+ block_hash: '00',
95
+ block_height: 1,
96
+ chains: [{chain: 'chain', network: 'network'}],
97
+ color: '#000000',
98
+ features: {'1': {is_known: true, is_required: false}},
99
+ identity_pubkey: Buffer.alloc(33).toString('hex'),
100
+ num_active_channels: 1,
101
+ num_peers: 1,
102
+ num_pending_channels: 1,
103
+ synced_to_chain: true,
104
+ uris: [],
105
+ version: 'version',
106
+ });
107
+ },
108
+ },
109
+ router: {
110
+ sendPaymentV2: ({}) => {
111
+ const data = args.data || makePaymentData({});
112
+ const emitter = new EventEmitter();
113
+
114
+ if (!!args.is_end) {
115
+ process.nextTick(() => emitter.emit('end'));
116
+ } else if (!!args.err) {
117
+ process.nextTick(() => emitter.emit('error', args.err));
118
+ } else {
119
+ process.nextTick(() => emitter.emit('data', data));
120
+ }
121
+
122
+ return emitter;
123
+ },
124
+ },
125
+ };
126
+ };
127
+
128
+ const makeArgs = overrides => {
129
+ const args = {
130
+ cltv_delta: 1,
131
+ destination: Buffer.alloc(33).toString('hex'),
132
+ features: [{bit: 1}],
133
+ id: Buffer.alloc(32).toString('hex'),
134
+ incoming_peer: Buffer.alloc(33).toString('hex'),
135
+ lnd: makeLnd({}),
136
+ max_fee: 1,
137
+ max_fee_mtokens: '1000',
138
+ messages: [{
139
+ type: '1',
140
+ value: Buffer.alloc(1).toString('hex'),
141
+ }],
142
+ mtokens: '1000',
143
+ outgoing_channel: '0x0x1',
144
+ pathfinding_timeout: 1,
145
+ routes: [[{
146
+ base_fee_mtokens: '1000',
147
+ channel: '0x0x1',
148
+ cltv_delta: 1,
149
+ fee_rate: 1,
150
+ public_key: Buffer.alloc(33).toString('hex'),
151
+ }]],
152
+ tokens: 1,
153
+ };
154
+
155
+ Object.keys(overrides).forEach(k => args[k] = overrides[k]);
156
+
157
+ return args;
158
+ };
159
+
160
+ const makeExpectedPayment = ({}) => {
161
+ return {
162
+ failed: undefined,
163
+ is_confirmed: true,
164
+ is_failed: false,
165
+ is_pending: false,
166
+ payment: {
167
+ fee: 0,
168
+ fee_mtokens: '1',
169
+ hops: [{
170
+ channel: '0x0x1',
171
+ channel_capacity: 1,
172
+ fee: 0,
173
+ fee_mtokens: '1',
174
+ forward: 0,
175
+ forward_mtokens: '1',
176
+ public_key: 'b',
177
+ timeout: 1,
178
+ }],
179
+ id: '66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925',
180
+ paths: [{
181
+ fee: 0,
182
+ fee_mtokens: '1',
183
+ hops: [{
184
+ channel: '0x0x1',
185
+ channel_capacity: 1,
186
+ fee: 0,
187
+ fee_mtokens: '1',
188
+ forward: 0,
189
+ forward_mtokens: '1',
190
+ public_key: 'b',
191
+ timeout: 1
192
+ }],
193
+ mtokens: '1',
194
+ safe_fee: 1,
195
+ safe_tokens: 1,
196
+ timeout: 1,
197
+ tokens: 0,
198
+ }],
199
+ mtokens: '1',
200
+ safe_fee: 1,
201
+ safe_tokens: 1,
202
+ secret: Buffer.alloc(32).toString('hex'),
203
+ timeout: 1,
204
+ tokens: 0,
205
+ },
206
+ };
207
+ };
208
+
209
+ const tests = [
210
+ {
211
+ args: makeArgs({destination: undefined}),
212
+ description: 'The payment destination is required',
213
+ error: [400, 'ExpectedDestinationToCheckPayability'],
214
+ },
215
+ {
216
+ args: makeArgs({lnd: undefined}),
217
+ description: 'LND is required',
218
+ error: [400, 'ExpectedAuthenticatedLndWithRouterToTestPayable'],
219
+ },
220
+ {
221
+ args: makeArgs({
222
+ lnd: {
223
+ chain: {
224
+ registerBlockEpochNtfn: ({}) => {
225
+ const emitter = new EventEmitter();
226
+
227
+ emitter.cancel = () => {};
228
+
229
+ process.nextTick(() => emitter.emit('error', 'err'));
230
+
231
+ return emitter;
232
+ },
233
+ },
234
+ default: {
235
+ getInfo: ({}, cbk) => {
236
+ return cbk('err');
237
+ },
238
+ },
239
+ router: {
240
+ sendPaymentV2: ({}) => {
241
+ const emitter = new EventEmitter();
242
+
243
+ process.nextTick(() => emitter.emit('error', 'err'));
244
+
245
+ return emitter;
246
+ },
247
+ },
248
+ },
249
+ }),
250
+ description: 'A payment attempt times out',
251
+ error: [
252
+ 503,
253
+ 'UnexpectedErrorCheckingPayability',
254
+ {err: [503, 'UnexpectedPaymentError', {err: 'err'}]},
255
+ ],
256
+ },
257
+ {
258
+ args: makeArgs({}),
259
+ description: 'A payment attempt times out',
260
+ expected: {is_payable: false},
261
+ },
262
+ ];
263
+
264
+ tests.forEach(({args, description, error, expected}) => {
265
+ return test(description, async () => {
266
+ if (!!error) {
267
+ await rejects(() => isDestinationPayable(args), error, 'Got error');
268
+ } else {
269
+ const payment = await isDestinationPayable(args);
270
+
271
+ deepStrictEqual(payment, expected, 'Got expected payment');
272
+ }
273
+
274
+ return;
275
+ });
276
+ });