ln-service 53.17.5 → 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 CHANGED
@@ -1,5 +1,14 @@
1
1
  # Versions
2
2
 
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
+
3
12
  ## 53.17.5
4
13
 
5
14
  - `signTransaction`: Add `root_hash` to support Taproot signatures with scripts
package/README.md CHANGED
@@ -151,6 +151,7 @@ for `unlocker` methods.
151
151
  - [getChannels](#getchannels) - Get all open channels
152
152
  - [getClosedChannels](#getclosedchannels) - Get previously open channels
153
153
  - [getConnectedWatchtowers](#getconnectedwatchtowers) - Get connected towers
154
+ - [getEphemeralChannelIds](#getephemeralchannelids) - Get other channel ids
154
155
  - [getFailedPayments](#getfailedpayments) - Get payments that were failed back
155
156
  - [getFeeRates](#getfeerates) - Get current routing fee rates
156
157
  - [getForwardingConfidence](#getforwardingconfidence) - Get pairwise confidence
@@ -1602,6 +1603,8 @@ Requires `offchain:read` permission
1602
1603
  `in_channel`, `in_payment`, `is_forward`, `out_channel`, `out_payment`,
1603
1604
  `payment` are not supported on LND 0.11.1 and below
1604
1605
 
1606
+ `is_trusted_funding` is not supported on LND 0.15.0 and below
1607
+
1605
1608
  {
1606
1609
  [is_active]: <Limit Results To Only Active Channels Bool> // false
1607
1610
  [is_offline]: <Limit Results To Only Offline Channels Bool> // false
@@ -1625,6 +1628,7 @@ Requires `offchain:read` permission
1625
1628
  is_opening: <Channel Is Opening Bool>
1626
1629
  is_partner_initiated: <Channel Partner Opened Channel Bool>
1627
1630
  is_private: <Channel Is Private Bool>
1631
+ [is_trusted_funding]: <Funding Output is Trusted Bool>
1628
1632
  local_balance: <Local Balance Tokens Number>
1629
1633
  [local_csv]: <Local CSV Blocks Delay Number>
1630
1634
  [local_dust]: <Local Non-Enforceable Amount Tokens Number>
@@ -1633,6 +1637,7 @@ Requires `offchain:read` permission
1633
1637
  [local_max_pending_mtokens]: <Local Maximum Pending Millitokens String>
1634
1638
  [local_min_htlc_mtokens]: <Local Minimum HTLC Millitokens String>
1635
1639
  local_reserve: <Local Reserved Tokens Number>
1640
+ other_ids: [<Other Channel Id String>]
1636
1641
  partner_public_key: <Channel Partner Public Key String>
1637
1642
  past_states: <Total Count of Past Channel States Number>
1638
1643
  pending_payments: [{
@@ -1682,6 +1687,8 @@ Multiple close type flags are supported.
1682
1687
 
1683
1688
  Requires `offchain:read` permission
1684
1689
 
1690
+ `other_ids is not supported on LND 0.15.0 and below
1691
+
1685
1692
  {
1686
1693
  [is_breach_close]: <Only Return Breach Close Channels Bool>
1687
1694
  [is_cooperative_close]: <Only Return Cooperative Close Channels Bool>
@@ -1719,6 +1726,7 @@ Requires `offchain:read` permission
1719
1726
  [is_partner_closed]: <Channel Was Closed By Channel Peer Bool>
1720
1727
  [is_partner_initiated]: <Channel Was Initiated By Channel Peer Bool>
1721
1728
  is_remote_force_close: <Is Remote Force Close Bool>
1729
+ other_ids: [<Other Channel Id String>]
1722
1730
  partner_public_key: <Partner Public Key Hex String>
1723
1731
  transaction_id: <Channel Funding Transaction Id Hex String>
1724
1732
  transaction_vout: <Channel Funding Output Index Number>
@@ -1776,6 +1784,35 @@ const {getConnectedWatchtowers} = require('ln-service');
1776
1784
  const {towers} = (await getConnectedWatchtowers({lnd}));
1777
1785
  ```
1778
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
+
1779
1816
  ### getFailedPayments
1780
1817
 
1781
1818
  Get failed payments made through channels.
@@ -1860,6 +1897,15 @@ Requires `offchain:read` permission
1860
1897
  [next]: <Next Opaque Paging Token String>
1861
1898
  }
1862
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
+
1863
1909
  ### getFeeRates
1864
1910
 
1865
1911
  Get a rundown on fees for channels
@@ -3550,12 +3596,17 @@ channel that was not funded.
3550
3596
  Use `is_avoiding_broadcast` only when self-publishing the raw transaction
3551
3597
  after the funding step.
3552
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
+
3553
3603
  {
3554
3604
  channels: [{
3555
3605
  capacity: <Channel Capacity Tokens Number>
3556
3606
  [cooperative_close_address]: <Restrict Coop Close To Address String>
3557
3607
  [give_tokens]: <Tokens to Gift To Partner Number> // Defaults to zero
3558
3608
  [is_private]: <Channel is Private Bool> // Defaults to false
3609
+ [is_trusted_funding]: <Peer Should Avoid Waiting For Confirmation Bool>
3559
3610
  [min_htlc_mtokens]: <Minimum HTLC Millitokens String>
3560
3611
  [partner_csv_delay]: <Peer Output CSV Delay Number>
3561
3612
  partner_public_key: <Public Key Hex String>
@@ -5002,6 +5053,8 @@ Subscribe to channel updates
5002
5053
 
5003
5054
  Requires `offchain:read` permission
5004
5055
 
5056
+ `is_trusted_funding`, `other_ids` are not supported on LND 0.15.0 and below
5057
+
5005
5058
  {
5006
5059
  lnd: <Authenticated LND API Object>
5007
5060
  }
@@ -5046,6 +5099,7 @@ Requires `offchain:read` permission
5046
5099
  [is_partner_closed]: <Channel Was Closed By Channel Peer Bool>
5047
5100
  [is_partner_initiated]: <Channel Was Initiated By Channel Peer Bool>
5048
5101
  is_remote_force_close: <Is Remote Force Close Bool>
5102
+ other_ids: [<Other Channel Id String>]
5049
5103
  partner_public_key: <Partner Public Key Hex String>
5050
5104
  transaction_id: <Channel Funding Transaction Id Hex String>
5051
5105
  transaction_vout: <Channel Funding Output Index Number>
@@ -5064,6 +5118,7 @@ Requires `offchain:read` permission
5064
5118
  is_opening: <Channel Is Opening Bool>
5065
5119
  is_partner_initiated: <Channel Partner Opened Channel Bool>
5066
5120
  is_private: <Channel Is Private Bool>
5121
+ [is_trusted_funding]: <Funding Output is Trusted Bool>
5067
5122
  local_balance: <Local Balance Tokens Number>
5068
5123
  [local_given]: <Local Initially Pushed Tokens Number>
5069
5124
  local_reserve: <Local Reserved Tokens Number>
@@ -5452,6 +5507,8 @@ listeners to `channel_request`
5452
5507
 
5453
5508
  LND 0.11.1 and below do not support `accept` or `reject` arguments
5454
5509
 
5510
+ LND 0.15.0 and below do not support `is_trusted_funding`
5511
+
5455
5512
  {
5456
5513
  lnd: <Authenticated LND API Object>
5457
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
@@ -11,7 +11,7 @@
11
11
  "cors": "2.8.5",
12
12
  "express": "4.18.1",
13
13
  "invoices": "2.1.0",
14
- "lightning": "5.16.6",
14
+ "lightning": "5.17.0",
15
15
  "macaroon": "3.0.4",
16
16
  "morgan": "1.10.0",
17
17
  "ws": "8.8.1"
@@ -28,9 +28,9 @@
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.2",
31
+ "ln-docker-daemons": "2.3.3",
32
32
  "p2tr": "1.3.1",
33
- "portfinder": "1.0.28",
33
+ "portfinder": "1.0.32",
34
34
  "psbt": "2.7.1",
35
35
  "rimraf": "3.0.2",
36
36
  "secp256k1": "4.0.3",
@@ -71,5 +71,5 @@
71
71
  "integration-test-0.12.0": "DOCKER_LND_VERSION=v0.12.0-beta npm run test",
72
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"
73
73
  },
74
- "version": "53.17.5"
74
+ "version": "53.18.0"
75
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(maxChanTokens - channel.final_local_balance, 2810, 'Final');
79
+ equal([53345, 2810].includes(spend), true, 'Final');
78
80
  } else {
79
- equal(maxChanTokens - channel.final_local_balance, 9050, 'Final');
81
+ equal(spend, 9050, 'Final');
80
82
  }
81
83
 
82
84
  equal(channel.capacity, maxChanTokens, 'Channel capacity reflected');
@@ -56,8 +56,6 @@ test(`Get node`, async ({end, equal, strictSame}) => {
56
56
  });
57
57
  });
58
58
 
59
- await delay(3000);
60
-
61
59
  const node = await getNode({lnd, public_key: id});
62
60
 
63
61
  {
@@ -17,60 +17,64 @@ test(`Get pending channels`, async ({end, equal}) => {
17
17
 
18
18
  const [{generate, lnd}, target] = nodes;
19
19
 
20
- const {features} = await getWalletInfo({lnd});
20
+ try {
21
+ const {features} = await getWalletInfo({lnd});
21
22
 
22
- const isAnchors = !!features.find(n => n.bit === anchorsFeatureBit);
23
+ const isAnchors = !!features.find(n => n.bit === anchorsFeatureBit);
23
24
 
24
- // Target starts a channel with control
25
- const coopChan = await setupChannel({generate, give, lnd, to: target});
25
+ // Target starts a channel with control
26
+ const coopChan = await setupChannel({generate, give, lnd, to: target});
26
27
 
27
- // Target closes the channel
28
- const niceClose = await closeChannel({
29
- lnd: target.lnd,
30
- tokens_per_vbyte: defaultFee,
31
- transaction_id: coopChan.transaction_id,
32
- transaction_vout: coopChan.transaction_vout,
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
- // Control views their pending channels
36
- const {channel} = await waitForPendingChannel({
37
- lnd,
38
- id: coopChan.transaction_id,
39
- });
36
+ // Control views their pending channels
37
+ const {channel} = await waitForPendingChannel({
38
+ lnd,
39
+ id: coopChan.transaction_id,
40
+ });
40
41
 
41
- if (channel.is_partner_initiated !== undefined) {
42
- equal(channel.is_partner_initiated, false, 'Channel was initiated');
43
- }
42
+ if (channel.is_partner_initiated !== undefined) {
43
+ equal(channel.is_partner_initiated, false, 'Channel was initiated');
44
+ }
44
45
 
45
- // LND 0.11.1 and below do not support anchor channels
46
- if (isAnchors) {
47
- equal(channel.local_balance, 986530, 'Original balance');
48
- equal(channel.pending_balance, 986530, 'Waiting on balance');
49
- } else {
50
- equal(channel.local_balance, 980950, 'Original balance');
51
- equal(channel.pending_balance, 980950, 'Waiting on balance');
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
- equal(channel.capacity, 1000000, 'Got channel capacity');
55
- equal(channel.close_transaction_id, undefined, 'No close tx id');
56
- equal(channel.is_active, false, 'Ended');
57
- equal(channel.is_closing, true, 'Closing');
58
- equal(channel.is_opening, false, 'Not Opening');
59
- equal(channel.local_reserve, 10000, 'Local reserve');
60
- equal(channel.partner_public_key, target.id, 'Target public key');
61
- equal(channel.pending_payments, undefined, 'No pending payments');
62
- equal(channel.received, 0, 'Never received');
63
- equal(channel.recovered_tokens, undefined, 'Nothing to recover in sweep');
64
- equal(channel.remote_reserve, 10000, 'Remote reserve');
65
- equal(channel.sent, 0, 'Never sent anything');
66
- equal(channel.timelock_expiration, undefined, 'No timelock in coop mode');
67
- equal(channel.transaction_fee, null, 'No transaction fee data');
68
- equal(channel.transaction_id, coopChan.transaction_id, 'funding tx id');
69
- equal(channel.transaction_vout, coopChan.transaction_vout, 'funding vout');
70
- equal(channel.transaction_weight, null, 'No funding tx weight data');
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
- if (!!channel.remote_balance) {
73
- equal(channel.remote_balance, give, 'Opposing channel balance');
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({});
@@ -334,7 +334,7 @@ test(`Propose a channel with a coop delay`, async ({end, equal, ok}) => {
334
334
  });
335
335
 
336
336
  const coopCloseAddress = await createChainAddress({
337
- format: 'np2wpkh',
337
+ format: 'p2wpkh',
338
338
  lnd: control.lnd,
339
339
  });
340
340
 
@@ -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: 10, times: 2000}, async () => {
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
- const postRemovalPeers = await getPeers({lnd});
32
+ await asyncRetry({interval, times}, async () => {
33
+ const postRemovalPeers = await getPeers({lnd});
31
34
 
32
- equal(postRemovalPeers.peers.length, [].length, 'Peer is removed');
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
- equal(closeEvent.final_local_balance, 897190, 'Close final local balance');
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 = 200;
29
+ const interval = 50;
30
30
  const size = 2;
31
- const times = 1000;
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
- equal(anchorTokens, 149, 'Sweep has tokens amount');
80
- equal(sweepTokens, 890455, 'Sweep has tokens amount');
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');