paid-services 3.17.0 → 3.18.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 CHANGED
@@ -1,6 +1,10 @@
1
1
  # Versions
2
2
 
3
- ## Version 3.17.0
3
+ ## Version 3.18.0
4
+
5
+ - `manageGroupJoin`: Add conflict tx for safe funded pending channel deletion
6
+
7
+ ## Version 3.17.2
4
8
 
5
9
  - `manageGroupJoin`: Add method to coordinate or join a channels group
6
10
 
@@ -1,4 +1,5 @@
1
1
  const asyncAuto = require('async/auto');
2
+ const asyncRetry = require('async/retry');
2
3
  const {connectPeer} = require('ln-sync');
3
4
  const {getChainBalance} = require('ln-service');
4
5
  const {getNodeAlias} = require('ln-sync');
@@ -8,9 +9,11 @@ const {getGroupDetails} = require('./p2p');
8
9
 
9
10
  const coordinatorFromJoinCode = n => n.slice(0, 66);
10
11
  const groupIdFromJoinCode = n => n.slice(66);
12
+ const interval = 500;
11
13
  const isCode = n => !!n && n.length === 98;
12
14
  const isPublicKey = n => !!n && /^0[2-3][0-9A-F]{64}$/i.test(n);
13
15
  const niceName = n => `${n.alias} ${n.id}`.trim();
16
+ const times = 2 * 60;
14
17
  const tokensAsBigUnit = tokens => (tokens / 1e8).toFixed(8);
15
18
 
16
19
  /** Ask to confirm joining a group
@@ -73,7 +76,10 @@ module.exports = ({ask, lnd}, cbk) => {
73
76
 
74
77
  // Connect to the coordinator
75
78
  connect: ['group', ({group}, cbk) => {
76
- return connectPeer({lnd, id: group.coordinator}, cbk);
79
+ return asyncRetry({interval, times}, cbk => {
80
+ return connectPeer({lnd, id: group.coordinator}, cbk);
81
+ },
82
+ cbk);
77
83
  }],
78
84
 
79
85
  // Get the coordinator node alias
@@ -78,6 +78,9 @@ module.exports = ({capacity, count, ecp, identity, lnd, rate}) => {
78
78
  return emitter.emit('error', err);
79
79
  };
80
80
 
81
+ // An error was encountered
82
+ coordinator.events.once('error', errored);
83
+
81
84
  // Group members have registered themselves
82
85
  coordinator.events.once('joined', async ({ids}) => {
83
86
  emitter.emit('filled', {ids});
@@ -59,7 +59,7 @@ module.exports = ({ask, lnd, logger}, cbk) => {
59
59
  rate: askForDetails.rate,
60
60
  });
61
61
 
62
- join.once('end', ({id}) => cbk(null, {id}));
62
+ join.once('end', ({id}) => cbk(null, {transaction_id: id}));
63
63
  join.once('error', err => cbk(err));
64
64
 
65
65
  join.once('peering', async ({inbound, outbound}) => {
@@ -70,7 +70,9 @@ module.exports = ({ask, lnd, logger}, cbk) => {
70
70
  return logger.info({peering_with: formatNodes(nodes)});
71
71
  });
72
72
 
73
- join.once('publishing', () => logger.info({publishing: true}));
73
+ join.once('publishing', ({refund, signed}) => {
74
+ return logger.info({refund, signed});
75
+ });
74
76
 
75
77
  return;
76
78
  }],
@@ -107,7 +107,7 @@ module.exports = ({ask, lnd, logger}, cbk) => {
107
107
  coordinate.events.once('broadcast', broadcast => {
108
108
  coordinate.events.removeAllListeners();
109
109
 
110
- return cbk(null, {id: broadcast.id});
110
+ return cbk(null, {transaction_id: broadcast.id});
111
111
  });
112
112
 
113
113
  coordinate.events.once('error', err => {
@@ -13,6 +13,8 @@ const half = n => n / 2;
13
13
  lnd: <Authenticated LND API Object>
14
14
  to: <Look for Outgoing Channel To Identity Public Key Hex String>
15
15
  }
16
+
17
+ @returns via cbk or Promise
16
18
  */
