paid-services 3.3.0 → 3.6.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/.prettierignore +2 -0
- package/CHANGELOG.md +17 -0
- package/capacity/accept_capacity_change.js +3 -3
- package/capacity/ask_for_change_details.js +34 -1
- package/capacity/capacity_change_requests.js +9 -0
- package/capacity/change_channel_capacity.js +7 -1
- package/capacity/encode_change_request.js +8 -1
- package/capacity/fee_for_replacement.js +1 -1
- package/capacity/get_capacity_change_requests.js +2 -1
- package/capacity/get_capacity_replacement.js +1 -1
- package/capacity/initiate_capacity_change.js +5 -5
- package/capacity/parse_capacity_change_request.js +8 -1
- package/capacity/propose_capacity_change.js +4 -1
- package/p2p/service_peer_requests.js +10 -2
- package/package.json +10 -9
- package/service_types.json +16 -0
- package/services/response_for_relay.js +0 -1
- package/test/capacity/test_capacity_change_requests.js +1 -0
- package/test/capacity/test_encode_change_request.js +5 -0
- package/test/capacity/test_parse_capacity_change_request.js +1 -0
- package/test/integration/test_accept_capacity_change.js +50 -14
- package/test/integration/test_change_channel_capacity.js +7 -1
- package/test/integration/test_decrease_channel_capacity.js +16 -7
- package/test/integration/test_increase_channel_capacity.js +4 -1
- package/test/trades/test_decode_basic_trade.js +40 -0
- package/test/trades/test_decode_open_trade.js +50 -0
- package/test/trades/test_encode_open_trade.js +35 -0
- package/test/trades/test_encode_trade.js +37 -0
- package/trades/accept_trade.js +61 -0
- package/trades/create_trade.js +149 -37
- package/trades/decode_anchored_trade.js +56 -0
- package/trades/decode_basic_trade.js +45 -0
- package/trades/decode_open_trade.js +69 -0
- package/trades/decode_trade.js +48 -66
- package/trades/decode_trade_secret.js +89 -0
- package/trades/encode_anchored_trade.js +35 -0
- package/trades/encode_open_trade.js +89 -0
- package/trades/encode_trade.js +48 -33
- package/trades/encode_trade_secret.js +50 -0
- package/trades/finalize_trade_secret.js +123 -0
- package/trades/find_trade.js +339 -0
- package/trades/manage_trade.js +61 -39
- package/trades/manage_trades.js +209 -2
- package/trades/network_from_network_record.js +3 -3
- package/trades/network_record_from_network.js +36 -0
- package/trades/network_record_from_request.js +2 -1
- package/trades/node_as_record.js +98 -0
- package/trades/record_as_node.js +113 -0
- package/trades/request_trade_by_id.js +95 -0
- package/trades/service_anchored_trades.js +181 -0
- package/trades/service_open_trade.js +172 -0
- package/trades/service_trade_requests.js +255 -0
- package/trades/trade_from_invoice.js +51 -0
- package/capacity/service_types.json +0 -6
package/.prettierignore
ADDED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# Versions
|
|
2
2
|
|
|
3
|
+
## Version 3.6.0
|
|
4
|
+
|
|
5
|
+
- `manageTrades`: Add support for persistent open trades
|
|
6
|
+
- `manageTrades`: Add expiration dates to open trades
|
|
7
|
+
- `manageTrades`: Support longer-lived open trade scenarios
|
|
8
|
+
- `manageTrades`: Show final encoded trade when requesting open trade
|
|
9
|
+
- `manageTrades`: Check for RPC signer support before trading
|
|
10
|
+
|
|
11
|
+
## Version 3.5.1
|
|
12
|
+
|
|
13
|
+
- `changeChannelCapacity`: Allow changing private/public status of channel
|
|
14
|
+
|
|
15
|
+
## Version 3.4.0
|
|
16
|
+
|
|
17
|
+
- `changeChannelCapacity`: Fix broken preservation of channel announce status
|
|
18
|
+
- `manageTrades`: Add support for open-ended trades
|
|
19
|
+
|
|
3
20
|
## Version 3.3.0
|
|
4
21
|
|
|
5
22
|
- `changeChannelCapacity`: Add method to change a channel's capacity
|
|
@@ -12,9 +12,9 @@ const {makePeerRequest} = require('./../p2p');
|
|
|
12
12
|
const parseAcceptResponse = require('./parse_accept_response');
|
|
13
13
|
const parseSignCapacityRequest = require('./parse_sign_capacity_request');
|
|
14
14
|
const {servicePeerRequests} = require('./../p2p');
|
|
15
|
-
const {serviceTypeAcceptCapacityChange} = require('
|
|
16
|
-
const {serviceTypeSignCapacityChange} = require('
|
|
17
|
-
const {serviceTypeWaitOnConfirmation} = require('
|
|
15
|
+
const {serviceTypeAcceptCapacityChange} = require('./../service_types');
|
|
16
|
+
const {serviceTypeSignCapacityChange} = require('./../service_types');
|
|
17
|
+
const {serviceTypeWaitOnConfirmation} = require('./../service_types');
|
|
18
18
|
|
|
19
19
|
const acceptChangeTimeoutMs = 1000 * 45;
|
|
20
20
|
const bufferAsHex = buffer => buffer.toString('hex');
|
|
@@ -24,6 +24,8 @@ const minNewLocalBalance = 0;
|
|
|
24
24
|
const nonNegative = n => Math.max(0, n);
|
|
25
25
|
const outputSize = 44;
|
|
26
26
|
const positive = n => Math.max(1, n);
|
|
27
|
+
const privateType = 1;
|
|
28
|
+
const publicType = 0;
|
|
27
29
|
const slowTarget = 1000;
|
|
28
30
|
const sumOf = arr => arr.reduce((sum, n) => sum + n, 0);
|
|
29
31
|
const sumOfTokens = arr => arr.reduce((sum, n) => sum + n.tokens, 0);
|
|
@@ -395,10 +397,37 @@ module.exports = ({ask, id, lnd}, cbk) => {
|
|
|
395
397
|
({amount}) => cbk(null, Number(amount)));
|
|
396
398
|
}],
|
|
397
399
|
|
|
400
|
+
// Confirm or change the announce status of the replacement channel
|
|
401
|
+
askForPublicPrivate: [
|
|
402
|
+
'askForDecrease',
|
|
403
|
+
'askForIncrease',
|
|
404
|
+
'channel',
|
|
405
|
+
({channel}, cbk) =>
|
|
406
|
+
{
|
|
407
|
+
return ask({
|
|
408
|
+
choices: ['Public', 'Private'].map(type => {
|
|
409
|
+
const isPrivate = type === 'Private';
|
|
410
|
+
|
|
411
|
+
// Exit early when the type would be different
|
|
412
|
+
if (isPrivate !== channel.is_private) {
|
|
413
|
+
return type;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
return `${type} (Keep Current Status)`;
|
|
417
|
+
}),
|
|
418
|
+
default: channel.is_private ? 'Private' : 'Public',
|
|
419
|
+
message: 'Channel type?',
|
|
420
|
+
name: 'type',
|
|
421
|
+
type: 'list',
|
|
422
|
+
},
|
|
423
|
+
({type}) => cbk(null, {is_private: type === 'Private'}));
|
|
424
|
+
}],
|
|
425
|
+
|
|
398
426
|
// Estimate the chain fee
|
|
399
427
|
estimateChainFee: [
|
|
400
428
|
'askForDecrease',
|
|
401
429
|
'askForIncrease',
|
|
430
|
+
'askForPublicPrivate',
|
|
402
431
|
'channel',
|
|
403
432
|
'getFeeRate',
|
|
404
433
|
({askForDecrease, askForIncrease, channel, getFeeRate}, cbk) =>
|
|
@@ -417,6 +446,7 @@ module.exports = ({ask, id, lnd}, cbk) => {
|
|
|
417
446
|
|
|
418
447
|
// Confirm chain fee payment estimate
|
|
419
448
|
confirmFeeEstimate: [
|
|
449
|
+
'askForPublicPrivate',
|
|
420
450
|
'channel',
|
|
421
451
|
'estimateChainFee',
|
|
422
452
|
({channel, estimateChainFee}, cbk) =>
|
|
@@ -437,6 +467,7 @@ module.exports = ({ask, id, lnd}, cbk) => {
|
|
|
437
467
|
details: [
|
|
438
468
|
'askForDecrease',
|
|
439
469
|
'askForIncrease',
|
|
470
|
+
'askForPublicPrivate',
|
|
440
471
|
'channel',
|
|
441
472
|
'confirmFeeEstimate',
|
|
442
473
|
'estimateChainFee',
|
|
@@ -444,6 +475,7 @@ module.exports = ({ask, id, lnd}, cbk) => {
|
|
|
444
475
|
({
|
|
445
476
|
askForDecrease,
|
|
446
477
|
askForIncrease,
|
|
478
|
+
askForPublicPrivate,
|
|
447
479
|
channel,
|
|
448
480
|
confirmFeeEstimate,
|
|
449
481
|
estimateChainFee,
|
|
@@ -478,6 +510,7 @@ module.exports = ({ask, id, lnd}, cbk) => {
|
|
|
478
510
|
channel: channel.id,
|
|
479
511
|
decrease: !!askForDecrease ? sumOfTokens(askForDecrease) : undefined,
|
|
480
512
|
increase: askForIncrease,
|
|
513
|
+
type: askForPublicPrivate.is_private ? privateType : publicType,
|
|
481
514
|
});
|
|
482
515
|
|
|
483
516
|
return cbk(null, {
|
|
@@ -491,7 +524,7 @@ module.exports = ({ask, id, lnd}, cbk) => {
|
|
|
491
524
|
fee_rate: channel.fee_rate,
|
|
492
525
|
id: channel.id,
|
|
493
526
|
increase: askForIncrease,
|
|
494
|
-
is_private:
|
|
527
|
+
is_private: askForPublicPrivate.is_private,
|
|
495
528
|
open_transaction: channel.open_transaction,
|
|
496
529
|
partner_csv_delay: channel.partner_csv_delay,
|
|
497
530
|
partner_public_key: channel.partner_public_key,
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const privateAsType = isPrivate => isPrivate ? 1 : 0;
|
|
2
|
+
|
|
1
3
|
/** Map change requests to requests considering local channels
|
|
2
4
|
|
|
3
5
|
{
|
|
@@ -13,6 +15,7 @@
|
|
|
13
15
|
from: <From Node Public Key Id Hex String>
|
|
14
16
|
id: <Change Request Id Hex String>
|
|
15
17
|
[increase]: <Add Capacity Tokens Number>
|
|
18
|
+
[type]: <Intended Replacement Channel Channel Type Flags Number>
|
|
16
19
|
}]
|
|
17
20
|
}
|
|
18
21
|
|
|
@@ -26,6 +29,7 @@
|
|
|
26
29
|
from: <From Node Public Key Id Hex String>
|
|
27
30
|
id: <Change Request Id Hex String>
|
|
28
31
|
[increase]: <Add Capacity Tokens Number>
|
|
32
|
+
[type]: <Change Channel Channel Type Flags Number>
|
|
29
33
|
}]
|
|
30
34
|
}
|
|
31
35
|
*/
|
|
@@ -61,6 +65,10 @@ module.exports = ({channels, requests}) => {
|
|
|
61
65
|
.map(request => {
|
|
62
66
|
const channel = channels.find(chan => chan.id === request.channel);
|
|
63
67
|
|
|
68
|
+
const currentType = privateAsType(channel.is_private);
|
|
69
|
+
|
|
70
|
+
const type = request.type !== undefined && request.type !== currentType;
|
|
71
|
+
|
|
64
72
|
return {
|
|
65
73
|
address: channel.cooperative_close_address,
|
|
66
74
|
capacity: channel.capacity,
|
|
@@ -69,6 +77,7 @@ module.exports = ({channels, requests}) => {
|
|
|
69
77
|
from: channel.partner_public_key,
|
|
70
78
|
id: request.id,
|
|
71
79
|
increase: request.increase,
|
|
80
|
+
type: type ? request.type : undefined,
|
|
72
81
|
};
|
|
73
82
|
});
|
|
74
83
|
|
|
@@ -10,6 +10,7 @@ const acceptCapacityChange = require('./accept_capacity_change');
|
|
|
10
10
|
const getCapacityChangeRequests = require('./get_capacity_change_requests');
|
|
11
11
|
const initiateCapacityChange = require('./initiate_capacity_change');
|
|
12
12
|
|
|
13
|
+
const describeType = type => !(type & 0) ? 'private' : 'public';
|
|
13
14
|
const interval = 10 * 1000;
|
|
14
15
|
const peerName = ({alias, id}) => `${alias} ${id.substring(0, 8)}`.trim();
|
|
15
16
|
const times = 6 * 60 * 6;
|
|
@@ -89,17 +90,22 @@ module.exports = ({ask, delay, lnd, logger}, cbk) => {
|
|
|
89
90
|
|
|
90
91
|
const change = !!request.increase ? 'Increase' : 'Decrease';
|
|
91
92
|
const delta = request.decrease || request.increase;
|
|
93
|
+
const hasType = request.type !== undefined;
|
|
92
94
|
const id = request.channel;
|
|
93
95
|
const peer = peerName(res);
|
|
94
96
|
const size = tokensAsBigUnit(request.capacity);
|
|
95
97
|
|
|
98
|
+
|
|
96
99
|
const action = `${change} capacity ${size} channel ${id}`;
|
|
97
100
|
const by = !!delta ? ` by ${tokensAsBigUnit(delta)}` : '';
|
|
101
|
+
const type = hasType ? describeType(request.type) : '';
|
|
102
|
+
|
|
103
|
+
const changeType = hasType ? ` and make channel ${type}` : '';
|
|
98
104
|
|
|
99
105
|
return ask({
|
|
100
106
|
type: 'confirm',
|
|
101
107
|
name: 'accept',
|
|
102
|
-
message: `${action} with ${peer}${by}?`,
|
|
108
|
+
message: `${action} with ${peer}${by}${changeType}?`,
|
|
103
109
|
},
|
|
104
110
|
({accept}) => {
|
|
105
111
|
if (!accept) {
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
const {encodeBigSize} = require('bolt01');
|
|
2
2
|
const {rawChanId} = require('bolt07');
|
|
3
3
|
|
|
4
|
+
const channelFlagsType = '5';
|
|
4
5
|
const channelIdRecordType = '2';
|
|
5
6
|
const decreaseRecordType = '3';
|
|
6
7
|
const increaseRecordType = '4';
|
|
7
8
|
const requestIdRecordType = '1';
|
|
9
|
+
const typeAsHex = type => Buffer.from([type]).toString('hex');
|
|
8
10
|
|
|
9
11
|
/** Encode a request to change a channel capacity
|
|
10
12
|
|
|
@@ -13,6 +15,7 @@ const requestIdRecordType = '1';
|
|
|
13
15
|
[decrease]: <Remove Channel Funds By Tokens Number>
|
|
14
16
|
id: <Request Id Hex String>
|
|
15
17
|
increase: <Add Channel Funds By Tokens Number>
|
|
18
|
+
type: <New Channel Type Number>
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
@returns
|
|
@@ -23,7 +26,7 @@ const requestIdRecordType = '1';
|
|
|
23
26
|
}]
|
|
24
27
|
}
|
|
25
28
|
*/
|
|
26
|
-
module.exports = ({channel, decrease, id, increase}) => {
|
|
29
|
+
module.exports = ({channel, decrease, id, increase, type}) => {
|
|
27
30
|
const records = [
|
|
28
31
|
{
|
|
29
32
|
type: requestIdRecordType,
|
|
@@ -33,6 +36,10 @@ module.exports = ({channel, decrease, id, increase}) => {
|
|
|
33
36
|
type: channelIdRecordType,
|
|
34
37
|
value: rawChanId({channel}).id,
|
|
35
38
|
},
|
|
39
|
+
{
|
|
40
|
+
type: channelFlagsType,
|
|
41
|
+
value: typeAsHex(type),
|
|
42
|
+
},
|
|
36
43
|
];
|
|
37
44
|
|
|
38
45
|
if (!!decrease) {
|
|
@@ -13,7 +13,7 @@ const dummySignature = Buffer.alloc(74);
|
|
|
13
13
|
const dummyTokens = 0;
|
|
14
14
|
const dummyVout = 0;
|
|
15
15
|
const hexAsBuffer = hex => Buffer.from(hex, 'hex');
|
|
16
|
-
const increaseBuffer =
|
|
16
|
+
const increaseBuffer = 300;
|
|
17
17
|
const {max} = Math;
|
|
18
18
|
const weightAsVBytes = weight => weight / 4;
|
|
19
19
|
|
|
@@ -4,7 +4,7 @@ const {returnResult} = require('asyncjs-util');
|
|
|
4
4
|
const {subscribeToPeerMessages} = require('ln-service');
|
|
5
5
|
|
|
6
6
|
const capacityChangeRequests = require('./capacity_change_requests');
|
|
7
|
-
const {serviceTypeChangeCapacity} = require('
|
|
7
|
+
const {serviceTypeChangeCapacity} = require('./../service_types');
|
|
8
8
|
const parseCapacityChangeRequest = require('./parse_capacity_change_request');
|
|
9
9
|
const {servicePeerRequests} = require('./../p2p');
|
|
10
10
|
|
|
@@ -28,6 +28,7 @@ const waitForRequestsTimeoutMs = 5000;
|
|
|
28
28
|
from: <From Node Public Key Id Hex String>
|
|
29
29
|
id: <Change Request Id Hex String>
|
|
30
30
|
[increase]: <Add Capacity Tokens Number>
|
|
31
|
+
[type]: <Intended Replacement Channel Channel Type Flags Number>
|
|
31
32
|
}]
|
|
32
33
|
}
|
|
33
34
|
*/
|
|
@@ -264,10 +264,10 @@ module.exports = (args, cbk) => {
|
|
|
264
264
|
channels: [{
|
|
265
265
|
capacity: newCapacity,
|
|
266
266
|
give_tokens: pendingChannel.remote_balance,
|
|
267
|
+
is_private: args.is_private,
|
|
267
268
|
partner_public_key: pendingChannel.partner_public_key,
|
|
268
269
|
}],
|
|
269
270
|
is_avoiding_broadcast: true,
|
|
270
|
-
is_private: args.is_private,
|
|
271
271
|
lnd: args.lnd,
|
|
272
272
|
},
|
|
273
273
|
cbk);
|
|
@@ -23,10 +23,10 @@ const {makePeerRequest} = require('./../p2p');
|
|
|
23
23
|
const parseAcceptRequest = require('./parse_accept_request');
|
|
24
24
|
const proposeCapacityChange = require('./propose_capacity_change');
|
|
25
25
|
const {servicePeerRequests} = require('./../p2p');
|
|
26
|
-
const {serviceTypeAcceptCapacityChange} = require('
|
|
27
|
-
const {serviceTypeChangeCapacity} = require('
|
|
28
|
-
const {serviceTypeSignCapacityChange} = require('
|
|
29
|
-
const {serviceTypeWaitOnConfirmation} = require('
|
|
26
|
+
const {serviceTypeAcceptCapacityChange} = require('./../service_types');
|
|
27
|
+
const {serviceTypeChangeCapacity} = require('./../service_types');
|
|
28
|
+
const {serviceTypeSignCapacityChange} = require('./../service_types');
|
|
29
|
+
const {serviceTypeWaitOnConfirmation} = require('./../service_types');
|
|
30
30
|
|
|
31
31
|
const bufferAsHex = buffer => buffer.toString('hex');
|
|
32
32
|
const capacityChangeRequestIdType = '0';
|
|
@@ -47,7 +47,6 @@ const rebroadcastTimeMs = 1000 * 5;
|
|
|
47
47
|
const recordsAsObject = a => a.reduce((sum, n) => sum[n.type] = n.value, {});
|
|
48
48
|
const requestCapacityChangeIntervalMs = 2000;
|
|
49
49
|
const requestCapacityChangeTimeoutMs = 1000 * 60 * 60 * 6;
|
|
50
|
-
const sumOf = arr => arr.reduce((sum, n) => sum + n, Number());
|
|
51
50
|
const testMessage = '00';
|
|
52
51
|
const tokensAsBigUnit = tokens => (tokens / 1e8).toFixed(8);
|
|
53
52
|
const uniq = arr => Array.from(new Set(arr));
|
|
@@ -438,6 +437,7 @@ module.exports = ({ask, lnd, logger}, cbk) => {
|
|
|
438
437
|
increase_transaction_id: getFunding.id,
|
|
439
438
|
increase_transaction_vout: getFunding.vout,
|
|
440
439
|
increase_witness_script: getFunding.script,
|
|
440
|
+
is_private: askForChangeDetails.is_private,
|
|
441
441
|
open_transaction: sendBasicRequest,
|
|
442
442
|
partner_public_key: askForChangeDetails.partner_public_key,
|
|
443
443
|
transaction_id: channel.transaction_id,
|
|
@@ -4,6 +4,7 @@ const {decodeBigSize} = require('bolt01');
|
|
|
4
4
|
const channelIdHexLength = 16;
|
|
5
5
|
const decodeNumber = encoded => BigInt(decodeBigSize({encoded}).decoded);
|
|
6
6
|
const defaultRecord = {value: '00'};
|
|
7
|
+
const hexAsNumber = n => Buffer.from(n, 'hex').readUInt8();
|
|
7
8
|
const idHexLength = 64;
|
|
8
9
|
const tooLarge = BigInt(Number.MAX_SAFE_INTEGER);
|
|
9
10
|
|
|
@@ -11,6 +12,7 @@ const findChannelRecord = records => records.find(n => n.type === '2');
|
|
|
11
12
|
const findDecreaseRecord = records => records.find(n => n.type === '3');
|
|
12
13
|
const findIncreaseRecord = records => records.find(n => n.type === '4');
|
|
13
14
|
const findRequestIdRecord = records => records.find(n => n.type === '1');
|
|
15
|
+
const findTypeRecord = records => records.find(n => n.type === '5');
|
|
14
16
|
const findVersionRecord = records => records.find(n => n.type === '0');
|
|
15
17
|
|
|
16
18
|
/** Parse a capacity change request
|
|
@@ -31,6 +33,7 @@ const findVersionRecord = records => records.find(n => n.type === '0');
|
|
|
31
33
|
from: <From Node Public Key Id Hex String>
|
|
32
34
|
id: <Change Request Id Hex String>
|
|
33
35
|
[increase]: <Add Capacity Tokens Number>
|
|
36
|
+
[type]: <Intended Replacement Channel Channel Type Flags Number>
|
|
34
37
|
}
|
|
35
38
|
}
|
|
36
39
|
*/
|
|
@@ -52,6 +55,7 @@ module.exports = ({from, records}) => {
|
|
|
52
55
|
return {};
|
|
53
56
|
}
|
|
54
57
|
|
|
58
|
+
// Make sure the channel id is a regular one
|
|
55
59
|
try {
|
|
56
60
|
chanFormat({id: channelRecord.value});
|
|
57
61
|
} catch (err) {
|
|
@@ -67,6 +71,7 @@ module.exports = ({from, records}) => {
|
|
|
67
71
|
|
|
68
72
|
const decreaseRecord = findDecreaseRecord(records);
|
|
69
73
|
const increaseRecord = findIncreaseRecord(records);
|
|
74
|
+
const typeRecord = findTypeRecord(records);
|
|
70
75
|
|
|
71
76
|
// Exit early when there is a change in both directions
|
|
72
77
|
if (!!decreaseRecord && !!increaseRecord) {
|
|
@@ -75,10 +80,11 @@ module.exports = ({from, records}) => {
|
|
|
75
80
|
|
|
76
81
|
const {channel} = chanFormat({id: channelRecord.value});
|
|
77
82
|
const id = idRecord.value;
|
|
83
|
+
const type = typeRecord ? hexAsNumber(typeRecord.value) : undefined;
|
|
78
84
|
|
|
79
85
|
// Exit early when there is no decrease or increase
|
|
80
86
|
if (!decreaseRecord && !increaseRecord) {
|
|
81
|
-
return {request: {channel, from, id}};
|
|
87
|
+
return {request: {channel, from, id, type}};
|
|
82
88
|
}
|
|
83
89
|
|
|
84
90
|
const decrease = decodeNumber((decreaseRecord || defaultRecord).value);
|
|
@@ -94,6 +100,7 @@ module.exports = ({from, records}) => {
|
|
|
94
100
|
channel,
|
|
95
101
|
from,
|
|
96
102
|
id,
|
|
103
|
+
type,
|
|
97
104
|
decrease: Number(decrease) || undefined,
|
|
98
105
|
increase: Number(increase) || undefined,
|
|
99
106
|
},
|
|
@@ -17,7 +17,7 @@ const finalizeCapacityReplacement = require('./finalize_capacity_replacement');
|
|
|
17
17
|
const getCapacityReplacement = require('./get_capacity_replacement');
|
|
18
18
|
const interimReplacementPsbt = require('./interim_replacement_psbt');
|
|
19
19
|
const {makePeerRequest} = require('./../p2p');
|
|
20
|
-
const {serviceTypeSignCapacityChange} = require('
|
|
20
|
+
const {serviceTypeSignCapacityChange} = require('./../service_types');
|
|
21
21
|
|
|
22
22
|
const capacityChangeIdType = '0';
|
|
23
23
|
const findSignatureRecord = records => records.find(n => n.type === '1');
|
|
@@ -40,6 +40,7 @@ const unsignedTransactionType = '1';
|
|
|
40
40
|
tokens: <Spend Value Number>
|
|
41
41
|
}]
|
|
42
42
|
id: <Capacity Change Request Id Hex String>
|
|
43
|
+
is_private: <Channel is Private Bool>
|
|
43
44
|
[increase]: <Increase Channel Size Tokens Number>
|
|
44
45
|
[increase_key_index]: <Increase Funds Transit Key Number>
|
|
45
46
|
[increase_output_script]: <Increase Funds Output Script Hex String>
|
|
@@ -119,7 +120,9 @@ module.exports = (args, cbk) => {
|
|
|
119
120
|
bitcoinjs_network: args.bitcoinjs_network,
|
|
120
121
|
decrease: args.decrease,
|
|
121
122
|
id: args.channel,
|
|
123
|
+
is_private: args.is_private,
|
|
122
124
|
increase: args.increase,
|
|
125
|
+
is_private: args.is_private,
|
|
123
126
|
lnd: args.lnd,
|
|
124
127
|
open_transaction: args.open_transaction,
|
|
125
128
|
transaction_id: args.transaction_id,
|
|
@@ -16,6 +16,7 @@ const returnSuccessResponse = require('./return_success_response');
|
|
|
16
16
|
|
|
17
17
|
@returns
|
|
18
18
|
{
|
|
19
|
+
end: <Add a Service Ended Function>
|
|
19
20
|
error: <Add an Error Listener Function>
|
|
20
21
|
request: <Add A Request Listener For Type Function>
|
|
21
22
|
stop: <Stop Listening Function> ({}) => {};
|
|
@@ -55,9 +56,15 @@ const returnSuccessResponse = require('./return_success_response');
|
|
|
55
56
|
*/
|
|
56
57
|
module.exports = ({lnd}) => {
|
|
57
58
|
const listeners = {};
|
|
58
|
-
const service = {error: () => {}};
|
|
59
|
+
const service = {end: () => {}, error: () => {}};
|
|
59
60
|
const sub = subscribeToPeerMessages({lnd});
|
|
60
61
|
|
|
62
|
+
sub.on('error', error => {
|
|
63
|
+
service.error(error);
|
|
64
|
+
|
|
65
|
+
return service.end();
|
|
66
|
+
});
|
|
67
|
+
|
|
61
68
|
sub.on('message_received', received => {
|
|
62
69
|
const from = received.public_key;
|
|
63
70
|
const {message} = received;
|
|
@@ -93,7 +100,8 @@ module.exports = ({lnd}) => {
|
|
|
93
100
|
});
|
|
94
101
|
|
|
95
102
|
return {
|
|
96
|
-
|
|
103
|
+
end: cbk => service.end = cbk,
|
|
104
|
+
error: cbk => service.error = cbk,
|
|
97
105
|
request: ({type}, cbk) => listeners[type] = cbk,
|
|
98
106
|
stop: ({}) => sub.removeAllListeners(),
|
|
99
107
|
};
|
package/package.json
CHANGED
|
@@ -7,19 +7,20 @@
|
|
|
7
7
|
"url": "https://github.com/alexbosworth/paid-services/issues"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"async": "3.2.
|
|
11
|
-
"asyncjs-util": "1.2.
|
|
10
|
+
"async": "3.2.3",
|
|
11
|
+
"asyncjs-util": "1.2.8",
|
|
12
12
|
"bolt01": "1.2.3",
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"ln-
|
|
13
|
+
"bolt07": "1.8.0",
|
|
14
|
+
"invoices": "2.0.3",
|
|
15
|
+
"ln-service": "53.4.0",
|
|
16
|
+
"ln-sync": "3.6.1"
|
|
16
17
|
},
|
|
17
18
|
"description": "Lightning Paid Services library",
|
|
18
19
|
"devDependencies": {
|
|
19
20
|
"@alexbosworth/tap": "15.0.10",
|
|
20
|
-
"ln-docker-daemons": "2.
|
|
21
|
+
"ln-docker-daemons": "2.2.0",
|
|
21
22
|
"mock-lnd": "1.4.1",
|
|
22
|
-
"secp256k1": "4.0.
|
|
23
|
+
"secp256k1": "4.0.3"
|
|
23
24
|
},
|
|
24
25
|
"engines": {
|
|
25
26
|
"node": ">=12.20"
|
|
@@ -37,7 +38,7 @@
|
|
|
37
38
|
},
|
|
38
39
|
"scripts": {
|
|
39
40
|
"integration-tests": "tap --branches=1 --functions=1 --lines=1 --statements=1 -t 120 test/integration/*.js",
|
|
40
|
-
"test": "tap --branches=1 --functions=1 --lines=1 --statements=1 -t 60 test/actions/*.js test/capacity/*.js test/client/*.js test/config/*.js test/p2p/*.js test/records/*.js test/respond/*.js test/server/*.js test/server/*.js test/services/*.js"
|
|
41
|
+
"test": "tap --branches=1 --functions=1 --lines=1 --statements=1 -t 60 test/actions/*.js test/capacity/*.js test/client/*.js test/config/*.js test/p2p/*.js test/records/*.js test/respond/*.js test/server/*.js test/server/*.js test/services/*.js test/trades/*.js"
|
|
41
42
|
},
|
|
42
|
-
"version": "3.
|
|
43
|
+
"version": "3.6.0"
|
|
43
44
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"serviceTypeAcceptCapacityChange": "8050002",
|
|
3
|
+
"serviceTypeChangeCapacity": "8050001",
|
|
4
|
+
"serviceTypeReceiveTrades": "8050006",
|
|
5
|
+
"serviceTypeRequestTrades": "8050005",
|
|
6
|
+
"serviceTypeSignCapacityChange": "8050004",
|
|
7
|
+
"serviceTypeWaitOnConfirmation": "8050003",
|
|
8
|
+
"types": {
|
|
9
|
+
"8050001": "serviceTypeChangeCapacity",
|
|
10
|
+
"8050002": "serviceTypeAcceptCapacityChange",
|
|
11
|
+
"8050003": "serviceTypeWaitOnConfirmation",
|
|
12
|
+
"8050004": "serviceTypeSignCapacityChange",
|
|
13
|
+
"8050005": "serviceTypeRequestTrades",
|
|
14
|
+
"8050006": "serviceTypeReceiveTrades"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -18,7 +18,6 @@ const defaultProbeTimeoutMs = 1000 * 60 * 5;
|
|
|
18
18
|
const expiresAt = () => new Date(Date.now() + 1000 * 60 * 30).toISOString();
|
|
19
19
|
const interval = 1000 * 60 * 10;
|
|
20
20
|
const rateDivisor = BigInt(1e6);
|
|
21
|
-
const sumOf = arr => arr.reduce((sum, n) => BigInt(n) + n, BigInt(0));
|
|
22
21
|
const text = 'Relay payment request created';
|
|
23
22
|
const times = 12;
|
|
24
23
|
|
|
@@ -8,6 +8,7 @@ const makeArgs = overrides => {
|
|
|
8
8
|
decrease: 0,
|
|
9
9
|
id: Buffer.alloc(32).toString('hex'),
|
|
10
10
|
increase: undefined,
|
|
11
|
+
type: 1,
|
|
11
12
|
};
|
|
12
13
|
|
|
13
14
|
Object.keys(overrides).forEach(k => args[k] = overrides[k]);
|
|
@@ -29,6 +30,10 @@ const tests = [
|
|
|
29
30
|
type: '2',
|
|
30
31
|
value: '0000000000000000',
|
|
31
32
|
},
|
|
33
|
+
{
|
|
34
|
+
type: '5',
|
|
35
|
+
value: '01',
|
|
36
|
+
},
|
|
32
37
|
],
|
|
33
38
|
},
|
|
34
39
|
},
|
|
@@ -32,7 +32,6 @@ const maturity = 100;
|
|
|
32
32
|
const proposeCapacityChange = propose;
|
|
33
33
|
const signCapacityReplacement = method;
|
|
34
34
|
const size = 2;
|
|
35
|
-
const sumOf = arr => arr.reduce((sum, n) => sum + n, 0);
|
|
36
35
|
const times = 2000;
|
|
37
36
|
const {toOutputScript} = address;
|
|
38
37
|
const weightAsVBytes = n => Math.ceil(n / 4);
|
|
@@ -111,9 +110,12 @@ test(`Accept capacity replacement`, async ({end, equal, strictSame}) => {
|
|
|
111
110
|
transaction_id: channel.transaction_id,
|
|
112
111
|
transaction_vout: channel.transaction_vout,
|
|
113
112
|
});
|
|
113
|
+
|
|
114
|
+
proposeDone = true;
|
|
115
|
+
|
|
116
|
+
return;
|
|
114
117
|
},
|
|
115
118
|
|
|
116
|
-
// Wait for a
|
|
117
119
|
accept: async () => {
|
|
118
120
|
await acceptCapacityChange({
|
|
119
121
|
id,
|
|
@@ -123,25 +125,59 @@ test(`Accept capacity replacement`, async ({end, equal, strictSame}) => {
|
|
|
123
125
|
lnd: target.lnd,
|
|
124
126
|
});
|
|
125
127
|
},
|
|
126
|
-
});
|
|
127
128
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
129
|
+
confirmTarget: ['accept', async ({}) => {
|
|
130
|
+
// Wait for the new channel to be active
|
|
131
|
+
const recreated = await asyncRetry({interval, times}, async () => {
|
|
132
|
+
const controlChannels = (await getChannels({lnd, is_active: true}));
|
|
131
133
|
|
|
132
|
-
|
|
133
|
-
return channel;
|
|
134
|
-
}
|
|
134
|
+
const [channel] = controlChannels.channels;
|
|
135
135
|
|
|
136
|
-
|
|
136
|
+
const targetChans = await getChannels({
|
|
137
|
+
is_active: true,
|
|
138
|
+
lnd: target.lnd,
|
|
139
|
+
});
|
|
137
140
|
|
|
138
|
-
|
|
139
|
-
|
|
141
|
+
const targetChan = targetChans.channels;
|
|
142
|
+
|
|
143
|
+
if (!!channel && !!targetChan && channel.capacity < capacity) {
|
|
144
|
+
return channel;
|
|
145
|
+
}
|
|
140
146
|
|
|
141
|
-
|
|
147
|
+
await generate({});
|
|
142
148
|
|
|
143
|
-
|
|
149
|
+
throw new Error('ExpectedChannelActivation');
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
strictSame(recreated.is_active, true, 'Recreated channel is active');
|
|
153
|
+
}],
|
|
154
|
+
|
|
155
|
+
confirmControl: ['accept', 'propose', async ({}) => {
|
|
156
|
+
// Wait for the new channel to be active
|
|
157
|
+
const recreated = await asyncRetry({interval, times}, async () => {
|
|
158
|
+
const controlChannels = (await getChannels({lnd, is_active: true}));
|
|
159
|
+
|
|
160
|
+
const [channel] = controlChannels.channels;
|
|
161
|
+
|
|
162
|
+
const targetChans = await getChannels({
|
|
163
|
+
is_active: true,
|
|
164
|
+
lnd: target.lnd,
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
const targetChan = targetChans.channels;
|
|
144
168
|
|
|
169
|
+
if (!!channel && !!targetChan && channel.capacity < capacity) {
|
|
170
|
+
return channel;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
await generate({});
|
|
174
|
+
|
|
175
|
+
throw new Error('ExpectedChannelActivation');
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
strictSame(recreated.is_active, true, 'Recreated channel is active');
|
|
179
|
+
}],
|
|
180
|
+
});
|
|
145
181
|
} catch (err) {
|
|
146
182
|
strictSame(err, null, 'Expected no failure');
|
|
147
183
|
} finally {
|
|
@@ -27,7 +27,6 @@ const log = () => {};
|
|
|
27
27
|
const maturity = 100;
|
|
28
28
|
const size = 2;
|
|
29
29
|
const slow = 5000;
|
|
30
|
-
const sumOf = arr => arr.reduce((sum, n) => sum + n, 0);
|
|
31
30
|
const times = 2000;
|
|
32
31
|
const {toOutputScript} = address;
|
|
33
32
|
const weightAsVBytes = n => Math.ceil(n / 4);
|
|
@@ -49,6 +48,7 @@ test(`Accept capacity replacement`, async ({end, equal, strictSame}) => {
|
|
|
49
48
|
// Open up a new channel
|
|
50
49
|
const channelOpen = await openChannel({
|
|
51
50
|
lnd,
|
|
51
|
+
is_private: true,
|
|
52
52
|
local_tokens: capacity,
|
|
53
53
|
partner_public_key: target.id,
|
|
54
54
|
partner_socket: target.socket,
|
|
@@ -103,6 +103,10 @@ test(`Accept capacity replacement`, async ({end, equal, strictSame}) => {
|
|
|
103
103
|
return cbk({query: target.id});
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
+
if (args.name === 'type') {
|
|
107
|
+
return cbk({type: args.default});
|
|
108
|
+
}
|
|
109
|
+
|
|
106
110
|
throw new Error('UnknownQueryNameForInitiator');
|
|
107
111
|
},
|
|
108
112
|
logger: {error: log, info: log},
|
|
@@ -159,6 +163,8 @@ test(`Accept capacity replacement`, async ({end, equal, strictSame}) => {
|
|
|
159
163
|
throw new Error('ExpectedChannelActivation');
|
|
160
164
|
}
|
|
161
165
|
|
|
166
|
+
equal(channel.is_private, true, 'Channel is private');
|
|
167
|
+
|
|
162
168
|
{
|
|
163
169
|
const {policies} = await getChannel({lnd, id: channel.id});
|
|
164
170
|
|