Completed
Push — master ( 1b680e...1143cd )
by thomas
02:25
created

describe(ꞌWallet.getAddressAndTypeꞌ)   B

Complexity

Conditions 1
Paths 2

Size

Total Lines 168

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
c 1
b 0
f 0
nc 2
dl 0
loc 168
rs 8.2857
nop 0

1 Function

Rating   Name   Duplication   Size   Complexity  
B ��) 0 31 2

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
/* jshint -W101, -W098 */
2
/* global window */
3
var _ = require('lodash');
4
var blocktrail = require('../');
5
var Wallet = blocktrail.Wallet;
6
var assert = require('assert');
7
var crypto = require('crypto');
8
var async = require('async');
9
var bitcoin = require('bitcoinjs-lib');
10
var bip39 = require("bip39");
11
12
/**
13
 * @type APIClient
14
 */
15
var client = blocktrail.BlocktrailSDK({
16
    apiKey : process.env.BLOCKTRAIL_SDK_APIKEY || window.BLOCKTRAIL_SDK_APIKEY || "EXAMPLE_BLOCKTRAIL_SDK_NODEJS_APIKEY",
17
    apiSecret : process.env.BLOCKTRAIL_SDK_APISECRET || window.BLOCKTRAIL_SDK_APISECRET || "EXAMPLE_BLOCKTRAIL_SDK_NODEJS_APISECRET",
18
    testnet : true
19
});
20
21
var TRANSACTION_TEST_WALLET_PRIMARY_MNEMONIC = "give pause forget seed dance crawl situate hole keen",
22
    TRANSACTION_TEST_WALLET_BACKUP_MNEMONIC = "give pause forget seed dance crawl situate hole give",
23
    TRANSACTION_TEST_WALLET_PASSWORD = "password";
24 View Code Duplication
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
25
var _createTestWallet = function(identifier, passphrase, primaryMnemonic, backupMnemonic, cb) {
26
    var keyIndex = 9999;
27
    var network = client.testnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin;
28
29
    var primarySeed = bip39.mnemonicToSeed(primaryMnemonic, passphrase);
30
    var primaryPrivateKey = bitcoin.HDNode.fromSeedBuffer(primarySeed, network);
31
32
    var backupSeed = bip39.mnemonicToSeed(backupMnemonic, "");
33
    var backupPrivateKey = bitcoin.HDNode.fromSeedBuffer(backupSeed, network);
34
    var backupPublicKey = backupPrivateKey.neutered();
35
36
    var checksum = primaryPrivateKey.getAddress();
37
    var primaryPublicKey = primaryPrivateKey.deriveHardened(keyIndex).neutered();
38
39
    client.storeNewWalletV1(
40
        identifier,
41
        [primaryPublicKey.toBase58(), "M/" + keyIndex + "'"],
42
        [backupPublicKey.toBase58(), "M"],
43
        primaryMnemonic,
44
        checksum,
45
        keyIndex,
46
        function(err, result) {
47
            if (err) {
48
                return cb(err);
49
            }
50
51
            var blocktrailPublicKeys = _.mapValues(result.blocktrail_public_keys, function(blocktrailPublicKey) {
52
                return bitcoin.HDNode.fromBase58(blocktrailPublicKey[0], network);
53
            });
54
55
            var wallet = new blocktrail.Wallet(
56
                client,
57
                identifier,
58
                blocktrail.Wallet.WALLET_VERSION_V1,
59
                primaryMnemonic,
60
                null,
61
                null,
62
                {keyIndex: primaryPublicKey},
63
                backupPublicKey,
64
                blocktrailPublicKeys,
65
                keyIndex,
66
                0,
67
                false,
68
                client.testnet,
69
                checksum
70
            );
71
72
            wallet.unlock({
73
                passphrase: passphrase
74
            }, function(err) {
75
                cb(err, wallet);
76
            });
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
77
        }
78
    );
79
};
80
81
var createDiscoveryTestWallet = function(identifier, passphrase, cb) {
82
    var primaryMnemonic = "give pause forget seed dance crawl situate hole kingdom";
83
    var backupMnemonic = "give pause forget seed dance crawl situate hole course";
84
85
    return _createTestWallet(identifier, passphrase, primaryMnemonic, backupMnemonic, cb);
86
};
87
88
var createTransactionTestWallet = function(identifier, cb) {
89
    return _createTestWallet(identifier, TRANSACTION_TEST_WALLET_PASSWORD, TRANSACTION_TEST_WALLET_PRIMARY_MNEMONIC, TRANSACTION_TEST_WALLET_BACKUP_MNEMONIC, cb);
90
};
91
92
var createRecoveryTestWallet = function(identifier, passphrase, cb) {
93
    var primaryMnemonic = "give pause forget seed dance crawl situate hole join";
94
    var backupMnemonic = "give pause forget seed dance crawl situate hole crater";
95
96
    return _createTestWallet(identifier, passphrase, primaryMnemonic, backupMnemonic, cb);
97
};
98
99
/**
100
 * Test operations on v2 and v3 wallets.
101
 * Also tests the default, encouraging to look at this test if it changes again.
102
 */
103
[
104
  blocktrail.Wallet.WALLET_VERSION_V2,
105
  blocktrail.Wallet.WALLET_VERSION_V3,
106
  null /* test our assumed default version */
107
].map(function(walletVersion) {
108
    var assumedDefault = blocktrail.Wallet.WALLET_VERSION_V3;
109
    describe('test new blank wallet, ' + walletVersion, function() {
110
        var myIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
111
        var wallet;
112
113
        after(function(cb) {
114
            if (wallet) {
115
                wallet.deleteWallet(true, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter err is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
116
                    cb();
117
                });
118
            } else {
119
                cb();
120
            }
121
        });
122
123
        it("shouldn't already exist", function(cb) {
124
            client.initWallet({
125
                identifier: myIdentifier,
126
                readOnly: true
127
            }, function(err, wallet) {
128
                assert.ok(err);
129
                assert.ok(!wallet, "wallet with random ID [" + myIdentifier + "] already exists...");
130
131
                cb();
132
            });
133
        });
134
135
        it("should be created", function(cb) {
136
            var progress = [];
137
            var cnf = {
138
                identifier: myIdentifier,
139
                passphrase: "password",
140
                keyIndex: 9999
141
            };
142
143
            var expectedVersion = assumedDefault;
144
            if (walletVersion !== null) {
145
                cnf.walletVersion = walletVersion;
146
                expectedVersion = walletVersion;
147
            }
148
149
            client.createNewWallet(cnf, function(err, _wallet, backupInfo) {
0 ignored issues
show
Unused Code introduced by
The parameter backupInfo is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
150
                assert.ifError(err);
151
                assert.ok(_wallet);
152
153
                wallet = _wallet;
154
                assert.equal(wallet.walletVersion, expectedVersion);
155
                assert.equal(wallet.identifier, myIdentifier);
156
                assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
157
158
                assert.deepEqual(progress, [
159
                    blocktrail.CREATE_WALLET_PROGRESS_START,
160
                    blocktrail.CREATE_WALLET_PROGRESS_ENCRYPT_SECRET,
161
                    blocktrail.CREATE_WALLET_PROGRESS_ENCRYPT_PRIMARY,
162
                    blocktrail.CREATE_WALLET_PROGRESS_ENCRYPT_RECOVERY,
163
                    blocktrail.CREATE_WALLET_PROGRESS_PRIMARY,
164
                    blocktrail.CREATE_WALLET_PROGRESS_BACKUP,
165
                    blocktrail.CREATE_WALLET_PROGRESS_SUBMIT,
166
                    blocktrail.CREATE_WALLET_PROGRESS_INIT,
167
                    blocktrail.CREATE_WALLET_PROGRESS_DONE
168
                ]);
169
170
                cb();
171
            })
172
            .progress(function(p) { progress.push(p); });
173
        });
174
175
        it("should lock", function(cb) {
176
            assert(!wallet.locked);
177
            wallet.lock();
178
            assert(wallet.locked);
179
            cb();
180
        });
181
182
        it("should init", function(cb) {
183
            client.initWallet({
184
                identifier: myIdentifier,
185
                readOnly: true
186
            }, function(err, _wallet) {
187
                assert.ifError(err);
188
                assert.ok(_wallet);
189
190
                wallet = _wallet;
191
192
                cb();
193
            });
194
        });
195
196
        it("should have a 0 balance", function(cb) {
197
            wallet.getBalance(function(err, confirmed, unconfirmed) {
198
                assert.ifError(err);
199
                assert.equal(confirmed, 0);
200
                assert.equal(unconfirmed, 0);
201
202
                cb();
203
            });
204
        });
205
206
        it("shouldn't be able to pay when locked", function(cb) {
207
            wallet.pay({
208
                "2N6Fg6T74Fcv1JQ8FkPJMs8mYmbm9kitTxy": blocktrail.toSatoshi(0.001)
209
            }, function(err, txHash) {
0 ignored issues
show
Unused Code introduced by
The parameter txHash is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
210
                assert.ok(!!err && err.message.match(/unlocked/));
211
                assert.ok(err instanceof blocktrail.WalletLockedError);
212
213
                cb();
214
            });
215
        });
216
217
        it("shouldn't be able to upgrade when locked", function(cb) {
218
            wallet.upgradeKeyIndex(10000, function(err) {
219
                assert.ok(!!err && err.message.match(/unlocked/));
220
                assert.ok(err instanceof blocktrail.WalletLockedError);
221
222
                cb();
223
            });
224
        });
225
226
        it("should unlock", function(cb) {
227
            wallet.unlock({password: "password"}, function(err) {
228
                assert.ifError(err);
229
230
                cb();
231
            });
232
        });
233
234
        it("should be able to unlock with secret", function(cb) {
235
            var secret = wallet.secret;
236
237
            wallet.lock();
238
            wallet.unlock({secret: secret}, function(err) {
239
                assert.ifError(err);
240
                cb();
241
            });
242
        });
243
244
        it("shouldn't be able to pay when unlocked (because of no balance)", function(cb) {
245
            wallet.pay({
246
                "2N6Fg6T74Fcv1JQ8FkPJMs8mYmbm9kitTxy": blocktrail.toSatoshi(0.001)
247
            }, function(err, txHash) {
0 ignored issues
show
Unused Code introduced by
The parameter txHash is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
248
                assert.ok(!!err && err.message.match(/balance/));
249
250
                cb();
251
            });
252
        });
253
254
        it("should be able to upgrade when unlocked", function(cb) {
255
            wallet.upgradeKeyIndex(10000, function(err) {
256
                assert.ifError(err);
257
258
                cb();
259
            });
260
        });
261
262
        it("should be able to password change", function(cb) {
263
            wallet.passwordChange("password2", function(err) {
264
                assert.ifError(err);
265
266
                client.initWallet({
267
                    identifier: myIdentifier,
268
                    password: "password2"
269
                }, function(err, _wallet) {
270
                    assert.ifError(err);
271
                    assert.ok(_wallet);
272
273
                    wallet = _wallet;
274
275
                    cb();
276
                });
277
            });
278
        });
279
    });
280
});
281
282
/**
283
 * Test operations on v2 and v3 wallets.
284
 */
