UNPKG

19.4 kBJavaScriptView Raw
1'use strict';
2
3/* jshint maxstatements: 30 */
4
5var chai = require('chai');
6var should = chai.should();
7var expect = chai.expect;
8
9var bitcore = require('..');
10var PublicKey = bitcore.PublicKey;
11var Address = bitcore.Address;
12var Script = bitcore.Script;
13var Networks = bitcore.Networks;
14
15describe('Witness Address', function() {
16
17 var pubkeyhash = Buffer.from('2a9540f5cd929bf742d16b4e1bf1b0e874c907c9', 'hex');
18 var str = 'bc1q9225pawdj2dlwsk3dd8phudsap6vjp7fg3nwdl';
19 var wrappedStr = '3LfTZncZYsaxGBWYfDg8MTTFVKHmUHoZyA';
20 var buf = Buffer.from(str, 'utf8');
21
22 it('should throw an error because of bad network param', function() {
23 (function() {
24 return new Address(P2WPKHLivenet[0], 'main', 'witnesspubkeyhash');
25 }).should.throw('Second argument must be "livenet" or "testnet".');
26 });
27
28 it('should throw an error because of bad type param', function() {
29 (function() {
30 return new Address(P2WPKHLivenet[0], 'livenet', 'pubkey');
31 }).should.throw('Third argument must be "pubkeyhash", "scripthash", "witnesspubkeyhash", or "witnessscripthash".');
32 });
33
34 // livenet valid
35 var P2WPKHLivenet = [
36 'bc1q9225pawdj2dlwsk3dd8phudsap6vjp7fg3nwdl',
37 'bc1q9225pawtn2dlwsk3dd8phudsap6vjp7f2h4044',
38 'bc1q9225pewdn2dlwsk3dd8phudsap6vjp7f8umq0y',
39 'bc1q9225rawdn2dlwsk3dd8phudsap6vjp7fgwh45q',
40 ' bc1q92z5pawdn2dlwsk3dd8phudsap6vjp7f82uucr \t\n'
41 ];
42
43 // livenet p2wsh
44 var P2WSHLivenet = [
45 'bc1q9225pawdn2dlwsk3dd8phudsap6vjp7fhqj5wnrpg457qjq0ycvsdffnze',
46 'bc1q9225pawdn2dlwsk3dd8phudsap6vjp7fhqj5wnrpg457qjq0ycvqcgpth2',
47 'bc1q9225pawdn2dlwsk3dd8phudsap6vjp7fhqj5wnrpg457qjq0yctsfgd86t',
48 'bc1q9225pawdn2dlwsk3dd8phudsap6vjp7fhqj5wnrpg457qjq0yctquf9l0c',
49 '\t \nbc1qr225pawdn2dlwsk3dd8phudsap6vjp7fhqj5wnrpg457qjq0yctqtdwmes \r'
50 ];
51
52 // testnet p2Wsh
53 var P2WSHTestnet = [
54 'tb1q9225pawdn2dlwsk3dd8phudsap6vjp7fhqj5wnrpg457qjq0ycvs6pluck',
55 'tb1q9225pawdn2dlwsk3dd8phudsap6vjp7fhqj5wnrpg457qjq0ycvq0qhyd9',
56 'tb1q9225pawdn2dlwsk3dd8phudsap6vjp7fhqj5wnrpg457qjq0ycts7qmgqy',
57 'tb1q9225pawdn2dlwsk3dd8phudsap6vjp7fhqj5wnrpg457qjq0yctqtpns4h'
58 ];
59
60 //livenet bad checksums
61 var badChecksums = [
62 'bc1q9225pawdj2dlwsk3dd8phudsap6vjp7fg3nwdd',
63 'bc1q9225pawtn2dlwsk3dd8phudsap6vjp7f2h4040',
64 'bc1q9225pewdn2dlwsk3dd8phudsap6vjp7f8umq00',
65 'bc1q9225rawdn2dlwsk3dd8phudsap6vjp7fgwh455'
66 ];
67
68 //livenet incorrect witness version
69 var incorrectWitnessVersions = [
70 'bc1p9225pawdj2dlwsk3dd8phudsap6vjp7fr0y9q5',
71 'bc1p9225pawdn2dlwsk3dd8phudsap6vjp7fhqj5wnrpg457qjq0ycvsjzekl8'
72 ];
73
74 //testnet valid
75 var P2WPKHTestnet = [
76 'tb1q5lrlddcjejvu0qyx0f5fg59zj89danlxtt058g',
77 'tb1qrqsut4l6payxr9zda6s74jsgupc096t40k234h',
78 'tb1qkjxpx3kzdqj3qydxfsd88rj8vwzy2ry9luturg',
79 'tb1qa38kkwah0mncpn29j6xlzv4xa5m3wrr0juyt2j'
80 ];
81
82 describe('validation', function() {
83
84 it('getValidationError detects network mismatchs', function() {
85 var error = Address.getValidationError('bc1q9225pawdj2dlwsk3dd8phudsap6vjp7fg3nwdl', 'testnet');
86 should.exist(error);
87 });
88
89 it('isValid returns true on a valid address', function() {
90 var valid = Address.isValid('bc1q9225pawdj2dlwsk3dd8phudsap6vjp7fg3nwdl', 'livenet');
91 valid.should.equal(true);
92 });
93
94 it('isValid returns false on network mismatch', function() {
95 var valid = Address.isValid('bc1q9225pawdj2dlwsk3dd8phudsap6vjp7fg3nwdl', 'testnet');
96 valid.should.equal(false);
97 });
98
99 it('validates correctly the P2WPKH test vector', function() {
100 for (var i = 0; i < P2WPKHLivenet.length; i++) {
101 var error = Address.getValidationError(P2WPKHLivenet[i]);
102 should.not.exist(error);
103 }
104 });
105
106 it('validates correctly the P2WSH test vector', function() {
107 for (var i = 0; i < P2WSHLivenet.length; i++) {
108 var error = Address.getValidationError(P2WSHLivenet[i]);
109 should.not.exist(error);
110 }
111 });
112
113 it('validates correctly the P2WSH testnet test vector', function() {
114 for (var i = 0; i < P2WSHTestnet.length; i++) {
115 var error = Address.getValidationError(P2WSHTestnet[i], 'testnet');
116 should.not.exist(error);
117 }
118 });
119
120 it('rejects correctly the P2WPKH livenet test vector with "testnet" parameter', function() {
121 for (var i = 0; i < P2WPKHLivenet.length; i++) {
122 var error = Address.getValidationError(P2WPKHLivenet[i], 'testnet');
123 should.exist(error);
124 }
125 });
126
127 it('validates correctly the P2WPKH livenet test vector with "livenet" parameter', function() {
128 for (var i = 0; i < P2WPKHLivenet.length; i++) {
129 var error = Address.getValidationError(P2WPKHLivenet[i], 'livenet');
130 should.not.exist(error);
131 }
132 });
133
134 it('should not validate if checksum is invalid', function() {
135 for (var i = 0; i < badChecksums.length; i++) {
136 var error = Address.getValidationError(badChecksums[i], 'livenet', 'witnesspubkeyhash');
137 should.exist(error);
138 error.message.should.equal('Invalid checksum for ' + badChecksums[i]);
139 }
140 });
141
142 it('should not validate if witness version is not 0', function() {
143 for (var i = 0; i < incorrectWitnessVersions.length; i++) {
144 var error = Address.getValidationError(incorrectWitnessVersions[i], 'livenet', 'witnesspubkeyhash');
145 should.exist(error);
146 error.message.should.equal('Only witness v0 addresses are supported.');
147 }
148 });
149
150 it('should not validate on a network mismatch', function() {
151 var error, i;
152 for (i = 0; i < P2WPKHLivenet.length; i++) {
153 error = Address.getValidationError(P2WPKHLivenet[i], 'testnet', 'witnesspubkeyhash');
154 should.exist(error);
155 error.message.should.equal('Address has mismatched network type.');
156 }
157 for (i = 0; i < P2WPKHTestnet.length; i++) {
158 error = Address.getValidationError(P2WPKHTestnet[i], 'livenet', 'witnesspubkeyhash');
159 should.exist(error);
160 error.message.should.equal('Address has mismatched network type.');
161 }
162 });
163
164 it('should not validate on a type mismatch', function() {
165 for (var i = 0; i < P2WPKHLivenet.length; i++) {
166 var error = Address.getValidationError(P2WPKHLivenet[i], 'livenet', 'witnessscripthash');
167 should.exist(error);
168 error.message.should.equal('Address has mismatched type.');
169 }
170 });
171
172 it('testnet addresses are validated correctly', function() {
173 for (var i = 0; i < P2WPKHTestnet.length; i++) {
174 var error = Address.getValidationError(P2WPKHTestnet[i], 'testnet');
175 should.not.exist(error);
176 }
177 });
178
179 it('addresses with whitespace are validated correctly', function() {
180 var ws = ' \r \t \n bc1q9225pawdj2dlwsk3dd8phudsap6vjp7fg3nwdl \t \n \r';
181 var error = Address.getValidationError(ws);
182 should.not.exist(error);
183 Address.fromString(ws).toString().should.equal('bc1q9225pawdj2dlwsk3dd8phudsap6vjp7fg3nwdl');
184 });
185 });
186
187 describe('instantiation', function() {
188 it('can be instantiated from another address', function() {
189 var address = Address.fromBuffer(buf);
190 var address2 = new Address({
191 hashBuffer: address.hashBuffer,
192 network: address.network,
193 type: address.type
194 });
195 address.toString().should.equal(address2.toString());
196 });
197 });
198
199 describe('encodings', function() {
200
201 it('should make an address from a buffer', function() {
202 Address.fromBuffer(buf).toString().should.equal(str);
203 new Address(buf).toString().should.equal(str);
204 new Address(buf).toString().should.equal(str);
205 });
206
207 it('should make an address from a string', function() {
208 Address.fromString(str).toString().should.equal(str);
209 new Address(str).toString().should.equal(str);
210 });
211
212 it('should make an address using a non-string network', function() {
213 Address.fromString(str, Networks.livenet).toString().should.equal(str);
214 });
215
216 it('should throw with bad network param', function() {
217 (function(){
218 Address.fromString(str, 'somenet');
219 }).should.throw('Unknown network');
220 });
221
222 it('should error because of incorrect format for script hash', function() {
223 (function() {
224 return new Address.fromScriptHash('notascript', null, Address.PayToWitnessScriptHash);
225 }).should.throw('Address supplied is not a buffer.');
226 });
227
228 it('should error because of incorrect type for pubkey transform', function() {
229 (function() {
230 return Address._transformPublicKey(new Buffer(20), null, Address.PayToWitnessPublicKeyHash);
231 }).should.throw('Address must be an instance of PublicKey.');
232 (function() {
233 return Address._transformPublicKey(new Buffer(20), null, Address.PayToScriptHash);
234 }).should.throw('Address must be an instance of PublicKey.');
235 });
236
237 it('should make this address from a compressed pubkey', function() {
238 var pubkey = new PublicKey('0285e9737a74c30a873f74df05124f2aa6f53042c2fc0a130d6cbd7d16b944b004');
239 var address = Address.fromPublicKey(pubkey, 'livenet', Address.PayToWitnessPublicKeyHash);
240 address.toString().should.equal('bc1qtuh205nkztchej8r84k8vna9upsjh7q8dvy576');
241 });
242
243 it('should make this wrapped address from a compressed pubkey', function() {
244 var pubkey = new PublicKey('0285e9737a74c30a873f74df05124f2aa6f53042c2fc0a130d6cbd7d16b944b004');
245 var address = Address.fromPublicKey(pubkey, 'livenet', Address.PayToScriptHash);
246 address.toString().should.equal('3GNVVBik6S9Ux5ccS6ymmEeQELXGJdP8p8');
247 });
248
249 it('should use the default network for pubkey', function() {
250 var pubkey = new PublicKey('0285e9737a74c30a873f74df05124f2aa6f53042c2fc0a130d6cbd7d16b944b004');
251 var address = Address.fromPublicKey(pubkey, null, Address.PayToWitnessPublicKeyHash);
252 address.network.should.equal(Networks.defaultNetwork);
253 });
254
255 it('should use the default network for pubkey', function() {
256 var pubkey = new PublicKey('0285e9737a74c30a873f74df05124f2aa6f53042c2fc0a130d6cbd7d16b944b004');
257 var address = Address.fromPublicKey(pubkey, null, Address.PayToScriptHash);
258 address.network.should.equal(Networks.defaultNetwork);
259 });
260
261 it('should fail to make an address with an uncompressed pubkey', function() {
262 var pubkey = new PublicKey('0485e9737a74c30a873f74df05124f2aa6f53042c2fc0a130d6cbd7d16b944b00' +
263 '4833fef26c8be4c4823754869ff4e46755b85d851077771c220e2610496a29d98');
264 (function() {
265 return Address.fromPublicKey(pubkey, 'livenet', Address.PayToWitnessPublicKeyHash);
266 }).should.throw('Witness addresses must use compressed public keys.');
267 });
268
269 it('should fail to make a wrapped address with an uncompressed pubkey', function() {
270 var pubkey = new PublicKey('0485e9737a74c30a873f74df05124f2aa6f53042c2fc0a130d6cbd7d16b944b00' +
271 '4833fef26c8be4c4823754869ff4e46755b85d851077771c220e2610496a29d98');
272 (function() {
273 return Address.fromPublicKey(pubkey, 'livenet', Address.PayToScriptHash);
274 }).should.throw('Witness addresses must use compressed public keys.');
275 });
276
277
278 it('should classify from a custom network', function() {
279 var custom = {
280 name: 'customnetwork2',
281 pubkeyhash: 0x1c,
282 privatekey: 0x1e,
283 scripthash: 0x28,
284 bech32prefix: 'abc',
285 xpubkey: 0x02e8de8f,
286 xprivkey: 0x02e8da54,
287 networkMagic: 0x0c110907,
288 port: 7333
289 };
290 var addressString = 'abc1q9225pawdj2dlwsk3dd8phudsap6vjp7fzfr9m9';
291 Networks.add(custom);
292 var network = Networks.get('customnetwork2');
293 var address = Address.fromString(addressString);
294 address.type.should.equal(Address.PayToWitnessPublicKeyHash);
295 address.network.should.equal(network);
296 Networks.remove(network);
297 });
298
299 describe('from a script', function() {
300 it('should make this address from a p2wpkh output script', function() {
301 var s = new Script('OP_0 20 ' +
302 '0x2a9540f5cd929bf742d16b4e1bf1b0e874c907c9');
303 var buf = s.toBuffer();
304 var a = Address.fromScript(s, 'livenet');
305 a.toString().should.equal('bc1q9225pawdj2dlwsk3dd8phudsap6vjp7fg3nwdl');
306 var b = new Address(s, 'livenet');
307 b.toString().should.equal('bc1q9225pawdj2dlwsk3dd8phudsap6vjp7fg3nwdl');
308 });
309
310 it('should make this address from a p2wsh input script', function() {
311 var s = Script.fromString('OP_0 32 0x2a9540f5cd9a9bf742d16b4e1bf1b0e874c907c9b825474c614569e0480f2619');
312 var a = Address.fromScript(s, 'livenet');
313 a.toString().should.equal('bc1q9225pawdn2dlwsk3dd8phudsap6vjp7fhqj5wnrpg457qjq0ycvsdffnze');
314 var b = new Address(s, 'livenet');
315 b.toString().should.equal('bc1q9225pawdn2dlwsk3dd8phudsap6vjp7fhqj5wnrpg457qjq0ycvsdffnze');
316 });
317
318 it('returns the same address if the script is a pay to witness public key hash out', function() {
319 var address = 'bc1q9225pawdj2dlwsk3dd8phudsap6vjp7fg3nwdl';
320 var script = Script.buildWitnessV0Out(new Address(address));
321 Address(script, Networks.livenet).toString().should.equal(address);
322 });
323 it('returns the same address if the script is a pay to witness script hash out', function() {
324 var address = 'bc1q9225pawdn2dlwsk3dd8phudsap6vjp7fhqj5wnrpg457qjq0ycvsdffnze';
325 var script = Script.buildWitnessV0Out(new Address(address));
326 Address(script, Networks.livenet).toString().should.equal(address);
327 });
328 });
329
330 it('should derive from this known address string livenet', function() {
331 var address = new Address(str);
332 var buffer = address.toBuffer();
333 buffer.toString().should.equal(Buffer.from(str, 'utf8').toString());
334 });
335
336 it('should derive from this known address string testnet', function() {
337 var a = new Address(P2WPKHTestnet[0], 'testnet');
338 var b = new Address(a.toString());
339 b.toString().should.equal(P2WPKHTestnet[0]);
340 b.network.should.equal(Networks.testnet);
341 });
342
343 it('should derive from this known address string livenet witness scripthash', function() {
344 var a = new Address(P2WSHLivenet[0], 'livenet', 'witnessscripthash');
345 var b = new Address(a.toString());
346 b.toString().should.equal(P2WSHLivenet[0]);
347 });
348
349 it('should derive from this known address string testnet witness scripthash', function() {
350 var address = new Address(P2WSHTestnet[0], 'testnet', 'witnessscripthash');
351 address = new Address(address.toString());
352 address.toString().should.equal(P2WSHTestnet[0]);
353 });
354
355 });
356
357 describe('#toBuffer', function() {
358
359 it('2a9540f5cd929bf742d16b4e1bf1b0e874c907c9 corresponds to hash bc1q9225pawdj2dlwsk3dd8phudsap6vjp7fg3nwdl', function() {
360 var address = new Address(str);
361 var fromBuffer = new Address(address.toBuffer())
362 address.hashBuffer.toString('hex').should.equal(pubkeyhash.toString('hex'));
363 });
364
365 });
366
367 describe('#object', function() {
368
369 it('roundtrip to-from-to', function() {
370 var obj = new Address(str).toObject();
371 var address = Address.fromObject(obj);
372 address.toString().should.equal(str);
373 });
374 });
375
376 describe('#toString', function() {
377
378 it('livenet witnesspubkeyhash address', function() {
379 var address = new Address(str);
380 address.toString().should.equal(str);
381 });
382
383 it('witnessscripthash address', function() {
384 var address = new Address(P2WSHLivenet[0]);
385 address.toString().should.equal(P2WSHLivenet[0]);
386 });
387
388 it('testnet witnessscripthash address', function() {
389 var address = new Address(P2WSHTestnet[0]);
390 address.toString().should.equal(P2WSHTestnet[0]);
391 });
392
393 it('testnet witnesspubkeyhash address', function() {
394 var address = new Address(P2WPKHTestnet[0]);
395 address.toString().should.equal(P2WPKHTestnet[0]);
396 });
397
398 });
399
400 describe('#inspect', function() {
401 it('should output formatted output correctly', function() {
402 var address = new Address(str);
403 var output = '<Address: bc1q9225pawdj2dlwsk3dd8phudsap6vjp7fg3nwdl, type: witnesspubkeyhash, network: livenet>';
404 address.inspect().should.equal(output);
405 });
406 });
407
408 describe('questions about the address', function() {
409 it('should detect a P2WSH address', function() {
410 new Address(P2WSHLivenet[0]).isPayToWitnessScriptHash().should.equal(true);
411 new Address(P2WSHLivenet[0]).isPayToWitnessPublicKeyHash().should.equal(false);
412 new Address(P2WSHTestnet[0]).isPayToWitnessScriptHash().should.equal(true);
413 new Address(P2WSHTestnet[0]).isPayToWitnessPublicKeyHash().should.equal(false);
414 });
415 it('should detect a Pay To Witness PubkeyHash address', function() {
416 new Address(P2WPKHLivenet[0]).isPayToWitnessPublicKeyHash().should.equal(true);
417 new Address(P2WPKHLivenet[0]).isPayToWitnessScriptHash().should.equal(false);
418 new Address(P2WPKHTestnet[0]).isPayToWitnessPublicKeyHash().should.equal(true);
419 new Address(P2WPKHTestnet[0]).isPayToWitnessScriptHash().should.equal(false);
420 });
421 });
422
423 it('can roundtrip from/to a object', function() {
424 var address = new Address(P2WSHLivenet[0]);
425 expect(new Address(address.toObject()).toString()).to.equal(P2WSHLivenet[0]);
426 });
427
428 it('will use the default network for an object', function() {
429 var obj = {
430 hash: '2a9540f5cd9a9bf742d16b4e1bf1b0e874c907c9b825474c614569e0480f2619',
431 type: 'witnessscripthash'
432 };
433 var address = new Address(obj);
434 address.network.should.equal(Networks.defaultNetwork);
435 });
436
437 describe('creating a P2WSH address from public keys', function() {
438
439 var public1 = '02da5798ed0c055e31339eb9b5cef0d3c0ccdec84a62e2e255eb5c006d4f3e7f5b';
440 var public2 = '0272073bf0287c4469a2a011567361d42529cd1a72ab0d86aa104ecc89342ffeb0';
441 var public3 = '02738a516a78355db138e8119e58934864ce222c553a5407cf92b9c1527e03c1a2';
442 var publics = [public1, public2, public3];
443
444 it('can create an address from a set of public keys', function() {
445 var address = Address.createMultisig(publics, 2, Networks.livenet, null, Address.PayToWitnessScriptHash);
446 address.toString().should.equal('bc1qukwqyzxcjdykr0cfxghwkrx9rkmdvapc08syez75q5ewg3j5umvsu5w9yf');
447 address = new Address(publics, 2, Networks.livenet, Address.PayToWitnessScriptHash);
448 address.toString().should.equal('bc1qukwqyzxcjdykr0cfxghwkrx9rkmdvapc08syez75q5ewg3j5umvsu5w9yf');
449 });
450
451 it('works on testnet also', function() {
452 var address = Address.createMultisig(publics, 2, Networks.testnet, null, Address.PayToWitnessScriptHash);
453 address.toString().should.equal('tb1qukwqyzxcjdykr0cfxghwkrx9rkmdvapc08syez75q5ewg3j5umvstuc27x');
454 });
455
456 it('can also be created by Address.createMultisig', function() {
457 var address = Address.createMultisig(publics, 2, null, null, Address.PayToWitnessScriptHash);
458 var address2 = Address.createMultisig(publics, 2, null, null, Address.PayToWitnessScriptHash);
459 address.toString().should.equal(address2.toString());
460 });
461
462 it('fails if invalid array is provided', function() {
463 expect(function() {
464 return Address.createMultisig([], 3, 'testnet', null, Address.PayToWitnessScriptHash);
465 }).to.throw('Number of required signatures must be less than or equal to the number of public keys');
466 });
467 });
468});