ln-service 59.4.1 → 59.5.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,11 @@
|
|
|
1
1
|
# Versions
|
|
2
2
|
|
|
3
|
+
## 59.5.0
|
|
4
|
+
|
|
5
|
+
- `createSignedRequest`: Add support for signing BLIP39 path payment requests
|
|
6
|
+
- `createUnsignedRequest`: Add support for specifying BLIP39 payment req paths
|
|
7
|
+
- `parsePaymentRequest`: Add support for parsing BLIP39 payment request paths
|
|
8
|
+
|
|
3
9
|
## 59.4.1
|
|
4
10
|
|
|
5
11
|
- `subscribeToForwardRequests`: Invalid requests to forward more than the
|
package/package.json
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"bolt07": "2.0.0",
|
|
16
|
-
"invoices": "6.
|
|
16
|
+
"invoices": "6.2.0",
|
|
17
17
|
"lightning": "12.3.1",
|
|
18
18
|
"macaroon": "3.0.4"
|
|
19
19
|
},
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"asyncjs-util": "1.2.12",
|
|
25
25
|
"bip32": "5.0.1",
|
|
26
26
|
"bip66": "2.0.0",
|
|
27
|
-
"bolt04": "1.
|
|
27
|
+
"bolt04": "1.2.0",
|
|
28
28
|
"ecpair": "3.0.2",
|
|
29
29
|
"ln-docker-daemons": "8.0.5",
|
|
30
30
|
"p2tr": "3.0.0",
|
|
@@ -61,5 +61,5 @@
|
|
|
61
61
|
"integration-test-0.20.0": "DOCKER_LND_VERSION=v0.20.0-beta npm run test",
|
|
62
62
|
"test": "echo $DOCKER_LND_VERSION && node test/runner"
|
|
63
63
|
},
|
|
64
|
-
"version": "59.
|
|
64
|
+
"version": "59.5.0"
|
|
65
65
|
}
|
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
const asyncRetry = require('async/retry');
|
|
2
|
+
const {equal} = require('node:assert').strict;
|
|
2
3
|
const {strictEqual} = require('node:assert').strict;
|
|
3
4
|
const test = require('node:test');
|
|
4
5
|
|
|
6
|
+
const {paymentPathFromChannels} = require('bolt04');
|
|
5
7
|
const {setupChannel} = require('ln-docker-daemons');
|
|
6
8
|
const {spawnLightningCluster} = require('ln-docker-daemons');
|
|
7
9
|
|
|
8
10
|
const {addPeer} = require('./../../');
|
|
9
11
|
const {createInvoice} = require('./../../');
|
|
12
|
+
const {createSignedRequest} = require('./../../');
|
|
13
|
+
const {createUnsignedRequest} = require('./../../');
|
|
10
14
|
const {decodePaymentRequest} = require('./../../');
|
|
15
|
+
const {getChannel} = require('./../../');
|
|
16
|
+
const {getHeight} = require('./../../');
|
|
17
|
+
const {getInvoice} = require('./../../');
|
|
11
18
|
const {getWalletInfo} = require('./../../');
|
|
12
19
|
const {parsePaymentRequest} = require('./../../');
|
|
13
20
|
const {pay} = require('./../../');
|
|
@@ -15,13 +22,14 @@ const {pay} = require('./../../');
|
|
|
15
22
|
const count = 100;
|
|
16
23
|
const expiry = () => new Date(Date.now() + (4 * 60 * 60 * 1000)).toISOString();
|
|
17
24
|
const give = 500000;
|
|
25
|
+
const hopCount = 5;
|
|
18
26
|
const interval = 100;
|
|
19
27
|
const size = 3;
|
|
20
28
|
const times = 10000;
|
|
21
29
|
const tokens = 100;
|
|
22
30
|
|
|
23
31
|
// Paying to an encrypted routes invoice should result in a payment
|
|
24
|
-
test(`Create an invoice`, async () => {
|
|
32
|
+
test(`Create an encrypted routes invoice`, async () => {
|
|
25
33
|
const {kill, nodes} = await spawnLightningCluster({size});
|
|
26
34
|
|
|
27
35
|
const [{generate, lnd}, target, remote] = nodes;
|
|
@@ -29,11 +37,16 @@ test(`Create an invoice`, async () => {
|
|
|
29
37
|
await generate({count});
|
|
30
38
|
|
|
31
39
|
try {
|
|
32
|
-
await setupChannel({
|
|
40
|
+
const channel1 = await setupChannel({
|
|
41
|
+
generate,
|
|
42
|
+
lnd,
|
|
43
|
+
give_tokens: give,
|
|
44
|
+
to: target,
|
|
45
|
+
});
|
|
33
46
|
|
|
34
47
|
await addPeer({lnd, public_key: remote.id, socket: remote.socket});
|
|
35
48
|
|
|
36
|
-
await setupChannel({
|
|
49
|
+
const channel2 = await setupChannel({
|
|
37
50
|
generate: target.generate,
|
|
38
51
|
give_tokens: give,
|
|
39
52
|
lnd: target.lnd,
|
|
@@ -55,6 +68,89 @@ test(`Create an invoice`, async () => {
|
|
|
55
68
|
await pay({lnd: remote.lnd, request: invoice.request});
|
|
56
69
|
});
|
|
57
70
|
|
|
71
|
+
// Try padded variations on encrypted routes
|
|
72
|
+
const remoteInvoice = await createInvoice({tokens, lnd: remote.lnd});
|
|
73
|
+
const targetInvoice = await createInvoice({tokens, lnd: target.lnd});
|
|
74
|
+
|
|
75
|
+
const remotePaymentDetails = parsePaymentRequest({
|
|
76
|
+
request: remoteInvoice.request,
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
const targetPaymentDetails = parsePaymentRequest({
|
|
80
|
+
request: targetInvoice.request,
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
const remoteHeight = await getHeight({lnd: remote.lnd});
|
|
84
|
+
const targetHeight = await getHeight({lnd: target.lnd});
|
|
85
|
+
|
|
86
|
+
// Paying to a direct peer but with dummy hops to hide that
|
|
87
|
+
const targetPath = paymentPathFromChannels({
|
|
88
|
+
channels: [],
|
|
89
|
+
cltv_delta: targetPaymentDetails.cltv_delta + 3,
|
|
90
|
+
destination: targetPaymentDetails.destination,
|
|
91
|
+
current_block_height: targetHeight.current_block_height,
|
|
92
|
+
hop_count: hopCount,
|
|
93
|
+
id: targetPaymentDetails.payment,
|
|
94
|
+
max_mtokens: targetPaymentDetails.mtokens,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// Paying to an indirect peer with a receiver fee added
|
|
98
|
+
const remotePath = paymentPathFromChannels({
|
|
99
|
+
channels: [await getChannel({lnd: remote.lnd, id: channel2.id})],
|
|
100
|
+
cltv_delta: remotePaymentDetails.cltv_delta + 3,
|
|
101
|
+
destination: remotePaymentDetails.destination,
|
|
102
|
+
current_block_height: remoteHeight.current_block_height,
|
|
103
|
+
hop_count: hopCount,
|
|
104
|
+
id: remotePaymentDetails.payment,
|
|
105
|
+
max_mtokens: remotePaymentDetails.mtokens,
|
|
106
|
+
receiver_base_fee_mtokens: '1000',
|
|
107
|
+
receiver_fee_rate: 10000,
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
equal(remotePath.hops.length, hopCount, 'Got expected hops for target');
|
|
111
|
+
equal(targetPath.hops.length, hopCount, 'Got expected hops for remote');
|
|
112
|
+
|
|
113
|
+
// Try paying a remote path
|
|
114
|
+
{
|
|
115
|
+
// Make a blinded version of the invoice
|
|
116
|
+
const {hrp, tags} = createUnsignedRequest({
|
|
117
|
+
description: remotePaymentDetails.description,
|
|
118
|
+
expires_at: remotePaymentDetails.expires_at,
|
|
119
|
+
features: [{bit: 8}, {bit: 15}, {bit: 24}, {bit: 262}],
|
|
120
|
+
id: remotePaymentDetails.id,
|
|
121
|
+
mtokens: remotePaymentDetails.mtokens,
|
|
122
|
+
network: 'regtest',
|
|
123
|
+
paths: [remotePath],
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
const request = createSignedRequest({hrp, tags}).request;
|
|
127
|
+
|
|
128
|
+
await pay({lnd, request});
|
|
129
|
+
|
|
130
|
+
const received = await getInvoice({
|
|
131
|
+
id: remotePaymentDetails.id,
|
|
132
|
+
lnd: remote.lnd,
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
equal(received.received_mtokens, '102001', 'Got receiver fee');
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Try paying a peer path to target
|
|
139
|
+
{
|
|
140
|
+
// Make a blinded version of the invoice
|
|
141
|
+
const {hrp, tags} = createUnsignedRequest({
|
|
142
|
+
description: targetPaymentDetails.description,
|
|
143
|
+
expires_at: targetPaymentDetails.expires_at,
|
|
144
|
+
features: [{bit: 8}, {bit: 15}, {bit: 24}, {bit: 262}],
|
|
145
|
+
id: targetPaymentDetails.id,
|
|
146
|
+
mtokens: targetPaymentDetails.mtokens,
|
|
147
|
+
network: 'regtest',
|
|
148
|
+
paths: [targetPath],
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
await pay({lnd, request: createSignedRequest({hrp, tags}).request});
|
|
152
|
+
}
|
|
153
|
+
|
|
58
154
|
await kill({});
|
|
59
155
|
} catch (err) {
|
|
60
156
|
await kill({});
|
|
@@ -235,18 +235,22 @@ test(`Open unconfirmed channels`, async () => {
|
|
|
235
235
|
|
|
236
236
|
// Confirm the private channel
|
|
237
237
|
const privateConfirmed = await asyncRetry({interval, times}, async () => {
|
|
238
|
-
// Generate the channel into a block
|
|
239
|
-
await broadcastChainTransaction({
|
|
240
|
-
lnd,
|
|
241
|
-
transaction: signedPrivate.transaction,
|
|
242
|
-
});
|
|
243
|
-
|
|
244
238
|
await generate({});
|
|
245
239
|
|
|
246
240
|
const [confirmed] = (await getChannels({lnd})).channels;
|
|
247
241
|
|
|
248
242
|
const shut = await getClosedChannels({lnd});
|
|
249
243
|
|
|
244
|
+
if (!!shut.channels.length) {
|
|
245
|
+
return confirmed;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Generate the channel into a block
|
|
249
|
+
await broadcastChainTransaction({
|
|
250
|
+
lnd,
|
|
251
|
+
transaction: signedPrivate.transaction,
|
|
252
|
+
});
|
|
253
|
+
|
|
250
254
|
if (!shut.channels.length) {
|
|
251
255
|
throw new Error('ExpectedClosedChannel');
|
|
252
256
|
}
|
|
@@ -54,6 +54,8 @@ test('Probe for route', async () => {
|
|
|
54
54
|
await addPeer({lnd, public_key: remote.id, socket: remote.socket});
|
|
55
55
|
});
|
|
56
56
|
|
|
57
|
+
await generate({});
|
|
58
|
+
|
|
57
59
|
await setupChannel({
|
|
58
60
|
generate,
|
|
59
61
|
lnd,
|
|
@@ -61,6 +63,8 @@ test('Probe for route', async () => {
|
|
|
61
63
|
to: target,
|
|
62
64
|
});
|
|
63
65
|
|
|
66
|
+
await target.generate({});
|
|
67
|
+
|
|
64
68
|
await setupChannel({
|
|
65
69
|
capacity: channelCapacityTokens,
|
|
66
70
|
lnd: target.lnd,
|
|
@@ -68,7 +72,6 @@ test('Probe for route', async () => {
|
|
|
68
72
|
give_tokens: Math.round(channelCapacityTokens / 2),
|
|
69
73
|
to: remote,
|
|
70
74
|
});
|
|
71
|
-
|
|
72
75
|
const invoice = await createInvoice({tokens, lnd: remote.lnd});
|
|
73
76
|
|
|
74
77
|
await delay(1000);
|