@opcat-labs/opcat 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/.mocharc.yaml +3 -0
  2. package/index.d.ts +1541 -0
  3. package/index.js +74 -0
  4. package/lib/address.js +478 -0
  5. package/lib/block/block.js +277 -0
  6. package/lib/block/blockheader.js +295 -0
  7. package/lib/block/index.js +4 -0
  8. package/lib/block/merkleblock.js +323 -0
  9. package/lib/bn.js +3423 -0
  10. package/lib/crypto/bn.js +278 -0
  11. package/lib/crypto/ecdsa.js +339 -0
  12. package/lib/crypto/hash.browser.js +171 -0
  13. package/lib/crypto/hash.js +2 -0
  14. package/lib/crypto/hash.node.js +171 -0
  15. package/lib/crypto/point.js +221 -0
  16. package/lib/crypto/random.browser.js +28 -0
  17. package/lib/crypto/random.js +2 -0
  18. package/lib/crypto/random.node.js +11 -0
  19. package/lib/crypto/signature.js +325 -0
  20. package/lib/encoding/base58.js +111 -0
  21. package/lib/encoding/base58check.js +121 -0
  22. package/lib/encoding/bufferreader.js +212 -0
  23. package/lib/encoding/bufferwriter.js +140 -0
  24. package/lib/encoding/decode-asm.js +24 -0
  25. package/lib/encoding/decode-hex.js +32 -0
  26. package/lib/encoding/decode-script-chunks.js +43 -0
  27. package/lib/encoding/encode-hex.js +284 -0
  28. package/lib/encoding/is-hex.js +7 -0
  29. package/lib/encoding/varint.js +75 -0
  30. package/lib/errors/index.js +54 -0
  31. package/lib/errors/spec.js +314 -0
  32. package/lib/hash-cache.js +50 -0
  33. package/lib/hdprivatekey.js +678 -0
  34. package/lib/hdpublickey.js +525 -0
  35. package/lib/message/message.js +191 -0
  36. package/lib/mnemonic/mnemonic.js +303 -0
  37. package/lib/mnemonic/pbkdf2.browser.js +68 -0
  38. package/lib/mnemonic/pbkdf2.js +2 -0
  39. package/lib/mnemonic/pbkdf2.node.js +68 -0
  40. package/lib/mnemonic/words/chinese.js +2054 -0
  41. package/lib/mnemonic/words/english.js +2054 -0
  42. package/lib/mnemonic/words/french.js +2054 -0
  43. package/lib/mnemonic/words/index.js +8 -0
  44. package/lib/mnemonic/words/italian.js +2054 -0
  45. package/lib/mnemonic/words/japanese.js +2054 -0
  46. package/lib/mnemonic/words/spanish.js +2054 -0
  47. package/lib/networks.js +379 -0
  48. package/lib/opcode.js +255 -0
  49. package/lib/privatekey.js +374 -0
  50. package/lib/publickey.js +386 -0
  51. package/lib/script/index.js +5 -0
  52. package/lib/script/interpreter.js +1834 -0
  53. package/lib/script/script.js +1074 -0
  54. package/lib/script/stack.js +109 -0
  55. package/lib/script/write-i32-le.js +17 -0
  56. package/lib/script/write-push-data.js +35 -0
  57. package/lib/script/write-u16-le.js +12 -0
  58. package/lib/script/write-u32-le.js +16 -0
  59. package/lib/script/write-u64-le.js +24 -0
  60. package/lib/script/write-u8-le.js +8 -0
  61. package/lib/script/write-varint.js +46 -0
  62. package/lib/transaction/index.js +7 -0
  63. package/lib/transaction/input/index.js +5 -0
  64. package/lib/transaction/input/input.js +354 -0
  65. package/lib/transaction/input/multisig.js +242 -0
  66. package/lib/transaction/input/publickey.js +100 -0
  67. package/lib/transaction/input/publickeyhash.js +118 -0
  68. package/lib/transaction/output.js +231 -0
  69. package/lib/transaction/sighash.js +167 -0
  70. package/lib/transaction/signature.js +97 -0
  71. package/lib/transaction/transaction.js +1639 -0
  72. package/lib/transaction/unspentoutput.js +113 -0
  73. package/lib/util/_.js +47 -0
  74. package/lib/util/js.js +90 -0
  75. package/lib/util/preconditions.js +33 -0
  76. package/package.json +26 -0
  77. package/test/address.js +509 -0
  78. package/test/block/block.js +251 -0
  79. package/test/block/blockheader.js +275 -0
  80. package/test/block/merklebloack.js +211 -0
  81. package/test/crypto/bn.js +177 -0
  82. package/test/crypto/ecdsa.js +391 -0
  83. package/test/crypto/hash.browser.js +135 -0
  84. package/test/crypto/hash.js +136 -0
  85. package/test/crypto/point.js +224 -0
  86. package/test/crypto/random.js +32 -0
  87. package/test/crypto/signature.js +409 -0
  88. package/test/data/bip69.json +215 -0
  89. package/test/data/bitcoind/base58_keys_invalid.json +52 -0
  90. package/test/data/bitcoind/base58_keys_valid.json +335 -0
  91. package/test/data/bitcoind/blocks.json +22 -0
  92. package/test/data/bitcoind/script_tests.json +3822 -0
  93. package/test/data/bitcoind/sig_canonical.json +7 -0
  94. package/test/data/bitcoind/sig_noncanonical.json +36 -0
  95. package/test/data/bitcoind/tx_invalid.json +445 -0
  96. package/test/data/bitcoind/tx_valid.json +44 -0
  97. package/test/data/blk86756-testnet.dat +0 -0
  98. package/test/data/blk86756-testnet.js +14 -0
  99. package/test/data/blk86756-testnet.json +684 -0
  100. package/test/data/block.hex +1 -0
  101. package/test/data/ecdsa.json +230 -0
  102. package/test/data/merkleblocks.js +488 -0
  103. package/test/data/messages.json +22 -0
  104. package/test/data/sighash.json +12 -0
  105. package/test/data/tx_creation.json +95 -0
  106. package/test/encoding/base58.js +131 -0
  107. package/test/encoding/base58check.js +136 -0
  108. package/test/encoding/bufferreader.js +337 -0
  109. package/test/encoding/bufferwriter.js +172 -0
  110. package/test/encoding/varint.js +104 -0
  111. package/test/hashCache.js +67 -0
  112. package/test/hdkeys.js +445 -0
  113. package/test/hdprivatekey.js +332 -0
  114. package/test/hdpublickey.js +304 -0
  115. package/test/index.js +16 -0
  116. package/test/message/message.js +204 -0
  117. package/test/mnemonic/data/fixtures.json +300 -0
  118. package/test/mnemonic/mnemonic.js +259 -0
  119. package/test/mnemonic/mocha.opts +1 -0
  120. package/test/mnemonic/pbkdf2.test.js +59 -0
  121. package/test/networks.js +159 -0
  122. package/test/opcode.js +161 -0
  123. package/test/privatekey.js +439 -0
  124. package/test/publickey.js +554 -0
  125. package/test/script/interpreter.js +734 -0
  126. package/test/script/script.js +1437 -0
  127. package/test/transaction/deserialize.js +34 -0
  128. package/test/transaction/input/input.js +90 -0
  129. package/test/transaction/input/multisig.js +90 -0
  130. package/test/transaction/input/publickey.js +68 -0
  131. package/test/transaction/input/publickeyhash.js +51 -0
  132. package/test/transaction/output.js +185 -0
  133. package/test/transaction/sighash.js +65 -0
  134. package/test/transaction/signature.js +114 -0
  135. package/test/transaction/transaction.js +1109 -0
  136. package/test/transaction/unspentoutput.js +110 -0
  137. package/test/util/js.js +76 -0
  138. package/test/util/preconditions.js +79 -0
