ln-service 52.14.4 → 53.0.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.
Files changed (121) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +163 -11
  3. package/package.json +7 -14
  4. package/test/autopilotrpc-integration/test_autopilot.js +9 -15
  5. package/test/chainrpc-integration/test_get_height.js +7 -10
  6. package/test/chainrpc-integration/test_subscribe_to_blocks.js +52 -31
  7. package/test/chainrpc-integration/test_subscribe_to_chain_address.js +72 -66
  8. package/test/chainrpc-integration/test_subscribe_to_chain_spend.js +47 -16
  9. package/test/{integration → extra-integration}/test_recover_funds_from_channel.js +0 -0
  10. package/test/{integration → extra-integration}/test_recover_funds_from_channels.js +0 -0
  11. package/test/{integration → extra-integration}/test_restrict_macaroon.js +0 -0
  12. package/test/{integration → extra-integration}/test_revoke_access.js +0 -0
  13. package/test/{integration → extra-integration}/test_subscribe_to_rpc_requests.js +1 -1
  14. package/test/integration/test_add_peer.js +16 -12
  15. package/test/integration/test_cancel_pending_channel.js +20 -6
  16. package/test/integration/test_close_channel.js +15 -10
  17. package/test/integration/test_create_chain_address.js +3 -6
  18. package/test/integration/test_create_invoice.js +27 -23
  19. package/test/integration/test_decode_payment_request.js +30 -29
  20. package/test/integration/test_delete_payment.js +11 -8
  21. package/test/integration/test_delete_payments.js +13 -16
  22. package/test/integration/test_get_access_ids.js +4 -7
  23. package/test/integration/test_get_backup.js +12 -8
  24. package/test/integration/test_get_backups.js +8 -10
  25. package/test/integration/test_get_chain_balance.js +9 -53
  26. package/test/integration/test_get_chain_fee_estimate.js +21 -10
  27. package/test/integration/test_get_chain_transactions.js +30 -52
  28. package/test/integration/test_get_channel.js +7 -7
  29. package/test/integration/test_get_channel_balance.js +5 -6
  30. package/test/integration/test_get_channels.js +11 -10
  31. package/test/integration/test_get_closed_channels.js +169 -139
  32. package/test/integration/test_get_failed_payments.js +37 -39
  33. package/test/integration/test_get_fee_rates.js +6 -9
  34. package/test/integration/test_get_forwards.js +34 -35
  35. package/test/integration/test_get_invoice.js +7 -11
  36. package/test/integration/test_get_invoices.js +33 -30
  37. package/test/integration/test_get_methods.js +4 -7
  38. package/test/integration/test_get_network_centrality.js +14 -17
  39. package/test/integration/test_get_network_graph.js +12 -15
  40. package/test/integration/test_get_network_info.js +5 -6
  41. package/test/integration/test_get_node.js +15 -31
  42. package/test/integration/test_get_payments.js +10 -10
  43. package/test/integration/test_get_peers.js +10 -13
  44. package/test/integration/test_get_pending_coop.js +13 -18
  45. package/test/integration/test_get_pending_force.js +29 -21
  46. package/test/integration/test_get_route_to_destination.js +47 -40
  47. package/test/integration/test_get_utxos.js +17 -42
  48. package/test/integration/test_get_wallet_info.js +5 -12
  49. package/test/integration/test_open_channel.js +16 -9
  50. package/test/integration/test_open_channels.js +66 -66
  51. package/test/integration/test_pay.js +39 -36
  52. package/test/integration/test_pay_private_invoice.js +78 -72
  53. package/test/integration/test_payment_errors.js +13 -11
  54. package/test/integration/test_propose_channel.js +74 -53
  55. package/test/integration/test_push_funds.js +11 -15
  56. package/test/integration/test_rebalance.js +11 -22
  57. package/test/integration/test_remove_peer.js +13 -48
  58. package/test/integration/test_send_message_to_peer.js +25 -17
  59. package/test/integration/test_send_to_chain_address.js +60 -51
  60. package/test/integration/test_send_to_chain_addresses.js +30 -18
  61. package/test/integration/test_sign_message.js +3 -6
  62. package/test/integration/test_stop_daemon.js +3 -9
  63. package/test/integration/test_subscribe_to_backups.js +19 -11
  64. package/test/integration/test_subscribe_to_channels.js +28 -20
  65. package/test/integration/test_subscribe_to_graph.js +43 -22
  66. package/test/integration/test_subscribe_to_invoices.js +89 -103
  67. package/test/integration/test_subscribe_to_open_requests.js +47 -31
  68. package/test/integration/test_subscribe_to_peer_messages.js +51 -21
  69. package/test/integration/test_subscribe_to_peers.js +11 -16
  70. package/test/integration/test_subscribe_to_transactions.js +49 -45
  71. package/test/integration/test_update_routing_fees.js +12 -16
  72. package/test/integration/test_verify_access.js +5 -10
  73. package/test/integration/test_verify_backup.js +10 -8
  74. package/test/integration/test_verify_backups.js +11 -16
  75. package/test/integration/test_verify_message.js +6 -9
  76. package/test/invoicesrpc-integration/test_cancel_invoice.js +15 -22
  77. package/test/invoicesrpc-integration/test_get_sweep_transactions.js +15 -11
  78. package/test/invoicesrpc-integration/test_push_payment.js +53 -55
  79. package/test/invoicesrpc-integration/test_settle_invoice.js +25 -19
  80. package/test/invoicesrpc-integration/test_subscribe_cancel_invoice.js +13 -11
  81. package/test/invoicesrpc-integration/test_subscribe_settle_invoice.js +20 -15
  82. package/test/macros/btcsuite_type_daemon.js +1 -1
  83. package/test/macros/chain_send_transaction.js +1 -1
  84. package/test/macros/change_password.js +15 -13
  85. package/test/macros/generate_blocks.js +24 -29
  86. package/test/macros/rpc.js +1 -0
  87. package/test/macros/setup_channel.js +23 -9
  88. package/test/macros/spawn_lnd.js +3 -1
  89. package/test/macros/wait_for_channel.js +8 -3
  90. package/test/macros/wait_for_route.js +2 -2
  91. package/test/routerrpc-integration/test_delete_forwarding_reputations.js +15 -22
  92. package/test/routerrpc-integration/test_disable_channel.js +8 -12
  93. package/test/routerrpc-integration/test_get_forwarding_confidence.js +17 -37
  94. package/test/routerrpc-integration/test_get_forwarding_reputations.js +26 -25
  95. package/test/routerrpc-integration/test_get_pathfinding_settings.js +6 -12
  96. package/test/routerrpc-integration/test_get_payment.js +19 -26
  97. package/test/routerrpc-integration/test_get_route_confidence.js +15 -21
  98. package/test/routerrpc-integration/test_get_route_through_hops.js +29 -32
  99. package/test/routerrpc-integration/test_multipath_payment.js +18 -20
  100. package/test/routerrpc-integration/test_pay_via_payment_details.js +19 -34
  101. package/test/routerrpc-integration/test_pay_via_payment_request.js +17 -27
  102. package/test/routerrpc-integration/test_pay_via_routes.js +37 -37
  103. package/test/routerrpc-integration/test_probe_for_route.js +27 -33
  104. package/test/routerrpc-integration/test_subscribe_to_forward_requests.js +138 -32
  105. package/test/routerrpc-integration/test_subscribe_to_forwards.js +83 -77
  106. package/test/routerrpc-integration/test_subscribe_to_past_payments.js +34 -28
  107. package/test/routerrpc-integration/test_update_pathfinding_settings.js +7 -10
  108. package/test/signerrpc-integration/test_diffie_hellman_compute_secret.js +15 -14
  109. package/test/signerrpc-integration/test_sign_bytes.js +11 -15
  110. package/test/signerrpc-integration/test_sign_transaction.js +6 -7
  111. package/test/signerrpc-integration/test_verify_bytes_signature.js +11 -12
  112. package/test/versionrpc-integration/test_get_wallet_version.js +6 -7
  113. package/test/walletrpc-integration/test_fund_psbt.js +13 -12
  114. package/test/walletrpc-integration/test_get_chain_fee_rate.js +4 -8
  115. package/test/walletrpc-integration/test_get_locked_utxos.js +11 -27
  116. package/test/walletrpc-integration/test_get_public_key.js +5 -13
  117. package/test/walletrpc-integration/test_lock_utxo.js +16 -23
  118. package/test/walletrpc-integration/test_send_to_chain_output_scripts.js +25 -6
  119. package/test/walletrpc-integration/test_sign_psbt.js +28 -19
  120. package/test/walletrpc-integration/test_unlock_utxo.js +16 -27
  121. package/test/walletrpc-integration/test_update_chain_transaction.js +6 -31
