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 CHANGED
@@ -1,6 +1,15 @@
1
1
  # Versions
2
2
 
3
- ## 53.17.3
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]: <Remote Non-Enforceable Amount Tokens Number>
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.7",
14
- "lightning": "5.16.3",
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.0"
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.9",
24
+ "asyncjs-util": "1.2.10",
25
25
  "bip32": "3.0.1",
26
26
  "bip66": "1.1.5",
27
- "bitcoinjs-lib": "6.0.1",
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.0",
31
+ "ln-docker-daemons": "2.3.3",
32
32
  "p2tr": "1.3.1",
33
- "portfinder": "1.0.28",
34
- "psbt": "2.6.0",
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.17.3"
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(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');