@@ -0,0 +1,259 @@
1
+ 'use strict';
2
+
3
+ var chai = require('chai');
4
+ var should = chai.should();
5
+ var opcat = require('../../');
6
+ var Mnemonic = opcat.Mnemonic;
7
+ var errors = require('../../').errors;
8
+ var bip39vectors = require('./data/fixtures.json');
9
+
10
+ describe('Mnemonic', function () {
11
+ this.timeout(30000);
12
+
13
+ it('should initialize the class', function () {
14
+ should.exist(Mnemonic);
15
+ });
16
+
17
+ describe('@fromRandom', function () {
18
+ it('should make a new mnemonic', function () {
19
+ let mnemonic = Mnemonic.fromRandom();
20
+ let mnemonic2 = Mnemonic.fromRandom();
21
+ mnemonic.toString().should.not.equal(mnemonic2.toString());
22
+ Mnemonic.Words.ENGLISH.includes(mnemonic.toString().split(' ')[0]).should.equal(true);
23
+ Mnemonic.Words.ENGLISH.includes(mnemonic.toString().split(' ')[1]).should.equal(true);
24
+ Mnemonic.Words.ENGLISH.includes(mnemonic.toString().split(' ')[2]).should.equal(true);
25
+ let mnemonic3 = Mnemonic.fromRandom(Mnemonic.Words.SPANISH);
26
+ Mnemonic.Words.SPANISH.includes(mnemonic3.toString().split(' ')[0]).should.equal(true);
27
+ Mnemonic.Words.SPANISH.includes(mnemonic3.toString().split(' ')[1]).should.equal(true);
28
+ Mnemonic.Words.SPANISH.includes(mnemonic3.toString().split(' ')[2]).should.equal(true);
29
+ });
30
+ });
31
+
32
+ describe('# Mnemonic', function () {
33
+ describe('Constructor', function () {
34
+ it('does not require new keyword', function () {
35
+ var mnemonic = Mnemonic();
36
+ mnemonic.should.be.instanceof(Mnemonic);
37
+ });
38
+
39
+ it('should fail with invalid data', function () {
40
+ (function () {
41
+ return new Mnemonic({});
42
+ }).should.throw(errors.InvalidArgument);
43
+ });
44
+
45
+ it('should fail with unknown word list', function () {
46
+ (function () {
47
+ return new Mnemonic(
48
+ 'pilots foster august tomorrow kit daughter unknown awesome model town village master',
49
+ );
50
+ }).should.throw(errors.Mnemonic.UnknownWordlist);
51
+ });
52
+
53
+ it('should fail with invalid mnemonic', function () {
54
+ (function () {
55
+ return new Mnemonic(
56
+ 'monster foster august tomorrow kit daughter unknown awesome model town village pilot',
57
+ );
58
+ }).should.throw(errors.Mnemonic.InvalidMnemonic);
59
+ });
60
+
61
+ it('should fail with invalid ENT', function () {
62
+ (function () {
63
+ return new Mnemonic(64);
64
+ }).should.throw(errors.InvalidArgument);
65
+ });
66
+
67
+ it('constructor defaults to english worldlist', function () {
68
+ var mnemonic = new Mnemonic();
69
+ mnemonic.wordlist.should.equal(Mnemonic.Words.ENGLISH);
70
+ });
71
+
72
+ it('allow using different worldlists', function () {
73
+ var mnemonic = new Mnemonic(Mnemonic.Words.SPANISH);
74
+ mnemonic.wordlist.should.equal(Mnemonic.Words.SPANISH);
75
+ });
76
+
77
+ it('constructor honor both length and wordlist', function () {
78
+ var mnemonic = new Mnemonic(32 * 7, Mnemonic.Words.SPANISH);
79
+ mnemonic.phrase.split(' ').length.should.equal(21);
80
+ mnemonic.wordlist.should.equal(Mnemonic.Words.SPANISH);
81
+ });
82
+
83
+ it('constructor should detect standard wordlist', function () {
84
+ var mnemonic = new Mnemonic(
85
+ 'afirmar diseño hielo fideo etapa ogro cambio fideo toalla pomelo número buscar',
86
+ );
87
+ mnemonic.wordlist.should.equal(Mnemonic.Words.SPANISH);
88
+ });
89
+ });
90
+
91
+ it('english wordlist is complete', function () {
92
+ Mnemonic.Words.ENGLISH.length.should.equal(2048);
93
+ Mnemonic.Words.ENGLISH[0].should.equal('abandon');
94
+ });
95
+
96
+ it('spanish wordlist is complete', function () {
97
+ Mnemonic.Words.SPANISH.length.should.equal(2048);
98
+ Mnemonic.Words.SPANISH[0].should.equal('ábaco');
99
+ });
100
+
101
+ it('japanese wordlist is complete', function () {
102
+ Mnemonic.Words.JAPANESE.length.should.equal(2048);
103
+ Mnemonic.Words.JAPANESE[0].should.equal('あいこくしん');
104
+ });
105
+
106
+ it('chinese wordlist is complete', function () {
107
+ Mnemonic.Words.CHINESE.length.should.equal(2048);
108
+ Mnemonic.Words.CHINESE[0].should.equal('的');
109
+ });
110
+
111
+ it('french wordlist is complete', function () {
112
+ Mnemonic.Words.FRENCH.length.should.equal(2048);
113
+ Mnemonic.Words.FRENCH[0].should.equal('abaisser');
114
+ });
115
+
116
+ it('italian wordlist is complete', function () {
117
+ Mnemonic.Words.ITALIAN.length.should.equal(2048);
118
+ Mnemonic.Words.ITALIAN[0].should.equal('abaco');
119
+ });
120
+
121
+ it('allows use different phrase lengths', function () {
122
+ var mnemonic;
123
+
124
+ mnemonic = new Mnemonic(32 * 4);
125
+ mnemonic.phrase.split(' ').length.should.equal(12);
126
+
127
+ mnemonic = new Mnemonic(32 * 5);
128
+ mnemonic.phrase.split(' ').length.should.equal(15);
129
+
130
+ mnemonic = new Mnemonic(32 * 6);
131
+ mnemonic.phrase.split(' ').length.should.equal(18);
132
+
133
+ mnemonic = new Mnemonic(32 * 7);
134
+ mnemonic.phrase.split(' ').length.should.equal(21);
135
+
136
+ mnemonic = new Mnemonic(32 * 8);
137
+ mnemonic.phrase.split(' ').length.should.equal(24);
138
+ });
139
+
140
+ it('validates a phrase', function () {
141
+ var valid = Mnemonic.isValid(
142
+ 'afirmar diseño hielo fideo etapa ogro cambio fideo toalla pomelo número buscar',
143
+ );
144
+ valid.should.equal(true);
145
+
146
+ var invalid = Mnemonic.isValid(
147
+ 'afirmar diseño hielo fideo etapa ogro cambio fideo hielo pomelo número buscar',
148
+ );
149
+ invalid.should.equal(false);
150
+
151
+ var invalid2 = Mnemonic.isValid(
152
+ 'afirmar diseño hielo fideo etapa ogro cambio fideo hielo pomelo número oneInvalidWord',
153
+ );
154
+ invalid2.should.equal(false);
155
+
156
+ var invalid3 = Mnemonic.isValid('totally invalid phrase');
157
+ invalid3.should.equal(false);
158
+
159
+ var valid2 = Mnemonic.isValid(
160
+ 'caution opprimer époque belote devenir ficeler filleul caneton apologie nectar frapper fouiller',
161
+ );
162
+ valid2.should.equal(true);
163
+ });
164
+
165
+ it('has a toString method', function () {
166
+ var mnemonic = new Mnemonic();
167
+ mnemonic.toString().should.equal(mnemonic.phrase);
168
+ });
169
+
170
+ it('has a fromString method', function () {
171
+ var mnemonic = Mnemonic.fromRandom();
172
+ mnemonic.toString().should.equal(mnemonic.phrase);
173
+ var mnemonic2 = Mnemonic.fromString(mnemonic.toString());
174
+ mnemonic2.toString().should.equal(mnemonic.toString());
175
+ var mnemonic3 = Mnemonic.fromRandom(Mnemonic.Words.SPANISH);
176
+ var mnemonic4 = Mnemonic.fromString(mnemonic3.toString(), Mnemonic.Words.SPANISH);
177
+ mnemonic3.toString().should.equal(mnemonic4.toString());
178
+ });
179
+
180
+ it('has a toString method', function () {
181
+ var mnemonic = new Mnemonic();
182
+ mnemonic.inspect().should.have.string('<Mnemonic:');
183
+ });
184
+
185
+ it('derives a seed without a passphrase', function () {
186
+ var mnemonic = new Mnemonic();
187
+ var seed = mnemonic.toSeed();
188
+ seed.length.should.equal(512 / 8);
189
+ should.exist(seed);
190
+ });
191
+
192
+ it('derives a seed using a passphrase', function () {
193
+ var mnemonic = new Mnemonic();
194
+ var seed = mnemonic.toSeed('my passphrase');
195
+ should.exist(seed);
196
+ });
197
+
198
+ it('derives an extended private key', function () {
199
+ var mnemonic = new Mnemonic();
200
+ var pk = mnemonic.toHDPrivateKey();
201
+ should.exist(pk);
202
+ });
203
+
204
+ it('Mnemonic.fromSeed should fail with invalid wordlist', function () {
205
+ (function () {
206
+ return Mnemonic.fromSeed(Buffer.alloc(1));
207
+ }).should.throw(errors.InvalidArgument);
208
+ });
209
+
210
+ it('Mnemonic.fromSeed should fail with invalid seed', function () {
211
+ (function () {
212
+ return Mnemonic.fromSeed();
213
+ }).should.throw(errors.InvalidArgument);
214
+ });
215
+
216
+ it('Constructor should fail with invalid seed', function () {
217
+ (function () {
218
+ return new Mnemonic(Buffer.alloc(1));
219
+ }).should.throw(errors.InvalidEntropy);
220
+ });
221
+
222
+ // To add new vectors for different languages:
223
+ // 1. Add and implement the wordlist so it appears in Mnemonic.Words
224
+ // 2. Add the vectors and make sure the key is lowercase of the key for Mnemonic.Words
225
+ var vectorwordlists = {};
226
+
227
+ for (var key in Mnemonic.Words) {
228
+ if (Mnemonic.Words.hasOwnProperty(key)) {
229
+ vectorwordlists[key.toLowerCase()] = Mnemonic.Words[key];
230
+ }
231
+ }
232
+
233
+ var testvector = function (v, lang) {
234
+ it('should pass test vector for ' + lang + ' #' + v, function () {
235
+ var wordlist = vectorwordlists[lang];
236
+ var vector = bip39vectors[lang][v];
237
+ var code = vector[1];
238
+ var mnemonic = vector[2];
239
+ var seed = vector[3];
240
+ var mnemonic1 = Mnemonic.fromSeed(Buffer.from(code, 'hex'), wordlist).phrase;
241
+ mnemonic1.should.equal(mnemonic);
242
+
243
+ var m = new Mnemonic(mnemonic);
244
+ var seed1 = m.toSeed(vector[0]);
245
+ seed1.toString('hex').should.equal(seed);
246
+
247
+ Mnemonic.isValid(mnemonic, wordlist).should.equal(true);
248
+ });
249
+ };
250
+
251
+ for (let key in bip39vectors) {
252
+ if (bip39vectors.hasOwnProperty(key)) {
253
+ for (var v = 0; v < bip39vectors[key].length; v++) {
254
+ testvector(v, key);
255
+ }
256
+ }
257
+ }
258
+ });
259
+ });
@@ -0,0 +1 @@
1
+ --timeout 7000
@@ -0,0 +1,59 @@
1
+ 'use strict';
2
+
3
+ var chai = require('chai');
4
+ chai.should();
5
+
6
+ var pbkdf2 = require('../../lib/mnemonic/pbkdf2');
7
+
8
+ describe('pbkdf2', function () {
9
+ this.timeout(10000);
10
+
11
+ // http://stackoverflow.com/questions/15593184/pbkdf2-hmac-sha-512-test-vectors
12
+ it('passes test vector 1', function () {
13
+ var key = 'password';
14
+ var salt = 'salt';
15
+
16
+ var res = pbkdf2(key, salt, 1, 64);
17
+ res
18
+ .toString('hex')
19
+ .should.equal(
20
+ '867f70cf1ade02cff3752599a3a53dc4af34c7a669815ae5d513554e1c8cf252c02d470a285a0501bad999bfe943c08f050235d7d68b1da55e63f73b60a57fce',
21
+ );
22
+ });
23
+
24
+ it('passes test vector 2', function () {
25
+ var key = 'password';
26
+ var salt = 'salt';
27
+
28
+ var res = pbkdf2(key, salt, 2, 64);
29
+ res
30
+ .toString('hex')
31
+ .should.equal(
32
+ 'e1d9c16aa681708a45f5c7c4e215ceb66e011a2e9f0040713f18aefdb866d53cf76cab2868a39b9f7840edce4fef5a82be67335c77a6068e04112754f27ccf4e',
33
+ );
34
+ });
35
+
36
+ it('passes test vector 3', function () {
37
+ var key = 'password';
38
+ var salt = 'salt';
39
+
40
+ var res = pbkdf2(key, salt, 4096, 64);
41
+ res
42
+ .toString('hex')
43
+ .should.equal(
44
+ 'd197b1b33db0143e018b12f3d1d1479e6cdebdcc97c5c0f87f6902e072f457b5143f30602641b3d55cd335988cb36b84376060ecd532e039b742a239434af2d5',
45
+ );
46
+ });
47
+
48
+ it('passes test vector 4', function () {
49
+ var key = 'passwordPASSWORDpassword';
50
+ var salt = 'saltSALTsaltSALTsaltSALTsaltSALTsalt';
51
+
52
+ var res = pbkdf2(key, salt, 4096, 64);
53
+ res
54
+ .toString('hex')
55
+ .should.equal(
56
+ '8c0511f4c6e597c6ac6315d8f0362e225f3c501495ba23b868c005174dc4ee71115b59f9e60cd9532fa33e0f75aefe30225c583a186cd82bd4daea9724a3d3b8',
57
+ );
58
+ });
59
+ });
@@ -0,0 +1,159 @@
1
+ 'use strict';
2
+
3
+ var expect = require('chai').expect;
4
+ var should = require('chai').should();
5
+ var opcat = require('..');
6
+ var networks = opcat.Networks;
7
+
8
+ describe('Networks', function () {
9
+ var customnet;
10
+
11
+ it('should contain all Networks', function () {
12
+ should.exist(networks.livenet);
13
+ should.exist(networks.testnet);
14
+ should.exist(networks.stn);
15
+ should.exist(networks.defaultNetwork);
16
+ });
17
+
18
+ it('should be able to define a custom Network', function () {
19
+ var custom = {
20
+ name: 'customnet',
21
+ alias: 'mynet',
22
+ pubkeyhash: 0x10,
23
+ privatekey: 0x90,
24
+ scripthash: 0x08,
25
+ xpubkey: 0x0278b20e,
26
+ xprivkey: 0x0278ade4,
27
+ networkMagic: 0xe7beb4d4,
28
+ port: 20001,
29
+ dnsSeeds: ['localhost', 'mynet.localhost'],
30
+ };
31
+ networks.add(custom);
32
+ customnet = networks.get('customnet');
33
+ for (var key in custom) {
34
+ if (key !== 'networkMagic') {
35
+ customnet[key].should.equal(custom[key]);
36
+ } else {
37
+ var expected = Buffer.from('e7beb4d4', 'hex');
38
+ customnet[key].should.deep.equal(expected);
39
+ }
40
+ }
41
+ });
42
+
43
+ it('should have network magic for testnet', function () {
44
+ var testnet = networks.get('testnet');
45
+ Buffer.isBuffer(testnet.networkMagic).should.equal(true);
46
+ });
47
+
48
+ it('should have network magic for stn', function () {
49
+ var stn = networks.get('stn');
50
+ Buffer.isBuffer(stn.networkMagic).should.equal(true);
51
+ });
52
+
53
+ it('can remove a custom network', function () {
54
+ networks.remove(customnet);
55
+ var net = networks.get('customnet');
56
+ should.equal(net, undefined);
57
+ });
58
+
59
+ it('should not set a network map for an undefined value', function () {
60
+ var custom = {
61
+ name: 'somenet',
62
+ pubkeyhash: 0x13,
63
+ privatekey: 0x93,
64
+ scripthash: 0x11,
65
+ xpubkey: 0x0278b20f,
66
+ xprivkey: 0x0278ade5,
67
+ networkMagic: 0xe7beb4d5,
68
+ port: 20008,
69
+ dnsSeeds: ['somenet.localhost'],
70
+ };
71
+ networks.add(custom);
72
+ var network = networks.get(undefined);
73
+ should.not.exist(network);
74
+ var somenet = networks.get('somenet');
75
+ should.exist(somenet);
76
+ somenet.name.should.equal('somenet');
77
+ networks.remove(somenet);
78
+ });
79
+
80
+ var constants = ['name', 'alias', 'pubkeyhash', 'scripthash', 'xpubkey', 'xprivkey'];
81
+
82
+ constants.forEach(function (key) {
83
+ it('should have constant ' + key + ' for livenet, testnet and stn', function () {
84
+ networks.testnet.hasOwnProperty(key).should.equal(true);
85
+ networks.livenet.hasOwnProperty(key).should.equal(true);
86
+ networks.stn.hasOwnProperty(key).should.equal(true);
87
+ });
88
+ });
89
+
90
+ it('tests only for the specified key', function () {
91
+ expect(networks.get(0x6f, 'pubkeyhash')).to.equal(networks.testnet);
92
+ expect(networks.get(0x6f, 'privatekey')).to.equal(undefined);
93
+ });
94
+
95
+ it('can test for multiple keys', function () {
96
+ expect(networks.get(0x6f, ['pubkeyhash', 'scripthash'])).to.equal(networks.testnet);
97
+ expect(networks.get(0xc4, ['pubkeyhash', 'scripthash'])).to.equal(networks.testnet);
98
+ expect(networks.get(0x6f, ['privatekey', 'port'])).to.equal(undefined);
99
+ });
100
+
101
+ it('should have regtest network', function () {
102
+ expect(networks.get('regtest').name).to.equal('regtest');
103
+ });
104
+
105
+ it('should have testnet network', function () {
106
+ expect(networks.get('testnet').name).to.equal('testnet');
107
+ });
108
+
109
+ it('should have stn network', function () {
110
+ expect(networks.get('stn').name).to.equal('stn');
111
+ });
112
+
113
+ it('should have livenet network', function () {
114
+ expect(networks.get('livenet').name).to.equal('livenet');
115
+ });
116
+
117
+ it('should have bchtest cashAddrPrefix', function () {
118
+ expect(networks.get('testnet').cashAddrPrefix).to.equal('bchtest');
119
+ });
120
+
121
+ it('should have bchreg cashAddrPrefix', function () {
122
+ expect(networks.get('regtest').cashAddrPrefix).to.equal('bchreg');
123
+ });
124
+
125
+ it('should have bchreg cashAddrPrefix after enableRegtest is called', function () {
126
+ var network = networks.get('testnet');
127
+ networks.enableRegtest();
128
+ expect(network.cashAddrPrefix).to.equal('bchreg');
129
+ });
130
+
131
+ it('should have bchtest cashAddrPrefix after disableRegtest is called', function () {
132
+ var network = networks.get('testnet');
133
+ networks.disableRegtest();
134
+ expect(network.cashAddrPrefix).to.equal('bchtest');
135
+ });
136
+ it('should have opcatstn cashAddrPrefix after enableStn is called', function () {
137
+ var network = networks.get('testnet');
138
+ networks.enableStn();
139
+ expect(network.cashAddrPrefix).to.equal('opcatstn');
140
+ });
141
+
142
+ it('should have bchtest cashAddrPrefix after disableStn is called', function () {
143
+ var network = networks.get('testnet');
144
+ networks.disableStn();
145
+ expect(network.cashAddrPrefix).to.equal('bchtest');
146
+ });
147
+
148
+ it('converts to string using the "name" property', function () {
149
+ networks.livenet.toString().should.equal('livenet');
150
+ });
151
+
152
+ it('network object should be immutable', function () {
153
+ expect(networks.testnet.name).to.equal('testnet');
154
+ var fn = function () {
155
+ networks.testnet.name = 'livenet';
156
+ };
157
+ expect(fn).to.throw(TypeError);
158
+ });
159
+ });
package/test/opcode.js ADDED
@@ -0,0 +1,161 @@
1
+ 'use strict';
2
+
3
+ var chai = require('chai');
4
+ var should = chai.should();
5
+ var expect = chai.expect;
6
+ var opcat = require('..');
7
+ var Opcode = opcat.Opcode;
8
+
9
+ describe('Opcode', function () {
10
+ it('should create a new Opcode', function () {
11
+ var opcode = new Opcode(5);
12
+ should.exist(opcode);
13
+ });
14
+
15
+ it('should convert to a string with this handy syntax', function () {
16
+ Opcode(0).toString().should.equal('OP_0');
17
+ Opcode(96).toString().should.equal('OP_16');
18
+ Opcode(97).toString().should.equal('OP_NOP');
19
+ });
20
+
21
+ it('should convert to a number with this handy syntax', function () {
22
+ Opcode('OP_0').toNumber().should.equal(0);
23
+ Opcode('OP_16').toNumber().should.equal(96);
24
+ Opcode('OP_NOP').toNumber().should.equal(97);
25
+ });
26
+
27
+ describe('#fromNumber', function () {
28
+ it('should work for 0', function () {
29
+ Opcode.fromNumber(0).num.should.equal(0);
30
+ });
31
+ it('should fail for non-number', function () {
32
+ Opcode.fromNumber.bind(null, 'a string').should.throw('Invalid Argument');
33
+ });
34
+ });
35
+
36
+ describe('#set', function () {
37
+ it('should work for object', function () {
38
+ Opcode(42).num.should.equal(42);
39
+ });
40
+ it('should fail for empty-object', function () {
41
+ expect(function () {
42
+ Opcode();
43
+ }).to.throw(TypeError);
44
+ });
45
+ });
46
+
47
+ describe('#toNumber', function () {
48
+ it('should work for 0', function () {
49
+ Opcode.fromNumber(0).toNumber().should.equal(0);
50
+ });
51
+ });
52
+
53
+ describe('#buffer', function () {
54
+ it('should correctly input/output a buffer', function () {
55
+ var buf = Buffer.from('a6', 'hex');
56
+ Opcode.fromBuffer(buf).toBuffer().should.deep.equal(buf);
57
+ });
58
+ });
59
+
60
+ describe('#fromString', function () {
61
+ it('should work for OP_0', function () {
62
+ Opcode.fromString('OP_0').num.should.equal(0);
63
+ });
64
+ it('should fail for invalid string', function () {
65
+ Opcode.fromString.bind(null, 'OP_SATOSHI').should.throw('Invalid opcodestr');
66
+ Opcode.fromString.bind(null, 'BANANA').should.throw('Invalid opcodestr');
67
+ });
68
+ it('should fail for non-string', function () {
69
+ Opcode.fromString.bind(null, 123).should.throw('Invalid Argument');
70
+ });
71
+ });
72
+
73
+ describe('#toString', function () {
74
+ it('should work for OP_0', function () {
75
+ Opcode.fromString('OP_0').toString().should.equal('OP_0');
76
+ });
77
+
78
+ it('should not work for non-opcode', function () {
79
+ expect(function () {
80
+ Opcode('OP_NOTACODE').toString();
81
+ }).to.throw('Opcode does not have a string representation');
82
+ });
83
+ });
84
+
85
+ describe('@map', function () {
86
+ it('should have a map containing 118 elements', function () {
87
+ Object.keys(Opcode.map).length.should.equal(118);
88
+ });
89
+ });
90
+
91
+ describe('@reverseMap', function () {
92
+ it('should exist and have op 185', function () {
93
+ should.exist(Opcode.reverseMap);
94
+ Opcode.reverseMap[185].should.equal('OP_NOP10');
95
+ });
96
+ });
97
+ var smallints = [
98
+ Opcode('OP_0'),
99
+ Opcode('OP_1'),
100
+ Opcode('OP_2'),
101
+ Opcode('OP_3'),
102
+ Opcode('OP_4'),
103
+ Opcode('OP_5'),
104
+ Opcode('OP_6'),
105
+ Opcode('OP_7'),
106
+ Opcode('OP_8'),
107
+ Opcode('OP_9'),
108
+ Opcode('OP_10'),
109
+ Opcode('OP_11'),
110
+ Opcode('OP_12'),
111
+ Opcode('OP_13'),
112
+ Opcode('OP_14'),
113
+ Opcode('OP_15'),
114
+ Opcode('OP_16'),
115
+ ];
116
+
117
+ describe('@smallInt', function () {
118
+ var testSmallInt = function (n, op) {
119
+ Opcode.smallInt(n).toString().should.equal(op.toString());
120
+ };
121
+
122
+ for (var i = 0; i < smallints.length; i++) {
123
+ var op = smallints[i];
124
+ it('should work for small int ' + op, testSmallInt.bind(null, i, op));
125
+ }
126
+
127
+ it('with not number', function () {
128
+ Opcode.smallInt.bind(null, '2').should.throw('Invalid Argument');
129
+ });
130
+
131
+ it('with n equal -1', function () {
132
+ Opcode.smallInt.bind(null, -1).should.throw('Invalid Argument');
133
+ });
134
+
135
+ it('with n equal 17', function () {
136
+ Opcode.smallInt.bind(null, 17).should.throw('Invalid Argument');
137
+ });
138
+ });
139
+ describe('@isSmallIntOp', function () {
140
+ var testIsSmallInt = function (op) {
141
+ Opcode.isSmallIntOp(op).should.equal(true);
142
+ };
143
+ for (var i = 0; i < smallints.length; i++) {
144
+ var op = smallints[i];
145
+ it('should work for small int ' + op, testIsSmallInt.bind(null, op));
146
+ }
147
+
148
+ it('should work for non-small ints', function () {
149
+ Opcode.isSmallIntOp(Opcode('OP_RETURN')).should.equal(false);
150
+ Opcode.isSmallIntOp(Opcode('OP_CHECKSIG')).should.equal(false);
151
+ Opcode.isSmallIntOp(Opcode('OP_IF')).should.equal(false);
152
+ Opcode.isSmallIntOp(Opcode('OP_NOP')).should.equal(false);
153
+ });
154
+ });
155
+
156
+ describe('#inspect', function () {
157
+ it('should output opcode by name, hex, and decimal', function () {
158
+ Opcode.fromString('OP_NOP').inspect().should.equal('<Opcode: OP_NOP, hex: 61, decimal: 97>');
159
+ });
160
+ });
161
+ });