17
19
  module.exports = ({capacity, from, id, lnd, to}, cbk) => {
18
20
  return new Promise((resolve, reject) => {
@@ -1,18 +1,28 @@
1
+ const {address} = require('bitcoinjs-lib');
1
2
  const asyncAuto = require('async/auto');
2
3
  const asyncRetry = require('async/retry');
4
+ const {createChainAddress} = require('ln-service');
5
+ const {createPsbt} = require('psbt');
3
6
  const {decodePsbt} = require('psbt');
4
7
  const {extendPsbt} = require('psbt');
5
8
  const {fundPendingChannels} = require('ln-service');
9
+ const {getChainFeeRate} = require('ln-service');
10
+ const {getMaxFundAmount} = require('ln-sync');
6
11
  const {getPendingChannels} = require('ln-service');
7
12
  const {partiallySignPsbt} = require('ln-service');
13
+ const {payments} = require('bitcoinjs-lib');
8
14
  const {returnResult} = require('asyncjs-util');
15
+ const {signPsbt} = require('ln-service');
9
16
  const tinysecp = require('tiny-secp256k1');
10
17
  const {Transaction} = require('bitcoinjs-lib');
11
18
  const {unextractTransaction} = require('psbt');
12
19
 
20
+ const bufferAsHex = buffer => buffer.toString('hex');
13
21
  const {concat} = Buffer;
14
22
  const dummySignature = Buffer.alloc(1);
23
+ const format = 'p2wpkh';
15
24
  const {from} = Buffer;
25
+ const {fromBech32} = address;
16
26
  const {fromHex} = Transaction;
17
27
  const hashAll = Transaction.SIGHASH_ALL;
18
28
  const hashDefault = Transaction.SIGHASH_DEFAULT;
@@ -21,6 +31,9 @@ const inputAsOutpoint = n => `${n.transaction_id}:${n.transaction_vout}`;
21
31
  const interval = 10;
22
32
  const {isArray} = Array;
23
33
  const notEmpty = arr => arr.filter(n => !!n);
34
+ const {p2wpkh} = payments;
35
+ const {random} = Math;
36
+ const slowConf = 144;
24
37
  const spendAsOutpoint = n => `${n.hash.reverse().toString('hex')}:${n.index}`;
25
38
  const times = 500;
26
39
 
@@ -49,6 +62,7 @@ const times = 500;
49
62
 
50
63
  @returns via cbk or Promise
51
64
  {
65
+ conflict: <Conflict Transaction Hex String>
52
66
  psbt: <Partially Signed PSBT Hex String>
53
67
  }
54
68
  */
@@ -79,11 +93,94 @@ module.exports = ({id, lnd, psbt, utxos}, cbk) => {
79
93
  return cbk();
80
94
  },
81
95
 
96
+ // Create a conflicting address to refund funds to
97
+ createConflictAddress: ['validate', ({}, cbk) => {
98
+ return createChainAddress({format, lnd}, cbk);
99
+ }],
100
+
101
+ // Get the conflicting tx fee rate
102
+ getRate: ['validate', ({}, cbk) => {
103
+ return getChainFeeRate({lnd, confirmation_target: slowConf}, cbk);
104
+ }],
105
+
106
+ // Find the conflicting amount to send to the refund address
107
+ getConflictAmount: [
108
+ 'createConflictAddress',
109
+ 'getRate',
110
+ ({createConflictAddress, getRate}, cbk) =>
111
+ {
112
+ const [input] = utxos;
113
+
114
+ return getMaxFundAmount({
115
+ lnd,
116
+ addresses: [createConflictAddress.address],
117
+ fee_tokens_per_vbyte: getRate.tokens_per_vbyte,
118
+ inputs: [{
119
+ tokens: input.witness_utxo.tokens,
120
+ transaction_id: input.transaction_id,
121
+ transaction_vout: input.transaction_vout,
122
+ }],
123
+ },
124
+ cbk);
125
+ }],
126
+
127
+ // Create a conflicting PSBT to sign
128
+ conflict: [
129
+ 'createConflictAddress',
130
+ 'ecp',
131
+ 'getConflictAmount',
132
+ ({createConflictAddress, ecp, getConflictAmount}, cbk) =>
133
+ {
134
+ const hash = fromBech32(createConflictAddress.address).data;
135
+ const [input] = utxos;
136
+
137
+ const {psbt} = createPsbt({
138
+ outputs: [{
139
+ script: bufferAsHex(p2wpkh({hash}).output),
140
+ tokens: getConflictAmount.max_tokens,
141
+ }],
142
+ utxos: [{
143
+ id: input.transaction_id,
144
+ vout: input.transaction_vout,
145
+ }],
146
+ });
147
+
148
+ const base = decodePsbt({ecp, psbt});
149
+
150
+ const tx = fromHex(base.unsigned_transaction);
151
+
152
+ const inputs = base.inputs.map((input, vin) => {
153
+ const outpoint = spendAsOutpoint(tx.ins[vin]);
154
+
155
+ // Look for relevant signing instructions
156
+ const utxo = utxos.find(n => inputAsOutpoint(n) === outpoint) || {};
157
+
158
+ return {
159
+ bip32_derivations: utxo.bip32_derivations,
160
+ non_witness_utxo: utxo.non_witness_utxo,
161
+ sighash_type: !!utxo.non_witness_utxo ? hashAll : hashDefault,
162
+ witness_utxo: utxo.witness_utxo,
163
+ };
164
+ });
165
+
166
+ // Extend the base PSBT with relevant signing information
167
+ return cbk(null, extendPsbt({ecp, inputs, psbt}).psbt);
168
+ }],
169
+
170
+ // Decode the PSBT to get the unsigned funding transaction
171
+ funding: ['ecp', 'validate', ({ecp}, cbk) => {
172
+ try {
173
+ return cbk(null, decodePsbt({ecp, psbt}));
174
+ } catch (err) {
175
+ return cbk([400, 'ExpectedValidPsbtToSignAndFundChannel', {err}]);
176
+ }
177
+ }],
178
+
82
179
  // Extend the PSBT with the derivation paths
83
- psbtToSign: ['ecp', 'validate', ({ecp}, cbk) => {
84
- const tx = fromHex(decodePsbt({ecp, psbt}).unsigned_transaction);
180
+ psbtToSign: ['ecp', 'funding', ({ecp, funding}, cbk) => {
181
+ const tx = fromHex(funding.unsigned_transaction);
85
182
 
86
- const inputs = decodePsbt({ecp, psbt}).inputs.map((input, vin) => {
183
+ const inputs = funding.inputs.map((input, vin) => {
87
184
  const outpoint = spendAsOutpoint(tx.ins[vin]);
88
185
 
89
186
  // Look for relevant signing instructions
@@ -101,6 +198,11 @@ module.exports = ({id, lnd, psbt, utxos}, cbk) => {
101
198
  return cbk(null, {psbt: extendPsbt({ecp, inputs, psbt}).psbt});
102
199
  }],
103
200
 
201
+ // Sign and finalize the conflicting PSBT
202
+ signConflict: ['conflict', ({conflict}, cbk) => {
203
+ return signPsbt({lnd, psbt: conflict}, cbk);
204
+ }],
205
+
104
206
  // Partially sign the PSBT that funds the channel open
105
207
  signPsbt: ['psbtToSign', ({psbtToSign}, cbk) => {
106
208
  return partiallySignPsbt({lnd, psbt: psbtToSign.psbt}, cbk);
@@ -151,7 +253,7 @@ module.exports = ({id, lnd, psbt, utxos}, cbk) => {
151
253
  }],
152
254
 
153
255
  // Fund the pending channel with the finalized PSBT
154
- fundChannel: ['finalizePsbt', ({finalizePsbt}, cbk) => {
256
+ fundChannel: ['conflict', 'finalizePsbt', ({finalizePsbt}, cbk) => {
155
257
  return fundPendingChannels({
156
258
  lnd,
157
259
  channels: [id],
@@ -182,7 +284,35 @@ module.exports = ({id, lnd, psbt, utxos}, cbk) => {
182
284
  },
183
285
  cbk);
184
286
  }],
287
+
288
+ // Final group funding transaction resolution
289
+ result: [
290
+ 'ecp',
291
+ 'signConflict',
292
+ 'signPsbt',
293
+ ({ecp, signConflict, signPsbt}, cbk) =>
294
+ {
295
+ const signed = decodePsbt({ecp, psbt: signPsbt.psbt});
296
+
297
+ const extended = extendPsbt({
298
+ ecp,
299
+ psbt,
300
+ inputs: signed.inputs.map(input => {
301
+ return {
302
+ non_witness_utxo: input.non_witness_utxo,
303
+ partial_sig: input.partial_sig,
304
+ taproot_key_spend_sig: input.taproot_key_spend_sig,
305
+ witness_utxo: input.witness_utxo,
306
+ };
307
+ }),
308
+ });
309
+
310
+ return cbk(null, {
311
+ conflict: signConflict.transaction,
312
+ psbt: extended.psbt,
313
+ });
314
+ }],
185
315
  },
186
- returnResult({reject, resolve, of: 'signPsbt'}, cbk));
316
+ returnResult({reject, resolve, of: 'result'}, cbk));
187
317
  });
188
318
  };
@@ -1,8 +1,11 @@
1
1
  const EventEmitter = require('events');
2
2
 
3
3
  const asyncAuto = require('async/auto');
4
+ const asyncReflect = require('async/reflect');
4
5
  const asyncRetry = require('async/retry');
6
+ const {cancelPendingChannel} = require('ln-service');
5
7
  const {decodePsbt} = require('psbt');
8
+ const {deletePendingChannel} = require('ln-service');
6
9
  const {returnResult} = require('asyncjs-util');
7
10
  const tinysecp = require('tiny-secp256k1');
8
11
  const {Transaction} = require('bitcoinjs-lib');
@@ -16,6 +19,7 @@ const {registerPendingOpen} = require('./p2p');
16
19
  const {registerSignedOpen} = require('./p2p');
17
20
 
18
21
  const {fromHex} = Transaction;
22
+ const hexAsBuffer = hex => Buffer.from(hex, 'hex');
19
23
  const interval = 1000;
20
24
  const times = 60 * 10;
21
25
 
@@ -138,10 +142,22 @@ module.exports = ({capacity, coordinator, count, id, lnd, rate}, cbk) => {
138
142
  }],
139
143
 
140
144
  // Decode the unsigned PSBT
141
- transaction: ['ecp', 'register', ({ecp, register}, cbk) => {
145
+ transaction: [
146
+ 'ecp',
147
+ 'propose',
148
+ 'register',
149
+ ({ecp, propose, register}, cbk) =>
150
+ {
151
+ const funding = hexAsBuffer(propose.funding);
142
152
  const psbt = decodePsbt({ecp, psbt: register.psbt});
143
153
 
144
- return cbk(null, {id: fromHex(psbt.unsigned_transaction).getId()});
154
+ const tx = fromHex(psbt.unsigned_transaction);
155
+
156
+ return cbk(null, {
157
+ id: tx.getId(),
158
+ raw: psbt.unsigned_transaction,
159
+ vout: tx.outs.findIndex(n => n.script.equals(funding)),
160
+ });
145
161
  }],
146
162
 
147
163
  // Confirm the incoming channel
@@ -150,7 +166,7 @@ module.exports = ({capacity, coordinator, count, id, lnd, rate}, cbk) => {
150
166
  'partners',
151
167
  'register',
152
168
  'transaction',
153
- ({ecp, partners, register, transaction}, cbk) =>
169
+ asyncReflect(({ecp, partners, register, transaction}, cbk) =>
154
170
  {
155
171
  // Make sure that there is an inbound channel
156
172
  return asyncRetry({interval, times}, cbk => {
@@ -164,12 +180,45 @@ module.exports = ({capacity, coordinator, count, id, lnd, rate}, cbk) => {
164
180
  cbk);
165
181
  },
166
182
  cbk);
183
+ })],
184
+
185
+ // Clean up funding pending channels when the channel group fails
186
+ clean: [
187
+ 'incoming',
188
+ 'propose',
189
+ 'register',
190
+ 'transaction',
191
+ ({incoming, propose, register, transaction}, cbk) =>
192
+ {
193
+ // Exit early when incoming channel is seen
194
+ if (!incoming.error) {
195
+ return cbk();
196
+ }
197
+
198
+ // When there was no incoming channel detected, fail and clean up
199
+ return deletePendingChannel({
200
+ lnd,
201
+ confirmed_transaction: register.conflict,
202
+ pending_transaction: transaction.raw,
203
+ pending_transaction_vout: transaction.vout,
204
+ },
205
+ err => {
206
+ if (!!err) {
207
+ return cbk([503, 'UnexpectedErrorCleaningUpGroupChannel', {err}]);
208
+ }
209
+
210
+ // Pass back the original error
211
+ return cbk(incoming.error);
212
+ });
167
213
  }],
168
214
 
169
215
  // Publish partial signatures to coordinator
170
- reveal: ['incoming', 'register', ({register}, cbk) => {
216
+ reveal: ['clean', 'incoming', 'register', ({register}, cbk) => {
171
217
  // Let listeners know that the signature will be sent to coordinator
172
- emitter.emit('publishing', {});
218
+ emitter.emit('publishing', {
219
+ refund: register.conflict,
220
+ signed: register.psbt,
221
+ });
173
222
 
174
223
  return registerSignedOpen({
175
224
  coordinator,
@@ -1,5 +1,7 @@
1
1
  const asyncAuto = require('async/auto');
2
+ const asyncReflect = require('async/reflect');
2
3
  const asyncRetry = require('async/retry');
4
+ const {cancelPendingChannel} = require('ln-service');
3
5
  const {connectPeer} = require('ln-sync');
4
6
  const {decodePsbt} = require('psbt');
5
7
  const {returnResult} = require('asyncjs-util');
@@ -46,7 +48,8 @@ const typeGroupChannelId = '1';
46
48
 
47
49
  @returns via cbk or Promise
48
50
  {
49
- psbt: <Unsigned PSBT Hex String>
51
+ conflict: <Conflict Transaction Hex String>
52
+ psbt: <Partially Signed PSBT Hex String>
50
53
  }
51
54
  */
52
55
  module.exports = (args, cbk) => {
@@ -94,7 +97,7 @@ module.exports = (args, cbk) => {
94
97
  }],
95
98
 
96
99
  // Send connection confirmation request
97
- request: ['connect', ({}, cbk) => {
100
+ request: ['connect', asyncReflect(({}, cbk) => {
98
101
  const {records} = encodePendingProposal({
99
102
  change: args.change,
100
103
  funding: args.funding,
@@ -145,17 +148,34 @@ module.exports = (args, cbk) => {
145
148
  });
146
149
  },
147
150
  cbk);
151
+ })],
152
+
153
+ // Clean up the pending channel if registration fails
154
+ clean: ['request', ({request}, cbk) => {
155
+ // Exit early when there was no error registering the pending channel
156
+ if (!request.error) {
157
+ return cbk();
158
+ }
159
+
160
+ return cancelPendingChannel({id: args.pending, lnd: args.lnd}, err => {
161
+ if (!!err) {
162
+ return cbk([503, 'UnexpectedErrorCleaningPendingChannel', {err}]);
163
+ }
164
+
165
+ // Return the original registration error
166
+ return cbk(request.error);
167
+ });
148
168
  }],
149
169
 
150
170
  // Check the unsigned funding transaction represents the partial open
151
- check: ['ecp', 'request', ({ecp, request}, cbk) => {
171
+ check: ['clean', 'ecp', 'request', ({ecp, request}, cbk) => {
152
172
  try {
153
- decodePsbt({ecp, psbt: request});
173
+ decodePsbt({ecp, psbt: request.value});
154
174
  } catch (err) {
155
175
  return cbk([503, 'ExpectedValidUnsignedResponsePsbt', {err}]);
156
176
  }
157
177
 
158
- const psbt = decodePsbt({ecp, psbt: request});
178
+ const psbt = decodePsbt({ecp, psbt: request.value});
159
179
 
160
180
  const tx = fromHex(psbt.unsigned_transaction);
161
181
 
@@ -207,7 +227,7 @@ module.exports = (args, cbk) => {
207
227
  return signAndFundGroupChannel({
208
228
  id: args.pending,
209
229
  lnd: args.lnd,
210
- psbt: request,
230
+ psbt: request.value,
211
231
  utxos: args.utxos,
212
232
  },
213
233
  cbk);
package/package.json CHANGED
@@ -15,10 +15,10 @@
15
15
  "bolt07": "1.8.2",
16
16
  "ecpair": "2.0.1",
17
17
  "goldengate": "11.2.3",
18
- "invoices": "2.0.7",
18
+ "invoices": "2.1.0",
19
19
  "ln-service": "53.17.4",
20
20
  "ln-sync": "3.13.0",
21
- "psbt": "2.6.0",
21
+ "psbt": "2.7.0",
22
22
  "p2tr": "1.3.1",
23
23
  "tiny-secp256k1": "2.2.1"
24
24
  },
@@ -47,5 +47,5 @@
47
47
  "integration-tests": "tap -j 2 --branches=1 --functions=1 --lines=1 --statements=1 -t 180 test/integration/*.js",
48
48
  "test": "tap --branches=1 --functions=1 --lines=1 --statements=1 -t 60 test/actions/*.js test/balanced/*.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"
49
49
  },
50
- "version": "3.17.0"
50
+ "version": "3.18.0"
51
51
  }
@@ -80,7 +80,7 @@ module.exports = ({ask, lnd, logger}, cbk) => {
80
80
  return true;
81
81
  },
82
82
  },
83
- cbk);
83
+ res => cbk(null, res));
84
84
  }],
85
85
 
86
86
  // Decode the connect details
@@ -108,7 +108,7 @@ module.exports = ({ask, lnd, logger, request}, cbk) => {
108
108
  message: `Pay ${parseRequest.tokens} and ${getRoute.fee} fee?`,
109
109
  type: 'confirm',
110
110
  },
111
- cbk);
111
+ res => cbk(null, res));
112
112
  }],
113
113
 
114
114
  // Pay the request
@@ -112,7 +112,7 @@ module.exports = ({ask, lnd, logger, request}, cbk) => {
112
112
  return true;
113
113
  },
114
114
  },
115
- cbk);
115
+ res => cbk(null, res));
116
116
  }],
117
117
 
118
118
  // Select method of pricing
@@ -128,7 +128,7 @@ module.exports = ({ask, lnd, logger, request}, cbk) => {
128
128
  name: 'action',
129
129
  type: 'list',
130
130
  },
131
- cbk);
131
+ res => cbk(null, res));
132
132
  }],
