ln-service 53.7.0 → 53.8.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 (41) hide show
  1. package/CHANGELOG.md +5 -1
  2. package/README.md +38 -2
  3. package/index.js +4 -2
  4. package/package.json +9 -6
  5. package/test/integration/test_add_peer.js +4 -2
  6. package/test/integration/test_delete_pending_channel.js +5 -2
  7. package/test/integration/test_get_closed_channels.js +0 -2
  8. package/test/integration/test_get_invoice.js +0 -1
  9. package/test/integration/test_get_node.js +13 -1
  10. package/test/integration/test_get_peers.js +32 -21
  11. package/test/integration/test_get_pending_force.js +1 -1
  12. package/test/integration/test_get_wallet_info.js +32 -26
  13. package/test/integration/test_open_channels.js +22 -15
  14. package/test/integration/test_pay.js +0 -1
  15. package/test/integration/test_pay_private_invoice.js +0 -1
  16. package/test/integration/test_propose_channel.js +438 -421
  17. package/test/integration/test_remove_peer.js +13 -9
  18. package/test/integration/test_send_message_to_peer.js +39 -28
  19. package/test/integration/test_send_to_chain_address.js +4 -0
  20. package/test/integration/test_subscribe_to_channels.js +0 -1
  21. package/test/integration/test_subscribe_to_invoices.js +80 -78
  22. package/test/integration/test_subscribe_to_peer_messages.js +6 -4
  23. package/test/integration/test_subscribe_to_peers.js +23 -19
  24. package/test/invoicesrpc-integration/test_get_sweep_transactions.js +0 -2
  25. package/test/invoicesrpc-integration/test_subscribe_cancel_invoice.js +0 -1
  26. package/test/macros/wait_for_channel.js +1 -1
  27. package/test/routerrpc-integration/test_delete_forwarding_reputations.js +61 -27
  28. package/test/routerrpc-integration/test_get_forwarding_reputations.js +42 -14
  29. package/test/routerrpc-integration/test_get_route_through_hops.js +33 -22
  30. package/test/routerrpc-integration/test_multipath_payment.js +0 -1
  31. package/test/routerrpc-integration/test_pay_via_payment_details.js +118 -111
  32. package/test/routerrpc-integration/test_pay_via_payment_request.js +92 -80
  33. package/test/routerrpc-integration/test_probe_for_route.js +78 -74
  34. package/test/routerrpc-integration/test_subscribe_to_forward_requests.js +0 -1
  35. package/test/routerrpc-integration/test_subscribe_to_forwards.js +518 -505
  36. package/test/routerrpc-integration/test_subscribe_to_past_payments.js +0 -3
  37. package/test/tower_clientrpc-integration/test_get_connected_watchtowers.js +0 -3
  38. package/test/walletrpc-integration/test_fund_psbt.js +113 -1
  39. package/test/walletrpc-integration/test_get_master_public_keys.js +79 -0
  40. package/test/walletrpc-integration/test_partially_sign_psbt.js +17 -5
  41. package/test/walletrpc-integration/test_sign_psbt.js +4 -1
@@ -10,6 +10,7 @@ const {script} = require('bitcoinjs-lib');
10
10
  const signPsbtWithKey = require('psbt').signPsbt;
11
11
  const {spawnLightningCluster} = require('ln-docker-daemons');
12
12
  const {test} = require('@alexbosworth/tap');
13
+ const tinysecp = require('tiny-secp256k1');
13
14
  const {Transaction} = require('bitcoinjs-lib');
14
15
  const {updatePsbt} = require('psbt');
15
16
 
@@ -49,447 +50,463 @@ const times = 300;
49
50
 
50
51
  // Proposing a cooperative delay channel should open a cooperative delay chan
