paid-services 3.7.0 → 3.10.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 +14 -0
- package/index.js +10 -0
- package/package.json +4 -4
- package/trades/create_anchored_trade.js +86 -0
- package/trades/create_trade.js +4 -9
- package/trades/find_trade.js +8 -7
- package/trades/get_anchored_trade.js +72 -0
- package/trades/index.js +13 -1
- package/trades/service_anchored_trades.js +31 -6
- package/trades/trade_from_invoice.js +3 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Versions
|
|
2
2
|
|
|
3
|
+
## Version 3.10.0
|
|
4
|
+
|
|
5
|
+
- `createAnchoredTrade`: Add method to create an anchored open trade
|
|
6
|
+
- `getAnchoredTrade`: Add method to get an anchored open trade
|
|
7
|
+
|
|
8
|
+
## Version 3.9.1
|
|
9
|
+
|
|
10
|
+
- `decodeTrade`: Add method to decode a trade-secret
|
|
11
|
+
|
|
12
|
+
## Version 3.8.0
|
|
13
|
+
|
|
14
|
+
- `encodeTrade`: Add method to encode a trade-secret
|
|
15
|
+
- `serviceAnchoredTrades`: Add method to serve open trade-secrets
|
|
16
|
+
|
|
3
17
|
## Version 3.7.0
|
|
4
18
|
|
|
5
19
|
- `changeChannelCapacity`: Add support for decreasing funds into a new channel
|
package/index.js
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
const {changeChannelCapacity} = require('./capacity');
|
|
2
2
|
const {confirmServiceUse} = require('./client');
|
|
3
|
+
const {createAnchoredTrade} = require('./trades');
|
|
4
|
+
const {decodeTrade} = require('./trades');
|
|
5
|
+
const {encodeTrade} = require('./trades');
|
|
6
|
+
const {getAnchoredTrade} = require('./trades');
|
|
3
7
|
const {getServiceSchema} = require('./client');
|
|
4
8
|
const {getServicesList} = require('./client');
|
|
5
9
|
const {makePeerRequest} = require('./p2p');
|
|
6
10
|
const {makeServiceRequest} = require('./client');
|
|
7
11
|
const {manageTrades} = require('./trades');
|
|
8
12
|
const {schema} = require('./services');
|
|
13
|
+
const {serviceAnchoredTrades} = require('./trades');
|
|
9
14
|
const {servicePaidRequests} = require('./server');
|
|
10
15
|
const {servicePeerRequests} = require('./p2p');
|
|
11
16
|
|
|
@@ -14,11 +19,16 @@ const serviceIds = schema.types;
|
|
|
14
19
|
module.exports = {
|
|
15
20
|
changeChannelCapacity,
|
|
16
21
|
confirmServiceUse,
|
|
22
|
+
createAnchoredTrade,
|
|
23
|
+
decodeTrade,
|
|
24
|
+
encodeTrade,
|
|
25
|
+
getAnchoredTrade,
|
|
17
26
|
getServiceSchema,
|
|
18
27
|
getServicesList,
|
|
19
28
|
makePeerRequest,
|
|
20
29
|
makeServiceRequest,
|
|
21
30
|
manageTrades,
|
|
31
|
+
serviceAnchoredTrades,
|
|
22
32
|
serviceIds,
|
|
23
33
|
servicePaidRequests,
|
|
24
34
|
servicePeerRequests,
|
package/package.json
CHANGED
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
"bolt01": "1.2.3",
|
|
13
13
|
"bolt07": "1.8.0",
|
|
14
14
|
"invoices": "2.0.3",
|
|
15
|
-
"ln-service": "53.
|
|
16
|
-
"ln-sync": "3.
|
|
15
|
+
"ln-service": "53.5.0",
|
|
16
|
+
"ln-sync": "3.7.0"
|
|
17
17
|
},
|
|
18
18
|
"description": "Lightning Paid Services library",
|
|
19
19
|
"devDependencies": {
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"url": "https://github.com/alexbosworth/paid-services.git"
|
|
38
38
|
},
|
|
39
39
|
"scripts": {
|
|
40
|
-
"integration-tests": "tap --branches=1 --functions=1 --lines=1 --statements=1 -t 180 test/integration/*.js",
|
|
40
|
+
"integration-tests": "tap -j 2 --branches=1 --functions=1 --lines=1 --statements=1 -t 180 test/integration/*.js",
|
|
41
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"
|
|
42
42
|
},
|
|
43
|
-
"version": "3.
|
|
43
|
+
"version": "3.10.0"
|
|
44
44
|
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
const asyncAuto = require('async/auto');
|
|
2
|
+
const {createInvoice} = require('ln-service');
|
|
3
|
+
const {returnResult} = require('asyncjs-util');
|
|
4
|
+
|
|
5
|
+
const encodeAnchoredTrade = require('./encode_anchored_trade');
|
|
6
|
+
|
|
7
|
+
const maxDescriptionLength = 100;
|
|
8
|
+
const maxSecretLength = 100;
|
|
9
|
+
|
|
10
|
+
/** Create an anchored trade
|
|
11
|
+
|
|
12
|
+
{
|
|
13
|
+
description: <Trade Description String>
|
|
14
|
+
expires_at: <Trade Expires at ISO 8601 Date String>
|
|
15
|
+
lnd: <Authenticated LND API Object>
|
|
16
|
+
secret: <Trade Secret String>
|
|
17
|
+
tokens: <Trade Price Tokens Number>
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@returns via cbk or Promise
|
|
21
|
+
{
|
|
22
|
+
id: <Anchored Trade Id Hex String>
|
|
23
|
+
}
|
|
24
|
+
*/
|
|
25
|
+
module.exports = (args, cbk) => {
|
|
26
|
+
return new Promise((resolve, reject) => {
|
|
27
|
+
return asyncAuto({
|
|
28
|
+
// Check arguments
|
|
29
|
+
validate: cbk => {
|
|
30
|
+
if (args.description === undefined) {
|
|
31
|
+
return cbk([400, 'ExpectedTradeDescriptionToCreateAnchoredTrade']);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (args.description.length > maxDescriptionLength) {
|
|
35
|
+
return cbk([400, 'ExpectedShorterTradeDescriptionToCreateTrade']);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (!args.expires_at) {
|
|
39
|
+
return cbk([400, 'ExpectedTradeExpirationDateToCreateTrade']);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (args.expires_at < new Date().toISOString()) {
|
|
43
|
+
return cbk([400, 'ExpectedLaterExpiresAtDateToCreateTrade']);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (!args.lnd) {
|
|
47
|
+
return cbk([400, 'ExpectedAuthenticatedLndToCreateAnchoredTrade']);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (!args.secret) {
|
|
51
|
+
return cbk([400, 'ExpectedTradeSecretToCreateAnchoredTrade']);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (args.secret.length > maxSecretLength) {
|
|
55
|
+
return cbk([400, 'ExpectedShorterTradeSecretToCreateAnchoredTrade']);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (!args.tokens) {
|
|
59
|
+
return cbk([400, 'ExpectedTokensPriceToCreateAnchoredTrade']);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return cbk();
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
// Create the trade
|
|
66
|
+
create: ['validate', ({}, cbk) => {
|
|
67
|
+
const {encoded} = encodeAnchoredTrade({
|
|
68
|
+
description: args.description,
|
|
69
|
+
secret: args.secret,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
return createInvoice({
|
|
73
|
+
description: encoded,
|
|
74
|
+
expires_at: args.expires_at,
|
|
75
|
+
lnd: args.lnd,
|
|
76
|
+
tokens: args.tokens,
|
|
77
|
+
},
|
|
78
|
+
cbk);
|
|
79
|
+
}],
|
|
80
|
+
|
|
81
|
+
// Final trade
|
|
82
|
+
trade: ['create', ({create}, cbk) => cbk(null, {id: create.id})],
|
|
83
|
+
},
|
|
84
|
+
returnResult({reject, resolve, of: 'trade'}, cbk));
|
|
85
|
+
});
|
|
86
|
+
};
|
package/trades/create_trade.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
const asyncAuto = require('async/auto');
|
|
2
|
-
const {createInvoice} = require('ln-service');
|
|
3
2
|
const {getChannels} = require('ln-service');
|
|
4
3
|
const {getNetwork} = require('ln-sync');
|
|
5
4
|
const {getWalletInfo} = require('ln-service');
|
|
6
5
|
const {returnResult} = require('asyncjs-util');
|
|
7
6
|
|
|
8
|
-
const
|
|
7
|
+
const createAnchoredTrade = require('./create_anchored_trade');
|
|
9
8
|
const finalizeTradeSecret = require('./finalize_trade_secret');
|
|
10
9
|
const serviceOpenTrade = require('./service_open_trade');
|
|
11
10
|
|
|
@@ -204,15 +203,11 @@ module.exports = ({ask, lnd, logger}, cbk) => {
|
|
|
204
203
|
return cbk();
|
|
205
204
|
}
|
|
206
205
|
|
|
207
|
-
|
|
208
|
-
description: askForDescription.description,
|
|
209
|
-
secret: askForSecret.secret,
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
return createInvoice({
|
|
206
|
+
return createAnchoredTrade({
|
|
213
207
|
lnd,
|
|
214
|
-
description:
|
|
208
|
+
description: askForDescription.description,
|
|
215
209
|
expires_at: futureDate(daysAsMs(askForExpiration.days)),
|
|
210
|
+
secret: askForSecret.secret,
|
|
216
211
|
tokens: asNumber(askForPrice.tokens),
|
|
217
212
|
},
|
|
218
213
|
cbk);
|
package/trades/find_trade.js
CHANGED
|
@@ -5,6 +5,7 @@ const asyncAuto = require('async/auto');
|
|
|
5
5
|
const asyncDetect = require('async/detect');
|
|
6
6
|
const asyncDetectSeries = require('async/detectSeries');
|
|
7
7
|
const asyncMap = require('async/map');
|
|
8
|
+
const asyncReflect = require('async/reflect');
|
|
8
9
|
const {getChannel} = require('ln-service');
|
|
9
10
|
const {getNode} = require('ln-service');
|
|
10
11
|
const {getPeers} = require('ln-service');
|
|
@@ -206,19 +207,19 @@ module.exports = ({ask, id, identity, lnd, logger, nodes}, cbk) => {
|
|
|
206
207
|
}],
|
|
207
208
|
|
|
208
209
|
// Request a specific trade
|
|
209
|
-
requestTrade: ['to', ({to}, cbk) => {
|
|
210
|
+
requestTrade: ['to', asyncReflect(({to}, cbk) => {
|
|
210
211
|
// Exit early when this is an open ended trade request with no id
|
|
211
212
|
if (!id) {
|
|
212
213
|
return cbk();
|
|
213
214
|
}
|
|
214
215
|
|
|
215
216
|
return requestTradeById({id, lnd, to}, cbk);
|
|
216
|
-
}],
|
|
217
|
+
})],
|
|
217
218
|
|
|
218
219
|
// Request an inventory of trades
|
|
219
|
-
requestTrades: ['to', ({to}, cbk) => {
|
|
220
|
-
// Exit early when
|
|
221
|
-
if (!!
|
|
220
|
+
requestTrades: ['requestTrade', 'to', ({requestTrade, to}, cbk) => {
|
|
221
|
+
// Exit early when there was a successful request for a specific id
|
|
222
|
+
if (!!requestTrade.value) {
|
|
222
223
|
return cbk();
|
|
223
224
|
}
|
|
224
225
|
|
|
@@ -285,7 +286,7 @@ module.exports = ({ask, id, identity, lnd, logger, nodes}, cbk) => {
|
|
|
285
286
|
({requestTrade, requestTrades}, cbk) =>
|
|
286
287
|
{
|
|
287
288
|
// Exit early when the trade was already selected
|
|
288
|
-
if (!!requestTrade) {
|
|
289
|
+
if (!!requestTrade.value) {
|
|
289
290
|
return cbk();
|
|
290
291
|
}
|
|
291
292
|
|
|
@@ -331,7 +332,7 @@ module.exports = ({ask, id, identity, lnd, logger, nodes}, cbk) => {
|
|
|
331
332
|
'requestTrade',
|
|
332
333
|
({fetchSelectedTrade, requestTrade}, cbk) =>
|
|
333
334
|
{
|
|
334
|
-
return cbk(null, fetchSelectedTrade || requestTrade);
|
|
335
|
+
return cbk(null, fetchSelectedTrade || requestTrade.value);
|
|
335
336
|
}],
|
|
336
337
|
},
|
|
337
338
|
returnResult({reject, resolve, of: 'trade'}, cbk));
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
const asyncAuto = require('async/auto');
|
|
2
|
+
const asyncReflect = require('async/reflect');
|
|
3
|
+
const {getInvoice} = require('ln-service');
|
|
4
|
+
const {returnResult} = require('asyncjs-util');
|
|
5
|
+
|
|
6
|
+
const decodeAnchoredTrade = require('./decode_anchored_trade');
|
|
7
|
+
|
|
8
|
+
/** Get anchored trade
|
|
9
|
+
|
|
10
|
+
{
|
|
11
|
+
id: <Trade Id Hex String>
|
|
12
|
+
lnd: <Authenticated LND API Object>
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@returns via cbk or Promise
|
|
16
|
+
{
|
|
17
|
+
[trade]: {
|
|
18
|
+
description: <Trade Description String>
|
|
19
|
+
expires_at: <Trade Expires at ISO 8601 Date String>
|
|
20
|
+
secret: <Trade Secret String>
|
|
21
|
+
tokens: <Trade Price Tokens Number>
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
*/
|
|
25
|
+
module.exports = ({id, lnd}, cbk) => {
|
|
26
|
+
return new Promise((resolve, reject) => {
|
|
27
|
+
return asyncAuto({
|
|
28
|
+
// Check arguments
|
|
29
|
+
validate: cbk => {
|
|
30
|
+
if (!id) {
|
|
31
|
+
return cbk([400, 'ExpectedIdToGetAnchoredTrade']);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (!lnd) {
|
|
35
|
+
return cbk([400, 'ExpectedLndToGetAnchoredTrade']);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return cbk();
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
// Get invoice
|
|
42
|
+
getInvoice: ['validate', asyncReflect(({}, cbk) => {
|
|
43
|
+
return getInvoice({id, lnd}, cbk);
|
|
44
|
+
})],
|
|
45
|
+
|
|
46
|
+
// Decode trade details
|
|
47
|
+
decode: ['getInvoice', ({getInvoice}, cbk) => {
|
|
48
|
+
if (!getInvoice.value) {
|
|
49
|
+
return cbk(null, {});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const encoded = getInvoice.value.description;
|
|
53
|
+
|
|
54
|
+
const {trade} = decodeAnchoredTrade({encoded});
|
|
55
|
+
|
|
56
|
+
if (!trade) {
|
|
57
|
+
return cbk([400, 'ExpectedAnchoredTradeData']);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return cbk(null, {
|
|
61
|
+
trade: {
|
|
62
|
+
description: trade.description,
|
|
63
|
+
expires_at: getInvoice.value.expires_at,
|
|
64
|
+
secret: trade.secret,
|
|
65
|
+
tokens: getInvoice.value.tokens,
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
}],
|
|
69
|
+
},
|
|
70
|
+
returnResult({reject, resolve, of: 'decode'}, cbk));
|
|
71
|
+
});
|
|
72
|
+
};
|
package/trades/index.js
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
const createAnchoredTrade = require('./create_anchored_trade');
|
|
2
|
+
const decodeTrade = require('./decode_trade');
|
|
3
|
+
const encodeTrade = require('./encode_trade');
|
|
4
|
+
const getAnchoredTrade = require('./get_anchored_trade');
|
|
1
5
|
const manageTrades = require('./manage_trades');
|
|
6
|
+
const serviceAnchoredTrades = require('./service_anchored_trades');
|
|
2
7
|
|
|
3
|
-
module.exports = {
|
|
8
|
+
module.exports = {
|
|
9
|
+
createAnchoredTrade,
|
|
10
|
+
decodeTrade,
|
|
11
|
+
encodeTrade,
|
|
12
|
+
getAnchoredTrade,
|
|
13
|
+
manageTrades,
|
|
14
|
+
serviceAnchoredTrades,
|
|
15
|
+
};
|
|
@@ -13,6 +13,7 @@ const defaultInvoicesLimit = 100;
|
|
|
13
13
|
const events = ['details', 'error', 'failure', 'settled', 'trade'];
|
|
14
14
|
const fromNow = date => new Date(date) - new Date();
|
|
15
15
|
const {keys} = Object;
|
|
16
|
+
const sumOf = arr => arr.reduce((sum, n) => sum + n, 0);
|
|
16
17
|
|
|
17
18
|
/** Service trades represented by anchored invoices
|
|
18
19
|
|
|
@@ -47,6 +48,7 @@ const {keys} = Object;
|
|
|
47
48
|
// Starting service for trade
|
|
48
49
|
@event 'start'
|
|
49
50
|
{
|
|
51
|
+
created_at: <Open Trade Created At ISO 8601 Date String>
|
|
50
52
|
description: <Trade Description String>
|
|
51
53
|
expires_at: <Trade Expires at ISO 8601 Date String>
|
|
52
54
|
id: <Trade Id Hex String>
|
|
@@ -86,6 +88,7 @@ module.exports = ({lnd}) => {
|
|
|
86
88
|
|
|
87
89
|
// Pick up the trade to service
|
|
88
90
|
emitter.emit('start', {
|
|
91
|
+
created_at: trade.created_at,
|
|
89
92
|
description: trade.description,
|
|
90
93
|
expires_at: trade.expires_at,
|
|
91
94
|
id: trade.id,
|
|
@@ -129,6 +132,28 @@ module.exports = ({lnd}) => {
|
|
|
129
132
|
// Listen for any new invoices that represent anchored trades
|
|
130
133
|
const sub = subscribeToInvoices({lnd});
|
|
131
134
|
|
|
135
|
+
// Stop servicing all trades
|
|
136
|
+
const stopService = () => {
|
|
137
|
+
// Stop paging in progress
|
|
138
|
+
paging.token = false;
|
|
139
|
+
|
|
140
|
+
// Stop listening to all invoices
|
|
141
|
+
sub.removeAllListeners();
|
|
142
|
+
|
|
143
|
+
// Stop listening to all anchor invoices
|
|
144
|
+
return keys(listening).forEach(id => listening[id].removeAllListeners());
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
// Stop the service when there are no more listeners
|
|
148
|
+
emitter.on('removeListener', () => {
|
|
149
|
+
// Exit early when there are still listeners on an event
|
|
150
|
+
if (!!sumOf(events.map(n => emitter.listenerCount(n)))) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return stopService();
|
|
155
|
+
});
|
|
156
|
+
|
|
132
157
|
// Listen for new trades to appear
|
|
133
158
|
sub.on('invoice_updated', invoice => {
|
|
134
159
|
const {trade} = tradeFromInvoice(invoice);
|
|
@@ -155,13 +180,13 @@ module.exports = ({lnd}) => {
|
|
|
155
180
|
if (!!err) {
|
|
156
181
|
emitter.emit(err);
|
|
157
182
|
|
|
158
|
-
// Stop
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
// Stop listening to all anchor invoices
|
|
162
|
-
keys(listening).forEach(id => listening[id].removeAllListeners());
|
|
183
|
+
// Stop the service
|
|
184
|
+
return stopService();
|
|
185
|
+
}
|
|
163
186
|
|
|
164
|
-
|
|
187
|
+
// Exit early when paging is already stopped
|
|
188
|
+
if (paging.token === false) {
|
|
189
|
+
return cbk();
|
|
165
190
|
}
|
|
166
191
|
|
|
167
192
|
paging.token = res.next || false;
|
|
@@ -3,6 +3,7 @@ const decodeAnchoredTrade = require('./decode_anchored_trade');
|
|
|
3
3
|
/** Derive open trade details from an invoice
|
|
4
4
|
|
|
5
5
|
{
|
|
6
|
+
created_at: <Invoice Created At ISO 8601 Date String>
|
|
6
7
|
description: <Invoice Description String>
|
|
7
8
|
id: <Invoice Id Hex String>
|
|
8
9
|
expires_at: <Invoice Expiration ISO 8601 Date String>
|
|
@@ -15,6 +16,7 @@ const decodeAnchoredTrade = require('./decode_anchored_trade');
|
|
|
15
16
|
@returns
|
|
16
17
|
{
|
|
17
18
|
[trade]: {
|
|
19
|
+
created_at: <Open Trade Created At ISO 8601 Date String>
|
|
18
20
|
description: <Trade Description String>
|
|
19
21
|
expires_at: <Trade Expires at ISO 8601 Date String>
|
|
20
22
|
id: <Trade Id Hex String>
|
|
@@ -41,6 +43,7 @@ module.exports = args => {
|
|
|
41
43
|
|
|
42
44
|
return {
|
|
43
45
|
trade: {
|
|
46
|
+
created_at: args.created_at,
|
|
44
47
|
description: trade.description,
|
|
45
48
|
expires_at: args.expires_at,
|
|
46
49
|
id: args.id,
|