133
133
 
134
134
  // Ask for fiat based cost
@@ -156,7 +156,7 @@ module.exports = ({ask, lnd, logger, request}, cbk) => {
156
156
  return true;
157
157
  },
158
158
  },
159
- cbk);
159
+ res => cbk(null, res));
160
160
  }],
161
161
 
162
162
  // Ask for absolute cost
@@ -189,7 +189,7 @@ module.exports = ({ask, lnd, logger, request}, cbk) => {
189
189
  return true;
190
190
  },
191
191
  },
192
- cbk);
192
+ res => cbk(null, res));
193
193
  }],
194
194
 
195
195
  // Ask for rate-based cost
@@ -222,7 +222,7 @@ module.exports = ({ask, lnd, logger, request}, cbk) => {
222
222
  return true;
223
223
  },
224
224
  },
225
- cbk);
225
+ res => cbk(null, res));
226
226
  }],
227
227
 
228
228
  // Ask for the expiration of the channel sale
@@ -239,7 +239,7 @@ module.exports = ({ask, lnd, logger, request}, cbk) => {
239
239
  return true;
240
240
  },
241
241
  },
242
- cbk);
242
+ res => cbk(null, res));
243
243
  }],
244
244
 
245
245
  // Check ability to get fiat prices
@@ -88,7 +88,7 @@ module.exports = ({ask, lnd, logger, request}, cbk) => {
88
88
  return true;
89
89
  },
