ln-service 59.5.0 → 59.7.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 +16 -0
- package/README.md +93 -9
- package/package.json +7 -2
- package/.gitattributes +0 -1
- package/.tm_properties +0 -1
- package/test/autopilotrpc-integration/test_autopilot.js +0 -87
- package/test/chainrpc-integration/test_get_block.js +0 -58
- package/test/chainrpc-integration/test_get_block_header.js +0 -62
- package/test/chainrpc-integration/test_get_height.js +0 -42
- package/test/chainrpc-integration/test_subscribe_to_blocks.js +0 -97
- package/test/chainrpc-integration/test_subscribe_to_chain_address.js +0 -119
- package/test/chainrpc-integration/test_subscribe_to_chain_spend.js +0 -116
- package/test/integration/test_add_peer.js +0 -59
- package/test/integration/test_cancel_pending_channel.js +0 -46
- package/test/integration/test_close_channel.js +0 -60
- package/test/integration/test_close_wait_pending.js +0 -121
- package/test/integration/test_create_chain_address.js +0 -63
- package/test/integration/test_create_invoice.js +0 -49
- package/test/integration/test_decode_payment_request.js +0 -75
- package/test/integration/test_delete_payment.js +0 -38
- package/test/integration/test_delete_payments.js +0 -42
- package/test/integration/test_delete_pending_channel.js +0 -202
- package/test/integration/test_encrypted_routes.js +0 -162
- package/test/integration/test_get_access_ids.js +0 -27
- package/test/integration/test_get_backup.js +0 -40
- package/test/integration/test_get_backups.js +0 -38
- package/test/integration/test_get_chain_balance.js +0 -36
- package/test/integration/test_get_chain_fee_estimate.js +0 -63
- package/test/integration/test_get_chain_transactions.js +0 -83
- package/test/integration/test_get_channel.js +0 -64
- package/test/integration/test_get_channel_balance.js +0 -23
- package/test/integration/test_get_channels.js +0 -84
- package/test/integration/test_get_closed_channels.js +0 -275
- package/test/integration/test_get_configuration.js +0 -35
- package/test/integration/test_get_failed_payments.js +0 -164
- package/test/integration/test_get_fee_rates.js +0 -40
- package/test/integration/test_get_forwards.js +0 -144
- package/test/integration/test_get_invoice.js +0 -67
- package/test/integration/test_get_invoices.js +0 -88
- package/test/integration/test_get_methods.js +0 -30
- package/test/integration/test_get_network_centrality.js +0 -72
- package/test/integration/test_get_network_graph.js +0 -87
- package/test/integration/test_get_network_info.js +0 -33
- package/test/integration/test_get_node.js +0 -117
- package/test/integration/test_get_payments.js +0 -69
- package/test/integration/test_get_peers.js +0 -58
- package/test/integration/test_get_pending_coop.js +0 -122
- package/test/integration/test_get_pending_force.js +0 -172
- package/test/integration/test_get_pending_payments.js +0 -86
- package/test/integration/test_get_route_to_destination.js +0 -153
- package/test/integration/test_get_settlement_status.js +0 -78
- package/test/integration/test_get_utxos.js +0 -49
- package/test/integration/test_get_wallet_info.js +0 -55
- package/test/integration/test_grant_access.js +0 -69
- package/test/integration/test_open_channel.js +0 -93
- package/test/integration/test_open_channel_max.js +0 -92
- package/test/integration/test_open_channels.js +0 -164
- package/test/integration/test_open_low_reserve.js +0 -92
- package/test/integration/test_open_simplified_taproot.js +0 -174
- package/test/integration/test_open_standard_taproot.js +0 -94
- package/test/integration/test_pay.js +0 -149
- package/test/integration/test_pay_private_invoice.js +0 -120
- package/test/integration/test_payment_errors.js +0 -102
- package/test/integration/test_propose_channel.js +0 -474
- package/test/integration/test_push_funds.js +0 -82
- package/test/integration/test_rebalance.js +0 -70
- package/test/integration/test_recover_funds_from_channel.js +0 -207
- package/test/integration/test_recover_funds_from_channels.js +0 -203
- package/test/integration/test_remove_peer.js +0 -52
- package/test/integration/test_restrict_macaroon.js +0 -96
- package/test/integration/test_revoke_access.js +0 -41
- package/test/integration/test_send_message_to_peer.js +0 -91
- package/test/integration/test_send_to_chain_address.js +0 -109
- package/test/integration/test_send_to_chain_addresses.js +0 -71
- package/test/integration/test_sign_message.js +0 -22
- package/test/integration/test_stop_daemon.js +0 -33
- package/test/integration/test_subscribe_to_backups.js +0 -94
- package/test/integration/test_subscribe_to_channels.js +0 -186
- package/test/integration/test_subscribe_to_graph.js +0 -176
- package/test/integration/test_subscribe_to_invoices.js +0 -147
- package/test/integration/test_subscribe_to_messages.js +0 -180
- package/test/integration/test_subscribe_to_open_requests.js +0 -167
- package/test/integration/test_subscribe_to_peer_messages.js +0 -130
- package/test/integration/test_subscribe_to_peers.js +0 -61
- package/test/integration/test_subscribe_to_rpc_requests.js +0 -309
- package/test/integration/test_subscribe_to_transactions.js +0 -93
- package/test/integration/test_trusted_funding.js +0 -302
- package/test/integration/test_trusted_open.js +0 -94
- package/test/integration/test_update_routing_fees.js +0 -108
- package/test/integration/test_verify_access.js +0 -38
- package/test/integration/test_verify_backup.js +0 -53
- package/test/integration/test_verify_backups.js +0 -54
- package/test/integration/test_verify_message.js +0 -24
- package/test/invoicesrpc-integration/test_cancel_invoice.js +0 -91
- package/test/invoicesrpc-integration/test_create_hinted_invoice.js +0 -95
- package/test/invoicesrpc-integration/test_get_sweep_transactions.js +0 -124
- package/test/invoicesrpc-integration/test_push_payment.js +0 -92
- package/test/invoicesrpc-integration/test_settle_invoice.js +0 -136
- package/test/invoicesrpc-integration/test_subscribe_cancel_invoice.js +0 -124
- package/test/invoicesrpc-integration/test_subscribe_settle_invoice.js +0 -123
- package/test/macros/index.js +0 -19
- package/test/macros/setup_channel.js +0 -101
- package/test/macros/wait_for_channel.js +0 -99
- package/test/macros/wait_for_pending_channel.js +0 -52
- package/test/macros/wait_for_route.js +0 -76
- package/test/macros/wait_for_termination.js +0 -29
- package/test/macros/wait_for_utxo.js +0 -56
- package/test/peersrpc-integration/test_add_advertised_feature.js +0 -43
- package/test/peersrpc-integration/test_add_external_socket.js +0 -36
- package/test/peersrpc-integration/test_remove_advertised_feature.js +0 -37
- package/test/peersrpc-integration/test_remove_external_socket.js +0 -34
- package/test/peersrpc-integration/test_update_alias.js +0 -33
- package/test/peersrpc-integration/test_update_color.js +0 -33
- package/test/routerrpc-integration/test_delete_forwarding_reputations.js +0 -101
- package/test/routerrpc-integration/test_disable_channel.js +0 -41
- package/test/routerrpc-integration/test_get_forwarding_confidence.js +0 -90
- package/test/routerrpc-integration/test_get_forwarding_reputations.js +0 -128
- package/test/routerrpc-integration/test_get_pathfinding_settings.js +0 -40
- package/test/routerrpc-integration/test_get_payment.js +0 -130
- package/test/routerrpc-integration/test_get_route_confidence.js +0 -77
- package/test/routerrpc-integration/test_get_route_through_hops.js +0 -148
- package/test/routerrpc-integration/test_get_routing_fee_estimate.js +0 -76
- package/test/routerrpc-integration/test_is_destination_payable.js +0 -53
- package/test/routerrpc-integration/test_multipath_payment.js +0 -178
- package/test/routerrpc-integration/test_pay_via_payment_details.js +0 -175
- package/test/routerrpc-integration/test_pay_via_payment_request.js +0 -151
- package/test/routerrpc-integration/test_pay_via_routes.js +0 -224
- package/test/routerrpc-integration/test_probe_for_route.js +0 -153
- package/test/routerrpc-integration/test_route_from_channels_complex.js +0 -327
- package/test/routerrpc-integration/test_route_from_channels_simple.js +0 -151
- package/test/routerrpc-integration/test_subscribe_to_forward_requests.js +0 -225
- package/test/routerrpc-integration/test_subscribe_to_forwards.js +0 -552
- package/test/routerrpc-integration/test_subscribe_to_past_payments.js +0 -81
- package/test/routerrpc-integration/test_subscribe_to_payments.js +0 -115
- package/test/routerrpc-integration/test_update_pathfinding_settings.js +0 -71
- package/test/runner.js +0 -30
- package/test/signerrpc-integration/test_begin_group_signing_session.js +0 -505
- package/test/signerrpc-integration/test_diffie_hellman_compute_secret.js +0 -37
- package/test/signerrpc-integration/test_sign_bytes.js +0 -76
- package/test/signerrpc-integration/test_sign_taproot.js +0 -436
- package/test/signerrpc-integration/test_sign_transaction.js +0 -35
- package/test/signerrpc-integration/test_verify_bytes_signature.js +0 -103
- package/test/tower_clientrpc-integration/test_connect_watchtower.js +0 -60
- package/test/tower_clientrpc-integration/test_get_connected_watchtowers.js +0 -70
- package/test/tower_serverrpc-integration/test_get_tower_server_info.js +0 -34
- package/test/versionrpc-integration/test_get_wallet_version.js +0 -38
- package/test/walletrpc-integration/test_broadcast_chain_transaction.js +0 -62
- package/test/walletrpc-integration/test_create_funded_psbt.js +0 -141
- package/test/walletrpc-integration/test_delete_chain_transaction.js +0 -82
- package/test/walletrpc-integration/test_fund_psbt.js +0 -489
- package/test/walletrpc-integration/test_get_chain_addresses.js +0 -60
- package/test/walletrpc-integration/test_get_chain_fee_rate.js +0 -24
- package/test/walletrpc-integration/test_get_chain_transaction.js +0 -70
- package/test/walletrpc-integration/test_get_locked_utxos.js +0 -67
- package/test/walletrpc-integration/test_get_master_public_keys.js +0 -84
- package/test/walletrpc-integration/test_get_minimum_relay_fee.js +0 -26
- package/test/walletrpc-integration/test_get_pending_sweeps.js +0 -83
- package/test/walletrpc-integration/test_get_public_key.js +0 -28
- package/test/walletrpc-integration/test_lock_utxo.js +0 -80
- package/test/walletrpc-integration/test_partially_sign_psbt.js +0 -224
- package/test/walletrpc-integration/test_request_batched_fee_increase.js +0 -60
- package/test/walletrpc-integration/test_request_chain_fee_increase.js +0 -63
- package/test/walletrpc-integration/test_send_to_chain_output_scripts.js +0 -69
- package/test/walletrpc-integration/test_sign_chain_address_message.js +0 -32
- package/test/walletrpc-integration/test_sign_psbt.js +0 -108
- package/test/walletrpc-integration/test_unlock_utxo.js +0 -72
- package/test/walletrpc-integration/test_update_chain_transaction.js +0 -43
- package/test/walletrpc-integration/test_verify_chain_address_message.js +0 -60
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
const {strictEqual} = require('node:assert').strict;
|
|
2
|
-
const test = require('node:test');
|
|
3
|
-
|
|
4
|
-
const {spawnLightningCluster} = require('ln-docker-daemons');
|
|
5
|
-
|
|
6
|
-
const {createInvoice} = require('./../../');
|
|
7
|
-
const {parsePaymentRequest} = require('./../../');
|
|
8
|
-
|
|
9
|
-
const count = 100;
|
|
10
|
-
|
|
11
|
-
// createInvoice should result in a created invoice
|
|
12
|
-
test(`Create an invoice`, async () => {
|
|
13
|
-
const [{generate, kill, lnd}] = (await spawnLightningCluster({})).nodes;
|
|
14
|
-
|
|
15
|
-
await generate({count});
|
|
16
|
-
|
|
17
|
-
try {
|
|
18
|
-
const invoice = await createInvoice({lnd});
|
|
19
|
-
|
|
20
|
-
const parsed = parsePaymentRequest({request: invoice.request});
|
|
21
|
-
|
|
22
|
-
strictEqual(invoice.chain_address, undefined, 'Address is undefined');
|
|
23
|
-
strictEqual(invoice.created_at, parsed.created_at, 'Invoice created date');
|
|
24
|
-
strictEqual(invoice.description, undefined, 'Description undefined');
|
|
25
|
-
strictEqual(invoice.id, parsed.id, 'Invoice has id');
|
|
26
|
-
strictEqual(invoice.mtokens, '0', 'Default mtokens are 0');
|
|
27
|
-
strictEqual(!!invoice.request, true, 'Invoice has request');
|
|
28
|
-
strictEqual(!!invoice.secret, true, 'Invoice returns secret');
|
|
29
|
-
strictEqual(invoice.tokens, 0, 'Default tokens are 0');
|
|
30
|
-
|
|
31
|
-
try {
|
|
32
|
-
const duplicate = await createInvoice({lnd, secret: invoice.secret});
|
|
33
|
-
|
|
34
|
-
equal(duplicate, null, 'Expected no duplicate invoice');
|
|
35
|
-
} catch (err) {
|
|
36
|
-
const [code, message] = err;
|
|
37
|
-
|
|
38
|
-
strictEqual(code, 409, 'Got expected error code');
|
|
39
|
-
strictEqual(message, 'InvoiceWithGivenHashAlreadyExists', 'Got msg');
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
} catch (err) {
|
|
43
|
-
strictEqual(err, null, 'Expected no error in create invoice');
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
await kill({});
|
|
47
|
-
|
|
48
|
-
return;
|
|
49
|
-
});
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
const {strictEqual} = require('node:assert').strict;
|
|
2
|
-
const test = require('node:test');
|
|
3
|
-
|
|
4
|
-
const asyncRetry = require('async/retry');
|
|
5
|
-
const {spawnLightningCluster} = require('ln-docker-daemons');
|
|
6
|
-
|
|
7
|
-
const {createInvoice} = require('./../../');
|
|
8
|
-
const {decodePaymentRequest} = require('./../../');
|
|
9
|
-
const {getIdentity} = require('./../../');
|
|
10
|
-
const {getWalletInfo} = require('./../../');
|
|
11
|
-
|
|
12
|
-
const interval = 50;
|
|
13
|
-
const times = 4000;
|
|
14
|
-
|
|
15
|
-
const tests = [
|
|
16
|
-
{
|
|
17
|
-
description: "Test invoice",
|
|
18
|
-
expected: {
|
|
19
|
-
cltv_delta: 99,
|
|
20
|
-
description: 'Read: Global Cryptocurrency Regulation',
|
|
21
|
-
id: '7426ba0604c3f8682c7016b44673f85c5bd9da2fa6c1080810cf53ae320c9863',
|
|
22
|
-
mtokens: '150000',
|
|
23
|
-
secret: '000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f',
|
|
24
|
-
safe_tokens: 150,
|
|
25
|
-
tokens: 150,
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
];
|
|
29
|
-
|
|
30
|
-
tests.forEach(({description, expected}) => {
|
|
31
|
-
return test(description, async () => {
|
|
32
|
-
const [{generate, kill, lnd}] = (await spawnLightningCluster({})).nodes;
|
|
33
|
-
|
|
34
|
-
await asyncRetry({interval, times}, async () => {
|
|
35
|
-
const wallet = await getWalletInfo({lnd});
|
|
36
|
-
|
|
37
|
-
await generate({});
|
|
38
|
-
|
|
39
|
-
if (!wallet.is_synced_to_chain) {
|
|
40
|
-
throw new Error('NotSyncedToChain');
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
try {
|
|
45
|
-
const {request} = await createInvoice({
|
|
46
|
-
lnd,
|
|
47
|
-
cltv_delta: expected.cltv_delta,
|
|
48
|
-
description: expected.description,
|
|
49
|
-
secret: expected.secret,
|
|
50
|
-
tokens: expected.tokens,
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
const decoded = await decodePaymentRequest({lnd, request});
|
|
54
|
-
const identity = (await getIdentity({lnd})).public_key;
|
|
55
|
-
|
|
56
|
-
strictEqual(decoded.chain_addresses, expected.chain_addresses, 'Addr');
|
|
57
|
-
strictEqual(decoded.cltv_delta, expected.cltv_delta, 'Decode cltv');
|
|
58
|
-
strictEqual(!!decoded.created_at, true, 'Created at date');
|
|
59
|
-
strictEqual(decoded.description, expected.description, 'Decode desc');
|
|
60
|
-
strictEqual(decoded.description_hash, expected.description_hash, 'Hash');
|
|
61
|
-
strictEqual(decoded.destination, identity, 'Got public key');
|
|
62
|
-
strictEqual(!!decoded.expires_at, true, 'Expiration date decoded');
|
|
63
|
-
strictEqual(decoded.id, expected.id, 'Decoded payment hash');
|
|
64
|
-
strictEqual(decoded.mtokens, expected.mtokens, 'Decode millitokens');
|
|
65
|
-
strictEqual(decoded.safe_tokens, expected.safe_tokens, 'Safe amount');
|
|
66
|
-
strictEqual(decoded.tokens, expected.tokens, 'Decode tokens amount');
|
|
67
|
-
} catch (err) {
|
|
68
|
-
strictEqual(err, null, 'Expected no error');
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
await kill({});
|
|
72
|
-
|
|
73
|
-
return;
|
|
74
|
-
});
|
|
75
|
-
});
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
const {strictEqual} = require('node:assert').strict;
|
|
2
|
-
const test = require('node:test');
|
|
3
|
-
|
|
4
|
-
const {setupChannel} = require('ln-docker-daemons');
|
|
5
|
-
const {spawnLightningCluster} = require('ln-docker-daemons');
|
|
6
|
-
|
|
7
|
-
const {createInvoice} = require('./../../');
|
|
8
|
-
const {deletePayment} = require('./../../');
|
|
9
|
-
const {getPayments} = require('./../../');
|
|
10
|
-
const {pay} = require('./../../');
|
|
11
|
-
|
|
12
|
-
const size = 2;
|
|
13
|
-
const tokens = 100;
|
|
14
|
-
|
|
15
|
-
// Deleting a payment should delete the payment record
|
|
16
|
-
test('Delete payment', async () => {
|
|
17
|
-
const {kill, nodes} = await spawnLightningCluster({size});
|
|
18
|
-
|
|
19
|
-
const [{generate, lnd}, target] = nodes;
|
|
20
|
-
|
|
21
|
-
await setupChannel({generate, lnd, to: target});
|
|
22
|
-
|
|
23
|
-
const invoice = await createInvoice({tokens, lnd: target.lnd});
|
|
24
|
-
|
|
25
|
-
const paid = await pay({lnd, request: invoice.request});
|
|
26
|
-
|
|
27
|
-
const priorLength = (await getPayments({lnd})).payments.length;
|
|
28
|
-
|
|
29
|
-
await deletePayment({lnd, id: invoice.id});
|
|
30
|
-
|
|
31
|
-
const wipedLength = (await getPayments({lnd})).payments.length;
|
|
32
|
-
|
|
33
|
-
strictEqual(priorLength - wipedLength, [paid].length, 'Payment deleted');
|
|
34
|
-
|
|
35
|
-
await kill({});
|
|
36
|
-
|
|
37
|
-
return;
|
|
38
|
-
});
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
const {strictEqual} = require('node:assert').strict;
|
|
2
|
-
const test = require('node:test');
|
|
3
|
-
|
|
4
|
-
const asyncRetry = require('async/retry');
|
|
5
|
-
const {setupChannel} = require('ln-docker-daemons');
|
|
6
|
-
const {spawnLightningCluster} = require('ln-docker-daemons');
|
|
7
|
-
|
|
8
|
-
const {createInvoice} = require('./../../');
|
|
9
|
-
const {deletePayments} = require('./../../');
|
|
10
|
-
const {getPayments} = require('./../../');
|
|
11
|
-
const {pay} = require('./../../');
|
|
12
|
-
|
|
13
|
-
const size = 2;
|
|
14
|
-
const times = 1000;
|
|
15
|
-
const tokens = 100;
|
|
16
|
-
|
|
17
|
-
// Deleting payments should delete all payments
|
|
18
|
-
test('Delete payments', async () => {
|
|
19
|
-
const {kill, nodes} = await spawnLightningCluster({size});
|
|
20
|
-
|
|
21
|
-
const [{generate, lnd}, target] = nodes;
|
|
22
|
-
|
|
23
|
-
await setupChannel({generate, lnd, to: target});
|
|
24
|
-
|
|
25
|
-
const invoice = await createInvoice({tokens, lnd: target.lnd});
|
|
26
|
-
|
|
27
|
-
const paid = await asyncRetry({times}, async () => {
|
|
28
|
-
return await pay({lnd, request: invoice.request});
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
const priorLength = (await getPayments({lnd})).payments.length;
|
|
32
|
-
|
|
33
|
-
await deletePayments({lnd});
|
|
34
|
-
|
|
35
|
-
const wipedLength = (await getPayments({lnd})).payments.length;
|
|
36
|
-
|
|
37
|
-
strictEqual(priorLength - wipedLength, [paid].length, 'History deleted');
|
|
38
|
-
|
|
39
|
-
await kill({});
|
|
40
|
-
|
|
41
|
-
return;
|
|
42
|
-
});
|
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
const {deepEqual} = require('node:assert').strict;
|
|
2
|
-
const test = require('node:test');
|
|
3
|
-
|
|
4
|
-
const asyncEach = require('async/each');
|
|
5
|
-
const asyncRetry = require('async/retry');
|
|
6
|
-
const asyncTimeout = require('async/timeout');
|
|
7
|
-
const {extractTransaction} = require('psbt');
|
|
8
|
-
const {spawnLightningCluster} = require('ln-docker-daemons');
|
|
9
|
-
const tinysecp = require('tiny-secp256k1');
|
|
10
|
-
|
|
11
|
-
const {addPeer} = require('./../../');
|
|
12
|
-
const {broadcastChainTransaction} = require('./../../');
|
|
13
|
-
const {cancelPendingChannel} = require('./../../');
|
|
14
|
-
const {deletePendingChannel} = require('./../../');
|
|
15
|
-
const {fundPendingChannels} = require('./../../');
|
|
16
|
-
const {fundPsbt} = require('./../../');
|
|
17
|
-
const {getChainBalance} = require('./../../');
|
|
18
|
-
const {getChannels} = require('./../../');
|
|
19
|
-
const {getLockedUtxos} = require('./../../');
|
|
20
|
-
const {getMasterPublicKeys} = require('./../../');
|
|
21
|
-
const {getPendingChannels} = require('./../../');
|
|
22
|
-
const {getWalletInfo} = require('./../../');
|
|
23
|
-
const {openChannels} = require('./../../');
|
|
24
|
-
const {signPsbt} = require('./../../');
|
|
25
|
-
const {unlockUtxo} = require('./../../');
|
|
26
|
-
|
|
27
|
-
const capacity = 1e6;
|
|
28
|
-
const count = 100;
|
|
29
|
-
const delay = n => new Promise(resolve => setTimeout(resolve, n));
|
|
30
|
-
const description = 'description';
|
|
31
|
-
const interval = 100;
|
|
32
|
-
const race = promises => Promise.race(promises);
|
|
33
|
-
const size = 3;
|
|
34
|
-
const timeout = 1000 * 20;
|
|
35
|
-
const times = 2000;
|
|
36
|
-
|
|
37
|
-
// Forfeiting a pending channel should remove the pending channel
|
|
38
|
-
test(`Forfeit pending channel`, async t => {
|
|
39
|
-
const ecp = (await import('ecpair')).ECPairFactory(tinysecp);
|
|
40
|
-
|
|
41
|
-
const {kill, nodes} = await spawnLightningCluster({size});
|
|
42
|
-
|
|
43
|
-
const [{generate, lnd}, target, remote] = nodes;
|
|
44
|
-
|
|
45
|
-
await asyncRetry({interval, times}, async () => {
|
|
46
|
-
const wallet = await getWalletInfo({lnd});
|
|
47
|
-
|
|
48
|
-
await generate({});
|
|
49
|
-
|
|
50
|
-
if (!wallet.is_synced_to_chain) {
|
|
51
|
-
throw new Error('NotSyncedToChain');
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
await generate({count});
|
|
56
|
-
|
|
57
|
-
await asyncEach([target, remote], async node => {
|
|
58
|
-
return await addPeer({lnd, public_key: node.id, socket: node.socket});
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
const channels = [{
|
|
62
|
-
capacity,
|
|
63
|
-
description,
|
|
64
|
-
is_private: true,
|
|
65
|
-
partner_public_key: target.id,
|
|
66
|
-
}];
|
|
67
|
-
|
|
68
|
-
// Propose a channel to target
|
|
69
|
-
const proposeToTarget = await asyncRetry({interval: 1000, times}, cbk => {
|
|
70
|
-
return asyncTimeout(openChannels, 1000 * 3)({
|
|
71
|
-
channels,
|
|
72
|
-
lnd,
|
|
73
|
-
is_avoiding_broadcast: true,
|
|
74
|
-
},
|
|
75
|
-
async (err, res) => {
|
|
76
|
-
await generate({});
|
|
77
|
-
|
|
78
|
-
await asyncEach([target, remote], async node => {
|
|
79
|
-
return await addPeer({lnd, public_key: node.id, socket: node.socket});
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
return cbk(err, res)
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
// Setup funding for the target
|
|
87
|
-
const fundTarget = await fundPsbt({lnd, outputs: proposeToTarget.pending});
|
|
88
|
-
|
|
89
|
-
// Sign the funding to the target
|
|
90
|
-
const signTarget = await signPsbt({lnd, psbt: fundTarget.psbt});
|
|
91
|
-
|
|
92
|
-
// Fund the target channel that will get stuck
|
|
93
|
-
await fundPendingChannels({
|
|
94
|
-
lnd,
|
|
95
|
-
channels: proposeToTarget.pending.map(n => n.id),
|
|
96
|
-
funding: signTarget.psbt,
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
await asyncEach((await getLockedUtxos({lnd})).utxos, async utxo => {
|
|
100
|
-
return await unlockUtxo({
|
|
101
|
-
lnd,
|
|
102
|
-
id: utxo.lock_id,
|
|
103
|
-
transaction_id: utxo.transaction_id,
|
|
104
|
-
transaction_vout: utxo.transaction_vout,
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
// Propose a channel to remote
|
|
109
|
-
const proposeToRemote = await asyncRetry({interval: 1000, times}, cbk => {
|
|
110
|
-
return asyncTimeout(openChannels, 1000 * 3)({
|
|
111
|
-
lnd,
|
|
112
|
-
channels: [{
|
|
113
|
-
capacity,
|
|
114
|
-
description,
|
|
115
|
-
is_private: true,
|
|
116
|
-
partner_public_key: remote.id,
|
|
117
|
-
}],
|
|
118
|
-
is_avoiding_broadcast: true,
|
|
119
|
-
},
|
|
120
|
-
cbk);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
// Setup funding for the remote, using the same inputs
|
|
124
|
-
const fundRemote = await fundPsbt({
|
|
125
|
-
lnd,
|
|
126
|
-
inputs: fundTarget.inputs,
|
|
127
|
-
outputs: proposeToRemote.pending
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
// Sign the funding to the target
|
|
131
|
-
const signRemote = await signPsbt({lnd, psbt: fundRemote.psbt});
|
|
132
|
-
|
|
133
|
-
// Fund the remote channel
|
|
134
|
-
await fundPendingChannels({
|
|
135
|
-
lnd,
|
|
136
|
-
channels: proposeToRemote.pending.map(n => n.id),
|
|
137
|
-
funding: signRemote.psbt,
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
await delay(2000);
|
|
141
|
-
|
|
142
|
-
const {transaction} = extractTransaction({ecp, psbt: signRemote.psbt});
|
|
143
|
-
|
|
144
|
-
await broadcastChainTransaction({lnd, transaction});
|
|
145
|
-
|
|
146
|
-
await generate({});
|
|
147
|
-
|
|
148
|
-
const channel = await asyncRetry({interval: 1000, times}, async () => {
|
|
149
|
-
const [channel] = (await getChannels({lnd})).channels;
|
|
150
|
-
|
|
151
|
-
// Exit early when the channel is created
|
|
152
|
-
if (!!channel) {
|
|
153
|
-
return channel;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
await broadcastChainTransaction({lnd, transaction});
|
|
157
|
-
|
|
158
|
-
await generate({});
|
|
159
|
-
|
|
160
|
-
throw new Error('ExpectedNewChannelCreated');
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
const [pending] = (await getPendingChannels({lnd})).pending_channels;
|
|
164
|
-
|
|
165
|
-
// Description is not supported in LND 0.16.4 or before
|
|
166
|
-
if (!!pending.description) {
|
|
167
|
-
deepEqual(pending.description, description, 'Got expected description');
|
|
168
|
-
deepEqual(pending.is_private, true, 'Got pending private status');
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
const stuckTx = extractTransaction({ecp, psbt: signTarget.psbt});
|
|
172
|
-
|
|
173
|
-
const [stuckPending] = proposeToTarget.pending;
|
|
174
|
-
|
|
175
|
-
// Try to cancel the pending channel, it will fail
|
|
176
|
-
try {
|
|
177
|
-
await cancelPendingChannel({lnd, id: stuckPending.id});
|
|
178
|
-
} catch (err) {
|
|
179
|
-
const [code] = err;
|
|
180
|
-
|
|
181
|
-
deepEqual(code, 503, 'Pending channel cannot be canceled');
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
try {
|
|
185
|
-
await deletePendingChannel({
|
|
186
|
-
lnd,
|
|
187
|
-
confirmed_transaction: transaction,
|
|
188
|
-
pending_transaction: stuckTx.transaction,
|
|
189
|
-
pending_transaction_vout: pending.transaction_vout,
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
const [notPending] = (await getPendingChannels({lnd})).pending_channels;
|
|
193
|
-
|
|
194
|
-
deepEqual(notPending, undefined, 'Conflicting pending deleted');
|
|
195
|
-
} catch (err) {
|
|
196
|
-
deepEqual(err, [501, 'DeletePendingChannelMethodNotSupported']);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
await kill({});
|
|
200
|
-
|
|
201
|
-
return;
|
|
202
|
-
});
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
const asyncRetry = require('async/retry');
|
|
2
|
-
const {equal} = require('node:assert').strict;
|
|
3
|
-
const {strictEqual} = require('node:assert').strict;
|
|
4
|
-
const test = require('node:test');
|
|
5
|
-
|
|
6
|
-
const {paymentPathFromChannels} = require('bolt04');
|
|
7
|
-
const {setupChannel} = require('ln-docker-daemons');
|
|
8
|
-
const {spawnLightningCluster} = require('ln-docker-daemons');
|
|
9
|
-
|
|
10
|
-
const {addPeer} = require('./../../');
|
|
11
|
-
const {createInvoice} = require('./../../');
|
|
12
|
-
const {createSignedRequest} = require('./../../');
|
|
13
|
-
const {createUnsignedRequest} = require('./../../');
|
|
14
|
-
const {decodePaymentRequest} = require('./../../');
|
|
15
|
-
const {getChannel} = require('./../../');
|
|
16
|
-
const {getHeight} = require('./../../');
|
|
17
|
-
const {getInvoice} = require('./../../');
|
|
18
|
-
const {getWalletInfo} = require('./../../');
|
|
19
|
-
const {parsePaymentRequest} = require('./../../');
|
|
20
|
-
const {pay} = require('./../../');
|
|
21
|
-
|
|
22
|
-
const count = 100;
|
|
23
|
-
const expiry = () => new Date(Date.now() + (4 * 60 * 60 * 1000)).toISOString();
|
|
24
|
-
const give = 500000;
|
|
25
|
-
const hopCount = 5;
|
|
26
|
-
const interval = 100;
|
|
27
|
-
const size = 3;
|
|
28
|
-
const times = 10000;
|
|
29
|
-
const tokens = 100;
|
|
30
|
-
|
|
31
|
-
// Paying to an encrypted routes invoice should result in a payment
|
|
32
|
-
test(`Create an encrypted routes invoice`, async () => {
|
|
33
|
-
const {kill, nodes} = await spawnLightningCluster({size});
|
|
34
|
-
|
|
35
|
-
const [{generate, lnd}, target, remote] = nodes;
|
|
36
|
-
|
|
37
|
-
await generate({count});
|
|
38
|
-
|
|
39
|
-
try {
|
|
40
|
-
const channel1 = await setupChannel({
|
|
41
|
-
generate,
|
|
42
|
-
lnd,
|
|
43
|
-
give_tokens: give,
|
|
44
|
-
to: target,
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
await addPeer({lnd, public_key: remote.id, socket: remote.socket});
|
|
48
|
-
|
|
49
|
-
const channel2 = await setupChannel({
|
|
50
|
-
generate: target.generate,
|
|
51
|
-
give_tokens: give,
|
|
52
|
-
lnd: target.lnd,
|
|
53
|
-
to: remote,
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
await asyncRetry({interval, times}, async () => {
|
|
57
|
-
await generate({});
|
|
58
|
-
|
|
59
|
-
const invoice = await createInvoice({
|
|
60
|
-
lnd,
|
|
61
|
-
tokens,
|
|
62
|
-
expires_at: expiry(),
|
|
63
|
-
is_encrypting_routes: true,
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
await addPeer({lnd, public_key: remote.id, socket: remote.socket});
|
|
67
|
-
|
|
68
|
-
await pay({lnd: remote.lnd, request: invoice.request});
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
// Try padded variations on encrypted routes
|
|
72
|
-
const remoteInvoice = await createInvoice({tokens, lnd: remote.lnd});
|
|
73
|
-
const targetInvoice = await createInvoice({tokens, lnd: target.lnd});
|
|
74
|
-
|
|
75
|
-
const remotePaymentDetails = parsePaymentRequest({
|
|
76
|
-
request: remoteInvoice.request,
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
const targetPaymentDetails = parsePaymentRequest({
|
|
80
|
-
request: targetInvoice.request,
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
const remoteHeight = await getHeight({lnd: remote.lnd});
|
|
84
|
-
const targetHeight = await getHeight({lnd: target.lnd});
|
|
85
|
-
|
|
86
|
-
// Paying to a direct peer but with dummy hops to hide that
|
|
87
|
-
const targetPath = paymentPathFromChannels({
|
|
88
|
-
channels: [],
|
|
89
|
-
cltv_delta: targetPaymentDetails.cltv_delta + 3,
|
|
90
|
-
destination: targetPaymentDetails.destination,
|
|
91
|
-
current_block_height: targetHeight.current_block_height,
|
|
92
|
-
hop_count: hopCount,
|
|
93
|
-
id: targetPaymentDetails.payment,
|
|
94
|
-
max_mtokens: targetPaymentDetails.mtokens,
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
// Paying to an indirect peer with a receiver fee added
|
|
98
|
-
const remotePath = paymentPathFromChannels({
|
|
99
|
-
channels: [await getChannel({lnd: remote.lnd, id: channel2.id})],
|
|
100
|
-
cltv_delta: remotePaymentDetails.cltv_delta + 3,
|
|
101
|
-
destination: remotePaymentDetails.destination,
|
|
102
|
-
current_block_height: remoteHeight.current_block_height,
|
|
103
|
-
hop_count: hopCount,
|
|
104
|
-
id: remotePaymentDetails.payment,
|
|
105
|
-
max_mtokens: remotePaymentDetails.mtokens,
|
|
106
|
-
receiver_base_fee_mtokens: '1000',
|
|
107
|
-
receiver_fee_rate: 10000,
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
equal(remotePath.hops.length, hopCount, 'Got expected hops for target');
|
|
111
|
-
equal(targetPath.hops.length, hopCount, 'Got expected hops for remote');
|
|
112
|
-
|
|
113
|
-
// Try paying a remote path
|
|
114
|
-
{
|
|
115
|
-
// Make a blinded version of the invoice
|
|
116
|
-
const {hrp, tags} = createUnsignedRequest({
|
|
117
|
-
description: remotePaymentDetails.description,
|
|
118
|
-
expires_at: remotePaymentDetails.expires_at,
|
|
119
|
-
features: [{bit: 8}, {bit: 15}, {bit: 24}, {bit: 262}],
|
|
120
|
-
id: remotePaymentDetails.id,
|
|
121
|
-
mtokens: remotePaymentDetails.mtokens,
|
|
122
|
-
network: 'regtest',
|
|
123
|
-
paths: [remotePath],
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
const request = createSignedRequest({hrp, tags}).request;
|
|
127
|
-
|
|
128
|
-
await pay({lnd, request});
|
|
129
|
-
|
|
130
|
-
const received = await getInvoice({
|
|
131
|
-
id: remotePaymentDetails.id,
|
|
132
|
-
lnd: remote.lnd,
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
equal(received.received_mtokens, '102001', 'Got receiver fee');
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// Try paying a peer path to target
|
|
139
|
-
{
|
|
140
|
-
// Make a blinded version of the invoice
|
|
141
|
-
const {hrp, tags} = createUnsignedRequest({
|
|
142
|
-
description: targetPaymentDetails.description,
|
|
143
|
-
expires_at: targetPaymentDetails.expires_at,
|
|
144
|
-
features: [{bit: 8}, {bit: 15}, {bit: 24}, {bit: 262}],
|
|
145
|
-
id: targetPaymentDetails.id,
|
|
146
|
-
mtokens: targetPaymentDetails.mtokens,
|
|
147
|
-
network: 'regtest',
|
|
148
|
-
paths: [targetPath],
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
await pay({lnd, request: createSignedRequest({hrp, tags}).request});
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
await kill({});
|
|
155
|
-
} catch (err) {
|
|
156
|
-
await kill({});
|
|
157
|
-
|
|
158
|
-
strictEqual(err, null, 'Expected no error in create invoice');
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
return;
|
|
162
|
-
});
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
const {deepStrictEqual} = require('node:assert').strict;
|
|
2
|
-
const test = require('node:test');
|
|
3
|
-
|
|
4
|
-
const {spawnLightningCluster} = require('ln-docker-daemons');
|
|
5
|
-
|
|
6
|
-
const {getAccessIds} = require('./../../');
|
|
7
|
-
const {grantAccess} = require('./../../');
|
|
8
|
-
|
|
9
|
-
const defaultId = '0';
|
|
10
|
-
const id = '1';
|
|
11
|
-
|
|
12
|
-
// Getting access ids should return root macaroon ids
|
|
13
|
-
test(`Get access ids`, async () => {
|
|
14
|
-
const {kill, nodes} = await spawnLightningCluster({});
|
|
15
|
-
|
|
16
|
-
const [{lnd}] = nodes;
|
|
17
|
-
|
|
18
|
-
await grantAccess({id, lnd, is_ok_to_create_chain_addresses: true});
|
|
19
|
-
|
|
20
|
-
const {ids} = await getAccessIds({lnd});
|
|
21
|
-
|
|
22
|
-
deepStrictEqual(ids, [defaultId, id], 'Got expected access ids');
|
|
23
|
-
|
|
24
|
-
await kill({});
|
|
25
|
-
|
|
26
|
-
return;
|
|
27
|
-
});
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
const {deepStrictEqual} = require('node:assert').strict;
|
|
2
|
-
const test = require('node:test');
|
|
3
|
-
|
|
4
|
-
const {setupChannel} = require('ln-docker-daemons');
|
|
5
|
-
const {spawnLightningCluster} = require('ln-docker-daemons');
|
|
6
|
-
|
|
7
|
-
const {getBackup} = require('./../../');
|
|
8
|
-
const {verifyBackup} = require('./../../');
|
|
9
|
-
|
|
10
|
-
const size = 2;
|
|
11
|
-
|
|
12
|
-
// Getting a channel backup should return a channel backup
|
|
13
|
-
test(`Get channel backup`, async () => {
|
|
14
|
-
const {kill, nodes} = await spawnLightningCluster({size});
|
|
15
|
-
|
|
16
|
-
const [{generate, lnd}, target] = nodes;
|
|
17
|
-
|
|
18
|
-
const channel = await setupChannel({generate, lnd, to: target});
|
|
19
|
-
|
|
20
|
-
const {backup} = await getBackup({
|
|
21
|
-
lnd,
|
|
22
|
-
transaction_id: channel.transaction_id,
|
|
23
|
-
transaction_vout: channel.transaction_vout,
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
deepStrictEqual(!!backup, true, 'Channel backup is returned');
|
|
27
|
-
|
|
28
|
-
const channelBackup = await verifyBackup({
|
|
29
|
-
backup,
|
|
30
|
-
lnd,
|
|
31
|
-
transaction_id: channel.transaction_id,
|
|
32
|
-
transaction_vout: channel.transaction_vout,
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
deepStrictEqual(channelBackup.is_valid, true, 'Is a valid backup');
|
|
36
|
-
|
|
37
|
-
await kill({});
|
|
38
|
-
|
|
39
|
-
return;
|
|
40
|
-
});
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
const {strictEqual} = require('node:assert').strict;
|
|
2
|
-
const test = require('node:test');
|
|
3
|
-
|
|
4
|
-
const asyncRetry = require('async/retry');
|
|
5
|
-
const {setupChannel} = require('ln-docker-daemons');
|
|
6
|
-
const {spawnLightningCluster} = require('ln-docker-daemons');
|
|
7
|
-
|
|
8
|
-
const {getBackups} = require('./../../');
|
|
9
|
-
|
|
10
|
-
const size = 2;
|
|
11
|
-
|
|
12
|
-
// Getting a set of channel backups should return channel backups
|
|
13
|
-
test(`Get channel backup`, async () => {
|
|
14
|
-
await asyncRetry({}, async () => {
|
|
15
|
-
const {kill, nodes} = await spawnLightningCluster({size});
|
|
16
|
-
|
|
17
|
-
const [{generate, lnd}, target] = nodes;
|
|
18
|
-
|
|
19
|
-
const channel = await setupChannel({generate, lnd, to: target});
|
|
20
|
-
|
|
21
|
-
const {backup, channels} = await getBackups({lnd});
|
|
22
|
-
|
|
23
|
-
strictEqual(!!backup, true, 'Multi-backup blob is returned');
|
|
24
|
-
strictEqual(channels.length, [channel].length, 'Individualized backup');
|
|
25
|
-
|
|
26
|
-
const [chanBackup] = channels;
|
|
27
|
-
|
|
28
|
-
strictEqual(!!chanBackup.backup.length, true, 'Channel backup has blob');
|
|
29
|
-
strictEqual(chanBackup.transaction_id, channel.transaction_id, 'Chan id');
|
|
30
|
-
strictEqual(chanBackup.transaction_vout, channel.transaction_vout, 'Vout');
|
|
31
|
-
|
|
32
|
-
await kill({});
|
|
33
|
-
|
|
34
|
-
return;
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
return;
|
|
38
|
-
});
|