285
[
286
    blocktrail.Wallet.WALLET_VERSION_V1,
287
    blocktrail.Wallet.WALLET_VERSION_V2,
288
    blocktrail.Wallet.WALLET_VERSION_V3
289
].map(function(walletVersion) {
290
    var primarySeed = bip39.mnemonicToSeed(TRANSACTION_TEST_WALLET_PRIMARY_MNEMONIC, TRANSACTION_TEST_WALLET_PASSWORD);
291
292
    describe('test input errors, ' + walletVersion, function() {
293
        it("shouldn't allow primaryPrivateKey in creation", function(cb) {
294
            var myIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
295
            var primaryPrivateKey = bitcoin.HDNode.fromSeedBuffer(primarySeed, bitcoin.networks.testnet);
296
297
            client.createNewWallet({
298
                identifier: myIdentifier,
299
                passphrase: "password",
300
                primaryPrivateKey: primaryPrivateKey,
301
                walletVersion: walletVersion,
302
                keyIndex: 9999
303
            }, function(err, wallet) {
0 ignored issues
show
Unused Code introduced by
The parameter wallet is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
304
                assert.ok(!!err, "should error");
305
306
                cb();
307
            });
308
        });
309
310
        it("shouldn't allow unlocking with primaryPrivateKey", function(cb) {
311
            client.createNewWallet({
312
                identifier: "unittest-transaction-inputerr-" + walletVersion,
313
                primarySeed: primarySeed,
314
                walletVersion: walletVersion,
315
                keyIndex: 9999
316
            }).then(function(r) {
317
                var wallet = r[0];
318
                wallet.lock();
319
                return wallet;
320
            }, function(err) {
321
                assert.ok(err.message.match(/already exists/));
322
323
                return client.initWallet({
324
                    identifier: "unittest-transaction-inputerr-" + walletVersion,
325
                    readOnly: true
326
                });
327
            }).then(function(wallet) {
328
                assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
329
330
                return wallet.unlock({primaryPrivateKey: bitcoin.HDNode.fromSeedBuffer(primarySeed, bitcoin.networks.testnet)})
331
                    .then(function() {
332
                        return;
0 ignored issues
show
Unused Code introduced by
This return has no effect and can be removed.
Loading history...
333
                    }, function(err) {
334
                        return err;
335
                    });
336
            })
337
                .then(function(err) {
338
                    assert.ok(!!err, "should error");
339
                    cb();
340
                })
341
                .done();
342
        });
343
    });
344
});
345
346
/**
347
 * Test upgrade to V3 from V1 and V2
348
 */