90
90
  },
91
- cbk);
91
+ res => cbk(null, res));
92
92
  }],
93
93
 
94
94
  // Get the public channels to use for an open trade
@@ -129,7 +129,7 @@ module.exports = ({ask, lnd, logger, request}, cbk) => {
129
129
  return true;
130
130
  },
131
131
  },
132
- cbk);
132
+ res => cbk(null, res));
133
133
  }],
134
134
 
135
135
  // Ask for the actual payload of the trade
@@ -150,7 +150,7 @@ module.exports = ({ask, lnd, logger, request}, cbk) => {
150
150
  return true;
151
151
  },
152
152
  },
153
- cbk);
153
+ res => cbk(null, res));
154
154
  }],
155
155
 
156
156
  // Select pricing type
@@ -173,7 +173,7 @@ module.exports = ({ask, lnd, logger, request}, cbk) => {
173
173
  name: 'type',
174
174
  type: 'list',
175
175
  },
176
- cbk);
176
+ res => cbk(null, res));
177
177
  }],
178
178
 
179
179
  // Ask for the fiat price of the secret
@@ -201,7 +201,7 @@ module.exports = ({ask, lnd, logger, request}, cbk) => {
201
201
  return true;
202
202
  },
203
203
  },
204
- cbk);
204
+ res => cbk(null, res));
205
205
  }],
