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,164 +0,0 @@
|
|
|
1
|
-
const {strictEqual} = require('node:assert').strict;
|
|
2
|
-
const test = require('node:test');
|
|
3
|
-
|
|
4
|
-
const asyncMap = require('async/map');
|
|
5
|
-
const asyncRetry = require('async/retry');
|
|
6
|
-
const {extractTransaction} = require('psbt');
|
|
7
|
-
const {finalizePsbt} = require('psbt');
|
|
8
|
-
const {spawnLightningCluster} = require('ln-docker-daemons');
|
|
9
|
-
const tinysecp = require('tiny-secp256k1');
|
|
10
|
-
const {transactionAsPsbt} = require('psbt');
|
|
11
|
-
|
|
12
|
-
const {addPeer} = require('./../../');
|
|
13
|
-
const {createChainAddress} = require('./../../');
|
|
14
|
-
const {fundPendingChannels} = require('./../../');
|
|
15
|
-
const {getChainBalance} = require('./../../');
|
|
16
|
-
const {getChainTransactions} = require('./../../');
|
|
17
|
-
const {getChannel} = require('./../../');
|
|
18
|
-
const {getChannels} = require('./../../');
|
|
19
|
-
const {getHeight} = require('./../../');
|
|
20
|
-
const {getPeers} = require('./../../');
|
|
21
|
-
const {openChannels} = require('./../../');
|
|
22
|
-
const {sendToChainAddresses} = require('./../../');
|
|
23
|
-
|
|
24
|
-
const baseFeeMtokens = '1234';
|
|
25
|
-
const capacity = 1e6;
|
|
26
|
-
const count = 10;
|
|
27
|
-
const defaultBaseFee = '1000';
|
|
28
|
-
const interval = 20;
|
|
29
|
-
const feeRate = 56;
|
|
30
|
-
const maturity = 100;
|
|
31
|
-
const race = promises => Promise.race(promises);
|
|
32
|
-
const size = 3;
|
|
33
|
-
const timeout = 250 * 10;
|
|
34
|
-
const times = 2000;
|
|
35
|
-
|
|
36
|
-
// Opening channels should open up channels
|
|
37
|
-
test(`Open channels`, async () => {
|
|
38
|
-
const ecp = (await import('ecpair')).ECPairFactory(tinysecp);
|
|
39
|
-
|
|
40
|
-
const {kill, nodes} = await spawnLightningCluster({size});
|
|
41
|
-
|
|
42
|
-
const [{generate, lnd}, target, remote] = nodes;
|
|
43
|
-
|
|
44
|
-
try {
|
|
45
|
-
await generate({count: maturity});
|
|
46
|
-
|
|
47
|
-
await asyncRetry({interval, times}, async () => {
|
|
48
|
-
const lnds = [lnd, target.lnd, remote.lnd];
|
|
49
|
-
|
|
50
|
-
await generate({});
|
|
51
|
-
|
|
52
|
-
const heights = await asyncMap(lnds, async lnd => {
|
|
53
|
-
return (await getHeight({lnd})).current_block_height;
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
const [controlHeight, targetHeight, remoteHeight] = heights;
|
|
57
|
-
|
|
58
|
-
if (controlHeight !== targetHeight || controlHeight !== remoteHeight) {
|
|
59
|
-
throw new Error('ExpectedSyncHeights');
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
const chainTx = (await getChainTransactions({lnd})).transactions;
|
|
64
|
-
|
|
65
|
-
const spending = chainTx.map(({transaction}) => transaction);
|
|
66
|
-
|
|
67
|
-
const {address} = await createChainAddress({lnd});
|
|
68
|
-
|
|
69
|
-
const channels = [target, remote].map(({id}) => ({
|
|
70
|
-
capacity,
|
|
71
|
-
base_fee_mtokens: baseFeeMtokens,
|
|
72
|
-
cooperative_close_address: address,
|
|
73
|
-
fee_rate: feeRate,
|
|
74
|
-
partner_public_key: id,
|
|
75
|
-
}));
|
|
76
|
-
|
|
77
|
-
let pending;
|
|
78
|
-
|
|
79
|
-
// Wait for peers to be connected
|
|
80
|
-
await asyncRetry({interval, times}, async () => {
|
|
81
|
-
await addPeer({lnd, public_key: remote.id, socket: remote.socket});
|
|
82
|
-
await addPeer({lnd, public_key: target.id, socket: target.socket});
|
|
83
|
-
|
|
84
|
-
if ((await getPeers({lnd})).peers.length !== channels.length) {
|
|
85
|
-
throw new Error('ExpectedConnectedPeersToOpenChannels');
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
return;
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
await asyncRetry({interval, times}, async () => {
|
|
92
|
-
pending = (await openChannels({channels, lnd})).pending;
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
// Normally funding would involve an un-broadcast transaction
|
|
96
|
-
const {id} = await sendToChainAddresses({lnd, send_to: pending});
|
|
97
|
-
|
|
98
|
-
await asyncRetry({interval, times}, async () => {
|
|
99
|
-
const {transactions} = await getChainTransactions({lnd});
|
|
100
|
-
|
|
101
|
-
if (!transactions.find(n => n.id === id)) {
|
|
102
|
-
throw new Error('ExpectedChainTransaction');
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return;
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
const fundTx = (await getChainTransactions({lnd})).transactions
|
|
109
|
-
.map(({transaction}) => transaction)
|
|
110
|
-
.find(transaction => spending.find(spend => transaction !== spend));
|
|
111
|
-
|
|
112
|
-
const fundingPsbt = transactionAsPsbt({
|
|
113
|
-
ecp,
|
|
114
|
-
spending,
|
|
115
|
-
transaction: fundTx,
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
const {psbt} = finalizePsbt({ecp, psbt: fundingPsbt.psbt});
|
|
119
|
-
|
|
120
|
-
const reconstitutedTransaction = extractTransaction({ecp, psbt});
|
|
121
|
-
|
|
122
|
-
await fundPendingChannels({
|
|
123
|
-
lnd,
|
|
124
|
-
channels: pending.map(({id}) => id),
|
|
125
|
-
funding: psbt,
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
await asyncRetry({interval, times}, async () => {
|
|
129
|
-
await generate({});
|
|
130
|
-
|
|
131
|
-
const {channels} = await getChannels({lnd});
|
|
132
|
-
|
|
133
|
-
if (channels.filter(n => !!n.is_active).length !== pending.length) {
|
|
134
|
-
throw new Error('ExpectedNewChannelsCreatedAndActive');
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
const [channel] = channels;
|
|
138
|
-
|
|
139
|
-
strictEqual(channel.cooperative_close_address, address, 'Channel close');
|
|
140
|
-
|
|
141
|
-
const {policies} = await getChannel({lnd, id: channel.id});
|
|
142
|
-
|
|
143
|
-
const policy = policies.find(n => !!n.cltv_delta);
|
|
144
|
-
|
|
145
|
-
// LND 0.15.5 and below do not support setting fees on open
|
|
146
|
-
if (policy.base_fee_mtokens === defaultBaseFee) {
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
strictEqual(policy.base_fee_mtokens, baseFeeMtokens, 'Base fee is set');
|
|
151
|
-
strictEqual(policy.fee_rate, feeRate, 'Fee rate is set');
|
|
152
|
-
|
|
153
|
-
return;
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
await kill({});
|
|
157
|
-
} catch (err) {
|
|
158
|
-
await kill({});
|
|
159
|
-
|
|
160
|
-
strictEqual(err, null, 'No error is reported');
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
return;
|
|
164
|
-
});
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
const {equal} = 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 {addPeer} = require('./../../');
|
|
8
|
-
const {getChannels} = require('./../../');
|
|
9
|
-
const {getWalletInfo} = require('./../../');
|
|
10
|
-
const {openChannel} = require('./../../');
|
|
11
|
-
const {subscribeToOpenRequests} = require('./../../');
|
|
12
|
-
|
|
13
|
-
const channelCapacityTokens = 1e6;
|
|
14
|
-
const confirmationCount = 6;
|
|
15
|
-
const count = 100;
|
|
16
|
-
const dustLimit = 354;
|
|
17
|
-
const interval = 10;
|
|
18
|
-
const size = 2;
|
|
19
|
-
const times = 2000;
|
|
20
|
-
|
|
21
|
-
// Open a channel with a low channel reserve
|
|
22
|
-
test(`Open channel but allow a minimal channel reserve`, async () => {
|
|
23
|
-
const {kill, nodes} = await spawnLightningCluster({size});
|
|
24
|
-
|
|
25
|
-
const [control, target] = nodes;
|
|
26
|
-
|
|
27
|
-
const {id, lnd} = control;
|
|
28
|
-
|
|
29
|
-
await target.generate({count});
|
|
30
|
-
|
|
31
|
-
await addPeer({lnd, public_key: target.id, socket: target.socket});
|
|
32
|
-
|
|
33
|
-
await asyncRetry({interval, times}, async () => {
|
|
34
|
-
const wallet = await getWalletInfo({lnd: target.lnd});
|
|
35
|
-
|
|
36
|
-
if (!wallet.is_synced_to_chain) {
|
|
37
|
-
throw new Error('ExpectedWalletSyncedToChain');
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
const acceptSub = subscribeToOpenRequests({lnd});
|
|
42
|
-
|
|
43
|
-
acceptSub.on('channel_request', request => {
|
|
44
|
-
request.accept({
|
|
45
|
-
min_confirmations: 1,
|
|
46
|
-
remote_csv: 999,
|
|
47
|
-
remote_reserve: 354,
|
|
48
|
-
remote_max_htlcs: 20,
|
|
49
|
-
remote_max_pending_mtokens: '200000',
|
|
50
|
-
remote_min_htlc_mtokens: '2000',
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
return;
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
try {
|
|
57
|
-
await asyncRetry({interval, times}, async () => {
|
|
58
|
-
return await openChannel({
|
|
59
|
-
lnd: target.lnd,
|
|
60
|
-
is_private: true,
|
|
61
|
-
is_allowing_minimal_reserve: true,
|
|
62
|
-
local_tokens: channelCapacityTokens,
|
|
63
|
-
partner_public_key: control.id,
|
|
64
|
-
socket: control.socket,
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
} catch (err) {
|
|
68
|
-
equal(err, null, 'Expected no error when a channel is accepted');
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
acceptSub.removeAllListeners();
|
|
72
|
-
|
|
73
|
-
await target.generate({count: confirmationCount});
|
|
74
|
-
|
|
75
|
-
const channel = await asyncRetry({interval, times}, async () => {
|
|
76
|
-
const [channel] = (await getChannels({lnd})).channels;
|
|
77
|
-
|
|
78
|
-
await control.generate({});
|
|
79
|
-
|
|
80
|
-
if (!channel) {
|
|
81
|
-
throw new Error('ExpectedChannelCreation');
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return channel;
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
equal(channel.remote_reserve, dustLimit, 'Got minimal reserve value');
|
|
88
|
-
|
|
89
|
-
await kill({});
|
|
90
|
-
|
|
91
|
-
return;
|
|
92
|
-
});
|
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
const {equal} = 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 {addPeer} = require('./../../');
|
|
8
|
-
const {broadcastChainTransaction} = require('./../../');
|
|
9
|
-
const {fundPendingChannels} = require('./../../');
|
|
10
|
-
const {fundPsbt} = require('./../../');
|
|
11
|
-
const {getChannels} = require('./../../');
|
|
12
|
-
const {openChannel} = require('./../../');
|
|
13
|
-
const {openChannels} = require('./../../');
|
|
14
|
-
const {signPsbt} = require('./../../');
|
|
15
|
-
|
|
16
|
-
const channelCapacityTokens = 1e6;
|
|
17
|
-
const count = 100;
|
|
18
|
-
const defaultFee = 1e3;
|
|
19
|
-
const description = 'description';
|
|
20
|
-
const interval = 250;
|
|
21
|
-
const size = 2;
|
|
22
|
-
const times = 1000;
|
|
23
|
-
|
|
24
|
-
// Opening a simplified taproot channel should open a simple taproot channel
|
|
25
|
-
test(`Open simplified taproot channel`, async () => {
|
|
26
|
-
// Test for LND 0.16.4 or below to exit early and avoid test
|
|
27
|
-
{
|
|
28
|
-
const {kill, nodes} = await spawnLightningCluster({size});
|
|
29
|
-
|
|
30
|
-
const [{generate, id, lnd}, target] = nodes;
|
|
31
|
-
|
|
32
|
-
await generate({count});
|
|
33
|
-
|
|
34
|
-
const channelOpen = await asyncRetry({interval, times}, async () => {
|
|
35
|
-
await addPeer({lnd, public_key: target.id, socket: target.socket});
|
|
36
|
-
|
|
37
|
-
return await openChannel({
|
|
38
|
-
description,
|
|
39
|
-
lnd,
|
|
40
|
-
chain_fee_tokens_per_vbyte: defaultFee,
|
|
41
|
-
local_tokens: channelCapacityTokens,
|
|
42
|
-
partner_public_key: target.id,
|
|
43
|
-
socket: target.socket,
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
const channel = await asyncRetry({interval, times}, async () => {
|
|
48
|
-
await generate({});
|
|
49
|
-
|
|
50
|
-
const {channels} = await getChannels({lnd});
|
|
51
|
-
|
|
52
|
-
const [channel] = channels;
|
|
53
|
-
|
|
54
|
-
if (!channel) {
|
|
55
|
-
throw new Error('ExpectedChannelOpened');
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return channel;
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
await kill({});
|
|
62
|
-
|
|
63
|
-
// Exit early when on LND 0.16.4 that do not support simplified taproot
|
|
64
|
-
if (channel.description !== description) {
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Try opening a simplified taproot channel
|
|
70
|
-
{
|
|
71
|
-
const {kill, nodes} = await spawnLightningCluster({
|
|
72
|
-
size,
|
|
73
|
-
lnd_configuration: ['--protocol.simple-taproot-chans'],
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
const [{generate, id, lnd}, target] = nodes;
|
|
77
|
-
|
|
78
|
-
await generate({count});
|
|
79
|
-
|
|
80
|
-
await addPeer({lnd, public_key: target.id, socket: target.socket});
|
|
81
|
-
|
|
82
|
-
const channelOpen = await asyncRetry({interval, times}, async () => {
|
|
83
|
-
await addPeer({lnd, public_key: target.id, socket: target.socket});
|
|
84
|
-
|
|
85
|
-
return await openChannel({
|
|
86
|
-
lnd,
|
|
87
|
-
chain_fee_tokens_per_vbyte: defaultFee,
|
|
88
|
-
is_private: true,
|
|
89
|
-
is_simplified_taproot: true,
|
|
90
|
-
local_tokens: channelCapacityTokens,
|
|
91
|
-
partner_public_key: target.id,
|
|
92
|
-
socket: target.socket,
|
|
93
|
-
});
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
const channel = await asyncRetry({interval, times}, async () => {
|
|
97
|
-
await generate({});
|
|
98
|
-
|
|
99
|
-
const {channels} = await getChannels({lnd});
|
|
100
|
-
|
|
101
|
-
const [channel] = channels;
|
|
102
|
-
|
|
103
|
-
if (!channel) {
|
|
104
|
-
throw new Error('ExpectedChannelOpened');
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return channel;
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
equal(channel.type, 'simplified_taproot', 'Opened simplified taproot');
|
|
111
|
-
|
|
112
|
-
await kill({});
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// Try opening a simplified taproot channel via PSBT funding
|
|
116
|
-
{
|
|
117
|
-
const {kill, nodes} = await spawnLightningCluster({
|
|
118
|
-
size,
|
|
119
|
-
lnd_configuration: ['--protocol.simple-taproot-chans'],
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
const [{generate, id, lnd}, target] = nodes;
|
|
123
|
-
|
|
124
|
-
await generate({count});
|
|
125
|
-
|
|
126
|
-
await addPeer({lnd, public_key: target.id, socket: target.socket});
|
|
127
|
-
|
|
128
|
-
const channelOpen = await asyncRetry({interval, times}, async () => {
|
|
129
|
-
await addPeer({lnd, public_key: target.id, socket: target.socket});
|
|
130
|
-
|
|
131
|
-
return await openChannels({
|
|
132
|
-
lnd,
|
|
133
|
-
channels: [{
|
|
134
|
-
capacity: channelCapacityTokens,
|
|
135
|
-
is_private: true,
|
|
136
|
-
is_simplified_taproot: true,
|
|
137
|
-
partner_public_key: target.id,
|
|
138
|
-
}],
|
|
139
|
-
});
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
const funded = await fundPsbt({lnd, outputs: channelOpen.pending});
|
|
143
|
-
|
|
144
|
-
const signed = await signPsbt({lnd, psbt: funded.psbt});
|
|
145
|
-
|
|
146
|
-
await fundPendingChannels({
|
|
147
|
-
lnd,
|
|
148
|
-
channels: channelOpen.pending.map(n => n.id),
|
|
149
|
-
funding: signed.psbt,
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
await broadcastChainTransaction({lnd, transaction: signed.transaction});
|
|
153
|
-
|
|
154
|
-
const channel = await asyncRetry({interval, times}, async () => {
|
|
155
|
-
await generate({});
|
|
156
|
-
|
|
157
|
-
const {channels} = await getChannels({lnd});
|
|
158
|
-
|
|
159
|
-
const [channel] = channels;
|
|
160
|
-
|
|
161
|
-
if (!channel) {
|
|
162
|
-
throw new Error('ExpectedChannelOpened');
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
return channel;
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
equal(channel.type, 'simplified_taproot', 'Opened simplified taproot');
|
|
169
|
-
|
|
170
|
-
await kill({});
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
return;
|
|
174
|
-
});
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
const {equal} = 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 {addPeer} = require('./../../');
|
|
8
|
-
const {broadcastChainTransaction} = require('./../../');
|
|
9
|
-
const {fundPendingChannels} = require('./../../');
|
|
10
|
-
const {fundPsbt} = require('./../../');
|
|
11
|
-
const {getChannels} = require('./../../');
|
|
12
|
-
const {openChannel} = require('./../../');
|
|
13
|
-
const {openChannels} = require('./../../');
|
|
14
|
-
const {signPsbt} = require('./../../');
|
|
15
|
-
|
|
16
|
-
const channelCapacityTokens = 1e6;
|
|
17
|
-
const count = 100;
|
|
18
|
-
const defaultFee = 1e3;
|
|
19
|
-
const description = 'description';
|
|
20
|
-
const interval = 250;
|
|
21
|
-
const size = 2;
|
|
22
|
-
const times = 1000;
|
|
23
|
-
|
|
24
|
-
// Opening a standard taproot channel should open a standard taproot channel
|
|
25
|
-
test(`Open standard taproot channel`, async () => {
|
|
26
|
-
// Test for LND 0.20.0 or below to exit early and avoid test
|
|
27
|
-
{
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const {kill, nodes} = await spawnLightningCluster({
|
|
31
|
-
size,
|
|
32
|
-
lnd_configuration: ['--protocol.simple-taproot-chans'],
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
const [{generate, id, lnd}, target] = nodes;
|
|
36
|
-
|
|
37
|
-
// Try opening a standard taproot channel
|
|
38
|
-
try {
|
|
39
|
-
await generate({count});
|
|
40
|
-
|
|
41
|
-
await addPeer({lnd, public_key: target.id, socket: target.socket});
|
|
42
|
-
|
|
43
|
-
const channelOpen = await asyncRetry({interval, times}, async () => {
|
|
44
|
-
await addPeer({lnd, public_key: target.id, socket: target.socket});
|
|
45
|
-
|
|
46
|
-
try {
|
|
47
|
-
return await openChannel({
|
|
48
|
-
lnd,
|
|
49
|
-
chain_fee_tokens_per_vbyte: defaultFee,
|
|
50
|
-
is_private: true,
|
|
51
|
-
is_standard_taproot: true,
|
|
52
|
-
local_tokens: channelCapacityTokens,
|
|
53
|
-
partner_public_key: target.id,
|
|
54
|
-
socket: target.socket,
|
|
55
|
-
});
|
|
56
|
-
} catch (err) {
|
|
57
|
-
const [code, message, details] = err;
|
|
58
|
-
|
|
59
|
-
if (!!details && details.err === 'unhandled request channel type 7') {
|
|
60
|
-
return;
|
|
61
|
-
} else {
|
|
62
|
-
throw err;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
// Exit early when there is no support for standard taproot
|
|
68
|
-
if (!channelOpen) {
|
|
69
|
-
return await kill({});
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const channel = await asyncRetry({interval, times}, async () => {
|
|
73
|
-
await generate({});
|
|
74
|
-
|
|
75
|
-
const {channels} = await getChannels({lnd});
|
|
76
|
-
|
|
77
|
-
const [channel] = channels;
|
|
78
|
-
|
|
79
|
-
if (!channel) {
|
|
80
|
-
throw new Error('ExpectedChannelOpened');
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return channel;
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
equal(channel.type, 'standard_taproot', 'Opened standard taproot');
|
|
87
|
-
} catch (err) {
|
|
88
|
-
equal(err, null, 'Expected no error');
|
|
89
|
-
} finally {
|
|
90
|
-
await kill({});
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return;
|
|
94
|
-
});
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
const {deepStrictEqual} = require('node:assert').strict;
|
|
2
|
-
const {randomBytes} = require('node:crypto');
|
|
3
|
-
const {strictEqual} = require('node:assert').strict;
|
|
4
|
-
const test = require('node:test');
|
|
5
|
-
|
|
6
|
-
const asyncRetry = require('async/retry');
|
|
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 {decodePaymentRequest} = require('./../../');
|
|
13
|
-
const {getHeight} = require('./../../');
|
|
14
|
-
const {getRouteToDestination} = require('./../../');
|
|
15
|
-
const {openChannel} = require('./../../');
|
|
16
|
-
const {pay} = require('./../../');
|
|
17
|
-
|
|
18
|
-
const confirmationCount = 6;
|
|
19
|
-
const interval = 10;
|
|
20
|
-
const mtokPadding = '000';
|
|
21
|
-
const size = 3;
|
|
22
|
-
const times = 1000;
|
|
23
|
-
const tokens = 100;
|
|
24
|
-
|
|
25
|
-
// Paying an invoice should settle the invoice
|
|
26
|
-
test(`Pay`, async ({end, equal, strictSame}) => {
|
|
27
|
-
const {kill, nodes} = await spawnLightningCluster({size});
|
|
28
|
-
|
|
29
|
-
const [{generate, lnd}, target, remote] = nodes;
|
|
30
|
-
|
|
31
|
-
try {
|
|
32
|
-
const channel = await setupChannel({generate, lnd, to: target});
|
|
33
|
-
|
|
34
|
-
const remoteChan = await setupChannel({
|
|
35
|
-
generate: target.generate,
|
|
36
|
-
lnd: target.lnd,
|
|
37
|
-
to: remote,
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
await addPeer({lnd, public_key: remote.id, socket: remote.socket});
|
|
41
|
-
|
|
42
|
-
const invoice = await createInvoice({tokens, lnd: remote.lnd});
|
|
43
|
-
|
|
44
|
-
const commitTxFee = channel.commit_transaction_fee;
|
|
45
|
-
|
|
46
|
-
const paid = await asyncRetry({interval, times}, async () => {
|
|
47
|
-
return await pay({lnd, request: invoice.request});
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
strictEqual(paid.fee, 1, 'Fee paid for hop');
|
|
51
|
-
strictEqual(paid.fee_mtokens, '1000', 'Fee mtokens tokens paid');
|
|
52
|
-
strictEqual(paid.id, invoice.id, 'Payment hash is equal on both sides');
|
|
53
|
-
strictEqual(paid.is_confirmed, true, 'Invoice is paid');
|
|
54
|
-
strictEqual(paid.is_outgoing, true, 'Payments are outgoing');
|
|
55
|
-
strictEqual(paid.mtokens, '101000', 'Paid mtokens');
|
|
56
|
-
strictEqual(paid.secret, invoice.secret, 'Paid for invoice secret');
|
|
57
|
-
strictEqual(paid.tokens, invoice.tokens + 1, 'Paid correct number of tok');
|
|
58
|
-
|
|
59
|
-
const height = (await getHeight({lnd})).current_block_height;
|
|
60
|
-
|
|
61
|
-
paid.hops.forEach(n => {
|
|
62
|
-
strictEqual(
|
|
63
|
-
n.timeout === height + 40 ||
|
|
64
|
-
n.timeout === height + 43 ||
|
|
65
|
-
n.timeout === height + 80,
|
|
66
|
-
true
|
|
67
|
-
);
|
|
68
|
-
|
|
69
|
-
delete n.timeout;
|
|
70
|
-
|
|
71
|
-
return;
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
const expectedHops = [
|
|
75
|
-
{
|
|
76
|
-
channel: channel.id,
|
|
77
|
-
fee: 1,
|
|
78
|
-
fee_mtokens: '1000',
|
|
79
|
-
forward: 100,
|
|
80
|
-
forward_mtokens: `${invoice.tokens}${mtokPadding}`,
|
|
81
|
-
public_key: target.id,
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
channel: remoteChan.id,
|
|
85
|
-
fee: 0,
|
|
86
|
-
fee_mtokens: '0',
|
|
87
|
-
forward: 100,
|
|
88
|
-
forward_mtokens: '100000',
|
|
89
|
-
public_key: remote.id,
|
|
90
|
-
},
|
|
91
|
-
];
|
|
92
|
-
|
|
93
|
-
deepStrictEqual(paid.hops, expectedHops, 'Hops are returned');
|
|
94
|
-
|
|
95
|
-
const invoice2 = await createInvoice({lnd: remote.lnd, tokens: 100});
|
|
96
|
-
|
|
97
|
-
const {destination} = await decodePaymentRequest({
|
|
98
|
-
lnd: remote.lnd,
|
|
99
|
-
request: invoice2.request,
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
await generate({count: confirmationCount});
|
|
103
|
-
|
|
104
|
-
const route = await asyncRetry({interval, times}, async () => {
|
|
105
|
-
const {route} = await getRouteToDestination({
|
|
106
|
-
destination,
|
|
107
|
-
lnd,
|
|
108
|
-
payment: invoice2.payment,
|
|
109
|
-
tokens: invoice2.tokens,
|
|
110
|
-
total_mtokens: !!invoice2.payment ? invoice2.mtokens : undefined,
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
if (!route) {
|
|
114
|
-
throw new Error('ExpectedRouteToDestination');
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
return route;
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
// Test paying to a route, but to an id that isn't known
|
|
121
|
-
try {
|
|
122
|
-
await pay({
|
|
123
|
-
lnd,
|
|
124
|
-
path: {routes: [route], id: randomBytes(32).toString('hex')},
|
|
125
|
-
});
|
|
126
|
-
} catch (err) {
|
|
127
|
-
const [code, message] = err;
|
|
128
|
-
|
|
129
|
-
strictEqual(code, 404, 'Unknown payment hashes mean user error');
|
|
130
|
-
strictEqual(message, 'UnknownPaymentHash', 'Specifically unknown error');
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// Test paying regularly to a destination
|
|
134
|
-
const directPay = await pay({
|
|
135
|
-
lnd,
|
|
136
|
-
path: {routes: [route], id: invoice2.id},
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
const zeroInvoice = await createInvoice({lnd: target.lnd});
|
|
140
|
-
|
|
141
|
-
await pay({lnd, request: zeroInvoice.request, mtokens: '1000'});
|
|
142
|
-
} catch (err) {
|
|
143
|
-
strictEqual(err, null, 'Not expecting an error');
|
|
144
|
-
} finally {
|
|
145
|
-
await kill({});
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
return;
|
|
149
|
-
});
|