ln-service 53.17.3 → 53.18.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 +10 -1
- package/README.md +59 -1
- package/index.js +2 -0
- package/package.json +10 -9
- package/test/integration/test_get_closed_channels.js +4 -2
- package/test/integration/test_get_node.js +0 -2
- package/test/integration/test_get_pending_coop.js +50 -46
- package/test/integration/test_propose_channel.js +1 -1
- package/test/integration/test_remove_peer.js +11 -3
- package/test/integration/test_subscribe_to_channels.js +3 -1
- package/test/integration/test_trusted_funding.js +244 -0
- package/test/invoicesrpc-integration/test_get_sweep_transactions.js +11 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
# Versions
|
|
2
2
|
|
|
3
|
-
## 53.
|
|
3
|
+
## 53.18.0
|
|
4
|
+
|
|
5
|
+
- `getChannels`: Add support for `is_trusted_funding` and `other_ids`
|
|
6
|
+
- `getClosedChannels`: Add support for `other_ids`
|
|
7
|
+
- `getEphemeralChannelIds`: Add method to get other channel ids
|
|
8
|
+
- `openChannels`: Add support for `is_trusted_funding` for instant opening
|
|
9
|
+
- `subscribeToChannels`: Add support for `is_trusted_funding`, `other_ids`
|
|
10
|
+
- `subscribeToOpenRequests`: Add support for `is_trusted_funding`
|
|
11
|
+
|
|
12
|
+
## 53.17.5
|
|
4
13
|
|
|
5
14
|
- `signTransaction`: Add `root_hash` to support Taproot signatures with scripts
|
|
6
15
|
|
package/README.md
CHANGED
|
@@ -9,6 +9,7 @@ through npm.
|
|
|
9
9
|
|
|
10
10
|
Supported LND versions:
|
|
11
11
|
|
|
12
|
+
- v0.15.0-beta
|
|
12
13
|
- v0.14.0-beta to v0.14.3-beta
|
|
13
14
|
- v0.13.0-beta to v0.13.4-beta
|
|
14
15
|
- v0.12.0-beta to v0.12.1-beta
|
|
@@ -150,6 +151,7 @@ for `unlocker` methods.
|
|
|
150
151
|
- [getChannels](#getchannels) - Get all open channels
|
|
151
152
|
- [getClosedChannels](#getclosedchannels) - Get previously open channels
|
|
152
153
|
- [getConnectedWatchtowers](#getconnectedwatchtowers) - Get connected towers
|
|
154
|
+
- [getEphemeralChannelIds](#getephemeralchannelids) - Get other channel ids
|
|
153
155
|
- [getFailedPayments](#getfailedpayments) - Get payments that were failed back
|
|
154
156
|
- [getFeeRates](#getfeerates) - Get current routing fee rates
|
|
155
157
|
- [getForwardingConfidence](#getforwardingconfidence) - Get pairwise confidence
|
|
@@ -1601,6 +1603,8 @@ Requires `offchain:read` permission
|
|
|
1601
1603
|
`in_channel`, `in_payment`, `is_forward`, `out_channel`, `out_payment`,
|
|
1602
1604
|
`payment` are not supported on LND 0.11.1 and below
|
|
1603
1605
|
|
|
1606
|
+
`is_trusted_funding` is not supported on LND 0.15.0 and below
|
|
1607
|
+
|
|
1604
1608
|
{
|
|
1605
1609
|
[is_active]: <Limit Results To Only Active Channels Bool> // false
|
|
1606
1610
|
[is_offline]: <Limit Results To Only Offline Channels Bool> // false
|
|
@@ -1624,14 +1628,16 @@ Requires `offchain:read` permission
|
|
|
1624
1628
|
is_opening: <Channel Is Opening Bool>
|
|
1625
1629
|
is_partner_initiated: <Channel Partner Opened Channel Bool>
|
|
1626
1630
|
is_private: <Channel Is Private Bool>
|
|
1631
|
+
[is_trusted_funding]: <Funding Output is Trusted Bool>
|
|
1627
1632
|
local_balance: <Local Balance Tokens Number>
|
|
1628
1633
|
[local_csv]: <Local CSV Blocks Delay Number>
|
|
1629
|
-
[local_dust]: <
|
|
1634
|
+
[local_dust]: <Local Non-Enforceable Amount Tokens Number>
|
|
1630
1635
|
[local_given]: <Local Initially Pushed Tokens Number>
|
|
1631
1636
|
[local_max_htlcs]: <Local Maximum Attached HTLCs Number>
|
|
1632
1637
|
[local_max_pending_mtokens]: <Local Maximum Pending Millitokens String>
|
|
1633
1638
|
[local_min_htlc_mtokens]: <Local Minimum HTLC Millitokens String>
|
|
1634
1639
|
local_reserve: <Local Reserved Tokens Number>
|
|
1640
|
+
other_ids: [<Other Channel Id String>]
|
|
1635
1641
|
partner_public_key: <Channel Partner Public Key String>
|
|
1636
1642
|
past_states: <Total Count of Past Channel States Number>
|
|
1637
1643
|
pending_payments: [{
|
|
@@ -1681,6 +1687,8 @@ Multiple close type flags are supported.
|
|
|
1681
1687
|
|
|
1682
1688
|
Requires `offchain:read` permission
|
|
1683
1689
|
|
|
1690
|
+
`other_ids is not supported on LND 0.15.0 and below
|
|
1691
|
+
|
|
1684
1692
|
{
|
|
1685
1693
|
[is_breach_close]: <Only Return Breach Close Channels Bool>
|
|
1686
1694
|
[is_cooperative_close]: <Only Return Cooperative Close Channels Bool>
|
|
@@ -1718,6 +1726,7 @@ Requires `offchain:read` permission
|
|
|
1718
1726
|
[is_partner_closed]: <Channel Was Closed By Channel Peer Bool>
|
|
1719
1727
|
[is_partner_initiated]: <Channel Was Initiated By Channel Peer Bool>
|
|
1720
1728
|
is_remote_force_close: <Is Remote Force Close Bool>
|
|
1729
|
+
other_ids: [<Other Channel Id String>]
|
|
1721
1730
|
partner_public_key: <Partner Public Key Hex String>
|
|
1722
1731
|
transaction_id: <Channel Funding Transaction Id Hex String>
|
|
1723
1732
|
transaction_vout: <Channel Funding Output Index Number>
|
|
@@ -1775,6 +1784,35 @@ const {getConnectedWatchtowers} = require('ln-service');
|
|
|
1775
1784
|
const {towers} = (await getConnectedWatchtowers({lnd}));
|
|
1776
1785
|
```
|
|
1777
1786
|
|
|
1787
|
+
### getEphemeralChannelIds
|
|
1788
|
+
|
|
1789
|
+
Get ephemeral channel ids
|
|
1790
|
+
|
|
1791
|
+
Requires `offchain:read` permission
|
|
1792
|
+
|
|
1793
|
+
This method is not supported on LND 0.15.0 and below
|
|
1794
|
+
|
|
1795
|
+
{
|
|
1796
|
+
lnd: <Authenticated LND API Object>
|
|
1797
|
+
}
|
|
1798
|
+
|
|
1799
|
+
@returns via cbk or Promise
|
|
1800
|
+
{
|
|
1801
|
+
channels: [{
|
|
1802
|
+
other_ids: [<Channel Identifier String>]
|
|
1803
|
+
reference_id: <Top Level Channel Identifier String>
|
|
1804
|
+
}]
|
|
1805
|
+
}
|
|
1806
|
+
|
|
1807
|
+
Example:
|
|
1808
|
+
|
|
1809
|
+
```node
|
|
1810
|
+
const {getEphemeralChannelIds} = require('ln-service');
|
|
1811
|
+
|
|
1812
|
+
// Get the list of ephemeral ids related to channels
|
|
1813
|
+
const {channels} = await getEphemeralChannelIds({lnd});
|
|
1814
|
+
```
|
|
1815
|
+
|
|
1778
1816
|
### getFailedPayments
|
|
1779
1817
|
|
|
1780
1818
|
Get failed payments made through channels.
|
|
@@ -1859,6 +1897,15 @@ Requires `offchain:read` permission
|
|
|
1859
1897
|
[next]: <Next Opaque Paging Token String>
|
|
1860
1898
|
}
|
|
1861
1899
|
|
|
1900
|
+
Example:
|
|
1901
|
+
|
|
1902
|
+
```node
|
|
1903
|
+
const {getFailedPayments} = require('ln-service');
|
|
1904
|
+
|
|
1905
|
+
// Get the list of failed payments
|
|
1906
|
+
const {payments} = await getFailedPayments({lnd});
|
|
1907
|
+
```
|
|
1908
|
+
|
|
1862
1909
|
### getFeeRates
|
|
1863
1910
|
|
|
1864
1911
|
Get a rundown on fees for channels
|
|
@@ -3549,12 +3596,17 @@ channel that was not funded.
|
|
|
3549
3596
|
Use `is_avoiding_broadcast` only when self-publishing the raw transaction
|
|
3550
3597
|
after the funding step.
|
|
3551
3598
|
|
|
3599
|
+
`is_trusted_funding` is not supported on LND 0.15.0 and below and requires
|
|
3600
|
+
`--protocol.option-scid-alias` and `--protocol.zero-conf` set on both sides
|
|
3601
|
+
as well as a channel open request listener to accept the trusted funding.
|
|
3602
|
+
|
|
3552
3603
|
{
|
|
3553
3604
|
channels: [{
|
|
3554
3605
|
capacity: <Channel Capacity Tokens Number>
|
|
3555
3606
|
[cooperative_close_address]: <Restrict Coop Close To Address String>
|
|
3556
3607
|
[give_tokens]: <Tokens to Gift To Partner Number> // Defaults to zero
|
|
3557
3608
|
[is_private]: <Channel is Private Bool> // Defaults to false
|
|
3609
|
+
[is_trusted_funding]: <Peer Should Avoid Waiting For Confirmation Bool>
|
|
3558
3610
|
[min_htlc_mtokens]: <Minimum HTLC Millitokens String>
|
|
3559
3611
|
[partner_csv_delay]: <Peer Output CSV Delay Number>
|
|
3560
3612
|
partner_public_key: <Public Key Hex String>
|
|
@@ -5001,6 +5053,8 @@ Subscribe to channel updates
|
|
|
5001
5053
|
|
|
5002
5054
|
Requires `offchain:read` permission
|
|
5003
5055
|
|
|
5056
|
+
`is_trusted_funding`, `other_ids` are not supported on LND 0.15.0 and below
|
|
5057
|
+
|
|
5004
5058
|
{
|
|
5005
5059
|
lnd: <Authenticated LND API Object>
|
|
5006
5060
|
}
|
|
@@ -5045,6 +5099,7 @@ Requires `offchain:read` permission
|
|
|
5045
5099
|
[is_partner_closed]: <Channel Was Closed By Channel Peer Bool>
|
|
5046
5100
|
[is_partner_initiated]: <Channel Was Initiated By Channel Peer Bool>
|
|
5047
5101
|
is_remote_force_close: <Is Remote Force Close Bool>
|
|
5102
|
+
other_ids: [<Other Channel Id String>]
|
|
5048
5103
|
partner_public_key: <Partner Public Key Hex String>
|
|
5049
5104
|
transaction_id: <Channel Funding Transaction Id Hex String>
|
|
5050
5105
|
transaction_vout: <Channel Funding Output Index Number>
|
|
@@ -5063,6 +5118,7 @@ Requires `offchain:read` permission
|
|
|
5063
5118
|
is_opening: <Channel Is Opening Bool>
|
|
5064
5119
|
is_partner_initiated: <Channel Partner Opened Channel Bool>
|
|
5065
5120
|
is_private: <Channel Is Private Bool>
|
|
5121
|
+
[is_trusted_funding]: <Funding Output is Trusted Bool>
|
|
5066
5122
|
local_balance: <Local Balance Tokens Number>
|
|
5067
5123
|
[local_given]: <Local Initially Pushed Tokens Number>
|
|
5068
5124
|
local_reserve: <Local Reserved Tokens Number>
|
|
@@ -5451,6 +5507,8 @@ listeners to `channel_request`
|
|
|
5451
5507
|
|
|
5452
5508
|
LND 0.11.1 and below do not support `accept` or `reject` arguments
|
|
5453
5509
|
|
|
5510
|
+
LND 0.15.0 and below do not support `is_trusted_funding`
|
|
5511
|
+
|
|
5454
5512
|
{
|
|
5455
5513
|
lnd: <Authenticated LND API Object>
|
|
5456
5514
|
}
|
package/index.js
CHANGED
|
@@ -42,6 +42,7 @@ const {getChannelBalance} = require('lightning');
|
|
|
42
42
|
const {getChannels} = require('lightning');
|
|
43
43
|
const {getClosedChannels} = require('lightning');
|
|
44
44
|
const {getConnectedWatchtowers} = require('lightning');
|
|
45
|
+
const {getEphemeralChannelIds} = require('lightning');
|
|
45
46
|
const {getFailedPayments} = require('lightning');
|
|
46
47
|
const {getFeeRates} = require('lightning');
|
|
47
48
|
const {getForwardingConfidence} = require('lightning');
|
|
@@ -191,6 +192,7 @@ module.exports = {
|
|
|
191
192
|
getChannels,
|
|
192
193
|
getClosedChannels,
|
|
193
194
|
getConnectedWatchtowers,
|
|
195
|
+
getEphemeralChannelIds,
|
|
194
196
|
getFailedPayments,
|
|
195
197
|
getFeeRates,
|
|
196
198
|
getForwardingConfidence,
|
package/package.json
CHANGED
|
@@ -10,28 +10,28 @@
|
|
|
10
10
|
"bolt07": "1.8.2",
|
|
11
11
|
"cors": "2.8.5",
|
|
12
12
|
"express": "4.18.1",
|
|
13
|
-
"invoices": "2.0
|
|
14
|
-
"lightning": "5.
|
|
13
|
+
"invoices": "2.1.0",
|
|
14
|
+
"lightning": "5.17.0",
|
|
15
15
|
"macaroon": "3.0.4",
|
|
16
16
|
"morgan": "1.10.0",
|
|
17
|
-
"ws": "8.8.
|
|
17
|
+
"ws": "8.8.1"
|
|
18
18
|
},
|
|
19
19
|
"description": "Interaction helper for your Lightning Network daemon",
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@alexbosworth/tap": "15.0.11",
|
|
22
22
|
"@alexbosworth/node-fetch": "2.6.2",
|
|
23
23
|
"async": "3.2.4",
|
|
24
|
-
"asyncjs-util": "1.2.
|
|
24
|
+
"asyncjs-util": "1.2.10",
|
|
25
25
|
"bip32": "3.0.1",
|
|
26
26
|
"bip66": "1.1.5",
|
|
27
|
-
"bitcoinjs-lib": "6.0.
|
|
27
|
+
"bitcoinjs-lib": "6.0.2",
|
|
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.
|
|
31
|
+
"ln-docker-daemons": "2.3.3",
|
|
32
32
|
"p2tr": "1.3.1",
|
|
33
|
-
"portfinder": "1.0.
|
|
34
|
-
"psbt": "2.
|
|
33
|
+
"portfinder": "1.0.32",
|
|
34
|
+
"psbt": "2.7.1",
|
|
35
35
|
"rimraf": "3.0.2",
|
|
36
36
|
"secp256k1": "4.0.3",
|
|
37
37
|
"tiny-secp256k1": "2.2.1",
|
|
@@ -57,6 +57,7 @@
|
|
|
57
57
|
},
|
|
58
58
|
"scripts": {
|
|
59
59
|
"integration-test-daily-lnd-build": "DOCKER_LND_VERSION=daily-testing-only npm run test",
|
|
60
|
+
"integration-test-0.15.0": "DOCKER_LND_VERSION=v0.15.0-beta npm run test",
|
|
60
61
|
"integration-test-0.14.3": "DOCKER_LND_VERSION=v0.14.3-beta npm run test",
|
|
61
62
|
"integration-test-0.14.2": "DOCKER_LND_VERSION=v0.14.2-beta npm run test",
|
|
62
63
|
"integration-test-0.14.1": "DOCKER_LND_VERSION=v0.14.1-beta npm run test",
|
|
@@ -70,5 +71,5 @@
|
|
|
70
71
|
"integration-test-0.12.0": "DOCKER_LND_VERSION=v0.12.0-beta npm run test",
|
|
71
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"
|
|
72
73
|
},
|
|
73
|
-
"version": "53.
|
|
74
|
+
"version": "53.18.0"
|
|
74
75
|
}
|
|
@@ -72,11 +72,13 @@ test(`Get closed channels`, async ({end, equal}) => {
|
|
|
72
72
|
|
|
73
73
|
equal(channels.length, [channelOpen].length, 'Channel close listed');
|
|
74
74
|
|
|
75
|
+
const spend = maxChanTokens - channel.final_local_balance;
|
|
76
|
+
|
|
75
77
|
// LND 0.11.1 and below do not use anchors
|
|
76
78
|
if (isAnchors) {
|
|
77
|
-
equal(
|
|
79
|
+
equal([53345, 2810].includes(spend), true, 'Final');
|
|
78
80
|
} else {
|
|
79
|
-
equal(
|
|
81
|
+
equal(spend, 9050, 'Final');
|
|
80
82
|
}
|
|
81
83
|
|
|
82
84
|
equal(channel.capacity, maxChanTokens, 'Channel capacity reflected');
|
|
@@ -17,60 +17,64 @@ test(`Get pending channels`, async ({end, equal}) => {
|
|
|
17
17
|
|
|
18
18
|
const [{generate, lnd}, target] = nodes;
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
try {
|
|
21
|
+
const {features} = await getWalletInfo({lnd});
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
const isAnchors = !!features.find(n => n.bit === anchorsFeatureBit);
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
// Target starts a channel with control
|
|
26
|
+
const coopChan = await setupChannel({generate, give, lnd, to: target});
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
// Target closes the channel
|
|
29
|
+
const niceClose = await closeChannel({
|
|
30
|
+
lnd: target.lnd,
|
|
31
|
+
tokens_per_vbyte: 100,
|
|
32
|
+
transaction_id: coopChan.transaction_id,
|
|
33
|
+
transaction_vout: coopChan.transaction_vout,
|
|
34
|
+
});
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
// Control views their pending channels
|
|
37
|
+
const {channel} = await waitForPendingChannel({
|
|
38
|
+
lnd,
|
|
39
|
+
id: coopChan.transaction_id,
|
|
40
|
+
});
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
if (channel.is_partner_initiated !== undefined) {
|
|
43
|
+
equal(channel.is_partner_initiated, false, 'Channel was initiated');
|
|
44
|
+
}
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
46
|
+
// LND 0.11.1 and below do not support anchor channels
|
|
47
|
+
if (isAnchors) {
|
|
48
|
+
equal(channel.local_balance, 986530, 'Original balance');
|
|
49
|
+
equal(channel.pending_balance, 986530, 'Waiting on balance');
|
|
50
|
+
} else {
|
|
51
|
+
equal(channel.local_balance, 980950, 'Original balance');
|
|
52
|
+
equal(channel.pending_balance, 980950, 'Waiting on balance');
|
|
53
|
+
}
|
|
53
54
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
55
|
+
equal(channel.capacity, 1000000, 'Got channel capacity');
|
|
56
|
+
equal(channel.close_transaction_id, undefined, 'No close tx id');
|
|
57
|
+
equal(channel.is_active, false, 'Ended');
|
|
58
|
+
equal(channel.is_closing, true, 'Closing');
|
|
59
|
+
equal(channel.is_opening, false, 'Not Opening');
|
|
60
|
+
equal(channel.local_reserve, 10000, 'Local reserve');
|
|
61
|
+
equal(channel.partner_public_key, target.id, 'Target public key');
|
|
62
|
+
equal(channel.pending_payments, undefined, 'No pending payments');
|
|
63
|
+
equal(channel.received, 0, 'Never received');
|
|
64
|
+
equal(channel.recovered_tokens, undefined, 'Nothing to recover in sweep');
|
|
65
|
+
equal(channel.remote_reserve, 10000, 'Remote reserve');
|
|
66
|
+
equal(channel.sent, 0, 'Never sent anything');
|
|
67
|
+
equal(channel.timelock_expiration, undefined, 'No timelock in coop mode');
|
|
68
|
+
equal(channel.transaction_fee, null, 'No transaction fee data');
|
|
69
|
+
equal(channel.transaction_id, coopChan.transaction_id, 'funding tx id');
|
|
70
|
+
equal(channel.transaction_vout, coopChan.transaction_vout, 'funding vout');
|
|
71
|
+
equal(channel.transaction_weight, null, 'No funding tx weight data');
|
|
71
72
|
|
|
72
|
-
|
|
73
|
-
|
|
73
|
+
if (!!channel.remote_balance) {
|
|
74
|
+
equal(channel.remote_balance, give, 'Opposing channel balance');
|
|
75
|
+
}
|
|
76
|
+
} catch (err) {
|
|
77
|
+
equal(err, null, 'Expected no error');
|
|
74
78
|
}
|
|
75
79
|
|
|
76
80
|
await kill({});
|
|
@@ -6,7 +6,9 @@ const {addPeer} = require('./../../');
|
|
|
6
6
|
const {getPeers} = require('./../../');
|
|
7
7
|
const {removePeer} = require('./../../');
|
|
8
8
|
|
|
9
|
+
const interval = 10;
|
|
9
10
|
const size = 2;
|
|
11
|
+
const times = 2000;
|
|
10
12
|
|
|
11
13
|
// Removing peers should result in a removed peer
|
|
12
14
|
test(`Remove a peer`, async ({end, equal}) => {
|
|
@@ -15,7 +17,7 @@ test(`Remove a peer`, async ({end, equal}) => {
|
|
|
15
17
|
const [{id, lnd}, target] = nodes;
|
|
16
18
|
|
|
17
19
|
try {
|
|
18
|
-
await asyncRetry({interval
|
|
20
|
+
await asyncRetry({interval, times}, async () => {
|
|
19
21
|
await addPeer({lnd, public_key: target.id, socket: target.socket});
|
|
20
22
|
});
|
|
21
23
|
|
|
@@ -27,9 +29,15 @@ test(`Remove a peer`, async ({end, equal}) => {
|
|
|
27
29
|
|
|
28
30
|
await removePeer({lnd, public_key: targetPeer.public_key});
|
|
29
31
|
|
|
30
|
-
|
|
32
|
+
await asyncRetry({interval, times}, async () => {
|
|
33
|
+
const postRemovalPeers = await getPeers({lnd});
|
|
31
34
|
|
|
32
|
-
|
|
35
|
+
if (!!postRemovalPeers.peers.length) {
|
|
36
|
+
throw new Error('ExpectedPeerRemoved');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
equal(postRemovalPeers.peers.length, [].length, 'Peer is removed');
|
|
40
|
+
});
|
|
33
41
|
} catch (err) {
|
|
34
42
|
equal(err, null, 'Expected no error');
|
|
35
43
|
}
|
|
@@ -148,7 +148,9 @@ test('Subscribe to channels', async ({end, equal, fail}) => {
|
|
|
148
148
|
const closeEvent = channelClosed.pop();
|
|
149
149
|
|
|
150
150
|
if (isAnchors) {
|
|
151
|
-
|
|
151
|
+
const final = closeEvent.final_local_balance;
|
|
152
|
+
|
|
153
|
+
equal([897190, 846655].includes(final), true, 'Close final local balance');
|
|
152
154
|
} else {
|
|
153
155
|
equal(closeEvent.final_local_balance, 890950, 'Close final local balance');
|
|
154
156
|
}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
const asyncRetry = require('async/retry');
|
|
2
|
+
const {spawnLightningCluster} = require('ln-docker-daemons');
|
|
3
|
+
const {test} = require('@alexbosworth/tap');
|
|
4
|
+
|
|
5
|
+
const {addPeer} = require('./../../');
|
|
6
|
+
const {broadcastChainTransaction} = require('./../../');
|
|
7
|
+
const {closeChannel} = require('./../../');
|
|
8
|
+
const {createInvoice} = require('./../../');
|
|
9
|
+
const {fundPendingChannels} = require('./../../');
|
|
10
|
+
const {fundPsbt} = require('./../../');
|
|
11
|
+
const {getChannels} = require('./../../');
|
|
12
|
+
const {getClosedChannels} = require('./../../');
|
|
13
|
+
const {getEphemeralChannelIds} = require('./../../');
|
|
14
|
+
const {getPendingChannels} = require('./../../');
|
|
15
|
+
const {openChannels} = require('./../../');
|
|
16
|
+
const {pay} = require('./../../');
|
|
17
|
+
const {signPsbt} = require('./../../');
|
|
18
|
+
const {subscribeToChannels} = require('./../../');
|
|
19
|
+
const {subscribeToOpenRequests} = require('./../../');
|
|
20
|
+
|
|
21
|
+
const capacity = 1e6;
|
|
22
|
+
const interval = 10;
|
|
23
|
+
const maturity = 100;
|
|
24
|
+
const size = 2;
|
|
25
|
+
const times = 2000;
|
|
26
|
+
|
|
27
|
+
// Opening unconfirmed channels should in immediate channel opening
|
|
28
|
+
test(`Open unconfirmed channels`, async ({end, equal, strictSame}) => {
|
|
29
|
+
// Unconfirmed channels are not supported on LND 0.15.0 and below
|
|
30
|
+
{
|
|
31
|
+
const {kill, nodes} = await spawnLightningCluster({});
|
|
32
|
+
|
|
33
|
+
const [{lnd}] = nodes;
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
await getEphemeralChannelIds({lnd});
|
|
37
|
+
} catch (err) {
|
|
38
|
+
strictSame(err, [501, 'ListAliasesMethodNotSupported']);
|
|
39
|
+
|
|
40
|
+
await kill({});
|
|
41
|
+
|
|
42
|
+
return end();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const {kill, nodes} = await spawnLightningCluster({
|
|
47
|
+
size,
|
|
48
|
+
lnd_configuration: [
|
|
49
|
+
'--maxpendingchannels=10',
|
|
50
|
+
'--protocol.option-scid-alias',
|
|
51
|
+
'--protocol.zero-conf',
|
|
52
|
+
],
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const [{generate, lnd}, target] = nodes;
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
// Make some funds to use
|
|
59
|
+
await generate({count: maturity});
|
|
60
|
+
|
|
61
|
+
// Connect to the peer
|
|
62
|
+
await addPeer({lnd, public_key: target.id, socket: target.socket});
|
|
63
|
+
|
|
64
|
+
// Wait for channel to be receptive to opens
|
|
65
|
+
await asyncRetry({interval, times}, async () => {
|
|
66
|
+
return await openChannels({
|
|
67
|
+
lnd,
|
|
68
|
+
channels: [{capacity, partner_public_key: target.id}],
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const acceptSub = subscribeToOpenRequests({lnd: target.lnd});
|
|
73
|
+
const channelsSub = subscribeToChannels({lnd});
|
|
74
|
+
|
|
75
|
+
const closings = [];
|
|
76
|
+
const opened = [];
|
|
77
|
+
|
|
78
|
+
channelsSub.on('channel_closed', update => closings.push(update));
|
|
79
|
+
channelsSub.on('channel_opened', update => opened.push(update));
|
|
80
|
+
|
|
81
|
+
acceptSub.on('channel_request', request => {
|
|
82
|
+
equal(request.is_trusted_funding, true, 'Request is trusted funding');
|
|
83
|
+
|
|
84
|
+
return request.accept({is_trusted_funding: true});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// Propose the channel to the peer
|
|
88
|
+
const {pending} = await openChannels({
|
|
89
|
+
lnd,
|
|
90
|
+
channels: [{
|
|
91
|
+
capacity,
|
|
92
|
+
is_trusted_funding: true,
|
|
93
|
+
partner_public_key: target.id,
|
|
94
|
+
}],
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// Setup funding to the 2:2 output
|
|
98
|
+
const fundTarget = await fundPsbt({lnd, outputs: pending});
|
|
99
|
+
|
|
100
|
+
// Sign the funding to the 2:2 output
|
|
101
|
+
const {psbt, transaction} = await signPsbt({lnd, psbt: fundTarget.psbt});
|
|
102
|
+
|
|
103
|
+
// Fund the channel
|
|
104
|
+
await fundPendingChannels({
|
|
105
|
+
lnd,
|
|
106
|
+
channels: pending.map(({id}) => id),
|
|
107
|
+
funding: psbt,
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
const invoice = await createInvoice({
|
|
111
|
+
lnd: target.lnd,
|
|
112
|
+
tokens: 100,
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
const channel = await asyncRetry({interval, times}, async () => {
|
|
116
|
+
const {channels} = await getChannels({lnd, is_active: true});
|
|
117
|
+
|
|
118
|
+
if (!channels.length) {
|
|
119
|
+
throw new Error('ExpectedTrustedChannelToAppear');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const [channel] = channels;
|
|
123
|
+
|
|
124
|
+
return channel;
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// Make sure the channel reflects that it is trusted funding
|
|
128
|
+
strictSame(channel.other_ids, [], 'Got no ephemeral ids');
|
|
129
|
+
equal(channel.id, '16000000x0x0', 'Channel id is faked');
|
|
130
|
+
equal(channel.is_trusted_funding, true, 'Channel funding is trusted');
|
|
131
|
+
|
|
132
|
+
// Make sure the open channel event reflected that it was trusted funding
|
|
133
|
+
const [event] = opened;
|
|
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');
|
|
138
|
+
|
|
139
|
+
// Make sure the channel can be used immediately
|
|
140
|
+
await pay({lnd, request: invoice.request});
|
|
141
|
+
|
|
142
|
+
// Generate the channel into a block
|
|
143
|
+
await broadcastChainTransaction({lnd, transaction});
|
|
144
|
+
|
|
145
|
+
const confirmed = await asyncRetry({interval, times}, async () => {
|
|
146
|
+
await generate({});
|
|
147
|
+
|
|
148
|
+
const [confirmed] = (await getChannels({lnd})).channels;
|
|
149
|
+
|
|
150
|
+
if (confirmed.id === channel.id) {
|
|
151
|
+
throw new Error('ExpectedChangeToRealChannelId');
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return confirmed;
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
equal(confirmed.id, '102x1x0', 'Channel id is real now');
|
|
158
|
+
equal(confirmed.is_trusted_funding, true, 'Channel funding was trusted');
|
|
159
|
+
strictSame(confirmed.other_ids, ['16000000x0x0'], 'Got ephemeral ids');
|
|
160
|
+
|
|
161
|
+
await closeChannel({lnd, id: confirmed.id});
|
|
162
|
+
|
|
163
|
+
// Propose a private channel to the peer
|
|
164
|
+
const openPrivate = await asyncRetry({interval, times}, async () => {
|
|
165
|
+
return await openChannels({
|
|
166
|
+
lnd,
|
|
167
|
+
channels: [{
|
|
168
|
+
capacity,
|
|
169
|
+
is_private: true,
|
|
170
|
+
is_trusted_funding: true,
|
|
171
|
+
partner_public_key: target.id,
|
|
172
|
+
}],
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// Setup funding to the 2:2 output for the private channel
|
|
177
|
+
const fundPrivate = await fundPsbt({lnd, outputs: openPrivate.pending});
|
|
178
|
+
|
|
179
|
+
// Sign the private funding
|
|
180
|
+
const signedPrivate = await signPsbt({lnd, psbt: fundPrivate.psbt});
|
|
181
|
+
|
|
182
|
+
// Fund the private channel
|
|
183
|
+
await fundPendingChannels({
|
|
184
|
+
lnd,
|
|
185
|
+
channels: openPrivate.pending.map(({id}) => id),
|
|
186
|
+
funding: signedPrivate.psbt,
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
// Generate the channel into a block
|
|
190
|
+
await broadcastChainTransaction({
|
|
191
|
+
lnd,
|
|
192
|
+
transaction: signedPrivate.transaction,
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
const privateConfirmed = await asyncRetry({interval, times}, async () => {
|
|
196
|
+
await generate({});
|
|
197
|
+
|
|
198
|
+
const [confirmed] = (await getChannels({lnd})).channels;
|
|
199
|
+
|
|
200
|
+
const shut = await getClosedChannels({lnd});
|
|
201
|
+
|
|
202
|
+
if (!shut.channels.length) {
|
|
203
|
+
throw new Error('ExpectedClosedChannel');
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (!confirmed.other_ids.length) {
|
|
207
|
+
throw new Error('ExpectedChangeToRealPrivateChannelId');
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return confirmed;
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
strictSame(privateConfirmed.other_ids, ['16000000x0x1'], 'Got private id');
|
|
214
|
+
|
|
215
|
+
const [closedChannel] = (await getClosedChannels({lnd})).channels;
|
|
216
|
+
|
|
217
|
+
equal(closedChannel.id, confirmed.id, 'Closed channel shows confirmed id');
|
|
218
|
+
strictSame(closedChannel.other_ids, confirmed.other_ids, 'Saved temp id');
|
|
219
|
+
|
|
220
|
+
const [closeEvent] = closings;
|
|
221
|
+
|
|
222
|
+
equal(closeEvent.id, confirmed.id, 'Closed event shows confirmed id');
|
|
223
|
+
strictSame(closeEvent.other_ids, confirmed.other_ids, 'Got temporary id');
|
|
224
|
+
|
|
225
|
+
const ephemeralIds = await getEphemeralChannelIds({lnd});
|
|
226
|
+
|
|
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
|
+
);
|
|
237
|
+
} catch (err) {
|
|
238
|
+
equal(err, null, 'No error is reported');
|
|
239
|
+
} finally {
|
|
240
|
+
return await kill({});
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return end();
|
|
244
|
+
});
|
|
@@ -26,9 +26,9 @@ const channelCapacityTokens = 1e6;
|
|
|
26
26
|
const confirmationCount = 6;
|
|
27
27
|
const defaultFee = 1e3;
|
|
28
28
|
const give = 1e5;
|
|
29
|
-
const interval =
|
|
29
|
+
const interval = 50;
|
|
30
30
|
const size = 2;
|
|
31
|
-
const times =
|
|
31
|
+
const times = 10000;
|
|
32
32
|
const tokens = 100;
|
|
33
33
|
|
|
34
34
|
// Force close a channel and get the resulting sweep transaction
|
|
@@ -76,8 +76,15 @@ test(`Get sweep transactions`, async ({end, equal}) => {
|
|
|
76
76
|
.map(n => n.tokens).sort();
|
|
77
77
|
|
|
78
78
|
equal(transactions.length, 2, 'Got closed channel sweep');
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
|
|
80
|
+
// LND 0.15.0 and before have different sweep tokens
|
|
81
|
+
if (sweepTokens === 890455) {
|
|
82
|
+
equal(anchorTokens, 149, 'Sweep has tokens amount');
|
|
83
|
+
equal(sweepTokens, 890455, 'Sweep has tokens amount');
|
|
84
|
+
} else {
|
|
85
|
+
equal(anchorTokens, 136, 'Sweep has tokens amount');
|
|
86
|
+
equal(sweepTokens, 889855, 'Sweep has tokens amount');
|
|
87
|
+
}
|
|
81
88
|
} else {
|
|
82
89
|
equal(transactions.length, [channel].length, 'Got closed channel sweep');
|
|
83
90
|
equal(transaction.spends.length, 1, 'Sweep has spends');
|