349
[
350
    blocktrail.Wallet.WALLET_VERSION_V1,
351
    blocktrail.Wallet.WALLET_VERSION_V2
352
].map(function(walletVersion) {
353
    describe("upgrade to V3 from " + walletVersion, function() {
354
        var myIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
355
        var passphrase = "password";
356
        var wallet;
357
358
        after(function(cb) {
359
            if (wallet) {
360
                wallet.deleteWallet(true, function(err, result) {
361
                    console.log(err, result);
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
362
                    cb();
363
                });
364
            } else {
365
                cb();
366
            }
367
        });
368
369
        it("can upgrade", function() {
370
            var addr;
371
            return client.createNewWallet({
372
                identifier: myIdentifier,
373
                passphrase: passphrase,
374
                walletVersion: walletVersion,
375
                keyIndex: 9999
376
            })
377
                .then(function(r) {
378
                    return r[0];
379
                })
380
                .then(function(_wallet) {
381
                    wallet = _wallet;
382
                    addr = wallet.getAddressByPath("M/9999'/0/0");
383
384
                    return wallet;
385
                })
386
                .then(function(wallet) {
387
                    var progress = [];
388
389
                    return wallet.upgradeToV3(passphrase)
390
                        .progress(function(p) {
391
                            progress.push(p);
392
                        })
393
                        .then(function() {
394
                            assert(progress.length);
395
                            return wallet;
396
                        });
397
                })
398
                .then(function(wallet) {
399
                    assert.equal(addr, wallet.getAddressByPath("M/9999'/0/0"));
400
                });
401
        });
402
403
        it("can unlock with secret", function() {
404
            var secret = wallet.secret;
405
            wallet.lock();
406
            return wallet.unlock({secret: secret});
407
        });
408
409
        it("can init after upgrade", function() {
410
            return client.initWallet({
411
                identifier: myIdentifier,
412
                passphrase: passphrase,
413
                keyIndex: 9999
414
            });
415
        });
416
    });
417
});
418
419
describe('test new blank wallet, v1', function() {
420
    var myIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
421
    var wallet;
422
423
    after(function(cb) {
424
        if (wallet) {
425
            wallet.deleteWallet(true, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter err is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
426
                cb();
427
            });
428
        } else {
429
            cb();
430
        }
431
    });
432
433
    it("shouldn't already exist", function(cb) {
434
        client.initWallet({
435
            identifier: myIdentifier,
436
            readOnly: true
437
        }, function(err, wallet) {
438
            assert.ok(err);
439
            assert.ok(!wallet, "wallet with random ID [" + myIdentifier + "] already exists...");
440
441
            cb();
442
        });
443
    });
444
445
    it("should be created", function(cb) {
446
        var progress = [];
447
448
        client.createNewWallet({
449
                identifier: myIdentifier,
450
                passphrase: "password",
451
                keyIndex: 9999,
452
                walletVersion: blocktrail.Wallet.WALLET_VERSION_V1
453
            }, function(err, _wallet) {
454
                assert.ifError(err);
455
                assert.ok(_wallet);
456
457
                wallet = _wallet;
458
459
                assert.equal(wallet.identifier, myIdentifier);
460
                assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
461
462
                assert.deepEqual(progress, [
463
                    blocktrail.CREATE_WALLET_PROGRESS_START,
464
                    blocktrail.CREATE_WALLET_PROGRESS_PRIMARY,
465
                    blocktrail.CREATE_WALLET_PROGRESS_BACKUP,
466
                    blocktrail.CREATE_WALLET_PROGRESS_SUBMIT,
467
                    blocktrail.CREATE_WALLET_PROGRESS_INIT,
468
                    blocktrail.CREATE_WALLET_PROGRESS_DONE
469
                ]);
470
471
                cb();
472
            }
473
        ).progress(function(p) { progress.push(p); });
474
    });
475
476
    it("should lock", function(cb) {
477
        assert(!wallet.locked);
478
        wallet.lock();
479
        assert(wallet.locked);
480
        cb();
481
    });
482
483
    it("should init", function(cb) {
484
        client.initWallet({
485
            identifier: myIdentifier,
486
            readOnly: true
487
        }, function(err, _wallet) {
488
            assert.ifError(err);
489
            assert.ok(_wallet);
490
            assert.equal(wallet.walletVersion, 'v1');
491
492
            wallet = _wallet;
493
494
            cb();
495
        });
496
    });
497
498
    it("should have a 0 balance", function(cb) {
499
        wallet.getBalance(function(err, confirmed, unconfirmed) {
500
            assert.ifError(err);
501
            assert.equal(confirmed, 0);
502
            assert.equal(unconfirmed, 0);
503
504
            cb();
505
        });
506
    });
507
508
    it("should unlock", function(cb) {
509
        wallet.unlock({password: "password"}, function(err) {
510
            assert.ifError(err);
511
512
            cb();
513
        });
514
    });
515
516
    it("shouldn't be able to password change", function(cb) {
517
        wallet.passwordChange("password2", function(err) {
518
            assert.ok(!!err && err.message.match(/version does not support/));
519
520
            cb();
521
        });
522
    });
523
});
524
525
describe('test new blank wallet, old syntax', function() {
526
    var myIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
527
    var wallet;
528
529
    after(function(cb) {
530
        if (wallet) {
531
            wallet.deleteWallet(true, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter err is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
532
                cb();
533
            });
534
        } else {
535
            cb();
536
        }
537
    });
538
539
    it("shouldn't already exist", function(cb) {
540
        client.initWallet(myIdentifier, "password", function(err, wallet) {
541
            assert.ok(err);
542
            assert.ok(!wallet, "wallet with random ID [" + myIdentifier + "] already exists...");
543
544
            cb();
545
        });
546
    });
547
548
    it("should be created", function(cb) {
549
        client.createNewWallet(myIdentifier, "password", 9999, function(err, _wallet) {
550
            assert.ifError(err);
551
            assert.ok(_wallet);
552
553
            wallet = _wallet;
554
555
            assert.equal(wallet.identifier, myIdentifier);
556
            assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
557
            cb();
558
        });
559
    });
560
561
    it("should have a 0 balance", function(cb) {
562
        wallet.getBalance(function(err, confirmed, unconfirmed) {
563
            assert.ifError(err);
564
            assert.equal(confirmed, 0);
565
            assert.equal(unconfirmed, 0);
566
567
            cb();
568
        });
569
    });
570
571
    it("shouldn't be able to pay", function(cb) {
572
        wallet.pay({
573
            "2N6Fg6T74Fcv1JQ8FkPJMs8mYmbm9kitTxy": blocktrail.toSatoshi(0.001)
574
        }, function(err, txHash) {
0 ignored issues
show
Unused Code introduced by
The parameter txHash is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
575
            assert.ok(!!err);
576
577
            cb();
578
        });
579
    });
580
});
581
582
describe('test new wallet, without mnemonics', function() {
583
    var myIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
584
    var wallet;
585
586
    var primarySeed = bip39.mnemonicToSeed(bip39.generateMnemonic(512), "password");
587
    var backupPrivateKey = bitcoin.HDNode.fromSeedBuffer(bip39.mnemonicToSeed(bip39.generateMnemonic(512), ""), bitcoin.networks.testnet);
588
    var backupPublicKey = backupPrivateKey.neutered();
589
590
    after(function(cb) {
591
        if (wallet) {
592
            wallet.deleteWallet(true, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter err is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
593
                cb();
594
            });
595
        } else {
596
            cb();
597
        }
598
    });
599
600
    it("shouldn't already exist", function(cb) {
601
        client.initWallet({
602
            identifier: myIdentifier
603
        }, function(err, wallet) {
604
            assert.ok(err);
605
            assert.ok(!wallet, "wallet with random ID [" + myIdentifier + "] already exists...");
606
607
            cb();
608
        });
609
    });
610
611
    it("should be created", function(cb) {
612
        client.createNewWallet({
613
                identifier: myIdentifier,
614
                primarySeed: primarySeed,
615
                backupPublicKey: backupPublicKey,
616
                keyIndex: 9999
617
            }, function(err, _wallet) {
618
                assert.ifError(err);
619
                assert.ok(_wallet);
620
621
                wallet = _wallet;
622
623
                assert.equal(wallet.identifier, myIdentifier);
624
                assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
625
                cb();
626
            }
627
        );
628
    });
629
630
    it("should be initializable", function(cb) {
631
        client.initWallet({
632
                identifier: myIdentifier,
633
                primarySeed: primarySeed,
634
                keyIndex: 9999
635
            }, function(err, _wallet) {
636
                assert.ifError(err);
637
                assert.ok(_wallet);
638
639
                wallet = _wallet;
640
641
                cb();
642
            }
643
        );
644
    });
645
646
    it("should have a 0 balance", function(cb) {
647
        wallet.getBalance(function(err, confirmed, unconfirmed) {
648
            assert.ifError(err);
649
            assert.equal(confirmed, 0);
650
            assert.equal(unconfirmed, 0);
651
652
            cb();
653
        });
654
    });
655
656
    it("shouldn't be able to pay", function(cb) {
657
        wallet.pay({
658
            "2N6Fg6T74Fcv1JQ8FkPJMs8mYmbm9kitTxy": blocktrail.toSatoshi(0.001)
659
        }, function(err, txHash) {
0 ignored issues
show
Unused Code introduced by
The parameter txHash is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
660
            assert.ok(!!err);
661
662
            cb();
663
        });
664
    });
665
});
666
667
describe('test wallet, do transaction', function() {
668
    var wallet;
669
670
    it("should exists", function(cb) {
671
        client.initWallet({
672
            identifier: "unittest-transaction",
673
            passphrase: TRANSACTION_TEST_WALLET_PASSWORD
674
        }, function(err, _wallet) {
675
            assert.ifError(err);
676
            assert.ok(_wallet);
677
            wallet = _wallet;
678
679
            assert.equal(wallet.primaryMnemonic, "give pause forget seed dance crawl situate hole keen");
680
            assert.equal(wallet.identifier, "unittest-transaction");
681
            assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
682
            cb();
683
        });
684
    });
685
686
    it("should have the expected addresses", function(cb) {
687
        assert.equal(wallet.getAddressByPath("M/9999'/0/1"), "2N65RcfKHiKQcPGZAA2QVeqitJvAQ8HroHD");
688
        assert.equal(wallet.getAddressByPath("M/9999'/0/6"), "2MynrezSyqCq1x5dMPtRDupTPA4sfVrNBKq");
689
        assert.equal(wallet.getAddressByPath("M/9999'/0/44"), "2N5eqrZE7LcfRyCWqpeh1T1YpMdgrq8HWzh");
690
691
        cb();
692
    });
693
694
    it("should have a balance", function(cb) {
695
        this.timeout(0);
696
697
        wallet.getBalance(function(err, confirmed, unconfirmed) {
698
            assert.ok(confirmed + unconfirmed > 0);
699
            assert.ok(confirmed > 0);
700
701
            cb();
702
        });
703
    });
704
705
    it("should return errors when expected", function(cb) {
706
        async.parallel([
707
            function(cb) {
708
                wallet.pay({"": blocktrail.toSatoshi(0.001)}, function(err) {
709
                    assert.ok(!!err);
710
                    assert.equal(err.message, "Invalid address [] (Invalid checksum)");
711
                    assert.ok(err instanceof blocktrail.InvalidAddressError);
712
713
                    cb();
714
                });
715
            },
716
            function(cb) {
717
                wallet.pay({"2N65RcfKHiKQcPGZAA2QVeqitJvAQ8HroHA": blocktrail.toSatoshi(0.001)}, function(err) {
718
                    assert.ok(!!err);
719
                    assert.equal(err.message, "Invalid address [2N65RcfKHiKQcPGZAA2QVeqitJvAQ8HroHA] (Invalid checksum)");
720
                    assert.ok(err instanceof blocktrail.InvalidAddressError);
721
722
                    cb();
723
                });
724
            },
725
            function(cb) {
726
                wallet.pay({"2N65RcfKHiKQcPGZAA2QVeqitJvAQ8HroHD": 1}, function(err) {
727
                    assert.ok(!!err);
728
                    assert.equal(err.message, "Values should be more than dust (" + blocktrail.DUST + ")");
729
                    assert.ok(err instanceof blocktrail.WalletSendError);
730
731
                    cb();
732
                });
733
            },
734
            function(cb) {
735
                wallet.pay({"2N65RcfKHiKQcPGZAA2QVeqitJvAQ8HroHD": 0}, function(err) {
736
                    assert.ok(!!err);
737
                    assert.equal(err.message, "Values should be non zero");
738
                    assert.ok(err instanceof blocktrail.WalletSendError);
739
740
                    cb();
741
                });
742
            },
743
            function(cb) {
744
                wallet.pay({"2N65RcfKHiKQcPGZAA2QVeqitJvAQ8HroHD": 1.1}, function(err) {
745
                    assert.ok(!!err);
746
                    assert.equal(err.message, "Values should be in Satoshis");
747
                    assert.ok(err instanceof blocktrail.WalletSendError);
748
749
                    cb();
750
                });
751
            }
752
        ], cb);
753
    });
754
755
    it("should be able to build a transaction paying a bech32 address", function(cb) {
756
        var address = "tb1qn08f8x0eamw66enrt497zu0v3u2danzey6asqs";
757
        var wp = "00149bce9399f9eeddad66635d4be171ec8f14decc59";
758
        var pay = {};
759
        pay[address] = blocktrail.toSatoshi(0.001);
760
761
        wallet.buildTransaction(pay, null, false, false, function(err, tx, utxos) {
0 ignored issues
show
Unused Code introduced by
The parameter utxos is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
762
            assert.ifError(err);
763
            assert.ok(tx);
764
            assert.ok(tx.toHex());
765
            assert.equal(wp, tx.outs[0].script.toString('hex'));
766
            cb();
767
        });
768
    });
769
770
    it("change should be randomized when building a transaction", function(cb) {
771
        wallet.getNewAddress(function(err, address, path) {
772
            assert.ifError(err);
773
            assert.ok(path.indexOf("M/9999'/0/") === 0);
774
            assert.ok(bitcoin.address.fromBase58Check(address));
775
776
            var pay = {};
777
            pay[address] = blocktrail.toSatoshi(0.001);
778
779
            var changeIdxs = [];
780
            var tryX = 10;
781
782
            async.whilst(
783
                function() { return tryX-- > 0 && _.uniq(changeIdxs).length < 2; },
784
                function(cb) {
785
                    wallet.buildTransaction(pay, function(err, tx, utxos) {
0 ignored issues
show
Unused Code introduced by
The parameter utxos is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
786
                        assert.ifError(err);
787
788
                        tx.outs.forEach(function(output, idx) {
789
                            var addr = bitcoin.address.fromOutputScript(output.script, client.testnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin);
790
791
                            if (addr !== address) {
792
                                changeIdxs.push(idx);
793
                            }
794
                        });
795
796
                        cb();
797
                    });
798
                },
799
                function() {
800
                    assert(_.uniq(changeIdxs).length > 1);
801
802
                    cb();
803
                }
804
            );
805
        });
806
807
        it("should be able to build a transaction", function(cb) {
0 ignored issues
show
Unused Code introduced by
The parameter cb is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
808
            wallet.getNewAddress(function(err, address, path) {
809
                assert.ifError(err);
810
                assert.ok(path.indexOf("M/9999'/0/") === 0);
811
                assert.ok(bitcoin.address.fromBase58Check(address));
812
813
                var pay = {};
814
                pay[address] = blocktrail.toSatoshi(0.001);
815
816
                wallet.buildTransaction(pay, function(err, tx, utxos) {
0 ignored issues
show
Unused Code introduced by
The parameter utxos is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
817
                    assert.ifError(err);
818
                    assert.ok(tx);
819
                    assert.ok(tx.toHex());
820
                });
821
            });
822
        });
823
    });
824
825
    it("should be able to do a payment", function(cb) {
826
        wallet.getNewAddress(function(err, address, path) {
827
            assert.ifError(err);
828
            assert.ok(path.indexOf("M/9999'/", wallet.chain, "/") === 0);
829
            assert.ok(bitcoin.address.fromBase58Check(address));
830
831
            var pay = {};
832
            pay[address] = blocktrail.toSatoshi(0.001);
833
834
            var progress = [];
835
836
            wallet.pay(pay, function(err, txHash) {
837
                assert.ifError(err);
838
                assert.ok(txHash);
839
840
                // change address doesn't always happen ...
841
                if (progress.indexOf(blocktrail.Wallet.PAY_PROGRESS_CHANGE_ADDRESS) === -1) {
842
                    progress.splice(2, 0, blocktrail.Wallet.PAY_PROGRESS_CHANGE_ADDRESS);
843
                }
844
845
                assert.deepEqual(progress, [
846
                    blocktrail.Wallet.PAY_PROGRESS_START,
847
                    blocktrail.Wallet.PAY_PROGRESS_COIN_SELECTION,
848
                    blocktrail.Wallet.PAY_PROGRESS_CHANGE_ADDRESS,
849
                    blocktrail.Wallet.PAY_PROGRESS_SIGN,
850
                    blocktrail.Wallet.PAY_PROGRESS_SEND,
851
                    blocktrail.Wallet.PAY_PROGRESS_DONE
852
                ]);
853
854
                // 200ms timeout, for w/e this is neccesary now ... @TODO: figure out why ...
855
                setTimeout(function() {
856
                    client.transaction(txHash, function(err, tx) {
857
                        assert.ifError(err);
858
                        assert.ok(tx);
859
860
                        cb();
861
                    });
862
                }, 200);
863
            }).progress(function(_progress) {
864
                progress.push(_progress);
865
            });
866
        });
867
    });
868
});
869
870
describe('test wallet with segwit chain', function() {
871
    var wallet;
872
873
    it("should exist and be setup", function(cb) {
874
        client.initWallet({
875
            identifier: "unittest-transaction",
876
            passphrase: TRANSACTION_TEST_WALLET_PASSWORD
877
        }, function(err, _wallet) {
878
            assert.ifError(err);
879
            assert.ok(_wallet);
880
            assert.equal(_wallet.primaryMnemonic, "give pause forget seed dance crawl situate hole keen");
881
            assert.equal(_wallet.identifier, "unittest-transaction");
882
            assert.equal(_wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
883
884
            if (_wallet.isSegwit()) {
885
                assert.equal(blocktrail.Wallet.CHAIN_BTC_SEGWIT, _wallet.chain);
886
            } else {
887
                assert.equal(blocktrail.Wallet.CHAIN_BTC_DEFAULT, _wallet.chain);
888
            }
889
890
            wallet = _wallet;
891
            cb();
892
        });
893
    });
894
895
    it("getNewAddress produces P2SH addresses", function(cb) {
896
        wallet.getNewAddress(function(err, address, path) {
897
            assert.ifError(err);
898
            if (wallet.isSegwit()) {
899
                assert.ok(path.indexOf("M/9999'/2/") === 0);
900
            } else {
901
                assert.ok(path.indexOf("M/9999'/0/") === 0);
902
            }
903
904
            assert.ok(bitcoin.address.fromBase58Check(address));
905
906
            cb();
907
        });
908
    });
909
910
    it("getWalletScriptByPath produces P2SH addresses, and returns witnessScript", function(cb) {
911
        var eAddress = "2N3j4Vx3D9LPumjtRbRe2RJpwVocvCCkHKh";
912
913
        assert.equal(wallet.getAddressByPath("M/9999'/2/0"), eAddress);
914
915
        var walletScript = wallet.getWalletScriptByPath("M/9999'/2/0");
916
        assert.equal(walletScript.address, eAddress);
917
        assert.ok(walletScript.witnessScript);
918
        assert.ok(walletScript.redeemScript);
919
        cb();
920
    });
921
});
922
923
describe('test wallet, do transaction, segwit spend', function() {
924
    var wallets = [];
925
    after(function(cb) {
926
        if (wallets.length > 0) {
927
            wallets.map(function(wallet) {
928
                wallet.deleteWallet(true);
929
            });
930
        }
931
        cb();
932
    });
933
934
    var unitTestWallet;
935
    var identifier = crypto.randomBytes(12).toString('hex');
936
    var segwitWallet;
937
    var receiveAddr;
938
    var receiveBackAddr;
939
    it("should setup the funding wallet", function(cb) {
940
        client.initWallet({
941
            identifier: "unittest-transaction",
942
            passphrase: TRANSACTION_TEST_WALLET_PASSWORD
943
        }, function(err, _wallet) {
944
            assert.ifError(err);
945
            assert.ok(_wallet);
946
947
            _wallet.getNewAddress(function(err, address, path) {
948
                assert.ifError(err);
949
                assert.ok(address);
950
                assert.ok(path);
951
952
                unitTestWallet = _wallet;
953
                receiveBackAddr = address;
954
                cb();
955
            });
956
        });
957
    });
958
959
    it("should make the receiving segwit wallet ", function(cb) {
960
        createTransactionTestWallet(identifier, function(err, newWallet) {
961
            wallets.push(newWallet);
962
            assert.ifError(err);
963
            newWallet.getNewAddress(function(err, address, path) {
964
                assert.ifError(err);
965
                assert.ok(bitcoin.address.fromBase58Check(address));
966
967
                if (newWallet.isSegwit()) {
968
                    assert.ok(path.indexOf("M/9999'/2/") === 0);
969
                } else {
970
                    assert.ok(path.indexOf("M/9999'/0/") === 0);
971
                }
972
973
                var checkScript = newWallet.getWalletScriptByPath(path);
974
                assert.ok(checkScript.address = address);
975
                assert.ok(checkScript.redeemScript instanceof Buffer);
0 ignored issues
show
Bug introduced by
The variable Buffer seems to be never declared. If this is a global, consider adding a /** global: Buffer */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
976
                if (newWallet.isSegwit()) {
977
                    assert.ok(checkScript.witnessScript instanceof Buffer);
978
                }
979
980
                segwitWallet = newWallet;
981
                receiveAddr = address;
982
                cb();
983
            });
984
        });
985
    });
986
987
    var paymentHash;
988
    it("should receive funds from unitTestWallet", function(cb) {
989
        var pay = {};
990
        pay[receiveAddr] = 30000;
991
        unitTestWallet.pay(pay, null, true, function(err, txid) {
992
            assert.ifError(err);
993
            assert.ok(txid);
994
            paymentHash = txid;
0 ignored issues
show
Unused Code introduced by
The variable paymentHash seems to be never used. Consider removing it.
Loading history...
995
            cb();
996
        });
997
    });
998
999
    it("should return to unitTestWallet", function(cb) {
1000
        var pay = {};
1001
        pay[receiveBackAddr] = 20000;
1002
        segwitWallet.pay(pay, null, true, function(err, txid) {
1003
            assert.ifError(err);
1004
            assert.ok(txid);
1005
1006
            client.transaction(txid, function(err, tx) {
1007
                assert.ifError(err);
1008
                assert.ok(tx);
1009
                cb();
1010
            });
1011
        });
1012
    });
1013
});
1014
describe('test wallet, do transaction, without mnemonics', function() {
1015
    var wallet;
1016
1017
    var primarySeed = bip39.mnemonicToSeed(TRANSACTION_TEST_WALLET_PRIMARY_MNEMONIC, TRANSACTION_TEST_WALLET_PASSWORD);
1018
1019
    it("should exists", function(cb) {
1020
        client.initWallet({
1021
                identifier: "unittest-transaction",
1022
                primarySeed: primarySeed,
1023
                primaryMnemonic: false // explicitly set false because we're reusing unittest-transaction which has a mnemonic stored
1024
            }, function(err, _wallet) {
1025
                assert.ifError(err);
1026
                assert.ok(_wallet);
1027
1028
                wallet = _wallet;
1029
1030
                assert.equal(wallet.identifier, "unittest-transaction");
1031
                assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
1032
                cb();
1033
            }
1034
        );
1035
    });
1036
1037
    it("should have the expected addresses", function(cb) {
1038
        assert.equal(wallet.getAddressByPath("M/9999'/0/1"), "2N65RcfKHiKQcPGZAA2QVeqitJvAQ8HroHD");
1039
        assert.equal(wallet.getAddressByPath("M/9999'/0/6"), "2MynrezSyqCq1x5dMPtRDupTPA4sfVrNBKq");
1040
        assert.equal(wallet.getAddressByPath("M/9999'/0/44"), "2N5eqrZE7LcfRyCWqpeh1T1YpMdgrq8HWzh");
1041
1042
        cb();
1043
    });
1044
1045
    it("should have a balance", function(cb) {
1046
        this.timeout(0);
1047
1048
        wallet.getBalance(function(err, confirmed, unconfirmed) {
1049
            assert.ok(confirmed + unconfirmed > 0);
1050
            assert.ok(confirmed > 0);
1051
1052
            cb();
1053
        });
1054
    });
1055
1056
    it("should be able to do a payment", function(cb) {
1057
        wallet.getNewAddress(function(err, address, path) {
1058
            assert.ifError(err);
1059
            assert.ok(path.indexOf("M/9999'/0/") === 0);
1060
            assert.ok(bitcoin.address.fromBase58Check(address));
1061
1062
            var pay = {};
1063
            pay[address] = blocktrail.toSatoshi(0.001);
1064
1065
            wallet.pay(pay, function(err, txHash) {
1066
                assert.ifError(err);
1067
                assert.ok(txHash);
1068
1069
                // 200ms timeout, for w/e this is neccesary now ... @TODO: figure out why ...
1070
                setTimeout(function() {
1071
                    client.transaction(txHash, function(err, tx) {
1072
                        assert.ifError(err);
1073
                        assert.ok(tx);
1074
1075
                        cb();
1076
                    });
1077
                }, 200);
1078
            });
1079
        });
1080
    });
1081
});
1082
1083
describe('test wallet, do opreturn transaction', function() {
1084
    var wallet;
1085
1086
    it("should exists", function(cb) {
1087
        client.initWallet({
1088
            identifier: "unittest-transaction",
1089
            passphrase: TRANSACTION_TEST_WALLET_PASSWORD
1090
        }, function(err, _wallet) {
1091
            assert.ifError(err);
1092
            assert.ok(_wallet);
1093
1094
            wallet = _wallet;
1095
1096
            assert.equal(wallet.primaryMnemonic, "give pause forget seed dance crawl situate hole keen");
1097
            assert.equal(wallet.identifier, "unittest-transaction");
1098
            assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
1099
            cb();
1100
        });
1101
    });
1102
1103
    it("should be able to do a payment with opreturn output", function(cb) {
1104
        wallet.getNewAddress(function(err, address, path) {
0 ignored issues
show
Unused Code introduced by
The parameter path is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1105
            assert.ifError(err);
1106
1107
            var pay = {};
1108
            pay[address] = blocktrail.toSatoshi(0.001);
1109
            pay[blocktrail.Wallet.OP_RETURN] = "BLOCKTRAILTESTDATA";
1110
1111
            wallet.pay(pay, function(err, txHash) {
1112
                assert.ifError(err);
1113
                assert.ok(txHash);
1114
1115
1116
                // 200ms timeout, for w/e this is neccesary now ... @TODO: figure out why ...
1117
                setTimeout(function() {
1118
                    client.transaction(txHash, function(err, tx) {
1119
                        assert.ifError(err);
1120
                        assert.ok(tx);
1121
1122
                        var hasOpreturn;
1123
                        tx.outputs.forEach(function(output) {
1124
                            if (output.type === 'op_return') {
1125
                                hasOpreturn = true;
1126
1127
                                assert.equal(output.script_hex, "6a12424c4f434b545241494c5445535444415441");
1128
                            }
1129
                        });
1130
                        assert.ok(hasOpreturn);
1131
1132
                        cb();
1133
                    });
1134
                }, 200);
1135
            });
1136
        });
1137
    });
1138
});
1139
1140
describe('test wallet, do forcefee transaction', function() {
1141
    var wallet;
1142
1143
    it("should exists", function(cb) {
1144
        client.initWallet({
1145
            identifier: "unittest-transaction",
1146
            passphrase: TRANSACTION_TEST_WALLET_PASSWORD
1147
        }, function(err, _wallet) {
1148
            assert.ifError(err);
1149
            assert.ok(_wallet);
1150
1151
            wallet = _wallet;
1152
1153
            assert.equal(wallet.primaryMnemonic, "give pause forget seed dance crawl situate hole keen");
1154
            assert.equal(wallet.identifier, "unittest-transaction");
1155
            assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
1156
            cb();
1157
        });
1158
    });
1159
1160
    it("should be able to do a payment with forced fee", function(cb) {
1161
        wallet.getNewAddress(function(err, address, path) {
0 ignored issues
show
Unused Code introduced by
The parameter path is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1162
            assert.ifError(err);
1163
1164
            var pay = {};
1165
            pay[address] = blocktrail.toSatoshi(0.01);
1166
            var forceFee = blocktrail.toSatoshi(0.00054321);
1167
1168
            wallet.pay(pay, null, false, true, blocktrail.Wallet.FEE_STRATEGY_FORCE_FEE, null, {
1169
                forcefee: forceFee,
1170
                checkFee: false
1171
            }, function(err, txHash) {
1172
                assert.ifError(err);
1173
                assert.ok(txHash);
1174
1175
                // 200ms timeout, for w/e this is neccesary now ... @TODO: figure out why ...
1176
                setTimeout(function() {
1177
                    client.transaction(txHash, function(err, tx) {
1178
                        assert.ifError(err);
1179
                        // this could very occasionally fail if change < DUST because then it's added to fee, so adjusted check for that
1180
                        assert.ok(tx['total_fee'] >= forceFee && tx['total_fee'] <= forceFee + blocktrail.DUST,
1181
                            "fee [" + tx['total_fee'] + "] should be equal to forced fee [" +  forceFee + "] for tx [" + txHash + "]");
1182
1183
                        cb();
1184
                    });
1185
                }, 200);
1186
            });
1187
        });
1188
    });
1189
});
1190
1191
describe('test wallet discovery and upgrade key index', function() {
1192
    var myIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
1193
    var wallet;
1194
1195
    after(function(cb) {
1196
        if (wallet) {
1197
            wallet.deleteWallet(true, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter err is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1198
                cb();
1199
            });
1200
        } else {
1201
            cb();
1202
        }
1203
    });
1204
1205
    it("should be created", function(cb) {
1206
        createDiscoveryTestWallet(myIdentifier, "password", function(err, _wallet) {
1207
            assert.ifError(err);
1208
            assert.ok(_wallet);
1209
            _wallet.chain = blocktrail.Wallet.CHAIN_BTC_DEFAULT;
1210
            wallet = _wallet;
1211
1212
            assert.equal(wallet.primaryMnemonic, "give pause forget seed dance crawl situate hole kingdom");
1213
            assert.equal(wallet.identifier, myIdentifier);
1214
            assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
1215
1216
            cb();
1217
        });
1218
    });
1219
1220
    it("should have the expected addresses", function(cb) {
1221
        async.series([
1222
            function(cb) {
1223
                wallet.getNewAddress(function(err, address, path) {
1224
                    assert.ifError(err);
1225
                    assert.equal(path, "M/9999'/0/0");
1226
                    assert.equal(address, "2Mtfn5S9tVWnnHsBQixCLTsCAPFHvfhu6bM");
1227
1228
                    cb();
1229
                });
1230
            },
1231
            function(cb) {
1232
                wallet.getNewAddress(function(err, address, path) {
1233
                    assert.ifError(err);
1234
                    assert.equal(path, "M/9999'/0/1");
1235
                    assert.equal(address, "2NG49GDkm5qCYvDFi4cxAnkSho8qLbEz6C4");
1236
1237
                    cb();
1238
                });
1239
            },
1240
            function(cb) {
1241
                assert.equal(wallet.getAddressByPath("M/9999'/0/1"), "2NG49GDkm5qCYvDFi4cxAnkSho8qLbEz6C4");
1242
                assert.equal(wallet.getAddressByPath("M/9999'/0/6"), "2N1kM5xeDaCN9Weog3mbyxjpryNZcirnkB7");
1243
1244
                cb();
1245
            }
1246
        ], cb);
1247
    });
1248
1249
    it("should have a balance after discovery", function(cb) {
1250
        this.timeout(0);
1251
1252
        wallet.doDiscovery(50, function(err, confirmed, unconfirmed) {
1253
            assert.ok(confirmed + unconfirmed > 0);
1254
1255
            cb();
1256
        });
1257
    });
1258
1259
    it("should be upgraded and have expected addresses", function(cb) {
1260
        // set upgrade
1261
        wallet.upgradeToKeyIndex = 10000;
1262
        // lock
1263
        wallet.lock();
1264
        // unlock should upgrade
1265
        wallet.unlock({
1266
            passphrase: "password"
1267
        }).then(function() {
1268
            assert.equal(wallet.getBlocktrailPublicKey("M/10000'").toBase58(), "tpubD9m9hziKhYQExWgzMUNXdYMNUtourv96sjTUS9jJKdo3EDJAnCBJooMPm6vGSmkNTNAmVt988dzNfNY12YYzk9E6PkA7JbxYeZBFy4XAaCp");
1269
1270
            assert.equal(wallet.getAddressByPath("M/10000'/0/0"), "2N9ZLKXgs12JQKXvLkngn7u9tsYaQ5kXJmk");
1271
1272
            wallet.getNewAddress(function(err, address, path) {
1273
                assert.ifError(err);
1274
                assert.equal(path, "M/10000'/0/0");
1275
                assert.equal(address, "2N9ZLKXgs12JQKXvLkngn7u9tsYaQ5kXJmk");
1276
1277
                cb();
1278
            });
1279
        });
1280
    });
1281
});
1282
1283
describe('test wallet with bad password', function() {
1284
    var myIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
1285
    var wallet;
1286
1287
    after(function(cb) {
1288
        if (wallet) {
1289
            wallet.deleteWallet(true, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter err is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1290
                cb();
1291
            });
1292
        } else {
1293
            cb();
1294
        }
1295
    });
1296
1297
    it("should be created", function(cb) {
1298
        createDiscoveryTestWallet(myIdentifier, "badpassword", function(err, _wallet) {
1299
            assert.ifError(err);
1300
            assert.ok(_wallet);
1301
1302
            _wallet.chain = blocktrail.Wallet.CHAIN_BTC_DEFAULT;
1303
            wallet = _wallet;
1304
1305
            assert.equal(wallet.primaryMnemonic, "give pause forget seed dance crawl situate hole kingdom");
1306
            assert.equal(wallet.identifier, myIdentifier);
1307
            assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
1308
1309
            cb();
1310
        });
1311
    });
1312
1313
    it("should have the expected addresses (different from with the correct password)", function(cb) {
1314
        async.series([
1315
            function(cb) {
1316
                wallet.getNewAddress(function(err, address, path) {
1317
                    assert.ifError(err);
1318
                    assert.equal(path, "M/9999'/0/0");
1319
                    assert.equal(address, "2N9SGrV4NKRjdACYvHLPpy2oiPrxTPd44rg");
1320
1321
                    cb();
1322
                });
1323
            },
1324
            function(cb) {
1325
                wallet.getNewAddress(function(err, address, path) {
1326
                    assert.ifError(err);
1327
                    assert.equal(path, "M/9999'/0/1");
1328
                    assert.equal(address, "2NDq3DRy9E3YgHDA3haPJj3FtUS6V93avkf");
1329
1330
                    cb();
1331
                });
1332
            }
1333
        ], cb);
1334
    });
1335
1336
    it("shouldn't have a balance after discovery", function(cb) {
1337
        this.timeout(0);
1338
1339
        wallet.doDiscovery(50, function(err, confirmed, unconfirmed) {
1340
            assert.ok(confirmed + unconfirmed === 0);
1341
1342
            cb();
1343
        });
1344
    });
1345
});
1346
1347
describe('test wallet webhook', function() {
1348
    // this.timeout(0); // disable, can take long
1349
1350
    var myIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
1351
    var wallet;
1352
1353
    after(function(cb) {
1354
        if (wallet) {
1355
            wallet.deleteWallet(true, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter err is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1356
                cb();
1357
            });
1358
        } else {
1359
            cb();
1360
        }
1361
    });
1362
1363
    it("shouldn't already exist", function(cb) {
1364
        client.initWallet({
1365
            identifier: myIdentifier,
1366
            passphrase: "password"
1367
        }, function(err, wallet) {
1368
            assert.ok(err);
1369
            assert.ok(!wallet, "wallet with random ID [" + myIdentifier + "] already exists...");
1370
1371
            cb();
1372
        });
1373
    });
1374
1375
    it("should be created", function(cb) {
1376
        client.createNewWallet({
1377
            identifier: myIdentifier,
1378
            passphrase: "password",
1379
            keyIndex: 9999
1380
        }, function(err, _wallet) {
1381
            assert.ifError(err);
1382
            assert.ok(_wallet);
1383
1384
            wallet = _wallet;
1385
1386
            assert.equal(wallet.identifier, myIdentifier);
1387
            assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
1388
            cb();
1389
        });
1390
    });
1391
1392
    it("should have a 0 balance", function(cb) {
1393
        wallet.getBalance(function(err, confirmed, unconfirmed) {
1394
            assert.ifError(err);
1395
            assert.equal(confirmed, 0);
1396
            assert.equal(unconfirmed, 0);
1397
1398
            cb();
1399
        });
1400
    });
1401
1402
    it("should be able to create a webhook", function(cb) {
1403
        wallet.setupWebhook("https://www.blocktrail.com/webhook-test", function(err, webhook) {
1404
            assert.ifError(err);
1405
            assert.equal(webhook['url'], "https://www.blocktrail.com/webhook-test");
1406
            assert.equal(webhook['identifier'], "WALLET-" + myIdentifier);
1407
1408
            wallet.deleteWebhook(function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1409
                assert.ifError(err);
1410
1411
                cb();
1412
            });
1413
        });
1414
    });