@@ -1,43 +1,50 @@
1
1
  const asyncRetry = require('async/retry');
2
+ const {spawnLightningCluster} = require('ln-docker-daemons');
2
3
  const {test} = require('@alexbosworth/tap');
3
4
 
5
+ const {addPeer} = require('./../../');
4
6
  const {createChainAddress} = require('./../../');
5
- const {createCluster} = require('./../macros');
7
+ const {getChainBalance} = require('./../../');
6
8
  const {openChannel} = require('./../../');
7
9
 
8
10
  const channelCapacityTokens = 1e6;
11
+ const count = 100;
9
12
  const defaultFee = 1e3;
10
13
  const defaultVout = 0;
11
- const format = 'p2wpkh';
12
14
  const giftTokens = 1000;
13
15
  const interval = 250;
14
- const times = 100;
16
+ const size = 2;
17
+ const times = 1000;
15
18
  const txIdHexLength = 32 * 2;
16
19
 
17
20
  // Opening a channel should open a channel
18
21
  test(`Open channel`, async ({end, equal}) => {
19
- const cluster = await createCluster({is_remote_skipped: true});
22
+ const {kill, nodes} = await spawnLightningCluster({size});
20
23
 
21
- const {lnd} = cluster.control;
24
+ const [{generate, lnd}, target] = nodes;
22
25
 
23
- const {address} = await createChainAddress({format, lnd});
26
+ const {address} = await createChainAddress({lnd});
27
+
28
+ await generate({count});
24
29
 
25
30
  const channelOpen = await asyncRetry({interval, times}, async () => {
31
+ await addPeer({lnd, public_key: target.id, socket: target.socket});
32
+
26
33
  return await openChannel({
27
34
  lnd,
28
35
  chain_fee_tokens_per_vbyte: defaultFee,
29
36
  cooperative_close_address: address,
30
37
  give_tokens: giftTokens,
31
38
  local_tokens: channelCapacityTokens,
32
- partner_public_key: cluster.target.public_key,
33
- socket: cluster.target.socket,
39
+ partner_public_key: target.id,
40
+ socket: target.socket,
34
41
  });
35
42
  });
36
43
 
37
44
  equal(channelOpen.transaction_id.length, txIdHexLength, 'Channel tx id');
38
45
  equal(channelOpen.transaction_vout, defaultVout, 'Channel tx output index');
39
46
 
40
- await cluster.kill({});
47
+ await kill({});
41
48
 
42
49
  return end();
43
50
  });
