paid-services 3.3.0 → 3.4.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 +5 -0
- package/capacity/accept_capacity_change.js +3 -3
- package/capacity/get_capacity_change_requests.js +1 -1
- package/capacity/get_capacity_replacement.js +1 -1
- package/capacity/initiate_capacity_change.js +5 -4
- package/capacity/propose_capacity_change.js +3 -1
- package/p2p/service_peer_requests.js +10 -2
- package/package.json +3 -2
- package/service_types.json +16 -0
- package/test/integration/test_accept_capacity_change.js +50 -13
- package/test/integration/test_change_channel_capacity.js +3 -0
- 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 +52 -0
- package/trades/create_trade.js +124 -44
- 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_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 +116 -0
- package/trades/find_trade.js +314 -0
- package/trades/manage_trade.js +46 -35
- 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 +89 -0
- package/trades/service_trade_requests.js +184 -0
- package/capacity/service_types.json +0 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Versions
|
|
2
2
|
|
|
3
|
+
## Version 3.4.0
|
|
4
|
+
|
|
5
|
+
- `changeChannelCapacity`: Fix broken preservation of channel announce status
|
|
6
|
+
- `manageTrades`: Add support for open-ended trades
|
|
7
|
+
|
|
3
8
|
## Version 3.3.0
|
|
4
9
|
|
|
5
10
|
- `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');
|
|
@@ -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
|
|
|
@@ -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';
|
|
@@ -438,6 +438,7 @@ module.exports = ({ask, lnd, logger}, cbk) => {
|
|
|
438
438
|
increase_transaction_id: getFunding.id,
|
|
439
439
|
increase_transaction_vout: getFunding.vout,
|
|
440
440
|
increase_witness_script: getFunding.script,
|
|
441
|
+
is_private: channel.is_private,
|
|
441
442
|
open_transaction: sendBasicRequest,
|
|
442
443
|
partner_public_key: askForChangeDetails.partner_public_key,
|
|
443
444
|
transaction_id: channel.transaction_id,
|
|
@@ -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,6 +120,7 @@ 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,
|
|
123
125
|
lnd: args.lnd,
|
|
124
126
|
open_transaction: args.open_transaction,
|
|
@@ -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
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"async": "3.2.2",
|
|
11
11
|
"asyncjs-util": "1.2.7",
|
|
12
12
|
"bolt01": "1.2.3",
|
|
13
|
+
"bolt07": "1.8.0",
|
|
13
14
|
"invoices": "2.0.2",
|
|
14
15
|
"ln-service": "53.2.0",
|
|
15
16
|
"ln-sync": "3.6.0"
|
|
@@ -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.4.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
|
+
}
|
|
@@ -111,9 +111,12 @@ test(`Accept capacity replacement`, async ({end, equal, strictSame}) => {
|
|
|
111
111
|
transaction_id: channel.transaction_id,
|
|
112
112
|
transaction_vout: channel.transaction_vout,
|
|
113
113
|
});
|
|
114
|
+
|
|
115
|
+
proposeDone = true;
|
|
116
|
+
|
|
117
|
+
return;
|
|
114
118
|
},
|
|
115
119
|
|
|
116
|
-
// Wait for a
|
|
117
120
|
accept: async () => {
|
|
118
121
|
await acceptCapacityChange({
|
|
119
122
|
id,
|
|
@@ -123,25 +126,59 @@ test(`Accept capacity replacement`, async ({end, equal, strictSame}) => {
|
|
|
123
126
|
lnd: target.lnd,
|
|
124
127
|
});
|
|
125
128
|
},
|
|
126
|
-
});
|
|
127
129
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
130
|
+
confirmTarget: ['accept', async ({}) => {
|
|
131
|
+
// Wait for the new channel to be active
|
|
132
|
+
const recreated = await asyncRetry({interval, times}, async () => {
|
|
133
|
+
const controlChannels = (await getChannels({lnd, is_active: true}));
|
|
131
134
|
|
|
132
|
-
|
|
133
|
-
return channel;
|
|
134
|
-
}
|
|
135
|
+
const [channel] = controlChannels.channels;
|
|
135
136
|
|
|
136
|
-
|
|
137
|
+
const targetChans = await getChannels({
|
|
138
|
+
is_active: true,
|
|
139
|
+
lnd: target.lnd,
|
|
140
|
+
});
|
|
137
141
|
|
|
138
|
-
|
|
139
|
-
|
|
142
|
+
const targetChan = targetChans.channels;
|
|
143
|
+
|
|
144
|
+
if (!!channel && !!targetChan && channel.capacity < capacity) {
|
|
145
|
+
return channel;
|
|
146
|
+
}
|
|
140
147
|
|
|
141
|
-
|
|
148
|
+
await generate({});
|
|
142
149
|
|
|
143
|
-
|
|
150
|
+
throw new Error('ExpectedChannelActivation');
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
strictSame(recreated.is_active, true, 'Recreated channel is active');
|
|
154
|
+
}],
|
|
155
|
+
|
|
156
|
+
confirmControl: ['accept', 'propose', async ({}) => {
|
|
157
|
+
// Wait for the new channel to be active
|
|
158
|
+
const recreated = await asyncRetry({interval, times}, async () => {
|
|
159
|
+
const controlChannels = (await getChannels({lnd, is_active: true}));
|
|
160
|
+
|
|
161
|
+
const [channel] = controlChannels.channels;
|
|
162
|
+
|
|
163
|
+
const targetChans = await getChannels({
|
|
164
|
+
is_active: true,
|
|
165
|
+
lnd: target.lnd,
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
const targetChan = targetChans.channels;
|
|
144
169
|
|
|
170
|
+
if (!!channel && !!targetChan && channel.capacity < capacity) {
|
|
171
|
+
return channel;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
await generate({});
|
|
175
|
+
|
|
176
|
+
throw new Error('ExpectedChannelActivation');
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
strictSame(recreated.is_active, true, 'Recreated channel is active');
|
|
180
|
+
}],
|
|
181
|
+
});
|
|
145
182
|
} catch (err) {
|
|
146
183
|
strictSame(err, null, 'Expected no failure');
|
|
147
184
|
} finally {
|
|
@@ -49,6 +49,7 @@ test(`Accept capacity replacement`, async ({end, equal, strictSame}) => {
|
|
|
49
49
|
// Open up a new channel
|
|
50
50
|
const channelOpen = await openChannel({
|
|
51
51
|
lnd,
|
|
52
|
+
is_private: true,
|
|
52
53
|
local_tokens: capacity,
|
|
53
54
|
partner_public_key: target.id,
|
|
54
55
|
partner_socket: target.socket,
|
|
@@ -159,6 +160,8 @@ test(`Accept capacity replacement`, async ({end, equal, strictSame}) => {
|
|
|
159
160
|
throw new Error('ExpectedChannelActivation');
|
|
160
161
|
}
|
|
161
162
|
|
|
163
|
+
equal(channel.is_private, true, 'Channel is private');
|
|
164
|
+
|
|
162
165
|
{
|
|
163
166
|
const {policies} = await getChannel({lnd, id: channel.id});
|
|
164
167
|
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const {test} = require('@alexbosworth/tap');
|
|
2
|
+
|
|
3
|
+
const method = require('./../../trades/decode_basic_trade');
|
|
4
|
+
|
|
5
|
+
const tests = [
|
|
6
|
+
{
|
|
7
|
+
args: {},
|
|
8
|
+
description: 'Records are expected',
|
|
9
|
+
error: 'ExpectedArrayOfRecordsToDecodeBasicTrade',
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
args: {records: []},
|
|
13
|
+
description: 'A description record is expected',
|
|
14
|
+
error: 'ExpectedDescriptionRecordToDecodeBasicTrade',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
args: {records: [{type: '2', value: '00'}]},
|
|
18
|
+
description: 'An id record is expected',
|
|
19
|
+
error: 'ExpectedIdRecordToDecodeBasicTradeDetails',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
args: {records: [{type: '1', value: '00'}, {type: '2', value: '00'}]},
|
|
23
|
+
description: 'Basic trade is encoded',
|
|
24
|
+
expected: {description: '\u0000', id: '00'},
|
|
25
|
+
},
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
tests.forEach(({args, description, error, expected}) => {
|
|
29
|
+
return test(description, async ({end, strictSame, throws}) => {
|
|
30
|
+
if (!!error) {
|
|
31
|
+
throws(() => method(args), new Error(error), 'Got error');
|
|
32
|
+
} else {
|
|
33
|
+
const res = method(args);
|
|
34
|
+
|
|
35
|
+
strictSame(res, expected, 'Got expected result');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return end();
|
|
39
|
+
});
|
|
40
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
const {test} = require('@alexbosworth/tap');
|
|
2
|
+
|
|
3
|
+
const method = require('./../../trades/decode_open_trade');
|
|
4
|
+
|
|
5
|
+
const tests = [
|
|
6
|
+
{
|
|
7
|
+
args: {},
|
|
8
|
+
description: 'A network name is expected',
|
|
9
|
+
error: 'ExpectedNetworkNameToDecodeOpenTrade',
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
args: {network: 'btc'},
|
|
13
|
+
description: 'Records are expected',
|
|
14
|
+
error: 'ExpectedArrayOfRecordsToDecodeOpenTrade',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
args: {network: 'btc', records: []},
|
|
18
|
+
description: 'Nodes are expected',
|
|
19
|
+
error: 'ExpectedNodesRecordToDecodeOpenTradeDetails',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
args: {
|
|
23
|
+
network: 'btc',
|
|
24
|
+
records: [
|
|
25
|
+
{type: '0', value: '01'},
|
|
26
|
+
{type: '4', value: '000a01080000010000020003'},
|
|
27
|
+
],
|
|
28
|
+
},
|
|
29
|
+
description: 'Open trade is decoded',
|
|
30
|
+
expected: {
|
|
31
|
+
id: undefined,
|
|
32
|
+
network: 'btc',
|
|
33
|
+
nodes: [{high_channel: '1x2x3'}],
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
tests.forEach(({args, description, error, expected}) => {
|
|
39
|
+
return test(description, async ({end, strictSame, throws}) => {
|
|
40
|
+
if (!!error) {
|
|
41
|
+
throws(() => method(args), new Error(error), 'Got error');
|
|
42
|
+
} else {
|
|
43
|
+
const res = method(args);
|
|
44
|
+
|
|
45
|
+
strictSame(res, expected, 'Got expected result');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return end();
|
|
49
|
+
});
|
|
50
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const {test} = require('@alexbosworth/tap');
|
|
2
|
+
|
|
3
|
+
const method = require('./../../trades/encode_open_trade');
|
|
4
|
+
|
|
5
|
+
const tests = [
|
|
6
|
+
{
|
|
7
|
+
args: {
|
|
8
|
+
network: 'btc',
|
|
9
|
+
nodes: [{
|
|
10
|
+
channels: [{
|
|
11
|
+
id: '1x2x3',
|
|
12
|
+
partner_public_key: Buffer.alloc(33, 2).toString('hex'),
|
|
13
|
+
}],
|
|
14
|
+
id: Buffer.alloc(33, 3).toString('hex'),
|
|
15
|
+
sockets: [],
|
|
16
|
+
}],
|
|
17
|
+
},
|
|
18
|
+
description: 'Open trade is encoded',
|
|
19
|
+
expected: {trade: '626f73ff000101040c000a01080000010000020003'},
|
|
20
|
+
},
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
tests.forEach(({args, description, error, expected}) => {
|
|
24
|
+
return test(description, async ({end, strictSame, throws}) => {
|
|
25
|
+
if (!!error) {
|
|
26
|
+
throws(() => method(args), new Error(error), 'Got error');
|
|
27
|
+
} else {
|
|
28
|
+
const res = method(args);
|
|
29
|
+
|
|
30
|
+
strictSame(res, expected, 'Got expected result');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return end();
|
|
34
|
+
});
|
|
35
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const {test} = require('@alexbosworth/tap');
|
|
2
|
+
|
|
3
|
+
const method = require('./../../trades/encode_trade');
|
|
4
|
+
|
|
5
|
+
const tests = [
|
|
6
|
+
{
|
|
7
|
+
args: {
|
|
8
|
+
connect: {
|
|
9
|
+
network: 'btc',
|
|
10
|
+
nodes: [{
|
|
11
|
+
channels: [{
|
|
12
|
+
id: '1x2x3',
|
|
13
|
+
partner_public_key: Buffer.alloc(33, 2).toString('hex'),
|
|
14
|
+
}],
|
|
15
|
+
id: Buffer.alloc(33, 3).toString('hex'),
|
|
16
|
+
sockets: [],
|
|
17
|
+
}],
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
description: 'Trade is encoded',
|
|
21
|
+
expected: {trade: '626f73ff000101040c000a01080000010000020003'},
|
|
22
|
+
},
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
tests.forEach(({args, description, error, expected}) => {
|
|
26
|
+
return test(description, async ({end, strictSame, throws}) => {
|
|
27
|
+
if (!!error) {
|
|
28
|
+
throws(() => method(args), new Error(error), 'Got error');
|
|
29
|
+
} else {
|
|
30
|
+
const res = method(args);
|
|
31
|
+
|
|
32
|
+
strictSame(res, expected, 'Got expected result');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return end();
|
|
36
|
+
});
|
|
37
|
+
});
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const asyncAuto = require('async/auto');
|
|
2
|
+
const asyncEach = require('async/each');
|
|
3
|
+
const {cancelHodlInvoice} = require('ln-service');
|
|
4
|
+
const {returnResult} = require('asyncjs-util');
|
|
5
|
+
const {settleHodlInvoice} = require('ln-service');
|
|
6
|
+
|
|
7
|
+
const {isArray} = Array;
|
|
8
|
+
|
|
9
|
+
/** Accept an open ended trade
|
|
10
|
+
|
|
11
|
+
{
|
|
12
|
+
cancel: [<Alternative Invoice Id Hex String>]
|
|
13
|
+
lnd: <Authenticated LND API Object>
|
|
14
|
+
secret: <Invoice to Settle Preimage Hex String>
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@returns via cbk or Promise
|
|
18
|
+
*/
|
|
19
|
+
module.exports = ({cancel, lnd, secret}, cbk) => {
|
|
20
|
+
return new Promise((resolve, reject) => {
|
|
21
|
+
return asyncAuto({
|
|
22
|
+
// Check arguments
|
|
23
|
+
validate: cbk => {
|
|
24
|
+
if (!isArray(cancel)) {
|
|
25
|
+
return cbk([400, 'ExpectedArrayOfIdsToCancelToAcceptTrade']);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (!lnd) {
|
|
29
|
+
return cbk([400, 'ExpectedAuthenticatedLndToAcceptTrade']);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (!secret) {
|
|
33
|
+
return cbk([400, 'ExpectedSettlementPreimageToAcceptTrade']);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return cbk();
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
// Cancel alternative invoices so that only one resolves as settled
|
|
40
|
+
cancel: ['validate', ({}, cbk) => {
|
|
41
|
+
return asyncEach(cancel, (id, cbk) => {
|
|
42
|
+
return cancelHodlInvoice({id, lnd}, cbk);
|
|
43
|
+
},
|
|
44
|
+
cbk);
|
|
45
|
+
}],
|
|
46
|
+
|
|
47
|
+
// Settle the held invoice with the preimage
|
|
48
|
+
settle: ['cancel', ({}, cbk) => settleHodlInvoice({lnd, secret}, cbk)],
|
|
49
|
+
},
|
|
50
|
+
returnResult({reject, resolve}, cbk));
|
|
51
|
+
});
|
|
52
|
+
};
|