1415
1416
    it("should be able to create a webhook with custom identifier", function(cb) {
1417
        var myWebhookIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
1418
1419
        wallet.setupWebhook("https://www.blocktrail.com/webhook-test", myWebhookIdentifier, function(err, webhook) {
1420
            assert.ifError(err);
1421
            assert.equal(webhook['url'], "https://www.blocktrail.com/webhook-test");
1422
            assert.equal(webhook['identifier'], myWebhookIdentifier);
1423
1424
            client.getWebhookEvents(myWebhookIdentifier, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1425
                assert.ifError(err);
1426
1427
                wallet.getNewAddress(function(err, address1) {
1428
                    assert.ifError(err);
1429
1430
                    wallet.deleteWebhook(myWebhookIdentifier, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1431
                        assert.ifError(err);
1432
1433
                        var myWebhookIdentifier = "nodejs-sdk-" + crypto.randomBytes(24).toString('hex');
1434
1435
                        wallet.setupWebhook("https://www.blocktrail.com/webhook-test", myWebhookIdentifier, function(err, webhook) {
1436
                            assert.ifError(err);
1437
                            assert.equal(webhook['url'], "https://www.blocktrail.com/webhook-test");
1438
                            assert.equal(webhook['identifier'], myWebhookIdentifier);
1439
1440
                            client.getWebhookEvents(myWebhookIdentifier, function(err, result) {
1441
                                assert.ifError(err);
1442
                                assert.ok(_.includes(_.map(result['data'], 'address'), address1));
1443
1444
                                wallet.getNewAddress(function(err, address2) {
1445
                                    assert.ifError(err);
1446
1447
                                    client.getWebhookEvents(myWebhookIdentifier, function(err, result) {
1448
                                        assert.ifError(err);
1449
                                        assert.ok(_.includes(_.map(result['data'], 'address'), address2));
1450
1451
                                        wallet.deleteWallet(function(err, result) {
1452
                                            assert.ifError(err);
1453
                                            assert.ok(result);
1454
1455
                                            client.deleteWebhook(myWebhookIdentifier, function(err, result) {
0 ignored issues
show
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1456
                                                assert.ok(err);
1457
1458
                                                cb();
1459
                                            });
1460
                                        });
1461
                                    });
1462
                                });
1463
                            });
1464
                        });
1465
                    });
1466
1467
                });
1468
            });
1469
        });