@@ -1,13 +1,14 @@
1
1
  const asyncRetry = require('async/retry');
2
2
  const {extractTransaction} = require('psbt');
3
3
  const {finalizePsbt} = require('psbt');
4
+ const {spawnLightningCluster} = require('ln-docker-daemons');
4
5
  const {test} = require('@alexbosworth/tap');
5
6
  const {transactionAsPsbt} = require('psbt');
6
7
 
7
8
  const {addPeer} = require('./../../');
8
- const {createCluster} = require('./../macros');
9
9
  const {delay} = require('./../macros');
10
10
  const {fundPendingChannels} = require('./../../');
11
+ const {getChainBalance} = require('./../../');
11
12
  const {getChainTransactions} = require('./../../');
12
13
  const {getChannels} = require('./../../');
13
14
  const {getPeers} = require('./../../');
@@ -16,99 +17,98 @@ const {sendToChainAddresses} = require('./../../');
16
17
 
17
18
  const capacity = 1e6;
18
19
  const count = 10;
19
- const interval = 200;
20
+ const interval = 1;
20
21
  const race = promises => Promise.race(promises);
22
+ const size = 3;
21
23
  const timeout = 250 * 10;
22
- const times = 100;
24
+ const times = 200;
23
25
 
24
26
  // Opening channels should open up channels
