ln-service 59.3.1 → 59.3.3
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 +1 -1
- package/package.json +11 -10
- package/test/integration/test_propose_channel.js +66 -63
- package/test/macros/index.js +0 -16
- package/test/signerrpc-integration/test_begin_group_signing_session.js +159 -97
- package/test/signerrpc-integration/test_sign_taproot.js +136 -68
- package/test/walletrpc-integration/test_fund_psbt.js +169 -100
- package/test/macros/btcsuite_type_daemon.js +0 -143
- package/test/macros/chain_send_transaction.js +0 -102
- package/test/macros/change_password.js +0 -441
- package/test/macros/connect_chain_node.js +0 -27
- package/test/macros/create_cluster.js +0 -426
- package/test/macros/generate_blocks.js +0 -141
- package/test/macros/get_raw_transaction.js +0 -78
- package/test/macros/mine_transaction.js +0 -87
- package/test/macros/rpc.js +0 -82
- package/test/macros/spawn_chain_daemon.js +0 -88
- package/test/macros/spawn_lnd.js +0 -558
|
@@ -1,426 +0,0 @@
|
|
|
1
|
-
const {promisify} = require('util');
|
|
2
|
-
|
|
3
|
-
const asyncAuto = require('async/auto');
|
|
4
|
-
const asyncEach = require('async/each');
|
|
5
|
-
const asyncRetry = require('async/retry');
|
|
6
|
-
const tinysecp = require('tiny-secp256k1');
|
|
7
|
-
|
|
8
|
-
const {addPeer} = require('./../../');
|
|
9
|
-
const chainSendTransaction = require('./chain_send_transaction');
|
|
10
|
-
const connectChainNode = require('./connect_chain_node');
|
|
11
|
-
const {createChainAddress} = require('./../../');
|
|
12
|
-
const generateBlocks = require('./generate_blocks');
|
|
13
|
-
const {getWalletInfo} = require('./../../');
|
|
14
|
-
const mineTransaction = require('./mine_transaction');
|
|
15
|
-
const rpc = require('./rpc');
|
|
16
|
-
const spawnLnd = require('./spawn_lnd');
|
|
17
|
-
const waitForTermination = require('./wait_for_termination');
|
|
18
|
-
|
|
19
|
-
const defaultFee = 1e3;
|
|
20
|
-
const defaultVout = 0;
|
|
21
|
-
const format = 'np2wpkh';
|
|
22
|
-
const maturityBlockCount = 429;
|
|
23
|
-
const retryMs = 20;
|
|
24
|
-
const retryTimes = 1000;
|
|
25
|
-
const seed = 'abandon tank dose ripple foil subway close flock laptop cabbage primary silent plastic unhappy west weird panda plastic brave prefer diesel glad jazz isolate';
|
|
26
|
-
const tokens = 50e8;
|
|
27
|
-
|
|
28
|
-
/** Create a cluster of lnds
|
|
29
|
-
|
|
30
|
-
{
|
|
31
|
-
[is_circular_enabled]: <Allow Circular Payments Bool>
|
|
32
|
-
[is_keysend_enabled]: <Nodes Accept Keysend Payments Bool>
|
|
33
|
-
[is_remote_skipped]: <Is Remote Node Creation Skipped Bool>
|
|
34
|
-
[nodes]: [{
|
|
35
|
-
chain_rpc_cert: <RPC Cert Path String>
|
|
36
|
-
chain_rpc_pass: <Chain RPC Password String>
|
|
37
|
-
chain_rpc_port: <RPC Port Number>
|
|
38
|
-
chain_rpc_user: <Chain RPC Username String>
|
|
39
|
-
kill: <Kill Function>
|
|
40
|
-
listen_ip: <Listen Ip String>
|
|
41
|
-
}]
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
@returns via cbk
|
|
45
|
-
{
|
|
46
|
-
control: {
|
|
47
|
-
kill: <Kill Function>
|
|
48
|
-
lnd: <Authenticated LND gRPC Object>
|
|
49
|
-
}
|
|
50
|
-
generate: <Generate Function> ({node, count}) -> (err) -> ()
|
|
51
|
-
kill: <Kill Nodes Promise Function>
|
|
52
|
-
[remote]: {
|
|
53
|
-
kill: <Kill Function>
|
|
54
|
-
lnd: <Authenticated LND gRPC Object>
|
|
55
|
-
}
|
|
56
|
-
target: {
|
|
57
|
-
kill: <Kill Function>
|
|
58
|
-
lnd: <Authenticated LND gRPC Object>
|
|
59
|
-
}
|
|
60
|
-
[remote_node_public_key]: <Remote Node Public Key Hex String>
|
|
61
|
-
target_node_public_key: <Target Node Public Key Hex String>
|
|
62
|
-
}
|
|
63
|
-
*/
|
|
64
|
-
module.exports = (args, cbk) => {
|
|
65
|
-
return asyncAuto({
|
|
66
|
-
// Import ECPair library
|
|
67
|
-
ecp: async () => (await import('ecpair')).ECPairFactory(tinysecp),
|
|
68
|
-
|
|
69
|
-
// Create control lnd
|
|
70
|
-
control: cbk => {
|
|
71
|
-
return spawnLnd({
|
|
72
|
-
seed,
|
|
73
|
-
circular: args.is_circular_enabled,
|
|
74
|
-
keysend: args.is_keysend_enabled,
|
|
75
|
-
},
|
|
76
|
-
cbk);
|
|
77
|
-
},
|
|
78
|
-
|
|
79
|
-
// Create target lnd
|
|
80
|
-
target: cbk => {
|
|
81
|
-
return spawnLnd({
|
|
82
|
-
circular: args.is_circular_enabled,
|
|
83
|
-
keysend: args.is_keysend_enabled,
|
|
84
|
-
},
|
|
85
|
-
cbk);
|
|
86
|
-
},
|
|
87
|
-
|
|
88
|
-
// Create remote lnd
|
|
89
|
-
remote: cbk => {
|
|
90
|
-
if (!!args.is_remote_skipped) {
|
|
91
|
-
return cbk();
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return spawnLnd({
|
|
95
|
-
circular: args.is_circular_enabled,
|
|
96
|
-
keysend: args.is_keysend_enabled,
|
|
97
|
-
},
|
|
98
|
-
cbk);
|
|
99
|
-
},
|
|
100
|
-
|
|
101
|
-
// Get the remote node info
|
|
102
|
-
remoteNode: ['remote', ({remote}, cbk) => {
|
|
103
|
-
if (!!args.is_remote_skipped) {
|
|
104
|
-
return cbk();
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return getWalletInfo({lnd: remote.lnd}, cbk);
|
|
108
|
-
}],
|
|
109
|
-
|
|
110
|
-
// Get the chain rpc cert
|
|
111
|
-
controlCert: ['control', ({control}, cbk) => {
|
|
112
|
-
return cbk(null, control.chain_rpc_cert_file);
|
|
113
|
-
}],
|
|
114
|
-
|
|
115
|
-
// Get the target rpc cert
|
|
116
|
-
targetCert: ['target', ({target}, cbk) => {
|
|
117
|
-
return cbk(null, target.chain_rpc_cert_file);
|
|
118
|
-
}],
|
|
119
|
-
|
|
120
|
-
// Get the target node info
|
|
121
|
-
targetNode: ['target', ({target}, cbk) => {
|
|
122
|
-
return getWalletInfo({lnd: target.lnd}, cbk);
|
|
123
|
-
}],
|
|
124
|
-
|
|
125
|
-
// Make a chain address for control
|
|
126
|
-
controlChainAddress: ['control', ({control}, cbk) => {
|
|
127
|
-
return createChainAddress({format, lnd: control.lnd}, cbk);
|
|
128
|
-
}],
|
|
129
|
-
|
|
130
|
-
// Make a chain address for target
|
|
131
|
-
targetChainAddress: ['target', ({target}, cbk) => {
|
|
132
|
-
return createChainAddress({format, lnd: target.lnd}, cbk);
|
|
133
|
-
}],
|
|
134
|
-
|
|
135
|
-
// Connect target and remote chains together
|
|
136
|
-
connectRemoteAndTargetChain: [
|
|
137
|
-
'control',
|
|
138
|
-
'controlCert',
|
|
139
|
-
'remote',
|
|
140
|
-
({control, controlCert, remote}, cbk) =>
|
|
141
|
-
{
|
|
142
|
-
if (!!args.is_remote_skipped) {
|
|
143
|
-
return cbk();
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
return connectChainNode({
|
|
147
|
-
cert: controlCert,
|
|
148
|
-
connect: `127.0.0.1:${remote.chain_listen_port}`,
|
|
149
|
-
host: control.listen_ip,
|
|
150
|
-
pass: control.chain_rpc_pass,
|
|
151
|
-
port: control.chain_rpc_port,
|
|
152
|
-
user: control.chain_rpc_user,
|
|
153
|
-
},
|
|
154
|
-
cbk);
|
|
155
|
-
}],
|
|
156
|
-
|
|
157
|
-
connectExtra: ['target', ({target}, cbk) => {
|
|
158
|
-
return asyncEach(args.nodes || [], (node, cbk) => {
|
|
159
|
-
return connectChainNode({
|
|
160
|
-
cert: node.chain_rpc_cert_file,
|
|
161
|
-
connect: `127.0.0.1:${target.chain_listen_port}`,
|
|
162
|
-
host: node.listen_ip,
|
|
163
|
-
pass: node.chain_rpc_pass,
|
|
164
|
-
port: node.chain_rpc_port,
|
|
165
|
-
user: node.chain_rpc_user,
|
|
166
|
-
},
|
|
167
|
-
cbk);
|
|
168
|
-
},
|
|
169
|
-
cbk);
|
|
170
|
-
}],
|
|
171
|
-
|
|
172
|
-
// Connect control and target chains together
|
|
173
|
-
connectTargetChain: [
|
|
174
|
-
'control',
|
|
175
|
-
'controlCert',
|
|
176
|
-
'target',
|
|
177
|
-
({control, controlCert, target}, cbk) =>
|
|
178
|
-
{
|
|
179
|
-
return connectChainNode({
|
|
180
|
-
cert: controlCert,
|
|
181
|
-
connect: `127.0.0.1:${target.chain_listen_port}`,
|
|
182
|
-
host: control.listen_ip,
|
|
183
|
-
pass: control.chain_rpc_pass,
|
|
184
|
-
port: control.chain_rpc_port,
|
|
185
|
-
user: control.chain_rpc_user,
|
|
186
|
-
},
|
|
187
|
-
cbk);
|
|
188
|
-
}],
|
|
189
|
-
|
|
190
|
-
// Generate blocks to maturity
|
|
191
|
-
generateBlocks: [
|
|
192
|
-
'connectRemoteAndTargetChain',
|
|
193
|
-
'connectTargetChain',
|
|
194
|
-
'control',
|
|
195
|
-
'controlCert',
|
|
196
|
-
({control, controlCert}, cbk) =>
|
|
197
|
-
{
|
|
198
|
-
return generateBlocks({
|
|
199
|
-
cert: controlCert,
|
|
200
|
-
count: maturityBlockCount,
|
|
201
|
-
host: control.listen_ip,
|
|
202
|
-
pass: control.chain_rpc_pass,
|
|
203
|
-
port: control.chain_rpc_port,
|
|
204
|
-
user: control.chain_rpc_user,
|
|
205
|
-
},
|
|
206
|
-
cbk);
|
|
207
|
-
}],
|
|
208
|
-
|
|
209
|
-
// Add target peer
|
|
210
|
-
addTargetPeer: [
|
|
211
|
-
'control',
|
|
212
|
-
'generateBlocks',
|
|
213
|
-
'target',
|
|
214
|
-
'targetNode',
|
|
215
|
-
({control, target, targetNode}, cbk) =>
|
|
216
|
-
{
|
|
217
|
-
return asyncRetry({interval: retryMs, times: retryTimes}, cbk => {
|
|
218
|
-
return addPeer({
|
|
219
|
-
lnd: control.lnd,
|
|
220
|
-
public_key: targetNode.public_key,
|
|
221
|
-
socket: target.socket,
|
|
222
|
-
},
|
|
223
|
-
cbk);
|
|
224
|
-
},
|
|
225
|
-
cbk);
|
|
226
|
-
}],
|
|
227
|
-
|
|
228
|
-
// Chain funding transactions
|
|
229
|
-
funding: [
|
|
230
|
-
'control',
|
|
231
|
-
'controlChainAddress',
|
|
232
|
-
'ecp',
|
|
233
|
-
'generateBlocks',
|
|
234
|
-
'targetChainAddress',
|
|
235
|
-
({
|
|
236
|
-
control,
|
|
237
|
-
controlChainAddress,
|
|
238
|
-
ecp,
|
|
239
|
-
generateBlocks,
|
|
240
|
-
targetChainAddress,
|
|
241
|
-
},
|
|
242
|
-
cbk) =>
|
|
243
|
-
{
|
|
244
|
-
const {blocks} = generateBlocks;
|
|
245
|
-
|
|
246
|
-
const [controlBlock, targetBlock] = blocks;
|
|
247
|
-
|
|
248
|
-
const [controlCoinbase] = controlBlock.transaction_ids;
|
|
249
|
-
const [targetCoinbase] = targetBlock.transaction_ids;
|
|
250
|
-
|
|
251
|
-
const controlChainSend = chainSendTransaction({
|
|
252
|
-
ecp,
|
|
253
|
-
tokens,
|
|
254
|
-
destination: controlChainAddress.address,
|
|
255
|
-
fee: defaultFee,
|
|
256
|
-
private_key: control.mining_key,
|
|
257
|
-
spend_transaction_id: controlCoinbase,
|
|
258
|
-
spend_vout: defaultVout,
|
|
259
|
-
});
|
|
260
|
-
|
|
261
|
-
const targetChainSend = chainSendTransaction({
|
|
262
|
-
ecp,
|
|
263
|
-
tokens,
|
|
264
|
-
destination: targetChainAddress.address,
|
|
265
|
-
fee: defaultFee,
|
|
266
|
-
private_key: control.mining_key,
|
|
267
|
-
spend_transaction_id: targetCoinbase,
|
|
268
|
-
spend_vout: defaultVout,
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
return cbk(null, {
|
|
272
|
-
control: controlChainSend.transaction,
|
|
273
|
-
target: targetChainSend.transaction
|
|
274
|
-
});
|
|
275
|
-
}],
|
|
276
|
-
|
|
277
|
-
// Generate some funds for control
|
|
278
|
-
generateControlFunds: [
|
|
279
|
-
'control',
|
|
280
|
-
'controlCert',
|
|
281
|
-
'funding',
|
|
282
|
-
({control, controlCert, funding}, cbk) =>
|
|
283
|
-
{
|
|
284
|
-
return mineTransaction({
|
|
285
|
-
transaction: funding.control,
|
|
286
|
-
cert: controlCert,
|
|
287
|
-
host: control.listen_ip,
|
|
288
|
-
pass: control.chain_rpc_pass,
|
|
289
|
-
port: control.chain_rpc_port,
|
|
290
|
-
user: control.chain_rpc_user,
|
|
291
|
-
},
|
|
292
|
-
cbk);
|
|
293
|
-
}],
|
|
294
|
-
|
|
295
|
-
// Generate some funds for target
|
|
296
|
-
generateTargetFunds: [
|
|
297
|
-
'connectRemoteAndTargetChain',
|
|
298
|
-
'control',
|
|
299
|
-
'controlCert',
|
|
300
|
-
'funding',
|
|
301
|
-
'generateControlFunds',
|
|
302
|
-
({control, controlCert, funding}, cbk) =>
|
|
303
|
-
{
|
|
304
|
-
return mineTransaction({
|
|
305
|
-
transaction: funding.target,
|
|
306
|
-
cert: controlCert,
|
|
307
|
-
host: control.listen_ip,
|
|
308
|
-
pass: control.chain_rpc_pass,
|
|
309
|
-
port: control.chain_rpc_port,
|
|
310
|
-
user: control.chain_rpc_user,
|
|
311
|
-
},
|
|
312
|
-
cbk);
|
|
313
|
-
}],
|
|
314
|
-
|
|
315
|
-
// Add remote peer
|
|
316
|
-
addRemotePeer: [
|
|
317
|
-
'connectRemoteAndTargetChain',
|
|
318
|
-
'generateTargetFunds',
|
|
319
|
-
'remote',
|
|
320
|
-
'remoteNode',
|
|
321
|
-
'target',
|
|
322
|
-
({remote, remoteNode, target}, cbk) =>
|
|
323
|
-
{
|
|
324
|
-
if (!!args.is_remote_skipped) {
|
|
325
|
-
return cbk();
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
return asyncRetry({interval: retryMs, times: retryTimes}, cbk => {
|
|
329
|
-
return addPeer({
|
|
330
|
-
lnd: target.lnd,
|
|
331
|
-
public_key: remoteNode.public_key,
|
|
332
|
-
socket: remote.socket,
|
|
333
|
-
},
|
|
334
|
-
cbk);
|
|
335
|
-
},
|
|
336
|
-
cbk);
|
|
337
|
-
}],
|
|
338
|
-
|
|
339
|
-
// Delay so that all the nodes can sync to the chain
|
|
340
|
-
syncToChain: [
|
|
341
|
-
'addRemotePeer',
|
|
342
|
-
'control',
|
|
343
|
-
'remote',
|
|
344
|
-
'target',
|
|
345
|
-
({control, remote, target}, cbk) =>
|
|
346
|
-
{
|
|
347
|
-
return asyncEach([control, remote, target], (node, cbk) => {
|
|
348
|
-
if (!node) {
|
|
349
|
-
return cbk();
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
return asyncRetry({interval: retryMs, times: retryTimes}, cbk => {
|
|
353
|
-
return getWalletInfo({lnd: node.lnd}, (err, res) => {
|
|
354
|
-
if (!!err) {
|
|
355
|
-
return cbk(err);
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
if (!res.is_synced_to_chain) {
|
|
359
|
-
return cbk([503, 'NodeWaitingToSyncToChain']);
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
return cbk();
|
|
363
|
-
});
|
|
364
|
-
},
|
|
365
|
-
cbk);
|
|
366
|
-
},
|
|
367
|
-
cbk);
|
|
368
|
-
}],
|
|
369
|
-
},
|
|
370
|
-
(err, res) => {
|
|
371
|
-
if (!!err && !!res.control) {
|
|
372
|
-
res.control.kill();
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
if (!!err && !!res.remote && !!res.remote.kill) {
|
|
376
|
-
res.remote.kill();
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
if (!!err && !!res.target) {
|
|
380
|
-
res.target.kill();
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
if (!!err) {
|
|
384
|
-
return cbk(err);
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
const {control} = res;
|
|
388
|
-
const {remote} = res;
|
|
389
|
-
const {remoteNode} = res;
|
|
390
|
-
const {target} = res;
|
|
391
|
-
|
|
392
|
-
const kill = promisify((args, cbk) => {
|
|
393
|
-
const nodes = [control, remote, target].concat(args.nodes)
|
|
394
|
-
.filter(n => !!n);
|
|
395
|
-
|
|
396
|
-
nodes.forEach(({kill}) => kill());
|
|
397
|
-
|
|
398
|
-
return asyncEach(nodes, ({lnd}, cbk) => {
|
|
399
|
-
return waitForTermination({lnd}, cbk);
|
|
400
|
-
},
|
|
401
|
-
cbk);
|
|
402
|
-
});
|
|
403
|
-
|
|
404
|
-
const generate = async (args, cbk) => {
|
|
405
|
-
return generateBlocks({
|
|
406
|
-
cert: (args.node || control).chain_rpc_cert_file,
|
|
407
|
-
count: args.count || 1,
|
|
408
|
-
host: (args.node || control).listen_ip,
|
|
409
|
-
pass: (args.node || control).chain_rpc_pass,
|
|
410
|
-
port: (args.node || control).chain_rpc_port,
|
|
411
|
-
user: (args.node || control).chain_rpc_user,
|
|
412
|
-
},
|
|
413
|
-
cbk);
|
|
414
|
-
};
|
|
415
|
-
|
|
416
|
-
return cbk(null, {
|
|
417
|
-
control,
|
|
418
|
-
kill,
|
|
419
|
-
remote,
|
|
420
|
-
generate,
|
|
421
|
-
target,
|
|
422
|
-
remote_node_public_key: !remoteNode ? null : remoteNode.public_key,
|
|
423
|
-
target_node_public_key: res.targetNode.public_key,
|
|
424
|
-
});
|
|
425
|
-
});
|
|
426
|
-
};
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
const asyncAuto = require('async/auto');
|
|
2
|
-
const asyncMap = require('async/map');
|
|
3
|
-
const asyncTimesSeries = require('async/timesSeries');
|
|
4
|
-
const asyncRetry = require('async/retry');
|
|
5
|
-
const {networks} = require('bitcoinjs-lib');
|
|
6
|
-
const {payments} = require('bitcoinjs-lib');
|
|
7
|
-
const {returnResult} = require('asyncjs-util');
|
|
8
|
-
const tinysecp = require('tiny-secp256k1');
|
|
9
|
-
|
|
10
|
-
const rpc = require('./rpc');
|
|
11
|
-
|
|
12
|
-
const interval = retryCount => 2000 * Math.random();
|
|
13
|
-
const {p2pkh} = payments;
|
|
14
|
-
const retryTimes = 50;
|
|
15
|
-
|
|
16
|
-
/** Generate blocks on the chain daemon
|
|
17
|
-
|
|
18
|
-
{
|
|
19
|
-
[cert]: <TLS Cert For RPC Connection Buffer Object>
|
|
20
|
-
[chain]: <Chain Type String>
|
|
21
|
-
[count]: <Blocks to Generate Number>
|
|
22
|
-
host: <Chain Daemon IP String>
|
|
23
|
-
[key]: <Mining Key WIF String>
|
|
24
|
-
pass: <RPC Password String>
|
|
25
|
-
port: <RPC Port Number>
|
|
26
|
-
user: <RPC Username String>
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
@return via cbk or Promise
|
|
30
|
-
{
|
|
31
|
-
blocks: [<Block Hash Hex String>]
|
|
32
|
-
}
|
|
33
|
-
*/
|
|
34
|
-
module.exports = ({cert, chain, count, host, key, pass, port, user}, cbk) => {
|
|
35
|
-
return new Promise((resolve, reject) => {
|
|
36
|
-
return asyncAuto({
|
|
37
|
-
// Import ECPair library
|
|
38
|
-
ecp: async () => (await import('ecpair')).ECPairFactory(tinysecp),
|
|
39
|
-
|
|
40
|
-
// Check arguments
|
|
41
|
-
validate: cbk => {
|
|
42
|
-
if (!host) {
|
|
43
|
-
return cbk([400, 'ExpectedChainRpcHostForGenerateBlocks']);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (!pass) {
|
|
47
|
-
return cbk([400, 'ExpectedChainRpcPassForGenerateBlocks']);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (!port) {
|
|
51
|
-
return cbk([400, 'ExpectedChainRpcPortForGenerateBlocks']);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
if (!user) {
|
|
55
|
-
return cbk([400, 'ExpectedChainRpcUserForGenerateBlocks']);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return cbk();
|
|
59
|
-
},
|
|
60
|
-
|
|
61
|
-
// Generate blocks
|
|
62
|
-
generate: ['ecp', 'validate', ({ecp}, cbk) => {
|
|
63
|
-
let cmd;
|
|
64
|
-
let params;
|
|
65
|
-
|
|
66
|
-
switch (chain) {
|
|
67
|
-
case 'bitcoind':
|
|
68
|
-
const miningKey = Buffer.from(key, 'hex');
|
|
69
|
-
const network = networks.testnet;
|
|
70
|
-
|
|
71
|
-
const pubkey = ecp.fromPublicKey(miningKey, network).publicKey;
|
|
72
|
-
|
|
73
|
-
cmd = 'generatetoaddress';
|
|
74
|
-
params = [[count].length, p2pkh({network, pubkey}).address];
|
|
75
|
-
break;
|
|
76
|
-
|
|
77
|
-
default:
|
|
78
|
-
cmd = 'generate';
|
|
79
|
-
params = [count];
|
|
80
|
-
break;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return rpc({
|
|
84
|
-
cert,
|
|
85
|
-
cmd,
|
|
86
|
-
host,
|
|
87
|
-
params,
|
|
88
|
-
pass,
|
|
89
|
-
port,
|
|
90
|
-
user,
|
|
91
|
-
},
|
|
92
|
-
(err, res) => {
|
|
93
|
-
if (!!err) {
|
|
94
|
-
return cbk([503, 'UnexpectedErrorGeneratingBlocks']);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (!res) {
|
|
98
|
-
return cbk();
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (!Array.isArray(res)) {
|
|
102
|
-
return cbk([503, 'ExpectedBlockHashesForBlockGeneration', res]);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return cbk(null, res);
|
|
106
|
-
});
|
|
107
|
-
}],
|
|
108
|
-
|
|
109
|
-
// Get blocks with transaction ids
|
|
110
|
-
blocks: ['generate', ({generate}, cbk) => {
|
|
111
|
-
const cmd = 'getblock';
|
|
112
|
-
|
|
113
|
-
return asyncMap(generate.filter(n => !!n), (blockId, cbk) => {
|
|
114
|
-
const opts = {cert, cmd, host, pass, port, user, params: [blockId]};
|
|
115
|
-
|
|
116
|
-
return asyncRetry({interval, times: retryTimes}, cbk => {
|
|
117
|
-
return rpc(opts, (err, res) => {
|
|
118
|
-
if (!!err) {
|
|
119
|
-
return cbk([503, 'UnexpectedErrorGettingBlock', {err}]);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
if (!res || !Array.isArray(res.tx)) {
|
|
123
|
-
return cbk([503, 'ExpectedBlockTransactionsForBlock', res]);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
return cbk(null, {id: blockId, transaction_ids: res.tx});
|
|
127
|
-
});
|
|
128
|
-
},
|
|
129
|
-
cbk);
|
|
130
|
-
},
|
|
131
|
-
cbk);
|
|
132
|
-
}],
|
|
133
|
-
|
|
134
|
-
// Final result
|
|
135
|
-
generation: ['blocks', ({blocks}, cbk) => {
|
|
136
|
-
return cbk(null, {blocks})
|
|
137
|
-
}],
|
|
138
|
-
},
|
|
139
|
-
returnResult({reject, resolve, of: 'generation'}, cbk));
|
|
140
|
-
});
|
|
141
|
-
};
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
const asyncAuto = require('async/auto');
|
|
2
|
-
const {returnResult} = require('asyncjs-util');
|
|
3
|
-
|
|
4
|
-
const rpc = require('./rpc');
|
|
5
|
-
|
|
6
|
-
const cmd = 'getrawtransaction';
|
|
7
|
-
|
|
8
|
-
/** Get a transaction
|
|
9
|
-
|
|
10
|
-
{
|
|
11
|
-
cert: <TLS Cert For RPC Connection Buffer Object>
|
|
12
|
-
host: <Chain Daemon IP String>
|
|
13
|
-
id: <Hex Encoded Transaction Hash String>
|
|
14
|
-
pass: <RPC Password String>
|
|
15
|
-
port: <RPC Port Number>
|
|
16
|
-
user: <RPC Username String>
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
@returns via cbk or PRomise
|
|
20
|
-
{
|
|
21
|
-
transaction: <Raw Transaction Hex String>
|
|
22
|
-
}
|
|
23
|
-
*/
|
|
24
|
-
module.exports = ({cert, host, id, pass, port, user}, cbk) => {
|
|
25
|
-
return new Promise((resolve, reject) => {
|
|
26
|
-
return asyncAuto({
|
|
27
|
-
// Check arguments
|
|
28
|
-
validate: cbk => {
|
|
29
|
-
if (!cert) {
|
|
30
|
-
return cbk([400, 'ExpectedChainRpcCertToGetRawTransaction']);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (!host) {
|
|
34
|
-
return cbk([400, 'ExpectedChainRpcHostToGetRawTransaction']);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if (!id) {
|
|
38
|
-
return cbk([400, 'ExpectedTransactionIdToGetRawTransaction']);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (!pass) {
|
|
42
|
-
return cbk([400, 'ExpectedChainRpcPassToGetRawTransaction']);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (!port) {
|
|
46
|
-
return cbk([400, 'ExpectedChainRpcPortToGetRawTransaction']);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (!user) {
|
|
50
|
-
return cbk([400, 'ExpectedChainRpcUserForMiningTransaction']);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return cbk();
|
|
54
|
-
},
|
|
55
|
-
|
|
56
|
-
// Get the raw transaction
|
|
57
|
-
getRawTransaction: ['validate', ({}, cbk) => {
|
|
58
|
-
return rpc({
|
|
59
|
-
cert,
|
|
60
|
-
cmd,
|
|
61
|
-
host,
|
|
62
|
-
pass,
|
|
63
|
-
port,
|
|
64
|
-
user,
|
|
65
|
-
params: [id],
|
|
66
|
-
},
|
|
67
|
-
(err, res) => {
|
|
68
|
-
if (!!err) {
|
|
69
|
-
return cbk([503, 'UnexpectedErrorGettingTransaction', {err}]);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return cbk(null, {transaction: res});
|
|
73
|
-
});
|
|
74
|
-
}],
|
|
75
|
-
},
|
|
76
|
-
returnResult({reject, resolve, of: 'getRawTransaction'}, cbk));
|
|
77
|
-
});
|
|
78
|
-
};
|