51
52
  test(`Propose a channel with a coop delay`, async ({end, equal, ok}) => {
53
+ const ecp = (await import('ecpair')).ECPairFactory(tinysecp);
54
+
52
55
  const {kill, nodes} = await spawnLightningCluster({size});
53
56
 
54
57
  const [control, target] = nodes;
55
58
 
56
59
  const {lnd, generate} = control;
57
60
 
58
- const {version} = await getWalletVersion({lnd});
59
-
60
- switch (version) {
61
- case '0.11.0-beta':
62
- case '0.11.1-beta':
63
- // Exit early when funding PSBTs is not supported
64
- await kill({});
65
-
66
- return end();
67
-
68
- default:
69
- break;
70
- }
71
-
72
- // Generate some funds for LND
73
- await asyncRetry({times}, async () => {
74
- await addPeer({lnd, public_key: target.id, socket: target.socket});
61
+ try {
62
+ const {version} = await getWalletVersion({lnd});
75
63
 
76
- await generate({});
64
+ switch (version) {
65
+ case '0.11.0-beta':
66
+ case '0.11.1-beta':
67
+ // Exit early when funding PSBTs is not supported
68
+ await kill({});
77
69
 
78
- const wallet = await getChainBalance({lnd});
70
+ return end();
79
71
 
80
- if (!wallet.chain_balance) {
81
- throw new Error('ExpectedChainBalanceForNode');
72
+ default:
73
+ break;
82
74
  }
83
- });
84
75
 
85
- // Generate some funds for LND
86
- await asyncRetry({times}, async () => {
87
- await target.generate({});
76
+ // Generate some funds for LND
77
+ await asyncRetry({times}, async () => {
78
+ await addPeer({lnd, public_key: target.id, socket: target.socket});
88
79
 
89
- const wallet = await getChainBalance({lnd: target.lnd});
80
+ await generate({});
90
81
 
91
- if (!wallet.chain_balance) {
92
- throw new Error('ExpectedChainBalanceForNode');
93
- }
94
- });
95
-
96
- const {features} = await getWalletInfo({lnd});
97
-
98
- const isAnchors = !!features.find(n => n.bit === anchorFeatureBit);
99
-
100
- // Derive a temporary key for control to pay into
101
- const controlDerivedKey = await getPublicKey({
102
- lnd,
103
- family: temporaryFamily,
104
- });
105
-
106
- // Derive a temporary key for target to pay into
107
- const targetDerivedKey = await getPublicKey({
108
- family: temporaryFamily,
109
- lnd: target.lnd,
110
- });
111
-
112
- // Control should fund and sign a transaction going to the control temp key
113
- const controlDerivedAddress = payments.p2wpkh({
114
- network: regtest,
115
- pubkey: Buffer.from(controlDerivedKey.public_key, 'hex'),
116
- });
117
-
118
- // Target should fund and sign a transaction going to the target temp key
119
- const targetDerivedAddress = payments.p2wpkh({
120
- network: regtest,
121
- pubkey: Buffer.from(targetDerivedKey.public_key, 'hex'),
122
- });
123
-
124
- const temporaryKeys = [controlDerivedKey, targetDerivedKey];
125
-
126
- const giveTokens = ceil(capacity / temporaryKeys.length);
127
-
128
- // Control can now fund a transaction to pay to the temp address
129
- const controlFundPsbt = await fundPsbt({
130
- lnd,
131
- fee_tokens_per_vbyte: feeRate,
132
- outputs: [{
133
- address: controlDerivedAddress.address,
134
- tokens: giveTokens + ceil(fundingFee / temporaryKeys.length),
135
- }],
136
- });
137
-
138
- // Target can now fund a transaction to pay to the temp address
139
- const targetFundPsbt = await fundPsbt({
140
- lnd: target.lnd,
141
- fee_tokens_per_vbyte: feeRate,
142
- outputs: [{
143
- address: targetDerivedAddress.address,
144
- tokens: giveTokens + ceil(fundingFee / temporaryKeys.length),
145
- }],
146
- });
147
-
148
- // Control can sign the funding to the temporary address
149
- const controlSignPsbt = await signPsbt({lnd, psbt: controlFundPsbt.psbt});
150
-
151
- // Target can sign the funding to the temporary address
152
- const targetSignPsbt = await signPsbt({
153
- lnd: target.lnd,
154
- psbt: targetFundPsbt.psbt,
155
- });
156
-
157
- // Decode the control funded PSBT
158
- const controlPsbt = decodePsbt({psbt: controlFundPsbt.psbt});
159
-
160
- // Decode the target funded PSBT
161
- const targetPsbt = decodePsbt({psbt: targetFundPsbt.psbt});
162
-
163
- // Derive the id of the control pre-funding tx
164
- const controlId = fromHex(controlPsbt.unsigned_transaction).getId();
165
-
166
- // Derive the id of the target pre-funding tx
167
- const targetId = fromHex(targetPsbt.unsigned_transaction).getId();
168
-
169
- // Derive a new control key for a 2:2 multisig
170
- const controlMultiSigKey = await getPublicKey({family, lnd});
171
-
172
- // Derive a new target key for a 2:2 multisig
173
- const targetMultiSigKey = await getPublicKey({family, lnd: target.lnd});
174
-
175
- const fundingMultiSigKeys = [
176
- controlMultiSigKey.public_key,
177
- targetMultiSigKey.public_key,
178
- ];
179
-
180
- // Make the channel 2:2 funding output from control and target keys
181
- const dualFundingChannelAddress = payments.p2wsh({
182
- redeem: p2ms({
183
- m: fundingMultiSigKeys.length,
184
- pubkeys: fundingMultiSigKeys.sort().map(n => Buffer.from(n, 'hex')),
185
- }),
186
- });
187
-
188
- const pendingChannelId = dualFundingChannelAddress.hash;
189
-
190
- // Create the basic PSBT that spends temporary funds to the 2:2 funding
191
- const dualFundPsbt = createPsbt({
192
- outputs: [{
193
- script: dualFundingChannelAddress.output.toString('hex'),
194
- tokens: capacity,
195
- }],
196
- utxos: [
197
- {
198
- id: fromHex(controlSignPsbt.transaction).getId(),
199
- vout: controlFundPsbt.outputs.findIndex(n => !n.is_change),
200
- },
201
- {
202
- id: fromHex(targetSignPsbt.transaction).getId(),
203
- vout: targetFundPsbt.outputs.findIndex(n => !n.is_change),
204
- },
205
- ],
206
- });
207
-
208
- const controlWithoutWitnessTx = fromHex(controlSignPsbt.transaction);
209
- const targetWithoutWitnessTx = fromHex(targetSignPsbt.transaction);
210
-
211
- // Eliminate the witnesses
212
- controlWithoutWitnessTx.ins.forEach((input, index) => {
213
- return controlWithoutWitnessTx.setWitness(index, []);
214
- });
215
-
216
- targetWithoutWitnessTx.ins.forEach((input, index) => {
217
- return targetWithoutWitnessTx.setWitness(index, []);
218
- });
219
-
220
- // Add the spending transactions to the psbt
221
- const psbtWithSpending = updatePsbt({
222
- psbt: dualFundPsbt.psbt,
223
- transactions: [
224
- controlWithoutWitnessTx.toHex(),
225
- targetWithoutWitnessTx.toHex(),
226
- ],
227
- });
228
-
229
- const finalFundingPsbt = decodePsbt({psbt: dualFundPsbt.psbt});
230
-
231
- const fundingTx = fromHex(finalFundingPsbt.unsigned_transaction);
232
-
233
- const fundingTxId = fundingTx.getId();
234
-
235
- const fundingTxVout = fundingTx.outs.findIndex(n => n.value === capacity);
236
-
237
- const controlTxHash = controlWithoutWitnessTx.getHash();
238
-
239
- const targetTxHash = targetWithoutWitnessTx.getHash();
240
-
241
- const controlVin = fundingTx.ins.findIndex(({hash}) => {
242
- return hash.equals(controlTxHash);
243
- });
244
-
245
- const targetVin = fundingTx.ins.findIndex(({hash}) => {
246
- return hash.equals(targetTxHash);
247
- });
248
-
249
- const decodePayout = decodePsbt({psbt: psbtWithSpending.psbt});
250
-
251
- // Call signTransaction on the unsigned tx that pays from temp -> multisig
252
- const controlSignDerivedKey = await signTransaction({
253
- lnd,
254
- inputs: [{
255
- key_family: temporaryFamily,
256
- key_index: controlDerivedKey.index,
257
- output_script: dualFundingChannelAddress.output.toString('hex'),
258
- output_tokens: giveTokens + ceil(fundingFee / temporaryKeys.length),
259
- sighash: Transaction.SIGHASH_ALL,
260
- vin: controlVin,
261
- witness_script: p2pkh({hash: controlDerivedAddress.hash}).output,
262
- }],
263
- transaction: decodePayout.unsigned_transaction,
264
- });
265
-
266
- const [controlDerivedSignature] = controlSignDerivedKey.signatures;
267
-
268
- const controlSignSpendingPsbt = updatePsbt({
269
- psbt: psbtWithSpending.psbt,
270
- signatures: controlSignDerivedKey.signatures.map(sig => {
271
- return {
272
- signature: Buffer.concat([
273
- Buffer.from(sig, 'hex'),
274
- Buffer.from([Transaction.SIGHASH_ALL]),
275
- ]).toString('hex') ,
276
- hash_type: Transaction.SIGHASH_ALL,
277
- public_key: controlDerivedKey.public_key,
82
+ const wallet = await getChainBalance({lnd});
83
+
84
+ if (!wallet.chain_balance) {
85
+ throw new Error('ExpectedChainBalanceForNode');
86
+ }
87
+ });
88
+
89
+ // Generate some funds for LND
90
+ await asyncRetry({times}, async () => {
91
+ await target.generate({});
92
+
93
+ const wallet = await getChainBalance({lnd: target.lnd});
94
+
95
+ if (!wallet.chain_balance) {
96
+ throw new Error('ExpectedChainBalanceForNode');
97
+ }
98
+ });
99
+
100
+ const {features} = await getWalletInfo({lnd});
101
+
102
+ const isAnchors = !!features.find(n => n.bit === anchorFeatureBit);
103
+
104
+ // Derive a temporary key for control to pay into
105
+ const controlDerivedKey = await getPublicKey({
106
+ lnd,
107
+ family: temporaryFamily,
108
+ });
109
+
110
+ // Derive a temporary key for target to pay into
111
+ const targetDerivedKey = await getPublicKey({
112
+ family: temporaryFamily,
113
+ lnd: target.lnd,
114
+ });
115
+
116
+ // Control should fund and sign a transaction going to the control temp key
117
+ const controlDerivedAddress = payments.p2wpkh({
118
+ network: regtest,
119
+ pubkey: Buffer.from(controlDerivedKey.public_key, 'hex'),
120
+ });
121
+
122
+ // Target should fund and sign a transaction going to the target temp key
123
+ const targetDerivedAddress = payments.p2wpkh({
124
+ network: regtest,
125
+ pubkey: Buffer.from(targetDerivedKey.public_key, 'hex'),
126
+ });
127
+
128
+ const temporaryKeys = [controlDerivedKey, targetDerivedKey];
129
+
130
+ const giveTokens = ceil(capacity / temporaryKeys.length);
131
+
132
+ // Control can now fund a transaction to pay to the temp address
133
+ const controlFundPsbt = await fundPsbt({
134
+ lnd,
135
+ fee_tokens_per_vbyte: feeRate,
136
+ outputs: [{
137
+ address: controlDerivedAddress.address,
138
+ tokens: giveTokens + ceil(fundingFee / temporaryKeys.length),
139
+ }],
140
+ });
141
+
142
+ // Target can now fund a transaction to pay to the temp address
143
+ const targetFundPsbt = await fundPsbt({
144
+ lnd: target.lnd,
145
+ fee_tokens_per_vbyte: feeRate,
146
+ outputs: [{
147
+ address: targetDerivedAddress.address,
148
+ tokens: giveTokens + ceil(fundingFee / temporaryKeys.length),
149
+ }],
150
+ });
151
+
152
+ // Control can sign the funding to the temporary address
153
+ const controlSignPsbt = await signPsbt({lnd, psbt: controlFundPsbt.psbt});
154
+
155
+ // Target can sign the funding to the temporary address
156
+ const targetSignPsbt = await signPsbt({
157
+ lnd: target.lnd,
158
+ psbt: targetFundPsbt.psbt,
159
+ });
160
+
161
+ // Decode the control funded PSBT
162
+ const controlPsbt = decodePsbt({ecp, psbt: controlFundPsbt.psbt});
163
+
164
+ // Decode the target funded PSBT
165
+ const targetPsbt = decodePsbt({ecp, psbt: targetFundPsbt.psbt});
166
+
167
+ // Derive the id of the control pre-funding tx
168
+ const controlId = fromHex(controlPsbt.unsigned_transaction).getId();
169
+
170
+ // Derive the id of the target pre-funding tx
171
+ const targetId = fromHex(targetPsbt.unsigned_transaction).getId();
172
+
173
+ // Derive a new control key for a 2:2 multisig
174
+ const controlMultiSigKey = await getPublicKey({family, lnd});
175
+
176
+ // Derive a new target key for a 2:2 multisig
177
+ const targetMultiSigKey = await getPublicKey({family, lnd: target.lnd});
178
+
179
+ const fundingMultiSigKeys = [
180
+ controlMultiSigKey.public_key,
181
+ targetMultiSigKey.public_key,
182
+ ];
183
+
184
+ // Make the channel 2:2 funding output from control and target keys
185
+ const dualFundingChannelAddress = payments.p2wsh({
186
+ redeem: p2ms({
187
+ m: fundingMultiSigKeys.length,
188
+ pubkeys: fundingMultiSigKeys.sort().map(n => Buffer.from(n, 'hex')),
189
+ }),
190
+ });
191
+
192
+ const pendingChannelId = dualFundingChannelAddress.hash;
193
+
194
+ // Create the basic PSBT that spends temporary funds to the 2:2 funding
195
+ const dualFundPsbt = createPsbt({
196
+ outputs: [{
197
+ script: dualFundingChannelAddress.output.toString('hex'),
198
+ tokens: capacity,
199
+ }],
200
+ utxos: [
201
+ {
202
+ id: fromHex(controlSignPsbt.transaction).getId(),
203
+ vout: controlFundPsbt.outputs.findIndex(n => !n.is_change),
204
+ },
205
+ {
206
+ id: fromHex(targetSignPsbt.transaction).getId(),
207
+ vout: targetFundPsbt.outputs.findIndex(n => !n.is_change),
208
+ },
209
+ ],
210
+ });
211
+
212
+ const controlWithoutWitnessTx = fromHex(controlSignPsbt.transaction);
213
+ const targetWithoutWitnessTx = fromHex(targetSignPsbt.transaction);
214
+
215
+ // Eliminate the witnesses
216
+ controlWithoutWitnessTx.ins.forEach((input, index) => {
217
+ return controlWithoutWitnessTx.setWitness(index, []);
218
+ });
219
+
220
+ targetWithoutWitnessTx.ins.forEach((input, index) => {
221
+ return targetWithoutWitnessTx.setWitness(index, []);
222
+ });
223
+
224
+ // Add the spending transactions to the psbt
225
+ const psbtWithSpending = updatePsbt({
226
+ ecp,
227
+ psbt: dualFundPsbt.psbt,
228
+ transactions: [
229
+ controlWithoutWitnessTx.toHex(),
230
+ targetWithoutWitnessTx.toHex(),
231
+ ],
232
+ });
233
+
234
+ const finalFundingPsbt = decodePsbt({ecp, psbt: dualFundPsbt.psbt});
235
+
236
+ const fundingTx = fromHex(finalFundingPsbt.unsigned_transaction);
237
+
238
+ const fundingTxId = fundingTx.getId();
239
+
240
+ const fundingTxVout = fundingTx.outs.findIndex(n => n.value === capacity);
241
+
242
+ const controlTxHash = controlWithoutWitnessTx.getHash();
243
+
244
+ const targetTxHash = targetWithoutWitnessTx.getHash();
245
+
246
+ const controlVin = fundingTx.ins.findIndex(({hash}) => {
247
+ return hash.equals(controlTxHash);
248
+ });
249
+
250
+ const targetVin = fundingTx.ins.findIndex(({hash}) => {
251
+ return hash.equals(targetTxHash);
252
+ });
253
+
254
+ const decodePayout = decodePsbt({ecp, psbt: psbtWithSpending.psbt});
255
+
256
+ // Call signTransaction on the unsigned tx that pays from temp -> multisig
257
+ const controlSignDerivedKey = await signTransaction({
258
+ lnd,
259
+ inputs: [{
260
+ key_family: temporaryFamily,
261
+ key_index: controlDerivedKey.index,
262
+ output_script: dualFundingChannelAddress.output.toString('hex'),
263
+ output_tokens: giveTokens + ceil(fundingFee / temporaryKeys.length),
264
+ sighash: Transaction.SIGHASH_ALL,
278
265
  vin: controlVin,
279
- };
280
- }),
281
- });
282
-
283
- // Call signTransaction on the unsigned tx that pays from temp -> multisig
284
- const targetSignDerivedKey = await signTransaction({
285
- inputs: [{
286
- key_family: temporaryFamily,
287
- key_index: targetDerivedKey.index,
288
- output_script: dualFundingChannelAddress.output.toString('hex'),
289
- output_tokens: giveTokens + ceil(fundingFee / temporaryKeys.length),
290
- sighash: Transaction.SIGHASH_ALL,
291
- vin: targetVin,
292
- witness_script: p2pkh({hash: targetDerivedAddress.hash}).output,
293
- }],
294
- lnd: target.lnd,
295
- transaction: decodePsbt({psbt: psbtWithSpending.psbt}).unsigned_transaction,
296
- });
297
-
298
- const [targetDerivedSignature] = targetSignDerivedKey.signatures;
299
-
300
- const targetSignSpendingPsbt = updatePsbt({
301
- psbt: psbtWithSpending.psbt,
302
- signatures: targetSignDerivedKey.signatures.map(sig => {
303
- return {
304
- signature: Buffer.concat([
305
- Buffer.from(sig, 'hex'),
306
- Buffer.from([Transaction.SIGHASH_ALL]),
307
- ]).toString('hex') ,
308
- hash_type: Transaction.SIGHASH_ALL,
309
- public_key: targetDerivedKey.public_key,
266
+ witness_script: p2pkh({hash: controlDerivedAddress.hash}).output,
267
+ }],
268
+ transaction: decodePayout.unsigned_transaction,
269
+ });
270
+
271
+ const [controlDerivedSignature] = controlSignDerivedKey.signatures;
272
+
273
+ const controlSignSpendingPsbt = updatePsbt({
274
+ ecp,
275
+ psbt: psbtWithSpending.psbt,
276
+ signatures: controlSignDerivedKey.signatures.map(sig => {
277
+ return {
278
+ signature: Buffer.concat([
279
+ Buffer.from(sig, 'hex'),
280
+ Buffer.from([Transaction.SIGHASH_ALL]),
281
+ ]).toString('hex') ,
282
+ hash_type: Transaction.SIGHASH_ALL,
283
+ public_key: controlDerivedKey.public_key,
284
+ vin: controlVin,
285
+ };
286
+ }),
287
+ });
288
+
289
+ // Call signTransaction on the unsigned tx that pays from temp -> multisig
290
+ const targetSignDerivedKey = await signTransaction({
291
+ inputs: [{
292
+ key_family: temporaryFamily,
293
+ key_index: targetDerivedKey.index,
294
+ output_script: dualFundingChannelAddress.output.toString('hex'),
295
+ output_tokens: giveTokens + ceil(fundingFee / temporaryKeys.length),
296
+ sighash: Transaction.SIGHASH_ALL,
310
297
  vin: targetVin,
311
- };
312
- }),
313
- });
314
-
315
- // Use the anticipated funding tx to prepare for a new channel open
316
- await prepareForChannelProposal({
317
- cooperative_close_delay: cooperativeCloseDelay,
318
- id: pendingChannelId.toString('hex'),
319
- key_index: targetMultiSigKey.index,
320
- lnd: target.lnd,
321
- remote_key: controlMultiSigKey.public_key,
322
- transaction_id: fundingTxId,
323
- transaction_vout: fundingTxVout,
324
- });
325
-
326
- const coopCloseAddress = await createChainAddress({
327
- format: 'np2wpkh',
328
- lnd: control.lnd,
329
- });
330
-
331
- // Propose the channel to the target
332
- await proposeChannel({
333
- capacity,
334
- cooperative_close_address: coopCloseAddress.address,
335
- cooperative_close_delay: cooperativeCloseDelay,
336
- give_tokens: capacity / fundingMultiSigKeys.length,
337
- id: pendingChannelId.toString('hex'),
338
- is_private: true,
339
- key_index: controlMultiSigKey.index,
340
- lnd: control.lnd,
341
- partner_public_key: target.id,
342
- remote_key: targetMultiSigKey.public_key,
343
- transaction_id: fundingTxId,
344
- transaction_vout: fundingTxVout,
345
- });
346
-
347
- const pendingTarget = await getPendingChannels({lnd: target.lnd});
348
-
349
- const [incoming] = pendingTarget.pending_channels;
350
-
351
- // LND 0.11.1 and before do not use anchor channels
352
- if (isAnchors) {
353
- equal(incoming.remote_balance, 496530, 'Remote balance amount');
354
- equal(incoming.transaction_fee, 2810, 'Commit tx fee');
355
- equal(incoming.transaction_weight, 1116, 'Funding tx weight');
356
- } else {
357
- equal(incoming.remote_balance, giveTokens - 9050, 'Remote balance amount');
358
- equal(incoming.transaction_fee, 9050, 'Commit tx fee');
359
- equal(incoming.transaction_weight, 724, 'Funding tx weight');
360
- }
361
-
362
- equal(incoming.capacity, 1000000, 'Incoming capacity is defined');
363
- equal(incoming.close_transaction_id, undefined, 'Not a closing tx');
364
- equal(incoming.is_active, false, 'Not active yet');
365
- equal(incoming.is_closing, false, 'Channel is not closing');
366
- equal(incoming.is_opening, true, 'Channel is opening');
367
- equal(incoming.is_partner_initiated, true, 'Peer initiated the channel');
368
- equal(incoming.local_balance, giveTokens, 'The incoming channel is split');
369
- equal(incoming.local_reserve, capacity * reserveRatio, 'Reserve ratio');
370
- equal(incoming.partner_public_key, control.id, 'Peer key');
371
- equal(incoming.pending_balance, undefined, 'No tokens pending');
372
- equal(incoming.pending_payments, undefined, 'No HTLCs active');
373
- equal(incoming.received, 0, 'Nothing received');
374
- equal(incoming.recovered_tokens, undefined, 'No recovery');
375
- equal(incoming.remote_reserve, capacity * reserveRatio, 'Got peer reserve');
376
- equal(incoming.sent, 0, 'Nothing sent');
377
- equal(incoming.timelock_expiration, undefined, 'No timelock');
378
- equal(incoming.transaction_id, fundingTxId, 'Funding tx id is correct');
379
- equal(incoming.transaction_vout, fundingTxVout, 'Funding vout is correct');
380
-
381
- // Setup the combined signed PSBTs that fund the channel
382
- const combinedTempPsbt = combinePsbts({
383
- psbts: [controlSignSpendingPsbt, targetSignSpendingPsbt].map(n => n.psbt),
384
- });
385
-
386
- // Finalize the combined PSBT
387
- const finalTempPsbt = finalizePsbt({psbt: combinedTempPsbt.psbt});
388
-
389
- // Pull out the signed broadcast-ready transaction from the PSBT
390
- const finalTempTx = extractTransaction({psbt: finalTempPsbt.psbt});
391
-
392
- // Calculate the size of the tx
393
- const txSize = fromHex(finalTempTx.transaction).virtualSize();
394
-
395
- equal(txSize <= fundingFee, true, 'Transaction size is not too large');
396
-
397
- // Broadcast the transaction to fund the control side
398
- await broadcastChainTransaction({
399
- lnd,
400
- transaction: controlSignPsbt.transaction,
401
- });
402
-
403
- // Broadcast the transaction to fund the target side
404
- await broadcastChainTransaction({
405
- lnd,
406
- transaction: targetSignPsbt.transaction,
407
- });
408
-
409
- // Broadcast the transaction to fund the channel
410
- await broadcastChainTransaction({
411
- lnd,
412
- transaction: finalTempTx.transaction,
413
- });
414
-
415
- // Mine the funding transactions into a block
416
- await asyncRetry({interval, times}, async () => {
417
- await control.generate({});
418
-
419
- const {channels} = await getChannels({lnd});
420
-
421
- if (!channels.find(n => n.is_active)) {
422
- throw new Error('ExpectedActiveChannel');
298
+ witness_script: p2pkh({hash: targetDerivedAddress.hash}).output,
299
+ }],
300
+ lnd: target.lnd,
301
+ transaction: decodePsbt({
302
+ ecp,
303
+ psbt: psbtWithSpending.psbt,
304
+ }).unsigned_transaction,
305
+ });
306
+
307
+ const [targetDerivedSignature] = targetSignDerivedKey.signatures;
308
+
309
+ const targetSignSpendingPsbt = updatePsbt({
310
+ ecp,
311
+ psbt: psbtWithSpending.psbt,
312
+ signatures: targetSignDerivedKey.signatures.map(sig => {
313
+ return {
314
+ signature: Buffer.concat([
315
+ Buffer.from(sig, 'hex'),
316
+ Buffer.from([Transaction.SIGHASH_ALL]),
317
+ ]).toString('hex') ,
318
+ hash_type: Transaction.SIGHASH_ALL,
319
+ public_key: targetDerivedKey.public_key,
320
+ vin: targetVin,
321
+ };
322
+ }),
323
+ });
324
+
325
+ // Use the anticipated funding tx to prepare for a new channel open
326
+ await prepareForChannelProposal({
327
+ cooperative_close_delay: cooperativeCloseDelay,
328
+ id: pendingChannelId.toString('hex'),
329
+ key_index: targetMultiSigKey.index,
330
+ lnd: target.lnd,
331
+ remote_key: controlMultiSigKey.public_key,
332
+ transaction_id: fundingTxId,
333
+ transaction_vout: fundingTxVout,
334
+ });
335
+
336
+ const coopCloseAddress = await createChainAddress({
337
+ format: 'np2wpkh',
338
+ lnd: control.lnd,
339
+ });
340
+
341
+ // Propose the channel to the target
342
+ await proposeChannel({
343
+ capacity,
344
+ cooperative_close_address: coopCloseAddress.address,
345
+ cooperative_close_delay: cooperativeCloseDelay,
346
+ give_tokens: capacity / fundingMultiSigKeys.length,
347
+ id: pendingChannelId.toString('hex'),
348
+ is_private: true,
349
+ key_index: controlMultiSigKey.index,
350
+ lnd: control.lnd,
351
+ partner_public_key: target.id,
352
+ remote_key: targetMultiSigKey.public_key,
353
+ transaction_id: fundingTxId,
354
+ transaction_vout: fundingTxVout,
355
+ });
356
+
357
+ const pendingTarget = await getPendingChannels({lnd: target.lnd});
358
+
359
+ const [incoming] = pendingTarget.pending_channels;
360
+
361
+ // LND 0.11.1 and before do not use anchor channels
362
+ if (isAnchors) {
363
+ equal(incoming.remote_balance, 496530, 'Remote balance amount');
364
+ equal(incoming.transaction_fee, 2810, 'Commit tx fee');
365
+ equal(incoming.transaction_weight, 1116, 'Funding tx weight');
366
+ } else {
367
+ equal(incoming.remote_balance, giveTokens - 9050, 'Remote balance');
368
+ equal(incoming.transaction_fee, 9050, 'Commit tx fee');
369
+ equal(incoming.transaction_weight, 724, 'Funding tx weight');
423
370
  }
424
371
 
425
- return;
426
- });
427
-
428
- const controlChannels = await getChannels({lnd});
429
-
430
- const [controlChannel] = controlChannels.channels;
431
-
432
- const closeAddr = coopCloseAddress.address;
372
+ equal(incoming.capacity, 1000000, 'Incoming capacity is defined');
373
+ equal(incoming.close_transaction_id, undefined, 'Not a closing tx');
374
+ equal(incoming.is_active, false, 'Not active yet');
375
+ equal(incoming.is_closing, false, 'Channel is not closing');
376
+ equal(incoming.is_opening, true, 'Channel is opening');
377
+ equal(incoming.is_partner_initiated, true, 'Peer initiated the channel');
378
+ equal(incoming.local_balance, giveTokens, 'The incoming channel is split');
379
+ equal(incoming.local_reserve, capacity * reserveRatio, 'Reserve ratio');
380
+ equal(incoming.partner_public_key, control.id, 'Peer key');
381
+ equal(incoming.pending_balance, undefined, 'No tokens pending');
382
+ equal(incoming.pending_payments, undefined, 'No HTLCs active');
383
+ equal(incoming.received, 0, 'Nothing received');
384
+ equal(incoming.recovered_tokens, undefined, 'No recovery');
385
+ equal(incoming.remote_reserve, capacity * reserveRatio, 'Got reserve');
386
+ equal(incoming.sent, 0, 'Nothing sent');
387
+ equal(incoming.timelock_expiration, undefined, 'No timelock');
388
+ equal(incoming.transaction_id, fundingTxId, 'Funding tx id is correct');
389
+ equal(incoming.transaction_vout, fundingTxVout, 'Funding vout is correct');
390
+
391
+ // Setup the combined signed PSBTs that fund the channel
392
+ const combinedTempPsbt = combinePsbts({
393
+ ecp,
394
+ psbts: [
395
+ controlSignSpendingPsbt,
396
+ targetSignSpendingPsbt,
397
+ ].map(n => n.psbt),
398
+ });
399
+
400
+ // Finalize the combined PSBT
401
+ const finalTempPsbt = finalizePsbt({ecp, psbt: combinedTempPsbt.psbt});
402
+
403
+ // Pull out the signed broadcast-ready transaction from the PSBT
404
+ const finalTempTx = extractTransaction({ecp, psbt: finalTempPsbt.psbt});
405
+
406
+ // Calculate the size of the tx
407
+ const txSize = fromHex(finalTempTx.transaction).virtualSize();
408
+
409
+ equal(txSize <= fundingFee, true, 'Transaction size is not too large');
410
+
411
+ // Broadcast the transaction to fund the control side
412
+ await broadcastChainTransaction({
413
+ lnd,
414
+ transaction: controlSignPsbt.transaction,
415
+ });
416
+
417
+ // Broadcast the transaction to fund the target side
418
+ await broadcastChainTransaction({
419
+ lnd,
420
+ transaction: targetSignPsbt.transaction,
421
+ });
422
+
423
+ // Broadcast the transaction to fund the channel
424
+ await broadcastChainTransaction({
425
+ lnd,
426
+ transaction: finalTempTx.transaction,
427
+ });
428
+
429
+ // Mine the funding transactions into a block
430
+ await asyncRetry({interval, times}, async () => {
431
+ await control.generate({});
432
+
433
+ const {channels} = await getChannels({lnd});
434
+
435
+ if (!channels.find(n => n.is_active)) {
436
+ throw new Error('ExpectedActiveChannel');
437
+ }
438
+
439
+ return;
440
+ });
441
+
442
+ const controlChannels = await getChannels({lnd});
443
+
444
+ const [controlChannel] = controlChannels.channels;
445
+
446
+ const closeAddr = coopCloseAddress.address;
447
+
448
+ // LND 0.11.1 and before do not use anchor channels
449
+ if (isAnchors) {
450
+ equal(controlChannel.commit_transaction_fee, 2810, 'Regular tx fee');
451
+ equal(controlChannel.commit_transaction_weight, 1116, 'Regular tx size');
452
+ } else {
453
+ equal(controlChannel.commit_transaction_fee, 9050, 'Regular tx fee');
454
+ equal(controlChannel.commit_transaction_weight, 724, 'Regular tx size');
455
+ }
433
456
 
434
- // LND 0.11.1 and before do not use anchor channels
435
- if (isAnchors) {
436
- equal(controlChannel.commit_transaction_fee, 2810, 'Regular tx fee');
437
- equal(controlChannel.commit_transaction_weight, 1116, 'Regular tx size');
438
- } else {
439
- equal(controlChannel.commit_transaction_fee, 9050, 'Regular tx fee');
440
- equal(controlChannel.commit_transaction_weight, 724, 'Regular tx size');
441
- }
457
+ equal(controlChannel.capacity, capacity, 'Channel with capacity created');
458
+ equal(controlChannel.cooperative_close_address, closeAddr, 'Got addr');
459
+ equal(!!controlChannel.cooperative_close_delay_height, true, 'Thaw');
460
+ equal(!!controlChannel.id, true, 'Got channel id');
461
+ equal(controlChannel.is_active, true, 'Channel is active and ready');
462
+ equal(controlChannel.is_closing, false, 'Channel is not closing');
463
+ equal(controlChannel.is_opening, false, 'Channel is already opened');
464
+ equal(controlChannel.is_partner_initiated, false, 'Control opened');
465
+ equal(controlChannel.is_private, true, 'Channel is private');
466
+ equal(controlChannel.local_balance, incoming.remote_balance, 'Control');
467
+ equal(controlChannel.local_csv, 144, 'Channel CSV');
468
+ ok(controlChannel.local_dust >= 354, 'Channel dust');
469
+ equal(controlChannel.local_given, giveTokens, 'Channel tokens given over');
470
+ equal(controlChannel.local_max_htlcs, 483, 'Channel HTLCs max set');
471
+ equal(controlChannel.partner_public_key, target.id, 'R-key');
472
+ equal(controlChannel.transaction_id, fundingTxId, 'Funding tx id');
473
+ equal(controlChannel.transaction_vout, fundingTxVout, 'Funding tx vout');
474
+
475
+ const targetChannels = await getChannels({lnd: target.lnd});
476
+
477
+ const [targetChannel] = targetChannels.channels;
478
+
479
+ // LND 0.11.1 and before do not use anchor channels
480
+ if (isAnchors) {
481
+ equal(targetChannel.commit_transaction_fee, 2810, 'Regular tx fee');
482
+ equal(targetChannel.commit_transaction_weight, 1116, 'Regular tx size');
483
+ } else {
484
+ equal(targetChannel.commit_transaction_fee, 9050, 'Regular tx fee');
485
+ equal(targetChannel.commit_transaction_weight, 724, 'Regular tx size');
486
+ }
442
487
 
443
- equal(controlChannel.capacity, capacity, 'Channel with capacity created');
444
- equal(controlChannel.cooperative_close_address, closeAddr, 'Got closeaddr');
445
- equal(!!controlChannel.cooperative_close_delay_height, true, 'Thaw height');
446
- equal(!!controlChannel.id, true, 'Got channel id');
447
- equal(controlChannel.is_active, true, 'Channel is active and ready');
448
- equal(controlChannel.is_closing, false, 'Channel is not closing');
449
- equal(controlChannel.is_opening, false, 'Channel is already opened');
450
- equal(controlChannel.is_partner_initiated, false, 'Control opened');
451
- equal(controlChannel.is_private, true, 'Channel is private');
452
- equal(controlChannel.local_balance, incoming.remote_balance, 'Control tok');
453
- equal(controlChannel.local_csv, 144, 'Channel CSV');
454
- ok(controlChannel.local_dust >= 354, 'Channel dust');
455
- equal(controlChannel.local_given, giveTokens, 'Channel tokens given over');
456
- equal(controlChannel.local_max_htlcs, 483, 'Channel HTLCs max set');
457
- equal(controlChannel.partner_public_key, target.id, 'R-key');
458
- equal(controlChannel.transaction_id, fundingTxId, 'Funding tx id');
459
- equal(controlChannel.transaction_vout, fundingTxVout, 'Funding tx vout');
460
-
461
- const targetChannels = await getChannels({lnd: target.lnd});
462
-
463
- const [targetChannel] = targetChannels.channels;
464
-
465
- // LND 0.11.1 and before do not use anchor channels
466
- if (isAnchors) {
467
- equal(targetChannel.commit_transaction_fee, 2810, 'Regular tx commit fee');
468
- equal(targetChannel.commit_transaction_weight, 1116, 'Regular tx size');
469
- } else {
470
- equal(targetChannel.commit_transaction_fee, 9050, 'Regular tx commit fee');
471
- equal(targetChannel.commit_transaction_weight, 724, 'Regular tx size');
488
+ equal(targetChannel.capacity, capacity, 'Channel with capacity created');
489
+ equal(targetChannel.cooperative_close_address, undefined, 'No close addr');
490
+ equal(!!targetChannel.cooperative_close_delay_height, true, 'Thaw height');
491
+ equal(!!targetChannel.id, true, 'Got channel id');
492
+ equal(targetChannel.is_active, true, 'Channel is active and ready');
493
+ equal(targetChannel.is_closing, false, 'Channel is not closing');
494
+ equal(targetChannel.is_opening, false, 'Channel is already opened');
495
+ equal(targetChannel.is_partner_initiated, true, 'Control opened');
496
+ equal(targetChannel.is_private, true, 'Channel is private');
497
+ equal(targetChannel.local_balance, giveTokens, 'Target tokens');
498
+ equal(targetChannel.local_csv, 144, 'Channel CSV');
499
+ ok(targetChannel.local_dust >= 354, 'Channel dust');
500
+ equal(targetChannel.local_given, 0, 'No tokens given');
501
+ equal(targetChannel.local_max_htlcs, 483, 'Channel HTLCs max set');
502
+ equal(targetChannel.partner_public_key, control.id, 'R-key');
503
+ equal(targetChannel.transaction_id, fundingTxId, 'Funding tx id');
504
+ equal(targetChannel.transaction_vout, fundingTxVout, 'Funding tx vout');
505
+ } catch (err) {
506
+ equal(err, null, 'Expected no error');
507
+ } finally {
508
+ await kill({});
472
509
  }
473
510
 
474
- equal(targetChannel.capacity, capacity, 'Channel with capacity created');
475
- equal(targetChannel.cooperative_close_address, undefined, 'No close addr');
476
- equal(!!targetChannel.cooperative_close_delay_height, true, 'Thaw height');
477
- equal(!!targetChannel.id, true, 'Got channel id');
478
- equal(targetChannel.is_active, true, 'Channel is active and ready');
479
- equal(targetChannel.is_closing, false, 'Channel is not closing');
480
- equal(targetChannel.is_opening, false, 'Channel is already opened');
481
- equal(targetChannel.is_partner_initiated, true, 'Control opened');
482
- equal(targetChannel.is_private, true, 'Channel is private');
483
- equal(targetChannel.local_balance, giveTokens, 'Target tokens');
484
- equal(targetChannel.local_csv, 144, 'Channel CSV');
485
- ok(targetChannel.local_dust >= 354, 'Channel dust');
486
- equal(targetChannel.local_given, 0, 'No tokens given');
487
- equal(targetChannel.local_max_htlcs, 483, 'Channel HTLCs max set');
488
- equal(targetChannel.partner_public_key, control.id, 'R-key');
489
- equal(targetChannel.transaction_id, fundingTxId, 'Funding tx id');
490
- equal(targetChannel.transaction_vout, fundingTxVout, 'Funding tx vout');
491
-
492
- await kill({});
493
-
494
511
  return end();
495
512
  });