25
27
  test(`Open channels`, async ({end, equal}) => {
26
- await asyncRetry({interval, times}, async () => {
27
- const cluster = await createCluster({});
28
+ const {kill, nodes} = await spawnLightningCluster({size});
28
29
 
29
- try {
30
- const {lnd} = cluster.control;
30
+ const [{generate, lnd}, target, remote] = nodes;
31
31
 
32
- const chainTx = (await getChainTransactions({lnd})).transactions;
32
+ await asyncRetry({times}, async () => {
33
+ if (!(await getChainBalance({lnd})).chain_balance) {
34
+ await generate({});
33
35
 
34
- const spending = chainTx.map(({transaction}) => transaction);
36
+ throw new Error('ExpectedChainBalanceToOpenChannel');
37
+ }
38
+ });
35
39
 
36
- await addPeer({
37
- lnd,
38
- public_key: cluster.remote.public_key,
39
- socket: cluster.remote.socket,
40
- });
40
+ try {
41
+ const chainTx = (await getChainTransactions({lnd})).transactions;
41
42
 
42
- const channels = [cluster.target, cluster.remote].map(node => ({
43
- capacity,
44
- partner_public_key: node.public_key,
45
- }));
43
+ const spending = chainTx.map(({transaction}) => transaction);
46
44
 
47
- let pending;
45
+ await addPeer({lnd, public_key: remote.id, socket: remote.socket});
48
46
 
49
- // Wait for peers to be connected
50
- await asyncRetry({interval, times}, async () => {
51
- await addPeer({
52
- lnd,
53
- public_key: cluster.remote.public_key,
54
- socket: cluster.remote.socket,
55
- });
47
+ const channels = [target, remote].map(node => ({
48
+ capacity,
49
+ partner_public_key: node.id,
50
+ }));
56
51
 
57
- if ((await getPeers({lnd})).peers.length !== channels.length) {
58
- throw new Error('ExpectedConnectedPeersToOpenChannels');
59
- }
52
+ let pending;
60
53
 
61
- return;
62
- });
54
+ // Wait for peers to be connected
55
+ await asyncRetry({interval, times}, async () => {
56
+ await addPeer({lnd, public_key: remote.id, socket: remote.socket});
63
57
 
64
- await asyncRetry({interval, times}, async () => {
65
- pending = (await openChannels({channels, lnd})).pending;
66
- });
58
+ if ((await getPeers({lnd})).peers.length !== channels.length) {
59
+ throw new Error('ExpectedConnectedPeersToOpenChannels');
60
+ }
67
61
 
68
- // Normally funding would involve an un-broadcast transaction
69
- await sendToChainAddresses({lnd, send_to: pending});
62
+ return;
63
+ });
70
64
 
71
- await asyncRetry({interval, times}, async() => {
72
- const {transactions} = await getChainTransactions({lnd});
65
+ await asyncRetry({interval, times}, async () => {
66
+ pending = (await openChannels({channels, lnd})).pending;
67
+ });
73
68
 
74
- if (transactions.length !== pending.length) {
75
- throw new Error('ExpectedMultipleChainTransactions');
76
- }
69
+ // Normally funding would involve an un-broadcast transaction
70
+ await sendToChainAddresses({lnd, send_to: pending});
77
71
 
78
- return;
79
- });
72
+ await asyncRetry({interval, times}, async() => {
73
+ const {transactions} = await getChainTransactions({lnd});
80
74
 
81
- const fundTx = (await getChainTransactions({lnd})).transactions
82
- .map(({transaction}) => transaction)
83
- .find(transaction => spending.find(spend => transaction !== spend));
75
+ if (transactions.length !== pending.length) {
76
+ throw new Error('ExpectedMultipleChainTransactions');
77
+ }
84
78
 
85
- const fundingPsbt = transactionAsPsbt({spending, transaction: fundTx});
79
+ return;
80
+ });
86
81
 
87
- const {psbt} = finalizePsbt({psbt: fundingPsbt.psbt});
82
+ const fundTx = (await getChainTransactions({lnd})).transactions
83
+ .map(({transaction}) => transaction)
84
+ .find(transaction => spending.find(spend => transaction !== spend));
88
85
 
89
- const reconstitutedTransaction = extractTransaction({psbt});
86
+ const fundingPsbt = transactionAsPsbt({spending, transaction: fundTx});
90
87
 
91
- await fundPendingChannels({
92
- lnd,
93
- channels: pending.map(({id}) => id),
94
- funding: psbt,
95
- });
88
+ const {psbt} = finalizePsbt({psbt: fundingPsbt.psbt});
96
89
 
97
- await asyncRetry({interval, times}, async () => {
98
- await cluster.generate({count});
90
+ const reconstitutedTransaction = extractTransaction({psbt});
99
91
 
100
- const {channels} = await getChannels({lnd})
92
+ await fundPendingChannels({
93
+ lnd,
94
+ channels: pending.map(({id}) => id),
95
+ funding: psbt,
96
+ });
101
97
 
102
- if (channels.filter(n => !!n.is_active).length !== pending.length) {
103
- throw new Error('ExpectedNewChannelsCreatedAndActive');
104
- }
98
+ await asyncRetry({interval, times}, async () => {
99
+ await generate({count});
105
100
 
106
- return;
107
- });
108
- } finally {
109
- return await cluster.kill({});
110
- }
111
- });
101
+ const {channels} = await getChannels({lnd});
102
+
103
+ if (channels.filter(n => !!n.is_active).length !== pending.length) {
104
+ throw new Error('ExpectedNewChannelsCreatedAndActive');
105
+ }
106
+
107
+ return;
108
+ });
109
+ } finally {
110
+ return await kill({});
111
+ }
112
112
 
113
113
  return end();
114
114
  });