206
206
 
207
207
  // Ask for the price of the secret
@@ -234,7 +234,7 @@ module.exports = ({ask, lnd, logger, request}, cbk) => {
234
234
  return true;
235
235
  },
236
236
  },
237
- cbk);
237
+ res => cbk(null, res));
238
238
  }],
239
239
 
240
240
  // Ask for the expiration of the trade
@@ -252,7 +252,7 @@ module.exports = ({ask, lnd, logger, request}, cbk) => {
252
252
  return true;
253
253
  },
254
254
  },
255
- cbk);
255
+ res => cbk(null, res));
256
256
  }],
257
257
 
258
258
  // Get the conversion to tokens for fiat
@@ -184,7 +184,7 @@ module.exports = ({ask, id, lnd, logger, nodes}, cbk) => {
184
184
  name: 'id',
185
185
  type: 'list',
186
186
  },
187
- cbk);
187
+ res => cbk(null, res));
188
188
  }],
189
189
 
190
190
  // Fetch the full trade-secret that was selected
@@ -56,7 +56,7 @@ module.exports = ({ask, lnd, logger}, cbk) => {
56
56
  type: 'input',
57
57
  validate: input => !!input,
58
58
  },
59
- cbk);
59
+ res => cbk(null, res));
60
60
  }],