1470
    });
1471
});
1472
1473
describe("Wallet.getAddressAndType", function() {
1474
    var fixtures = [
1475
        {
1476
            address: "tb1qn08f8x0eamw66enrt497zu0v3u2danzey6asqs",
1477
            network: bitcoin.networks.testnet,
1478
            type: "bech32",
1479
            valid: true
1480
        },
1481
        {
1482
            address: "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7",
1483
            network: bitcoin.networks.testnet,
1484
            type: "bech32",
1485
            valid: true
1486
        },
1487
        {
1488
            address: "muinVykhtZyonxQxk8zBptX6Lmri91bdNG",
1489
            network: bitcoin.networks.testnet,
1490
            type: "base58",
1491
            valid: true
1492
        },
1493
        {
1494
            address: "2N7T4CD6CEuNHJoGKpoJH3YexqektXjyy6L",
1495
            network: bitcoin.networks.testnet,
1496
            type: "base58",
1497
            valid: true
1498
        },
1499
        {
1500
            address: "16uf9UUBbUHdVAnETGZQnvXZcf9NPU1QR6",
1501
            network: bitcoin.networks.bitcoin,
1502
            type: "base58",
1503
            valid: true
1504
        },
1505
        {
1506
            address: "3CgSFohdEqd7pSxbDAJeJo6X5Qm2tBbby9",
1507
            network: bitcoin.networks.bitcoin,
1508
            type: "base58",
1509
            valid: true
1510
        },
1511
        {
1512
            address: "bc1qqy36hngpyw4u6qfr40xszgate5qj827dqy36hngpyw4u6qfr40xsp3an42",
1513
            network: bitcoin.networks.bitcoin,
1514
            type: "bech32",
1515
            valid: true
1516
        },
1517
        {
1518
            address: "bc1qn08f8x0eamw66enrt497zu0v3u2danzewuxrmr",
1519
            network: bitcoin.networks.bitcoin,
1520
            type: "bech32",
1521
            valid: true
1522
        },
1523
        {
1524
            address: "16uf9UUBbUHdVAnETGZQnvXZcf9NPU1QR6",
1525
            network: bitcoin.networks.testnet,
1526
            type: "base58",
1527
            error: "Address invalid on this network",
1528
            valid: false
1529
        },
1530
        {
1531
            address: "3CgSFohdEqd7pSxbDAJeJo6X5Qm2tBbby9",
1532
            network: bitcoin.networks.testnet,
1533
            type: "base58",
1534
            error: "Address invalid on this network",
1535
            valid: false
1536
        },
1537
        {
1538
            address: "bc1qqy36hngpyw4u6qfr40xszgate5qj827dqy36hngpyw4u6qfr40xsp3an42",
1539
            network: bitcoin.networks.testnet,
1540
            type: "bech32",
1541
            error: "Address invalid on this network",
1542
            valid: false
1543
        },
1544
        {
1545
            address: "bc1qn08f8x0eamw66enrt497zu0v3u2danzewuxrmr",
1546
            network: bitcoin.networks.testnet,
1547
            type: "bech32",
1548
            error: "Address invalid on this network",
1549
            valid: false
1550
        },
1551
        {
1552
            address: "bc1qqy36hngpyw4u6qfr40xszgate5qj827dqy36hngpyw4u6qfr40xsp3an42",
1553
            network: bitcoin.networks.bitcoincash,
1554
            error: "Non-base58 character",
1555
            type: "bech32",
1556
            valid: false
1557
        },
1558
        {
1559
            address: "bc1qn08f8x0eamw66enrt497zu0v3u2danzewuxrmr",
1560
            network: bitcoin.networks.bitcoincash,
1561
            error: "Non-base58 character",
1562
            type: "bech32",
1563
            valid: false
1564
        },
1565
        {
1566
            address: "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7",
1567
            network: bitcoin.networks.bitcoincashtestnet,
1568
            error: "Non-base58 character",
1569
            type: "bech32",
1570
            valid: false
1571
        },
1572
        {
1573
            address: "tb1qn08f8x0eamw66enrt497zu0v3u2danzey6asqs",
1574
            network: bitcoin.networks.bitcoincashtestnet,
1575
            error: "Non-base58 character",
1576
            type: "bech32",
1577
            valid: false
1578
        },
1579
        {
1580
            address: "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7",
1581
            network: bitcoin.networks.bitcoin,
1582
            error: "Address invalid on this network",
1583
            type: "bech32",
1584
            valid: false
1585
        },
1586
        {
1587
            address: "tb1qn08f8x0eamw66enrt497zu0v3u2danzey6asqs",
1588
            network: bitcoin.networks.bitcoin,
1589
            error: "Address invalid on this network",
1590
            type: "bech32",
1591
            valid: false
1592
        },
1593
        {
1594
            address: "bc1qqy36hngpyw4u6qfr40xszgate5qj827dqy36hngpyw4u6qfr40xsp3an42",
1595
            network: bitcoin.networks.testnet,
1596
            error: "Address invalid on this network",
1597
            type: "bech32",
1598
            valid: false
1599
        },
1600
        {
1601
            address: "bc1qn08f8x0eamw66enrt497zu0v3u2danzewuxrmr",
1602
            network: bitcoin.networks.testnet,
1603
            error: "Address invalid on this network",
1604
            type: "bech32",
1605
            valid: false
1606
        }
1607
    ];
1608
1609
    fixtures.map(function(fixture) {
1610
        var description =
1611
            (fixture.valid ? "parses" : "fails to parse") +
1612
            " a " + fixture.type + " address: " + fixture.address;
1613
1614
        it(description, function(cb) {
1615
            var addrAndType;
1616
            var err;
1617
            try {
1618
                addrAndType = Wallet.getAddressAndType(fixture.address, fixture.network);
1619
            } catch (e) {
1620
                err = e;
1621
            }
1622
1623
            if (fixture.valid) {
1624
                assert.ifError(err);
0 ignored issues
show
Bug introduced by
The variable err seems to not be initialized for all possible execution paths. Are you sure ifError handles undefined variables?
Loading history...
1625
                assert.ok(Object.keys(addrAndType).indexOf("address") !== -1);
1626
                assert.ok(Object.keys(addrAndType).indexOf("decoded") !== -1);
1627
                assert.ok(Object.keys(addrAndType).indexOf("type") !== -1);
1628
                assert.equal(addrAndType.type, fixture.type);
1629
                assert.equal(addrAndType.address, fixture.address);
1630
            } else {
1631
                assert.ok(typeof err === "object");
1632
                assert.ok(typeof addrAndType === "undefined");
1633
                if (Object.keys(fixture).indexOf("error") !== -1) {
1634
                    assert.equal(err.message, fixture.error);
1635
                }
1636
            }
1637
            cb();
1638
        });
1639
    });
1640
});
1641
1642
describe("Wallet.convertPayToOutputs", function() {
1643
    var network = bitcoin.networks.testnet;
1644
    var fixtures = [
1645
        {
1646
            description: "p2wpkh",
1647
            network: bitcoin.networks.testnet,
1648
            value: 12345,
1649
            address: "tb1qn08f8x0eamw66enrt497zu0v3u2danzey6asqs",
1650
            script: "00149bce9399f9eeddad66635d4be171ec8f14decc59"
1651
        },
1652
        {
1653
            description: "p2wsh",
1654
            network: bitcoin.networks.testnet,
1655
            value: 12345,
1656
            address: "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7",
1657
            script: "00201863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262"
1658
        },
1659
        {
1660
            description: "p2pkh",
1661
            network: bitcoin.networks.testnet,
1662
            value: 12345,
1663
            address: "muinVykhtZyonxQxk8zBptX6Lmri91bdNG",
1664
            script: "76a9149bce9399f9eeddad66635d4be171ec8f14decc5988ac"
1665
        },
1666
        {
1667
            description: "p2sh",
1668
            network: bitcoin.networks.testnet,
1669
            value: 12345,
1670
            address: "2N7T4CD6CEuNHJoGKpoJH3YexqektXjyy6L",
1671
            script: "a9149bce9399f9eeddad66635d4be171ec8f14decc5987"
1672
        }
1673
    ];
1674
1675
    fixtures.map(function(fixture, i) {
1676
1677
        it(fixture.description + " converted to script, " + i, function(cb) {
1678
            var test = function(outputs) {
1679
                assert.ok(Array.isArray(outputs));
1680
                assert.equal(outputs[0].value, fixture.value);
1681
                assert.equal(outputs[0].scriptPubKey, fixture.script);
1682
                assert.equal(outputs[0].address, null);
1683
            };
1684
1685
            // should accept some input of ours
1686
            var pay = [{
1687
                scriptPubKey: fixture.script,
1688
                value: fixture.value
1689
            }];
1690
1691
            var outputs = Wallet.convertPayToOutputs(pay, network);
1692
            test(outputs);
1693
1694
            pay = {};
1695
            pay[fixture.address] = fixture.value;
1696
1697
            // should deal with simple mapping form
1698
            outputs = Wallet.convertPayToOutputs(pay, network);
1699
            test(outputs);
1700
1701
            // repeating the procedure should pass the same test
1702
            outputs = Wallet.convertPayToOutputs(outputs, network);
1703
            test(outputs);
1704
1705
            cb();
1706
        });
1707
    });
1708
});
1709
1710
describe('test wallet coin selection forms', function() {
1711
    var wallet;
1712
1713
    it("BTC testnet wallet should exist", function(cb) {
1714
        client.initWallet({
1715
            identifier: "unittest-transaction",
1716
            passphrase: "password"
1717
        }, function(err, _wallet) {
1718
            assert.ifError(err);
1719
            assert.ok(_wallet);
1720
1721
            wallet = _wallet;
1722
1723
            client.allWallets({page: 1}, function(err, wallets) {
1724
                assert.ifError(err);
1725
1726
                assert.ok(wallets['data'].length > 0);
1727
1728
                assert.equal(wallet.primaryMnemonic, "give pause forget seed dance crawl situate hole keen");
1729
                assert.equal(wallet.identifier, "unittest-transaction");
1730
                assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
1731
1732
                cb();
1733
            });
1734
        });
1735
    });
1736
1737
    it("shouldnt coin select for wrong network", function(cb) {
1738
        var pay = {};
1739
        pay["bc1qqy36hngpyw4u6qfr40xszgate5qj827dqy36hngpyw4u6qfr40xsp3an42"] = 10000;
1740
        wallet.coinSelection(pay, function(err, res) {
0 ignored issues
show
Unused Code introduced by
The parameter res is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1741
            assert.ok(err);
1742
            cb();
1743
        });
1744
    });
1745
1746
    var fixtures = [
1747
        {"tb1qn08f8x0eamw66enrt497zu0v3u2danzey6asqs": 10000},
1748
        {"tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7": 10000},
1749
        [
1750
            {
1751
                "address": "tb1qn08f8x0eamw66enrt497zu0v3u2danzey6asqs",
1752
                "value": 10000
1753
            },
1754
            {
1755
                "address": "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7",
1756
                "value": 10000
1757
            }
1758
        ],
1759
        [
1760
            {
1761
                "scriptPubKey": "00149bce9399f9eeddad66635d4be171ec8f14decc59",
1762
                "value": 10000
1763
            },
1764
            {
1765
                "address": "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7",
1766
                "value": 10000
1767
            }
1768
        ]
1769
    ];
1770
1771
    fixtures.map(function(fixture) {
1772
        var type = "object";
1773
        if (Array.isArray(fixture)) {
1774
            type = "outputs array";
1775
        }
1776
        it("should coin select for " + type, function(cb) {
1777
            wallet.coinSelection(fixture, false, function(err, res) {
0 ignored issues
show
Unused Code introduced by
The parameter res is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1778
                assert.ifError(err);
1779
                cb();
1780
            });
1781
        });
1782
    });
1783
});
1784
1785
describe('test wallet list transactions and addresses', function() {
1786
    var wallet;
1787
1788
    it("should exists", function(cb) {
1789
        client.initWallet({
1790
            identifier: "unittest-transaction",
1791
            passphrase: "password"
1792
        }, function(err, _wallet) {
1793
            assert.ifError(err);
1794
            assert.ok(_wallet);
1795
1796
            wallet = _wallet;
1797
1798
            client.allWallets({page: 1}, function(err, wallets) {
1799
                assert.ifError(err);
1800
1801
                assert.ok(wallets['data'].length > 0);
1802
1803
                assert.equal(wallet.primaryMnemonic, "give pause forget seed dance crawl situate hole keen");
1804
                assert.equal(wallet.identifier, "unittest-transaction");
1805
                assert.equal(wallet.getBlocktrailPublicKey("M/9999'").toBase58(), "tpubD9q6vq9zdP3gbhpjs7n2TRvT7h4PeBhxg1Kv9jEc1XAss7429VenxvQTsJaZhzTk54gnsHRpgeeNMbm1QTag4Wf1QpQ3gy221GDuUCxgfeZ");
1806
1807
                cb();
1808
            });
1809
        });
1810
    });
1811
1812
    it("should list expected transactions", function(cb) {
1813
        wallet.transactions({page: 1, limit: 23}, function(err, transactions) {
1814
            assert.ifError(err);
1815
            assert.ok(transactions['data']);
1816
            assert.ok(transactions['total']);
1817
            assert.ok(transactions['data'].length === 23);
1818
            assert.ok(transactions['data'][0]['hash'], "2cb21783635a5f22e9934b8c3262146b42d251dfb14ee961d120936a6c40fe89");
1819
1820
            cb();
1821
        });
1822
    });
1823
1824
    it("should list expected addresses", function(cb) {
1825
        wallet.addresses({page: 1, limit: 23}, function(err, addresses) {
1826
            assert.ifError(err);
1827
            assert.ok(addresses['data']);
1828
            assert.ok(addresses['total']);
1829
            assert.ok(addresses['data'].length === 23);
1830
            assert.ok(addresses['data'][0]['address'], "2MzyKviSL6pnWxkbHV7ecFRE3hWKfzmT8WS");
1831
1832
            cb();
1833
        });
1834
    });
1835
1836
    it("should list UTXOs", function(cb) {
1837
        wallet.utxos({page: 0, limit: 23}, function(err, addresses) {
1838
            assert.ifError(err);
1839
            assert.ok(addresses['data']);
1840
            assert.ok(addresses['total']);
1841
            assert.ok(addresses['data'].length === 23);
1842
1843
            cb();
1844
        });
1845
    });
1846
});
1847
1848
describe("size estimation", function() {
1849
1850
    it("should estimate proper size for 1 input 1 output TX", function() {
1851
        var txb = new bitcoin.TransactionBuilder(bitcoin.networks.testnet);
1852
        txb.addInput('4200000000000000000000000000000000000000000000000000000000000000', 0);
1853
        txb.addOutput('2MzyKviSL6pnWxkbHV7ecFRE3hWKfzmT8WS', 1);
1854
1855
        assert.equal(347, blocktrail.Wallet.estimateIncompleteTxSize(txb.buildIncomplete()));
1856
    });
1857
1858
    it("should estimate proper size for 99 inputs 1 output TX", function() {
1859
        var txb = new bitcoin.TransactionBuilder(bitcoin.networks.testnet);
1860
        for (var i = 0; i < 99; i++) {
1861
            txb.addInput('4200000000000000000000000000000000000000000000000000000000000000', i);
1862
        }
1863
        txb.addOutput('2MzyKviSL6pnWxkbHV7ecFRE3hWKfzmT8WS', 1);
1864
1865
        assert.equal(29453, blocktrail.Wallet.estimateIncompleteTxSize(txb.buildIncomplete()));
1866
    });
1867
1868
    it("should estimate proper size for 1 input 99 outputs TX", function() {
1869
        var txb = new bitcoin.TransactionBuilder(bitcoin.networks.testnet);
1870
        txb.addInput('4200000000000000000000000000000000000000000000000000000000000000', 0);
1871
        for (var i = 0; i < 99; i++) {
1872
            txb.addOutput('2MzyKviSL6pnWxkbHV7ecFRE3hWKfzmT8WS', 1);
1873
        }
1874
1875
        assert.equal(3679, blocktrail.Wallet.estimateIncompleteTxSize(txb.buildIncomplete()));
1876
    });
1877
});
1878
1879
describe("APIClient", function() {
1880
    it("resolvePrimaryPrivateKeyFromOptions", function(cb) {
1881
        client.resolvePrimaryPrivateKeyFromOptions({
1882
            passphrase: "password",
1883
            primaryMnemonic: "give pause forget seed dance crawl situate hole keen"
1884
        }, function(err, options) {
1885
            assert.ifError(err);
1886
            assert.ok(options.primaryPrivateKey);
1887
            assert.ok(options.primaryPrivateKey instanceof bitcoin.HDNode);
1888
            assert.equal("tprv8ZgxMBicQKsPeR93md5eVTbLDgQ8kfV4CDNtrVXv5p29KXtx7VHKFQThGkFgC61sYeeeaVH1yFv4thcvxS9cYdFrYwTNmkGhkQEJycSzAhE", options.primaryPrivateKey.toBase58());
1889
1890
            cb();
1891
1892
        });
1893
    });
1894
});
1895