@@ -1,5 +1,7 @@
1
1
  const {randomBytes} = require('crypto');
2
2
 
3
+ const asyncRetry = require('async/retry');
4
+ const {spawnLightningCluster} = require('ln-docker-daemons');
3
5
  const {test} = require('@alexbosworth/tap');
4
6
 
5
7
  const {addPeer} = require('./../../');
@@ -22,42 +24,37 @@ const channelCapacityTokens = 1e6;
22
24
  const confirmationCount = 6;
23
25
  const defaultFee = 1e3;
24
26
  const defaultVout = 0;
27
+ const interval = 10;
25
28
  const mtokPadding = '000';
26
29
  const reserveRatio = 0.99;
30
+ const size = 3;
31
+ const times = 1000;
27
32
  const tokens = 100;
28
33
  const txIdHexLength = 32 * 2;
29
34
 
30
35
  // Paying an invoice should settle the invoice
31
36
  test(`Pay`, async ({end, equal, strictSame}) => {
32
- const cluster = await createCluster({});
37
+ const {kill, nodes} = await spawnLightningCluster({size});
33
38
 
34
- const {lnd} = cluster.control;
39
+ const [{generate, lnd}, target, remote] = nodes;
35
40
 
36
- const channel = await setupChannel({
37
- lnd,
38
- generate: cluster.generate,
39
- to: cluster.target,
40
- });
41
+ const channel = await setupChannel({generate, lnd, to: target});
41
42
 
42
43
  const remoteChan = await setupChannel({
43
- generate: cluster.generate,
44
- generator: cluster.target,
45
- lnd: cluster.target.lnd,
46
- to: cluster.remote,
47
- });
48
-
49
- await addPeer({
50
- lnd,
51
- public_key: cluster.remote.public_key,
52
- socket: cluster.remote.socket,
44
+ generate: target.generate,
45
+ lnd: target.lnd,
46
+ to: remote,
53
47
  });
54
48
 
55
- await delay(3000);
49
+ await addPeer({lnd, public_key: remote.id, socket: remote.socket});
56
50
 
57
- const invoice = await createInvoice({tokens, lnd: cluster.remote.lnd});
51
+ const invoice = await createInvoice({tokens, lnd: remote.lnd});
58
52
 
59
53
  const commitTxFee = channel.commit_transaction_fee;
60
- const paid = await pay({lnd, request: invoice.request});
54
+
55
+ const paid = await asyncRetry({interval, times}, async () => {
56
+ return await pay({lnd, request: invoice.request});
57
+ });
61
58
 
62
59
  equal(paid.fee, 1, 'Fee paid for hop');
63
60
  equal(paid.fee_mtokens, '1000', 'Fee mtokens tokens paid');
@@ -86,7 +83,7 @@ test(`Pay`, async ({end, equal, strictSame}) => {
86
83
  fee_mtokens: '1000',
87
84
  forward: 100,
88
85
  forward_mtokens: `${invoice.tokens}${mtokPadding}`,
89
- public_key: cluster.target.public_key,
86
+ public_key: target.id,
90
87
  },
91
88
  {
92
89
  channel: remoteChan.id,
@@ -95,35 +92,41 @@ test(`Pay`, async ({end, equal, strictSame}) => {
95
92
  fee_mtokens: '0',
96
93
  forward: 100,
97
94
  forward_mtokens: '100000',
98
- public_key: cluster.remote.public_key,
95
+ public_key: remote.id,
99
96
  },
100
97
  ];
101
98
 
102
99
  strictSame(paid.hops, expectedHops, 'Hops are returned');
103
100
 
104
- const invoice2 = await createInvoice({lnd: cluster.remote.lnd, tokens: 100});
101
+ const invoice2 = await createInvoice({lnd: remote.lnd, tokens: 100});
105
102
 
106
103
  const {destination} = await decodePaymentRequest({
107
- lnd: cluster.remote.lnd,
104
+ lnd: remote.lnd,
108
105
  request: invoice2.request,
109
106
  });
110
107
 
111
- await cluster.generate({count: confirmationCount, node: cluster.control});
108
+ await generate({count: confirmationCount});
112
109
 
113
- await delay(3000);
110
+ const route = await asyncRetry({interval, times}, async () => {
111
+ const {route} = await getRouteToDestination({
112
+ destination,
113
+ lnd,
114
+ payment: invoice2.payment,
115
+ tokens: invoice2.tokens,
116
+ total_mtokens: !!invoice2.payment ? invoice2.mtokens : undefined,
117
+ });
114
118
 
115
- const {route} = await getRouteToDestination({
116
- destination,
117
- lnd,
118
- payment: invoice2.payment,
119
- tokens: invoice2.tokens,
120
- total_mtokens: !!invoice2.payment ? invoice2.mtokens : undefined,
119
+ if (!route) {
120
+ throw new Error('ExpectedRouteToDestination');
121
+ }
122
+
123
+ return route;
121
124
  });
122
125
 
123
126
  // Test paying to a route, but to an id that isn't known
124
127
  try {
125
128
  await pay({
126
- lnd: cluster.control.lnd,
129
+ lnd,
127
130
  path: {routes: [route], id: randomBytes(32).toString('hex')},
128
131
  });
129
132
  } catch (err) {
@@ -135,15 +138,15 @@ test(`Pay`, async ({end, equal, strictSame}) => {
135
138
 
136
139
  // Test paying regularly to a destination
137
140
  const directPay = await pay({
138
- lnd: cluster.control.lnd,
141
+ lnd,
139
142
  path: {routes: [route], id: invoice2.id},
140
143
  });
141
144
 
142
- const zeroInvoice = await createInvoice({lnd: cluster.target.lnd});
145
+ const zeroInvoice = await createInvoice({lnd: target.lnd});
143
146
 
144
147
  await pay({lnd, request: zeroInvoice.request, mtokens: '1000'});
145
148
 
146
- await cluster.kill({});
149
+ await kill({});
147
150
 
148
151
  return end();
149
152
  });
@@ -1,102 +1,108 @@
1
1
  const {randomBytes} = require('crypto');
2
2
 
3
+ const asyncRetry = require('async/retry');
4
+ const {spawnLightningCluster} = require('ln-docker-daemons');
3
5
  const {test} = require('@alexbosworth/tap');
4
6
 
5
- const {addPeer} = require('./../../');
6
- const {createCluster} = require('./../macros');
7
+ const {cancelHodlInvoice} = require('./../../');
7
8
  const {createInvoice} = require('./../../');
8
9
  const {decodePaymentRequest} = require('./../../');
9
- const {delay} = require('./../macros');
10
10
  const {getChannel} = require('./../../');
11
11
  const {getChannels} = require('./../../');
12
12
  const {getInvoice} = require('./../../');
13
13
  const {getRouteToDestination} = require('./../../');
14
14
  const {openChannel} = require('./../../');
15
+ const {parsePaymentRequest} = require('./../../');
15
16
  const {pay} = require('./../../');
17
+ const {removePeer} = require('./../../');
16
18
  const {setupChannel} = require('./../macros');
17
19
  const {waitForChannel} = require('./../macros');
18
20
  const {waitForPendingChannel} = require('./../macros');
19
21
 
20
22
  const channelCapacityTokens = 1e6;
21
23
  const confirmationCount = 6;
24
+ const count = 100;
22
25
  const defaultFee = 1e3;
23
26
  const defaultVout = 0;
27
+ const interval = 10;
24
28
  const mtokPadding = '000';
25
29
  const reserveRatio = 0.99;
30
+ const size = 3;
31
+ const times = 1000;
26
32
  const tokens = 100;
27
33
  const txIdHexLength = 32 * 2;
28
34
 
29
35
  // Paying a private invoice should settle the invoice
30
36
  test(`Pay private invoice`, async ({end, equal, strictSame}) => {
31
- const cluster = await createCluster({});
32
-
33
- const {lnd} = cluster.control;
34
- const remoteLnd = cluster.remote.lnd;
35
-
36
- await addPeer({
37
- lnd,
38
- public_key: cluster.target.public_key,
39
- socket: cluster.target.socket,
40
- });
41
-
42
- const channel = await setupChannel({
43
- lnd,
44
- generate: cluster.generate,
45
- to: cluster.target,
46
- });
47
-
48
- await addPeer({
49
- lnd: cluster.target.lnd,
50
- public_key: cluster.remote.public_key,
51
- socket: cluster.remote.socket,
52
- });
53
-
54
- const remoteChannel = await setupChannel({
55
- capacity: channelCapacityTokens,
56
- generate: cluster.generate,
57
- generator: cluster.target,
58
- hidden: true,
59
- lnd: cluster.target.lnd,
60
- to: cluster.remote,
61
- });
62
-
63
-
64
- await addPeer({
65
- lnd,
66
- public_key: cluster.remote.public_key,
67
- socket: cluster.remote.socket,
68
- });
69
-
70
- await cluster.generate({count: confirmationCount, node: cluster.target});
71
-
72
- const invoice = await createInvoice({
73
- tokens,
74
- is_including_private_channels: true,
75
- lnd: cluster.remote.lnd,
76
- });
77
-
78
- const {id} = invoice;
79
- const {request} = invoice;
80
-
81
- const decodedRequest = await decodePaymentRequest({lnd, request});
82
-
83
- const {route} = await getRouteToDestination({
84
- lnd,
85
- destination: decodedRequest.destination,
86
- payment: invoice.payment,
87
- routes: decodedRequest.routes,
88
- tokens: invoice.tokens,
89
- total_mtokens: !!invoice.payment ? invoice.mtokens : undefined,
90
- });
91
-
92
- const payment = await pay({lnd, path: {id, routes: [route]}});
93
-
94
- const paidInvoice = await getInvoice({id, lnd: cluster.remote.lnd});
95
-
96
- equal(paidInvoice.secret, invoice.secret, 'Paying invoice got secret');
97
- equal(paidInvoice.is_confirmed, true, 'Private invoice is paid');
98
-
99
- await cluster.kill({});
37
+ const {kill, nodes} = await spawnLightningCluster({size});
38
+
39
+ try {
40
+ const [{generate, lnd}, target, remote] = nodes;
41
+
42
+ await generate({count: 400});
43
+
44
+ const channel = await setupChannel({generate, lnd, to: target});
45
+
46
+ const remoteChannel = await setupChannel({
47
+ capacity: channelCapacityTokens,
48
+ generate: target.generate,
49
+ hidden: true,
50
+ lnd: target.lnd,
51
+ to: remote,
52
+ });
53
+
54
+ const invoice = await asyncRetry({interval, times}, async () => {
55
+ const invoice = await createInvoice({
56
+ tokens,
57
+ is_including_private_channels: true,
58
+ lnd: remote.lnd,
59
+ });
60
+
61
+ const {routes} = parsePaymentRequest({request: invoice.request});
62
+
63
+ // Wait for private routes to get picked up
64
+ if (!routes) {
65
+ await cancelHodlInvoice({id: invoice.id, lnd: remote.lnd});
66
+
67
+ throw new Error('ExpectedRouteForInvoice');
68
+ }
69
+
70
+ return invoice;
71
+ });
72
+
73
+ const {id} = invoice;
74
+ const {request} = invoice;
75
+
76
+ const decodedRequest = await decodePaymentRequest({lnd, request});
77
+
78
+ const route = await asyncRetry({interval: 10, times: 1000}, async () => {
79
+ const {route} = await getRouteToDestination({
80
+ lnd,
81
+ destination: decodedRequest.destination,
82
+ payment: invoice.payment,
83
+ routes: decodedRequest.routes,
84
+ tokens: invoice.tokens,
85
+ total_mtokens: !!invoice.payment ? invoice.mtokens : undefined,
86
+ });
87
+
88
+ if (!route) {
89
+ throw new Error('ExpectedRouteToDestination');
90
+ }
91
+
92
+ return route;
93
+ });
94
+
95
+ const payment = await pay({lnd, path: {id, routes: [route]}});
96
+
97
+ const paidInvoice = await getInvoice({id, lnd: remote.lnd});
98
+
99
+ equal(paidInvoice.secret, invoice.secret, 'Paying invoice got secret');
100
+ equal(paidInvoice.is_confirmed, true, 'Private invoice is paid');
101
+ } catch (err) {
102
+ equal(err, null, 'Expected no error paying invoice');
103
+ }
104
+
105
+ await kill({});
100
106
 
101
107
  return end();
102
108
  });
@@ -2,9 +2,9 @@ const asyncRetry = require('async/retry');
2
2
  const {decodeChanId} = require('bolt07');
3
3
  const {hopsFromChannels} = require('bolt07');
4
4
  const {routeFromHops} = require('bolt07');
5
+ const {spawnLightningCluster} = require('ln-docker-daemons');
5
6
  const {test} = require('@alexbosworth/tap');
6
7
 
7
- const {createCluster} = require('./../macros');
8
8
  const {createInvoice} = require('./../../');
9
9
  const {delay} = require('./../macros');
10
10
  const {getChannel} = require('./../../');
@@ -16,28 +16,30 @@ const {setupChannel} = require('./../macros');
16
16
 
17
17
  const interval = retryCount => 50 * Math.pow(2, retryCount);
18
18
  const mtok = '000';
19
+ const size = 2;
19
20
  const times = 15;
20
21
  const tokens = 1e3;
21
22
 
22
23
  // Encountering errors in payment should return valid error codes
23
24
  test('Payment errors', async ({end, equal}) => {
24
- const cluster = await createCluster({is_remote_skipped: true});
25
+ const {kill, nodes} = await spawnLightningCluster({size});
25
26
 
26
- const {lnd} = cluster.control;
27
+ const [control, target] = nodes;
28
+
29
+ const {lnd} = control;
27
30
 
28
31
  // Create a channel from the control to the target node
29
32
  const controlToTargetChannel = await setupChannel({
30
33
  lnd,
31
- generate: cluster.generate,
32
- to: cluster.target,
34
+ generate: control.generate,
35
+ to: target,
33
36
  });
34
37
 
35
38
  // Create a channel from the target back to the control
36
39
  const targetToControlChannel = await setupChannel({
37
- generate: cluster.generate,
38
- generator: cluster.target,
39
- lnd: cluster.target.lnd,
40
- to: cluster.control,
40
+ generate: target.generate,
41
+ lnd: target.lnd,
42
+ to: control,
41
43
  });
42
44
 
43
45
  const height = (await getHeight({lnd})).current_block_height;
@@ -49,7 +51,7 @@ test('Payment errors', async ({end, equal}) => {
49
51
 
50
52
  const [inChanId, outChanId] = channels.map(({id}) => id).sort();
51
53
 
52
- const destination = (await getIdentity({lnd})).public_key;
54
+ const destination = control.id;
53
55
 
54
56
  try {
55
57
  let route;
@@ -93,7 +95,7 @@ test('Payment errors', async ({end, equal}) => {
93
95
  }
94
96
  }
95
97
 
96
- await cluster.kill({});
98
+ await kill({});
97
99
 
98
100
  return end();
99
101
  });