61
61
 
62
62
  // Derive the self public key
@@ -182,7 +182,7 @@ module.exports = ({ask, lnd, logger}, cbk) => {
182
182
  name: 'action',
183
183
  type: 'list',
184
184
  },
185
- cbk);
185
+ res => cbk(null, res));
186
186
  }],
187
187
 
188
188
  // Cancel past offer
@@ -244,7 +244,7 @@ module.exports = ({ask, lnd, logger}, cbk) => {
244
244
  name: 'action',
245
245
  type: 'list',
246
246
  },
247
- cbk);
247
+ res => cbk(null, res));
248
248
  }],
249
249
 
250
250
  // Ask for preimage in case it is separately known
@@ -279,7 +279,7 @@ module.exports = ({ask, lnd, logger}, cbk) => {
279
279
  return true;
280
280
  },
281
281
  },
282
- cbk);
282
+ res => cbk(null, res));
283
283
  }],
284
284
 
285
285
  // Pay and get the preimage through paying for it
@@ -95,7 +95,7 @@ module.exports = ({ask, lnd, logger, request, separator}, cbk) => {
95
95
  name: 'action',
96
96
  type: 'list',
97
97
  },
98
- cbk);
98
+ res => cbk(null, res));
99
99
  }],
100
100
 
101
101
  // Confirm that signer RPC is enabled, this is required for trade secret
@@ -212,7 +212,7 @@ module.exports = ({ask, lnd, logger, request, separator}, cbk) => {
212
212
  name: 'manage',
213
213
  type: 'list',
214
214
  },
215
- cbk);
215
+ res => cbk(null, res));
216
216
  }],
217
217
 
218
218
  // Manage an open trades
@@ -232,7 +232,7 @@ module.exports = ({ask, lnd, logger, request, separator}, cbk) => {
232
232
  name: 'trade',
233
233
  type: 'list',
234
234
  },
235
- cbk);
235
+ res => cbk(null, res));
236
236
  }],
237
237
 
238
238
  // Service an open trade