ln-service 56.8.2 → 56.10.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.10.0
|
|
4
|
+
|
|
5
|
+
- `createInvoice`, `createHodlInvoice`: Add `routes` to customize the hop hints
|
|
6
|
+
|
|
7
|
+
## 56.9.0
|
|
8
|
+
|
|
9
|
+
- `openChannel`: Add `is_trusted_funding` to support skipping confirmation wait
|
|
10
|
+
|
|
3
11
|
## 56.8.2
|
|
4
12
|
|
|
5
13
|
- `subscribeToForwards`: Cancel subscription when there are no event listeners
|
package/README.md
CHANGED
|
@@ -641,6 +641,13 @@ Requires `address:write`, `invoices:write` permission
|
|
|
641
641
|
[is_including_private_channels]: <Invoice Includes Private Channels Bool>
|
|
642
642
|
lnd: <Authenticated LND API Object>
|
|
643
643
|
[mtokens]: <Millitokens String>
|
|
644
|
+
[routes]: [[{
|
|
645
|
+
[base_fee_mtokens]: <Base Routing Fee In Millitokens String>
|
|
646
|
+
[channel]: <Standard Format Channel Id String>
|
|
647
|
+
[cltv_delta]: <CLTV Blocks Delta Number>
|
|
648
|
+
[fee_rate]: <Fee Rate In Millitokens Per Million Number>
|
|
649
|
+
public_key: <Forward Edge Public Key Hex String>
|
|
650
|
+
}]]
|
|
644
651
|
[tokens]: <Tokens Number>
|
|
645
652
|
}
|
|
646
653
|
|
|
@@ -707,6 +714,13 @@ Requires `address:write`, `invoices:write` permission
|
|
|
707
714
|
lnd: <Authenticated LND API Object>
|
|
708
715
|
[secret]: <Payment Preimage Hex String>
|
|
709
716
|
[mtokens]: <Millitokens String>
|
|
717
|
+
[routes]: [[{
|
|
718
|
+
[base_fee_mtokens]: <Base Routing Fee In Millitokens String>
|
|
719
|
+
[channel]: <Standard Format Channel Id String>
|
|
720
|
+
[cltv_delta]: <CLTV Blocks Delta Number>
|
|
721
|
+
[fee_rate]: <Fee Rate In Millitokens Per Million Number>
|
|
722
|
+
public_key: <Forward Edge Public Key Hex String>
|
|
723
|
+
}]]
|
|
710
724
|
[tokens]: <Tokens Number>
|
|
711
725
|
}
|
|
712
726
|
|
|
@@ -3724,6 +3738,7 @@ Requires `offchain:write`, `onchain:write`, `peers:write` permissions
|
|
|
3724
3738
|
[give_tokens]: <Tokens to Gift To Partner Number> // Defaults to zero
|
|
3725
3739
|
[is_max_funding]: <Use Maximal Chain Funds For Local Funding Bool>
|
|
3726
3740
|
[is_private]: <Channel is Private Bool> // Defaults to false
|
|
3741
|
+
[is_trusted_funding]: <Accept Funding as Trusted Bool>
|
|
3727
3742
|
lnd: <Authenticated LND API Object>
|
|
3728
3743
|
local_tokens: <Total Channel Capacity Tokens Number>
|
|
3729
3744
|
[min_confirmations]: <Spend UTXOs With Minimum Confirmations 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.
|
|
14
|
+
"lightning": "9.10.0",
|
|
15
15
|
"macaroon": "3.0.4",
|
|
16
16
|
"morgan": "1.10.0",
|
|
17
17
|
"ws": "8.13.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.
|
|
72
|
+
"version": "56.10.0"
|
|
73
73
|
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
const {deepEqual} = require('node:assert').strict;
|
|
2
|
+
const {equal} = require('node:assert').strict;
|
|
3
|
+
const test = require('node:test');
|
|
4
|
+
|
|
5
|
+
const asyncRetry = require('async/retry');
|
|
6
|
+
const {spawnLightningCluster} = require('ln-docker-daemons');
|
|
7
|
+
|
|
8
|
+
const {addPeer} = require('./../../');
|
|
9
|
+
const {getEphemeralChannelIds} = require('./../../');
|
|
10
|
+
const {openChannel} = require('./../../');
|
|
11
|
+
const {openChannels} = require('./../../');
|
|
12
|
+
const {subscribeToChannels} = require('./../../');
|
|
13
|
+
const {subscribeToOpenRequests} = require('./../../');
|
|
14
|
+
|
|
15
|
+
const capacity = 1e6;
|
|
16
|
+
const interval = 10;
|
|
17
|
+
const maturity = 100;
|
|
18
|
+
const size = 2;
|
|
19
|
+
const times = 4000;
|
|
20
|
+
|
|
21
|
+
// Opening an unconfirmed channel should in an immediate channel opening
|
|
22
|
+
test(`Open an unconfirmed channel`, async () => {
|
|
23
|
+
// Unconfirmed channels are not supported on LND 0.15.0 and below
|
|
24
|
+
{
|
|
25
|
+
const {kill, nodes} = await spawnLightningCluster({});
|
|
26
|
+
|
|
27
|
+
const [{lnd}] = nodes;
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
await getEphemeralChannelIds({lnd});
|
|
31
|
+
|
|
32
|
+
await kill({});
|
|
33
|
+
} catch (err) {
|
|
34
|
+
deepEqual(err, [501, 'ListAliasesMethodNotSupported']);
|
|
35
|
+
|
|
36
|
+
await kill({});
|
|
37
|
+
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const {kill, nodes} = await spawnLightningCluster({
|
|
43
|
+
size,
|
|
44
|
+
lnd_configuration: [
|
|
45
|
+
'--maxpendingchannels=10',
|
|
46
|
+
'--protocol.option-scid-alias',
|
|
47
|
+
'--protocol.zero-conf',
|
|
48
|
+
],
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const [{generate, lnd}, target] = nodes;
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
await generate({count: maturity});
|
|
55
|
+
|
|
56
|
+
// Connect to the peer
|
|
57
|
+
await addPeer({lnd, public_key: target.id, socket: target.socket});
|
|
58
|
+
|
|
59
|
+
// Wait for channel to be receptive to opens
|
|
60
|
+
await asyncRetry({interval, times}, async () => {
|
|
61
|
+
return await openChannels({
|
|
62
|
+
lnd,
|
|
63
|
+
channels: [{capacity, partner_public_key: target.id}],
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const acceptSub = subscribeToOpenRequests({lnd: target.lnd});
|
|
68
|
+
|
|
69
|
+
acceptSub.on('channel_request', request => {
|
|
70
|
+
equal(request.is_trusted_funding, true, 'Request is trusted funding');
|
|
71
|
+
|
|
72
|
+
return request.accept({is_trusted_funding: true});
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
// Propose the channel to the peer
|
|
76
|
+
const pending = await asyncRetry({interval, times}, async () => {
|
|
77
|
+
return await openChannel({
|
|
78
|
+
lnd,
|
|
79
|
+
is_trusted_funding: true,
|
|
80
|
+
local_tokens: capacity,
|
|
81
|
+
partner_public_key: target.id,
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
equal(pending.transaction_id.length, 64, 'Got transaction id');
|
|
86
|
+
equal(pending.transaction_vout, 0, 'Got transaction output index');
|
|
87
|
+
} catch (err) {
|
|
88
|
+
equal(err, null, 'No more error reported');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
await kill({});
|
|
92
|
+
|
|
93
|
+
return;
|
|
94
|
+
});
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
const {deepEqual} = require('node:assert').strict;
|
|
2
|
+
const test = require('node:test');
|
|
3
|
+
|
|
4
|
+
const asyncRetry = require('async/retry');
|
|
5
|
+
const {setupChannel} = require('ln-docker-daemons');
|
|
6
|
+
const {spawnLightningCluster} = require('ln-docker-daemons');
|
|
7
|
+
|
|
8
|
+
const {cancelHodlInvoice} = require('./../../');
|
|
9
|
+
const {createHodlInvoice} = require('./../../');
|
|
10
|
+
const {createInvoice} = require('./../../');
|
|
11
|
+
const {parsePaymentRequest} = require('./../../');
|
|
12
|
+
|
|
13
|
+
const interval = 10;
|
|
14
|
+
const size = 3;
|
|
15
|
+
const times = 1000;
|
|
16
|
+
const tokens = 100;
|
|
17
|
+
|
|
18
|
+
// createInvoice should result in a created invoice with hop hints
|
|
19
|
+
test(`Create an invoice with hop hints`, async t => {
|
|
20
|
+
const {kill, nodes} = await spawnLightningCluster({size});
|
|
21
|
+
|
|
22
|
+
t.after(async () => await kill({}));
|
|
23
|
+
|
|
24
|
+
const [{generate, lnd}, target, remote] = nodes;
|
|
25
|
+
|
|
26
|
+
const channel = await setupChannel({generate, lnd, to: target});
|
|
27
|
+
|
|
28
|
+
const remoteChannel = await setupChannel({
|
|
29
|
+
generate: target.generate,
|
|
30
|
+
is_private: true,
|
|
31
|
+
lnd: target.lnd,
|
|
32
|
+
to: remote,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const specialRoutes = [[
|
|
36
|
+
{
|
|
37
|
+
public_key: target.id,
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
base_fee_mtokens: '123456',
|
|
41
|
+
channel: remoteChannel.id,
|
|
42
|
+
cltv_delta: 200,
|
|
43
|
+
fee_rate: 123456,
|
|
44
|
+
public_key: remote.id,
|
|
45
|
+
},
|
|
46
|
+
]];
|
|
47
|
+
|
|
48
|
+
const invoice = await asyncRetry({interval, times}, async () => {
|
|
49
|
+
const invoice = await createInvoice({
|
|
50
|
+
tokens,
|
|
51
|
+
is_including_private_channels: true,
|
|
52
|
+
lnd: remote.lnd,
|
|
53
|
+
routes: specialRoutes,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const hodlInvoice = await createHodlInvoice({
|
|
57
|
+
tokens,
|
|
58
|
+
is_including_private_channels: true,
|
|
59
|
+
lnd: remote.lnd,
|
|
60
|
+
routes: specialRoutes,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const {routes} = parsePaymentRequest({request: invoice.request});
|
|
64
|
+
|
|
65
|
+
// Wait for private routes to get picked up
|
|
66
|
+
if (!routes) {
|
|
67
|
+
await cancelHodlInvoice({id: invoice.id, lnd: remote.lnd});
|
|
68
|
+
|
|
69
|
+
throw new Error('ExpectedRouteForInvoice');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const hodl = parsePaymentRequest({request: hodlInvoice.request});
|
|
73
|
+
|
|
74
|
+
// Wait for private routes to get picked up
|
|
75
|
+
if (!hodl.routes) {
|
|
76
|
+
await cancelHodlInvoice({id: hodl.id, lnd: remote.lnd});
|
|
77
|
+
|
|
78
|
+
throw new Error('ExpectedRouteForHodlInvoice');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
normal_routes: routes,
|
|
83
|
+
hodl_routes: hodl.routes,
|
|
84
|
+
};
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
deepEqual(invoice.normal_routes, specialRoutes, 'Got expected routes');
|
|
88
|
+
deepEqual(invoice.hodl_routes, specialRoutes, 'Got expected hodl routes');
|
|
89
|
+
|
|
90
|
+
return;
|
|
91
|
+
});
|