UNPKG

254 kBJavaScriptView Raw
1import _Aes from 'aes';
2import _Bn from 'bn.js';
3import bs58 from 'bs58';
4import elliptic from 'bitcoin-elliptic';
5import hashjs from 'hash.js';
6import pbkdf2 from 'pbkdf2-compat';
7import isHex from 'is-hex';
8import randomBytes from 'randombytes';
9
10var version = "2.0.2";
11
12function Bn(n, base, ...rest) {
13 if (!(this instanceof Bn)) {
14 return new Bn(n, base, ...rest);
15 }
16
17 _Bn.call(this, n, base, ...rest);
18}
19
20Object.keys(_Bn).forEach(function (key) {
21 Bn[key] = _Bn[key];
22});
23Bn.prototype = Object.create(_Bn.prototype);
24Bn.prototype.constructor = Bn;
25
26function reverseBuf(buf) {
27 const buf2 = Buffer.alloc(buf.length);
28
29 for (let i = 0; i < buf.length; i++) {
30 buf2[i] = buf[buf.length - 1 - i];
31 }
32
33 return buf2;
34}
35
36Bn.prototype.fromHex = function (hex, opts) {
37 return this.fromBuffer(Buffer.from(hex, 'hex'), opts);
38};
39
40Bn.prototype.toHex = function (opts) {
41 return this.toBuffer(opts).toString('hex');
42};
43
44Bn.prototype.toJSON = function () {
45 return this.toString();
46};
47
48Bn.prototype.fromJSON = function (str) {
49 const bn = Bn(str);
50 bn.copy(this);
51 return this;
52};
53
54Bn.prototype.fromNumber = function (n) {
55 const bn = Bn(n);
56 bn.copy(this);
57 return this;
58};
59
60Bn.prototype.toNumber = function () {
61 return parseInt(this.toString(10), 10);
62};
63
64Bn.prototype.fromString = function (str, base) {
65 const bn = Bn(str, base);
66 bn.copy(this);
67 return this;
68};
69
70Bn.fromBuffer = function (buf, opts = {
71 endian: 'big'
72}) {
73 if (opts.endian === 'little') {
74 buf = reverseBuf(buf);
75 }
76
77 const hex = buf.toString('hex');
78 const bn = new Bn(hex, 16);
79 return bn;
80};
81
82Bn.prototype.fromBuffer = function (buf, opts) {
83 const bn = Bn.fromBuffer(buf, opts);
84 bn.copy(this);
85 return this;
86};
87
88Bn.prototype.toBuffer = function (opts = {
89 size: undefined,
90 endian: 'big'
91}) {
92 let buf;
93
94 if (opts.size) {
95 const hex = this.toString(16, 2);
96 const natlen = hex.length / 2;
97 buf = Buffer.from(hex, 'hex');
98
99 if (natlen === opts.size) ; else if (natlen > opts.size) {
100 buf = buf.slice(natlen - buf.length, buf.length);
101 } else if (natlen < opts.size) {
102 const rbuf = Buffer.alloc(opts.size);
103
104 for (let i = 0; i < buf.length; i++) {
105 rbuf[rbuf.length - 1 - i] = buf[buf.length - 1 - i];
106 }
107
108 for (let i = 0; i < opts.size - natlen; i++) {
109 rbuf[i] = 0;
110 }
111
112 buf = rbuf;
113 }
114 } else {
115 const hex = this.toString(16, 2);
116 buf = Buffer.from(hex, 'hex');
117 }
118
119 if (opts.endian === 'little') {
120 buf = reverseBuf(buf);
121 }
122
123 const longzero = Buffer.from([0]);
124
125 if (Buffer.compare(buf, longzero) === 0) {
126 return Buffer.from([]);
127 }
128
129 return buf;
130};
131
132Bn.prototype.toFastBuffer = Bn.prototype.toBuffer;
133Bn.fromFastBuffer = Bn.fromBuffer;
134Bn.prototype.fromFastBuffer = Bn.prototype.fromBuffer;
135
136Bn.prototype.fromSm = function (buf, opts = {
137 endian: 'big'
138}) {
139 if (buf.length === 0) {
140 this.fromBuffer(Buffer.from([0]));
141 }
142
143 const endian = opts.endian;
144
145 if (endian === 'little') {
146 buf = reverseBuf(buf);
147 }
148
149 if (buf[0] & 0x80) {
150 buf[0] = buf[0] & 0x7f;
151 this.fromBuffer(buf);
152 this.neg().copy(this);
153 } else {
154 this.fromBuffer(buf);
155 }
156
157 return this;
158};
159
160Bn.prototype.toSm = function (opts = {
161 endian: 'big'
162}) {
163 const endian = opts.endian;
164 let buf;
165
166 if (this.cmp(0) === -1) {
167 buf = this.neg().toBuffer();
168
169 if (buf[0] & 0x80) {
170 buf = Buffer.concat([Buffer.from([0x80]), buf]);
171 } else {
172 buf[0] = buf[0] | 0x80;
173 }
174 } else {
175 buf = this.toBuffer();
176
177 if (buf[0] & 0x80) {
178 buf = Buffer.concat([Buffer.from([0x00]), buf]);
179 }
180 }
181
182 if (buf.length === 1 & buf[0] === 0) {
183 buf = Buffer.from([]);
184 }
185
186 if (endian === 'little') {
187 buf = reverseBuf(buf);
188 }
189
190 return buf;
191};
192
193Bn.prototype.fromBits = function (bits, opts = {
194 strict: false
195}) {
196 let buf = Buffer.alloc(4);
197 buf.writeUInt32BE(bits, 0);
198 bits = buf.readInt32BE(0);
199
200 if (opts.strict && bits & 0x00800000) {
201 throw new Error('negative bit set');
202 }
203
204 const nsize = bits >> 24;
205 const nword = bits & 0x007fffff;
206 buf = Buffer.alloc(4);
207 buf.writeInt32BE(nword);
208
209 if (nsize <= 3) {
210 buf = buf.slice(1, nsize + 1);
211 } else {
212 const fill = Buffer.alloc(nsize - 3);
213 fill.fill(0);
214 buf = Buffer.concat([buf, fill]);
215 }
216
217 this.fromBuffer(buf);
218
219 if (bits & 0x00800000) {
220 Bn(0).sub(this).copy(this);
221 }
222
223 return this;
224};
225
226Bn.prototype.toBits = function () {
227 let buf;
228
229 if (this.lt(0)) {
230 buf = this.neg().toBuffer();
231 } else {
232 buf = this.toBuffer();
233 }
234
235 let nsize = buf.length;
236 let nword;
237
238 if (nsize > 3) {
239 nword = Buffer.concat([Buffer.from([0]), buf.slice(0, 3)]).readUInt32BE(0);
240 } else if (nsize <= 3) {
241 const blank = Buffer.alloc(3 - nsize + 1);
242 blank.fill(0);
243 nword = Buffer.concat([blank, buf.slice(0, nsize)]).readUInt32BE(0);
244 }
245
246 if (nword & 0x00800000) {
247 nword >>= 8;
248 nsize++;
249 }
250
251 if (this.lt(0)) {
252 nword |= 0x00800000;
253 }
254
255 const bits = nsize << 24 | nword;
256 buf = Buffer.alloc(4);
257 buf.writeInt32BE(bits, 0);
258 return buf.readUInt32BE(0);
259};
260
261Bn.prototype.fromScriptNumBuffer = function (buf, fRequireMinimal, nMaxNumSize) {
262 if (nMaxNumSize === undefined) {
263 nMaxNumSize = 4;
264 }
265
266 if (buf.length > nMaxNumSize) {
267 throw new Error('script number overflow');
268 }
269
270 if (fRequireMinimal && buf.length > 0) {
271 if ((buf[buf.length - 1] & 0x7f) === 0) {
272 if (buf.length <= 1 || (buf[buf.length - 2] & 0x80) === 0) {
273 throw new Error('non-minimally encoded script number');
274 }
275 }
276 }
277
278 return this.fromSm(buf, {
279 endian: 'little'
280 });
281};
282
283Bn.prototype.toScriptNumBuffer = function (buf) {
284 return this.toSm({
285 endian: 'little'
286 });
287};
288
289Bn.prototype.neg = function () {
290 const _neg = _Bn.prototype.neg.call(this);
291
292 const neg = Object.create(Bn.prototype);
293
294 _neg.copy(neg);
295
296 return neg;
297};
298
299Bn.prototype.add = function (bn) {
300 const _bn = _Bn.prototype.add.call(this, bn);
301
302 bn = Object.create(Bn.prototype);
303
304 _bn.copy(bn);
305
306 return bn;
307};
308
309Bn.prototype.sub = function (bn) {
310 const _bn = _Bn.prototype.sub.call(this, bn);
311
312 bn = Object.create(Bn.prototype);
313
314 _bn.copy(bn);
315
316 return bn;
317};
318
319Bn.prototype.mul = function (bn) {
320 const _bn = _Bn.prototype.mul.call(this, bn);
321
322 bn = Object.create(Bn.prototype);
323
324 _bn.copy(bn);
325
326 return bn;
327};
328
329Bn.prototype.mod = function (bn) {
330 const _bn = _Bn.prototype.mod.call(this, bn);
331
332 bn = Object.create(Bn.prototype);
333
334 _bn.copy(bn);
335
336 return bn;
337};
338
339Bn.prototype.umod = function (bn) {
340 const _bn = _Bn.prototype.umod.call(this, bn);
341
342 bn = Object.create(Bn.prototype);
343
344 _bn.copy(bn);
345
346 return bn;
347};
348
349Bn.prototype.invm = function (bn) {
350 const _bn = _Bn.prototype.invm.call(this, bn);
351
352 bn = Object.create(Bn.prototype);
353
354 _bn.copy(bn);
355
356 return bn;
357};
358
359Bn.prototype.div = function (bn) {
360 const _bn = _Bn.prototype.div.call(this, bn);
361
362 bn = Object.create(Bn.prototype);
363
364 _bn.copy(bn);
365
366 return bn;
367};
368
369Bn.prototype.ushln = function (bits) {
370 const _bn = _Bn.prototype.ushln.call(this, bits);
371
372 const bn = Object.create(Bn.prototype);
373
374 _bn.copy(bn);
375
376 return bn;
377};
378
379Bn.prototype.ushrn = function (bits) {
380 const _bn = _Bn.prototype.ushrn.call(this, bits);
381
382 const bn = Object.create(Bn.prototype);
383
384 _bn.copy(bn);
385
386 return bn;
387};
388
389Bn.prototype.cmp = function (bn) {
390 return _Bn.prototype.cmp.call(this, bn);
391};
392
393function decorate(name) {
394 Bn.prototype['_' + name] = Bn.prototype[name];
395
396 const f = function (b) {
397 if (typeof b === 'string') {
398 b = new Bn(b);
399 } else if (typeof b === 'number') {
400 b = new Bn(b.toString());
401 }
402
403 return this['_' + name](b);
404 };
405
406 Bn.prototype[name] = f;
407}
408
409Bn.prototype.eq = function (b) {
410 return this.cmp(b) === 0;
411};
412
413Bn.prototype.neq = function (b) {
414 return this.cmp(b) !== 0;
415};
416
417Bn.prototype.gt = function (b) {
418 return this.cmp(b) > 0;
419};
420
421Bn.prototype.geq = function (b) {
422 return this.cmp(b) >= 0;
423};
424
425Bn.prototype.lt = function (b) {
426 return this.cmp(b) < 0;
427};
428
429Bn.prototype.leq = function (b) {
430 return this.cmp(b) <= 0;
431};
432
433decorate('add');
434decorate('sub');
435decorate('mul');
436decorate('mod');
437decorate('invm');
438decorate('div');
439decorate('cmp');
440decorate('gt');
441decorate('geq');
442decorate('lt');
443decorate('leq');
444
445class Br {
446 constructor(buf) {
447 this.fromObject({
448 buf
449 });
450 }
451
452 fromObject(obj) {
453 this.buf = obj.buf || this.buf || undefined;
454 this.pos = obj.pos || this.pos || 0;
455 return this;
456 }
457
458 eof() {
459 return this.pos >= this.buf.length;
460 }
461
462 read(len = this.buf.length) {
463 const buf = this.buf.slice(this.pos, this.pos + len);
464 this.pos = this.pos + len;
465 return buf;
466 }
467
468 readReverse(len = this.buf.length) {
469 const buf = this.buf.slice(this.pos, this.pos + len);
470 this.pos = this.pos + len;
471 const buf2 = Buffer.alloc(buf.length);
472
473 for (let i = 0; i < buf2.length; i++) {
474 buf2[i] = buf[buf.length - 1 - i];
475 }
476
477 return buf2;
478 }
479
480 readUInt8() {
481 const val = this.buf.readUInt8(this.pos);
482 this.pos = this.pos + 1;
483 return val;
484 }
485
486 readInt8() {
487 const val = this.buf.readInt8(this.pos);
488 this.pos = this.pos + 1;
489 return val;
490 }
491
492 readUInt16BE() {
493 const val = this.buf.readUInt16BE(this.pos);
494 this.pos = this.pos + 2;
495 return val;
496 }
497
498 readInt16BE() {
499 const val = this.buf.readInt16BE(this.pos);
500 this.pos = this.pos + 2;
501 return val;
502 }
503
504 readUInt16LE() {
505 const val = this.buf.readUInt16LE(this.pos);
506 this.pos = this.pos + 2;
507 return val;
508 }
509
510 readInt16LE() {
511 const val = this.buf.readInt16LE(this.pos);
512 this.pos = this.pos + 2;
513 return val;
514 }
515
516 readUInt32BE() {
517 const val = this.buf.readUInt32BE(this.pos);
518 this.pos = this.pos + 4;
519 return val;
520 }
521
522 readInt32BE() {
523 const val = this.buf.readInt32BE(this.pos);
524 this.pos = this.pos + 4;
525 return val;
526 }
527
528 readUInt32LE() {
529 const val = this.buf.readUInt32LE(this.pos);
530 this.pos = this.pos + 4;
531 return val;
532 }
533
534 readInt32LE() {
535 const val = this.buf.readInt32LE(this.pos);
536 this.pos = this.pos + 4;
537 return val;
538 }
539
540 readUInt64BEBn() {
541 const buf = this.buf.slice(this.pos, this.pos + 8);
542 const bn = new Bn().fromBuffer(buf);
543 this.pos = this.pos + 8;
544 return bn;
545 }
546
547 readUInt64LEBn() {
548 const buf = this.readReverse(8);
549 const bn = new Bn().fromBuffer(buf);
550 return bn;
551 }
552
553 readVarIntNum() {
554 const first = this.readUInt8();
555 let bn, n;
556
557 switch (first) {
558 case 0xfd:
559 return this.readUInt16LE();
560
561 case 0xfe:
562 return this.readUInt32LE();
563
564 case 0xff:
565 bn = this.readUInt64LEBn();
566 n = bn.toNumber();
567
568 if (n <= Math.pow(2, 53)) {
569 return n;
570 } else {
571 throw new Error('number too large to retain precision - use readVarIntBn');
572 }
573
574 default:
575 return first;
576 }
577 }
578
579 readVarIntBuf() {
580 const first = this.buf.readUInt8(this.pos);
581
582 switch (first) {
583 case 0xfd:
584 return this.read(1 + 2);
585
586 case 0xfe:
587 return this.read(1 + 4);
588
589 case 0xff:
590 return this.read(1 + 8);
591
592 default:
593 return this.read(1);
594 }
595 }
596
597 readVarIntBn() {
598 const first = this.readUInt8();
599
600 switch (first) {
601 case 0xfd:
602 return new Bn(this.readUInt16LE());
603
604 case 0xfe:
605 return new Bn(this.readUInt32LE());
606
607 case 0xff:
608 return this.readUInt64LEBn();
609
610 default:
611 return new Bn(first);
612 }
613 }
614
615}
616
617class Bw {
618 constructor(bufs) {
619 this.fromObject({
620 bufs
621 });
622 }
623
624 fromObject(obj) {
625 this.bufs = obj.bufs || this.bufs || [];
626 return this;
627 }
628
629 getLength() {
630 let len = 0;
631
632 for (const i in this.bufs) {
633 const buf = this.bufs[i];
634 len = len + buf.length;
635 }
636
637 return len;
638 }
639
640 toBuffer() {
641 return Buffer.concat(this.bufs);
642 }
643
644 write(buf) {
645 this.bufs.push(buf);
646 return this;
647 }
648
649 writeReverse(buf) {
650 const buf2 = Buffer.alloc(buf.length);
651
652 for (let i = 0; i < buf2.length; i++) {
653 buf2[i] = buf[buf.length - 1 - i];
654 }
655
656 this.bufs.push(buf2);
657 return this;
658 }
659
660 writeUInt8(n) {
661 const buf = Buffer.alloc(1);
662 buf.writeUInt8(n, 0);
663 this.write(buf);
664 return this;
665 }
666
667 writeInt8(n) {
668 const buf = Buffer.alloc(1);
669 buf.writeInt8(n, 0);
670 this.write(buf);
671 return this;
672 }
673
674 writeUInt16BE(n) {
675 const buf = Buffer.alloc(2);
676 buf.writeUInt16BE(n, 0);
677 this.write(buf);
678 return this;
679 }
680
681 writeInt16BE(n) {
682 const buf = Buffer.alloc(2);
683 buf.writeInt16BE(n, 0);
684 this.write(buf);
685 return this;
686 }
687
688 writeUInt16LE(n) {
689 const buf = Buffer.alloc(2);
690 buf.writeUInt16LE(n, 0);
691 this.write(buf);
692 return this;
693 }
694
695 writeInt16LE(n) {
696 const buf = Buffer.alloc(2);
697 buf.writeInt16LE(n, 0);
698 this.write(buf);
699 return this;
700 }
701
702 writeUInt32BE(n) {
703 const buf = Buffer.alloc(4);
704 buf.writeUInt32BE(n, 0);
705 this.write(buf);
706 return this;
707 }
708
709 writeInt32BE(n) {
710 const buf = Buffer.alloc(4);
711 buf.writeInt32BE(n, 0);
712 this.write(buf);
713 return this;
714 }
715
716 writeUInt32LE(n) {
717 const buf = Buffer.alloc(4);
718 buf.writeUInt32LE(n, 0);
719 this.write(buf);
720 return this;
721 }
722
723 writeInt32LE(n) {
724 const buf = Buffer.alloc(4);
725 buf.writeInt32LE(n, 0);
726 this.write(buf);
727 return this;
728 }
729
730 writeUInt64BEBn(bn) {
731 const buf = bn.toBuffer({
732 size: 8
733 });
734 this.write(buf);
735 return this;
736 }
737
738 writeUInt64LEBn(bn) {
739 const buf = bn.toBuffer({
740 size: 8
741 });
742 this.writeReverse(buf);
743 return this;
744 }
745
746 writeVarIntNum(n) {
747 const buf = Bw.varIntBufNum(n);
748 this.write(buf);
749 return this;
750 }
751
752 writeVarIntBn(bn) {
753 const buf = Bw.varIntBufBn(bn);
754 this.write(buf);
755 return this;
756 }
757
758 static varIntBufNum(n) {
759 let buf;
760
761 if (n < 253) {
762 buf = Buffer.alloc(1);
763 buf.writeUInt8(n, 0);
764 } else if (n < 0x10000) {
765 buf = Buffer.alloc(1 + 2);
766 buf.writeUInt8(253, 0);
767 buf.writeUInt16LE(n, 1);
768 } else if (n < 0x100000000) {
769 buf = Buffer.alloc(1 + 4);
770 buf.writeUInt8(254, 0);
771 buf.writeUInt32LE(n, 1);
772 } else {
773 buf = Buffer.alloc(1 + 8);
774 buf.writeUInt8(255, 0);
775 buf.writeInt32LE(n & -1, 1);
776 buf.writeUInt32LE(Math.floor(n / 0x100000000), 5);
777 }
778
779 return buf;
780 }
781
782 static varIntBufBn(bn) {
783 let buf;
784 const n = bn.toNumber();
785
786 if (n < 253) {
787 buf = Buffer.alloc(1);
788 buf.writeUInt8(n, 0);
789 } else if (n < 0x10000) {
790 buf = Buffer.alloc(1 + 2);
791 buf.writeUInt8(253, 0);
792 buf.writeUInt16LE(n, 1);
793 } else if (n < 0x100000000) {
794 buf = Buffer.alloc(1 + 4);
795 buf.writeUInt8(254, 0);
796 buf.writeUInt32LE(n, 1);
797 } else {
798 const bw = new Bw();
799 bw.writeUInt8(255);
800 bw.writeUInt64LEBn(bn);
801 buf = bw.toBuffer();
802 }
803
804 return buf;
805 }
806
807}
808
809class Struct {
810 constructor(obj) {
811 this.fromObject(obj);
812 }
813
814 fromObject(obj) {
815 if (!obj) {
816 return this;
817 }
818
819 for (const key of Object.keys(obj)) {
820 if (obj[key] !== undefined) {
821 this[key] = obj[key];
822 }
823 }
824
825 return this;
826 }
827
828 static fromObject(obj) {
829 return new this().fromObject(obj);
830 }
831
832 fromBr(br) {
833 if (!(br instanceof Br)) {
834 throw new Error('br must be a buffer reader');
835 }
836
837 throw new Error('not implemented');
838 }
839
840 static fromBr(br) {
841 return new this().fromBr(br);
842 }
843
844 asyncFromBr(br) {
845 if (!(br instanceof Br)) {
846 throw new Error('br must be a buffer reader');
847 }
848
849 throw new Error('not implemented');
850 }
851
852 static asyncFromBr(br) {
853 return new this().asyncFromBr(br);
854 }
855
856 toBw(bw) {
857 throw new Error('not implemented');
858 }
859
860 asyncToBw(bw) {
861 throw new Error('not implemented');
862 }
863
864 *genFromBuffers() {
865 throw new Error('not implemented');
866 }
867
868 *expect(len, startbuf) {
869 let buf = startbuf;
870 const bw = new Bw();
871 let gotlen = 0;
872
873 if (startbuf) {
874 bw.write(startbuf);
875 gotlen += startbuf.length;
876 }
877
878 while (gotlen < len) {
879 const remainderlen = len - gotlen;
880 buf = yield remainderlen;
881
882 if (!buf) {
883 continue;
884 }
885
886 bw.write(buf);
887 gotlen += buf.length;
888 }
889
890 buf = bw.toBuffer();
891 const overlen = gotlen - len;
892 const remainderbuf = buf.slice(buf.length - overlen, buf.length);
893 buf = buf.slice(0, buf.length - overlen);
894 return {
895 buf: buf,
896 remainderbuf: remainderbuf
897 };
898 }
899
900 fromBuffer(buf, ...rest) {
901 if (!Buffer.isBuffer(buf)) {
902 throw new Error('buf must be a buffer');
903 }
904
905 const br = new Br(buf);
906 return this.fromBr(br, ...rest);
907 }
908
909 static fromBuffer(...rest) {
910 return new this().fromBuffer(...rest);
911 }
912
913 asyncFromBuffer(buf, ...rest) {
914 if (!Buffer.isBuffer(buf)) {
915 throw new Error('buf must be a buffer');
916 }
917
918 const br = new Br(buf);
919 return this.asyncFromBr(br, ...rest);
920 }
921
922 static asyncFromBuffer(buf, ...rest) {
923 return new this().asyncFromBuffer(buf, ...rest);
924 }
925
926 fromFastBuffer(buf, ...rest) {
927 if (buf.length === 0) {
928 return this;
929 } else {
930 return this.fromBuffer(buf, ...rest);
931 }
932 }
933
934 static fromFastBuffer(...rest) {
935 return new this().fromFastBuffer(...rest);
936 }
937
938 toBuffer(...rest) {
939 return this.toBw(...rest).toBuffer();
940 }
941
942 asyncToBuffer(...rest) {
943 return this.asyncToBw(...rest).then(bw => bw.toBuffer());
944 }
945
946 toFastBuffer(...rest) {
947 if (Object.keys(this).length === 0) {
948 return Buffer.alloc(0);
949 } else {
950 return this.toBuffer(...rest);
951 }
952 }
953
954 fromHex(hex, ...rest) {
955 if (!isHex(hex)) {
956 throw new Error('invalid hex string');
957 }
958
959 const buf = Buffer.from(hex, 'hex');
960 return this.fromBuffer(buf, ...rest);
961 }
962
963 static fromHex(hex, ...rest) {
964 return new this().fromHex(hex, ...rest);
965 }
966
967 asyncFromHex(hex, ...rest) {
968 if (!isHex(hex)) {
969 throw new Error('invalid hex string');
970 }
971
972 const buf = Buffer.from(hex, 'hex');
973 return this.asyncFromBuffer(buf, ...rest);
974 }
975
976 static asyncFromHex(hex, ...rest) {
977 return new this().asyncFromHex(hex, ...rest);
978 }
979
980 fromFastHex(hex, ...rest) {
981 if (!isHex(hex)) {
982 throw new Error('invalid hex string');
983 }
984
985 const buf = Buffer.from(hex, 'hex');
986 return this.fromFastBuffer(buf, ...rest);
987 }
988
989 static fromFastHex(hex, ...rest) {
990 return new this().fromFastHex(hex, ...rest);
991 }
992
993 toHex(...rest) {
994 return this.toBuffer(...rest).toString('hex');
995 }
996
997 asyncToHex(...rest) {
998 return this.asyncToBuffer(...rest).then(buf => buf.toString('hex'));
999 }
1000
1001 toFastHex(...rest) {
1002 return this.toFastBuffer(...rest).toString('hex');
1003 }
1004
1005 fromString(str, ...rest) {
1006 if (typeof str !== 'string') {
1007 throw new Error('str must be a string');
1008 }
1009
1010 return this.fromHex(str, ...rest);
1011 }
1012
1013 static fromString(str, ...rest) {
1014 return new this().fromString(str, ...rest);
1015 }
1016
1017 asyncFromString(str, ...rest) {
1018 if (typeof str !== 'string') {
1019 throw new Error('str must be a string');
1020 }
1021
1022 return this.asyncFromHex(str, ...rest);
1023 }
1024
1025 static asyncFromString(str, ...rest) {
1026 return new this().asyncFromString(str, ...rest);
1027 }
1028
1029 toString(...rest) {
1030 return this.toHex(...rest);
1031 }
1032
1033 asyncToString(...rest) {
1034 return this.asyncToHex(...rest);
1035 }
1036
1037 fromJSON(json) {
1038 throw new Error('not implemented');
1039 }
1040
1041 static fromJSON(json, ...rest) {
1042 return new this().fromJSON(json, ...rest);
1043 }
1044
1045 asyncFromJSON(json, ...rest) {
1046 throw new Error('not implemented');
1047 }
1048
1049 static asyncFromJSON(json, ...rest) {
1050 return new this().asyncFromJSON(json, ...rest);
1051 }
1052
1053 toJSON() {
1054 var json = {};
1055
1056 for (var val in this) {
1057 if (Array.isArray(this[val])) {
1058 const arr = [];
1059
1060 for (var i in this[val]) {
1061 if (typeof this[val][i].toJSON === 'function') {
1062 arr.push(this[val][i].toJSON());
1063 } else {
1064 arr.push(JSON.stringify(this[val][i]));
1065 }
1066 }
1067
1068 json[val] = arr;
1069 } else if (this[val] === null) {
1070 json[val] = this[val];
1071 } else if (typeof this[val] === 'object' && typeof this[val].toJSON === 'function') {
1072 json[val] = this[val].toJSON();
1073 } else if (typeof this[val] === 'boolean' || typeof this[val] === 'number' || typeof this[val] === 'string') {
1074 json[val] = this[val];
1075 } else if (Buffer.isBuffer(this[val])) {
1076 json[val] = this[val].toString('hex');
1077 } else if (this[val] instanceof Map) {
1078 json[val] = JSON.stringify(this[val]);
1079 } else if (typeof this[val] === 'object') {
1080 throw new Error('not implemented');
1081 }
1082 }
1083
1084 return json;
1085 }
1086
1087 asyncToJSON() {
1088 throw new Error('not implemented');
1089 }
1090
1091 clone() {
1092 return this.cloneByJSON();
1093 }
1094
1095 cloneByBuffer() {
1096 return new this.constructor().fromBuffer(this.toBuffer());
1097 }
1098
1099 cloneByFastBuffer() {
1100 return new this.constructor().fromFastBuffer(this.toFastBuffer());
1101 }
1102
1103 cloneByHex() {
1104 return new this.constructor().fromHex(this.toHex());
1105 }
1106
1107 cloneByString() {
1108 return new this.constructor().fromString(this.toString());
1109 }
1110
1111 cloneByJSON() {
1112 return new this.constructor().fromJSON(this.toJSON());
1113 }
1114
1115}
1116
1117class Base58 extends Struct {
1118 constructor(buf) {
1119 super({
1120 buf
1121 });
1122 }
1123
1124 fromHex(hex) {
1125 return this.fromBuffer(Buffer.from(hex, 'hex'));
1126 }
1127
1128 toHex() {
1129 return this.toBuffer().toString('hex');
1130 }
1131
1132 static encode(buf) {
1133 if (!Buffer.isBuffer(buf)) {
1134 throw new Error('Input should be a buffer');
1135 }
1136
1137 return bs58.encode(buf);
1138 }
1139
1140 static decode(str) {
1141 if (typeof str !== 'string') {
1142 throw new Error('Input should be a string');
1143 }
1144
1145 return Buffer.from(bs58.decode(str));
1146 }
1147
1148 fromBuffer(buf) {
1149 this.buf = buf;
1150 return this;
1151 }
1152
1153 fromString(str) {
1154 const buf = Base58.decode(str);
1155 this.buf = buf;
1156 return this;
1157 }
1158
1159 toBuffer() {
1160 return this.buf;
1161 }
1162
1163 toString() {
1164 return Base58.encode(this.buf);
1165 }
1166
1167}
1168
1169const cmp = (buf1, buf2) => {
1170 if (!Buffer.isBuffer(buf1) || !Buffer.isBuffer(buf2)) {
1171 throw new Error('buf1 and buf2 must be buffers');
1172 }
1173
1174 if (buf1.length !== buf2.length) {
1175 return false;
1176 }
1177
1178 let d = 0;
1179
1180 for (let i = 0; i < buf1.length; i++) {
1181 const x = buf1[i];
1182 const y = buf2[i];
1183 d |= x ^ y;
1184 }
1185
1186 return d === 0;
1187};
1188
1189class WorkersResult extends Struct {
1190 constructor(resbuf, isError, id) {
1191 super({
1192 resbuf,
1193 isError,
1194 id
1195 });
1196 }
1197
1198 fromResult(result, id) {
1199 if (result.toFastBuffer) {
1200 this.resbuf = result.toFastBuffer();
1201 } else if (Buffer.isBuffer(result)) {
1202 this.resbuf = result;
1203 } else {
1204 this.resbuf = Buffer.from(JSON.stringify(result));
1205 }
1206
1207 this.isError = false;
1208 this.id = id;
1209 return this;
1210 }
1211
1212 static fromResult(result, id) {
1213 return new this().fromResult(result, id);
1214 }
1215
1216 fromError(error, id) {
1217 this.resbuf = Buffer.from(JSON.stringify(error.message));
1218 this.isError = true;
1219 this.id = id;
1220 return this;
1221 }
1222
1223 toBw(bw) {
1224 if (!bw) {
1225 bw = new Bw();
1226 }
1227
1228 bw.writeVarIntNum(this.resbuf.length);
1229 bw.write(this.resbuf);
1230 bw.writeUInt8(Number(this.isError));
1231 bw.writeVarIntNum(this.id);
1232 return bw;
1233 }
1234
1235 fromBr(br) {
1236 const resbuflen = br.readVarIntNum();
1237 this.resbuf = br.read(resbuflen);
1238 this.isError = Boolean(br.readUInt8());
1239 this.id = br.readVarIntNum();
1240 return this;
1241 }
1242
1243}
1244
1245let globalWorkers;
1246
1247class Workers {
1248 constructor(nativeWorkers = [], lastid = 0, incompconsteRes = [], promisemap = new Map()) {
1249 this.nativeWorkers = nativeWorkers;
1250 this.lastid = lastid;
1251 this.incompconsteRes = incompconsteRes;
1252 this.promisemap = promisemap;
1253 }
1254
1255 asyncObjectMethod(obj, methodname, args, id = this.lastid + 1) {
1256 if (!args) {
1257 throw new Error('must specify args');
1258 }
1259
1260 const result = obj[methodname](...args);
1261 const workersResult = new WorkersResult().fromResult(result, id);
1262 return workersResult;
1263 }
1264
1265 static asyncObjectMethod(obj, methodname, args, id) {
1266 if (!globalWorkers) {
1267 globalWorkers = new Workers();
1268 }
1269
1270 return globalWorkers.asyncObjectMethod(obj, methodname, args, id);
1271 }
1272
1273 asyncClassMethod(classObj, methodname, args, id = this.lastid + 1) {
1274 if (!args) {
1275 throw new Error('must specify args');
1276 }
1277
1278 const result = classObj[methodname](...args);
1279 const workersResult = new WorkersResult().fromResult(result, id);
1280 return workersResult;
1281 }
1282
1283 static asyncClassMethod(classObj, methodname, args, id) {
1284 if (!globalWorkers) {
1285 globalWorkers = new Workers();
1286 }
1287
1288 return globalWorkers.asyncClassMethod(classObj, methodname, args, id);
1289 }
1290
1291 static endGlobalWorkers() {
1292 if (globalWorkers && !process.browser) {
1293 globalWorkers = undefined;
1294 }
1295 }
1296
1297}
1298
1299class Hash {}
1300
1301Hash.sha1 = function (buf) {
1302 if (!Buffer.isBuffer(buf)) {
1303 throw new Error('sha1 hash must be of a buffer');
1304 }
1305
1306 const Sha1 = hashjs.sha1;
1307 const hash = new Sha1().update(buf).digest();
1308 return Buffer.from(hash);
1309};
1310
1311Hash.sha1.blockSize = 512;
1312
1313Hash.asyncSha1 = async function (buf) {
1314 const args = [buf];
1315 const workersResult = await Workers.asyncClassMethod(Hash, 'sha1', args);
1316 return workersResult.resbuf;
1317};
1318
1319Hash.sha256 = function (buf) {
1320 if (!Buffer.isBuffer(buf)) {
1321 throw new Error('sha256 hash must be of a buffer');
1322 }
1323
1324 const Sha256 = hashjs.sha256;
1325 const hash = new Sha256().update(buf).digest();
1326 return Buffer.from(hash);
1327};
1328
1329Hash.sha256.blockSize = 512;
1330
1331Hash.asyncSha256 = async function (buf) {
1332 const args = [buf];
1333 const workersResult = await Workers.asyncClassMethod(Hash, 'sha256', args);
1334 return workersResult.resbuf;
1335};
1336
1337Hash.sha256Sha256 = function (buf) {
1338 try {
1339 return Hash.sha256(Hash.sha256(buf));
1340 } catch (e) {
1341 throw new Error('sha256Sha256 hash must be of a buffer: ' + e);
1342 }
1343};
1344
1345Hash.asyncSha256Sha256 = async function (buf) {
1346 const args = [buf];
1347 const workersResult = await Workers.asyncClassMethod(Hash, 'sha256Sha256', args);
1348 return workersResult.resbuf;
1349};
1350
1351Hash.ripemd160 = function (buf) {
1352 if (!Buffer.isBuffer(buf)) {
1353 throw new Error('ripemd160 hash must be of a buffer');
1354 }
1355
1356 const Ripemd160 = hashjs.ripemd160;
1357 const hash = new Ripemd160().update(buf).digest();
1358 return Buffer.from(hash);
1359};
1360
1361Hash.asyncRipemd160 = async function (buf) {
1362 const args = [buf];
1363 const workersResult = await Workers.asyncClassMethod(Hash, 'ripemd160', args);
1364 return workersResult.resbuf;
1365};
1366
1367Hash.sha256Ripemd160 = function (buf) {
1368 try {
1369 return Hash.ripemd160(Hash.sha256(buf));
1370 } catch (e) {
1371 throw new Error('sha256Ripemd160 hash must be of a buffer: ' + e);
1372 }
1373};
1374
1375Hash.asyncSha256Ripemd160 = async function (buf) {
1376 const args = [buf];
1377 const workersResult = await Workers.asyncClassMethod(Hash, 'sha256Ripemd160', args);
1378 return workersResult.resbuf;
1379};
1380
1381Hash.sha512 = function (buf) {
1382 if (!Buffer.isBuffer(buf)) {
1383 throw new Error('sha512 hash must be of a buffer');
1384 }
1385
1386 const Sha512 = hashjs.sha512;
1387 const hash = new Sha512().update(buf).digest();
1388 return Buffer.from(hash);
1389};
1390
1391Hash.asyncSha512 = async function (buf) {
1392 const args = [buf];
1393 const workersResult = await Workers.asyncClassMethod(Hash, 'sha512', args);
1394 return workersResult.resbuf;
1395};
1396
1397Hash.sha512.blockSize = 1024;
1398
1399Hash.hmac = function (hashFStr, data, key) {
1400 if (hashFStr !== 'sha1' && hashFStr !== 'sha256' && hashFStr !== 'sha512') {
1401 throw new Error('invalid choice of hash function');
1402 }
1403
1404 const hashf = Hash[hashFStr];
1405
1406 if (!Buffer.isBuffer(data) || !Buffer.isBuffer(key)) {
1407 throw new Error('data and key must be buffers');
1408 }
1409
1410 const blockSize = hashf.blockSize / 8;
1411
1412 if (key.length > blockSize) {
1413 key = hashf(key);
1414 }
1415
1416 if (key.length < blockSize) {
1417 const fill = Buffer.alloc(blockSize);
1418 fill.fill(0, key.length);
1419 key.copy(fill);
1420 key = fill;
1421 }
1422
1423 const oKeyPad = Buffer.alloc(blockSize);
1424 const iKeyPad = Buffer.alloc(blockSize);
1425
1426 for (let i = 0; i < blockSize; i++) {
1427 oKeyPad[i] = 0x5c ^ key[i];
1428 iKeyPad[i] = 0x36 ^ key[i];
1429 }
1430
1431 return hashf(Buffer.concat([oKeyPad, hashf(Buffer.concat([iKeyPad, data]))]));
1432};
1433
1434Hash.sha1Hmac = function (data, key) {
1435 return Hash.hmac('sha1', data, key);
1436};
1437
1438Hash.asyncSha1Hmac = async function (data, key) {
1439 const args = [data, key];
1440 const workersResult = await Workers.asyncClassMethod(Hash, 'sha1Hmac', args);
1441 return workersResult.resbuf;
1442};
1443
1444Hash.sha1Hmac.bitsize = 160;
1445
1446Hash.sha256Hmac = function (data, key) {
1447 return Hash.hmac('sha256', data, key);
1448};
1449
1450Hash.asyncSha256Hmac = async function (data, key) {
1451 const args = [data, key];
1452 const workersResult = await Workers.asyncClassMethod(Hash, 'sha256Hmac', args);
1453 return workersResult.resbuf;
1454};
1455
1456Hash.sha256Hmac.bitsize = 256;
1457
1458Hash.sha512Hmac = function (data, key) {
1459 return Hash.hmac('sha512', data, key);
1460};
1461
1462Hash.asyncSha512Hmac = async function (data, key) {
1463 const args = [data, key];
1464 const workersResult = await Workers.asyncClassMethod(Hash, 'sha512Hmac', args);
1465 return workersResult.resbuf;
1466};
1467
1468Hash.sha512Hmac.bitsize = 512;
1469
1470class Base58Check extends Struct {
1471 constructor(buf) {
1472 super({
1473 buf
1474 });
1475 }
1476
1477 fromHex(hex) {
1478 return this.fromBuffer(Buffer.from(hex, 'hex'));
1479 }
1480
1481 toHex() {
1482 return this.toBuffer().toString('hex');
1483 }
1484
1485 static decode(s) {
1486 if (typeof s !== 'string') {
1487 throw new Error('Input must be a string');
1488 }
1489
1490 const buf = Base58.decode(s);
1491
1492 if (buf.length < 4) {
1493 throw new Error('Input string too short');
1494 }
1495
1496 const data = buf.slice(0, -4);
1497 const csum = buf.slice(-4);
1498 const hash = Hash.sha256Sha256(data);
1499 const hash4 = hash.slice(0, 4);
1500
1501 if (!cmp(csum, hash4)) {
1502 throw new Error('Checksum mismatch');
1503 }
1504
1505 return data;
1506 }
1507
1508 static encode(buf) {
1509 if (!Buffer.isBuffer(buf)) {
1510 throw new Error('Input must be a buffer');
1511 }
1512
1513 const checkedBuf = Buffer.alloc(buf.length + 4);
1514 const hash = Hash.sha256Sha256(buf);
1515 buf.copy(checkedBuf);
1516 hash.copy(checkedBuf, buf.length);
1517 return Base58.encode(checkedBuf);
1518 }
1519
1520 fromBuffer(buf) {
1521 this.buf = buf;
1522 return this;
1523 }
1524
1525 fromString(str) {
1526 const buf = Base58Check.decode(str);
1527 this.buf = buf;
1528 return this;
1529 }
1530
1531 toBuffer() {
1532 return this.buf;
1533 }
1534
1535 toString() {
1536 return Base58Check.encode(this.buf);
1537 }
1538
1539}
1540
1541class Config {
1542 constructor(values) {
1543 this.keyDefined = key => key in values;
1544
1545 this.getValue = key => values[key];
1546 }
1547
1548 get(key) {
1549 if (this.keyDefined(key)) {
1550 return this.getValue(key);
1551 } else {
1552 throw new Error(`Unknown configuration: ${key}`);
1553 }
1554 }
1555
1556}
1557
1558class ConfigBuilder {
1559 constructor() {
1560 this.variables = {};
1561 }
1562
1563 build() {
1564 return new Config(this.variables);
1565 }
1566
1567 addValue(key, value) {
1568 if (value === undefined) {
1569 throw new Error(`Failed to add "${key}" property. The value cannot be undefined`);
1570 }
1571
1572 if (key in this.variables) {
1573 throw new Error(`"${key}" already has a value defined.`);
1574 }
1575
1576 this.variables[key] = value;
1577 return this;
1578 }
1579
1580 addValueWithDefault(key, value, defaultValue) {
1581 if (defaultValue === undefined) {
1582 throw new Error(`Failed to add "${key}" property. Default value cannot be undefined`);
1583 }
1584
1585 return this.addValue(key, value === undefined ? defaultValue : value);
1586 }
1587
1588}
1589
1590const config = new ConfigBuilder().addValue('NETWORK', process.env.NETWORK || 'mainnet').build();
1591
1592const Constants = {};
1593Constants.Mainnet = {
1594 maxsize: 0x02000000,
1595 Address: {
1596 pubKeyHash: 0x00
1597 },
1598 Bip32: {
1599 pubKey: 0x0488b21e,
1600 privKey: 0x0488ade4
1601 },
1602 Block: {
1603 maxNBits: 0x1d00ffff,
1604 magicNum: 0xf9beb4d9
1605 },
1606 Msg: {
1607 magicNum: 0xf9beb4d9,
1608 versionBytesNum: 70012
1609 },
1610 PrivKey: {
1611 versionByteNum: 0x80
1612 },
1613 TxBuilder: {
1614 dust: 546,
1615 feePerKbNum: 0.00000500e8
1616 },
1617 Workers: {
1618 timeout: 60000
1619 }
1620};
1621Constants.Testnet = Object.assign({}, Constants.Mainnet, {
1622 Address: {
1623 pubKeyHash: 0x6f
1624 },
1625 Bip32: {
1626 pubKey: 0x043587cf,
1627 privKey: 0x04358394
1628 },
1629 Block: {
1630 maxNBits: 0x1d00ffff,
1631 magicNum: 0x0b110907
1632 },
1633 Msg: {
1634 magicNum: 0x0b110907,
1635 versionBytesNum: 70012
1636 },
1637 PrivKey: {
1638 versionByteNum: 0xef
1639 }
1640});
1641Constants.Regtest = Object.assign({}, Constants.Mainnet, {
1642 Address: {
1643 pubKeyHash: 0x6f
1644 },
1645 Bip32: {
1646 pubKey: 0x043587cf,
1647 privKey: 0x04358394
1648 },
1649 Block: {
1650 maxNBits: 0x1d00ffff,
1651 magicNum: 0xdab5bffa
1652 },
1653 Msg: {
1654 magicNum: 0x0b110907,
1655 versionBytesNum: 70012
1656 },
1657 PrivKey: {
1658 versionByteNum: 0xef
1659 }
1660});
1661
1662if (config.get('NETWORK') === 'testnet') {
1663 Constants.Default = Object.assign({}, Constants.Testnet);
1664} else if (config.get('NETWORK') === 'mainnet') {
1665 Constants.Default = Object.assign({}, Constants.Mainnet);
1666} else if (config.get('NETWORK') === 'regtest') {
1667 Constants.Default = Object.assign({}, Constants.Regtest);
1668} else {
1669 throw new Error(`must set network in environment variable - mainnet, testnet or regtest?, received ${config.get('NETWORK')}`);
1670}
1671
1672const map = {
1673 OP_FALSE: 0x00,
1674 OP_0: 0x00,
1675 OP_PUSHDATA1: 0x4c,
1676 OP_PUSHDATA2: 0x4d,
1677 OP_PUSHDATA4: 0x4e,
1678 OP_1NEGATE: 0x4f,
1679 OP_RESERVED: 0x50,
1680 OP_TRUE: 0x51,
1681 OP_1: 0x51,
1682 OP_2: 0x52,
1683 OP_3: 0x53,
1684 OP_4: 0x54,
1685 OP_5: 0x55,
1686 OP_6: 0x56,
1687 OP_7: 0x57,
1688 OP_8: 0x58,
1689 OP_9: 0x59,
1690 OP_10: 0x5a,
1691 OP_11: 0x5b,
1692 OP_12: 0x5c,
1693 OP_13: 0x5d,
1694 OP_14: 0x5e,
1695 OP_15: 0x5f,
1696 OP_16: 0x60,
1697 OP_NOP: 0x61,
1698 OP_VER: 0x62,
1699 OP_IF: 0x63,
1700 OP_NOTIF: 0x64,
1701 OP_VERIF: 0x65,
1702 OP_VERNOTIF: 0x66,
1703 OP_ELSE: 0x67,
1704 OP_ENDIF: 0x68,
1705 OP_VERIFY: 0x69,
1706 OP_RETURN: 0x6a,
1707 OP_TOALTSTACK: 0x6b,
1708 OP_FROMALTSTACK: 0x6c,
1709 OP_2DROP: 0x6d,
1710 OP_2DUP: 0x6e,
1711 OP_3DUP: 0x6f,
1712 OP_2OVER: 0x70,
1713 OP_2ROT: 0x71,
1714 OP_2SWAP: 0x72,
1715 OP_IFDUP: 0x73,
1716 OP_DEPTH: 0x74,
1717 OP_DROP: 0x75,
1718 OP_DUP: 0x76,
1719 OP_NIP: 0x77,
1720 OP_OVER: 0x78,
1721 OP_PICK: 0x79,
1722 OP_ROLL: 0x7a,
1723 OP_ROT: 0x7b,
1724 OP_SWAP: 0x7c,
1725 OP_TUCK: 0x7d,
1726 OP_CAT: 0x7e,
1727 OP_SUBSTR: 0x7f,
1728 OP_SPLIT: 0x7f,
1729 OP_LEFT: 0x80,
1730 OP_NUM2BIN: 0x80,
1731 OP_RIGHT: 0x81,
1732 OP_BIN2NUM: 0x81,
1733 OP_SIZE: 0x82,
1734 OP_INVERT: 0x83,
1735 OP_AND: 0x84,
1736 OP_OR: 0x85,
1737 OP_XOR: 0x86,
1738 OP_EQUAL: 0x87,
1739 OP_EQUALVERIFY: 0x88,
1740 OP_RESERVED1: 0x89,
1741 OP_RESERVED2: 0x8a,
1742 OP_1ADD: 0x8b,
1743 OP_1SUB: 0x8c,
1744 OP_2MUL: 0x8d,
1745 OP_2DIV: 0x8e,
1746 OP_NEGATE: 0x8f,
1747 OP_ABS: 0x90,
1748 OP_NOT: 0x91,
1749 OP_0NOTEQUAL: 0x92,
1750 OP_ADD: 0x93,
1751 OP_SUB: 0x94,
1752 OP_MUL: 0x95,
1753 OP_DIV: 0x96,
1754 OP_MOD: 0x97,
1755 OP_LSHIFT: 0x98,
1756 OP_RSHIFT: 0x99,
1757 OP_BOOLAND: 0x9a,
1758 OP_BOOLOR: 0x9b,
1759 OP_NUMEQUAL: 0x9c,
1760 OP_NUMEQUALVERIFY: 0x9d,
1761 OP_NUMNOTEQUAL: 0x9e,
1762 OP_LESSTHAN: 0x9f,
1763 OP_GREATERTHAN: 0xa0,
1764 OP_LESSTHANOREQUAL: 0xa1,
1765 OP_GREATERTHANOREQUAL: 0xa2,
1766 OP_MIN: 0xa3,
1767 OP_MAX: 0xa4,
1768 OP_WITHIN: 0xa5,
1769 OP_RIPEMD160: 0xa6,
1770 OP_SHA1: 0xa7,
1771 OP_SHA256: 0xa8,
1772 OP_HASH160: 0xa9,
1773 OP_HASH256: 0xaa,
1774 OP_CODESEPARATOR: 0xab,
1775 OP_CHECKSIG: 0xac,
1776 OP_CHECKSIGVERIFY: 0xad,
1777 OP_CHECKMULTISIG: 0xae,
1778 OP_CHECKMULTISIGVERIFY: 0xaf,
1779 OP_NOP1: 0xb0,
1780 OP_NOP2: 0xb1,
1781 OP_CHECKLOCKTIMEVERIFY: 0xb1,
1782 OP_NOP3: 0xb2,
1783 OP_CHECKSEQUENCEVERIFY: 0xb2,
1784 OP_NOP4: 0xb3,
1785 OP_NOP5: 0xb4,
1786 OP_NOP6: 0xb5,
1787 OP_NOP7: 0xb6,
1788 OP_NOP8: 0xb7,
1789 OP_NOP9: 0xb8,
1790 OP_NOP10: 0xb9,
1791 OP_SMALLDATA: 0xf9,
1792 OP_SMALLINTEGER: 0xfa,
1793 OP_PUBKEYS: 0xfb,
1794 OP_PUBKEYHASH: 0xfd,
1795 OP_PUBKEY: 0xfe,
1796 OP_INVALIDOPCODE: 0xff
1797};
1798
1799class OpCode extends Struct {
1800 constructor(num) {
1801 super({
1802 num
1803 });
1804 }
1805
1806 fromNumber(num) {
1807 this.num = num;
1808 return this;
1809 }
1810
1811 static fromNumber(num) {
1812 return new this().fromNumber(num);
1813 }
1814
1815 toNumber() {
1816 return this.num;
1817 }
1818
1819 fromString(str) {
1820 const num = map[str];
1821
1822 if (num === undefined) {
1823 throw new Error('Invalid opCodeStr');
1824 }
1825
1826 this.num = num;
1827 return this;
1828 }
1829
1830 static fromString(str) {
1831 return new this().fromString(str);
1832 }
1833
1834 toString() {
1835 const str = OpCode.str[this.num];
1836
1837 if (str === undefined) {
1838 if (this.num > 0 && this.num < OpCode.OP_PUSHDATA1) {
1839 return this.num.toString();
1840 }
1841
1842 throw new Error('OpCode does not have a string representation');
1843 }
1844
1845 return str;
1846 }
1847
1848}
1849
1850OpCode.str = {};
1851
1852for (const opCodeStr in map) {
1853 OpCode[opCodeStr] = map[opCodeStr];
1854
1855 if (Object.prototype.hasOwnProperty.call(map, opCodeStr)) {
1856 OpCode.str[map[opCodeStr]] = opCodeStr;
1857 }
1858}
1859
1860const ec = elliptic.curves.secp256k1;
1861
1862const _point = ec.curve.point();
1863
1864const _Point = _point.constructor;
1865
1866class Point extends _Point {
1867 constructor(x, y, isRed) {
1868 super(ec.curve, x, y, isRed);
1869 }
1870
1871 static fromX(isOdd, x) {
1872 const _point = ec.curve.pointFromX(x, isOdd);
1873
1874 const point = Object.create(Point.prototype);
1875 return point.copyFrom(_point);
1876 }
1877
1878 copyFrom(point) {
1879 if (!(point instanceof _Point)) {
1880 throw new Error('point should be an external point');
1881 }
1882
1883 Object.keys(point).forEach(function (key) {
1884 this[key] = point[key];
1885 }.bind(this));
1886 return this;
1887 }
1888
1889 add(p) {
1890 p = _Point.prototype.add.call(this, p);
1891 const point = Object.create(Point.prototype);
1892 return point.copyFrom(p);
1893 }
1894
1895 mul(bn) {
1896 if (!bn.lt(Point.getN())) {
1897 throw new Error('point mul out of range');
1898 }
1899
1900 const p = _Point.prototype.mul.call(this, bn);
1901
1902 const point = Object.create(Point.prototype);
1903 return point.copyFrom(p);
1904 }
1905
1906 mulAdd(bn1, point, bn2) {
1907 const p = _Point.prototype.mulAdd.call(this, bn1, point, bn2);
1908
1909 point = Object.create(Point.prototype);
1910 return point.copyFrom(p);
1911 }
1912
1913 getX() {
1914 const _x = _Point.prototype.getX.call(this);
1915
1916 const x = Object.create(Bn.prototype);
1917
1918 _x.copy(x);
1919
1920 return x;
1921 }
1922
1923 getY() {
1924 const _y = _Point.prototype.getY.call(this);
1925
1926 const y = Object.create(Bn.prototype);
1927
1928 _y.copy(y);
1929
1930 return y;
1931 }
1932
1933 fromX(isOdd, x) {
1934 const point = Point.fromX(isOdd, x);
1935 return this.copyFrom(point);
1936 }
1937
1938 toJSON() {
1939 return {
1940 x: this.getX().toString(),
1941 y: this.getY().toString()
1942 };
1943 }
1944
1945 fromJSON(json) {
1946 const x = new Bn().fromString(json.x);
1947 const y = new Bn().fromString(json.y);
1948 const point = new Point(x, y);
1949 return this.copyFrom(point);
1950 }
1951
1952 toString() {
1953 return JSON.stringify(this.toJSON());
1954 }
1955
1956 fromString(str) {
1957 const json = JSON.parse(str);
1958 const p = new Point().fromJSON(json);
1959 return this.copyFrom(p);
1960 }
1961
1962 static getG() {
1963 const _g = ec.curve.g;
1964 const g = Object.create(Point.prototype);
1965 return g.copyFrom(_g);
1966 }
1967
1968 static getN() {
1969 return new Bn(ec.curve.n.toArray());
1970 }
1971
1972 validate() {
1973 const p2 = Point.fromX(this.getY().isOdd(), this.getX());
1974
1975 if (!(p2.getY().cmp(this.getY()) === 0)) {
1976 throw new Error('Invalid y value of public key');
1977 }
1978
1979 if (!(this.getX().gt(-1) && this.getX().lt(Point.getN())) || !(this.getY().gt(-1) && this.getY().lt(Point.getN()))) {
1980 throw new Error('Point does not lie on the curve');
1981 }
1982
1983 return this;
1984 }
1985
1986}
1987
1988class PubKey extends Struct {
1989 constructor(point, compressed) {
1990 super({
1991 point,
1992 compressed
1993 });
1994 }
1995
1996 fromJSON(json) {
1997 this.fromFastHex(json);
1998 return this;
1999 }
2000
2001 toJSON() {
2002 return this.toFastHex();
2003 }
2004
2005 fromPrivKey(privKey) {
2006 this.fromObject({
2007 point: Point.getG().mul(privKey.bn),
2008 compressed: privKey.compressed
2009 });
2010 return this;
2011 }
2012
2013 static fromPrivKey(privKey) {
2014 return new this().fromPrivKey(privKey);
2015 }
2016
2017 async asyncFromPrivKey(privKey) {
2018 const workersResult = await Workers.asyncObjectMethod(this, 'fromPrivKey', [privKey]);
2019 return this.fromFastBuffer(workersResult.resbuf);
2020 }
2021
2022 static asyncFromPrivKey(privKey) {
2023 return new this().asyncFromPrivKey(privKey);
2024 }
2025
2026 fromBuffer(buf, strict) {
2027 return this.fromDer(buf, strict);
2028 }
2029
2030 async asyncFromBuffer(buf, strict) {
2031 const args = [buf, strict];
2032 const workersResult = await Workers.asyncObjectMethod(this, 'fromBuffer', args);
2033 return this.fromFastBuffer(workersResult.resbuf);
2034 }
2035
2036 fromFastBuffer(buf) {
2037 if (buf.length === 0) {
2038 return this;
2039 }
2040
2041 const compressed = Boolean(buf[0]);
2042 buf = buf.slice(1);
2043 this.fromDer(buf);
2044 this.compressed = compressed;
2045 return this;
2046 }
2047
2048 fromDer(buf, strict) {
2049 if (strict === undefined) {
2050 strict = true;
2051 } else {
2052 strict = false;
2053 }
2054
2055 if (buf[0] === 0x04 || !strict && (buf[0] === 0x06 || buf[0] === 0x07)) {
2056 const xbuf = buf.slice(1, 33);
2057 const ybuf = buf.slice(33, 65);
2058
2059 if (xbuf.length !== 32 || ybuf.length !== 32 || buf.length !== 65) {
2060 throw new Error('LEngth of x and y must be 32 bytes');
2061 }
2062
2063 const x = new Bn(xbuf);
2064 const y = new Bn(ybuf);
2065 this.point = new Point(x, y);
2066 this.compressed = false;
2067 } else if (buf[0] === 0x03) {
2068 const xbuf = buf.slice(1);
2069 const x = new Bn(xbuf);
2070 this.fromX(true, x);
2071 this.compressed = true;
2072 } else if (buf[0] === 0x02) {
2073 const xbuf = buf.slice(1);
2074 const x = new Bn(xbuf);
2075 this.fromX(false, x);
2076 this.compressed = true;
2077 } else {
2078 throw new Error('Invalid DER format pubKey');
2079 }
2080
2081 return this;
2082 }
2083
2084 static fromDer(buf, strict) {
2085 return new this().fromDer(buf, strict);
2086 }
2087
2088 fromString(str) {
2089 this.fromDer(Buffer.from(str, 'hex'));
2090 return this;
2091 }
2092
2093 fromX(odd, x) {
2094 if (typeof odd !== 'boolean') {
2095 throw new Error('Must specify whether y is odd or not (true or false)');
2096 }
2097
2098 this.point = Point.fromX(odd, x);
2099 return this;
2100 }
2101
2102 static fromX(odd, x) {
2103 return new this().fromX(odd, x);
2104 }
2105
2106 toBuffer() {
2107 const compressed = this.compressed === undefined ? true : this.compressed;
2108 return this.toDer(compressed);
2109 }
2110
2111 toFastBuffer() {
2112 if (!this.point) {
2113 return Buffer.alloc(0);
2114 }
2115
2116 const bw = new Bw();
2117 const compressed = this.compressed === undefined ? true : Boolean(this.compressed);
2118 bw.writeUInt8(Number(compressed));
2119 bw.write(this.toDer(false));
2120 return bw.toBuffer();
2121 }
2122
2123 toDer(compressed) {
2124 compressed = compressed === undefined ? this.compressed : compressed;
2125
2126 if (typeof compressed !== 'boolean') {
2127 throw new Error('Must specify whether the public key is compressed or not (true or false)');
2128 }
2129
2130 const x = this.point.getX();
2131 const y = this.point.getY();
2132 const xbuf = x.toBuffer({
2133 size: 32
2134 });
2135 const ybuf = y.toBuffer({
2136 size: 32
2137 });
2138 let prefix;
2139
2140 if (!compressed) {
2141 prefix = Buffer.from([0x04]);
2142 return Buffer.concat([prefix, xbuf, ybuf]);
2143 } else {
2144 const odd = ybuf[ybuf.length - 1] % 2;
2145
2146 if (odd) {
2147 prefix = Buffer.from([0x03]);
2148 } else {
2149 prefix = Buffer.from([0x02]);
2150 }
2151
2152 return Buffer.concat([prefix, xbuf]);
2153 }
2154 }
2155
2156 toString() {
2157 const compressed = this.compressed === undefined ? true : this.compressed;
2158 return this.toDer(compressed).toString('hex');
2159 }
2160
2161 static isCompressedOrUncompressed(buf) {
2162 if (buf.length < 33) {
2163 return false;
2164 }
2165
2166 if (buf[0] === 0x04) {
2167 if (buf.length !== 65) {
2168 return false;
2169 }
2170 } else if (buf[0] === 0x02 || buf[0] === 0x03) {
2171 if (buf.length !== 33) {
2172 return false;
2173 }
2174 } else {
2175 return false;
2176 }
2177
2178 return true;
2179 }
2180
2181 validate() {
2182 if (this.point.isInfinity()) {
2183 throw new Error('point: Point cannot be equal to Infinity');
2184 }
2185
2186 if (this.point.eq(new Point(new Bn(0), new Bn(0)))) {
2187 throw new Error('point: Point cannot be equal to 0, 0');
2188 }
2189
2190 this.point.validate();
2191 return this;
2192 }
2193
2194}
2195
2196class Random {}
2197
2198Random.getRandomBuffer = function (size) {
2199 return randomBytes(size);
2200};
2201
2202class PrivKey extends Struct {
2203 constructor(bn, compressed, constants = null) {
2204 super({
2205 bn,
2206 compressed
2207 });
2208 constants = constants || Constants.Default.PrivKey;
2209 this.Constants = constants;
2210 }
2211
2212 fromJSON(json) {
2213 this.fromHex(json);
2214 return this;
2215 }
2216
2217 toJSON() {
2218 return this.toHex();
2219 }
2220
2221 fromRandom() {
2222 let privBuf, bn, condition;
2223
2224 do {
2225 privBuf = Random.getRandomBuffer(32);
2226 bn = new Bn().fromBuffer(privBuf);
2227 condition = bn.lt(Point.getN());
2228 } while (!condition);
2229
2230 this.fromObject({
2231 bn: bn,
2232 compressed: true
2233 });
2234 return this;
2235 }
2236
2237 static fromRandom() {
2238 return new this().fromRandom();
2239 }
2240
2241 toBuffer() {
2242 let compressed = this.compressed;
2243
2244 if (compressed === undefined) {
2245 compressed = true;
2246 }
2247
2248 const privBuf = this.bn.toBuffer({
2249 size: 32
2250 });
2251 let buf;
2252
2253 if (compressed) {
2254 buf = Buffer.concat([Buffer.from([this.Constants.versionByteNum]), privBuf, Buffer.from([0x01])]);
2255 } else {
2256 buf = Buffer.concat([Buffer.from([this.Constants.versionByteNum]), privBuf]);
2257 }
2258
2259 return buf;
2260 }
2261
2262 fromBuffer(buf) {
2263 if (buf.length === 1 + 32 + 1 && buf[1 + 32 + 1 - 1] === 1) {
2264 this.compressed = true;
2265 } else if (buf.length === 1 + 32) {
2266 this.compressed = false;
2267 } else {
2268 throw new Error('Length of privKey buffer must be 33 (uncompressed pubKey) or 34 (compressed pubKey)');
2269 }
2270
2271 if (buf[0] !== this.Constants.versionByteNum) {
2272 throw new Error('Invalid versionByteNum byte');
2273 }
2274
2275 return this.fromBn(new Bn().fromBuffer(buf.slice(1, 1 + 32)));
2276 }
2277
2278 toBn() {
2279 return this.bn;
2280 }
2281
2282 fromBn(bn) {
2283 this.bn = bn;
2284 return this;
2285 }
2286
2287 static fromBn(bn) {
2288 return new this().fromBn(bn);
2289 }
2290
2291 validate() {
2292 if (!this.bn.lt(Point.getN())) {
2293 throw new Error('Number must be less than N');
2294 }
2295
2296 if (typeof this.compressed !== 'boolean') {
2297 throw new Error('Must specify whether the corresponding public key is compressed or not (true or false)');
2298 }
2299
2300 return this;
2301 }
2302
2303 toWif() {
2304 return Base58Check.encode(this.toBuffer());
2305 }
2306
2307 fromWif(str) {
2308 return this.fromBuffer(Base58Check.decode(str));
2309 }
2310
2311 static fromWif(str) {
2312 return new this().fromWif(str);
2313 }
2314
2315 toString() {
2316 return this.toWif();
2317 }
2318
2319 fromString(str) {
2320 return this.fromWif(str);
2321 }
2322
2323}
2324
2325PrivKey.Mainnet = class extends PrivKey {
2326 constructor(bn, compressed) {
2327 super(bn, compressed, Constants.Mainnet.PrivKey);
2328 }
2329
2330};
2331PrivKey.Testnet = class extends PrivKey {
2332 constructor(bn, compressed) {
2333 super(bn, compressed, Constants.Testnet.PrivKey);
2334 }
2335
2336};
2337
2338class Sig extends Struct {
2339 constructor(r, s, nHashType, recovery, compressed) {
2340 super({
2341 r,
2342 s,
2343 nHashType,
2344 recovery,
2345 compressed
2346 });
2347 }
2348
2349 fromBuffer(buf) {
2350 try {
2351 return this.fromDer(buf, true);
2352 } catch (e) {}
2353
2354 try {
2355 return this.fromCompact(buf);
2356 } catch (e) {}
2357
2358 return this.fromTxFormat(buf);
2359 }
2360
2361 toBuffer() {
2362 if (this.nHashType !== undefined) {
2363 return this.toTxFormat();
2364 } else if (this.recovery !== undefined) {
2365 return this.toCompact();
2366 }
2367
2368 return this.toDer();
2369 }
2370
2371 fromCompact(buf) {
2372 let compressed = true;
2373 let recovery = buf.slice(0, 1)[0] - 27 - 4;
2374
2375 if (recovery < 0) {
2376 compressed = false;
2377 recovery = recovery + 4;
2378 }
2379
2380 if (!(recovery === 0 || recovery === 1 || recovery === 2 || recovery === 3)) {
2381 throw new Error('i must be 0, 1, 2, or 3');
2382 }
2383
2384 this.compressed = compressed;
2385 this.recovery = recovery;
2386 const rsbuf = buf.slice(1);
2387 this.fromRS(rsbuf);
2388 return this;
2389 }
2390
2391 static fromCompact(buf) {
2392 return new this().fromCompact(buf);
2393 }
2394
2395 fromRS(rsbuf) {
2396 const b2 = rsbuf.slice(0, 32);
2397 const b3 = rsbuf.slice(32, 64);
2398
2399 if (b2.length !== 32) {
2400 throw new Error('r must be 32 bytes');
2401 }
2402
2403 if (b3.length !== 32 || rsbuf.length > 64) {
2404 throw new Error('s must be 32 bytes');
2405 }
2406
2407 this.r = new Bn().fromBuffer(b2);
2408 this.s = new Bn().fromBuffer(b3);
2409 return this;
2410 }
2411
2412 static fromRS(rsbuf) {
2413 return new this().fromRS(rsbuf);
2414 }
2415
2416 fromDer(buf, strict) {
2417 const obj = Sig.parseDer(buf, strict);
2418 this.r = obj.r;
2419 this.s = obj.s;
2420 return this;
2421 }
2422
2423 static fromDer(buf, strict) {
2424 return new this().fromDer(buf, strict);
2425 }
2426
2427 fromTxFormat(buf) {
2428 if (buf.length === 0) {
2429 this.r = new Bn(1);
2430 this.s = new Bn(1);
2431 this.nHashType = 1;
2432 return this;
2433 }
2434
2435 const nHashType = buf.readUInt8(buf.length - 1);
2436 const derbuf = buf.slice(0, buf.length - 1);
2437 this.fromDer(derbuf, false);
2438 this.nHashType = nHashType;
2439 return this;
2440 }
2441
2442 static fromTxFormat(buf) {
2443 return new this().fromTxFormat(buf);
2444 }
2445
2446 fromString(str) {
2447 return this.fromHex(str);
2448 }
2449
2450 static parseDer(buf, strict) {
2451 if (strict === undefined) {
2452 strict = true;
2453 }
2454
2455 if (!Buffer.isBuffer(buf)) {
2456 throw new Error('DER formatted signature should be a buffer');
2457 }
2458
2459 const header = buf[0];
2460
2461 if (header !== 0x30) {
2462 throw new Error('Header byte should be 0x30');
2463 }
2464
2465 let length = buf[1];
2466 const buflength = buf.slice(2).length;
2467
2468 if (strict && length !== buflength) {
2469 throw new Error('LEngth byte should length of what follows');
2470 } else {
2471 length = length < buflength ? length : buflength;
2472 }
2473
2474 const rheader = buf[2 + 0];
2475
2476 if (rheader !== 0x02) {
2477 throw new Error('Integer byte for r should be 0x02');
2478 }
2479
2480 const rlength = buf[2 + 1];
2481 const rbuf = buf.slice(2 + 2, 2 + 2 + rlength);
2482 const r = new Bn().fromBuffer(rbuf);
2483 const rneg = buf[2 + 1 + 1] === 0x00;
2484
2485 if (rlength !== rbuf.length) {
2486 throw new Error('LEngth of r incorrect');
2487 }
2488
2489 const sheader = buf[2 + 2 + rlength + 0];
2490
2491 if (sheader !== 0x02) {
2492 throw new Error('Integer byte for s should be 0x02');
2493 }
2494
2495 const slength = buf[2 + 2 + rlength + 1];
2496 const sbuf = buf.slice(2 + 2 + rlength + 2, 2 + 2 + rlength + 2 + slength);
2497 const s = new Bn().fromBuffer(sbuf);
2498 const sneg = buf[2 + 2 + rlength + 2 + 2] === 0x00;
2499
2500 if (slength !== sbuf.length) {
2501 throw new Error('LEngth of s incorrect');
2502 }
2503
2504 const sumlength = 2 + 2 + rlength + 2 + slength;
2505
2506 if (length !== sumlength - 2) {
2507 throw new Error('LEngth of signature incorrect');
2508 }
2509
2510 const obj = {
2511 header: header,
2512 length: length,
2513 rheader: rheader,
2514 rlength: rlength,
2515 rneg: rneg,
2516 rbuf: rbuf,
2517 r: r,
2518 sheader: sheader,
2519 slength: slength,
2520 sneg: sneg,
2521 sbuf: sbuf,
2522 s: s
2523 };
2524 return obj;
2525 }
2526
2527 static IsTxDer(buf) {
2528 if (buf.length < 9) {
2529 return false;
2530 }
2531
2532 if (buf.length > 73) {
2533 return false;
2534 }
2535
2536 if (buf[0] !== 0x30) {
2537 return false;
2538 }
2539
2540 if (buf[1] !== buf.length - 3) {
2541 return false;
2542 }
2543
2544 const nLEnR = buf[3];
2545
2546 if (5 + nLEnR >= buf.length) {
2547 return false;
2548 }
2549
2550 const nLEnS = buf[5 + nLEnR];
2551
2552 if (nLEnR + nLEnS + 7 !== buf.length) {
2553 return false;
2554 }
2555
2556 const R = buf.slice(4);
2557
2558 if (buf[4 - 2] !== 0x02) {
2559 return false;
2560 }
2561
2562 if (nLEnR === 0) {
2563 return false;
2564 }
2565
2566 if (R[0] & 0x80) {
2567 return false;
2568 }
2569
2570 if (nLEnR > 1 && R[0] === 0x00 && !(R[1] & 0x80)) {
2571 return false;
2572 }
2573
2574 const S = buf.slice(6 + nLEnR);
2575
2576 if (buf[6 + nLEnR - 2] !== 0x02) {
2577 return false;
2578 }
2579
2580 if (nLEnS === 0) {
2581 return false;
2582 }
2583
2584 if (S[0] & 0x80) {
2585 return false;
2586 }
2587
2588 if (nLEnS > 1 && S[0] === 0x00 && !(S[1] & 0x80)) {
2589 return false;
2590 }
2591
2592 return true;
2593 }
2594
2595 hasLowS() {
2596 if (this.s.lt(1) || this.s.gt(Bn.fromBuffer(Buffer.from('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0', 'hex')))) {
2597 return false;
2598 }
2599
2600 return true;
2601 }
2602
2603 hasDefinedHashType() {
2604 if (this.nHashType < Sig.SIGHASH_ALL || this.nHashType > Sig.SIGHASH_SINGLE) {
2605 return false;
2606 }
2607
2608 return true;
2609 }
2610
2611 toCompact(recovery, compressed) {
2612 recovery = typeof recovery === 'number' ? recovery : this.recovery;
2613 compressed = typeof compressed === 'boolean' ? compressed : this.compressed;
2614
2615 if (!(recovery === 0 || recovery === 1 || recovery === 2 || recovery === 3)) {
2616 throw new Error('recovery must be equal to 0, 1, 2, or 3');
2617 }
2618
2619 let val = recovery + 27 + 4;
2620
2621 if (compressed === false) {
2622 val = val - 4;
2623 }
2624
2625 const b1 = Buffer.from([val]);
2626 const b2 = this.r.toBuffer({
2627 size: 32
2628 });
2629 const b3 = this.s.toBuffer({
2630 size: 32
2631 });
2632 return Buffer.concat([b1, b2, b3]);
2633 }
2634
2635 toRS() {
2636 return Buffer.concat([this.r.toBuffer({
2637 size: 32
2638 }), this.s.toBuffer({
2639 size: 32
2640 })]);
2641 }
2642
2643 toDer() {
2644 const rnbuf = this.r.toBuffer();
2645 const snbuf = this.s.toBuffer();
2646 const rneg = rnbuf[0] & 0x80;
2647 const sneg = snbuf[0] & 0x80;
2648 const rbuf = rneg ? Buffer.concat([Buffer.from([0x00]), rnbuf]) : rnbuf;
2649 const sbuf = sneg ? Buffer.concat([Buffer.from([0x00]), snbuf]) : snbuf;
2650 const length = 2 + rbuf.length + 2 + sbuf.length;
2651 const rlength = rbuf.length;
2652 const slength = sbuf.length;
2653 const rheader = 0x02;
2654 const sheader = 0x02;
2655 const header = 0x30;
2656 const der = Buffer.concat([Buffer.from([header, length, rheader, rlength]), rbuf, Buffer.from([sheader, slength]), sbuf]);
2657 return der;
2658 }
2659
2660 toTxFormat() {
2661 const derbuf = this.toDer();
2662 const buf = Buffer.alloc(1);
2663 buf.writeUInt8(this.nHashType, 0);
2664 return Buffer.concat([derbuf, buf]);
2665 }
2666
2667 toString() {
2668 return this.toHex();
2669 }
2670
2671}
2672
2673Sig.SIGHASH_ALL = 0x00000001;
2674Sig.SIGHASH_NONE = 0x00000002;
2675Sig.SIGHASH_SINGLE = 0x00000003;
2676Sig.SIGHASH_FORKID = 0x00000040;
2677Sig.SIGHASH_ANYONECANPAY = 0x00000080;
2678
2679class Script extends Struct {
2680 constructor(chunks = []) {
2681 super({
2682 chunks
2683 });
2684 }
2685
2686 fromJSON(json) {
2687 return this.fromString(json);
2688 }
2689
2690 toJSON() {
2691 return this.toString();
2692 }
2693
2694 fromBuffer(buf) {
2695 this.chunks = [];
2696 const br = new Br(buf);
2697
2698 while (!br.eof()) {
2699 const opCodeNum = br.readUInt8();
2700 let len = 0;
2701
2702 let _buf = Buffer.from([]);
2703
2704 if (opCodeNum > 0 && opCodeNum < OpCode.OP_PUSHDATA1) {
2705 len = opCodeNum;
2706 this.chunks.push({
2707 buf: br.read(len),
2708 len: len,
2709 opCodeNum: opCodeNum
2710 });
2711 } else if (opCodeNum === OpCode.OP_PUSHDATA1) {
2712 try {
2713 len = br.readUInt8();
2714 _buf = br.read(len);
2715 } catch (err) {
2716 br.read();
2717 }
2718
2719 this.chunks.push({
2720 buf: _buf,
2721 len: len,
2722 opCodeNum: opCodeNum
2723 });
2724 } else if (opCodeNum === OpCode.OP_PUSHDATA2) {
2725 try {
2726 len = br.readUInt16LE();
2727 _buf = br.read(len);
2728 } catch (err) {
2729 br.read();
2730 }
2731
2732 this.chunks.push({
2733 buf: _buf,
2734 len: len,
2735 opCodeNum: opCodeNum
2736 });
2737 } else if (opCodeNum === OpCode.OP_PUSHDATA4) {
2738 try {
2739 len = br.readUInt32LE();
2740 _buf = br.read(len);
2741 } catch (err) {
2742 br.read();
2743 }
2744
2745 this.chunks.push({
2746 buf: _buf,
2747 len: len,
2748 opCodeNum: opCodeNum
2749 });
2750 } else {
2751 this.chunks.push({
2752 opCodeNum: opCodeNum
2753 });
2754 }
2755 }
2756
2757 return this;
2758 }
2759
2760 toBuffer() {
2761 const bw = new Bw();
2762
2763 for (let i = 0; i < this.chunks.length; i++) {
2764 const chunk = this.chunks[i];
2765 const opCodeNum = chunk.opCodeNum;
2766 bw.writeUInt8(opCodeNum);
2767
2768 if (chunk.buf) {
2769 if (opCodeNum < OpCode.OP_PUSHDATA1) {
2770 bw.write(chunk.buf);
2771 } else if (opCodeNum === OpCode.OP_PUSHDATA1) {
2772 bw.writeUInt8(chunk.len);
2773 bw.write(chunk.buf);
2774 } else if (opCodeNum === OpCode.OP_PUSHDATA2) {
2775 bw.writeUInt16LE(chunk.len);
2776 bw.write(chunk.buf);
2777 } else if (opCodeNum === OpCode.OP_PUSHDATA4) {
2778 bw.writeUInt32LE(chunk.len);
2779 bw.write(chunk.buf);
2780 }
2781 }
2782 }
2783
2784 return bw.toBuffer();
2785 }
2786
2787 fromString(str) {
2788 this.chunks = [];
2789
2790 if (str === '' || str === undefined) {
2791 return this;
2792 }
2793
2794 const tokens = str.split(' ');
2795 let i = 0;
2796
2797 while (i < tokens.length) {
2798 const token = tokens[i];
2799 let opCodeNum;
2800
2801 try {
2802 const opCode = new OpCode().fromString(token);
2803 opCodeNum = opCode.toNumber();
2804 } catch (err) {}
2805
2806 if (opCodeNum === undefined) {
2807 opCodeNum = parseInt(token, 10);
2808
2809 if (opCodeNum > 0 && opCodeNum < OpCode.OP_PUSHDATA1) {
2810 this.chunks.push({
2811 buf: Buffer.from(tokens[i + 1].slice(2), 'hex'),
2812 len: opCodeNum,
2813 opCodeNum: opCodeNum
2814 });
2815 i = i + 2;
2816 } else if (opCodeNum === 0) {
2817 this.chunks.push({
2818 opCodeNum: 0
2819 });
2820 i = i + 1;
2821 } else {
2822 throw new Error('Invalid script');
2823 }
2824 } else if (opCodeNum === OpCode.OP_PUSHDATA1 || opCodeNum === OpCode.OP_PUSHDATA2 || opCodeNum === OpCode.OP_PUSHDATA4) {
2825 if (tokens[i + 2].slice(0, 2) !== '0x') {
2826 throw new Error('Pushdata data must start with 0x');
2827 }
2828
2829 this.chunks.push({
2830 buf: Buffer.from(tokens[i + 2].slice(2), 'hex'),
2831 len: parseInt(tokens[i + 1], 10),
2832 opCodeNum: opCodeNum
2833 });
2834 i = i + 3;
2835 } else {
2836 this.chunks.push({
2837 opCodeNum: opCodeNum
2838 });
2839 i = i + 1;
2840 }
2841 }
2842
2843 return this;
2844 }
2845
2846 toString() {
2847 let str = '';
2848
2849 for (let i = 0; i < this.chunks.length; i++) {
2850 const chunk = this.chunks[i];
2851 const opCodeNum = chunk.opCodeNum;
2852
2853 if (!chunk.buf) {
2854 if (OpCode.str[opCodeNum] !== undefined) {
2855 str = str + ' ' + new OpCode(opCodeNum).toString();
2856 } else {
2857 str = str + ' ' + '0x' + opCodeNum.toString(16);
2858 }
2859 } else {
2860 if (opCodeNum === OpCode.OP_PUSHDATA1 || opCodeNum === OpCode.OP_PUSHDATA2 || opCodeNum === OpCode.OP_PUSHDATA4) {
2861 str = str + ' ' + new OpCode(opCodeNum).toString();
2862 }
2863
2864 str = str + ' ' + chunk.len;
2865 str = str + ' ' + '0x' + chunk.buf.toString('hex');
2866 }
2867 }
2868
2869 return str.substr(1);
2870 }
2871
2872 fromBitcoindString(str) {
2873 const bw = new Bw();
2874 const tokens = str.split(' ');
2875 let i;
2876
2877 for (i = 0; i < tokens.length; i++) {
2878 const token = tokens[i];
2879
2880 if (token === '') {
2881 continue;
2882 }
2883
2884 if (token[0] === '0' && token[1] === 'x') {
2885 const hex = token.slice(2);
2886 bw.write(Buffer.from(hex, 'hex'));
2887 } else if (token[0] === "'") {
2888 const tstr = token.slice(1, token.length - 1);
2889 const cbuf = Buffer.from(tstr);
2890 const tbuf = new Script().writeBuffer(cbuf).toBuffer();
2891 bw.write(tbuf);
2892 } else if (OpCode['OP_' + token] !== undefined) {
2893 const opstr = 'OP_' + token;
2894 const opCodeNum = OpCode[opstr];
2895 bw.writeUInt8(opCodeNum);
2896 } else if (typeof OpCode[token] === 'number') {
2897 const opstr = token;
2898 const opCodeNum = OpCode[opstr];
2899 bw.writeUInt8(opCodeNum);
2900 } else if (!isNaN(parseInt(token, 10))) {
2901 const bn = new Bn(token);
2902 const script = new Script().writeBn(bn);
2903 const tbuf = script.toBuffer();
2904 bw.write(tbuf);
2905 } else {
2906 throw new Error('Could not determine type of script value');
2907 }
2908 }
2909
2910 const buf = bw.toBuffer();
2911 return this.fromBuffer(buf);
2912 }
2913
2914 static fromBitcoindString(str) {
2915 return new this().fromBitcoindString(str);
2916 }
2917
2918 toBitcoindString() {
2919 let str = '';
2920
2921 for (let i = 0; i < this.chunks.length; i++) {
2922 const chunk = this.chunks[i];
2923
2924 if (chunk.buf) {
2925 const buf = new Script([chunk]).toBuffer();
2926 const hex = buf.toString('hex');
2927 str = str + ' ' + '0x' + hex;
2928 } else if (OpCode.str[chunk.opCodeNum] !== undefined) {
2929 const ostr = new OpCode(chunk.opCodeNum).toString();
2930 str = str + ' ' + ostr.slice(3);
2931 } else {
2932 str = str + ' ' + '0x' + chunk.opCodeNum.toString(16);
2933 }
2934 }
2935
2936 return str.substr(1);
2937 }
2938
2939 fromAsmString(str) {
2940 this.chunks = [];
2941 const tokens = str.split(' ');
2942 let i = 0;
2943
2944 while (i < tokens.length) {
2945 const token = tokens[i];
2946 let opCode, opCodeNum;
2947
2948 try {
2949 opCode = OpCode.fromString(token);
2950 opCodeNum = opCode.toNumber();
2951 } catch (err) {
2952 opCode = undefined;
2953 opCodeNum = undefined;
2954 }
2955
2956 if (token === '0') {
2957 opCodeNum = 0;
2958 this.chunks.push({
2959 opCodeNum: opCodeNum
2960 });
2961 i = i + 1;
2962 } else if (token === '-1') {
2963 opCodeNum = OpCode.OP_1NEGATE;
2964 this.chunks.push({
2965 opCodeNum: opCodeNum
2966 });
2967 i = i + 1;
2968 } else if (opCode === undefined) {
2969 const hex = tokens[i];
2970 const buf = Buffer.from(hex, 'hex');
2971
2972 if (buf.toString('hex') !== hex) {
2973 throw new Error('invalid hex string in script');
2974 }
2975
2976 const len = buf.length;
2977
2978 if (len >= 0 && len < OpCode.OP_PUSHDATA1) {
2979 opCodeNum = len;
2980 } else if (len < Math.pow(2, 8)) {
2981 opCodeNum = OpCode.OP_PUSHDATA1;
2982 } else if (len < Math.pow(2, 16)) {
2983 opCodeNum = OpCode.OP_PUSHDATA2;
2984 } else if (len < Math.pow(2, 32)) {
2985 opCodeNum = OpCode.OP_PUSHDATA4;
2986 }
2987
2988 this.chunks.push({
2989 buf: buf,
2990 len: buf.length,
2991 opCodeNum: opCodeNum
2992 });
2993 i = i + 1;
2994 } else {
2995 this.chunks.push({
2996 opCodeNum: opCodeNum
2997 });
2998 i = i + 1;
2999 }
3000 }
3001
3002 return this;
3003 }
3004
3005 static fromAsmString(str) {
3006 return new this().fromAsmString(str);
3007 }
3008
3009 toAsmString() {
3010 var str = '';
3011
3012 for (var i = 0; i < this.chunks.length; i++) {
3013 var chunk = this.chunks[i];
3014 str += this._chunkToString(chunk);
3015 }
3016
3017 return str.substr(1);
3018 }
3019
3020 _chunkToString(chunk, type) {
3021 var opCodeNum = chunk.opCodeNum;
3022 var str = '';
3023
3024 if (!chunk.buf) {
3025 if (typeof OpCode.str[opCodeNum] !== 'undefined') {
3026 if (opCodeNum === 0) {
3027 str = str + ' 0';
3028 } else if (opCodeNum === 79) {
3029 str = str + ' -1';
3030 } else {
3031 str = str + ' ' + new OpCode(opCodeNum).toString();
3032 }
3033 } else {
3034 var numstr = opCodeNum.toString(16);
3035
3036 if (numstr.length % 2 !== 0) {
3037 numstr = '0' + numstr;
3038 }
3039
3040 str = str + ' ' + numstr;
3041 }
3042 } else {
3043 if (chunk.len > 0) {
3044 str = str + ' ' + chunk.buf.toString('hex');
3045 }
3046 }
3047
3048 return str;
3049 }
3050
3051 fromOpReturnData(dataBuf) {
3052 this.writeOpCode(OpCode.OP_RETURN);
3053 this.writeBuffer(dataBuf);
3054 return this;
3055 }
3056
3057 static fromOpReturnData(dataBuf) {
3058 return new this().fromOpReturnData(dataBuf);
3059 }
3060
3061 fromSafeData(dataBuf) {
3062 this.writeOpCode(OpCode.OP_FALSE);
3063 this.writeOpCode(OpCode.OP_RETURN);
3064 this.writeBuffer(dataBuf);
3065 return this;
3066 }
3067
3068 static fromSafeData(dataBuf) {
3069 return new this().fromSafeData(dataBuf);
3070 }
3071
3072 fromSafeDataArray(dataBufs) {
3073 this.writeOpCode(OpCode.OP_FALSE);
3074 this.writeOpCode(OpCode.OP_RETURN);
3075
3076 for (const i in dataBufs) {
3077 const dataBuf = dataBufs[i];
3078 this.writeBuffer(dataBuf);
3079 }
3080
3081 return this;
3082 }
3083
3084 static fromSafeDataArray(dataBufs) {
3085 return new this().fromSafeDataArray(dataBufs);
3086 }
3087
3088 getData() {
3089 if (this.isSafeDataOut()) {
3090 const chunks = this.chunks.slice(2);
3091 const buffers = chunks.map(chunk => chunk.buf);
3092 return buffers;
3093 }
3094
3095 if (this.isOpReturn()) {
3096 const chunks = this.chunks.slice(1);
3097 const buffers = chunks.map(chunk => chunk.buf);
3098 return buffers;
3099 }
3100
3101 throw new Error('Unrecognized script type to get data from');
3102 }
3103
3104 fromPubKeyHash(hashBuf) {
3105 if (hashBuf.length !== 20) {
3106 throw new Error('hashBuf must be a 20 byte buffer');
3107 }
3108
3109 this.writeOpCode(OpCode.OP_DUP);
3110 this.writeOpCode(OpCode.OP_HASH160);
3111 this.writeBuffer(hashBuf);
3112 this.writeOpCode(OpCode.OP_EQUALVERIFY);
3113 this.writeOpCode(OpCode.OP_CHECKSIG);
3114 return this;
3115 }
3116
3117 static fromPubKeyHash(hashBuf) {
3118 return new this().fromPubKeyHash(hashBuf);
3119 }
3120
3121 static sortPubKeys(pubKeys) {
3122 return pubKeys.slice().sort((pubKey1, pubKey2) => {
3123 const buf1 = pubKey1.toBuffer();
3124 const buf2 = pubKey2.toBuffer();
3125 const len = Math.max(buf1.length, buf2.length);
3126
3127 for (let i = 0; i <= len; i++) {
3128 if (buf1[i] === undefined) {
3129 return -1;
3130 }
3131
3132 if (buf2[i] === undefined) {
3133 return 1;
3134 }
3135
3136 if (buf1[i] < buf2[i]) {
3137 return -1;
3138 }
3139
3140 if (buf1[i] > buf2[i]) {
3141 return 1;
3142 } else {
3143 continue;
3144 }
3145 }
3146 });
3147 }
3148
3149 fromPubKeys(m, pubKeys, sort = true) {
3150 if (typeof m !== 'number') {
3151 throw new Error('m must be a number');
3152 }
3153
3154 if (sort === true) {
3155 pubKeys = Script.sortPubKeys(pubKeys);
3156 }
3157
3158 this.writeOpCode(m + OpCode.OP_1 - 1);
3159
3160 for (const i in pubKeys) {
3161 this.writeBuffer(pubKeys[i].toBuffer());
3162 }
3163
3164 this.writeOpCode(pubKeys.length + OpCode.OP_1 - 1);
3165 this.writeOpCode(OpCode.OP_CHECKMULTISIG);
3166 return this;
3167 }
3168
3169 static fromPubKeys(m, pubKeys, sort) {
3170 return new this().fromPubKeys(m, pubKeys, sort);
3171 }
3172
3173 removeCodeseparators() {
3174 const chunks = [];
3175
3176 for (let i = 0; i < this.chunks.length; i++) {
3177 if (this.chunks[i].opCodeNum !== OpCode.OP_CODESEPARATOR) {
3178 chunks.push(this.chunks[i]);
3179 }
3180 }
3181
3182 this.chunks = chunks;
3183 return this;
3184 }
3185
3186 isPushOnly() {
3187 for (let i = 0; i < this.chunks.length; i++) {
3188 const chunk = this.chunks[i];
3189 const opCodeNum = chunk.opCodeNum;
3190
3191 if (opCodeNum > OpCode.OP_16) {
3192 return false;
3193 }
3194 }
3195
3196 return true;
3197 }
3198
3199 isOpReturn() {
3200 if (this.chunks[0].opCodeNum === OpCode.OP_RETURN && this.chunks.filter(chunk => Buffer.isBuffer(chunk.buf)).length === this.chunks.slice(1).length) {
3201 return true;
3202 } else {
3203 return false;
3204 }
3205 }
3206
3207 isSafeDataOut() {
3208 if (this.chunks.length < 2) {
3209 return false;
3210 }
3211
3212 if (this.chunks[0].opCodeNum !== OpCode.OP_FALSE) {
3213 return false;
3214 }
3215
3216 var chunks = this.chunks.slice(1);
3217 var script2 = new Script(chunks);
3218 return script2.isOpReturn();
3219 }
3220
3221 isPubKeyHashOut() {
3222 if (this.chunks[0] && this.chunks[0].opCodeNum === OpCode.OP_DUP && this.chunks[1] && this.chunks[1].opCodeNum === OpCode.OP_HASH160 && this.chunks[2].buf && this.chunks[3] && this.chunks[3].opCodeNum === OpCode.OP_EQUALVERIFY && this.chunks[4] && this.chunks[4].opCodeNum === OpCode.OP_CHECKSIG) {
3223 return true;
3224 } else {
3225 return false;
3226 }
3227 }
3228
3229 isPubKeyHashIn() {
3230 if (this.chunks.length === 2 && (this.chunks[0].buf || this.chunks[0].opCodeNum === OpCode.OP_0) && (this.chunks[1].buf || this.chunks[0].opCodeNum === OpCode.OP_0)) {
3231 return true;
3232 } else {
3233 return false;
3234 }
3235 }
3236
3237 isScriptHashOut() {
3238 const buf = this.toBuffer();
3239 return buf.length === 23 && buf[0] === OpCode.OP_HASH160 && buf[1] === 0x14 && buf[22] === OpCode.OP_EQUAL;
3240 }
3241
3242 isScriptHashIn() {
3243 if (!this.isPushOnly()) {
3244 return false;
3245 }
3246
3247 try {
3248 new Script().fromBuffer(this.chunks[this.chunks.length - 1].buf);
3249 } catch (err) {
3250 return false;
3251 }
3252
3253 return true;
3254 }
3255
3256 isMultiSigOut() {
3257 const m = this.chunks[0].opCodeNum - OpCode.OP_1 + 1;
3258
3259 if (!(m >= 1 && m <= 16)) {
3260 return false;
3261 }
3262
3263 const pubKeychunks = this.chunks.slice(1, this.chunks.length - 2);
3264
3265 if (!pubKeychunks.every(chunk => {
3266 try {
3267 const buf = chunk.buf;
3268 const pubKey = new PubKey().fromDer(buf);
3269 pubKey.validate();
3270 return true;
3271 } catch (err) {
3272 return false;
3273 }
3274 })) {
3275 return false;
3276 }
3277
3278 const n = this.chunks[this.chunks.length - 2].opCodeNum - OpCode.OP_1 + 1;
3279
3280 if (!(n >= m && n <= 16)) {
3281 return false;
3282 }
3283
3284 if (this.chunks[1 + n + 1].opCodeNum !== OpCode.OP_CHECKMULTISIG) {
3285 return false;
3286 }
3287
3288 return true;
3289 }
3290
3291 isMultiSigIn() {
3292 if (this.chunks[0].opCodeNum !== OpCode.OP_0) {
3293 return false;
3294 }
3295
3296 const remaining = this.chunks.slice(1);
3297
3298 if (remaining.length < 1) {
3299 return false;
3300 }
3301
3302 return remaining.every(chunk => Buffer.isBuffer(chunk.buf) && Sig.IsTxDer(chunk.buf));
3303 }
3304
3305 findAndDelete(script) {
3306 const buf = script.toBuffer();
3307
3308 for (let i = 0; i < this.chunks.length; i++) {
3309 const script2 = new Script([this.chunks[i]]);
3310 const buf2 = script2.toBuffer();
3311
3312 if (cmp(buf, buf2)) {
3313 this.chunks.splice(i, 1);
3314 }
3315 }
3316
3317 return this;
3318 }
3319
3320 writeScript(script) {
3321 this.chunks = this.chunks.concat(script.chunks);
3322 return this;
3323 }
3324
3325 static writeScript(script) {
3326 return new this().writeScript(script);
3327 }
3328
3329 writeString(str) {
3330 const script = new Script().fromString(str);
3331 this.chunks = this.chunks.concat(script.chunks);
3332 return this;
3333 }
3334
3335 static writeString(str) {
3336 return new this().writeString(str);
3337 }
3338
3339 writeOpCode(opCodeNum) {
3340 this.chunks.push({
3341 opCodeNum
3342 });
3343 return this;
3344 }
3345
3346 static writeOpCode(opCodeNum) {
3347 return new this().writeOpCode(opCodeNum);
3348 }
3349
3350 setChunkOpCode(i, opCodeNum) {
3351 this.chunks[i] = {
3352 opCodeNum
3353 };
3354 return this;
3355 }
3356
3357 writeBn(bn) {
3358 if (bn.cmp(0) === OpCode.OP_0) {
3359 this.chunks.push({
3360 opCodeNum: OpCode.OP_0
3361 });
3362 } else if (bn.cmp(-1) === 0) {
3363 this.chunks.push({
3364 opCodeNum: OpCode.OP_1NEGATE
3365 });
3366 } else if (bn.cmp(1) >= 0 && bn.cmp(16) <= 0) {
3367 this.chunks.push({
3368 opCodeNum: bn.toNumber() + OpCode.OP_1 - 1
3369 });
3370 } else {
3371 const buf = bn.toSm({
3372 endian: 'little'
3373 });
3374 this.writeBuffer(buf);
3375 }
3376
3377 return this;
3378 }
3379
3380 static writeBn(bn) {
3381 return new this().writeBn(bn);
3382 }
3383
3384 writeNumber(number) {
3385 this.writeBn(new Bn().fromNumber(number));
3386 return this;
3387 }
3388
3389 static writeNumber(number) {
3390 return new this().writeNumber(number);
3391 }
3392
3393 setChunkBn(i, bn) {
3394 this.chunks[i] = new Script().writeBn(bn).chunks[0];
3395 return this;
3396 }
3397
3398 writeBuffer(buf) {
3399 let opCodeNum;
3400 const len = buf.length;
3401
3402 if (buf.length > 0 && buf.length < OpCode.OP_PUSHDATA1) {
3403 opCodeNum = buf.length;
3404 } else if (buf.length === 0) {
3405 opCodeNum = OpCode.OP_0;
3406 } else if (buf.length < Math.pow(2, 8)) {
3407 opCodeNum = OpCode.OP_PUSHDATA1;
3408 } else if (buf.length < Math.pow(2, 16)) {
3409 opCodeNum = OpCode.OP_PUSHDATA2;
3410 } else if (buf.length < Math.pow(2, 32)) {
3411 opCodeNum = OpCode.OP_PUSHDATA4;
3412 } else {
3413 throw new Error("You can't push that much data");
3414 }
3415
3416 this.chunks.push({
3417 buf: buf,
3418 len: len,
3419 opCodeNum: opCodeNum
3420 });
3421 return this;
3422 }
3423
3424 static writeBuffer(buf) {
3425 return new this().writeBuffer(buf);
3426 }
3427
3428 setChunkBuffer(i, buf) {
3429 this.chunks[i] = new Script().writeBuffer(buf).chunks[0];
3430 return this;
3431 }
3432
3433 checkMinimalPush(i) {
3434 const chunk = this.chunks[i];
3435 const buf = chunk.buf;
3436 const opCodeNum = chunk.opCodeNum;
3437
3438 if (!buf) {
3439 return true;
3440 }
3441
3442 if (buf.length === 0) {
3443 return opCodeNum === OpCode.OP_0;
3444 } else if (buf.length === 1 && buf[0] >= 1 && buf[0] <= 16) {
3445 return opCodeNum === OpCode.OP_1 + (buf[0] - 1);
3446 } else if (buf.length === 1 && buf[0] === 0x81) {
3447 return opCodeNum === OpCode.OP_1NEGATE;
3448 } else if (buf.length <= 75) {
3449 return opCodeNum === buf.length;
3450 } else if (buf.length <= 255) {
3451 return opCodeNum === OpCode.OP_PUSHDATA1;
3452 } else if (buf.length <= 65535) {
3453 return opCodeNum === OpCode.OP_PUSHDATA2;
3454 }
3455
3456 return true;
3457 }
3458
3459}
3460
3461class Address extends Struct {
3462 constructor(versionByteNum, hashBuf, constants = null) {
3463 super({
3464 versionByteNum,
3465 hashBuf
3466 });
3467 constants = constants || Constants.Default.Address;
3468 this.Constants = constants;
3469 }
3470
3471 fromBuffer(buf) {
3472 if (buf.length !== 1 + 20) {
3473 throw new Error('address buffers must be exactly 21 bytes');
3474 }
3475
3476 if (buf[0] !== this.Constants.pubKeyHash) {
3477 throw new Error('address: invalid versionByteNum byte');
3478 }
3479
3480 this.versionByteNum = buf[0];
3481 this.hashBuf = buf.slice(1);
3482 return this;
3483 }
3484
3485 fromPubKeyHashBuf(hashBuf) {
3486 this.hashBuf = hashBuf;
3487 this.versionByteNum = this.Constants.pubKeyHash;
3488 return this;
3489 }
3490
3491 static fromPubKeyHashBuf(hashBuf) {
3492 return new this().fromPubKeyHashBuf(hashBuf);
3493 }
3494
3495 fromPubKey(pubKey) {
3496 const hashBuf = Hash.sha256Ripemd160(pubKey.toBuffer());
3497 return this.fromPubKeyHashBuf(hashBuf);
3498 }
3499
3500 static fromPubKey(pubKey) {
3501 return new this().fromPubKey(pubKey);
3502 }
3503
3504 async asyncFromPubKey(pubKey) {
3505 const args = [pubKey];
3506 const workersResult = await Workers.asyncObjectMethod(this, 'fromPubKey', args);
3507 return this.fromFastBuffer(workersResult.resbuf);
3508 }
3509
3510 static asyncFromPubKey(pubKey) {
3511 return new this().asyncFromPubKey(pubKey);
3512 }
3513
3514 fromPrivKey(privKey) {
3515 const pubKey = new PubKey().fromPrivKey(privKey);
3516 const hashBuf = Hash.sha256Ripemd160(pubKey.toBuffer());
3517 return this.fromPubKeyHashBuf(hashBuf);
3518 }
3519
3520 static fromPrivKey(privKey) {
3521 return new this().fromPrivKey(privKey);
3522 }
3523
3524 async asyncFromPrivKey(privKey) {
3525 const args = [privKey];
3526 const workersResult = await Workers.asyncObjectMethod(this, 'fromPrivKey', args);
3527 return this.fromFastBuffer(workersResult.resbuf);
3528 }
3529
3530 static asyncFromPrivKey(privKey) {
3531 return new this().fromPrivKey(privKey);
3532 }
3533
3534 fromRandom() {
3535 const randomPrivKey = new PrivKey().fromRandom();
3536 return this.fromPrivKey(randomPrivKey);
3537 }
3538
3539 static fromRandom() {
3540 return new this().fromRandom();
3541 }
3542
3543 async asyncFromRandom() {
3544 const args = [];
3545 const workersResult = await Workers.asyncObjectMethod(this, 'fromRandom', args);
3546 return this.fromFastBuffer(workersResult.resbuf);
3547 }
3548
3549 static asyncFromRandom() {
3550 return new this().fromRandom();
3551 }
3552
3553 fromString(str) {
3554 const buf = Base58Check.decode(str);
3555 return this.fromBuffer(buf);
3556 }
3557
3558 async asyncFromString(str) {
3559 const args = [str];
3560 const workersResult = await Workers.asyncObjectMethod(this, 'fromString', args);
3561 return this.fromFastBuffer(workersResult.resbuf);
3562 }
3563
3564 static asyncFromString(str) {
3565 return new this().asyncFromString(str);
3566 }
3567
3568 static isValid(addrstr) {
3569 let address;
3570
3571 try {
3572 address = new Address().fromString(addrstr);
3573 } catch (e) {
3574 return false;
3575 }
3576
3577 return address.isValid();
3578 }
3579
3580 isValid() {
3581 try {
3582 this.validate();
3583 return true;
3584 } catch (e) {
3585 return false;
3586 }
3587 }
3588
3589 toTxOutScript() {
3590 const script = new Script();
3591 script.writeOpCode(OpCode.OP_DUP);
3592 script.writeOpCode(OpCode.OP_HASH160);
3593 script.writeBuffer(this.hashBuf);
3594 script.writeOpCode(OpCode.OP_EQUALVERIFY);
3595 script.writeOpCode(OpCode.OP_CHECKSIG);
3596 return script;
3597 }
3598
3599 fromTxInScript(script) {
3600 const pubKeyHashBuf = Hash.sha256Ripemd160(script.chunks[1].buf || Buffer.from('00'.repeat(32), 'hex'));
3601 return this.fromPubKeyHashBuf(pubKeyHashBuf);
3602 }
3603
3604 static fromTxInScript(script) {
3605 return new this().fromTxInScript(script);
3606 }
3607
3608 fromTxOutScript(script) {
3609 return this.fromPubKeyHashBuf(script.chunks[2].buf);
3610 }
3611
3612 static fromTxOutScript(script) {
3613 return new this().fromTxOutScript(script);
3614 }
3615
3616 toBuffer() {
3617 const versionByteBuf = Buffer.from([this.versionByteNum]);
3618 const buf = Buffer.concat([versionByteBuf, this.hashBuf]);
3619 return buf;
3620 }
3621
3622 toJSON() {
3623 const json = {};
3624
3625 if (this.hashBuf) {
3626 json.hashBuf = this.hashBuf.toString('hex');
3627 }
3628
3629 if (typeof this.versionByteNum !== 'undefined') {
3630 json.versionByteNum = this.versionByteNum;
3631 }
3632
3633 return json;
3634 }
3635
3636 fromJSON(json) {
3637 if (json.hashBuf) {
3638 this.hashBuf = Buffer.from(json.hashBuf, 'hex');
3639 }
3640
3641 if (typeof json.versionByteNum !== 'undefined') {
3642 this.versionByteNum = json.versionByteNum;
3643 }
3644
3645 return this;
3646 }
3647
3648 toString() {
3649 return Base58Check.encode(this.toBuffer());
3650 }
3651
3652 async asyncToString() {
3653 const args = [];
3654 const workersResult = await Workers.asyncObjectMethod(this, 'toString', args);
3655 return JSON.parse(workersResult.resbuf.toString());
3656 }
3657
3658 validate() {
3659 if (!Buffer.isBuffer(this.hashBuf) || this.hashBuf.length !== 20) {
3660 throw new Error('hashBuf must be a buffer of 20 bytes');
3661 }
3662
3663 if (this.versionByteNum !== this.Constants.pubKeyHash) {
3664 throw new Error('invalid versionByteNum');
3665 }
3666
3667 return this;
3668 }
3669
3670}
3671
3672Address.Mainnet = class extends Address {
3673 constructor(versionByteNum, hashBuf) {
3674 super(versionByteNum, hashBuf, Constants.Mainnet.Address);
3675 }
3676
3677};
3678Address.Testnet = class extends Address {
3679 constructor(versionByteNum, hashBuf) {
3680 super(versionByteNum, hashBuf, Constants.Testnet.Address);
3681 }
3682
3683};
3684
3685class Bip32 extends Struct {
3686 constructor(versionBytesNum, depth, parentFingerPrint, childIndex, chainCode, privKey, pubKey, constants = null, PrivKey$1 = PrivKey) {
3687 super({
3688 versionBytesNum,
3689 depth,
3690 parentFingerPrint,
3691 childIndex,
3692 chainCode,
3693 privKey,
3694 pubKey
3695 });
3696 constants = constants || Constants.Default.Bip32;
3697 this.Constants = constants;
3698 this.PrivKey = PrivKey$1;
3699 }
3700
3701 fromRandom() {
3702 this.versionBytesNum = this.Constants.privKey;
3703 this.depth = 0x00;
3704 this.parentFingerPrint = Buffer.from([0, 0, 0, 0]);
3705 this.childIndex = 0;
3706 this.chainCode = Random.getRandomBuffer(32);
3707 this.privKey = new this.PrivKey().fromRandom();
3708 this.pubKey = new PubKey().fromPrivKey(this.privKey);
3709 return this;
3710 }
3711
3712 static fromRandom() {
3713 return new this().fromRandom();
3714 }
3715
3716 fromString(str) {
3717 return this.fromBuffer(Base58Check.decode(str));
3718 }
3719
3720 async asyncFromString(str) {
3721 const args = [str];
3722 const workersResult = await Workers.asyncObjectMethod(this, 'fromString', args);
3723 return this.fromFastBuffer(workersResult.resbuf);
3724 }
3725
3726 fromSeed(bytes) {
3727 if (!Buffer.isBuffer(bytes)) {
3728 throw new Error('bytes must be a buffer');
3729 }
3730
3731 if (bytes.length < 128 / 8) {
3732 throw new Error('Need more than 128 bits of entropy');
3733 }
3734
3735 if (bytes.length > 512 / 8) {
3736 throw new Error('More than 512 bits of entropy is nonstandard');
3737 }
3738
3739 const hash = Hash.sha512Hmac(bytes, Buffer.from('Bitcoin seed'));
3740 this.depth = 0x00;
3741 this.parentFingerPrint = Buffer.from([0, 0, 0, 0]);
3742 this.childIndex = 0;
3743 this.chainCode = hash.slice(32, 64);
3744 this.versionBytesNum = this.Constants.privKey;
3745 this.privKey = new this.PrivKey().fromBn(Bn().fromBuffer(hash.slice(0, 32)));
3746 this.pubKey = new PubKey().fromPrivKey(this.privKey);
3747 return this;
3748 }
3749
3750 static fromSeed(bytes) {
3751 return new this().fromSeed(bytes);
3752 }
3753
3754 async asyncFromSeed(bytes) {
3755 const workersResult = await Workers.asyncObjectMethod(this, 'fromSeed', [bytes]);
3756 return this.fromFastBuffer(workersResult.resbuf);
3757 }
3758
3759 static asyncFromSeed(bytes) {
3760 return new this().asyncFromSeed(bytes);
3761 }
3762
3763 fromBuffer(buf) {
3764 if (buf.length !== 78) {
3765 throw new Error('incorrect bip32 data length');
3766 }
3767
3768 this.versionBytesNum = buf.slice(0, 4).readUInt32BE(0);
3769 this.depth = buf.slice(4, 5).readUInt8(0);
3770 this.parentFingerPrint = buf.slice(5, 9);
3771 this.childIndex = buf.slice(9, 13).readUInt32BE(0);
3772 this.chainCode = buf.slice(13, 45);
3773 const keyBytes = buf.slice(45, 78);
3774 const isPrivate = this.versionBytesNum === this.Constants.privKey;
3775 const isPublic = this.versionBytesNum === this.Constants.pubKey;
3776
3777 if (isPrivate && keyBytes[0] === 0) {
3778 this.privKey = new this.PrivKey().fromBn(Bn().fromBuffer(keyBytes.slice(1, 33)));
3779 this.pubKey = new PubKey().fromPrivKey(this.privKey);
3780 } else if (isPublic && (keyBytes[0] === 0x02 || keyBytes[0] === 0x03)) {
3781 this.pubKey = new PubKey().fromDer(keyBytes);
3782 } else {
3783 throw new Error('Invalid key');
3784 }
3785
3786 return this;
3787 }
3788
3789 fromFastBuffer(buf) {
3790 if (buf.length === 0) {
3791 return this;
3792 }
3793
3794 if (buf.length !== 78 && buf.length !== 78 + 33) {
3795 throw new Error('incorrect bip32 fastBuffer data length: ' + buf.length);
3796 }
3797
3798 this.versionBytesNum = buf.slice(0, 4).readUInt32BE(0);
3799 this.depth = buf.slice(4, 5).readUInt8(0);
3800 this.parentFingerPrint = buf.slice(5, 9);
3801 this.childIndex = buf.slice(9, 13).readUInt32BE(0);
3802 this.chainCode = buf.slice(13, 45);
3803 const keyBytes = buf.slice(45, buf.length);
3804 const isPrivate = this.versionBytesNum === this.Constants.privKey;
3805 const isPublic = this.versionBytesNum === this.Constants.pubKey;
3806
3807 if (isPrivate && keyBytes[0] === 0 && buf.length === 78) {
3808 this.privKey = new this.PrivKey().fromBn(Bn().fromBuffer(keyBytes.slice(1, 33)));
3809 this.pubKey = new PubKey().fromPrivKey(this.privKey);
3810 } else if (isPublic && buf.length === 78 + 33) {
3811 this.pubKey = new PubKey().fromFastBuffer(keyBytes);
3812 this.pubKey.compressed = true;
3813 } else {
3814 throw new Error('Invalid key');
3815 }
3816
3817 return this;
3818 }
3819
3820 derive(path) {
3821 const e = path.split('/');
3822
3823 if (path === 'm') {
3824 return this;
3825 }
3826
3827 let bip32 = this;
3828
3829 for (const i in e) {
3830 const c = e[i];
3831
3832 if (i === '0') {
3833 if (c !== 'm') throw new Error('invalid path');
3834 continue;
3835 }
3836
3837 if (parseInt(c.replace("'", ''), 10).toString() !== c.replace("'", '')) {
3838 throw new Error('invalid path');
3839 }
3840
3841 const usePrivate = c.length > 1 && c[c.length - 1] === "'";
3842 let childIndex = parseInt(usePrivate ? c.slice(0, c.length - 1) : c, 10) & 0x7fffffff;
3843
3844 if (usePrivate) {
3845 childIndex += 0x80000000;
3846 }
3847
3848 bip32 = bip32.deriveChild(childIndex);
3849 }
3850
3851 return bip32;
3852 }
3853
3854 async asyncDerive(path) {
3855 const workersResult = await Workers.asyncObjectMethod(this, 'derive', [path]);
3856 return new this.constructor().fromFastBuffer(workersResult.resbuf);
3857 }
3858
3859 deriveChild(i) {
3860 if (typeof i !== 'number') {
3861 throw new Error('i must be a number');
3862 }
3863
3864 let ib = [];
3865 ib.push(i >> 24 & 0xff);
3866 ib.push(i >> 16 & 0xff);
3867 ib.push(i >> 8 & 0xff);
3868 ib.push(i & 0xff);
3869 ib = Buffer.from(ib);
3870 const usePrivate = (i & 0x80000000) !== 0;
3871 const isPrivate = this.versionBytesNum === this.Constants.privKey;
3872
3873 if (usePrivate && (!this.privKey || !isPrivate)) {
3874 throw new Error('Cannot do private key derivation without private key');
3875 }
3876
3877 let ret = null;
3878
3879 if (this.privKey) {
3880 let data = null;
3881
3882 if (usePrivate) {
3883 data = Buffer.concat([Buffer.from([0]), this.privKey.bn.toBuffer({
3884 size: 32
3885 }), ib]);
3886 } else {
3887 data = Buffer.concat([this.pubKey.toBuffer({
3888 size: 32
3889 }), ib]);
3890 }
3891
3892 const hash = Hash.sha512Hmac(data, this.chainCode);
3893 const il = Bn().fromBuffer(hash.slice(0, 32), {
3894 size: 32
3895 });
3896 const ir = hash.slice(32, 64);
3897 const k = il.add(this.privKey.bn).mod(Point.getN());
3898 ret = new this.constructor();
3899 ret.chainCode = ir;
3900 ret.privKey = new this.PrivKey().fromBn(k);
3901 ret.pubKey = new PubKey().fromPrivKey(ret.privKey);
3902 } else {
3903 const data = Buffer.concat([this.pubKey.toBuffer(), ib]);
3904 const hash = Hash.sha512Hmac(data, this.chainCode);
3905 const il = Bn().fromBuffer(hash.slice(0, 32));
3906 const ir = hash.slice(32, 64);
3907 const ilG = Point.getG().mul(il);
3908 const Kpar = this.pubKey.point;
3909 const Ki = ilG.add(Kpar);
3910 const newpub = new PubKey();
3911 newpub.point = Ki;
3912 ret = new this.constructor();
3913 ret.chainCode = ir;
3914 ret.pubKey = newpub;
3915 }
3916
3917 ret.childIndex = i;
3918 const pubKeyhash = Hash.sha256Ripemd160(this.pubKey.toBuffer());
3919 ret.parentFingerPrint = pubKeyhash.slice(0, 4);
3920 ret.versionBytesNum = this.versionBytesNum;
3921 ret.depth = this.depth + 1;
3922 return ret;
3923 }
3924
3925 toPublic() {
3926 const bip32 = new this.constructor().fromObject(this);
3927 bip32.versionBytesNum = this.Constants.pubKey;
3928 bip32.privKey = undefined;
3929 return bip32;
3930 }
3931
3932 toBuffer() {
3933 const isPrivate = this.versionBytesNum === this.Constants.privKey;
3934 const isPublic = this.versionBytesNum === this.Constants.pubKey;
3935
3936 if (isPrivate) {
3937 return new Bw().writeUInt32BE(this.versionBytesNum).writeUInt8(this.depth).write(this.parentFingerPrint).writeUInt32BE(this.childIndex).write(this.chainCode).writeUInt8(0).write(this.privKey.bn.toBuffer({
3938 size: 32
3939 })).toBuffer();
3940 } else if (isPublic) {
3941 if (this.pubKey.compressed === false) {
3942 throw new Error('cannot convert bip32 to buffer if pubKey is not compressed');
3943 }
3944
3945 return new Bw().writeUInt32BE(this.versionBytesNum).writeUInt8(this.depth).write(this.parentFingerPrint).writeUInt32BE(this.childIndex).write(this.chainCode).write(this.pubKey.toBuffer()).toBuffer();
3946 } else {
3947 throw new Error('bip32: invalid versionBytesNum byte');
3948 }
3949 }
3950
3951 toFastBuffer() {
3952 if (!this.versionBytesNum) {
3953 return Buffer.alloc(0);
3954 }
3955
3956 const isPrivate = this.versionBytesNum === this.Constants.privKey;
3957 const isPublic = this.versionBytesNum === this.Constants.pubKey;
3958
3959 if (isPrivate) {
3960 return new Bw().writeUInt32BE(this.versionBytesNum).writeUInt8(this.depth).write(this.parentFingerPrint).writeUInt32BE(this.childIndex).write(this.chainCode).writeUInt8(0).write(this.privKey.bn.toBuffer({
3961 size: 32
3962 })).toBuffer();
3963 } else if (isPublic) {
3964 return new Bw().writeUInt32BE(this.versionBytesNum).writeUInt8(this.depth).write(this.parentFingerPrint).writeUInt32BE(this.childIndex).write(this.chainCode).write(this.pubKey.toFastBuffer()).toBuffer();
3965 } else {
3966 throw new Error('bip32: invalid versionBytesNum byte');
3967 }
3968 }
3969
3970 toString() {
3971 return Base58Check.encode(this.toBuffer());
3972 }
3973
3974 async asyncToString() {
3975 const workersResult = await Workers.asyncObjectMethod(this, 'toString', []);
3976 return JSON.parse(workersResult.resbuf.toString());
3977 }
3978
3979 toJSON() {
3980 return this.toFastHex();
3981 }
3982
3983 fromJSON(json) {
3984 return this.fromFastHex(json);
3985 }
3986
3987 isPrivate() {
3988 return this.versionBytesNum === this.Constants.privKey;
3989 }
3990
3991}
3992
3993Bip32.Mainnet = class extends Bip32 {
3994 constructor(versionBytesNum, depth, parentFingerPrint, childIndex, chainCode, privKey, pubKey) {
3995 super(versionBytesNum, depth, parentFingerPrint, childIndex, chainCode, privKey, pubKey, Constants.Mainnet.Bip32, PrivKey.Mainnet);
3996 }
3997
3998};
3999Bip32.Testnet = class extends Bip32 {
4000 constructor(versionBytesNum, depth, parentFingerPrint, childIndex, chainCode, privKey, pubKey) {
4001 super(versionBytesNum, depth, parentFingerPrint, childIndex, chainCode, privKey, pubKey, Constants.Testnet.Bip32, PrivKey.Testnet);
4002 }
4003
4004};
4005
4006const wordList = ['abandon', 'ability', 'able', 'about', 'above', 'absent', 'absorb', 'abstract', 'absurd', 'abuse', 'access', 'accident', 'account', 'accuse', 'achieve', 'acid', 'acoustic', 'acquire', 'across', 'act', 'action', 'actor', 'actress', 'actual', 'adapt', 'add', 'addict', 'address', 'adjust', 'admit', 'adult', 'advance', 'advice', 'aerobic', 'affair', 'afford', 'afraid', 'again', 'age', 'agent', 'agree', 'ahead', 'aim', 'air', 'airport', 'aisle', 'alarm', 'album', 'alcohol', 'alert', 'alien', 'all', 'alley', 'allow', 'almost', 'alone', 'alpha', 'already', 'also', 'alter', 'always', 'amateur', 'amazing', 'among', 'amount', 'amused', 'analyst', 'anchor', 'ancient', 'anger', 'angle', 'angry', 'animal', 'ankle', 'announce', 'annual', 'another', 'answer', 'antenna', 'antique', 'anxiety', 'any', 'apart', 'apology', 'appear', 'apple', 'approve', 'april', 'arch', 'arctic', 'area', 'arena', 'argue', 'arm', 'armed', 'armor', 'army', 'around', 'arrange', 'arrest', 'arrive', 'arrow', 'art', 'artefact', 'artist', 'artwork', 'ask', 'aspect', 'assault', 'asset', 'assist', 'assume', 'asthma', 'athlete', 'atom', 'attack', 'attend', 'attitude', 'attract', 'auction', 'audit', 'august', 'aunt', 'author', 'auto', 'autumn', 'average', 'avocado', 'avoid', 'awake', 'aware', 'away', 'awesome', 'awful', 'awkward', 'axis', 'baby', 'bachelor', 'bacon', 'badge', 'bag', 'balance', 'balcony', 'ball', 'bamboo', 'banana', 'banner', 'bar', 'barely', 'bargain', 'barrel', 'base', 'basic', 'basket', 'battle', 'beach', 'bean', 'beauty', 'because', 'become', 'beef', 'before', 'begin', 'behave', 'behind', 'believe', 'below', 'belt', 'bench', 'benefit', 'best', 'betray', 'better', 'between', 'beyond', 'bicycle', 'bid', 'bike', 'bind', 'biology', 'bird', 'birth', 'bitter', 'black', 'blade', 'blame', 'blanket', 'blast', 'bleak', 'bless', 'blind', 'blood', 'blossom', 'blouse', 'blue', 'blur', 'blush', 'board', 'boat', 'body', 'boil', 'bomb', 'bone', 'bonus', 'book', 'boost', 'border', 'boring', 'borrow', 'boss', 'bottom', 'bounce', 'box', 'boy', 'bracket', 'brain', 'brand', 'brass', 'brave', 'bread', 'breeze', 'brick', 'bridge', 'brief', 'bright', 'bring', 'brisk', 'broccoli', 'broken', 'bronze', 'broom', 'brother', 'brown', 'brush', 'bubble', 'buddy', 'budget', 'buffalo', 'build', 'bulb', 'bulk', 'bullet', 'bundle', 'bunker', 'burden', 'burger', 'burst', 'bus', 'business', 'busy', 'butter', 'buyer', 'buzz', 'cabbage', 'cabin', 'cable', 'cactus', 'cage', 'cake', 'call', 'calm', 'camera', 'camp', 'can', 'canal', 'cancel', 'candy', 'cannon', 'canoe', 'canvas', 'canyon', 'capable', 'capital', 'captain', 'car', 'carbon', 'card', 'cargo', 'carpet', 'carry', 'cart', 'case', 'cash', 'casino', 'castle', 'casual', 'cat', 'catalog', 'catch', 'category', 'cattle', 'caught', 'cause', 'caution', 'cave', 'ceiling', 'celery', 'cement', 'census', 'century', 'cereal', 'certain', 'chair', 'chalk', 'champion', 'change', 'chaos', 'chapter', 'charge', 'chase', 'chat', 'cheap', 'check', 'cheese', 'chef', 'cherry', 'chest', 'chicken', 'chief', 'child', 'chimney', 'choice', 'choose', 'chronic', 'chuckle', 'chunk', 'churn', 'cigar', 'cinnamon', 'circle', 'citizen', 'city', 'civil', 'claim', 'clap', 'clarify', 'claw', 'clay', 'clean', 'clerk', 'clever', 'click', 'client', 'cliff', 'climb', 'clinic', 'clip', 'clock', 'clog', 'close', 'cloth', 'cloud', 'clown', 'club', 'clump', 'cluster', 'clutch', 'coach', 'coast', 'coconut', 'code', 'coffee', 'coil', 'coin', 'collect', 'color', 'column', 'combine', 'come', 'comfort', 'comic', 'common', 'company', 'concert', 'conduct', 'confirm', 'congress', 'connect', 'consider', 'control', 'convince', 'cook', 'cool', 'copper', 'copy', 'coral', 'core', 'corn', 'correct', 'cost', 'cotton', 'couch', 'country', 'couple', 'course', 'cousin', 'cover', 'coyote', 'crack', 'cradle', 'craft', 'cram', 'crane', 'crash', 'crater', 'crawl', 'crazy', 'cream', 'credit', 'creek', 'crew', 'cricket', 'crime', 'crisp', 'critic', 'crop', 'cross', 'crouch', 'crowd', 'crucial', 'cruel', 'cruise', 'crumble', 'crunch', 'crush', 'cry', 'crystal', 'cube', 'culture', 'cup', 'cupboard', 'curious', 'current', 'curtain', 'curve', 'cushion', 'custom', 'cute', 'cycle', 'dad', 'damage', 'damp', 'dance', 'danger', 'daring', 'dash', 'daughter', 'dawn', 'day', 'deal', 'debate', 'debris', 'decade', 'december', 'decide', 'decline', 'decorate', 'decrease', 'deer', 'defense', 'define', 'defy', 'degree', 'delay', 'deliver', 'demand', 'demise', 'denial', 'dentist', 'deny', 'depart', 'depend', 'deposit', 'depth', 'deputy', 'derive', 'describe', 'desert', 'design', 'desk', 'despair', 'destroy', 'detail', 'detect', 'develop', 'device', 'devote', 'diagram', 'dial', 'diamond', 'diary', 'dice', 'diesel', 'diet', 'differ', 'digital', 'dignity', 'dilemma', 'dinner', 'dinosaur', 'direct', 'dirt', 'disagree', 'discover', 'disease', 'dish', 'dismiss', 'disorder', 'display', 'distance', 'divert', 'divide', 'divorce', 'dizzy', 'doctor', 'document', 'dog', 'doll', 'dolphin', 'domain', 'donate', 'donkey', 'donor', 'door', 'dose', 'double', 'dove', 'draft', 'dragon', 'drama', 'drastic', 'draw', 'dream', 'dress', 'drift', 'drill', 'drink', 'drip', 'drive', 'drop', 'drum', 'dry', 'duck', 'dumb', 'dune', 'during', 'dust', 'dutch', 'duty', 'dwarf', 'dynamic', 'eager', 'eagle', 'early', 'earn', 'earth', 'easily', 'east', 'easy', 'echo', 'ecology', 'economy', 'edge', 'edit', 'educate', 'effort', 'egg', 'eight', 'either', 'elbow', 'elder', 'electric', 'elegant', 'element', 'elephant', 'elevator', 'elite', 'else', 'embark', 'embody', 'embrace', 'emerge', 'emotion', 'employ', 'empower', 'empty', 'enable', 'enact', 'end', 'endless', 'endorse', 'enemy', 'energy', 'enforce', 'engage', 'engine', 'enhance', 'enjoy', 'enlist', 'enough', 'enrich', 'enroll', 'ensure', 'enter', 'entire', 'entry', 'envelope', 'episode', 'equal', 'equip', 'era', 'erase', 'erode', 'erosion', 'error', 'erupt', 'escape', 'essay', 'essence', 'estate', 'eternal', 'ethics', 'evidence', 'evil', 'evoke', 'evolve', 'exact', 'example', 'excess', 'exchange', 'excite', 'exclude', 'excuse', 'execute', 'exercise', 'exhaust', 'exhibit', 'exile', 'exist', 'exit', 'exotic', 'expand', 'expect', 'expire', 'explain', 'expose', 'express', 'extend', 'extra', 'eye', 'eyebrow', 'fabric', 'face', 'faculty', 'fade', 'faint', 'faith', 'fall', 'false', 'fame', 'family', 'famous', 'fan', 'fancy', 'fantasy', 'farm', 'fashion', 'fat', 'fatal', 'father', 'fatigue', 'fault', 'favorite', 'feature', 'february', 'federal', 'fee', 'feed', 'feel', 'female', 'fence', 'festival', 'fetch', 'fever', 'few', 'fiber', 'fiction', 'field', 'figure', 'file', 'film', 'filter', 'final', 'find', 'fine', 'finger', 'finish', 'fire', 'firm', 'first', 'fiscal', 'fish', 'fit', 'fitness', 'fix', 'flag', 'flame', 'flash', 'flat', 'flavor', 'flee', 'flight', 'flip', 'float', 'flock', 'floor', 'flower', 'fluid', 'flush', 'fly', 'foam', 'focus', 'fog', 'foil', 'fold', 'follow', 'food', 'foot', 'force', 'forest', 'forget', 'fork', 'fortune', 'forum', 'forward', 'fossil', 'foster', 'found', 'fox', 'fragile', 'frame', 'frequent', 'fresh', 'friend', 'fringe', 'frog', 'front', 'frost', 'frown', 'frozen', 'fruit', 'fuel', 'fun', 'funny', 'furnace', 'fury', 'future', 'gadget', 'gain', 'galaxy', 'gallery', 'game', 'gap', 'garage', 'garbage', 'garden', 'garlic', 'garment', 'gas', 'gasp', 'gate', 'gather', 'gauge', 'gaze', 'general', 'genius', 'genre', 'gentle', 'genuine', 'gesture', 'ghost', 'giant', 'gift', 'giggle', 'ginger', 'giraffe', 'girl', 'give', 'glad', 'glance', 'glare', 'glass', 'glide', 'glimpse', 'globe', 'gloom', 'glory', 'glove', 'glow', 'glue', 'goat', 'goddess', 'gold', 'good', 'goose', 'gorilla', 'gospel', 'gossip', 'govern', 'gown', 'grab', 'grace', 'grain', 'grant', 'grape', 'grass', 'gravity', 'great', 'green', 'grid', 'grief', 'grit', 'grocery', 'group', 'grow', 'grunt', 'guard', 'guess', 'guide', 'guilt', 'guitar', 'gun', 'gym', 'habit', 'hair', 'half', 'hammer', 'hamster', 'hand', 'happy', 'harbor', 'hard', 'harsh', 'harvest', 'hat', 'have', 'hawk', 'hazard', 'head', 'health', 'heart', 'heavy', 'hedgehog', 'height', 'hello', 'helmet', 'help', 'hen', 'hero', 'hidden', 'high', 'hill', 'hint', 'hip', 'hire', 'history', 'hobby', 'hockey', 'hold', 'hole', 'holiday', 'hollow', 'home', 'honey', 'hood', 'hope', 'horn', 'horror', 'horse', 'hospital', 'host', 'hotel', 'hour', 'hover', 'hub', 'huge', 'human', 'humble', 'humor', 'hundred', 'hungry', 'hunt', 'hurdle', 'hurry', 'hurt', 'husband', 'hybrid', 'ice', 'icon', 'idea', 'identify', 'idle', 'ignore', 'ill', 'illegal', 'illness', 'image', 'imitate', 'immense', 'immune', 'impact', 'impose', 'improve', 'impulse', 'inch', 'include', 'income', 'increase', 'index', 'indicate', 'indoor', 'industry', 'infant', 'inflict', 'inform', 'inhale', 'inherit', 'initial', 'inject', 'injury', 'inmate', 'inner', 'innocent', 'input', 'inquiry', 'insane', 'insect', 'inside', 'inspire', 'install', 'intact', 'interest', 'into', 'invest', 'invite', 'involve', 'iron', 'island', 'isolate', 'issue', 'item', 'ivory', 'jacket', 'jaguar', 'jar', 'jazz', 'jealous', 'jeans', 'jelly', 'jewel', 'job', 'join', 'joke', 'journey', 'joy', 'judge', 'juice', 'jump', 'jungle', 'junior', 'junk', 'just', 'kangaroo', 'keen', 'keep', 'ketchup', 'key', 'kick', 'kid', 'kidney', 'kind', 'kingdom', 'kiss', 'kit', 'kitchen', 'kite', 'kitten', 'kiwi', 'knee', 'knife', 'knock', 'know', 'lab', 'label', 'labor', 'ladder', 'lady', 'lake', 'lamp', 'language', 'laptop', 'large', 'later', 'latin', 'laugh', 'laundry', 'lava', 'law', 'lawn', 'lawsuit', 'layer', 'lazy', 'leader', 'leaf', 'learn', 'leave', 'lecture', 'left', 'leg', 'legal', 'legend', 'leisure', 'lemon', 'lend', 'length', 'lens', 'leopard', 'lesson', 'letter', 'level', 'liar', 'liberty', 'library', 'license', 'life', 'lift', 'light', 'like', 'limb', 'limit', 'link', 'lion', 'liquid', 'list', 'little', 'live', 'lizard', 'load', 'loan', 'lobster', 'local', 'lock', 'logic', 'lonely', 'long', 'loop', 'lottery', 'loud', 'lounge', 'love', 'loyal', 'lucky', 'luggage', 'lumber', 'lunar', 'lunch', 'luxury', 'lyrics', 'machine', 'mad', 'magic', 'magnet', 'maid', 'mail', 'main', 'major', 'make', 'mammal', 'man', 'manage', 'mandate', 'mango', 'mansion', 'manual', 'maple', 'marble', 'march', 'margin', 'marine', 'market', 'marriage', 'mask', 'mass', 'master', 'match', 'material', 'math', 'matrix', 'matter', 'maximum', 'maze', 'meadow', 'mean', 'measure', 'meat', 'mechanic', 'medal', 'media', 'melody', 'melt', 'member', 'memory', 'mention', 'menu', 'mercy', 'merge', 'merit', 'merry', 'mesh', 'message', 'metal', 'method', 'middle', 'midnight', 'milk', 'million', 'mimic', 'mind', 'minimum', 'minor', 'minute', 'miracle', 'mirror', 'misery', 'miss', 'mistake', 'mix', 'mixed', 'mixture', 'mobile', 'model', 'modify', 'mom', 'moment', 'monitor', 'monkey', 'monster', 'month', 'moon', 'moral', 'more', 'morning', 'mosquito', 'mother', 'motion', 'motor', 'mountain', 'mouse', 'move', 'movie', 'much', 'muffin', 'mule', 'multiply', 'muscle', 'museum', 'mushroom', 'music', 'must', 'mutual', 'myself', 'mystery', 'myth', 'naive', 'name', 'napkin', 'narrow', 'nasty', 'nation', 'nature', 'near', 'neck', 'need', 'negative', 'neglect', 'neither', 'nephew', 'nerve', 'nest', 'net', 'network', 'neutral', 'never', 'news', 'next', 'nice', 'night', 'noble', 'noise', 'nominee', 'noodle', 'normal', 'north', 'nose', 'notable', 'note', 'nothing', 'notice', 'novel', 'now', 'nuclear', 'number', 'nurse', 'nut', 'oak', 'obey', 'object', 'oblige', 'obscure', 'observe', 'obtain', 'obvious', 'occur', 'ocean', 'october', 'odor', 'off', 'offer', 'office', 'often', 'oil', 'okay', 'old', 'olive', 'olympic', 'omit', 'once', 'one', 'onion', 'online', 'only', 'open', 'opera', 'opinion', 'oppose', 'option', 'orange', 'orbit', 'orchard', 'order', 'ordinary', 'organ', 'orient', 'original', 'orphan', 'ostrich', 'other', 'outdoor', 'outer', 'output', 'outside', 'oval', 'oven', 'over', 'own', 'owner', 'oxygen', 'oyster', 'ozone', 'pact', 'paddle', 'page', 'pair', 'palace', 'palm', 'panda', 'panel', 'panic', 'panther', 'paper', 'parade', 'parent', 'park', 'parrot', 'party', 'pass', 'patch', 'path', 'patient', 'patrol', 'pattern', 'pause', 'pave', 'payment', 'peace', 'peanut', 'pear', 'peasant', 'pelican', 'pen', 'penalty', 'pencil', 'people', 'pepper', 'perfect', 'permit', 'person', 'pet', 'phone', 'photo', 'phrase', 'physical', 'piano', 'picnic', 'picture', 'piece', 'pig', 'pigeon', 'pill', 'pilot', 'pink', 'pioneer', 'pipe', 'pistol', 'pitch', 'pizza', 'place', 'planet', 'plastic', 'plate', 'play', 'please', 'pledge', 'pluck', 'plug', 'plunge', 'poem', 'poet', 'point', 'polar', 'pole', 'police', 'pond', 'pony', 'pool', 'popular', 'portion', 'position', 'possible', 'post', 'potato', 'pottery', 'poverty', 'powder', 'power', 'practice', 'praise', 'predict', 'prefer', 'prepare', 'present', 'pretty', 'prevent', 'price', 'pride', 'primary', 'print', 'priority', 'prison', 'private', 'prize', 'problem', 'process', 'produce', 'profit', 'program', 'project', 'promote', 'proof', 'property', 'prosper', 'protect', 'proud', 'provide', 'public', 'pudding', 'pull', 'pulp', 'pulse', 'pumpkin', 'punch', 'pupil', 'puppy', 'purchase', 'purity', 'purpose', 'purse', 'push', 'put', 'puzzle', 'pyramid', 'quality', 'quantum', 'quarter', 'question', 'quick', 'quit', 'quiz', 'quote', 'rabbit', 'raccoon', 'race', 'rack', 'radar', 'radio', 'rail', 'rain', 'raise', 'rally', 'ramp', 'ranch', 'random', 'range', 'rapid', 'rare', 'rate', 'rather', 'raven', 'raw', 'razor', 'ready', 'real', 'reason', 'rebel', 'rebuild', 'recall', 'receive', 'recipe', 'record', 'recycle', 'reduce', 'reflect', 'reform', 'refuse', 'region', 'regret', 'regular', 'reject', 'relax', 'release', 'relief', 'rely', 'remain', 'remember', 'remind', 'remove', 'render', 'renew', 'rent', 'reopen', 'repair', 'repeat', 'replace', 'report', 'require', 'rescue', 'resemble', 'resist', 'resource', 'response', 'result', 'retire', 'retreat', 'return', 'reunion', 'reveal', 'review', 'reward', 'rhythm', 'rib', 'ribbon', 'rice', 'rich', 'ride', 'ridge', 'rifle', 'right', 'rigid', 'ring', 'riot', 'ripple', 'risk', 'ritual', 'rival', 'river', 'road', 'roast', 'robot', 'robust', 'rocket', 'romance', 'roof', 'rookie', 'room', 'rose', 'rotate', 'rough', 'round', 'route', 'royal', 'rubber', 'rude', 'rug', 'rule', 'run', 'runway', 'rural', 'sad', 'saddle', 'sadness', 'safe', 'sail', 'salad', 'salmon', 'salon', 'salt', 'salute', 'same', 'sample', 'sand', 'satisfy', 'satoshi', 'sauce', 'sausage', 'save', 'say', 'scale', 'scan', 'scare', 'scatter', 'scene', 'scheme', 'school', 'science', 'scissors', 'scorpion', 'scout', 'scrap', 'screen', 'script', 'scrub', 'sea', 'search', 'season', 'seat', 'second', 'secret', 'section', 'security', 'seed', 'seek', 'segment', 'select', 'sell', 'seminar', 'senior', 'sense', 'sentence', 'series', 'service', 'session', 'settle', 'setup', 'seven', 'shadow', 'shaft', 'shallow', 'share', 'shed', 'shell', 'sheriff', 'shield', 'shift', 'shine', 'ship', 'shiver', 'shock', 'shoe', 'shoot', 'shop', 'short', 'shoulder', 'shove', 'shrimp', 'shrug', 'shuffle', 'shy', 'sibling', 'sick', 'side', 'siege', 'sight', 'sign', 'silent', 'silk', 'silly', 'silver', 'similar', 'simple', 'since', 'sing', 'siren', 'sister', 'situate', 'six', 'size', 'skate', 'sketch', 'ski', 'skill', 'skin', 'skirt', 'skull', 'slab', 'slam', 'sleep', 'slender', 'slice', 'slide', 'slight', 'slim', 'slogan', 'slot', 'slow', 'slush', 'small', 'smart', 'smile', 'smoke', 'smooth', 'snack', 'snake', 'snap', 'sniff', 'snow', 'soap', 'soccer', 'social', 'sock', 'soda', 'soft', 'solar', 'soldier', 'solid', 'solution', 'solve', 'someone', 'song', 'soon', 'sorry', 'sort', 'soul', 'sound', 'soup', 'source', 'south', 'space', 'spare', 'spatial', 'spawn', 'speak', 'special', 'speed', 'spell', 'spend', 'sphere', 'spice', 'spider', 'spike', 'spin', 'spirit', 'split', 'spoil', 'sponsor', 'spoon', 'sport', 'spot', 'spray', 'spread', 'spring', 'spy', 'square', 'squeeze', 'squirrel', 'stable', 'stadium', 'staff', 'stage', 'stairs', 'stamp', 'stand', 'start', 'state', 'stay', 'steak', 'steel', 'stem', 'step', 'stereo', 'stick', 'still', 'sting', 'stock', 'stomach', 'stone', 'stool', 'story', 'stove', 'strategy', 'street', 'strike', 'strong', 'struggle', 'student', 'stuff', 'stumble', 'style', 'subject', 'submit', 'subway', 'success', 'such', 'sudden', 'suffer', 'sugar', 'suggest', 'suit', 'summer', 'sun', 'sunny', 'sunset', 'super', 'supply', 'supreme', 'sure', 'surface', 'surge', 'surprise', 'surround', 'survey', 'suspect', 'sustain', 'swallow', 'swamp', 'swap', 'swarm', 'swear', 'sweet', 'swift', 'swim', 'swing', 'switch', 'sword', 'symbol', 'symptom', 'syrup', 'system', 'table', 'tackle', 'tag', 'tail', 'talent', 'talk', 'tank', 'tape', 'target', 'task', 'taste', 'tattoo', 'taxi', 'teach', 'team', 'tell', 'ten', 'tenant', 'tennis', 'tent', 'term', 'test', 'text', 'thank', 'that', 'theme', 'then', 'theory', 'there', 'they', 'thing', 'this', 'thought', 'three', 'thrive', 'throw', 'thumb', 'thunder', 'ticket', 'tide', 'tiger', 'tilt', 'timber', 'time', 'tiny', 'tip', 'tired', 'tissue', 'title', 'toast', 'tobacco', 'today', 'toddler', 'toe', 'together', 'toilet', 'token', 'tomato', 'tomorrow', 'tone', 'tongue', 'tonight', 'tool', 'tooth', 'top', 'topic', 'topple', 'torch', 'tornado', 'tortoise', 'toss', 'total', 'tourist', 'toward', 'tower', 'town', 'toy', 'track', 'trade', 'traffic', 'tragic', 'train', 'transfer', 'trap', 'trash', 'travel', 'tray', 'treat', 'tree', 'trend', 'trial', 'tribe', 'trick', 'trigger', 'trim', 'trip', 'trophy', 'trouble', 'truck', 'true', 'truly', 'trumpet', 'trust', 'truth', 'try', 'tube', 'tuition', 'tumble', 'tuna', 'tunnel', 'turkey', 'turn', 'turtle', 'twelve', 'twenty', 'twice', 'twin', 'twist', 'two', 'type', 'typical', 'ugly', 'umbrella', 'unable', 'unaware', 'uncle', 'uncover', 'under', 'undo', 'unfair', 'unfold', 'unhappy', 'uniform', 'unique', 'unit', 'universe', 'unknown', 'unlock', 'until', 'unusual', 'unveil', 'update', 'upgrade', 'uphold', 'upon', 'upper', 'upset', 'urban', 'urge', 'usage', 'use', 'used', 'useful', 'useless', 'usual', 'utility', 'vacant', 'vacuum', 'vague', 'valid', 'valley', 'valve', 'van', 'vanish', 'vapor', 'various', 'vast', 'vault', 'vehicle', 'velvet', 'vendor', 'venture', 'venue', 'verb', 'verify', 'version', 'very', 'vessel', 'veteran', 'viable', 'vibrant', 'vicious', 'victory', 'video', 'view', 'village', 'vintage', 'violin', 'virtual', 'virus', 'visa', 'visit', 'visual', 'vital', 'vivid', 'vocal', 'voice', 'void', 'volcano', 'volume', 'vote', 'voyage', 'wage', 'wagon', 'wait', 'walk', 'wall', 'walnut', 'want', 'warfare', 'warm', 'warrior', 'wash', 'wasp', 'waste', 'water', 'wave', 'way', 'wealth', 'weapon', 'wear', 'weasel', 'weather', 'web', 'wedding', 'weekend', 'weird', 'welcome', 'west', 'wet', 'whale', 'what', 'wheat', 'wheel', 'when', 'where', 'whip', 'whisper', 'wide', 'width', 'wife', 'wild', 'will', 'win', 'window', 'wine', 'wing', 'wink', 'winner', 'winter', 'wire', 'wisdom', 'wise', 'wish', 'witness', 'wolf', 'woman', 'wonder', 'wood', 'wool', 'word', 'work', 'world', 'worry', 'worth', 'wrap', 'wreck', 'wrestle', 'wrist', 'write', 'wrong', 'yard', 'year', 'yellow', 'you', 'young', 'youth', 'zebra', 'zero', 'zone', 'zoo'];
4007wordList.space = ' ';
4008
4009class Bip39 extends Struct {
4010 constructor(mnemonic, seed, wordlist = wordList) {
4011 super({
4012 mnemonic,
4013 seed
4014 });
4015 this.Wordlist = wordlist;
4016 }
4017
4018 toBw(bw) {
4019 if (!bw) {
4020 bw = new Bw();
4021 }
4022
4023 if (this.mnemonic) {
4024 const buf = Buffer.from(this.mnemonic);
4025 bw.writeVarIntNum(buf.length);
4026 bw.write(buf);
4027 } else {
4028 bw.writeVarIntNum(0);
4029 }
4030
4031 if (this.seed) {
4032 bw.writeVarIntNum(this.seed.length);
4033 bw.write(this.seed);
4034 } else {
4035 bw.writeVarIntNum(0);
4036 }
4037
4038 return bw;
4039 }
4040
4041 fromBr(br) {
4042 const mnemoniclen = br.readVarIntNum();
4043
4044 if (mnemoniclen > 0) {
4045 this.mnemonic = br.read(mnemoniclen).toString();
4046 }
4047
4048 const seedlen = br.readVarIntNum();
4049
4050 if (seedlen > 0) {
4051 this.seed = br.read(seedlen);
4052 }
4053
4054 return this;
4055 }
4056
4057 fromRandom(bits) {
4058 if (!bits) {
4059 bits = 128;
4060 }
4061
4062 if (bits % 32 !== 0) {
4063 throw new Error('bits must be multiple of 32');
4064 }
4065
4066 if (bits < 128) {
4067 throw new Error('bits must be at least 128');
4068 }
4069
4070 const buf = Random.getRandomBuffer(bits / 8);
4071 this.entropy2Mnemonic(buf);
4072 this.mnemonic2Seed();
4073 return this;
4074 }
4075
4076 static fromRandom(bits) {
4077 return new this().fromRandom(bits);
4078 }
4079
4080 async asyncFromRandom(bits) {
4081 if (!bits) {
4082 bits = 128;
4083 }
4084
4085 const buf = Random.getRandomBuffer(bits / 8);
4086 let workersResult = await Workers.asyncObjectMethod(this, 'entropy2Mnemonic', [buf]);
4087 const bip39 = new Bip39().fromFastBuffer(workersResult.resbuf);
4088 workersResult = await Workers.asyncObjectMethod(bip39, 'mnemonic2Seed', []);
4089 return this.fromFastBuffer(workersResult.resbuf);
4090 }
4091
4092 static asyncFromRandom(bits) {
4093 return new this().asyncFromRandom(bits);
4094 }
4095
4096 fromEntropy(buf) {
4097 this.entropy2Mnemonic(buf);
4098 return this;
4099 }
4100
4101 static fromEntropy(buf) {
4102 return new this().fromEntropy(buf);
4103 }
4104
4105 async asyncFromEntropy(buf) {
4106 const workersResult = await Workers.asyncObjectMethod(this, 'fromEntropy', [buf]);
4107 return this.fromFastBuffer(workersResult.resbuf);
4108 }
4109
4110 static asyncFromEntropy(buf) {
4111 return new this().asyncFromEntropy(buf);
4112 }
4113
4114 fromString(mnemonic) {
4115 this.mnemonic = mnemonic;
4116 return this;
4117 }
4118
4119 toString() {
4120 return this.mnemonic;
4121 }
4122
4123 toSeed(passphrase) {
4124 this.mnemonic2Seed(passphrase);
4125 return this.seed;
4126 }
4127
4128 async asyncToSeed(passphrase) {
4129 if (passphrase === undefined) {
4130 passphrase = '';
4131 }
4132
4133 const args = [passphrase];
4134 const workersResult = await Workers.asyncObjectMethod(this, 'toSeed', args);
4135 return workersResult.resbuf;
4136 }
4137
4138 entropy2Mnemonic(buf) {
4139 if (!Buffer.isBuffer(buf) || buf.length < 128 / 8) {
4140 throw new Error('Entropy is less than 128 bits. It must be 128 bits or more.');
4141 }
4142
4143 const hash = Hash.sha256(buf);
4144 let bin = '';
4145 const bits = buf.length * 8;
4146
4147 for (let i = 0; i < buf.length; i++) {
4148 bin = bin + ('00000000' + buf[i].toString(2)).slice(-8);
4149 }
4150
4151 let hashbits = hash[0].toString(2);
4152 hashbits = ('00000000' + hashbits).slice(-8).slice(0, bits / 32);
4153 bin = bin + hashbits;
4154
4155 if (bin.length % 11 !== 0) {
4156 throw new Error('internal error - entropy not an even multiple of 11 bits - ' + bin.length);
4157 }
4158
4159 let mnemonic = '';
4160
4161 for (let i = 0; i < bin.length / 11; i++) {
4162 if (mnemonic !== '') {
4163 mnemonic = mnemonic + this.Wordlist.space;
4164 }
4165
4166 const wi = parseInt(bin.slice(i * 11, (i + 1) * 11), 2);
4167 mnemonic = mnemonic + this.Wordlist[wi];
4168 }
4169
4170 this.mnemonic = mnemonic;
4171 return this;
4172 }
4173
4174 check() {
4175 const mnemonic = this.mnemonic;
4176 const words = mnemonic.split(this.Wordlist.space);
4177 let bin = '';
4178
4179 for (let i = 0; i < words.length; i++) {
4180 const ind = this.Wordlist.indexOf(words[i]);
4181
4182 if (ind < 0) {
4183 return false;
4184 }
4185
4186 bin = bin + ('00000000000' + ind.toString(2)).slice(-11);
4187 }
4188
4189 if (bin.length % 11 !== 0) {
4190 throw new Error('internal error - entropy not an even multiple of 11 bits - ' + bin.length);
4191 }
4192
4193 const cs = bin.length / 33;
4194 const hashBits = bin.slice(-cs);
4195 const nonhashBits = bin.slice(0, bin.length - cs);
4196 const buf = Buffer.alloc(nonhashBits.length / 8);
4197
4198 for (let i = 0; i < nonhashBits.length / 8; i++) {
4199 buf.writeUInt8(parseInt(bin.slice(i * 8, (i + 1) * 8), 2), i);
4200 }
4201
4202 const hash = Hash.sha256(buf);
4203 let expectedHashBits = hash[0].toString(2);
4204 expectedHashBits = ('00000000' + expectedHashBits).slice(-8).slice(0, cs);
4205 return expectedHashBits === hashBits;
4206 }
4207
4208 mnemonic2Seed(passphrase = '') {
4209 let mnemonic = this.mnemonic;
4210
4211 if (!this.check()) {
4212 throw new Error('Mnemonic does not pass the check - was the mnemonic typed incorrectly? Are there extra spaces?');
4213 }
4214
4215 if (typeof passphrase !== 'string') {
4216 throw new Error('passphrase must be a string or undefined');
4217 }
4218
4219 mnemonic = mnemonic.normalize('NFKD');
4220 passphrase = passphrase.normalize('NFKD');
4221 const mbuf = Buffer.from(mnemonic);
4222 const pbuf = Buffer.concat([Buffer.from('mnemonic'), Buffer.from(passphrase)]);
4223 this.seed = pbkdf2.pbkdf2Sync(mbuf, pbuf, 2048, 64, 'sha512');
4224 return this;
4225 }
4226
4227 isValid(passphrase = '') {
4228 let isValid;
4229
4230 try {
4231 isValid = !!this.mnemonic2Seed(passphrase);
4232 } catch (err) {
4233 isValid = false;
4234 }
4235
4236 return isValid;
4237 }
4238
4239 static isValid(mnemonic, passphrase = '') {
4240 return new Bip39(mnemonic).isValid(passphrase);
4241 }
4242
4243}
4244
4245const wordList$1 = ['あいこくしん', 'あいさつ', 'あいだ', 'あおぞら', 'あかちゃん', 'あきる', 'あけがた', 'あける', 'あこがれる', 'あさい', 'あさひ', 'あしあと', 'あじわう', 'あずかる', 'あずき', 'あそぶ', 'あたえる', 'あたためる', 'あたりまえ', 'あたる', 'あつい', 'あつかう', 'あっしゅく', 'あつまり', 'あつめる', 'あてな', 'あてはまる', 'あひる', 'あぶら', 'あぶる', 'あふれる', 'あまい', 'あまど', 'あまやかす', 'あまり', 'あみもの', 'あめりか', 'あやまる', 'あゆむ', 'あらいぐま', 'あらし', 'あらすじ', 'あらためる', 'あらゆる', 'あらわす', 'ありがとう', 'あわせる', 'あわてる', 'あんい', 'あんがい', 'あんこ', 'あんぜん', 'あんてい', 'あんない', 'あんまり', 'いいだす', 'いおん', 'いがい', 'いがく', 'いきおい', 'いきなり', 'いきもの', 'いきる', 'いくじ', 'いくぶん', 'いけばな', 'いけん', 'いこう', 'いこく', 'いこつ', 'いさましい', 'いさん', 'いしき', 'いじゅう', 'いじょう', 'いじわる', 'いずみ', 'いずれ', 'いせい', 'いせえび', 'いせかい', 'いせき', 'いぜん', 'いそうろう', 'いそがしい', 'いだい', 'いだく', 'いたずら', 'いたみ', 'いたりあ', 'いちおう', 'いちじ', 'いちど', 'いちば', 'いちぶ', 'いちりゅう', 'いつか', 'いっしゅん', 'いっせい', 'いっそう', 'いったん', 'いっち', 'いってい', 'いっぽう', 'いてざ', 'いてん', 'いどう', 'いとこ', 'いない', 'いなか', 'いねむり', 'いのち', 'いのる', 'いはつ', 'いばる', 'いはん', 'いびき', 'いひん', 'いふく', 'いへん', 'いほう', 'いみん', 'いもうと', 'いもたれ', 'いもり', 'いやがる', 'いやす', 'いよかん', 'いよく', 'いらい', 'いらすと', 'いりぐち', 'いりょう', 'いれい', 'いれもの', 'いれる', 'いろえんぴつ', 'いわい', 'いわう', 'いわかん', 'いわば', 'いわゆる', 'いんげんまめ', 'いんさつ', 'いんしょう', 'いんよう', 'うえき', 'うえる', 'うおざ', 'うがい', 'うかぶ', 'うかべる', 'うきわ', 'うくらいな', 'うくれれ', 'うけたまわる', 'うけつけ', 'うけとる', 'うけもつ', 'うける', 'うごかす', 'うごく', 'うこん', 'うさぎ', 'うしなう', 'うしろがみ', 'うすい', 'うすぎ', 'うすぐらい', 'うすめる', 'うせつ', 'うちあわせ', 'うちがわ', 'うちき', 'うちゅう', 'うっかり', 'うつくしい', 'うったえる', 'うつる', 'うどん', 'うなぎ', 'うなじ', 'うなずく', 'うなる', 'うねる', 'うのう', 'うぶげ', 'うぶごえ', 'うまれる', 'うめる', 'うもう', 'うやまう', 'うよく', 'うらがえす', 'うらぐち', 'うらない', 'うりあげ', 'うりきれ', 'うるさい', 'うれしい', 'うれゆき', 'うれる', 'うろこ', 'うわき', 'うわさ', 'うんこう', 'うんちん', 'うんてん', 'うんどう', 'えいえん', 'えいが', 'えいきょう', 'えいご', 'えいせい', 'えいぶん', 'えいよう', 'えいわ', 'えおり', 'えがお', 'えがく', 'えきたい', 'えくせる', 'えしゃく', 'えすて', 'えつらん', 'えのぐ', 'えほうまき', 'えほん', 'えまき', 'えもじ', 'えもの', 'えらい', 'えらぶ', 'えりあ', 'えんえん', 'えんかい', 'えんぎ', 'えんげき', 'えんしゅう', 'えんぜつ', 'えんそく', 'えんちょう', 'えんとつ', 'おいかける', 'おいこす', 'おいしい', 'おいつく', 'おうえん', 'おうさま', 'おうじ', 'おうせつ', 'おうたい', 'おうふく', 'おうべい', 'おうよう', 'おえる', 'おおい', 'おおう', 'おおどおり', 'おおや', 'おおよそ', 'おかえり', 'おかず', 'おがむ', 'おかわり', 'おぎなう', 'おきる', 'おくさま', 'おくじょう', 'おくりがな', 'おくる', 'おくれる', 'おこす', 'おこなう', 'おこる', 'おさえる', 'おさない', 'おさめる', 'おしいれ', 'おしえる', 'おじぎ', 'おじさん', 'おしゃれ', 'おそらく', 'おそわる', 'おたがい', 'おたく', 'おだやか', 'おちつく', 'おっと', 'おつり', 'おでかけ', 'おとしもの', 'おとなしい', 'おどり', 'おどろかす', 'おばさん', 'おまいり', 'おめでとう', 'おもいで', 'おもう', 'おもたい', 'おもちゃ', 'おやつ', 'おやゆび', 'およぼす', 'おらんだ', 'おろす', 'おんがく', 'おんけい', 'おんしゃ', 'おんせん', 'おんだん', 'おんちゅう', 'おんどけい', 'かあつ', 'かいが', 'がいき', 'がいけん', 'がいこう', 'かいさつ', 'かいしゃ', 'かいすいよく', 'かいぜん', 'かいぞうど', 'かいつう', 'かいてん', 'かいとう', 'かいふく', 'がいへき', 'かいほう', 'かいよう', 'がいらい', 'かいわ', 'かえる', 'かおり', 'かかえる', 'かがく', 'かがし', 'かがみ', 'かくご', 'かくとく', 'かざる', 'がぞう', 'かたい', 'かたち', 'がちょう', 'がっきゅう', 'がっこう', 'がっさん', 'がっしょう', 'かなざわし', 'かのう', 'がはく', 'かぶか', 'かほう', 'かほご', 'かまう', 'かまぼこ', 'かめれおん', 'かゆい', 'かようび', 'からい', 'かるい', 'かろう', 'かわく', 'かわら', 'がんか', 'かんけい', 'かんこう', 'かんしゃ', 'かんそう', 'かんたん', 'かんち', 'がんばる', 'きあい', 'きあつ', 'きいろ', 'ぎいん', 'きうい', 'きうん', 'きえる', 'きおう', 'きおく', 'きおち', 'きおん', 'きかい', 'きかく', 'きかんしゃ', 'ききて', 'きくばり', 'きくらげ', 'きけんせい', 'きこう', 'きこえる', 'きこく', 'きさい', 'きさく', 'きさま', 'きさらぎ', 'ぎじかがく', 'ぎしき', 'ぎじたいけん', 'ぎじにってい', 'ぎじゅつしゃ', 'きすう', 'きせい', 'きせき', 'きせつ', 'きそう', 'きぞく', 'きぞん', 'きたえる', 'きちょう', 'きつえん', 'ぎっちり', 'きつつき', 'きつね', 'きてい', 'きどう', 'きどく', 'きない', 'きなが', 'きなこ', 'きぬごし', 'きねん', 'きのう', 'きのした', 'きはく', 'きびしい', 'きひん', 'きふく', 'きぶん', 'きぼう', 'きほん', 'きまる', 'きみつ', 'きむずかしい', 'きめる', 'きもだめし', 'きもち', 'きもの', 'きゃく', 'きやく', 'ぎゅうにく', 'きよう', 'きょうりゅう', 'きらい', 'きらく', 'きりん', 'きれい', 'きれつ', 'きろく', 'ぎろん', 'きわめる', 'ぎんいろ', 'きんかくじ', 'きんじょ', 'きんようび', 'ぐあい', 'くいず', 'くうかん', 'くうき', 'くうぐん', 'くうこう', 'ぐうせい', 'くうそう', 'ぐうたら', 'くうふく', 'くうぼ', 'くかん', 'くきょう', 'くげん', 'ぐこう', 'くさい', 'くさき', 'くさばな', 'くさる', 'くしゃみ', 'くしょう', 'くすのき', 'くすりゆび', 'くせげ', 'くせん', 'ぐたいてき', 'くださる', 'くたびれる', 'くちこみ', 'くちさき', 'くつした', 'ぐっすり', 'くつろぐ', 'くとうてん', 'くどく', 'くなん', 'くねくね', 'くのう', 'くふう', 'くみあわせ', 'くみたてる', 'くめる', 'くやくしょ', 'くらす', 'くらべる', 'くるま', 'くれる', 'くろう', 'くわしい', 'ぐんかん', 'ぐんしょく', 'ぐんたい', 'ぐんて', 'けあな', 'けいかく', 'けいけん', 'けいこ', 'けいさつ', 'げいじゅつ', 'けいたい', 'げいのうじん', 'けいれき', 'けいろ', 'けおとす', 'けおりもの', 'げきか', 'げきげん', 'げきだん', 'げきちん', 'げきとつ', 'げきは', 'げきやく', 'げこう', 'げこくじょう', 'げざい', 'けさき', 'げざん', 'けしき', 'けしごむ', 'けしょう', 'げすと', 'けたば', 'けちゃっぷ', 'けちらす', 'けつあつ', 'けつい', 'けつえき', 'けっこん', 'けつじょ', 'けっせき', 'けってい', 'けつまつ', 'げつようび', 'げつれい', 'けつろん', 'げどく', 'けとばす', 'けとる', 'けなげ', 'けなす', 'けなみ', 'けぬき', 'げねつ', 'けねん', 'けはい', 'げひん', 'けぶかい', 'げぼく', 'けまり', 'けみかる', 'けむし', 'けむり', 'けもの', 'けらい', 'けろけろ', 'けわしい', 'けんい', 'けんえつ', 'けんお', 'けんか', 'げんき', 'けんげん', 'けんこう', 'けんさく', 'けんしゅう', 'けんすう', 'げんそう', 'けんちく', 'けんてい', 'けんとう', 'けんない', 'けんにん', 'げんぶつ', 'けんま', 'けんみん', 'けんめい', 'けんらん', 'けんり', 'こあくま', 'こいぬ', 'こいびと', 'ごうい', 'こうえん', 'こうおん', 'こうかん', 'ごうきゅう', 'ごうけい', 'こうこう', 'こうさい', 'こうじ', 'こうすい', 'ごうせい', 'こうそく', 'こうたい', 'こうちゃ', 'こうつう', 'こうてい', 'こうどう', 'こうない', 'こうはい', 'ごうほう', 'ごうまん', 'こうもく', 'こうりつ', 'こえる', 'こおり', 'ごかい', 'ごがつ', 'ごかん', 'こくご', 'こくさい', 'こくとう', 'こくない', 'こくはく', 'こぐま', 'こけい', 'こける', 'ここのか', 'こころ', 'こさめ', 'こしつ', 'こすう', 'こせい', 'こせき', 'こぜん', 'こそだて', 'こたい', 'こたえる', 'こたつ', 'こちょう', 'こっか', 'こつこつ', 'こつばん', 'こつぶ', 'こてい', 'こてん', 'ことがら', 'ことし', 'ことば', 'ことり', 'こなごな', 'こねこね', 'このまま', 'このみ', 'このよ', 'ごはん', 'こひつじ', 'こふう', 'こふん', 'こぼれる', 'ごまあぶら', 'こまかい', 'ごますり', 'こまつな', 'こまる', 'こむぎこ', 'こもじ', 'こもち', 'こもの', 'こもん', 'こやく', 'こやま', 'こゆう', 'こゆび', 'こよい', 'こよう', 'こりる', 'これくしょん', 'ころっけ', 'こわもて', 'こわれる', 'こんいん', 'こんかい', 'こんき', 'こんしゅう', 'こんすい', 'こんだて', 'こんとん', 'こんなん', 'こんびに', 'こんぽん', 'こんまけ', 'こんや', 'こんれい', 'こんわく', 'ざいえき', 'さいかい', 'さいきん', 'ざいげん', 'ざいこ', 'さいしょ', 'さいせい', 'ざいたく', 'ざいちゅう', 'さいてき', 'ざいりょう', 'さうな', 'さかいし', 'さがす', 'さかな', 'さかみち', 'さがる', 'さぎょう', 'さくし', 'さくひん', 'さくら', 'さこく', 'さこつ', 'さずかる', 'ざせき', 'さたん', 'さつえい', 'ざつおん', 'ざっか', 'ざつがく', 'さっきょく', 'ざっし', 'さつじん', 'ざっそう', 'さつたば', 'さつまいも', 'さてい', 'さといも', 'さとう', 'さとおや', 'さとし', 'さとる', 'さのう', 'さばく', 'さびしい', 'さべつ', 'さほう', 'さほど', 'さます', 'さみしい', 'さみだれ', 'さむけ', 'さめる', 'さやえんどう', 'さゆう', 'さよう', 'さよく', 'さらだ', 'ざるそば', 'さわやか', 'さわる', 'さんいん', 'さんか', 'さんきゃく', 'さんこう', 'さんさい', 'ざんしょ', 'さんすう', 'さんせい', 'さんそ', 'さんち', 'さんま', 'さんみ', 'さんらん', 'しあい', 'しあげ', 'しあさって', 'しあわせ', 'しいく', 'しいん', 'しうち', 'しえい', 'しおけ', 'しかい', 'しかく', 'じかん', 'しごと', 'しすう', 'じだい', 'したうけ', 'したぎ', 'したて', 'したみ', 'しちょう', 'しちりん', 'しっかり', 'しつじ', 'しつもん', 'してい', 'してき', 'してつ', 'じてん', 'じどう', 'しなぎれ', 'しなもの', 'しなん', 'しねま', 'しねん', 'しのぐ', 'しのぶ', 'しはい', 'しばかり', 'しはつ', 'しはらい', 'しはん', 'しひょう', 'しふく', 'じぶん', 'しへい', 'しほう', 'しほん', 'しまう', 'しまる', 'しみん', 'しむける', 'じむしょ', 'しめい', 'しめる', 'しもん', 'しゃいん', 'しゃうん', 'しゃおん', 'じゃがいも', 'しやくしょ', 'しゃくほう', 'しゃけん', 'しゃこ', 'しゃざい', 'しゃしん', 'しゃせん', 'しゃそう', 'しゃたい', 'しゃちょう', 'しゃっきん', 'じゃま', 'しゃりん', 'しゃれい', 'じゆう', 'じゅうしょ', 'しゅくはく', 'じゅしん', 'しゅっせき', 'しゅみ', 'しゅらば', 'じゅんばん', 'しょうかい', 'しょくたく', 'しょっけん', 'しょどう', 'しょもつ', 'しらせる', 'しらべる', 'しんか', 'しんこう', 'じんじゃ', 'しんせいじ', 'しんちく', 'しんりん', 'すあげ', 'すあし', 'すあな', 'ずあん', 'すいえい', 'すいか', 'すいとう', 'ずいぶん', 'すいようび', 'すうがく', 'すうじつ', 'すうせん', 'すおどり', 'すきま', 'すくう', 'すくない', 'すける', 'すごい', 'すこし', 'ずさん', 'すずしい', 'すすむ', 'すすめる', 'すっかり', 'ずっしり', 'ずっと', 'すてき', 'すてる', 'すねる', 'すのこ', 'すはだ', 'すばらしい', 'ずひょう', 'ずぶぬれ', 'すぶり', 'すふれ', 'すべて', 'すべる', 'ずほう', 'すぼん', 'すまい', 'すめし', 'すもう', 'すやき', 'すらすら', 'するめ', 'すれちがう', 'すろっと', 'すわる', 'すんぜん', 'すんぽう', 'せあぶら', 'せいかつ', 'せいげん', 'せいじ', 'せいよう', 'せおう', 'せかいかん', 'せきにん', 'せきむ', 'せきゆ', 'せきらんうん', 'せけん', 'せこう', 'せすじ', 'せたい', 'せたけ', 'せっかく', 'せっきゃく', 'ぜっく', 'せっけん', 'せっこつ', 'せっさたくま', 'せつぞく', 'せつだん', 'せつでん', 'せっぱん', 'せつび', 'せつぶん', 'せつめい', 'せつりつ', 'せなか', 'せのび', 'せはば', 'せびろ', 'せぼね', 'せまい', 'せまる', 'せめる', 'せもたれ', 'せりふ', 'ぜんあく', 'せんい', 'せんえい', 'せんか', 'せんきょ', 'せんく', 'せんげん', 'ぜんご', 'せんさい', 'せんしゅ', 'せんすい', 'せんせい', 'せんぞ', 'せんたく', 'せんちょう', 'せんてい', 'せんとう', 'せんぬき', 'せんねん', 'せんぱい', 'ぜんぶ', 'ぜんぽう', 'せんむ', 'せんめんじょ', 'せんもん', 'せんやく', 'せんゆう', 'せんよう', 'ぜんら', 'ぜんりゃく', 'せんれい', 'せんろ', 'そあく', 'そいとげる', 'そいね', 'そうがんきょう', 'そうき', 'そうご', 'そうしん', 'そうだん', 'そうなん', 'そうび', 'そうめん', 'そうり', 'そえもの', 'そえん', 'そがい', 'そげき', 'そこう', 'そこそこ', 'そざい', 'そしな', 'そせい', 'そせん', 'そそぐ', 'そだてる', 'そつう', 'そつえん', 'そっかん', 'そつぎょう', 'そっけつ', 'そっこう', 'そっせん', 'そっと', 'そとがわ', 'そとづら', 'そなえる', 'そなた', 'そふぼ', 'そぼく', 'そぼろ', 'そまつ', 'そまる', 'そむく', 'そむりえ', 'そめる', 'そもそも', 'そよかぜ', 'そらまめ', 'そろう', 'そんかい', 'そんけい', 'そんざい', 'そんしつ', 'そんぞく', 'そんちょう', 'ぞんび', 'ぞんぶん', 'そんみん', 'たあい', 'たいいん', 'たいうん', 'たいえき', 'たいおう', 'だいがく', 'たいき', 'たいぐう', 'たいけん', 'たいこ', 'たいざい', 'だいじょうぶ', 'だいすき', 'たいせつ', 'たいそう', 'だいたい', 'たいちょう', 'たいてい', 'だいどころ', 'たいない', 'たいねつ', 'たいのう', 'たいはん', 'だいひょう', 'たいふう', 'たいへん', 'たいほ', 'たいまつばな', 'たいみんぐ', 'たいむ', 'たいめん', 'たいやき', 'たいよう', 'たいら', 'たいりょく', 'たいる', 'たいわん', 'たうえ', 'たえる', 'たおす', 'たおる', 'たおれる', 'たかい', 'たかね', 'たきび', 'たくさん', 'たこく', 'たこやき', 'たさい', 'たしざん', 'だじゃれ', 'たすける', 'たずさわる', 'たそがれ', 'たたかう', 'たたく', 'ただしい', 'たたみ', 'たちばな', 'だっかい', 'だっきゃく', 'だっこ', 'だっしゅつ', 'だったい', 'たてる', 'たとえる', 'たなばた', 'たにん', 'たぬき', 'たのしみ', 'たはつ', 'たぶん', 'たべる', 'たぼう', 'たまご', 'たまる', 'だむる', 'ためいき', 'ためす', 'ためる', 'たもつ', 'たやすい', 'たよる', 'たらす', 'たりきほんがん', 'たりょう', 'たりる', 'たると', 'たれる', 'たれんと', 'たろっと', 'たわむれる', 'だんあつ', 'たんい', 'たんおん', 'たんか', 'たんき', 'たんけん', 'たんご', 'たんさん', 'たんじょうび', 'だんせい', 'たんそく', 'たんたい', 'だんち', 'たんてい', 'たんとう', 'だんな', 'たんにん', 'だんねつ', 'たんのう', 'たんぴん', 'だんぼう', 'たんまつ', 'たんめい', 'だんれつ', 'だんろ', 'だんわ', 'ちあい', 'ちあん', 'ちいき', 'ちいさい', 'ちえん', 'ちかい', 'ちから', 'ちきゅう', 'ちきん', 'ちけいず', 'ちけん', 'ちこく', 'ちさい', 'ちしき', 'ちしりょう', 'ちせい', 'ちそう', 'ちたい', 'ちたん', 'ちちおや', 'ちつじょ', 'ちてき', 'ちてん', 'ちぬき', 'ちぬり', 'ちのう', 'ちひょう', 'ちへいせん', 'ちほう', 'ちまた', 'ちみつ', 'ちみどろ', 'ちめいど', 'ちゃんこなべ', 'ちゅうい', 'ちゆりょく', 'ちょうし', 'ちょさくけん', 'ちらし', 'ちらみ', 'ちりがみ', 'ちりょう', 'ちるど', 'ちわわ', 'ちんたい', 'ちんもく', 'ついか', 'ついたち', 'つうか', 'つうじょう', 'つうはん', 'つうわ', 'つかう', 'つかれる', 'つくね', 'つくる', 'つけね', 'つける', 'つごう', 'つたえる', 'つづく', 'つつじ', 'つつむ', 'つとめる', 'つながる', 'つなみ', 'つねづね', 'つのる', 'つぶす', 'つまらない', 'つまる', 'つみき', 'つめたい', 'つもり', 'つもる', 'つよい', 'つるぼ', 'つるみく', 'つわもの', 'つわり', 'てあし', 'てあて', 'てあみ', 'ていおん', 'ていか', 'ていき', 'ていけい', 'ていこく', 'ていさつ', 'ていし', 'ていせい', 'ていたい', 'ていど', 'ていねい', 'ていひょう', 'ていへん', 'ていぼう', 'てうち', 'ておくれ', 'てきとう', 'てくび', 'でこぼこ', 'てさぎょう', 'てさげ', 'てすり', 'てそう', 'てちがい', 'てちょう', 'てつがく', 'てつづき', 'でっぱ', 'てつぼう', 'てつや', 'でぬかえ', 'てぬき', 'てぬぐい', 'てのひら', 'てはい', 'てぶくろ', 'てふだ', 'てほどき', 'てほん', 'てまえ', 'てまきずし', 'てみじか', 'てみやげ', 'てらす', 'てれび', 'てわけ', 'てわたし', 'でんあつ', 'てんいん', 'てんかい', 'てんき', 'てんぐ', 'てんけん', 'てんごく', 'てんさい', 'てんし', 'てんすう', 'でんち', 'てんてき', 'てんとう', 'てんない', 'てんぷら', 'てんぼうだい', 'てんめつ', 'てんらんかい', 'でんりょく', 'でんわ', 'どあい', 'といれ', 'どうかん', 'とうきゅう', 'どうぐ', 'とうし', 'とうむぎ', 'とおい', 'とおか', 'とおく', 'とおす', 'とおる', 'とかい', 'とかす', 'ときおり', 'ときどき', 'とくい', 'とくしゅう', 'とくてん', 'とくに', 'とくべつ', 'とけい', 'とける', 'とこや', 'とさか', 'としょかん', 'とそう', 'とたん', 'とちゅう', 'とっきゅう', 'とっくん', 'とつぜん', 'とつにゅう', 'とどける', 'ととのえる', 'とない', 'となえる', 'となり', 'とのさま', 'とばす', 'どぶがわ', 'とほう', 'とまる', 'とめる', 'ともだち', 'ともる', 'どようび', 'とらえる', 'とんかつ', 'どんぶり', 'ないかく', 'ないこう', 'ないしょ', 'ないす', 'ないせん', 'ないそう', 'なおす', 'ながい', 'なくす', 'なげる', 'なこうど', 'なさけ', 'なたでここ', 'なっとう', 'なつやすみ', 'ななおし', 'なにごと', 'なにもの', 'なにわ', 'なのか', 'なふだ', 'なまいき', 'なまえ', 'なまみ', 'なみだ', 'なめらか', 'なめる', 'なやむ', 'ならう', 'ならび', 'ならぶ', 'なれる', 'なわとび', 'なわばり', 'にあう', 'にいがた', 'にうけ', 'におい', 'にかい', 'にがて', 'にきび', 'にくしみ', 'にくまん', 'にげる', 'にさんかたんそ', 'にしき', 'にせもの', 'にちじょう', 'にちようび', 'にっか', 'にっき', 'にっけい', 'にっこう', 'にっさん', 'にっしょく', 'にっすう', 'にっせき', 'にってい', 'になう', 'にほん', 'にまめ', 'にもつ', 'にやり', 'にゅういん', 'にりんしゃ', 'にわとり', 'にんい', 'にんか', 'にんき', 'にんげん', 'にんしき', 'にんずう', 'にんそう', 'にんたい', 'にんち', 'にんてい', 'にんにく', 'にんぷ', 'にんまり', 'にんむ', 'にんめい', 'にんよう', 'ぬいくぎ', 'ぬかす', 'ぬぐいとる', 'ぬぐう', 'ぬくもり', 'ぬすむ', 'ぬまえび', 'ぬめり', 'ぬらす', 'ぬんちゃく', 'ねあげ', 'ねいき', 'ねいる', 'ねいろ', 'ねぐせ', 'ねくたい', 'ねくら', 'ねこぜ', 'ねこむ', 'ねさげ', 'ねすごす', 'ねそべる', 'ねだん', 'ねつい', 'ねっしん', 'ねつぞう', 'ねったいぎょ', 'ねぶそく', 'ねふだ', 'ねぼう', 'ねほりはほり', 'ねまき', 'ねまわし', 'ねみみ', 'ねむい', 'ねむたい', 'ねもと', 'ねらう', 'ねわざ', 'ねんいり', 'ねんおし', 'ねんかん', 'ねんきん', 'ねんぐ', 'ねんざ', 'ねんし', 'ねんちゃく', 'ねんど', 'ねんぴ', 'ねんぶつ', 'ねんまつ', 'ねんりょう', 'ねんれい', 'のいず', 'のおづま', 'のがす', 'のきなみ', 'のこぎり', 'のこす', 'のこる', 'のせる', 'のぞく', 'のぞむ', 'のたまう', 'のちほど', 'のっく', 'のばす', 'のはら', 'のべる', 'のぼる', 'のみもの', 'のやま', 'のらいぬ', 'のらねこ', 'のりもの', 'のりゆき', 'のれん', 'のんき', 'ばあい', 'はあく', 'ばあさん', 'ばいか', 'ばいく', 'はいけん', 'はいご', 'はいしん', 'はいすい', 'はいせん', 'はいそう', 'はいち', 'ばいばい', 'はいれつ', 'はえる', 'はおる', 'はかい', 'ばかり', 'はかる', 'はくしゅ', 'はけん', 'はこぶ', 'はさみ', 'はさん', 'はしご', 'ばしょ', 'はしる', 'はせる', 'ぱそこん', 'はそん', 'はたん', 'はちみつ', 'はつおん', 'はっかく', 'はづき', 'はっきり', 'はっくつ', 'はっけん', 'はっこう', 'はっさん', 'はっしん', 'はったつ', 'はっちゅう', 'はってん', 'はっぴょう', 'はっぽう', 'はなす', 'はなび', 'はにかむ', 'はぶらし', 'はみがき', 'はむかう', 'はめつ', 'はやい', 'はやし', 'はらう', 'はろうぃん', 'はわい', 'はんい', 'はんえい', 'はんおん', 'はんかく', 'はんきょう', 'ばんぐみ', 'はんこ', 'はんしゃ', 'はんすう', 'はんだん', 'ぱんち', 'ぱんつ', 'はんてい', 'はんとし', 'はんのう', 'はんぱ', 'はんぶん', 'はんぺん', 'はんぼうき', 'はんめい', 'はんらん', 'はんろん', 'ひいき', 'ひうん', 'ひえる', 'ひかく', 'ひかり', 'ひかる', 'ひかん', 'ひくい', 'ひけつ', 'ひこうき', 'ひこく', 'ひさい', 'ひさしぶり', 'ひさん', 'びじゅつかん', 'ひしょ', 'ひそか', 'ひそむ', 'ひたむき', 'ひだり', 'ひたる', 'ひつぎ', 'ひっこし', 'ひっし', 'ひつじゅひん', 'ひっす', 'ひつぜん', 'ぴったり', 'ぴっちり', 'ひつよう', 'ひてい', 'ひとごみ', 'ひなまつり', 'ひなん', 'ひねる', 'ひはん', 'ひびく', 'ひひょう', 'ひほう', 'ひまわり', 'ひまん', 'ひみつ', 'ひめい', 'ひめじし', 'ひやけ', 'ひやす', 'ひよう', 'びょうき', 'ひらがな', 'ひらく', 'ひりつ', 'ひりょう', 'ひるま', 'ひるやすみ', 'ひれい', 'ひろい', 'ひろう', 'ひろき', 'ひろゆき', 'ひんかく', 'ひんけつ', 'ひんこん', 'ひんしゅ', 'ひんそう', 'ぴんち', 'ひんぱん', 'びんぼう', 'ふあん', 'ふいうち', 'ふうけい', 'ふうせん', 'ぷうたろう', 'ふうとう', 'ふうふ', 'ふえる', 'ふおん', 'ふかい', 'ふきん', 'ふくざつ', 'ふくぶくろ', 'ふこう', 'ふさい', 'ふしぎ', 'ふじみ', 'ふすま', 'ふせい', 'ふせぐ', 'ふそく', 'ぶたにく', 'ふたん', 'ふちょう', 'ふつう', 'ふつか', 'ふっかつ', 'ふっき', 'ふっこく', 'ぶどう', 'ふとる', 'ふとん', 'ふのう', 'ふはい', 'ふひょう', 'ふへん', 'ふまん', 'ふみん', 'ふめつ', 'ふめん', 'ふよう', 'ふりこ', 'ふりる', 'ふるい', 'ふんいき', 'ぶんがく', 'ぶんぐ', 'ふんしつ', 'ぶんせき', 'ふんそう', 'ぶんぽう', 'へいあん', 'へいおん', 'へいがい', 'へいき', 'へいげん', 'へいこう', 'へいさ', 'へいしゃ', 'へいせつ', 'へいそ', 'へいたく', 'へいてん', 'へいねつ', 'へいわ', 'へきが', 'へこむ', 'べにいろ', 'べにしょうが', 'へらす', 'へんかん', 'べんきょう', 'べんごし', 'へんさい', 'へんたい', 'べんり', 'ほあん', 'ほいく', 'ぼうぎょ', 'ほうこく', 'ほうそう', 'ほうほう', 'ほうもん', 'ほうりつ', 'ほえる', 'ほおん', 'ほかん', 'ほきょう', 'ぼきん', 'ほくろ', 'ほけつ', 'ほけん', 'ほこう', 'ほこる', 'ほしい', 'ほしつ', 'ほしゅ', 'ほしょう', 'ほせい', 'ほそい', 'ほそく', 'ほたて', 'ほたる', 'ぽちぶくろ', 'ほっきょく', 'ほっさ', 'ほったん', 'ほとんど', 'ほめる', 'ほんい', 'ほんき', 'ほんけ', 'ほんしつ', 'ほんやく', 'まいにち', 'まかい', 'まかせる', 'まがる', 'まける', 'まこと', 'まさつ', 'まじめ', 'ますく', 'まぜる', 'まつり', 'まとめ', 'まなぶ', 'まぬけ', 'まねく', 'まほう', 'まもる', 'まゆげ', 'まよう', 'まろやか', 'まわす', 'まわり', 'まわる', 'まんが', 'まんきつ', 'まんぞく', 'まんなか', 'みいら', 'みうち', 'みえる', 'みがく', 'みかた', 'みかん', 'みけん', 'みこん', 'みじかい', 'みすい', 'みすえる', 'みせる', 'みっか', 'みつかる', 'みつける', 'みてい', 'みとめる', 'みなと', 'みなみかさい', 'みねらる', 'みのう', 'みのがす', 'みほん', 'みもと', 'みやげ', 'みらい', 'みりょく', 'みわく', 'みんか', 'みんぞく', 'むいか', 'むえき', 'むえん', 'むかい', 'むかう', 'むかえ', 'むかし', 'むぎちゃ', 'むける', 'むげん', 'むさぼる', 'むしあつい', 'むしば', 'むじゅん', 'むしろ', 'むすう', 'むすこ', 'むすぶ', 'むすめ', 'むせる', 'むせん', 'むちゅう', 'むなしい', 'むのう', 'むやみ', 'むよう', 'むらさき', 'むりょう', 'むろん', 'めいあん', 'めいうん', 'めいえん', 'めいかく', 'めいきょく', 'めいさい', 'めいし', 'めいそう', 'めいぶつ', 'めいれい', 'めいわく', 'めぐまれる', 'めざす', 'めした', 'めずらしい', 'めだつ', 'めまい', 'めやす', 'めんきょ', 'めんせき', 'めんどう', 'もうしあげる', 'もうどうけん', 'もえる', 'もくし', 'もくてき', 'もくようび', 'もちろん', 'もどる', 'もらう', 'もんく', 'もんだい', 'やおや', 'やける', 'やさい', 'やさしい', 'やすい', 'やすたろう', 'やすみ', 'やせる', 'やそう', 'やたい', 'やちん', 'やっと', 'やっぱり', 'やぶる', 'やめる', 'ややこしい', 'やよい', 'やわらかい', 'ゆうき', 'ゆうびんきょく', 'ゆうべ', 'ゆうめい', 'ゆけつ', 'ゆしゅつ', 'ゆせん', 'ゆそう', 'ゆたか', 'ゆちゃく', 'ゆでる', 'ゆにゅう', 'ゆびわ', 'ゆらい', 'ゆれる', 'ようい', 'ようか', 'ようきゅう', 'ようじ', 'ようす', 'ようちえん', 'よかぜ', 'よかん', 'よきん', 'よくせい', 'よくぼう', 'よけい', 'よごれる', 'よさん', 'よしゅう', 'よそう', 'よそく', 'よっか', 'よてい', 'よどがわく', 'よねつ', 'よやく', 'よゆう', 'よろこぶ', 'よろしい', 'らいう', 'らくがき', 'らくご', 'らくさつ', 'らくだ', 'らしんばん', 'らせん', 'らぞく', 'らたい', 'らっか', 'られつ', 'りえき', 'りかい', 'りきさく', 'りきせつ', 'りくぐん', 'りくつ', 'りけん', 'りこう', 'りせい', 'りそう', 'りそく', 'りてん', 'りねん', 'りゆう', 'りゅうがく', 'りよう', 'りょうり', 'りょかん', 'りょくちゃ', 'りょこう', 'りりく', 'りれき', 'りろん', 'りんご', 'るいけい', 'るいさい', 'るいじ', 'るいせき', 'るすばん', 'るりがわら', 'れいかん', 'れいぎ', 'れいせい', 'れいぞうこ', 'れいとう', 'れいぼう', 'れきし', 'れきだい', 'れんあい', 'れんけい', 'れんこん', 'れんさい', 'れんしゅう', 'れんぞく', 'れんらく', 'ろうか', 'ろうご', 'ろうじん', 'ろうそく', 'ろくが', 'ろこつ', 'ろじうら', 'ろしゅつ', 'ろせん', 'ろてん', 'ろめん', 'ろれつ', 'ろんぎ', 'ろんぱ', 'ろんぶん', 'ろんり', 'わかす', 'わかめ', 'わかやま', 'わかれる', 'わしつ', 'わじまし', 'わすれもの', 'わらう', 'われる'];
4246wordList$1.space = ' ';
4247
4248class KeyPair extends Struct {
4249 constructor(privKey, pubKey, PrivKey$1 = PrivKey) {
4250 super({
4251 privKey,
4252 pubKey
4253 });
4254 this.PrivKey = PrivKey$1;
4255 }
4256
4257 fromJSON(json) {
4258 if (json.privKey) {
4259 this.privKey = this.PrivKey.fromJSON(json.privKey);
4260 }
4261
4262 if (json.pubKey) {
4263 this.pubKey = PubKey.fromJSON(json.pubKey);
4264 }
4265
4266 return this;
4267 }
4268
4269 fromBr(br) {
4270 const buflen1 = br.readUInt8();
4271
4272 if (buflen1 > 0) {
4273 this.privKey = new this.PrivKey().fromFastBuffer(br.read(buflen1));
4274 }
4275
4276 const buflen2 = br.readUInt8();
4277
4278 if (buflen2 > 0) {
4279 this.pubKey = new PubKey().fromFastBuffer(br.read(buflen2));
4280 }
4281
4282 return this;
4283 }
4284
4285 toBw(bw) {
4286 if (!bw) {
4287 bw = new Bw();
4288 }
4289
4290 if (this.privKey) {
4291 const privKeybuf = this.privKey.toFastBuffer();
4292 bw.writeUInt8(privKeybuf.length);
4293 bw.write(privKeybuf);
4294 } else {
4295 bw.writeUInt8(0);
4296 }
4297
4298 if (this.pubKey) {
4299 const pubKeybuf = this.pubKey.toFastBuffer();
4300 bw.writeUInt8(pubKeybuf.length);
4301 bw.write(pubKeybuf);
4302 } else {
4303 bw.writeUInt8(0);
4304 }
4305
4306 return bw;
4307 }
4308
4309 fromString(str) {
4310 return this.fromJSON(JSON.parse(str));
4311 }
4312
4313 toString() {
4314 return JSON.stringify(this.toJSON());
4315 }
4316
4317 toPublic() {
4318 const keyPair = new KeyPair().fromObject(this);
4319 keyPair.privKey = undefined;
4320 return keyPair;
4321 }
4322
4323 fromPrivKey(privKey) {
4324 this.privKey = privKey;
4325 this.pubKey = new PubKey().fromPrivKey(privKey);
4326 return this;
4327 }
4328
4329 static fromPrivKey(privKey) {
4330 return new this().fromPrivKey(privKey);
4331 }
4332
4333 async asyncFromPrivKey(privKey) {
4334 this.privKey = privKey;
4335 this.pubKey = await new PubKey().asyncFromPrivKey(privKey);
4336 return this;
4337 }
4338
4339 static asyncFromPrivKey(privKey) {
4340 return new this().asyncFromPrivKey(privKey);
4341 }
4342
4343 fromRandom() {
4344 this.privKey = new this.PrivKey().fromRandom();
4345 this.pubKey = new PubKey().fromPrivKey(this.privKey);
4346 return this;
4347 }
4348
4349 static fromRandom() {
4350 return new this().fromRandom();
4351 }
4352
4353 async asyncFromRandom() {
4354 this.privKey = new this.PrivKey().fromRandom();
4355 return this.asyncFromPrivKey(this.privKey);
4356 }
4357
4358 static asyncFromRandom() {
4359 return new this().asyncFromRandom();
4360 }
4361
4362}
4363
4364KeyPair.Mainnet = class extends KeyPair {
4365 constructor(privKey, pubKey) {
4366 super(privKey, pubKey, PrivKey.Mainnet);
4367 }
4368
4369};
4370KeyPair.Testnet = class extends KeyPair {
4371 constructor(privKey, pubKey) {
4372 super(privKey, pubKey, PrivKey.Testnet);
4373 }
4374
4375};
4376
4377class Ecdsa extends Struct {
4378 constructor(sig, keyPair, hashBuf, k, endian, verified) {
4379 super({
4380 sig,
4381 keyPair,
4382 hashBuf,
4383 k,
4384 endian,
4385 verified
4386 });
4387 }
4388
4389 toJSON() {
4390 return {
4391 sig: this.sig ? this.sig.toString() : undefined,
4392 keyPair: this.keyPair ? this.keyPair.toBuffer().toString('hex') : undefined,
4393 hashBuf: this.hashBuf ? this.hashBuf.toString('hex') : undefined,
4394 k: this.k ? this.k.toString() : undefined,
4395 endian: this.endian,
4396 verified: this.verified
4397 };
4398 }
4399
4400 fromJSON(json) {
4401 this.sig = json.sig ? new Sig().fromString(json.sig) : undefined;
4402 this.keyPair = json.keyPair ? new KeyPair().fromBuffer(Buffer.from(json.keyPair, 'hex')) : undefined;
4403 this.hashBuf = json.hashBuf ? Buffer.from(json.hashBuf, 'hex') : undefined;
4404 this.k = json.k ? new Bn().fromString(json.k) : undefined;
4405 this.endian = json.endian;
4406 this.verified = json.verified;
4407 return this;
4408 }
4409
4410 toBuffer() {
4411 const str = JSON.stringify(this.toJSON());
4412 return Buffer.from(str);
4413 }
4414
4415 fromBuffer(buf) {
4416 const json = JSON.parse(buf.toString());
4417 return this.fromJSON(json);
4418 }
4419
4420 calcrecovery() {
4421 for (let recovery = 0; recovery < 4; recovery++) {
4422 let Qprime;
4423 this.sig.recovery = recovery;
4424
4425 try {
4426 Qprime = this.sig2PubKey();
4427 } catch (e) {
4428 continue;
4429 }
4430
4431 if (Qprime.point.eq(this.keyPair.pubKey.point)) {
4432 const compressed = this.keyPair.pubKey.compressed;
4433 this.sig.compressed = this.keyPair.pubKey.compressed === undefined ? true : compressed;
4434 return this;
4435 }
4436 }
4437
4438 this.sig.recovery = undefined;
4439 throw new Error('Unable to find valid recovery factor');
4440 }
4441
4442 async asyncCalcrecovery() {
4443 const workersResult = await Workers.asyncObjectMethod(this, 'calcrecovery', []);
4444 return this.fromFastBuffer(workersResult.resbuf);
4445 }
4446
4447 static calcrecovery(sig, pubKey, hashBuf) {
4448 const ecdsa = new Ecdsa().fromObject({
4449 sig: sig,
4450 keyPair: new KeyPair().fromObject({
4451 pubKey: pubKey
4452 }),
4453 hashBuf: hashBuf
4454 });
4455 return ecdsa.calcrecovery().sig;
4456 }
4457
4458 static async asyncCalcrecovery(sig, pubKey, hashBuf) {
4459 const workersResult = await Workers.asyncClassMethod(Ecdsa, 'calcrecovery', [sig, pubKey, hashBuf]);
4460 return new Sig().fromFastBuffer(workersResult.resbuf);
4461 }
4462
4463 fromString(str) {
4464 const obj = JSON.parse(str);
4465
4466 if (obj.hashBuf) {
4467 this.hashBuf = Buffer.from(obj.hashBuf, 'hex');
4468 }
4469
4470 if (obj.keyPair) {
4471 this.keyPair = new KeyPair().fromString(obj.keyPair);
4472 }
4473
4474 if (obj.sig) {
4475 this.sig = new Sig().fromString(obj.sig);
4476 }
4477
4478 if (obj.k) {
4479 this.k = new Bn(obj.k, 10);
4480 }
4481
4482 return this;
4483 }
4484
4485 randomK() {
4486 const N = Point.getN();
4487 let k;
4488
4489 do {
4490 k = new Bn().fromBuffer(Random.getRandomBuffer(32));
4491 } while (!(k.lt(N) && k.gt(0)));
4492
4493 this.k = k;
4494 return this;
4495 }
4496
4497 deterministicK(badrs) {
4498 let v = Buffer.alloc(32);
4499 v.fill(0x01);
4500 let k = Buffer.alloc(32);
4501 k.fill(0x00);
4502 const x = this.keyPair.privKey.bn.toBuffer({
4503 size: 32
4504 });
4505 k = Hash.sha256Hmac(Buffer.concat([v, Buffer.from([0x00]), x, this.hashBuf]), k);
4506 v = Hash.sha256Hmac(v, k);
4507 k = Hash.sha256Hmac(Buffer.concat([v, Buffer.from([0x01]), x, this.hashBuf]), k);
4508 v = Hash.sha256Hmac(v, k);
4509 v = Hash.sha256Hmac(v, k);
4510 let T = new Bn().fromBuffer(v);
4511 const N = Point.getN();
4512
4513 if (badrs === undefined) {
4514 badrs = 0;
4515 }
4516
4517 for (let i = 0; i < badrs || !(T.lt(N) && T.gt(0)); i++) {
4518 k = Hash.sha256Hmac(Buffer.concat([v, Buffer.from([0x00])]), k);
4519 v = Hash.sha256Hmac(v, k);
4520 v = Hash.sha256Hmac(v, k);
4521 T = new Bn().fromBuffer(v);
4522 }
4523
4524 this.k = T;
4525 return this;
4526 }
4527
4528 sig2PubKey() {
4529 const recovery = this.sig.recovery;
4530
4531 if (!(recovery === 0 || recovery === 1 || recovery === 2 || recovery === 3)) {
4532 throw new Error('i must be equal to 0, 1, 2, or 3');
4533 }
4534
4535 const e = new Bn().fromBuffer(this.hashBuf);
4536 const r = this.sig.r;
4537 const s = this.sig.s;
4538 const isYOdd = recovery & 1;
4539 const isSecondKey = recovery >> 1;
4540 const n = Point.getN();
4541 const G = Point.getG();
4542 const x = isSecondKey ? r.add(n) : r;
4543 const R = Point.fromX(isYOdd, x);
4544 let errm = '';
4545
4546 try {
4547 R.mul(n);
4548 } catch (err) {
4549 errm = err.message;
4550 }
4551
4552 if (errm !== 'point mul out of range') {
4553 throw new Error('nR is not a valid curve point');
4554 }
4555
4556 const eNeg = e.neg().umod(n);
4557 const rInv = r.invm(n);
4558 const Q = R.mul(s).add(G.mul(eNeg)).mul(rInv);
4559 const pubKey = new PubKey(Q);
4560 pubKey.compressed = this.sig.compressed;
4561 pubKey.validate();
4562 return pubKey;
4563 }
4564
4565 async asyncSig2PubKey() {
4566 const workersResult = await Workers.asyncObjectMethod(this, 'sig2PubKey', []);
4567 return PubKey.fromFastBuffer(workersResult.resbuf);
4568 }
4569
4570 static sig2PubKey(sig, hashBuf) {
4571 const ecdsa = new Ecdsa().fromObject({
4572 sig: sig,
4573 hashBuf: hashBuf
4574 });
4575 return ecdsa.sig2PubKey();
4576 }
4577
4578 static async asyncSig2PubKey(sig, hashBuf) {
4579 const ecdsa = new Ecdsa().fromObject({
4580 sig: sig,
4581 hashBuf: hashBuf
4582 });
4583 const pubKey = await ecdsa.asyncSig2PubKey();
4584 return pubKey;
4585 }
4586
4587 verifyStr(enforceLowS = true) {
4588 if (!Buffer.isBuffer(this.hashBuf) || this.hashBuf.length !== 32) {
4589 return 'hashBuf must be a 32 byte buffer';
4590 }
4591
4592 try {
4593 this.keyPair.pubKey.validate();
4594 } catch (e) {
4595 return 'Invalid pubKey: ' + e;
4596 }
4597
4598 const r = this.sig.r;
4599 const s = this.sig.s;
4600
4601 if (!(r.gt(0) && r.lt(Point.getN())) || !(s.gt(0) && s.lt(Point.getN()))) {
4602 return 'r and s not in range';
4603 }
4604
4605 if (enforceLowS) {
4606 if (!this.sig.hasLowS()) {
4607 return 's is too high and does not satisfy low s contraint - see bip 62';
4608 }
4609 }
4610
4611 const e = new Bn().fromBuffer(this.hashBuf, this.endian ? {
4612 endian: this.endian
4613 } : undefined);
4614 const n = Point.getN();
4615 const sinv = s.invm(n);
4616 const u1 = sinv.mul(e).mod(n);
4617 const u2 = sinv.mul(r).mod(n);
4618 const p = Point.getG().mulAdd(u1, this.keyPair.pubKey.point, u2);
4619
4620 if (p.isInfinity()) {
4621 return 'p is infinity';
4622 }
4623
4624 if (!(p.getX().mod(n).cmp(r) === 0)) {
4625 return 'Invalid signature';
4626 } else {
4627 return false;
4628 }
4629 }
4630
4631 sign() {
4632 const hashBuf = this.endian === 'little' ? new Br(this.hashBuf).readReverse() : this.hashBuf;
4633 const privKey = this.keyPair.privKey;
4634 const d = privKey.bn;
4635
4636 if (!hashBuf || !privKey || !d) {
4637 throw new Error('invalid parameters');
4638 }
4639
4640 if (!Buffer.isBuffer(hashBuf) || hashBuf.length !== 32) {
4641 throw new Error('hashBuf must be a 32 byte buffer');
4642 }
4643
4644 const N = Point.getN();
4645 const G = Point.getG();
4646 const e = new Bn().fromBuffer(hashBuf);
4647 let badrs = 0;
4648 let k, Q, r, s;
4649
4650 do {
4651 if (!this.k || badrs > 0) {
4652 this.deterministicK(badrs);
4653 }
4654
4655 badrs++;
4656 k = this.k;
4657 Q = G.mul(k);
4658 r = Q.getX().mod(N);
4659 s = k.invm(N).mul(e.add(d.mul(r))).mod(N);
4660 } while (r.cmp(0) <= 0 || s.cmp(0) <= 0);
4661
4662 if (s.gt(new Bn().fromBuffer(Buffer.from('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0', 'hex')))) {
4663 s = Point.getN().sub(s);
4664 }
4665
4666 this.sig = Sig.fromObject({
4667 r: r,
4668 s: s,
4669 compressed: this.keyPair.pubKey.compressed
4670 });
4671 return this;
4672 }
4673
4674 async asyncSign() {
4675 const workersResult = await Workers.asyncObjectMethod(this, 'sign', []);
4676 return this.fromFastBuffer(workersResult.resbuf);
4677 }
4678
4679 signRandomK() {
4680 this.randomK();
4681 return this.sign();
4682 }
4683
4684 toString() {
4685 const obj = {};
4686
4687 if (this.hashBuf) {
4688 obj.hashBuf = this.hashBuf.toString('hex');
4689 }
4690
4691 if (this.keyPair) {
4692 obj.keyPair = this.keyPair.toString();
4693 }
4694
4695 if (this.sig) {
4696 obj.sig = this.sig.toString();
4697 }
4698
4699 if (this.k) {
4700 obj.k = this.k.toString();
4701 }
4702
4703 return JSON.stringify(obj);
4704 }
4705
4706 verify(enforceLowS = true) {
4707 if (!this.verifyStr(enforceLowS)) {
4708 this.verified = true;
4709 } else {
4710 this.verified = false;
4711 }
4712
4713 return this;
4714 }
4715
4716 async asyncVerify(enforceLowS = true) {
4717 const workersResult = await Workers.asyncObjectMethod(this, 'verify', [enforceLowS]);
4718 return this.fromFastBuffer(workersResult.resbuf);
4719 }
4720
4721 static sign(hashBuf, keyPair, endian) {
4722 return new Ecdsa().fromObject({
4723 hashBuf: hashBuf,
4724 endian: endian,
4725 keyPair: keyPair
4726 }).sign().sig;
4727 }
4728
4729 static async asyncSign(hashBuf, keyPair, endian) {
4730 const ecdsa = new Ecdsa().fromObject({
4731 hashBuf: hashBuf,
4732 endian: endian,
4733 keyPair: keyPair
4734 });
4735 await ecdsa.asyncSign();
4736 return ecdsa.sig;
4737 }
4738
4739 static verify(hashBuf, sig, pubKey, endian, enforceLowS = true) {
4740 return new Ecdsa().fromObject({
4741 hashBuf: hashBuf,
4742 endian: endian,
4743 sig: sig,
4744 keyPair: new KeyPair().fromObject({
4745 pubKey: pubKey
4746 })
4747 }).verify(enforceLowS).verified;
4748 }
4749
4750 static async asyncVerify(hashBuf, sig, pubKey, endian, enforceLowS = true) {
4751 const ecdsa = new Ecdsa().fromObject({
4752 hashBuf: hashBuf,
4753 endian: endian,
4754 sig: sig,
4755 keyPair: new KeyPair().fromObject({
4756 pubKey: pubKey
4757 })
4758 });
4759 await ecdsa.asyncVerify(enforceLowS);
4760 return ecdsa.verified;
4761 }
4762
4763}
4764
4765class Bsm extends Struct {
4766 constructor(messageBuf, keyPair, sig, address, verified) {
4767 super({
4768 messageBuf,
4769 keyPair,
4770 sig,
4771 address,
4772 verified
4773 });
4774 }
4775
4776 static magicHash(messageBuf) {
4777 if (!Buffer.isBuffer(messageBuf)) {
4778 throw new Error('messageBuf must be a buffer');
4779 }
4780
4781 const bw = new Bw();
4782 bw.writeVarIntNum(Bsm.magicBytes.length);
4783 bw.write(Bsm.magicBytes);
4784 bw.writeVarIntNum(messageBuf.length);
4785 bw.write(messageBuf);
4786 const buf = bw.toBuffer();
4787 const hashBuf = Hash.sha256Sha256(buf);
4788 return hashBuf;
4789 }
4790
4791 static async asyncMagicHash(messageBuf) {
4792 const args = [messageBuf];
4793 const workersResult = await Workers.asyncClassMethod(Bsm, 'magicHash', args);
4794 return workersResult.resbuf;
4795 }
4796
4797 static sign(messageBuf, keyPair) {
4798 const m = new Bsm(messageBuf, keyPair);
4799 m.sign();
4800 const sigbuf = m.sig.toCompact();
4801 const sigstr = sigbuf.toString('base64');
4802 return sigstr;
4803 }
4804
4805 static async asyncSign(messageBuf, keyPair) {
4806 const args = [messageBuf, keyPair];
4807 const workersResult = await Workers.asyncClassMethod(Bsm, 'sign', args);
4808 const sigstr = JSON.parse(workersResult.resbuf.toString());
4809 return sigstr;
4810 }
4811
4812 static verify(messageBuf, sigstr, address) {
4813 const sigbuf = Buffer.from(sigstr, 'base64');
4814 const message = new Bsm();
4815 message.messageBuf = messageBuf;
4816 message.sig = new Sig().fromCompact(sigbuf);
4817 message.address = address;
4818 return message.verify().verified;
4819 }
4820
4821 static async asyncVerify(messageBuf, sigstr, address) {
4822 const args = [messageBuf, sigstr, address];
4823 const workersResult = await Workers.asyncClassMethod(Bsm, 'verify', args);
4824 const res = JSON.parse(workersResult.resbuf.toString());
4825 return res;
4826 }
4827
4828 sign() {
4829 const hashBuf = Bsm.magicHash(this.messageBuf);
4830 const ecdsa = new Ecdsa().fromObject({
4831 hashBuf: hashBuf,
4832 keyPair: this.keyPair
4833 });
4834 ecdsa.sign();
4835 ecdsa.calcrecovery();
4836 this.sig = ecdsa.sig;
4837 return this;
4838 }
4839
4840 verify() {
4841 const hashBuf = Bsm.magicHash(this.messageBuf);
4842 const ecdsa = new Ecdsa();
4843 ecdsa.hashBuf = hashBuf;
4844 ecdsa.sig = this.sig;
4845 ecdsa.keyPair = new KeyPair();
4846 ecdsa.keyPair.pubKey = ecdsa.sig2PubKey();
4847
4848 if (!ecdsa.verify()) {
4849 this.verified = false;
4850 return this;
4851 }
4852
4853 const address = new Address().fromPubKey(ecdsa.keyPair.pubKey, undefined, this.sig.compressed);
4854
4855 if (cmp(address.hashBuf, this.address.hashBuf)) {
4856 this.verified = true;
4857 } else {
4858 this.verified = false;
4859 }
4860
4861 return this;
4862 }
4863
4864}
4865
4866Bsm.magicBytes = Buffer.from('Bitcoin Signed Message:\n');
4867
4868class BlockHeader extends Struct {
4869 constructor(versionBytesNum, prevBlockHashBuf, merkleRootBuf, time, bits, nonce) {
4870 super({
4871 versionBytesNum,
4872 prevBlockHashBuf,
4873 merkleRootBuf,
4874 time,
4875 bits,
4876 nonce
4877 });
4878 }
4879
4880 fromJSON(json) {
4881 this.fromObject({
4882 versionBytesNum: json.versionBytesNum,
4883 prevBlockHashBuf: Buffer.from(json.prevBlockHashBuf, 'hex'),
4884 merkleRootBuf: Buffer.from(json.merkleRootBuf, 'hex'),
4885 time: json.time,
4886 bits: json.bits,
4887 nonce: json.nonce
4888 });
4889 return this;
4890 }
4891
4892 toJSON() {
4893 return {
4894 versionBytesNum: this.versionBytesNum,
4895 prevBlockHashBuf: this.prevBlockHashBuf.toString('hex'),
4896 merkleRootBuf: this.merkleRootBuf.toString('hex'),
4897 time: this.time,
4898 bits: this.bits,
4899 nonce: this.nonce
4900 };
4901 }
4902
4903 fromBr(br) {
4904 this.versionBytesNum = br.readUInt32LE();
4905 this.prevBlockHashBuf = br.read(32);
4906 this.merkleRootBuf = br.read(32);
4907 this.time = br.readUInt32LE();
4908 this.bits = br.readUInt32LE();
4909 this.nonce = br.readUInt32LE();
4910 return this;
4911 }
4912
4913 toBw(bw) {
4914 if (!bw) {
4915 bw = new Bw();
4916 }
4917
4918 bw.writeUInt32LE(this.versionBytesNum);
4919 bw.write(this.prevBlockHashBuf);
4920 bw.write(this.merkleRootBuf);
4921 bw.writeUInt32LE(this.time);
4922 bw.writeUInt32LE(this.bits);
4923 bw.writeUInt32LE(this.nonce);
4924 return bw;
4925 }
4926
4927}
4928
4929class Merkle extends Struct {
4930 constructor(hashBuf, buf, merkle1, merkle2) {
4931 super({
4932 hashBuf,
4933 buf,
4934 merkle1,
4935 merkle2
4936 });
4937 }
4938
4939 hash() {
4940 if (this.hashBuf) {
4941 return this.hashBuf;
4942 }
4943
4944 if (this.buf) {
4945 return Hash.sha256Sha256(this.buf);
4946 }
4947
4948 const hashBuf1 = this.merkle1.hash();
4949 const hashBuf2 = this.merkle2.hash();
4950 this.buf = Buffer.concat([hashBuf1, hashBuf2]);
4951 return Hash.sha256Sha256(this.buf);
4952 }
4953
4954 fromBuffers(bufs) {
4955 if (bufs.length < 1) {
4956 throw new Error('buffers must have a length');
4957 }
4958
4959 bufs = bufs.slice();
4960 const log = Math.log2(bufs.length);
4961
4962 if (!Number.isInteger(log)) {
4963 const lastval = bufs[bufs.length - 1];
4964 var len = Math.pow(2, Math.ceil(log));
4965
4966 for (let i = bufs.length; i < len; i++) {
4967 bufs.push(lastval);
4968 }
4969 }
4970
4971 const bufs1 = bufs.slice(0, bufs.length / 2);
4972 const bufs2 = bufs.slice(bufs.length / 2);
4973 this.fromBufferArrays(bufs1, bufs2);
4974 return this;
4975 }
4976
4977 static fromBuffers(bufs) {
4978 return new this().fromBuffers(bufs);
4979 }
4980
4981 fromBufferArrays(bufs1, bufs2) {
4982 if (bufs1.length === 1) {
4983 this.merkle1 = new Merkle(undefined, bufs1[0]);
4984 this.merkle2 = new Merkle(undefined, bufs2[0]);
4985 return this;
4986 }
4987
4988 const bufs11 = bufs1.slice(0, bufs1.length / 2);
4989 const bufs12 = bufs1.slice(bufs1.length / 2);
4990 this.merkle1 = new Merkle().fromBufferArrays(bufs11, bufs12);
4991 const bufs21 = bufs2.slice(0, bufs2.length / 2);
4992 const bufs22 = bufs2.slice(bufs2.length / 2);
4993 this.merkle2 = new Merkle().fromBufferArrays(bufs21, bufs22);
4994 return this;
4995 }
4996
4997 static fromBufferArrays(bufs1, bufs2) {
4998 return new this().fromBufferArrays(bufs1, bufs2);
4999 }
5000
5001 leavesNum() {
5002 if (this.merkle1) {
5003 return this.merkle1.leavesNum() + this.merkle2.leavesNum();
5004 }
5005
5006 if (this.buf) {
5007 return 1;
5008 }
5009
5010 throw new Error('invalid number of leaves');
5011 }
5012
5013}
5014
5015class HashCache extends Struct {
5016 constructor(prevoutsHashBuf, sequenceHashBuf, outputsHashBuf) {
5017 super();
5018 this.fromObject({
5019 prevoutsHashBuf,
5020 sequenceHashBuf,
5021 outputsHashBuf
5022 });
5023 }
5024
5025 fromBuffer(buf) {
5026 return this.fromJSON(JSON.parse(buf.toString()));
5027 }
5028
5029 toBuffer() {
5030 return Buffer.from(JSON.stringify(this.toJSON()));
5031 }
5032
5033 fromJSON(json) {
5034 this.prevoutsHashBuf = json.prevoutsHashBuf ? Buffer.from(json.prevoutsHashBuf, 'hex') : undefined;
5035 this.sequenceHashBuf = json.sequenceHashBuf ? Buffer.from(json.sequenceHashBuf, 'hex') : undefined;
5036 this.outputsHashBuf = json.outputsHashBuf ? Buffer.from(json.outputsHashBuf, 'hex') : undefined;
5037 return this;
5038 }
5039
5040 toJSON() {
5041 return {
5042 prevoutsHashBuf: this.prevoutsHashBuf ? this.prevoutsHashBuf.toString('hex') : undefined,
5043 sequenceHashBuf: this.sequenceHashBuf ? this.sequenceHashBuf.toString('hex') : undefined,
5044 outputsHashBuf: this.outputsHashBuf ? this.outputsHashBuf.toString('hex') : undefined
5045 };
5046 }
5047
5048}
5049
5050class VarInt extends Struct {
5051 constructor(buf) {
5052 super({
5053 buf
5054 });
5055 }
5056
5057 fromJSON(json) {
5058 this.fromObject({
5059 buf: Buffer.from(json, 'hex')
5060 });
5061 return this;
5062 }
5063
5064 toJSON() {
5065 return this.buf.toString('hex');
5066 }
5067
5068 fromBuffer(buf) {
5069 this.buf = buf;
5070 return this;
5071 }
5072
5073 fromBr(br) {
5074 this.buf = br.readVarIntBuf();
5075 return this;
5076 }
5077
5078 fromBn(bn) {
5079 this.buf = new Bw().writeVarIntBn(bn).toBuffer();
5080 return this;
5081 }
5082
5083 static fromBn(bn) {
5084 return new this().fromBn(bn);
5085 }
5086
5087 fromNumber(num) {
5088 this.buf = new Bw().writeVarIntNum(num).toBuffer();
5089 return this;
5090 }
5091
5092 static fromNumber(num) {
5093 return new this().fromNumber(num);
5094 }
5095
5096 toBuffer() {
5097 return this.buf;
5098 }
5099
5100 toBn() {
5101 return new Br(this.buf).readVarIntBn();
5102 }
5103
5104 toNumber() {
5105 return new Br(this.buf).readVarIntNum();
5106 }
5107
5108}
5109
5110class TxIn extends Struct {
5111 constructor(txHashBuf, txOutNum, scriptVi, script, nSequence = 0xffffffff) {
5112 super({
5113 txHashBuf,
5114 txOutNum,
5115 scriptVi,
5116 script,
5117 nSequence
5118 });
5119 }
5120
5121 setScript(script) {
5122 this.scriptVi = VarInt.fromNumber(script.toBuffer().length);
5123 this.script = script;
5124 return this;
5125 }
5126
5127 fromProperties(txHashBuf, txOutNum, script, nSequence) {
5128 this.fromObject({
5129 txHashBuf,
5130 txOutNum,
5131 nSequence
5132 });
5133 this.setScript(script);
5134 return this;
5135 }
5136
5137 static fromProperties(txHashBuf, txOutNum, script, nSequence) {
5138 return new this().fromProperties(txHashBuf, txOutNum, script, nSequence);
5139 }
5140
5141 fromJSON(json) {
5142 this.fromObject({
5143 txHashBuf: typeof json.txHashBuf !== 'undefined' ? Buffer.from(json.txHashBuf, 'hex') : undefined,
5144 txOutNum: json.txOutNum,
5145 scriptVi: typeof json.scriptVi !== 'undefined' ? VarInt.fromJSON(json.scriptVi) : undefined,
5146 script: typeof json.script !== 'undefined' ? Script.fromJSON(json.script) : undefined,
5147 nSequence: json.nSequence
5148 });
5149 return this;
5150 }
5151
5152 toJSON() {
5153 return {
5154 txHashBuf: typeof this.txHashBuf !== 'undefined' ? this.txHashBuf.toString('hex') : undefined,
5155 txOutNum: this.txOutNum,
5156 scriptVi: typeof this.scriptVi !== 'undefined' ? this.scriptVi.toJSON() : undefined,
5157 script: typeof this.script !== 'undefined' ? this.script.toJSON() : undefined,
5158 nSequence: this.nSequence
5159 };
5160 }
5161
5162 fromBr(br) {
5163 this.txHashBuf = br.read(32);
5164 this.txOutNum = br.readUInt32LE();
5165 this.scriptVi = VarInt.fromBuffer(br.readVarIntBuf());
5166 this.script = Script.fromBuffer(br.read(this.scriptVi.toNumber()));
5167 this.nSequence = br.readUInt32LE();
5168 return this;
5169 }
5170
5171 toBw(bw) {
5172 if (!bw) {
5173 bw = new Bw();
5174 }
5175
5176 bw.write(this.txHashBuf);
5177 bw.writeUInt32LE(this.txOutNum);
5178 bw.write(this.scriptVi.buf);
5179 bw.write(this.script.toBuffer());
5180 bw.writeUInt32LE(this.nSequence);
5181 return bw;
5182 }
5183
5184 fromPubKeyHashTxOut(txHashBuf, txOutNum, txOut, pubKey) {
5185 const script = new Script();
5186
5187 if (txOut.script.isPubKeyHashOut()) {
5188 script.writeOpCode(OpCode.OP_0);
5189
5190 if (pubKey) {
5191 script.writeBuffer(pubKey.toBuffer());
5192 } else {
5193 script.writeOpCode(OpCode.OP_0);
5194 }
5195 } else {
5196 throw new Error('txOut must be of type pubKeyHash');
5197 }
5198
5199 this.txHashBuf = txHashBuf;
5200 this.txOutNum = txOutNum;
5201 this.setScript(script);
5202 return this;
5203 }
5204
5205 hasNullInput() {
5206 const hex = this.txHashBuf.toString('hex');
5207
5208 if (hex === '0000000000000000000000000000000000000000000000000000000000000000' && this.txOutNum === 0xffffffff) {
5209 return true;
5210 }
5211
5212 return false;
5213 }
5214
5215 setNullInput() {
5216 this.txHashBuf = Buffer.alloc(32);
5217 this.txHashBuf.fill(0);
5218 this.txOutNum = 0xffffffff;
5219 }
5220
5221}
5222
5223TxIn.LOCKTIME_VERIFY_SEQUENCE = 1 << 0;
5224TxIn.SEQUENCE_FINAL = 0xffffffff;
5225TxIn.SEQUENCE_LOCKTIME_DISABLE_FLAG = 1 << 31;
5226TxIn.SEQUENCE_LOCKTIME_TYPE_FLAG = 1 << 22;
5227TxIn.SEQUENCE_LOCKTIME_MASK = 0x0000ffff;
5228TxIn.SEQUENCE_LOCKTIME_GRANULARITY = 9;
5229
5230class TxOut extends Struct {
5231 constructor(valueBn, scriptVi, script) {
5232 super({
5233 valueBn,
5234 scriptVi,
5235 script
5236 });
5237 }
5238
5239 setScript(script) {
5240 this.scriptVi = VarInt.fromNumber(script.toBuffer().length);
5241 this.script = script;
5242 return this;
5243 }
5244
5245 fromProperties(valueBn, script) {
5246 this.fromObject({
5247 valueBn
5248 });
5249 this.setScript(script);
5250 return this;
5251 }
5252
5253 static fromProperties(valueBn, script) {
5254 return new this().fromProperties(valueBn, script);
5255 }
5256
5257 fromJSON(json) {
5258 this.fromObject({
5259 valueBn: new Bn().fromJSON(json.valueBn),
5260 scriptVi: new VarInt().fromJSON(json.scriptVi),
5261 script: new Script().fromJSON(json.script)
5262 });
5263 return this;
5264 }
5265
5266 toJSON() {
5267 return {
5268 valueBn: this.valueBn.toJSON(),
5269 scriptVi: this.scriptVi.toJSON(),
5270 script: this.script.toJSON()
5271 };
5272 }
5273
5274 fromBr(br) {
5275 this.valueBn = br.readUInt64LEBn();
5276 this.scriptVi = VarInt.fromNumber(br.readVarIntNum());
5277 this.script = new Script().fromBuffer(br.read(this.scriptVi.toNumber()));
5278 return this;
5279 }
5280
5281 toBw(bw) {
5282 if (!bw) {
5283 bw = new Bw();
5284 }
5285
5286 bw.writeUInt64LEBn(this.valueBn);
5287 bw.write(this.scriptVi.buf);
5288 bw.write(this.script.toBuffer());
5289 return bw;
5290 }
5291
5292}
5293
5294class Tx extends Struct {
5295 constructor(versionBytesNum = 1, txInsVi = VarInt.fromNumber(0), txIns = [], txOutsVi = VarInt.fromNumber(0), txOuts = [], nLockTime = 0) {
5296 super({
5297 versionBytesNum,
5298 txInsVi,
5299 txIns,
5300 txOutsVi,
5301 txOuts,
5302 nLockTime
5303 });
5304 }
5305
5306 fromJSON(json) {
5307 const txIns = [];
5308 json.txIns.forEach(function (txIn) {
5309 txIns.push(new TxIn().fromJSON(txIn));
5310 });
5311 const txOuts = [];
5312 json.txOuts.forEach(function (txOut) {
5313 txOuts.push(new TxOut().fromJSON(txOut));
5314 });
5315 this.fromObject({
5316 versionBytesNum: json.versionBytesNum,
5317 txInsVi: new VarInt().fromJSON(json.txInsVi),
5318 txIns: txIns,
5319 txOutsVi: new VarInt().fromJSON(json.txOutsVi),
5320 txOuts: txOuts,
5321 nLockTime: json.nLockTime
5322 });
5323 return this;
5324 }
5325
5326 toJSON() {
5327 const txIns = [];
5328 this.txIns.forEach(function (txIn) {
5329 txIns.push(txIn.toJSON());
5330 });
5331 const txOuts = [];
5332 this.txOuts.forEach(function (txOut) {
5333 txOuts.push(txOut.toJSON());
5334 });
5335 return {
5336 versionBytesNum: this.versionBytesNum,
5337 txInsVi: this.txInsVi.toJSON(),
5338 txIns: txIns,
5339 txOutsVi: this.txOutsVi.toJSON(),
5340 txOuts: txOuts,
5341 nLockTime: this.nLockTime
5342 };
5343 }
5344
5345 fromBr(br) {
5346 this.versionBytesNum = br.readUInt32LE();
5347 this.txInsVi = new VarInt(br.readVarIntBuf());
5348 const txInsNum = this.txInsVi.toNumber();
5349 this.txIns = [];
5350
5351 for (let i = 0; i < txInsNum; i++) {
5352 this.txIns.push(new TxIn().fromBr(br));
5353 }
5354
5355 this.txOutsVi = new VarInt(br.readVarIntBuf());
5356 const txOutsNum = this.txOutsVi.toNumber();
5357 this.txOuts = [];
5358
5359 for (let i = 0; i < txOutsNum; i++) {
5360 this.txOuts.push(new TxOut().fromBr(br));
5361 }
5362
5363 this.nLockTime = br.readUInt32LE();
5364 return this;
5365 }
5366
5367 toBw(bw) {
5368 if (!bw) {
5369 bw = new Bw();
5370 }
5371
5372 bw.writeUInt32LE(this.versionBytesNum);
5373 bw.write(this.txInsVi.buf);
5374
5375 for (let i = 0; i < this.txIns.length; i++) {
5376 this.txIns[i].toBw(bw);
5377 }
5378
5379 bw.write(this.txOutsVi.buf);
5380
5381 for (let i = 0; i < this.txOuts.length; i++) {
5382 this.txOuts[i].toBw(bw);
5383 }
5384
5385 bw.writeUInt32LE(this.nLockTime);
5386 return bw;
5387 }
5388
5389 hashPrevouts() {
5390 const bw = new Bw();
5391
5392 for (const i in this.txIns) {
5393 const txIn = this.txIns[i];
5394 bw.write(txIn.txHashBuf);
5395 bw.writeUInt32LE(txIn.txOutNum);
5396 }
5397
5398 return Hash.sha256Sha256(bw.toBuffer());
5399 }
5400
5401 hashSequence() {
5402 const bw = new Bw();
5403
5404 for (const i in this.txIns) {
5405 const txIn = this.txIns[i];
5406 bw.writeUInt32LE(txIn.nSequence);
5407 }
5408
5409 return Hash.sha256Sha256(bw.toBuffer());
5410 }
5411
5412 hashOutputs() {
5413 const bw = new Bw();
5414
5415 for (const i in this.txOuts) {
5416 const txOut = this.txOuts[i];
5417 bw.write(txOut.toBuffer());
5418 }
5419
5420 return Hash.sha256Sha256(bw.toBuffer());
5421 }
5422
5423 sighash(nHashType, nIn, subScript, valueBn, flags = 0, hashCache = new HashCache()) {
5424 if (nHashType & Sig.SIGHASH_FORKID && flags & Tx.SCRIPT_ENABLE_SIGHASH_FORKID) {
5425 let hashPrevouts = Buffer.alloc(32, 0);
5426 let hashSequence = Buffer.alloc(32, 0);
5427 let hashOutputs = Buffer.alloc(32, 0);
5428
5429 if (!(nHashType & Sig.SIGHASH_ANYONECANPAY)) {
5430 hashPrevouts = hashCache.prevoutsHashBuf ? hashCache.prevoutsHashBuf : hashCache.prevoutsHashBuf = this.hashPrevouts();
5431 }
5432
5433 if (!(nHashType & Sig.SIGHASH_ANYONECANPAY) && (nHashType & 0x1f) !== Sig.SIGHASH_SINGLE && (nHashType & 0x1f) !== Sig.SIGHASH_NONE) {
5434 hashSequence = hashCache.sequenceHashBuf ? hashCache.sequenceHashBuf : hashCache.sequenceHashBuf = this.hashSequence();
5435 }
5436
5437 if ((nHashType & 0x1f) !== Sig.SIGHASH_SINGLE && (nHashType & 0x1f) !== Sig.SIGHASH_NONE) {
5438 hashOutputs = hashCache.outputsHashBuf ? hashCache.outputsHashBuf : hashCache.outputsHashBuf = this.hashOutputs();
5439 } else if ((nHashType & 0x1f) === Sig.SIGHASH_SINGLE && nIn < this.txOuts.length) {
5440 hashOutputs = Hash.sha256Sha256(this.txOuts[nIn].toBuffer());
5441 }
5442
5443 const bw = new Bw();
5444 bw.writeUInt32LE(this.versionBytesNum);
5445 bw.write(hashPrevouts);
5446 bw.write(hashSequence);
5447 bw.write(this.txIns[nIn].txHashBuf);
5448 bw.writeUInt32LE(this.txIns[nIn].txOutNum);
5449 bw.writeVarIntNum(subScript.toBuffer().length);
5450 bw.write(subScript.toBuffer());
5451 bw.writeUInt64LEBn(valueBn);
5452 bw.writeUInt32LE(this.txIns[nIn].nSequence);
5453 bw.write(hashOutputs);
5454 bw.writeUInt32LE(this.nLockTime);
5455 bw.writeUInt32LE(nHashType >>> 0);
5456 return new Br(Hash.sha256Sha256(bw.toBuffer())).readReverse();
5457 }
5458
5459 const txcopy = this.cloneByBuffer();
5460 subScript = new Script().fromBuffer(subScript.toBuffer());
5461 subScript.removeCodeseparators();
5462
5463 for (let i = 0; i < txcopy.txIns.length; i++) {
5464 txcopy.txIns[i] = TxIn.fromBuffer(txcopy.txIns[i].toBuffer()).setScript(new Script());
5465 }
5466
5467 txcopy.txIns[nIn] = TxIn.fromBuffer(txcopy.txIns[nIn].toBuffer()).setScript(subScript);
5468
5469 if ((nHashType & 31) === Sig.SIGHASH_NONE) {
5470 txcopy.txOuts.length = 0;
5471 txcopy.txOutsVi = VarInt.fromNumber(0);
5472
5473 for (let i = 0; i < txcopy.txIns.length; i++) {
5474 if (i !== nIn) {
5475 txcopy.txIns[i].nSequence = 0;
5476 }
5477 }
5478 } else if ((nHashType & 31) === Sig.SIGHASH_SINGLE) {
5479 if (nIn > txcopy.txOuts.length - 1) {
5480 return Buffer.from('0000000000000000000000000000000000000000000000000000000000000001', 'hex');
5481 }
5482
5483 txcopy.txOuts.length = nIn + 1;
5484 txcopy.txOutsVi = VarInt.fromNumber(nIn + 1);
5485
5486 for (let i = 0; i < txcopy.txOuts.length; i++) {
5487 if (i < nIn) {
5488 txcopy.txOuts[i] = TxOut.fromProperties(new Bn().fromBuffer(Buffer.from('ffffffffffffffff', 'hex')), new Script());
5489 }
5490 }
5491
5492 for (let i = 0; i < txcopy.txIns.length; i++) {
5493 if (i !== nIn) {
5494 txcopy.txIns[i].nSequence = 0;
5495 }
5496 }
5497 }
5498
5499 if (nHashType & Sig.SIGHASH_ANYONECANPAY) {
5500 txcopy.txIns[0] = txcopy.txIns[nIn];
5501 txcopy.txIns.length = 1;
5502 txcopy.txInsVi = VarInt.fromNumber(1);
5503 }
5504
5505 const buf = new Bw().write(txcopy.toBuffer()).writeInt32LE(nHashType).toBuffer();
5506 return new Br(Hash.sha256Sha256(buf)).readReverse();
5507 }
5508
5509 async asyncSighash(nHashType, nIn, subScript, valueBn, flags = 0, hashCache = {}) {
5510 const workersResult = await Workers.asyncObjectMethod(this, 'sighash', [nHashType, nIn, subScript, valueBn, flags, hashCache]);
5511 return workersResult.resbuf;
5512 }
5513
5514 sign(keyPair, nHashType = Sig.SIGHASH_ALL | Sig.SIGHASH_FORKID, nIn, subScript, valueBn, flags = Tx.SCRIPT_ENABLE_SIGHASH_FORKID, hashCache = {}) {
5515 const hashBuf = this.sighash(nHashType, nIn, subScript, valueBn, flags, hashCache);
5516 const sig = Ecdsa.sign(hashBuf, keyPair, 'little').fromObject({
5517 nHashType: nHashType
5518 });
5519 return sig;
5520 }
5521
5522 async asyncSign(keyPair, nHashType = Sig.SIGHASH_ALL | Sig.SIGHASH_FORKID, nIn, subScript, valueBn, flags = Tx.SCRIPT_ENABLE_SIGHASH_FORKID, hashCache = {}) {
5523 const workersResult = await Workers.asyncObjectMethod(this, 'sign', [keyPair, nHashType, nIn, subScript, valueBn, flags, hashCache]);
5524 return new Sig().fromFastBuffer(workersResult.resbuf);
5525 }
5526
5527 verify(sig, pubKey, nIn, subScript, enforceLowS = false, valueBn, flags = Tx.SCRIPT_ENABLE_SIGHASH_FORKID, hashCache = {}) {
5528 const hashBuf = this.sighash(sig.nHashType, nIn, subScript, valueBn, flags, hashCache);
5529 return Ecdsa.verify(hashBuf, sig, pubKey, 'little', enforceLowS);
5530 }
5531
5532 async asyncVerify(sig, pubKey, nIn, subScript, enforceLowS = false, valueBn, flags = Tx.SCRIPT_ENABLE_SIGHASH_FORKID, hashCache = {}) {
5533 const workersResult = await Workers.asyncObjectMethod(this, 'verify', [sig, pubKey, nIn, subScript, enforceLowS, valueBn, flags, hashCache]);
5534 return JSON.parse(workersResult.resbuf.toString());
5535 }
5536
5537 hash() {
5538 return Hash.sha256Sha256(this.toBuffer());
5539 }
5540
5541 async asyncHash() {
5542 const workersResult = await Workers.asyncObjectMethod(this, 'hash', []);
5543 return workersResult.resbuf;
5544 }
5545
5546 id() {
5547 return new Br(this.hash()).readReverse().toString('hex');
5548 }
5549
5550 async asyncId() {
5551 const workersResult = await Workers.asyncObjectMethod(this, 'id', []);
5552 return JSON.parse(workersResult.resbuf.toString());
5553 }
5554
5555 addTxIn(txHashBuf, txOutNum, script, nSequence) {
5556 let txIn;
5557
5558 if (txHashBuf instanceof TxIn) {
5559 txIn = txHashBuf;
5560 } else {
5561 txIn = new TxIn().fromObject({
5562 txHashBuf,
5563 txOutNum,
5564 nSequence
5565 }).setScript(script);
5566 }
5567
5568 this.txIns.push(txIn);
5569 this.txInsVi = VarInt.fromNumber(this.txInsVi.toNumber() + 1);
5570 return this;
5571 }
5572
5573 addTxOut(valueBn, script) {
5574 let txOut;
5575
5576 if (valueBn instanceof TxOut) {
5577 txOut = valueBn;
5578 } else {
5579 txOut = new TxOut().fromObject({
5580 valueBn
5581 }).setScript(script);
5582 }
5583
5584 this.txOuts.push(txOut);
5585 this.txOutsVi = VarInt.fromNumber(this.txOutsVi.toNumber() + 1);
5586 return this;
5587 }
5588
5589 isCoinbase() {
5590 return this.txIns.length === 1 && this.txIns[0].hasNullInput();
5591 }
5592
5593 sort() {
5594 this.txIns.sort((first, second) => {
5595 return new Br(first.txHashBuf).readReverse().compare(new Br(second.txHashBuf).readReverse()) || first.txOutNum - second.txOutNum;
5596 });
5597 this.txOuts.sort((first, second) => {
5598 return first.valueBn.sub(second.valueBn).toNumber() || first.script.toBuffer().compare(second.script.toBuffer());
5599 });
5600 return this;
5601 }
5602
5603}
5604
5605Tx.MAX_MONEY = 21000000 * 1e8;
5606Tx.SCRIPT_ENABLE_SIGHASH_FORKID = 1 << 16;
5607
5608class Block extends Struct {
5609 constructor(blockHeader, txsVi, txs) {
5610 super({
5611 blockHeader,
5612 txsVi,
5613 txs
5614 });
5615 }
5616
5617 fromJSON(json) {
5618 const txs = [];
5619 json.txs.forEach(function (tx) {
5620 txs.push(new Tx().fromJSON(tx));
5621 });
5622 this.fromObject({
5623 blockHeader: new BlockHeader().fromJSON(json.blockHeader),
5624 txsVi: new VarInt().fromJSON(json.txsVi),
5625 txs: txs
5626 });
5627 return this;
5628 }
5629
5630 toJSON() {
5631 const txs = [];
5632 this.txs.forEach(function (tx) {
5633 txs.push(tx.toJSON());
5634 });
5635 return {
5636 blockHeader: this.blockHeader.toJSON(),
5637 txsVi: this.txsVi.toJSON(),
5638 txs: txs
5639 };
5640 }
5641
5642 fromBr(br) {
5643 this.blockHeader = new BlockHeader().fromBr(br);
5644 this.txsVi = new VarInt(br.readVarIntBuf());
5645 const txsNum = this.txsVi.toNumber();
5646 this.txs = [];
5647
5648 for (let i = 0; i < txsNum; i++) {
5649 this.txs.push(new Tx().fromBr(br));
5650 }
5651
5652 return this;
5653 }
5654
5655 toBw(bw) {
5656 if (!bw) {
5657 bw = new Bw();
5658 }
5659
5660 bw.write(this.blockHeader.toBuffer());
5661 bw.write(this.txsVi.buf);
5662 const txsNum = this.txsVi.toNumber();
5663
5664 for (let i = 0; i < txsNum; i++) {
5665 this.txs[i].toBw(bw);
5666 }
5667
5668 return bw;
5669 }
5670
5671 hash() {
5672 return Hash.sha256Sha256(this.blockHeader.toBuffer());
5673 }
5674
5675 async asyncHash() {
5676 const workersResult = await Workers.asyncObjectMethod(this, 'hash', []);
5677 return workersResult.resbuf;
5678 }
5679
5680 id() {
5681 return new Br(this.hash()).readReverse().toString('hex');
5682 }
5683
5684 async asyncId() {
5685 const workersResult = await Workers.asyncObjectMethod(this, 'id', []);
5686 return JSON.parse(workersResult.resbuf.toString());
5687 }
5688
5689 verifyMerkleRoot() {
5690 const txsbufs = this.txs.map(tx => tx.toBuffer());
5691 const merkleRootBuf = Merkle.fromBuffers(txsbufs).hash();
5692 return Buffer.compare(merkleRootBuf, this.blockHeader.merkleRootBuf);
5693 }
5694
5695 static iterateTxs(blockBuf) {
5696 const br = new Br(blockBuf);
5697 const blockHeader = new BlockHeader().fromBr(br);
5698 const txsVi = new VarInt(br.readVarIntBuf());
5699 const txsNum = txsVi.toNumber();
5700 return {
5701 blockHeader,
5702 txsVi,
5703 txsNum,
5704
5705 *[Symbol.iterator]() {
5706 for (let i = 0; i < txsNum; i++) {
5707 yield new Tx().fromBr(br);
5708 }
5709 }
5710
5711 };
5712 }
5713
5714}
5715
5716Block.MAX_BLOCK_SIZE = 1000000;
5717
5718class Interp extends Struct {
5719 constructor(script, tx, nIn, stack = [], altStack = [], pc = 0, pBeginCodeHash = 0, nOpCount = 0, ifStack = [], errStr = '', flags = Interp.defaultFlags, valueBn = new Bn(0)) {
5720 super({
5721 script,
5722 tx,
5723 nIn,
5724 stack,
5725 altStack,
5726 pc,
5727 pBeginCodeHash,
5728 nOpCount,
5729 ifStack,
5730 errStr,
5731 flags,
5732 valueBn
5733 });
5734 }
5735
5736 initialize() {
5737 this.script = new Script();
5738 this.stack = [];
5739 this.altStack = [];
5740 this.pc = 0;
5741 this.pBeginCodeHash = 0;
5742 this.nOpCount = 0;
5743 this.ifStack = [];
5744 this.errStr = '';
5745 this.flags = Interp.defaultFlags;
5746 return this;
5747 }
5748
5749 fromJSON(json) {
5750 this.fromJSONNoTx(json);
5751 this.tx = json.tx ? new Tx().fromJSON(json.tx) : undefined;
5752 return this;
5753 }
5754
5755 fromJSONNoTx(json) {
5756 this.fromObject({
5757 script: json.script !== undefined ? new Script().fromJSON(json.script) : undefined,
5758 nIn: json.nIn
5759 });
5760 this.stack = [];
5761 json.stack.forEach(function (hex) {
5762 this.stack.push(Buffer.from(hex, 'hex'));
5763 }.bind(this));
5764 this.altStack = [];
5765 json.altStack.forEach(function (hex) {
5766 this.altStack.push(Buffer.from(hex, 'hex'));
5767 }.bind(this));
5768 this.fromObject({
5769 pc: json.pc,
5770 pBeginCodeHash: json.pBeginCodeHash,
5771 nOpCount: json.nOpCount,
5772 ifStack: json.ifStack,
5773 errStr: json.errStr,
5774 flags: json.flags
5775 });
5776 return this;
5777 }
5778
5779 fromBr(br) {
5780 let jsonNoTxBufLEn = br.readVarIntNum();
5781 let jsonNoTxBuf = br.read(jsonNoTxBufLEn);
5782 this.fromJSONNoTx(JSON.parse(jsonNoTxBuf.toString()));
5783 let txbuflen = br.readVarIntNum();
5784
5785 if (txbuflen > 0) {
5786 let txbuf = br.read(txbuflen);
5787 this.tx = new Tx().fromFastBuffer(txbuf);
5788 }
5789
5790 return this;
5791 }
5792
5793 toJSON() {
5794 let json = this.toJSONNoTx();
5795 json.tx = this.tx ? this.tx.toJSON() : undefined;
5796 return json;
5797 }
5798
5799 toJSONNoTx() {
5800 let stack = [];
5801 this.stack.forEach(function (buf) {
5802 stack.push(buf.toString('hex'));
5803 });
5804 let altStack = [];
5805 this.altStack.forEach(function (buf) {
5806 altStack.push(buf.toString('hex'));
5807 });
5808 return {
5809 script: this.script ? this.script.toJSON() : undefined,
5810 nIn: this.nIn,
5811 stack: stack,
5812 altStack: altStack,
5813 pc: this.pc,
5814 pBeginCodeHash: this.pBeginCodeHash,
5815 nOpCount: this.nOpCount,
5816 ifStack: this.ifStack,
5817 errStr: this.errStr,
5818 flags: this.flags
5819 };
5820 }
5821
5822 toBw(bw) {
5823 if (!bw) {
5824 bw = new Bw();
5825 }
5826
5827 let jsonNoTxBuf = Buffer.from(JSON.stringify(this.toJSONNoTx()));
5828 bw.writeVarIntNum(jsonNoTxBuf.length);
5829 bw.write(jsonNoTxBuf);
5830
5831 if (this.tx) {
5832 let txbuf = this.tx.toFastBuffer();
5833 bw.writeVarIntNum(txbuf.length);
5834 bw.write(txbuf);
5835 } else {
5836 bw.writeVarIntNum(0);
5837 }
5838
5839 return bw;
5840 }
5841
5842 static getFlags(flagstr) {
5843 let flags = 0;
5844
5845 if (flagstr.indexOf('NONE') !== -1) {
5846 flags = flags | Interp.SCRIPT_VERIFY_NONE;
5847 }
5848
5849 if (flagstr.indexOf('P2SH') !== -1) {
5850 flags = flags | Interp.SCRIPT_VERIFY_P2SH;
5851 }
5852
5853 if (flagstr.indexOf('STRICTENC') !== -1) {
5854 flags = flags | Interp.SCRIPT_VERIFY_STRICTENC;
5855 }
5856
5857 if (flagstr.indexOf('DERSIG') !== -1) {
5858 flags = flags | Interp.SCRIPT_VERIFY_DERSIG;
5859 }
5860
5861 if (flagstr.indexOf('LOW_S') !== -1) {
5862 flags = flags | Interp.SCRIPT_VERIFY_LOW_S;
5863 }
5864
5865 if (flagstr.indexOf('NULLDUMMY') !== -1) {
5866 flags = flags | Interp.SCRIPT_VERIFY_NULLDUMMY;
5867 }
5868
5869 if (flagstr.indexOf('SIGPUSHONLY') !== -1) {
5870 flags = flags | Interp.SCRIPT_VERIFY_SIGPUSHONLY;
5871 }
5872
5873 if (flagstr.indexOf('MINIMALDATA') !== -1) {
5874 flags = flags | Interp.SCRIPT_VERIFY_MINIMALDATA;
5875 }
5876
5877 if (flagstr.indexOf('DISCOURAGE_UPGRADABLE_NOPS') !== -1) {
5878 flags = flags | Interp.SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS;
5879 }
5880
5881 if (flagstr.indexOf('CLEANSTACK') !== -1) {
5882 flags = flags | Interp.SCRIPT_VERIFY_CLEANSTACK;
5883 }
5884
5885 if (flagstr.indexOf('CHECKLOCKTIMEVERIFY') !== -1) {
5886 flags = flags | Interp.SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
5887 }
5888
5889 if (flagstr.indexOf('CHECKSEQUENCEVERIFY') !== -1) {
5890 flags = flags | Interp.SCRIPT_VERIFY_CHECKSEQUENCEVERIFY;
5891 }
5892
5893 if (flagstr.indexOf('SIGHASH_FORKID') !== -1) {
5894 flags = flags | Interp.SCRIPT_ENABLE_SIGHASH_FORKID;
5895 }
5896
5897 return flags;
5898 }
5899
5900 static castToBool(buf) {
5901 for (let i = 0; i < buf.length; i++) {
5902 if (buf[i] !== 0) {
5903 if (i === buf.length - 1 && buf[i] === 0x80) {
5904 return false;
5905 }
5906
5907 return true;
5908 }
5909 }
5910
5911 return false;
5912 }
5913
5914 checkSigEncoding(buf) {
5915 if (buf.length === 0) {
5916 return true;
5917 }
5918
5919 if ((this.flags & (Interp.SCRIPT_VERIFY_DERSIG | Interp.SCRIPT_VERIFY_LOW_S | Interp.SCRIPT_VERIFY_STRICTENC)) !== 0 && !Sig.IsTxDer(buf)) {
5920 this.errStr = 'SCRIPT_ERR_SIG_DER';
5921 return false;
5922 } else if ((this.flags & Interp.SCRIPT_VERIFY_LOW_S) !== 0) {
5923 let sig = new Sig().fromTxFormat(buf);
5924
5925 if (!sig.hasLowS()) {
5926 this.errStr = 'SCRIPT_ERR_SIG_DER';
5927 return false;
5928 }
5929 } else if ((this.flags & Interp.SCRIPT_VERIFY_STRICTENC) !== 0) {
5930 let sig = new Sig().fromTxFormat(buf);
5931
5932 if (!sig.hasDefinedHashType()) {
5933 this.errStr = 'SCRIPT_ERR_SIG_HASHTYPE';
5934 return false;
5935 }
5936 }
5937
5938 return true;
5939 }
5940
5941 checkPubKeyEncoding(buf) {
5942 if ((this.flags & Interp.SCRIPT_VERIFY_STRICTENC) !== 0 && !PubKey.isCompressedOrUncompressed(buf)) {
5943 this.errStr = 'SCRIPT_ERR_PUBKEYTYPE';
5944 return false;
5945 }
5946
5947 return true;
5948 }
5949
5950 checkLockTime(nLockTime) {
5951 if (!(this.tx.nLockTime < Interp.LOCKTIME_THRESHOLD && nLockTime < Interp.LOCKTIME_THRESHOLD || this.tx.nLockTime >= Interp.LOCKTIME_THRESHOLD && nLockTime >= Interp.LOCKTIME_THRESHOLD)) {
5952 return false;
5953 }
5954
5955 if (nLockTime > this.tx.nLockTime) {
5956 return false;
5957 }
5958
5959 if (TxIn.SEQUENCE_FINAL === this.tx.txIns[this.nIn].nSequence) {
5960 return false;
5961 }
5962
5963 return true;
5964 }
5965
5966 checkSequence(nSequence) {
5967 let txToSequence = this.tx.txIns[this.nIn].nSequence;
5968
5969 if (this.tx.versionBytesNum < 2) {
5970 return false;
5971 }
5972
5973 if (txToSequence & TxIn.SEQUENCE_LOCKTIME_DISABLE_FLAG) {
5974 return false;
5975 }
5976
5977 let nLockTimeMask = TxIn.SEQUENCE_LOCKTIME_TYPE_FLAG | TxIn.SEQUENCE_LOCKTIME_MASK;
5978 let txToSequenceMasked = txToSequence & nLockTimeMask;
5979 let nSequenceMasked = nSequence & nLockTimeMask;
5980
5981 if (!(txToSequenceMasked < TxIn.SEQUENCE_LOCKTIME_TYPE_FLAG && nSequenceMasked < TxIn.SEQUENCE_LOCKTIME_TYPE_FLAG || txToSequenceMasked >= TxIn.SEQUENCE_LOCKTIME_TYPE_FLAG && nSequenceMasked >= TxIn.SEQUENCE_LOCKTIME_TYPE_FLAG)) {
5982 return false;
5983 }
5984
5985 if (nSequenceMasked > txToSequenceMasked) {
5986 return false;
5987 }
5988
5989 return true;
5990 }
5991
5992 *eval() {
5993 if (this.script.toBuffer().length > 10000) {
5994 this.errStr = 'SCRIPT_ERR_SCRIPT_SIZE';
5995 yield false;
5996 }
5997
5998 try {
5999 while (this.pc < this.script.chunks.length) {
6000 let fSuccess = this.step();
6001
6002 if (!fSuccess) {
6003 yield false;
6004 } else {
6005 yield fSuccess;
6006 }
6007 }
6008
6009 if (this.stack.length + this.altStack.length > 1000) {
6010 this.errStr = 'SCRIPT_ERR_STACK_SIZE';
6011 yield false;
6012 }
6013 } catch (e) {
6014 this.errStr = 'SCRIPT_ERR_UNKNOWN_ERROR: ' + e;
6015 yield false;
6016 }
6017
6018 if (this.ifStack.length > 0) {
6019 this.errStr = 'SCRIPT_ERR_UNBALANCED_CONDITIONAL';
6020 yield false;
6021 }
6022
6023 yield true;
6024 }
6025
6026 step() {
6027 let fRequireMinimal = (this.flags & Interp.SCRIPT_VERIFY_MINIMALDATA) !== 0;
6028 let fExec = !(this.ifStack.indexOf(false) + 1);
6029 let chunk = this.script.chunks[this.pc];
6030 this.pc++;
6031 let opCodeNum = chunk.opCodeNum;
6032
6033 if (opCodeNum === undefined) {
6034 this.errStr = 'SCRIPT_ERR_BAD_OPCODE';
6035 return false;
6036 }
6037
6038 if (chunk.buf && chunk.buf.length > Interp.MAX_SCRIPT_ELEMENT_SIZE) {
6039 this.errStr = 'SCRIPT_ERR_PUSH_SIZE';
6040 return false;
6041 }
6042
6043 if (opCodeNum > OpCode.OP_16 && ++this.nOpCount > 201) {
6044 this.errStr = 'SCRIPT_ERR_OP_COUNT';
6045 return false;
6046 }
6047
6048 if (opCodeNum === OpCode.OP_LEFT || opCodeNum === OpCode.OP_RIGHT || opCodeNum === OpCode.OP_2MUL || opCodeNum === OpCode.OP_2DIV) {
6049 this.errStr = 'SCRIPT_ERR_DISABLED_OPCODE';
6050 return false;
6051 }
6052
6053 if (fExec && opCodeNum >= 0 && opCodeNum <= OpCode.OP_PUSHDATA4) {
6054 if (fRequireMinimal && !this.script.checkMinimalPush(this.pc - 1)) {
6055 this.errStr = 'SCRIPT_ERR_MINIMALDATA';
6056 return false;
6057 }
6058
6059 if (!chunk.buf) {
6060 this.stack.push(Interp.false);
6061 } else if (chunk.len !== chunk.buf.length) {
6062 throw new Error('LEngth of push value not equal to length of data');
6063 } else {
6064 this.stack.push(chunk.buf);
6065 }
6066 } else if (fExec || OpCode.OP_IF <= opCodeNum && opCodeNum <= OpCode.OP_ENDIF) {
6067 switch (opCodeNum) {
6068 case OpCode.OP_1NEGATE:
6069 case OpCode.OP_1:
6070 case OpCode.OP_2:
6071 case OpCode.OP_3:
6072 case OpCode.OP_4:
6073 case OpCode.OP_5:
6074 case OpCode.OP_6:
6075 case OpCode.OP_7:
6076 case OpCode.OP_8:
6077 case OpCode.OP_9:
6078 case OpCode.OP_10:
6079 case OpCode.OP_11:
6080 case OpCode.OP_12:
6081 case OpCode.OP_13:
6082 case OpCode.OP_14:
6083 case OpCode.OP_15:
6084 case OpCode.OP_16:
6085 {
6086 let n = opCodeNum - (OpCode.OP_1 - 1);
6087
6088 let _buf = new Bn(n).toScriptNumBuffer();
6089
6090 this.stack.push(_buf);
6091 }
6092 break;
6093
6094 case OpCode.OP_NOP:
6095 break;
6096
6097 case OpCode.OP_CHECKLOCKTIMEVERIFY:
6098 {
6099 if (!(this.flags & Interp.SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY)) {
6100 if (this.flags & Interp.SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) {
6101 this.errStr = 'SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS';
6102 return false;
6103 }
6104
6105 break;
6106 }
6107
6108 if (this.stack.length < 1) {
6109 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6110 return false;
6111 }
6112
6113 let nLockTimebuf = this.stack[this.stack.length - 1];
6114 let nLockTimebn = new Bn().fromScriptNumBuffer(nLockTimebuf, fRequireMinimal, 5);
6115 let nLockTime = nLockTimebn.toNumber();
6116
6117 if (nLockTime < 0) {
6118 this.errStr = 'SCRIPT_ERR_NEGATIVE_LOCKTIME';
6119 return false;
6120 }
6121
6122 if (!this.checkLockTime(nLockTime)) {
6123 this.errStr = 'SCRIPT_ERR_UNSATISFIED_LOCKTIME';
6124 return false;
6125 }
6126 }
6127 break;
6128
6129 case OpCode.OP_CHECKSEQUENCEVERIFY:
6130 {
6131 if (!(this.flags & Interp.SCRIPT_VERIFY_CHECKSEQUENCEVERIFY)) {
6132 if (this.flags & Interp.SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) {
6133 this.errStr = 'SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS';
6134 return false;
6135 }
6136
6137 break;
6138 }
6139
6140 if (this.stack.length < 1) {
6141 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6142 return false;
6143 }
6144
6145 let nSequencebuf = this.stack[this.stack.length - 1];
6146 let nSequencebn = new Bn().fromScriptNumBuffer(nSequencebuf, fRequireMinimal, 5);
6147 let nSequence = nSequencebn.toNumber();
6148
6149 if (nSequence < 0) {
6150 this.errStr = 'SCRIPT_ERR_NEGATIVE_LOCKTIME';
6151 return false;
6152 }
6153
6154 if ((nSequence & TxIn.SEQUENCE_LOCKTIME_DISABLE_FLAG) !== 0) {
6155 break;
6156 }
6157
6158 if (!this.checkSequence(nSequence)) {
6159 this.errStr = 'SCRIPT_ERR_UNSATISFIED_LOCKTIME';
6160 return false;
6161 }
6162 }
6163 break;
6164
6165 case OpCode.OP_NOP1:
6166 case OpCode.OP_NOP3:
6167 case OpCode.OP_NOP4:
6168 case OpCode.OP_NOP5:
6169 case OpCode.OP_NOP6:
6170 case OpCode.OP_NOP7:
6171 case OpCode.OP_NOP8:
6172 case OpCode.OP_NOP9:
6173 case OpCode.OP_NOP10:
6174 if (this.flags & Interp.SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) {
6175 this.errStr = 'SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS';
6176 return false;
6177 }
6178
6179 break;
6180
6181 case OpCode.OP_IF:
6182 case OpCode.OP_NOTIF:
6183 {
6184 let fValue = false;
6185
6186 if (fExec) {
6187 if (this.stack.length < 1) {
6188 this.errStr = 'SCRIPT_ERR_UNBALANCED_CONDITIONAL';
6189 return false;
6190 }
6191
6192 let _buf2 = this.stack.pop();
6193
6194 fValue = Interp.castToBool(_buf2);
6195
6196 if (opCodeNum === OpCode.OP_NOTIF) {
6197 fValue = !fValue;
6198 }
6199 }
6200
6201 this.ifStack.push(fValue);
6202 }
6203 break;
6204
6205 case OpCode.OP_ELSE:
6206 if (this.ifStack.length === 0) {
6207 this.errStr = 'SCRIPT_ERR_UNBALANCED_CONDITIONAL';
6208 return false;
6209 }
6210
6211 this.ifStack[this.ifStack.length - 1] = !this.ifStack[this.ifStack.length - 1];
6212 break;
6213
6214 case OpCode.OP_ENDIF:
6215 if (this.ifStack.length === 0) {
6216 this.errStr = 'SCRIPT_ERR_UNBALANCED_CONDITIONAL';
6217 return false;
6218 }
6219
6220 this.ifStack.pop();
6221 break;
6222
6223 case OpCode.OP_VERIFY:
6224 {
6225 if (this.stack.length < 1) {
6226 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6227 return false;
6228 }
6229
6230 let _buf3 = this.stack[this.stack.length - 1];
6231 let fValue = Interp.castToBool(_buf3);
6232
6233 if (fValue) {
6234 this.stack.pop();
6235 } else {
6236 this.errStr = 'SCRIPT_ERR_VERIFY';
6237 return false;
6238 }
6239 }
6240 break;
6241
6242 case OpCode.OP_RETURN:
6243 {
6244 this.errStr = 'SCRIPT_ERR_OP_RETURN';
6245 return false;
6246 }
6247
6248 case OpCode.OP_TOALTSTACK:
6249 if (this.stack.length < 1) {
6250 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6251 return false;
6252 }
6253
6254 this.altStack.push(this.stack.pop());
6255 break;
6256
6257 case OpCode.OP_FROMALTSTACK:
6258 if (this.altStack.length < 1) {
6259 this.errStr = 'SCRIPT_ERR_INVALID_ALTSTACK_OPERATION';
6260 return false;
6261 }
6262
6263 this.stack.push(this.altStack.pop());
6264 break;
6265
6266 case OpCode.OP_2DROP:
6267 if (this.stack.length < 2) {
6268 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6269 return false;
6270 }
6271
6272 this.stack.pop();
6273 this.stack.pop();
6274 break;
6275
6276 case OpCode.OP_2DUP:
6277 {
6278 if (this.stack.length < 2) {
6279 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6280 return false;
6281 }
6282
6283 let _buf4 = this.stack[this.stack.length - 2];
6284 let _buf5 = this.stack[this.stack.length - 1];
6285 this.stack.push(_buf4);
6286 this.stack.push(_buf5);
6287 }
6288 break;
6289
6290 case OpCode.OP_3DUP:
6291 {
6292 if (this.stack.length < 3) {
6293 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6294 return false;
6295 }
6296
6297 let _buf6 = this.stack[this.stack.length - 3];
6298 let _buf7 = this.stack[this.stack.length - 2];
6299 let buf3 = this.stack[this.stack.length - 1];
6300 this.stack.push(_buf6);
6301 this.stack.push(_buf7);
6302 this.stack.push(buf3);
6303 }
6304 break;
6305
6306 case OpCode.OP_2OVER:
6307 {
6308 if (this.stack.length < 4) {
6309 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6310 return false;
6311 }
6312
6313 let _buf8 = this.stack[this.stack.length - 4];
6314 let _buf9 = this.stack[this.stack.length - 3];
6315 this.stack.push(_buf8);
6316 this.stack.push(_buf9);
6317 }
6318 break;
6319
6320 case OpCode.OP_2ROT:
6321 {
6322 if (this.stack.length < 6) {
6323 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6324 return false;
6325 }
6326
6327 let spliced = this.stack.splice(this.stack.length - 6, 2);
6328 this.stack.push(spliced[0]);
6329 this.stack.push(spliced[1]);
6330 }
6331 break;
6332
6333 case OpCode.OP_2SWAP:
6334 {
6335 if (this.stack.length < 4) {
6336 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6337 return false;
6338 }
6339
6340 let spliced = this.stack.splice(this.stack.length - 4, 2);
6341 this.stack.push(spliced[0]);
6342 this.stack.push(spliced[1]);
6343 }
6344 break;
6345
6346 case OpCode.OP_IFDUP:
6347 {
6348 if (this.stack.length < 1) {
6349 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6350 return false;
6351 }
6352
6353 let _buf10 = this.stack[this.stack.length - 1];
6354 let fValue = Interp.castToBool(_buf10);
6355
6356 if (fValue) {
6357 this.stack.push(_buf10);
6358 }
6359 }
6360 break;
6361
6362 case OpCode.OP_DEPTH:
6363 {
6364 let _buf11 = new Bn(this.stack.length).toScriptNumBuffer();
6365
6366 this.stack.push(_buf11);
6367 }
6368 break;
6369
6370 case OpCode.OP_DROP:
6371 if (this.stack.length < 1) {
6372 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6373 return false;
6374 }
6375
6376 this.stack.pop();
6377 break;
6378
6379 case OpCode.OP_DUP:
6380 if (this.stack.length < 1) {
6381 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6382 return false;
6383 }
6384
6385 this.stack.push(this.stack[this.stack.length - 1]);
6386 break;
6387
6388 case OpCode.OP_NIP:
6389 if (this.stack.length < 2) {
6390 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6391 return false;
6392 }
6393
6394 this.stack.splice(this.stack.length - 2, 1);
6395 break;
6396
6397 case OpCode.OP_OVER:
6398 if (this.stack.length < 2) {
6399 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6400 return false;
6401 }
6402
6403 this.stack.push(this.stack[this.stack.length - 2]);
6404 break;
6405
6406 case OpCode.OP_PICK:
6407 case OpCode.OP_ROLL:
6408 {
6409 if (this.stack.length < 2) {
6410 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6411 return false;
6412 }
6413
6414 let _buf12 = this.stack[this.stack.length - 1];
6415 let bn = new Bn().fromScriptNumBuffer(_buf12, fRequireMinimal);
6416 let n = bn.toNumber();
6417 this.stack.pop();
6418
6419 if (n < 0 || n >= this.stack.length) {
6420 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6421 return false;
6422 }
6423
6424 _buf12 = this.stack[this.stack.length - n - 1];
6425
6426 if (opCodeNum === OpCode.OP_ROLL) {
6427 this.stack.splice(this.stack.length - n - 1, 1);
6428 }
6429
6430 this.stack.push(_buf12);
6431 }
6432 break;
6433
6434 case OpCode.OP_ROT:
6435 {
6436 if (this.stack.length < 3) {
6437 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6438 return false;
6439 }
6440
6441 let x1 = this.stack[this.stack.length - 3];
6442 let x2 = this.stack[this.stack.length - 2];
6443 let x3 = this.stack[this.stack.length - 1];
6444 this.stack[this.stack.length - 3] = x2;
6445 this.stack[this.stack.length - 2] = x3;
6446 this.stack[this.stack.length - 1] = x1;
6447 }
6448 break;
6449
6450 case OpCode.OP_SWAP:
6451 {
6452 if (this.stack.length < 2) {
6453 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6454 return false;
6455 }
6456
6457 let x1 = this.stack[this.stack.length - 2];
6458 let x2 = this.stack[this.stack.length - 1];
6459 this.stack[this.stack.length - 2] = x2;
6460 this.stack[this.stack.length - 1] = x1;
6461 }
6462 break;
6463
6464 case OpCode.OP_TUCK:
6465 if (this.stack.length < 2) {
6466 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6467 return false;
6468 }
6469
6470 this.stack.splice(this.stack.length - 2, 0, this.stack[this.stack.length - 1]);
6471 break;
6472
6473 case OpCode.OP_SIZE:
6474 {
6475 if (this.stack.length < 1) {
6476 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6477 return false;
6478 }
6479
6480 let bn = new Bn(this.stack[this.stack.length - 1].length);
6481 this.stack.push(bn.toScriptNumBuffer());
6482 }
6483 break;
6484
6485 case OpCode.OP_OR:
6486 case OpCode.OP_AND:
6487 case OpCode.OP_XOR:
6488 if (this.stack.length < 2) {
6489 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6490 return false;
6491 }
6492
6493 let buf1 = this.stack[this.stack.length - 2];
6494 let buf2 = this.stack[this.stack.length - 1];
6495
6496 if (buf1.length != buf2.length) {
6497 this.errStr = 'SCRIPT_ERR_INVALID_OPERAND_SIZE';
6498 return false;
6499 }
6500
6501 switch (opCodeNum) {
6502 case OpCode.OP_AND:
6503 for (let i = 0; i < buf1.length; i++) {
6504 buf1[i] &= buf2[i];
6505 }
6506
6507 break;
6508
6509 case OpCode.OP_OR:
6510 for (let i = 0; i < buf1.length; i++) {
6511 buf1[i] |= buf2[i];
6512 }
6513
6514 break;
6515
6516 case OpCode.OP_XOR:
6517 for (let i = 0; i < buf1.length; i++) {
6518 buf1[i] ^= buf2[i];
6519 }
6520
6521 break;
6522 }
6523
6524 this.stack.pop();
6525 break;
6526
6527 case OpCode.OP_INVERT:
6528 if (this.stack.length < 1) {
6529 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6530 return false;
6531 }
6532
6533 let buf = this.stack[this.stack.length - 1];
6534
6535 for (let i = 0; i < buf.length; i++) {
6536 buf[i] = ~buf[i];
6537 }
6538
6539 break;
6540
6541 case OpCode.OP_LSHIFT:
6542 case OpCode.OP_RSHIFT:
6543 {
6544 if (this.stack.length < 2) {
6545 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6546 return false;
6547 }
6548
6549 let _buf13 = this.stack[this.stack.length - 2];
6550 let value = new Bn(_buf13);
6551 let n = new Bn().fromScriptNumBuffer(this.stack[this.stack.length - 1], fRequireMinimal).toNumber();
6552
6553 if (n < 0) {
6554 this.errStr = 'SCRIPT_ERR_INVALID_NUMBER_RANGE';
6555 return false;
6556 }
6557
6558 this.stack.pop();
6559 this.stack.pop();
6560
6561 switch (opCodeNum) {
6562 case OpCode.OP_LSHIFT:
6563 value = value.ushln(n);
6564 break;
6565
6566 case OpCode.OP_RSHIFT:
6567 value = value.ushrn(n);
6568 break;
6569 }
6570
6571 let _buf14 = value.toBuffer().slice(-_buf13.length);
6572
6573 if (_buf14.length < _buf13.length) {
6574 _buf14 = Buffer.concat([Buffer.alloc(_buf13.length - _buf14.length), _buf14]);
6575 }
6576
6577 this.stack.push(_buf14);
6578 break;
6579 }
6580
6581 case OpCode.OP_EQUAL:
6582 case OpCode.OP_EQUALVERIFY:
6583 {
6584 if (this.stack.length < 2) {
6585 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6586 return false;
6587 }
6588
6589 let _buf15 = this.stack[this.stack.length - 2];
6590 let _buf16 = this.stack[this.stack.length - 1];
6591 let fEqual = cmp(_buf15, _buf16);
6592 this.stack.pop();
6593 this.stack.pop();
6594 this.stack.push(fEqual ? Interp.true : Interp.false);
6595
6596 if (opCodeNum === OpCode.OP_EQUALVERIFY) {
6597 if (fEqual) {
6598 this.stack.pop();
6599 } else {
6600 this.errStr = 'SCRIPT_ERR_EQUALVERIFY';
6601 return false;
6602 }
6603 }
6604 }
6605 break;
6606
6607 case OpCode.OP_1ADD:
6608 case OpCode.OP_1SUB:
6609 case OpCode.OP_NEGATE:
6610 case OpCode.OP_ABS:
6611 case OpCode.OP_NOT:
6612 case OpCode.OP_0NOTEQUAL:
6613 {
6614 if (this.stack.length < 1) {
6615 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6616 return false;
6617 }
6618
6619 let _buf17 = this.stack[this.stack.length - 1];
6620 let bn = new Bn().fromScriptNumBuffer(_buf17, fRequireMinimal);
6621
6622 switch (opCodeNum) {
6623 case OpCode.OP_1ADD:
6624 bn = bn.add(1);
6625 break;
6626
6627 case OpCode.OP_1SUB:
6628 bn = bn.sub(1);
6629 break;
6630
6631 case OpCode.OP_NEGATE:
6632 bn = bn.neg();
6633 break;
6634
6635 case OpCode.OP_ABS:
6636 if (bn.lt(0)) bn = bn.neg();
6637 break;
6638
6639 case OpCode.OP_NOT:
6640 bn = new Bn(bn.eq(0) + 0);
6641 break;
6642
6643 case OpCode.OP_0NOTEQUAL:
6644 bn = new Bn(bn.neq(0) + 0);
6645 break;
6646 }
6647
6648 this.stack.pop();
6649 this.stack.push(bn.toScriptNumBuffer());
6650 }
6651 break;
6652
6653 case OpCode.OP_ADD:
6654 case OpCode.OP_SUB:
6655 case OpCode.OP_MUL:
6656 case OpCode.OP_DIV:
6657 case OpCode.OP_MOD:
6658 case OpCode.OP_BOOLAND:
6659 case OpCode.OP_BOOLOR:
6660 case OpCode.OP_NUMEQUAL:
6661 case OpCode.OP_NUMEQUALVERIFY:
6662 case OpCode.OP_NUMNOTEQUAL:
6663 case OpCode.OP_LESSTHAN:
6664 case OpCode.OP_GREATERTHAN:
6665 case OpCode.OP_LESSTHANOREQUAL:
6666 case OpCode.OP_GREATERTHANOREQUAL:
6667 case OpCode.OP_MIN:
6668 case OpCode.OP_MAX:
6669 {
6670 if (this.stack.length < 2) {
6671 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6672 return false;
6673 }
6674
6675 let bn1 = new Bn().fromScriptNumBuffer(this.stack[this.stack.length - 2], fRequireMinimal);
6676 let bn2 = new Bn().fromScriptNumBuffer(this.stack[this.stack.length - 1], fRequireMinimal);
6677 let bn = new Bn(0);
6678
6679 switch (opCodeNum) {
6680 case OpCode.OP_ADD:
6681 bn = bn1.add(bn2);
6682 break;
6683
6684 case OpCode.OP_SUB:
6685 bn = bn1.sub(bn2);
6686 break;
6687
6688 case OpCode.OP_MUL:
6689 bn = bn1.mul(bn2);
6690 break;
6691
6692 case OpCode.OP_DIV:
6693 if (bn2 == 0) {
6694 this.errStr = "SCRIPT_ERR_DIV_BY_ZERO";
6695 return false;
6696 }
6697
6698 bn = bn1.div(bn2);
6699 break;
6700
6701 case OpCode.OP_MOD:
6702 if (bn2 == 0) {
6703 this.errStr = "SCRIPT_ERR_DIV_BY_ZERO";
6704 return false;
6705 }
6706
6707 bn = bn1.mod(bn2);
6708 break;
6709
6710 case OpCode.OP_BOOLAND:
6711 bn = new Bn((bn1.neq(0) && bn2.neq(0)) + 0);
6712 break;
6713
6714 case OpCode.OP_BOOLOR:
6715 bn = new Bn((bn1.neq(0) || bn2.neq(0)) + 0);
6716 break;
6717
6718 case OpCode.OP_NUMEQUAL:
6719 bn = new Bn(bn1.eq(bn2) + 0);
6720 break;
6721
6722 case OpCode.OP_NUMEQUALVERIFY:
6723 bn = new Bn(bn1.eq(bn2) + 0);
6724 break;
6725
6726 case OpCode.OP_NUMNOTEQUAL:
6727 bn = new Bn(bn1.neq(bn2) + 0);
6728 break;
6729
6730 case OpCode.OP_LESSTHAN:
6731 bn = new Bn(bn1.lt(bn2) + 0);
6732 break;
6733
6734 case OpCode.OP_GREATERTHAN:
6735 bn = new Bn(bn1.gt(bn2) + 0);
6736 break;
6737
6738 case OpCode.OP_LESSTHANOREQUAL:
6739 bn = new Bn(bn1.leq(bn2) + 0);
6740 break;
6741
6742 case OpCode.OP_GREATERTHANOREQUAL:
6743 bn = new Bn(bn1.geq(bn2) + 0);
6744 break;
6745
6746 case OpCode.OP_MIN:
6747 bn = bn1.lt(bn2) ? bn1 : bn2;
6748 break;
6749
6750 case OpCode.OP_MAX:
6751 bn = bn1.gt(bn2) ? bn1 : bn2;
6752 break;
6753 }
6754
6755 this.stack.pop();
6756 this.stack.pop();
6757 this.stack.push(bn.toScriptNumBuffer());
6758
6759 if (opCodeNum === OpCode.OP_NUMEQUALVERIFY) {
6760 if (Interp.castToBool(this.stack[this.stack.length - 1])) {
6761 this.stack.pop();
6762 } else {
6763 this.errStr = 'SCRIPT_ERR_NUMEQUALVERIFY';
6764 return false;
6765 }
6766 }
6767 }
6768 break;
6769
6770 case OpCode.OP_WITHIN:
6771 {
6772 if (this.stack.length < 3) {
6773 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6774 return false;
6775 }
6776
6777 let bn1 = new Bn().fromScriptNumBuffer(this.stack[this.stack.length - 3], fRequireMinimal);
6778 let bn2 = new Bn().fromScriptNumBuffer(this.stack[this.stack.length - 2], fRequireMinimal);
6779 let bn3 = new Bn().fromScriptNumBuffer(this.stack[this.stack.length - 1], fRequireMinimal);
6780 let fValue = bn2.leq(bn1) && bn1.lt(bn3);
6781 this.stack.pop();
6782 this.stack.pop();
6783 this.stack.pop();
6784 this.stack.push(fValue ? Interp.true : Interp.false);
6785 }
6786 break;
6787
6788 case OpCode.OP_RIPEMD160:
6789 case OpCode.OP_SHA1:
6790 case OpCode.OP_SHA256:
6791 case OpCode.OP_HASH160:
6792 case OpCode.OP_HASH256:
6793 {
6794 if (this.stack.length < 1) {
6795 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6796 return false;
6797 }
6798
6799 let _buf18 = this.stack[this.stack.length - 1];
6800 let bufHash;
6801
6802 if (opCodeNum === OpCode.OP_RIPEMD160) {
6803 bufHash = Hash.ripemd160(_buf18);
6804 } else if (opCodeNum === OpCode.OP_SHA1) {
6805 bufHash = Hash.sha1(_buf18);
6806 } else if (opCodeNum === OpCode.OP_SHA256) {
6807 bufHash = Hash.sha256(_buf18);
6808 } else if (opCodeNum === OpCode.OP_HASH160) {
6809 bufHash = Hash.sha256Ripemd160(_buf18);
6810 } else if (opCodeNum === OpCode.OP_HASH256) {
6811 bufHash = Hash.sha256Sha256(_buf18);
6812 }
6813
6814 this.stack.pop();
6815 this.stack.push(bufHash);
6816 }
6817 break;
6818
6819 case OpCode.OP_CODESEPARATOR:
6820 this.pBeginCodeHash = this.pc;
6821 break;
6822
6823 case OpCode.OP_CHECKSIG:
6824 case OpCode.OP_CHECKSIGVERIFY:
6825 {
6826 if (this.stack.length < 2) {
6827 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6828 return false;
6829 }
6830
6831 let bufSig = this.stack[this.stack.length - 2];
6832 let bufPubKey = this.stack[this.stack.length - 1];
6833 let subScript = new Script().fromObject({
6834 chunks: this.script.chunks.slice(this.pBeginCodeHash)
6835 });
6836 let nHashType = bufSig.length > 0 ? bufSig.readUInt8(bufSig.length - 1) : 0;
6837
6838 if (nHashType & Sig.SIGHASH_FORKID) {
6839 if (!(this.flags & Interp.SCRIPT_ENABLE_SIGHASH_FORKID)) {
6840 this.errStr = 'SCRIPT_ERR_ILLEGAL_FORKID';
6841 return false;
6842 }
6843 } else {
6844 subScript.findAndDelete(new Script().writeBuffer(bufSig));
6845 }
6846
6847 if (!this.checkSigEncoding(bufSig) || !this.checkPubKeyEncoding(bufPubKey)) {
6848 return false;
6849 }
6850
6851 let fSuccess;
6852
6853 try {
6854 let sig = new Sig().fromTxFormat(bufSig);
6855 let pubKey = new PubKey().fromBuffer(bufPubKey, false);
6856 fSuccess = this.tx.verify(sig, pubKey, this.nIn, subScript, Boolean(this.flags & Interp.SCRIPT_VERIFY_LOW_S), this.valueBn, this.flags);
6857 } catch (e) {
6858 fSuccess = false;
6859 }
6860
6861 this.stack.pop();
6862 this.stack.pop();
6863 this.stack.push(fSuccess ? Interp.true : Interp.false);
6864
6865 if (opCodeNum === OpCode.OP_CHECKSIGVERIFY) {
6866 if (fSuccess) {
6867 this.stack.pop();
6868 } else {
6869 this.errStr = 'SCRIPT_ERR_CHECKSIGVERIFY';
6870 return false;
6871 }
6872 }
6873 }
6874 break;
6875
6876 case OpCode.OP_CHECKMULTISIG:
6877 case OpCode.OP_CHECKMULTISIGVERIFY:
6878 {
6879 let i = 1;
6880
6881 if (this.stack.length < i) {
6882 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6883 return false;
6884 }
6885
6886 let nKeysCount = new Bn().fromScriptNumBuffer(this.stack[this.stack.length - i], fRequireMinimal).toNumber();
6887
6888 if (nKeysCount < 0 || nKeysCount > 20) {
6889 this.errStr = 'SCRIPT_ERR_PUBKEY_COUNT';
6890 return false;
6891 }
6892
6893 this.nOpCount += nKeysCount;
6894
6895 if (this.nOpCount > 201) {
6896 this.errStr = 'SCRIPT_ERR_OP_COUNT';
6897 return false;
6898 }
6899
6900 let ikey = ++i;
6901 i += nKeysCount;
6902
6903 if (this.stack.length < i) {
6904 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6905 return false;
6906 }
6907
6908 let nSigsCount = new Bn().fromScriptNumBuffer(this.stack[this.stack.length - i], fRequireMinimal).toNumber();
6909
6910 if (nSigsCount < 0 || nSigsCount > nKeysCount) {
6911 this.errStr = 'SCRIPT_ERR_SIG_COUNT';
6912 return false;
6913 }
6914
6915 let isig = ++i;
6916 i += nSigsCount;
6917
6918 if (this.stack.length < i) {
6919 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6920 return false;
6921 }
6922
6923 let subScript = new Script().fromObject({
6924 chunks: this.script.chunks.slice(this.pBeginCodeHash)
6925 });
6926
6927 for (let k = 0; k < nSigsCount; k++) {
6928 let bufSig = this.stack[this.stack.length - isig - k];
6929 let nHashType = bufSig.length > 0 ? bufSig.readUInt8(bufSig.length - 1) : 0;
6930
6931 if (nHashType & Sig.SIGHASH_FORKID) {
6932 if (!(this.flags & Interp.SCRIPT_ENABLE_SIGHASH_FORKID)) {
6933 this.errStr = 'SCRIPT_ERR_ILLEGAL_FORKID';
6934 return false;
6935 }
6936 } else {
6937 subScript.findAndDelete(new Script().writeBuffer(bufSig));
6938 }
6939 }
6940
6941 let fSuccess = true;
6942
6943 while (fSuccess && nSigsCount > 0) {
6944 let bufSig = this.stack[this.stack.length - isig];
6945 let bufPubKey = this.stack[this.stack.length - ikey];
6946
6947 if (!this.checkSigEncoding(bufSig) || !this.checkPubKeyEncoding(bufPubKey)) {
6948 return false;
6949 }
6950
6951 let fOk;
6952
6953 try {
6954 let sig = new Sig().fromTxFormat(bufSig);
6955 let pubKey = new PubKey().fromBuffer(bufPubKey, false);
6956 fOk = this.tx.verify(sig, pubKey, this.nIn, subScript, Boolean(this.flags & Interp.SCRIPT_VERIFY_LOW_S), this.valueBn, this.flags);
6957 } catch (e) {
6958 fOk = false;
6959 }
6960
6961 if (fOk) {
6962 isig++;
6963 nSigsCount--;
6964 }
6965
6966 ikey++;
6967 nKeysCount--;
6968
6969 if (nSigsCount > nKeysCount) {
6970 fSuccess = false;
6971 }
6972 }
6973
6974 while (i-- > 1) {
6975 this.stack.pop();
6976 }
6977
6978 if (this.stack.length < 1) {
6979 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
6980 return false;
6981 }
6982
6983 if (this.flags & Interp.SCRIPT_VERIFY_NULLDUMMY && this.stack[this.stack.length - 1].length) {
6984 this.errStr = 'SCRIPT_ERR_SIG_NULLDUMMY';
6985 return false;
6986 }
6987
6988 this.stack.pop();
6989 this.stack.push(fSuccess ? Interp.true : Interp.false);
6990
6991 if (opCodeNum === OpCode.OP_CHECKMULTISIGVERIFY) {
6992 if (fSuccess) {
6993 this.stack.pop();
6994 } else {
6995 this.errStr = 'SCRIPT_ERR_CHECKMULTISIGVERIFY';
6996 return false;
6997 }
6998 }
6999 }
7000 break;
7001
7002 case OpCode.OP_CAT:
7003 if (this.stack.length < 2) {
7004 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
7005 return false;
7006 }
7007
7008 let vch1 = this.stack[this.stack.length - 2];
7009 let vch2 = this.stack[this.stack.length - 1];
7010 this.stack[this.stack.length - 2] = Buffer.concat([vch1, vch2]);
7011 this.stack.pop();
7012 break;
7013
7014 case OpCode.OP_SPLIT:
7015 if (this.stack.length < 2) {
7016 this.errStr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
7017 return false;
7018 }
7019
7020 let data = this.stack[this.stack.length - 2];
7021 let position = new Bn().fromScriptNumBuffer(this.stack[this.stack.length - 1], fRequireMinimal);
7022
7023 if (position.lt(0) || position.gt(data.length)) {
7024 this.errStr = 'SCRIPT_ERR_INVALID_SPLIT_RANGE';
7025 return false;
7026 }
7027
7028 let n1 = data.slice(0, position);
7029 let n2 = data.slice(position);
7030 this.stack.pop();
7031 this.stack.pop();
7032 this.stack.push(n1);
7033 this.stack.push(n2);
7034 break;
7035
7036 default:
7037 this.errStr = 'SCRIPT_ERR_BAD_OPCODE';
7038 return false;
7039 }
7040 }
7041
7042 return true;
7043 }
7044
7045 verify(scriptSig, scriptPubKey, tx, nIn, flags, valueBn) {
7046 let results = this.results(scriptSig, scriptPubKey, tx, nIn, flags, valueBn);
7047
7048 for (let success of results) {
7049 if (!success) {
7050 return false;
7051 }
7052 }
7053
7054 return true;
7055 }
7056
7057 *results(scriptSig, scriptPubKey, tx, nIn, flags, valueBn) {
7058 let stackCopy;
7059 this.fromObject({
7060 script: scriptSig,
7061 tx: tx,
7062 nIn: nIn,
7063 flags: flags,
7064 valueBn: valueBn
7065 });
7066
7067 if ((flags & Interp.SCRIPT_VERIFY_SIGPUSHONLY) !== 0 && !scriptSig.isPushOnly()) {
7068 this.errStr = this.errStr || 'SCRIPT_ERR_SIG_PUSHONLY';
7069 yield false;
7070 }
7071
7072 yield* this.eval();
7073
7074 if (flags & Interp.SCRIPT_VERIFY_P2SH) {
7075 stackCopy = this.stack.slice();
7076 }
7077
7078 let stack = this.stack;
7079 this.initialize();
7080 this.fromObject({
7081 script: scriptPubKey,
7082 stack: stack,
7083 tx: tx,
7084 nIn: nIn,
7085 flags: flags,
7086 valueBn: valueBn
7087 });
7088 yield* this.eval();
7089
7090 if (this.stack.length === 0) {
7091 this.errStr = this.errStr || 'SCRIPT_ERR_EVAL_FALSE';
7092 yield false;
7093 }
7094
7095 let buf = this.stack[this.stack.length - 1];
7096
7097 if (!Interp.castToBool(buf)) {
7098 this.errStr = this.errStr || 'SCRIPT_ERR_EVAL_FALSE';
7099 yield false;
7100 }
7101
7102 if (flags & Interp.SCRIPT_VERIFY_P2SH && scriptPubKey.isScriptHashOut()) {
7103 if (!scriptSig.isPushOnly()) {
7104 this.errStr = this.errStr || 'SCRIPT_ERR_SIG_PUSHONLY';
7105 yield false;
7106 }
7107
7108 let tmp = stack;
7109 stack = stackCopy;
7110 stackCopy = tmp;
7111
7112 if (stack.length === 0) {
7113 throw new Error('internal error - stack copy empty');
7114 }
7115
7116 let pubKeySerialized = stack[stack.length - 1];
7117 let scriptPubKey2 = new Script().fromBuffer(pubKeySerialized);
7118 stack.pop();
7119 this.initialize();
7120 this.fromObject({
7121 script: scriptPubKey2,
7122 stack: stack,
7123 tx: tx,
7124 nIn: nIn,
7125 flags: flags,
7126 valueBn: valueBn
7127 });
7128 yield* this.eval();
7129
7130 if (stack.length === 0) {
7131 this.errStr = this.errStr || 'SCRIPT_ERR_EVAL_FALSE';
7132 yield false;
7133 }
7134
7135 if (!Interp.castToBool(stack[stack.length - 1])) {
7136 this.errStr = this.errStr || 'SCRIPT_ERR_EVAL_FALSE';
7137 yield false;
7138 } else {
7139 yield true;
7140 }
7141 }
7142
7143 if ((flags & Interp.SCRIPT_VERIFY_CLEANSTACK) !== 0) {
7144 if (!(flags & Interp.SCRIPT_VERIFY_P2SH)) {
7145 throw new Error('cannot use CLEANSTACK without P2SH');
7146 }
7147
7148 if (stack.length !== 1) {
7149 this.errStr = this.errStr || 'SCRIPT_ERR_CLEANSTACK';
7150 yield false;
7151 }
7152 }
7153
7154 yield true;
7155 }
7156
7157 getDebugObject() {
7158 let pc = this.pc - 1;
7159 return {
7160 errStr: this.errStr,
7161 scriptStr: this.script ? this.script.toString() : 'no script found',
7162 pc: pc,
7163 stack: this.stack.map(buf => buf.toString('hex')),
7164 altStack: this.altStack.map(buf => buf.toString('hex')),
7165 opCodeStr: this.script ? OpCode.fromNumber(this.script.chunks[pc].opCodeNum).toString() : 'no script found'
7166 };
7167 }
7168
7169 getDebugString() {
7170 return JSON.stringify(this.getDebugObject(), null, 2);
7171 }
7172
7173}
7174
7175Interp.true = Buffer.from([1]);
7176Interp.false = Buffer.from([]);
7177Interp.MAX_SCRIPT_ELEMENT_SIZE = 520;
7178Interp.LOCKTIME_THRESHOLD = 500000000;
7179Interp.SCRIPT_VERIFY_NONE = 0;
7180Interp.SCRIPT_VERIFY_P2SH = 1 << 0;
7181Interp.SCRIPT_VERIFY_STRICTENC = 1 << 1;
7182Interp.SCRIPT_VERIFY_DERSIG = 1 << 2;
7183Interp.SCRIPT_VERIFY_LOW_S = 1 << 3;
7184Interp.SCRIPT_VERIFY_NULLDUMMY = 1 << 4;
7185Interp.SCRIPT_VERIFY_SIGPUSHONLY = 1 << 5;
7186Interp.SCRIPT_VERIFY_MINIMALDATA = 1 << 6;
7187Interp.SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = 1 << 7;
7188Interp.SCRIPT_VERIFY_CLEANSTACK = 1 << 8;
7189Interp.SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = 1 << 9;
7190Interp.SCRIPT_VERIFY_CHECKSEQUENCEVERIFY = 1 << 10;
7191Interp.SCRIPT_ENABLE_SIGHASH_FORKID = 1 << 16;
7192Interp.defaultFlags = Interp.SCRIPT_VERIFY_P2SH | Interp.SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
7193
7194class SigOperations extends Struct {
7195 constructor(map = new Map()) {
7196 super({
7197 map
7198 });
7199 }
7200
7201 toJSON() {
7202 const json = {};
7203 this.map.forEach((arr, label) => {
7204 json[label] = arr.map(obj => ({
7205 nScriptChunk: obj.nScriptChunk,
7206 type: obj.type,
7207 addressStr: obj.addressStr,
7208 nHashType: obj.nHashType,
7209 log: obj.log
7210 }));
7211 });
7212 return json;
7213 }
7214
7215 fromJSON(json) {
7216 Object.keys(json).forEach(label => {
7217 this.map.set(label, json[label].map(obj => ({
7218 nScriptChunk: obj.nScriptChunk,
7219 type: obj.type,
7220 addressStr: obj.addressStr,
7221 nHashType: obj.nHashType,
7222 log: obj.log
7223 })));
7224 });
7225 return this;
7226 }
7227
7228 setOne(txHashBuf, txOutNum, nScriptChunk, type = 'sig', addressStr, nHashType = Sig.SIGHASH_ALL | Sig.SIGHASH_FORKID) {
7229 const label = txHashBuf.toString('hex') + ':' + txOutNum;
7230 const obj = {
7231 nScriptChunk,
7232 type,
7233 addressStr,
7234 nHashType
7235 };
7236 this.map.set(label, [obj]);
7237 return this;
7238 }
7239
7240 setMany(txHashBuf, txOutNum, arr) {
7241 const label = txHashBuf.toString('hex') + ':' + txOutNum;
7242 arr = arr.map(obj => ({
7243 type: obj.type || 'sig',
7244 nHashType: obj.nHashType || Sig.SIGHASH_ALL | Sig.SIGHASH_FORKID,
7245 ...obj
7246 }));
7247 this.map.set(label, arr);
7248 return this;
7249 }
7250
7251 addOne(txHashBuf, txOutNum, nScriptChunk, type = 'sig', addressStr, nHashType = Sig.SIGHASH_ALL | Sig.SIGHASH_FORKID) {
7252 const arr = this.get(txHashBuf, txOutNum) || [];
7253 arr.push({
7254 nScriptChunk,
7255 type,
7256 addressStr,
7257 nHashType
7258 });
7259 this.setMany(txHashBuf, txOutNum, arr);
7260 return this;
7261 }
7262
7263 get(txHashBuf, txOutNum) {
7264 const label = txHashBuf.toString('hex') + ':' + txOutNum;
7265 return this.map.get(label);
7266 }
7267
7268}
7269
7270class TxOutMap extends Struct {
7271 constructor(map = new Map()) {
7272 super({
7273 map
7274 });
7275 }
7276
7277 toJSON() {
7278 const json = {};
7279 this.map.forEach((txOut, label) => {
7280 json[label] = txOut.toHex();
7281 });
7282 return json;
7283 }
7284
7285 fromJSON(json) {
7286 Object.keys(json).forEach(label => {
7287 this.map.set(label, TxOut.fromHex(json[label]));
7288 });
7289 return this;
7290 }
7291
7292 set(txHashBuf, txOutNum, txOut) {
7293 const label = txHashBuf.toString('hex') + ':' + txOutNum;
7294 this.map.set(label, txOut);
7295 return this;
7296 }
7297
7298 get(txHashBuf, txOutNum) {
7299 const label = txHashBuf.toString('hex') + ':' + txOutNum;
7300 return this.map.get(label);
7301 }
7302
7303 setTx(tx) {
7304 const txhashhex = tx.hash().toString('hex');
7305 tx.txOuts.forEach((txOut, index) => {
7306 const label = txhashhex + ':' + index;
7307 this.map.set(label, txOut);
7308 });
7309 return this;
7310 }
7311
7312}
7313
7314const Constants$1 = Constants.Default.TxBuilder;
7315
7316class TxBuilder extends Struct {
7317 constructor(tx = new Tx(), txIns = [], txOuts = [], uTxOutMap = new TxOutMap(), sigOperations = new SigOperations(), changeScript, changeAmountBn, feeAmountBn, feePerKbNum = Constants$1.feePerKbNum, nLockTime = 0, versionBytesNum = 1, sigsPerInput = 1, dust = Constants$1.dust, dustChangeToFees = false, hashCache = new HashCache()) {
7318 super({
7319 tx,
7320 txIns,
7321 txOuts,
7322 uTxOutMap,
7323 sigOperations,
7324 changeScript,
7325 changeAmountBn,
7326 feeAmountBn,
7327 feePerKbNum,
7328 nLockTime,
7329 versionBytesNum,
7330 sigsPerInput,
7331 dust,
7332 dustChangeToFees,
7333 hashCache
7334 });
7335 }
7336
7337 toJSON() {
7338 const json = {};
7339 json.tx = this.tx.toHex();
7340 json.txIns = this.txIns.map(txIn => txIn.toHex());
7341 json.txOuts = this.txOuts.map(txOut => txOut.toHex());
7342 json.uTxOutMap = this.uTxOutMap.toJSON();
7343 json.sigOperations = this.sigOperations.toJSON();
7344 json.changeScript = this.changeScript ? this.changeScript.toHex() : undefined;
7345 json.changeAmountBn = this.changeAmountBn ? this.changeAmountBn.toNumber() : undefined;
7346 json.feeAmountBn = this.feeAmountBn ? this.feeAmountBn.toNumber() : undefined;
7347 json.feePerKbNum = this.feePerKbNum;
7348 json.sigsPerInput = this.sigsPerInput;
7349 json.dust = this.dust;
7350 json.dustChangeToFees = this.dustChangeToFees;
7351 json.hashCache = this.hashCache.toJSON();
7352 return json;
7353 }
7354
7355 fromJSON(json) {
7356 this.tx = new Tx().fromHex(json.tx);
7357 this.txIns = json.txIns.map(txIn => TxIn.fromHex(txIn));
7358 this.txOuts = json.txOuts.map(txOut => TxOut.fromHex(txOut));
7359 this.uTxOutMap = new TxOutMap().fromJSON(json.uTxOutMap);
7360 this.sigOperations = new SigOperations().fromJSON(json.sigOperations);
7361 this.changeScript = json.changeScript ? new Script().fromHex(json.changeScript) : undefined;
7362 this.changeAmountBn = json.changeAmountBn ? new Bn(json.changeAmountBn) : undefined;
7363 this.feeAmountBn = json.feeAmountBn ? new Bn(json.feeAmountBn) : undefined;
7364 this.feePerKbNum = json.feePerKbNum || this.feePerKbNum;
7365 this.sigsPerInput = json.sigsPerInput || this.sigsPerInput;
7366 this.dust = json.dust || this.dust;
7367 this.dustChangeToFees = json.dustChangeToFees || this.dustChangeToFees;
7368 this.hashCache = HashCache.fromJSON(json.hashCache);
7369 return this;
7370 }
7371
7372 setFeePerKbNum(feePerKbNum) {
7373 if (typeof feePerKbNum !== 'number' || feePerKbNum <= 0) {
7374 throw new Error('cannot set a fee of zero or less');
7375 }
7376
7377 this.feePerKbNum = feePerKbNum;
7378 return this;
7379 }
7380
7381 setChangeAddress(changeAddress) {
7382 this.changeScript = changeAddress.toTxOutScript();
7383 return this;
7384 }
7385
7386 setChangeScript(changeScript) {
7387 this.changeScript = changeScript;
7388 return this;
7389 }
7390
7391 setNLocktime(nLockTime) {
7392 this.nLockTime = nLockTime;
7393 return this;
7394 }
7395
7396 setVersion(versionBytesNum) {
7397 this.versionBytesNum = versionBytesNum;
7398 return this;
7399 }
7400
7401 setDust(dust = Constants$1.dust) {
7402 this.dust = dust;
7403 return this;
7404 }
7405
7406 sendDustChangeToFees(dustChangeToFees = false) {
7407 this.dustChangeToFees = dustChangeToFees;
7408 return this;
7409 }
7410
7411 importPartiallySignedTx(tx, uTxOutMap = this.uTxOutMap, sigOperations = this.sigOperations) {
7412 this.tx = tx;
7413 this.uTxOutMap = uTxOutMap;
7414 this.sigOperations = sigOperations;
7415 return this;
7416 }
7417
7418 inputFromScript(txHashBuf, txOutNum, txOut, script, nSequence) {
7419 if (!Buffer.isBuffer(txHashBuf) || !(typeof txOutNum === 'number') || !(txOut instanceof TxOut) || !(script instanceof Script)) {
7420 throw new Error('invalid one of: txHashBuf, txOutNum, txOut, script');
7421 }
7422
7423 this.txIns.push(TxIn.fromProperties(txHashBuf, txOutNum, script, nSequence));
7424 this.uTxOutMap.set(txHashBuf, txOutNum, txOut);
7425 return this;
7426 }
7427
7428 addSigOperation(txHashBuf, txOutNum, nScriptChunk, type, addressStr, nHashType) {
7429 this.sigOperations.addOne(txHashBuf, txOutNum, nScriptChunk, type, addressStr, nHashType);
7430 return this;
7431 }
7432
7433 inputFromPubKeyHash(txHashBuf, txOutNum, txOut, pubKey, nSequence, nHashType) {
7434 if (!Buffer.isBuffer(txHashBuf) || typeof txOutNum !== 'number' || !(txOut instanceof TxOut)) {
7435 throw new Error('invalid one of: txHashBuf, txOutNum, txOut');
7436 }
7437
7438 this.txIns.push(new TxIn().fromObject({
7439 nSequence
7440 }).fromPubKeyHashTxOut(txHashBuf, txOutNum, txOut, pubKey));
7441 this.uTxOutMap.set(txHashBuf, txOutNum, txOut);
7442 const addressStr = Address.fromTxOutScript(txOut.script).toString();
7443 this.addSigOperation(txHashBuf, txOutNum, 0, 'sig', addressStr, nHashType);
7444 this.addSigOperation(txHashBuf, txOutNum, 1, 'pubKey', addressStr);
7445 return this;
7446 }
7447
7448 outputToAddress(valueBn, addr) {
7449 if (!(addr instanceof Address) || !(valueBn instanceof Bn)) {
7450 throw new Error('addr must be an Address, and valueBn must be a Bn');
7451 }
7452
7453 const script = new Script().fromPubKeyHash(addr.hashBuf);
7454 this.outputToScript(valueBn, script);
7455 return this;
7456 }
7457
7458 outputToScript(valueBn, script) {
7459 if (!(script instanceof Script) || !(valueBn instanceof Bn)) {
7460 throw new Error('script must be a Script, and valueBn must be a Bn');
7461 }
7462
7463 const txOut = TxOut.fromProperties(valueBn, script);
7464 this.txOuts.push(txOut);
7465 return this;
7466 }
7467
7468 buildOutputs() {
7469 let outAmountBn = new Bn(0);
7470 this.txOuts.forEach(txOut => {
7471 if (txOut.valueBn.lt(this.dust) && !txOut.script.isOpReturn() && !txOut.script.isSafeDataOut()) {
7472 throw new Error('cannot create output lesser than dust');
7473 }
7474
7475 outAmountBn = outAmountBn.add(txOut.valueBn);
7476 this.tx.addTxOut(txOut);
7477 });
7478 return outAmountBn;
7479 }
7480
7481 buildInputs(outAmountBn, extraInputsNum = 0) {
7482 let inAmountBn = new Bn(0);
7483
7484 for (const txIn of this.txIns) {
7485 const txOut = this.uTxOutMap.get(txIn.txHashBuf, txIn.txOutNum);
7486 inAmountBn = inAmountBn.add(txOut.valueBn);
7487 this.tx.addTxIn(txIn);
7488
7489 if (inAmountBn.geq(outAmountBn)) {
7490 if (extraInputsNum <= 0) {
7491 break;
7492 }
7493
7494 extraInputsNum--;
7495 }
7496 }
7497
7498 if (inAmountBn.lt(outAmountBn)) {
7499 throw new Error('not enough funds for outputs: inAmountBn ' + inAmountBn.toNumber() + ' outAmountBn ' + outAmountBn.toNumber());
7500 }
7501
7502 return inAmountBn;
7503 }
7504
7505 estimateSize() {
7506 const sigSize = 1 + 1 + 1 + 1 + 32 + 1 + 1 + 32 + 1 + 1;
7507 const pubKeySize = 1 + 1 + 33;
7508 let size = this.tx.toBuffer().length;
7509 this.tx.txIns.forEach(txIn => {
7510 const {
7511 txHashBuf,
7512 txOutNum
7513 } = txIn;
7514 const sigOperations = this.sigOperations.get(txHashBuf, txOutNum);
7515 sigOperations.forEach(obj => {
7516 const {
7517 nScriptChunk,
7518 type
7519 } = obj;
7520 const script = new Script([txIn.script.chunks[nScriptChunk]]);
7521 const scriptSize = script.toBuffer().length;
7522 size -= scriptSize;
7523
7524 if (type === 'sig') {
7525 size += sigSize;
7526 } else if (obj.type === 'pubKey') {
7527 size += pubKeySize;
7528 } else {
7529 throw new Error('unsupported sig operations type');
7530 }
7531 });
7532 });
7533 size = size + 1;
7534 return Math.round(size);
7535 }
7536
7537 estimateFee(extraFeeAmount = new Bn(0)) {
7538 const fee = Math.ceil(this.estimateSize() / 1000 * this.feePerKbNum);
7539 return new Bn(fee).add(extraFeeAmount);
7540 }
7541
7542 build(opts = {
7543 useAllInputs: false
7544 }) {
7545 let minFeeAmountBn;
7546
7547 if (this.txIns.length <= 0) {
7548 throw Error('tx-builder number of inputs must be greater than 0');
7549 }
7550
7551 if (!this.changeScript) {
7552 throw new Error('must specify change script to use build method');
7553 }
7554
7555 for (let extraInputsNum = opts.useAllInputs ? this.txIns.length - 1 : 0; extraInputsNum < this.txIns.length; extraInputsNum++) {
7556 this.tx = new Tx();
7557 const outAmountBn = this.buildOutputs();
7558 const changeTxOut = TxOut.fromProperties(new Bn(0), this.changeScript);
7559 this.tx.addTxOut(changeTxOut);
7560 let inAmountBn;
7561
7562 try {
7563 inAmountBn = this.buildInputs(outAmountBn, extraInputsNum);
7564 } catch (err) {
7565 if (err.message.includes('not enough funds for outputs')) {
7566 throw new Error('unable to gather enough inputs for outputs and fee');
7567 } else {
7568 throw err;
7569 }
7570 }
7571
7572 this.changeAmountBn = inAmountBn.sub(outAmountBn);
7573 changeTxOut.valueBn = this.changeAmountBn;
7574 minFeeAmountBn = this.estimateFee();
7575
7576 if (this.changeAmountBn.geq(minFeeAmountBn) && this.changeAmountBn.sub(minFeeAmountBn).gt(this.dust)) {
7577 break;
7578 }
7579 }
7580
7581 if (this.changeAmountBn.geq(minFeeAmountBn)) {
7582 this.feeAmountBn = minFeeAmountBn;
7583 this.changeAmountBn = this.changeAmountBn.sub(this.feeAmountBn);
7584 this.tx.txOuts[this.tx.txOuts.length - 1].valueBn = this.changeAmountBn;
7585
7586 if (this.changeAmountBn.lt(this.dust)) {
7587 if (this.dustChangeToFees) {
7588 this.tx.txOuts.pop();
7589 this.tx.txOutsVi = VarInt.fromNumber(this.tx.txOutsVi.toNumber() - 1);
7590 this.feeAmountBn = this.feeAmountBn.add(this.changeAmountBn);
7591 this.changeAmountBn = new Bn(0);
7592 } else {
7593 throw new Error('unable to create change amount greater than dust');
7594 }
7595 }
7596
7597 this.tx.nLockTime = this.nLockTime;
7598 this.tx.versionBytesNum = this.versionBytesNum;
7599
7600 if (this.tx.txOuts.length === 0) {
7601 throw new Error('outputs length is zero - unable to create any outputs greater than dust');
7602 }
7603
7604 return this;
7605 } else {
7606 throw new Error('unable to gather enough inputs for outputs and fee');
7607 }
7608 }
7609
7610 sort() {
7611 this.tx.sort();
7612 return this;
7613 }
7614
7615 static allSigsPresent(m, script) {
7616 let present = 0;
7617
7618 for (let i = 1; i < script.chunks.length - 1; i++) {
7619 if (script.chunks[i].buf) {
7620 present++;
7621 }
7622 }
7623
7624 return present === m;
7625 }
7626
7627 static removeBlankSigs(script) {
7628 script = new Script(script.chunks.slice());
7629
7630 for (let i = 1; i < script.chunks.length - 1; i++) {
7631 if (!script.chunks[i].buf) {
7632 script.chunks.splice(i, 1);
7633 }
7634 }
7635
7636 return script;
7637 }
7638
7639 fillSig(nIn, nScriptChunk, sig) {
7640 const txIn = this.tx.txIns[nIn];
7641 txIn.script.chunks[nScriptChunk] = new Script().writeBuffer(sig.toTxFormat()).chunks[0];
7642 txIn.scriptVi = VarInt.fromNumber(txIn.script.toBuffer().length);
7643 return this;
7644 }
7645
7646 getSig(keyPair, nHashType = Sig.SIGHASH_ALL | Sig.SIGHASH_FORKID, nIn, subScript, flags = Tx.SCRIPT_ENABLE_SIGHASH_FORKID) {
7647 let valueBn;
7648
7649 if (nHashType & Sig.SIGHASH_FORKID && flags & Tx.SCRIPT_ENABLE_SIGHASH_FORKID) {
7650 const txHashBuf = this.tx.txIns[nIn].txHashBuf;
7651 const txOutNum = this.tx.txIns[nIn].txOutNum;
7652 const txOut = this.uTxOutMap.get(txHashBuf, txOutNum);
7653
7654 if (!txOut) {
7655 throw new Error('for SIGHASH_FORKID must provide UTXOs');
7656 }
7657
7658 valueBn = txOut.valueBn;
7659 }
7660
7661 return this.tx.sign(keyPair, nHashType, nIn, subScript, valueBn, flags, this.hashCache);
7662 }
7663
7664 asyncGetSig(keyPair, nHashType = Sig.SIGHASH_ALL | Sig.SIGHASH_FORKID, nIn, subScript, flags = Tx.SCRIPT_ENABLE_SIGHASH_FORKID) {
7665 let valueBn;
7666
7667 if (nHashType & Sig.SIGHASH_FORKID && flags & Tx.SCRIPT_ENABLE_SIGHASH_FORKID) {
7668 const txHashBuf = this.tx.txIns[nIn].txHashBuf;
7669 const txOutNum = this.tx.txIns[nIn].txOutNum;
7670 const txOut = this.uTxOutMap.get(txHashBuf, txOutNum);
7671
7672 if (!txOut) {
7673 throw new Error('for SIGHASH_FORKID must provide UTXOs');
7674 }
7675
7676 valueBn = txOut.valueBn;
7677 }
7678
7679 return this.tx.asyncSign(keyPair, nHashType, nIn, subScript, valueBn, flags, this.hashCache);
7680 }
7681
7682 signTxIn(nIn, keyPair, txOut, nScriptChunk, nHashType = Sig.SIGHASH_ALL | Sig.SIGHASH_FORKID, flags = Tx.SCRIPT_ENABLE_SIGHASH_FORKID) {
7683 const txIn = this.tx.txIns[nIn];
7684 const script = txIn.script;
7685
7686 if (nScriptChunk === undefined && script.isPubKeyHashIn()) {
7687 nScriptChunk = 0;
7688 }
7689
7690 if (nScriptChunk === undefined) {
7691 throw new Error('cannot sign unknown script type for input ' + nIn);
7692 }
7693
7694 const txHashBuf = txIn.txHashBuf;
7695 const txOutNum = txIn.txOutNum;
7696
7697 if (!txOut) {
7698 txOut = this.uTxOutMap.get(txHashBuf, txOutNum);
7699 }
7700
7701 const outScript = txOut.script;
7702 const subScript = outScript;
7703 const sig = this.getSig(keyPair, nHashType, nIn, subScript, flags, this.hashCache);
7704 this.fillSig(nIn, nScriptChunk, sig);
7705 return this;
7706 }
7707
7708 async asyncSignTxIn(nIn, keyPair, txOut, nScriptChunk, nHashType = Sig.SIGHASH_ALL | Sig.SIGHASH_FORKID, flags = Tx.SCRIPT_ENABLE_SIGHASH_FORKID) {
7709 const txIn = this.tx.txIns[nIn];
7710 const script = txIn.script;
7711
7712 if (nScriptChunk === undefined && script.isPubKeyHashIn()) {
7713 nScriptChunk = 0;
7714 }
7715
7716 if (nScriptChunk === undefined) {
7717 throw new Error('cannot sign unknown script type for input ' + nIn);
7718 }
7719
7720 const txHashBuf = txIn.txHashBuf;
7721 const txOutNum = txIn.txOutNum;
7722
7723 if (!txOut) {
7724 txOut = this.uTxOutMap.get(txHashBuf, txOutNum);
7725 }
7726
7727 const outScript = txOut.script;
7728 const subScript = outScript;
7729 const sig = await this.asyncGetSig(keyPair, nHashType, nIn, subScript, flags, this.hashCache);
7730 this.fillSig(nIn, nScriptChunk, sig);
7731 return this;
7732 }
7733
7734 signWithKeyPairs(keyPairs) {
7735 const addressStrMap = {};
7736
7737 for (const keyPair of keyPairs) {
7738 const addressStr = Address.fromPubKey(keyPair.pubKey).toString();
7739 addressStrMap[addressStr] = keyPair;
7740 }
7741
7742 for (const nIn in this.tx.txIns) {
7743 const txIn = this.tx.txIns[nIn];
7744 const arr = this.sigOperations.get(txIn.txHashBuf, txIn.txOutNum);
7745
7746 for (const obj of arr) {
7747 const {
7748 nScriptChunk,
7749 type,
7750 addressStr,
7751 nHashType
7752 } = obj;
7753 const keyPair = addressStrMap[addressStr];
7754
7755 if (!keyPair) {
7756 obj.log = `cannot find keyPair for addressStr ${addressStr}`;
7757 continue;
7758 }
7759
7760 const txOut = this.uTxOutMap.get(txIn.txHashBuf, txIn.txOutNum);
7761
7762 if (type === 'sig') {
7763 this.signTxIn(nIn, keyPair, txOut, nScriptChunk, nHashType);
7764 obj.log = 'successfully inserted signature';
7765 } else if (type === 'pubKey') {
7766 txIn.script.chunks[nScriptChunk] = new Script().writeBuffer(keyPair.pubKey.toBuffer()).chunks[0];
7767 txIn.setScript(txIn.script);
7768 obj.log = 'successfully inserted public key';
7769 } else {
7770 obj.log = `cannot perform operation of type ${type}`;
7771 continue;
7772 }
7773 }
7774 }
7775
7776 return this;
7777 }
7778
7779}
7780
7781class TxVerifier extends Struct {
7782 constructor(tx, txOutMap, errStr, interp) {
7783 super({
7784 tx,
7785 txOutMap,
7786 errStr,
7787 interp
7788 });
7789 }
7790
7791 verify(flags = Interp.SCRIPT_ENABLE_SIGHASH_FORKID) {
7792 return !this.checkStr() && !this.verifyStr(flags);
7793 }
7794
7795 async asyncVerify(flags) {
7796 const verifyStr = await this.asyncVerifyStr(flags);
7797 return !this.checkStr() && !verifyStr;
7798 }
7799
7800 static verify(tx, txOutMap, flags) {
7801 return new TxVerifier(tx, txOutMap).verify(flags);
7802 }
7803
7804 static asyncVerify(tx, txOutMap, flags) {
7805 return new TxVerifier(tx, txOutMap).asyncVerify(flags);
7806 }
7807
7808 checkStr() {
7809 if (this.tx.txIns.length === 0 || this.tx.txInsVi.toNumber() === 0) {
7810 this.errStr = 'transaction txIns empty';
7811 return this.errStr;
7812 }
7813
7814 if (this.tx.txOuts.length === 0 || this.tx.txOutsVi.toNumber() === 0) {
7815 this.errStr = 'transaction txOuts empty';
7816 return this.errStr;
7817 }
7818
7819 if (this.tx.toBuffer().length > Block.MAX_BLOCK_SIZE) {
7820 this.errStr = 'transaction over the maximum block size';
7821 return this.errStr;
7822 }
7823
7824 let valueoutbn = new Bn(0);
7825
7826 for (let i = 0; i < this.tx.txOuts.length; i++) {
7827 const txOut = this.tx.txOuts[i];
7828
7829 if (txOut.valueBn.lt(0)) {
7830 this.errStr = 'transaction txOut ' + i + ' negative';
7831 return this.errStr;
7832 }
7833
7834 if (txOut.valueBn.gt(Tx.MAX_MONEY)) {
7835 this.errStr = 'transaction txOut ' + i + ' greater than MAX_MONEY';
7836 return this.errStr;
7837 }
7838
7839 valueoutbn = valueoutbn.add(txOut.valueBn);
7840
7841 if (valueoutbn.gt(Tx.MAX_MONEY)) {
7842 this.errStr = 'transaction txOut ' + i + ' total output greater than MAX_MONEY';
7843 return this.errStr;
7844 }
7845 }
7846
7847 const txInmap = {};
7848
7849 for (let i = 0; i < this.tx.txIns.length; i++) {
7850 const txIn = this.tx.txIns[i];
7851 const inputid = txIn.txHashBuf.toString('hex') + ':' + txIn.txOutNum;
7852
7853 if (txInmap[inputid] !== undefined) {
7854 this.errStr = 'transaction input ' + i + ' duplicate input';
7855 return this.errStr;
7856 }
7857
7858 txInmap[inputid] = true;
7859 }
7860
7861 if (this.tx.isCoinbase()) {
7862 const buf = this.tx.txIns[0].script.toBuffer();
7863
7864 if (buf.length < 2 || buf.length > 100) {
7865 this.errStr = 'coinbase trasaction script size invalid';
7866 return this.errStr;
7867 }
7868 } else {
7869 for (let i = 0; i < this.tx.txIns.length; i++) {
7870 if (this.tx.txIns[i].hasNullInput()) {
7871 this.errStr = 'transaction input ' + i + ' has null input';
7872 return this.errStr;
7873 }
7874 }
7875 }
7876
7877 return false;
7878 }
7879
7880 verifyStr(flags) {
7881 for (let i = 0; i < this.tx.txIns.length; i++) {
7882 if (!this.verifyNIn(i, flags)) {
7883 this.errStr = 'input ' + i + ' failed script verify';
7884 return this.errStr;
7885 }
7886 }
7887
7888 return false;
7889 }
7890
7891 async asyncVerifyStr(flags) {
7892 for (let i = 0; i < this.tx.txIns.length; i++) {
7893 const verifyNIn = await this.asyncVerifyNIn(i, flags);
7894
7895 if (!verifyNIn) {
7896 this.errStr = 'input ' + i + ' failed script verify';
7897 return this.errStr;
7898 }
7899 }
7900
7901 return false;
7902 }
7903
7904 verifyNIn(nIn, flags) {
7905 const txIn = this.tx.txIns[nIn];
7906 const scriptSig = txIn.script;
7907 const txOut = this.txOutMap.get(txIn.txHashBuf, txIn.txOutNum);
7908
7909 if (!txOut) {
7910 console.log('output ' + txIn.txOutNum + ' not found');
7911 return false;
7912 }
7913
7914 const scriptPubKey = txOut.script;
7915 const valueBn = txOut.valueBn;
7916 this.interp = new Interp();
7917 const verified = this.interp.verify(scriptSig, scriptPubKey, this.tx, nIn, flags, valueBn);
7918 return verified;
7919 }
7920
7921 async asyncVerifyNIn(nIn, flags) {
7922 const txIn = this.tx.txIns[nIn];
7923 const scriptSig = txIn.script;
7924 const txOut = this.txOutMap.get(txIn.txHashBuf, txIn.txOutNum);
7925
7926 if (!txOut) {
7927 console.log('output ' + txIn.txOutNum + ' not found');
7928 return false;
7929 }
7930
7931 const scriptPubKey = txOut.script;
7932 const valueBn = txOut.valueBn;
7933 this.interp = new Interp();
7934 const workersResult = await Workers.asyncObjectMethod(this.interp, 'verify', [scriptSig, scriptPubKey, this.tx, nIn, flags, valueBn]);
7935 const verified = JSON.parse(workersResult.resbuf.toString());
7936 return verified;
7937 }
7938
7939 getDebugObject() {
7940 return {
7941 errStr: this.errStr,
7942 interpFailure: this.interp ? this.interp.getDebugObject() : undefined
7943 };
7944 }
7945
7946 getDebugString() {
7947 return JSON.stringify(this.getDebugObject(), null, 2);
7948 }
7949
7950}
7951
7952class Aes {}
7953
7954Aes.encrypt = function (messageBuf, keyBuf) {
7955 const key = Aes.buf2Words(keyBuf);
7956 const message = Aes.buf2Words(messageBuf);
7957 const a = new _Aes(key);
7958 const enc = a.encrypt(message);
7959 const encBuf = Aes.words2Buf(enc);
7960 return encBuf;
7961};
7962
7963Aes.decrypt = function (encBuf, keyBuf) {
7964 const enc = Aes.buf2Words(encBuf);
7965 const key = Aes.buf2Words(keyBuf);
7966 const a = new _Aes(key);
7967 const message = a.decrypt(enc);
7968 const messageBuf = Aes.words2Buf(message);
7969 return messageBuf;
7970};
7971
7972Aes.buf2Words = function (buf) {
7973 if (buf.length % 4) {
7974 throw new Error('buf length must be a multiple of 4');
7975 }
7976
7977 const words = [];
7978
7979 for (let i = 0; i < buf.length / 4; i++) {
7980 words.push(buf.readUInt32BE(i * 4));
7981 }
7982
7983 return words;
7984};
7985
7986Aes.words2Buf = function (words) {
7987 const buf = Buffer.alloc(words.length * 4);
7988
7989 for (let i = 0; i < words.length; i++) {
7990 buf.writeUInt32BE(words[i], i * 4);
7991 }
7992
7993 return buf;
7994};
7995
7996class Cbc {}
7997
7998Cbc.buf2BlocksBuf = function (buf, blockSize) {
7999 const bytesize = blockSize / 8;
8000 const blockBufs = [];
8001
8002 for (let i = 0; i <= buf.length / bytesize; i++) {
8003 let blockBuf = buf.slice(i * bytesize, i * bytesize + bytesize);
8004
8005 if (blockBuf.length < blockSize) {
8006 blockBuf = Cbc.pkcs7Pad(blockBuf, blockSize);
8007 }
8008
8009 blockBufs.push(blockBuf);
8010 }
8011
8012 return blockBufs;
8013};
8014
8015Cbc.blockBufs2Buf = function (blockBufs) {
8016 let last = blockBufs[blockBufs.length - 1];
8017 last = Cbc.pkcs7Unpad(last);
8018 blockBufs[blockBufs.length - 1] = last;
8019 const buf = Buffer.concat(blockBufs);
8020 return buf;
8021};
8022
8023Cbc.encrypt = function (messageBuf, ivBuf, blockCipher, cipherKeyBuf) {
8024 const blockSize = ivBuf.length * 8;
8025 const blockBufs = Cbc.buf2BlocksBuf(messageBuf, blockSize);
8026 const encBufs = Cbc.encryptBlocks(blockBufs, ivBuf, blockCipher, cipherKeyBuf);
8027 const encBuf = Buffer.concat(encBufs);
8028 return encBuf;
8029};
8030
8031Cbc.decrypt = function (encBuf, ivBuf, blockCipher, cipherKeyBuf) {
8032 const bytesize = ivBuf.length;
8033 const encBufs = [];
8034
8035 for (let i = 0; i < encBuf.length / bytesize; i++) {
8036 encBufs.push(encBuf.slice(i * bytesize, i * bytesize + bytesize));
8037 }
8038
8039 const blockBufs = Cbc.decryptBlocks(encBufs, ivBuf, blockCipher, cipherKeyBuf);
8040 const buf = Cbc.blockBufs2Buf(blockBufs);
8041 return buf;
8042};
8043
8044Cbc.encryptBlock = function (blockBuf, ivBuf, blockCipher, cipherKeyBuf) {
8045 const xorbuf = Cbc.xorBufs(blockBuf, ivBuf);
8046 const encBuf = blockCipher.encrypt(xorbuf, cipherKeyBuf);
8047 return encBuf;
8048};
8049
8050Cbc.decryptBlock = function (encBuf, ivBuf, blockCipher, cipherKeyBuf) {
8051 const xorbuf = blockCipher.decrypt(encBuf, cipherKeyBuf);
8052 const blockBuf = Cbc.xorBufs(xorbuf, ivBuf);
8053 return blockBuf;
8054};
8055
8056Cbc.encryptBlocks = function (blockBufs, ivBuf, blockCipher, cipherKeyBuf) {
8057 const encBufs = [];
8058
8059 for (let i = 0; i < blockBufs.length; i++) {
8060 const blockBuf = blockBufs[i];
8061 const encBuf = Cbc.encryptBlock(blockBuf, ivBuf, blockCipher, cipherKeyBuf);
8062 encBufs.push(encBuf);
8063 ivBuf = encBuf;
8064 }
8065
8066 return encBufs;
8067};
8068
8069Cbc.decryptBlocks = function (encBufs, ivBuf, blockCipher, cipherKeyBuf) {
8070 const blockBufs = [];
8071
8072 for (let i = 0; i < encBufs.length; i++) {
8073 const encBuf = encBufs[i];
8074 const blockBuf = Cbc.decryptBlock(encBuf, ivBuf, blockCipher, cipherKeyBuf);
8075 blockBufs.push(blockBuf);
8076 ivBuf = encBuf;
8077 }
8078
8079 return blockBufs;
8080};
8081
8082Cbc.pkcs7Pad = function (buf, blockSize) {
8083 const bytesize = blockSize / 8;
8084 const padbytesize = bytesize - buf.length;
8085 const pad = Buffer.alloc(padbytesize);
8086 pad.fill(padbytesize);
8087 const paddedbuf = Buffer.concat([buf, pad]);
8088 return paddedbuf;
8089};
8090
8091Cbc.pkcs7Unpad = function (paddedbuf) {
8092 const padlength = paddedbuf[paddedbuf.length - 1];
8093 const padbuf = paddedbuf.slice(paddedbuf.length - padlength, paddedbuf.length);
8094 const padbuf2 = Buffer.alloc(padlength);
8095 padbuf2.fill(padlength);
8096
8097 if (!cmp(padbuf, padbuf2)) {
8098 throw new Error('invalid padding');
8099 }
8100
8101 return paddedbuf.slice(0, paddedbuf.length - padlength);
8102};
8103
8104Cbc.xorBufs = function (buf1, buf2) {
8105 if (buf1.length !== buf2.length) {
8106 throw new Error('bufs must have the same length');
8107 }
8108
8109 const buf = Buffer.alloc(buf1.length);
8110
8111 for (let i = 0; i < buf1.length; i++) {
8112 buf[i] = buf1[i] ^ buf2[i];
8113 }
8114
8115 return buf;
8116};
8117
8118class Aescbc {}
8119
8120Aescbc.encrypt = function (messageBuf, cipherKeyBuf, ivBuf, concatIvBuf = true) {
8121 ivBuf = ivBuf || Random.getRandomBuffer(128 / 8);
8122 const ctBuf = Cbc.encrypt(messageBuf, ivBuf, Aes, cipherKeyBuf);
8123
8124 if (concatIvBuf) {
8125 return Buffer.concat([ivBuf, ctBuf]);
8126 } else {
8127 return ctBuf;
8128 }
8129};
8130
8131Aescbc.decrypt = function (encBuf, cipherKeyBuf, ivBuf = false) {
8132 if (!ivBuf) {
8133 const _ivBuf = encBuf.slice(0, 128 / 8);
8134
8135 const ctBuf = encBuf.slice(128 / 8);
8136 return Cbc.decrypt(ctBuf, _ivBuf, Aes, cipherKeyBuf);
8137 } else {
8138 const ctBuf = encBuf;
8139 return Cbc.decrypt(ctBuf, ivBuf, Aes, cipherKeyBuf);
8140 }
8141};
8142
8143class Ach {}
8144
8145Ach.encrypt = function (messageBuf, cipherKeyBuf, ivBuf) {
8146 const encBuf = Aescbc.encrypt(messageBuf, cipherKeyBuf, ivBuf);
8147 const hmacbuf = Hash.sha256Hmac(encBuf, cipherKeyBuf);
8148 return Buffer.concat([hmacbuf, encBuf]);
8149};
8150
8151Ach.asyncEncrypt = async function (messageBuf, cipherKeyBuf, ivBuf) {
8152 if (!ivBuf) {
8153 ivBuf = Random.getRandomBuffer(128 / 8);
8154 }
8155
8156 const args = [messageBuf, cipherKeyBuf, ivBuf];
8157 const workersResult = await Workers.asyncClassMethod(Ach, 'encrypt', args);
8158 return workersResult.resbuf;
8159};
8160
8161Ach.decrypt = function (encBuf, cipherKeyBuf) {
8162 if (encBuf.length < (256 + 128 + 128) / 8) {
8163 throw new Error('The encrypted data must be at least 256+128+128 bits, which is the length of the Hmac plus the iv plus the smallest encrypted data size');
8164 }
8165
8166 const hmacbuf = encBuf.slice(0, 256 / 8);
8167 encBuf = encBuf.slice(256 / 8, encBuf.length);
8168 const hmacbuf2 = Hash.sha256Hmac(encBuf, cipherKeyBuf);
8169
8170 if (!cmp(hmacbuf, hmacbuf2)) {
8171 throw new Error('Message authentication failed - Hmacs are not equivalent');
8172 }
8173
8174 return Aescbc.decrypt(encBuf, cipherKeyBuf);
8175};
8176
8177Ach.asyncDecrypt = async function (encBuf, cipherKeyBuf) {
8178 const args = [encBuf, cipherKeyBuf];
8179 const workersResult = await Workers.asyncClassMethod(Ach, 'decrypt', args);
8180 return workersResult.resbuf;
8181};
8182
8183class Ecies {}
8184
8185Ecies.ivkEkM = function (privKey, pubKey) {
8186 const r = privKey.bn;
8187 const KB = pubKey.point;
8188 const P = KB.mul(r);
8189 const S = new PubKey(P);
8190 const Sbuf = S.toBuffer();
8191 const hash = Hash.sha512(Sbuf);
8192 return {
8193 iv: hash.slice(0, 16),
8194 kE: hash.slice(16, 32),
8195 kM: hash.slice(32, 64)
8196 };
8197};
8198
8199Ecies.electrumEncrypt = function (messageBuf, toPubKey, fromKeyPair, noKey = false) {
8200 if (!Buffer.isBuffer(messageBuf)) {
8201 throw new Error('messageBuf must be a buffer');
8202 }
8203
8204 let Rbuf;
8205
8206 if (fromKeyPair === null) {
8207 fromKeyPair = KeyPair.fromRandom();
8208 }
8209
8210 if (!noKey) {
8211 Rbuf = fromKeyPair.pubKey.toDer(true);
8212 }
8213
8214 const {
8215 iv,
8216 kE,
8217 kM
8218 } = Ecies.ivkEkM(fromKeyPair.privKey, toPubKey);
8219 const ciphertext = Aescbc.encrypt(messageBuf, kE, iv, false);
8220 const BIE1 = Buffer.from('BIE1');
8221 let encBuf;
8222
8223 if (Rbuf) {
8224 encBuf = Buffer.concat([BIE1, Rbuf, ciphertext]);
8225 } else {
8226 encBuf = Buffer.concat([BIE1, ciphertext]);
8227 }
8228
8229 const hmac = Hash.sha256Hmac(encBuf, kM);
8230 return Buffer.concat([encBuf, hmac]);
8231};
8232
8233Ecies.electrumDecrypt = function (encBuf, toPrivKey, fromPubKey = null) {
8234 if (!Buffer.isBuffer(encBuf)) {
8235 throw new Error('encBuf must be a buffer');
8236 }
8237
8238 const tagLength = 32;
8239 const magic = encBuf.slice(0, 4);
8240
8241 if (!magic.equals(Buffer.from('BIE1'))) {
8242 throw new Error('Invalid Magic');
8243 }
8244
8245 let offset = 4;
8246
8247 if (fromPubKey === null) {
8248 const pub = encBuf.slice(4, 37);
8249 fromPubKey = PubKey.fromDer(pub);
8250 offset = 37;
8251 }
8252
8253 const {
8254 iv,
8255 kE,
8256 kM
8257 } = Ecies.ivkEkM(toPrivKey, fromPubKey);
8258 const ciphertext = encBuf.slice(offset, encBuf.length - tagLength);
8259 const hmac = encBuf.slice(encBuf.length - tagLength, encBuf.length);
8260 const hmac2 = Hash.sha256Hmac(encBuf.slice(0, encBuf.length - tagLength), kM);
8261
8262 if (!hmac.equals(hmac2)) {
8263 throw new Error('Invalid checksum');
8264 }
8265
8266 return Aescbc.decrypt(ciphertext, kE, iv);
8267};
8268
8269Ecies.bitcoreEncrypt = function (messageBuf, toPubKey, fromKeyPair, ivBuf) {
8270 if (!fromKeyPair) {
8271 fromKeyPair = KeyPair.fromRandom();
8272 }
8273
8274 const r = fromKeyPair.privKey.bn;
8275 const RPubKey = fromKeyPair.pubKey;
8276 const RBuf = RPubKey.toDer(true);
8277 const KB = toPubKey.point;
8278 const P = KB.mul(r);
8279 const S = P.getX();
8280 const Sbuf = S.toBuffer({
8281 size: 32
8282 });
8283 const kEkM = Hash.sha512(Sbuf);
8284 const kE = kEkM.slice(0, 32);
8285 const kM = kEkM.slice(32, 64);
8286 const c = Aescbc.encrypt(messageBuf, kE, ivBuf);
8287 const d = Hash.sha256Hmac(c, kM);
8288 const encBuf = Buffer.concat([RBuf, c, d]);
8289 return encBuf;
8290};
8291
8292Ecies.asyncBitcoreEncrypt = async function (messageBuf, toPubKey, fromKeyPair, ivBuf) {
8293 if (!fromKeyPair) {
8294 fromKeyPair = await KeyPair.asyncFromRandom();
8295 }
8296
8297 if (!ivBuf) {
8298 ivBuf = Random.getRandomBuffer(128 / 8);
8299 }
8300
8301 const args = [messageBuf, toPubKey, fromKeyPair, ivBuf];
8302 const workersResult = await Workers.asyncClassMethod(Ecies, 'bitcoreEncrypt', args);
8303 return workersResult.resbuf;
8304};
8305
8306Ecies.bitcoreDecrypt = function (encBuf, toPrivKey) {
8307 const kB = toPrivKey.bn;
8308 const fromPubKey = PubKey.fromDer(encBuf.slice(0, 33));
8309 const R = fromPubKey.point;
8310 const P = R.mul(kB);
8311
8312 if (P.eq(new Point())) {
8313 throw new Error('P equals 0');
8314 }
8315
8316 const S = P.getX();
8317 const Sbuf = S.toBuffer({
8318 size: 32
8319 });
8320 const kEkM = Hash.sha512(Sbuf);
8321 const kE = kEkM.slice(0, 32);
8322 const kM = kEkM.slice(32, 64);
8323 const c = encBuf.slice(33, encBuf.length - 32);
8324 const d = encBuf.slice(encBuf.length - 32, encBuf.length);
8325 const d2 = Hash.sha256Hmac(c, kM);
8326
8327 if (!cmp(d, d2)) {
8328 throw new Error('Invalid checksum');
8329 }
8330
8331 const messageBuf = Aescbc.decrypt(c, kE);
8332 return messageBuf;
8333};
8334
8335Ecies.asyncBitcoreDecrypt = async function (encBuf, toPrivKey) {
8336 const args = [encBuf, toPrivKey];
8337 const workersResult = await Workers.asyncClassMethod(Ecies, 'bitcoreDecrypt', args);
8338 return workersResult.resbuf;
8339};
8340
8341const deps = {
8342 aes: _Aes,
8343 bnjs: _Bn,
8344 bs58,
8345 elliptic,
8346 hashjs,
8347 pbkdf2compat: pbkdf2
8348};
8349
8350export { Ach, Address, Aes, Aescbc, Base58, Base58Check, Bip32, Bip39, Block, BlockHeader, Bn, Br, Bsm, Bw, Cbc, Constants, Ecdsa, Ecies, Hash, Interp, KeyPair, OpCode, Point, PrivKey, PubKey, Random, Script, Sig, Struct, Tx, TxBuilder, TxIn, TxOut, TxOutMap, TxVerifier, VarInt, Workers, WorkersResult, cmp, deps, wordList as en, wordList$1 as jp, version };
8351//# sourceMappingURL=bsv.modern.js.map