xpi-ts 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +516 -0
  3. package/dist/index.d.ts +9 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +8 -0
  6. package/dist/lib/bitcore/address.d.ts +66 -0
  7. package/dist/lib/bitcore/address.d.ts.map +1 -0
  8. package/dist/lib/bitcore/address.js +407 -0
  9. package/dist/lib/bitcore/block/block.d.ts +57 -0
  10. package/dist/lib/bitcore/block/block.d.ts.map +1 -0
  11. package/dist/lib/bitcore/block/block.js +233 -0
  12. package/dist/lib/bitcore/block/blockheader.d.ts +82 -0
  13. package/dist/lib/bitcore/block/blockheader.d.ts.map +1 -0
  14. package/dist/lib/bitcore/block/blockheader.js +323 -0
  15. package/dist/lib/bitcore/block/index.d.ts +5 -0
  16. package/dist/lib/bitcore/block/index.d.ts.map +1 -0
  17. package/dist/lib/bitcore/block/index.js +2 -0
  18. package/dist/lib/bitcore/chunk.d.ts +22 -0
  19. package/dist/lib/bitcore/chunk.d.ts.map +1 -0
  20. package/dist/lib/bitcore/chunk.js +46 -0
  21. package/dist/lib/bitcore/crypto/bn.d.ts +53 -0
  22. package/dist/lib/bitcore/crypto/bn.d.ts.map +1 -0
  23. package/dist/lib/bitcore/crypto/bn.js +238 -0
  24. package/dist/lib/bitcore/crypto/ecdsa.d.ts +46 -0
  25. package/dist/lib/bitcore/crypto/ecdsa.d.ts.map +1 -0
  26. package/dist/lib/bitcore/crypto/ecdsa.js +247 -0
  27. package/dist/lib/bitcore/crypto/hash.d.ts +16 -0
  28. package/dist/lib/bitcore/crypto/hash.d.ts.map +1 -0
  29. package/dist/lib/bitcore/crypto/hash.js +87 -0
  30. package/dist/lib/bitcore/crypto/index.d.ts +9 -0
  31. package/dist/lib/bitcore/crypto/index.d.ts.map +1 -0
  32. package/dist/lib/bitcore/crypto/index.js +8 -0
  33. package/dist/lib/bitcore/crypto/musig2.d.ts +40 -0
  34. package/dist/lib/bitcore/crypto/musig2.d.ts.map +1 -0
  35. package/dist/lib/bitcore/crypto/musig2.js +236 -0
  36. package/dist/lib/bitcore/crypto/point.d.ts +20 -0
  37. package/dist/lib/bitcore/crypto/point.d.ts.map +1 -0
  38. package/dist/lib/bitcore/crypto/point.js +133 -0
  39. package/dist/lib/bitcore/crypto/random.d.ts +7 -0
  40. package/dist/lib/bitcore/crypto/random.d.ts.map +1 -0
  41. package/dist/lib/bitcore/crypto/random.js +30 -0
  42. package/dist/lib/bitcore/crypto/schnorr.d.ts +40 -0
  43. package/dist/lib/bitcore/crypto/schnorr.d.ts.map +1 -0
  44. package/dist/lib/bitcore/crypto/schnorr.js +185 -0
  45. package/dist/lib/bitcore/crypto/signature.d.ts +53 -0
  46. package/dist/lib/bitcore/crypto/signature.d.ts.map +1 -0
  47. package/dist/lib/bitcore/crypto/signature.js +300 -0
  48. package/dist/lib/bitcore/crypto/sigtype.d.ts +5 -0
  49. package/dist/lib/bitcore/crypto/sigtype.d.ts.map +1 -0
  50. package/dist/lib/bitcore/crypto/sigtype.js +18 -0
  51. package/dist/lib/bitcore/encoding/base58.d.ts +16 -0
  52. package/dist/lib/bitcore/encoding/base58.d.ts.map +1 -0
  53. package/dist/lib/bitcore/encoding/base58.js +55 -0
  54. package/dist/lib/bitcore/encoding/base58check.d.ts +9 -0
  55. package/dist/lib/bitcore/encoding/base58check.d.ts.map +1 -0
  56. package/dist/lib/bitcore/encoding/base58check.js +82 -0
  57. package/dist/lib/bitcore/encoding/bufferreader.d.ts +34 -0
  58. package/dist/lib/bitcore/encoding/bufferreader.d.ts.map +1 -0
  59. package/dist/lib/bitcore/encoding/bufferreader.js +198 -0
  60. package/dist/lib/bitcore/encoding/bufferwriter.d.ts +36 -0
  61. package/dist/lib/bitcore/encoding/bufferwriter.d.ts.map +1 -0
  62. package/dist/lib/bitcore/encoding/bufferwriter.js +189 -0
  63. package/dist/lib/bitcore/encoding/varint.d.ts +20 -0
  64. package/dist/lib/bitcore/encoding/varint.d.ts.map +1 -0
  65. package/dist/lib/bitcore/encoding/varint.js +61 -0
  66. package/dist/lib/bitcore/errors.d.ts +28 -0
  67. package/dist/lib/bitcore/errors.d.ts.map +1 -0
  68. package/dist/lib/bitcore/errors.js +325 -0
  69. package/dist/lib/bitcore/hdprivatekey.d.ts +78 -0
  70. package/dist/lib/bitcore/hdprivatekey.d.ts.map +1 -0
  71. package/dist/lib/bitcore/hdprivatekey.js +381 -0
  72. package/dist/lib/bitcore/hdpublickey.d.ts +98 -0
  73. package/dist/lib/bitcore/hdpublickey.d.ts.map +1 -0
  74. package/dist/lib/bitcore/hdpublickey.js +416 -0
  75. package/dist/lib/bitcore/index.d.ts +60 -0
  76. package/dist/lib/bitcore/index.d.ts.map +1 -0
  77. package/dist/lib/bitcore/index.js +44 -0
  78. package/dist/lib/bitcore/message.d.ts +23 -0
  79. package/dist/lib/bitcore/message.d.ts.map +1 -0
  80. package/dist/lib/bitcore/message.js +112 -0
  81. package/dist/lib/bitcore/mnemonic/errors.d.ts +7 -0
  82. package/dist/lib/bitcore/mnemonic/errors.d.ts.map +1 -0
  83. package/dist/lib/bitcore/mnemonic/errors.js +20 -0
  84. package/dist/lib/bitcore/mnemonic/index.d.ts +5 -0
  85. package/dist/lib/bitcore/mnemonic/index.d.ts.map +1 -0
  86. package/dist/lib/bitcore/mnemonic/index.js +4 -0
  87. package/dist/lib/bitcore/mnemonic/mnemonic.d.ts +23 -0
  88. package/dist/lib/bitcore/mnemonic/mnemonic.d.ts.map +1 -0
  89. package/dist/lib/bitcore/mnemonic/mnemonic.js +164 -0
  90. package/dist/lib/bitcore/mnemonic/pbkdf2.d.ts +2 -0
  91. package/dist/lib/bitcore/mnemonic/pbkdf2.d.ts.map +1 -0
  92. package/dist/lib/bitcore/mnemonic/pbkdf2.js +25 -0
  93. package/dist/lib/bitcore/mnemonic/words/english.d.ts +2 -0
  94. package/dist/lib/bitcore/mnemonic/words/english.d.ts.map +1 -0
  95. package/dist/lib/bitcore/mnemonic/words/english.js +2050 -0
  96. package/dist/lib/bitcore/mnemonic/words/index.d.ts +4 -0
  97. package/dist/lib/bitcore/mnemonic/words/index.d.ts.map +1 -0
  98. package/dist/lib/bitcore/mnemonic/words/index.js +4 -0
  99. package/dist/lib/bitcore/musig2/index.d.ts +3 -0
  100. package/dist/lib/bitcore/musig2/index.d.ts.map +1 -0
  101. package/dist/lib/bitcore/musig2/index.js +2 -0
  102. package/dist/lib/bitcore/musig2/session.d.ts +79 -0
  103. package/dist/lib/bitcore/musig2/session.d.ts.map +1 -0
  104. package/dist/lib/bitcore/musig2/session.js +346 -0
  105. package/dist/lib/bitcore/musig2/signer.d.ts +61 -0
  106. package/dist/lib/bitcore/musig2/signer.d.ts.map +1 -0
  107. package/dist/lib/bitcore/musig2/signer.js +146 -0
  108. package/dist/lib/bitcore/networks.d.ts +53 -0
  109. package/dist/lib/bitcore/networks.d.ts.map +1 -0
  110. package/dist/lib/bitcore/networks.js +150 -0
  111. package/dist/lib/bitcore/opcode.d.ts +250 -0
  112. package/dist/lib/bitcore/opcode.d.ts.map +1 -0
  113. package/dist/lib/bitcore/opcode.js +270 -0
  114. package/dist/lib/bitcore/privatekey.d.ts +56 -0
  115. package/dist/lib/bitcore/privatekey.d.ts.map +1 -0
  116. package/dist/lib/bitcore/privatekey.js +237 -0
  117. package/dist/lib/bitcore/publickey.d.ts +59 -0
  118. package/dist/lib/bitcore/publickey.d.ts.map +1 -0
  119. package/dist/lib/bitcore/publickey.js +263 -0
  120. package/dist/lib/bitcore/script/interpreter.d.ts +98 -0
  121. package/dist/lib/bitcore/script/interpreter.d.ts.map +1 -0
  122. package/dist/lib/bitcore/script/interpreter.js +1704 -0
  123. package/dist/lib/bitcore/script.d.ts +111 -0
  124. package/dist/lib/bitcore/script.d.ts.map +1 -0
  125. package/dist/lib/bitcore/script.js +1112 -0
  126. package/dist/lib/bitcore/taproot/musig2.d.ts +29 -0
  127. package/dist/lib/bitcore/taproot/musig2.d.ts.map +1 -0
  128. package/dist/lib/bitcore/taproot/musig2.js +104 -0
  129. package/dist/lib/bitcore/taproot/nft.d.ts +164 -0
  130. package/dist/lib/bitcore/taproot/nft.d.ts.map +1 -0
  131. package/dist/lib/bitcore/taproot/nft.js +407 -0
  132. package/dist/lib/bitcore/taproot.d.ts +65 -0
  133. package/dist/lib/bitcore/taproot.d.ts.map +1 -0
  134. package/dist/lib/bitcore/taproot.js +288 -0
  135. package/dist/lib/bitcore/transaction/index.d.ts +12 -0
  136. package/dist/lib/bitcore/transaction/index.d.ts.map +1 -0
  137. package/dist/lib/bitcore/transaction/index.js +6 -0
  138. package/dist/lib/bitcore/transaction/input.d.ts +202 -0
  139. package/dist/lib/bitcore/transaction/input.d.ts.map +1 -0
  140. package/dist/lib/bitcore/transaction/input.js +911 -0
  141. package/dist/lib/bitcore/transaction/output.d.ts +48 -0
  142. package/dist/lib/bitcore/transaction/output.d.ts.map +1 -0
  143. package/dist/lib/bitcore/transaction/output.js +231 -0
  144. package/dist/lib/bitcore/transaction/sighash.d.ts +32 -0
  145. package/dist/lib/bitcore/transaction/sighash.d.ts.map +1 -0
  146. package/dist/lib/bitcore/transaction/sighash.js +335 -0
  147. package/dist/lib/bitcore/transaction/signature.d.ts +36 -0
  148. package/dist/lib/bitcore/transaction/signature.d.ts.map +1 -0
  149. package/dist/lib/bitcore/transaction/signature.js +130 -0
  150. package/dist/lib/bitcore/transaction/transaction.d.ts +164 -0
  151. package/dist/lib/bitcore/transaction/transaction.d.ts.map +1 -0
  152. package/dist/lib/bitcore/transaction/transaction.js +1016 -0
  153. package/dist/lib/bitcore/transaction/unspentoutput.d.ts +58 -0
  154. package/dist/lib/bitcore/transaction/unspentoutput.d.ts.map +1 -0
  155. package/dist/lib/bitcore/transaction/unspentoutput.js +167 -0
  156. package/dist/lib/bitcore/unit.d.ts +44 -0
  157. package/dist/lib/bitcore/unit.d.ts.map +1 -0
  158. package/dist/lib/bitcore/unit.js +106 -0
  159. package/dist/lib/bitcore/uri.d.ts +29 -0
  160. package/dist/lib/bitcore/uri.d.ts.map +1 -0
  161. package/dist/lib/bitcore/uri.js +163 -0
  162. package/dist/lib/bitcore/util/base32.d.ts +5 -0
  163. package/dist/lib/bitcore/util/base32.d.ts.map +1 -0
  164. package/dist/lib/bitcore/util/base32.js +58 -0
  165. package/dist/lib/bitcore/util/buffer.d.ts +18 -0
  166. package/dist/lib/bitcore/util/buffer.d.ts.map +1 -0
  167. package/dist/lib/bitcore/util/buffer.js +76 -0
  168. package/dist/lib/bitcore/util/convertBits.d.ts +2 -0
  169. package/dist/lib/bitcore/util/convertBits.d.ts.map +1 -0
  170. package/dist/lib/bitcore/util/convertBits.js +26 -0
  171. package/dist/lib/bitcore/util/js.d.ts +9 -0
  172. package/dist/lib/bitcore/util/js.d.ts.map +1 -0
  173. package/dist/lib/bitcore/util/js.js +45 -0
  174. package/dist/lib/bitcore/util/preconditions.d.ts +6 -0
  175. package/dist/lib/bitcore/util/preconditions.d.ts.map +1 -0
  176. package/dist/lib/bitcore/util/preconditions.js +31 -0
  177. package/dist/lib/bitcore/util.d.ts +14 -0
  178. package/dist/lib/bitcore/util.d.ts.map +1 -0
  179. package/dist/lib/bitcore/util.js +13 -0
  180. package/dist/lib/bitcore/xaddress.d.ts +45 -0
  181. package/dist/lib/bitcore/xaddress.d.ts.map +1 -0
  182. package/dist/lib/bitcore/xaddress.js +279 -0
  183. package/dist/lib/rank/api.d.ts +75 -0
  184. package/dist/lib/rank/api.d.ts.map +1 -0
  185. package/dist/lib/rank/api.js +4 -0
  186. package/dist/lib/rank/index.d.ts +127 -0
  187. package/dist/lib/rank/index.d.ts.map +1 -0
  188. package/dist/lib/rank/index.js +421 -0
  189. package/dist/lib/rank/opcode.d.ts +23 -0
  190. package/dist/lib/rank/opcode.d.ts.map +1 -0
  191. package/dist/lib/rank/opcode.js +23 -0
  192. package/dist/lib/rank/script.d.ts +2 -0
  193. package/dist/lib/rank/script.d.ts.map +1 -0
  194. package/dist/lib/rank/script.js +7 -0
  195. package/dist/lib/rank/transaction.d.ts +3 -0
  196. package/dist/lib/rank/transaction.d.ts.map +1 -0
  197. package/dist/lib/rank/transaction.js +12 -0
  198. package/dist/lib/rpc.d.ts +136 -0
  199. package/dist/lib/rpc.d.ts.map +1 -0
  200. package/dist/lib/rpc.js +62 -0
  201. package/dist/utils/constants.d.ts +18 -0
  202. package/dist/utils/constants.d.ts.map +1 -0
  203. package/dist/utils/constants.js +20 -0
  204. package/dist/utils/env.d.ts +3 -0
  205. package/dist/utils/env.d.ts.map +1 -0
  206. package/dist/utils/env.js +8 -0
  207. package/dist/utils/string.d.ts +11 -0
  208. package/dist/utils/string.d.ts.map +1 -0
  209. package/dist/utils/string.js +47 -0
  210. package/dist/utils/types.d.ts +2 -0
  211. package/dist/utils/types.d.ts.map +1 -0
  212. package/dist/utils/types.js +1 -0
  213. package/dist/utils/wallet.d.ts +12 -0
  214. package/dist/utils/wallet.d.ts.map +1 -0
  215. package/dist/utils/wallet.js +28 -0
  216. package/package.json +91 -0
@@ -0,0 +1,1112 @@
1
+ import { Preconditions } from './util/preconditions.js';
2
+ import { BufferReader } from './encoding/bufferreader.js';
3
+ import { BufferWriter } from './encoding/bufferwriter.js';
4
+ import { Hash } from './crypto/hash.js';
5
+ import { Opcode } from './opcode.js';
6
+ import { PublicKey } from './publickey.js';
7
+ import { Address } from './address.js';
8
+ import { BitcoreError } from './errors.js';
9
+ import { BufferUtil } from './util/buffer.js';
10
+ import { Signature } from './crypto/signature.js';
11
+ import { Chunk } from './chunk.js';
12
+ import { TAPROOT_SIZE_WITH_STATE, TAPROOT_SIZE_WITHOUT_STATE, } from './taproot.js';
13
+ export class Script {
14
+ chunks;
15
+ _network;
16
+ constructor(from) {
17
+ if (Buffer.isBuffer(from)) {
18
+ return Script.fromBuffer(from);
19
+ }
20
+ else if (from instanceof Address) {
21
+ return Script.fromAddress(from);
22
+ }
23
+ else if (from instanceof Script) {
24
+ return Script.fromBuffer(from.toBuffer());
25
+ }
26
+ else if (typeof from === 'string') {
27
+ return Script.fromString(from);
28
+ }
29
+ else if (typeof from === 'object' &&
30
+ from !== null &&
31
+ Array.isArray(from.chunks)) {
32
+ this.set(from);
33
+ }
34
+ else {
35
+ this.chunks = [];
36
+ }
37
+ }
38
+ set(obj) {
39
+ Preconditions.checkArgument(typeof obj === 'object', 'obj', 'Must be an object');
40
+ Preconditions.checkArgument(Array.isArray(obj.chunks), 'obj.chunks', 'Must be an array');
41
+ this.chunks = obj.chunks;
42
+ this._network = obj._network;
43
+ return this;
44
+ }
45
+ static fromBuffer(buffer) {
46
+ const script = new Script();
47
+ script.chunks = [];
48
+ const br = new BufferReader(buffer);
49
+ while (!br.finished()) {
50
+ try {
51
+ const opcodenum = br.readUInt8();
52
+ let len, buf;
53
+ if (opcodenum > 0 && opcodenum < Opcode.OP_PUSHDATA1) {
54
+ len = opcodenum;
55
+ script.chunks.push(new Chunk({
56
+ buf: br.read(len),
57
+ len: len,
58
+ opcodenum: opcodenum,
59
+ }));
60
+ }
61
+ else if (opcodenum === Opcode.OP_PUSHDATA1) {
62
+ len = br.readUInt8();
63
+ buf = br.read(len);
64
+ script.chunks.push(new Chunk({
65
+ buf: buf,
66
+ len: len,
67
+ opcodenum: opcodenum,
68
+ }));
69
+ }
70
+ else if (opcodenum === Opcode.OP_PUSHDATA2) {
71
+ len = br.readUInt16LE();
72
+ buf = br.read(len);
73
+ script.chunks.push(new Chunk({
74
+ buf: buf,
75
+ len: len,
76
+ opcodenum: opcodenum,
77
+ }));
78
+ }
79
+ else if (opcodenum === Opcode.OP_PUSHDATA4) {
80
+ len = br.readUInt32LE();
81
+ buf = br.read(len);
82
+ script.chunks.push(new Chunk({
83
+ buf: buf,
84
+ len: len,
85
+ opcodenum: opcodenum,
86
+ }));
87
+ }
88
+ else {
89
+ script.chunks.push(new Chunk({
90
+ opcodenum: opcodenum,
91
+ }));
92
+ }
93
+ }
94
+ catch (e) {
95
+ if (e instanceof RangeError) {
96
+ throw new BitcoreError.Script.InvalidBuffer(buffer.toString('hex'));
97
+ }
98
+ throw e;
99
+ }
100
+ }
101
+ return script;
102
+ }
103
+ static fromString(str) {
104
+ Preconditions.checkArgument(typeof str === 'string', 'str', 'Must be a string');
105
+ const cleanStr = str.replace(/\s/g, '').toLowerCase();
106
+ if (!/^[0-9a-f]*$/.test(cleanStr)) {
107
+ throw new BitcoreError.Script.InvalidScriptString(str);
108
+ }
109
+ const buffer = Buffer.from(cleanStr, 'hex');
110
+ return Script.fromBuffer(buffer);
111
+ }
112
+ static fromASM(str) {
113
+ const script = new Script();
114
+ script.chunks = [];
115
+ const tokens = str.split(' ');
116
+ let i = 0;
117
+ while (i < tokens.length) {
118
+ const token = tokens[i];
119
+ const opcode = new Opcode(token);
120
+ const opcodenum = opcode.num;
121
+ if (opcodenum === undefined) {
122
+ const buf = Buffer.from(tokens[i], 'hex');
123
+ let opcodenum;
124
+ const len = buf.length;
125
+ if (len >= 0 && len < Opcode.OP_PUSHDATA1) {
126
+ opcodenum = len;
127
+ }
128
+ else if (len < Math.pow(2, 8)) {
129
+ opcodenum = Opcode.OP_PUSHDATA1;
130
+ }
131
+ else if (len < Math.pow(2, 16)) {
132
+ opcodenum = Opcode.OP_PUSHDATA2;
133
+ }
134
+ else if (len < Math.pow(2, 32)) {
135
+ opcodenum = Opcode.OP_PUSHDATA4;
136
+ }
137
+ else {
138
+ throw new Error('Invalid push data length');
139
+ }
140
+ script.chunks.push(new Chunk({
141
+ buf: buf,
142
+ len: buf.length,
143
+ opcodenum: opcodenum,
144
+ }));
145
+ i = i + 1;
146
+ }
147
+ else {
148
+ script.chunks.push(new Chunk({
149
+ opcodenum: opcodenum,
150
+ }));
151
+ i = i + 1;
152
+ }
153
+ }
154
+ return script;
155
+ }
156
+ static fromHex(str) {
157
+ return new Script(Buffer.from(str, 'hex'));
158
+ }
159
+ static fromAddress(address) {
160
+ if (typeof address === 'string') {
161
+ address = Address.fromString(address);
162
+ }
163
+ if (address.isPayToTaproot()) {
164
+ return Script.buildPayToTaproot(address.hashBuffer);
165
+ }
166
+ else if (address.isPayToScriptHash()) {
167
+ return Script.buildScriptHashOut(address);
168
+ }
169
+ else if (address.isPayToPublicKeyHash()) {
170
+ return Script.buildPublicKeyHashOut(address);
171
+ }
172
+ throw new BitcoreError.Script.UnrecognizedAddress(address);
173
+ }
174
+ static buildMultisigOut(publicKeys, threshold, opts = {}) {
175
+ Preconditions.checkArgument(threshold <= publicKeys.length, 'threshold', 'Number of required signatures must be less than or equal to the number of public keys');
176
+ const script = new Script();
177
+ script.add(Opcode.OP_1 + threshold - 1);
178
+ const sorted = opts.noSorting
179
+ ? publicKeys
180
+ : publicKeys.sort((a, b) => a.toString().localeCompare(b.toString()));
181
+ for (const pubkey of sorted) {
182
+ script.add(pubkey.toBuffer());
183
+ }
184
+ script.add(Opcode.OP_1 + publicKeys.length - 1);
185
+ script.add(Opcode.OP_CHECKMULTISIG);
186
+ return script;
187
+ }
188
+ static buildPublicKeyHashOut(to) {
189
+ Preconditions.checkArgument(to !== undefined, 'to', 'Must be defined');
190
+ Preconditions.checkArgument(to instanceof PublicKey ||
191
+ to instanceof Address ||
192
+ typeof to === 'string', 'to', 'Must be PublicKey, Address, or string');
193
+ let address;
194
+ if (to instanceof PublicKey) {
195
+ address = to.toAddress();
196
+ }
197
+ else if (typeof to === 'string') {
198
+ address = Address.fromString(to);
199
+ }
200
+ else {
201
+ address = to;
202
+ }
203
+ const script = new Script();
204
+ script.chunks = [];
205
+ script
206
+ .add(Opcode.OP_DUP)
207
+ .add(Opcode.OP_HASH160)
208
+ .add(address.hashBuffer)
209
+ .add(Opcode.OP_EQUALVERIFY)
210
+ .add(Opcode.OP_CHECKSIG);
211
+ script._network = address.network;
212
+ return script;
213
+ }
214
+ static buildScriptHashOut(script) {
215
+ Preconditions.checkArgument(script instanceof Script ||
216
+ (script instanceof Address && script.isPayToScriptHash()), 'script', 'Must be Script or P2SH Address');
217
+ const s = new Script();
218
+ s.add(Opcode.OP_HASH160)
219
+ .add(script instanceof Address
220
+ ? script.hashBuffer
221
+ : Hash.sha256ripemd160(script.toBuffer()))
222
+ .add(Opcode.OP_EQUAL);
223
+ s._network =
224
+ script._network ||
225
+ script.network;
226
+ return s;
227
+ }
228
+ static buildMultisigIn(pubkeys, threshold, signatures, opts = {}) {
229
+ const script = new Script();
230
+ if (opts.signingMethod === 'schnorr' && opts.checkBits) {
231
+ const N = pubkeys.length;
232
+ let checkBitsValue = 0;
233
+ for (let i = 0; i < opts.checkBits.length; i++) {
234
+ checkBitsValue |= opts.checkBits[i] << (8 * i);
235
+ }
236
+ if (N >= 1 && N <= 4) {
237
+ script.add(Opcode.OP_1 + checkBitsValue - 1);
238
+ }
239
+ else if (N >= 5 && N <= 8) {
240
+ if (checkBitsValue === 0x81 && N === 8 && threshold === 2) {
241
+ script.add(Opcode.OP_1NEGATE);
242
+ }
243
+ else if (checkBitsValue >= 0x01 && checkBitsValue <= 0x10) {
244
+ script.add(Opcode.OP_1 + checkBitsValue - 1);
245
+ }
246
+ else {
247
+ script.add(0x01);
248
+ script.add(checkBitsValue);
249
+ }
250
+ }
251
+ else if (N >= 9 && N <= 16) {
252
+ script.add(0x02);
253
+ script.add(checkBitsValue & 0xff);
254
+ script.add((checkBitsValue >> 8) & 0xff);
255
+ }
256
+ else if (N >= 17 && N <= 20) {
257
+ script.add(0x03);
258
+ script.add(checkBitsValue & 0xff);
259
+ script.add((checkBitsValue >> 8) & 0xff);
260
+ script.add((checkBitsValue >> 16) & 0xff);
261
+ }
262
+ }
263
+ else {
264
+ script.add(Opcode.OP_0);
265
+ }
266
+ for (const sig of signatures) {
267
+ script.add(sig);
268
+ }
269
+ script.add((opts.cachedMultisig || Script.buildMultisigOut(pubkeys, threshold, opts)).toBuffer());
270
+ return script;
271
+ }
272
+ static buildP2SHMultisigIn(pubkeys, threshold, signatures, opts = {}) {
273
+ const script = new Script();
274
+ if (opts.signingMethod === 'schnorr' && opts.checkBits) {
275
+ const N = pubkeys.length;
276
+ let checkBitsValue = 0;
277
+ for (let i = 0; i < opts.checkBits.length; i++) {
278
+ checkBitsValue |= opts.checkBits[i] << (8 * i);
279
+ }
280
+ if (N >= 1 && N <= 4) {
281
+ script.add(Opcode.OP_1 + checkBitsValue - 1);
282
+ }
283
+ else if (N >= 5 && N <= 8) {
284
+ if (checkBitsValue === 0x81 && N === 8 && threshold === 2) {
285
+ script.add(Opcode.OP_1NEGATE);
286
+ }
287
+ else if (checkBitsValue >= 0x01 && checkBitsValue <= 0x10) {
288
+ script.add(Opcode.OP_1 + checkBitsValue - 1);
289
+ }
290
+ else {
291
+ script.add(0x01);
292
+ script.add(checkBitsValue);
293
+ }
294
+ }
295
+ else if (N >= 9 && N <= 16) {
296
+ script.add(0x02);
297
+ script.add(checkBitsValue & 0xff);
298
+ script.add((checkBitsValue >> 8) & 0xff);
299
+ }
300
+ else if (N >= 17 && N <= 20) {
301
+ script.add(0x03);
302
+ script.add(checkBitsValue & 0xff);
303
+ script.add((checkBitsValue >> 8) & 0xff);
304
+ script.add((checkBitsValue >> 16) & 0xff);
305
+ }
306
+ }
307
+ else {
308
+ script.add(Opcode.OP_0);
309
+ }
310
+ for (const sig of signatures) {
311
+ script.add(sig);
312
+ }
313
+ script.add((opts.cachedMultisig || Script.buildMultisigOut(pubkeys, threshold, opts)).toBuffer());
314
+ return script;
315
+ }
316
+ static buildWitnessMultisigOutFromScript(script) {
317
+ const scriptHash = Hash.sha256(script.toBuffer());
318
+ const witnessScript = new Script();
319
+ witnessScript.add(Opcode.OP_0);
320
+ witnessScript.add(scriptHash);
321
+ return witnessScript;
322
+ }
323
+ static buildPublicKeyOut(pubkey) {
324
+ const script = new Script();
325
+ script.add(pubkey.toBuffer());
326
+ script.add(Opcode.OP_CHECKSIG);
327
+ return script;
328
+ }
329
+ static buildDataOut(data, encoding = 'utf8') {
330
+ let buffer;
331
+ if (typeof data === 'string') {
332
+ if (encoding === 'hex') {
333
+ buffer = Buffer.from(data, 'hex');
334
+ }
335
+ else {
336
+ buffer = Buffer.from(data, 'utf8');
337
+ }
338
+ }
339
+ else {
340
+ buffer = data;
341
+ }
342
+ const script = new Script();
343
+ script.add(Opcode.OP_RETURN);
344
+ script.add(buffer);
345
+ return script;
346
+ }
347
+ static buildPublicKeyIn(signature, sigtype) {
348
+ const script = new Script();
349
+ if (signature instanceof Signature) {
350
+ if (signature.isSchnorr) {
351
+ script.add(signature.toTxFormat('schnorr'));
352
+ }
353
+ else {
354
+ signature = signature.toTxFormat();
355
+ script.add(BufferUtil.concat([
356
+ signature,
357
+ BufferUtil.integerAsSingleByteBuffer(sigtype || Signature.SIGHASH_ALL),
358
+ ]));
359
+ }
360
+ }
361
+ else {
362
+ script.add(BufferUtil.concat([
363
+ signature,
364
+ BufferUtil.integerAsSingleByteBuffer(sigtype || Signature.SIGHASH_ALL),
365
+ ]));
366
+ }
367
+ return script;
368
+ }
369
+ static buildPublicKeyHashIn(publicKey, signature, sigtype) {
370
+ const script = new Script();
371
+ if (signature instanceof Signature) {
372
+ if (signature.isSchnorr) {
373
+ script.add(signature.toTxFormat('schnorr'));
374
+ }
375
+ else {
376
+ signature = signature.toTxFormat();
377
+ script.add(BufferUtil.concat([
378
+ signature,
379
+ BufferUtil.integerAsSingleByteBuffer(sigtype || Signature.SIGHASH_ALL),
380
+ ]));
381
+ }
382
+ }
383
+ else {
384
+ script.add(BufferUtil.concat([
385
+ signature,
386
+ BufferUtil.integerAsSingleByteBuffer(sigtype || Signature.SIGHASH_ALL),
387
+ ]));
388
+ }
389
+ script.add(publicKey.toBuffer());
390
+ return script;
391
+ }
392
+ static buildPayToTaproot(commitment, state) {
393
+ Preconditions.checkArgument(commitment !== undefined, 'commitment', 'Must be defined');
394
+ const commitmentBuf = commitment instanceof PublicKey ? commitment.toBuffer() : commitment;
395
+ if (commitmentBuf.length !== 33) {
396
+ throw new Error('Taproot commitment must be 33-byte compressed public key');
397
+ }
398
+ if (state && state.length !== 32) {
399
+ throw new Error('Taproot state must be exactly 32 bytes');
400
+ }
401
+ const script = new Script();
402
+ script.add(Opcode.OP_SCRIPTTYPE);
403
+ script.add(Opcode.OP_1);
404
+ script.add(commitmentBuf);
405
+ if (state) {
406
+ script.add(state);
407
+ }
408
+ return script;
409
+ }
410
+ add(chunk) {
411
+ if (chunk instanceof Opcode) {
412
+ this.chunks.push(new Chunk({
413
+ opcodenum: chunk.num,
414
+ }));
415
+ }
416
+ else if (Buffer.isBuffer(chunk)) {
417
+ const chunkObj = {
418
+ buf: chunk,
419
+ len: chunk.length,
420
+ opcodenum: chunk.length,
421
+ };
422
+ if (chunk.length < Opcode.OP_PUSHDATA1) {
423
+ chunkObj.opcodenum = chunk.length;
424
+ }
425
+ else if (chunk.length <= 0xff) {
426
+ chunkObj.opcodenum = Opcode.OP_PUSHDATA1;
427
+ }
428
+ else if (chunk.length <= 0xffff) {
429
+ chunkObj.opcodenum = Opcode.OP_PUSHDATA2;
430
+ }
431
+ else {
432
+ chunkObj.opcodenum = Opcode.OP_PUSHDATA4;
433
+ }
434
+ this.chunks.push(new Chunk(chunkObj));
435
+ }
436
+ else if (typeof chunk === 'number') {
437
+ this.chunks.push(new Chunk({
438
+ opcodenum: chunk,
439
+ }));
440
+ }
441
+ else {
442
+ throw new TypeError('Invalid chunk type');
443
+ }
444
+ return this;
445
+ }
446
+ toBuffer() {
447
+ const bw = new BufferWriter();
448
+ for (const chunk of this.chunks) {
449
+ bw.writeUInt8(chunk.opcodenum);
450
+ if (chunk.buf) {
451
+ if (chunk.opcodenum === Opcode.OP_PUSHDATA1) {
452
+ bw.writeUInt8(chunk.len);
453
+ }
454
+ else if (chunk.opcodenum === Opcode.OP_PUSHDATA2) {
455
+ bw.writeUInt16LE(chunk.len);
456
+ }
457
+ else if (chunk.opcodenum === Opcode.OP_PUSHDATA4) {
458
+ bw.writeUInt32LE(chunk.len);
459
+ }
460
+ bw.write(chunk.buf);
461
+ }
462
+ }
463
+ return bw.toBuffer();
464
+ }
465
+ toString() {
466
+ return this.toBuffer().toString('hex');
467
+ }
468
+ toP2PKH() {
469
+ if (!this.isPayToPublicKeyHash()) {
470
+ throw new Error('Script is not a P2PKH address');
471
+ }
472
+ return this.chunks[2].buf.toString('hex');
473
+ }
474
+ toP2SH() {
475
+ if (!this.isPayToScriptHash()) {
476
+ throw new Error('Script is not a P2SH address');
477
+ }
478
+ return this.chunks[1].buf.toString('hex');
479
+ }
480
+ toASM() {
481
+ let str = '';
482
+ for (let i = 0; i < this.chunks.length; i++) {
483
+ const chunk = this.chunks[i];
484
+ str += this._chunkToString(chunk, 'asm');
485
+ }
486
+ return str.substring(1);
487
+ }
488
+ toHex() {
489
+ return this.toBuffer().toString('hex');
490
+ }
491
+ inspect() {
492
+ return '<Script: ' + this.toString() + '>';
493
+ }
494
+ _chunkToString(chunk, type) {
495
+ const opcodenum = chunk.opcodenum;
496
+ const asm = type === 'asm';
497
+ let str = '';
498
+ if (!chunk.buf) {
499
+ const opcodeNames = {};
500
+ for (const [name, value] of Object.entries(Opcode.map)) {
501
+ if (name === 'OP_FALSE' ||
502
+ name === 'OP_TRUE' ||
503
+ name === 'OP_NOP2' ||
504
+ name === 'OP_NOP3') {
505
+ continue;
506
+ }
507
+ if (!opcodeNames[value]) {
508
+ opcodeNames[value] = name;
509
+ }
510
+ }
511
+ if (opcodeNames[opcodenum]) {
512
+ if (asm) {
513
+ if (opcodenum === 0) {
514
+ str = str + ' 0';
515
+ }
516
+ else if (opcodenum === 79) {
517
+ str = str + ' -1';
518
+ }
519
+ else {
520
+ str = str + ' ' + opcodeNames[opcodenum];
521
+ }
522
+ }
523
+ else {
524
+ str = str + ' ' + opcodeNames[opcodenum];
525
+ }
526
+ }
527
+ else {
528
+ let numstr = opcodenum.toString(16);
529
+ if (numstr.length % 2 !== 0) {
530
+ numstr = '0' + numstr;
531
+ }
532
+ if (asm) {
533
+ str = str + ' ' + numstr;
534
+ }
535
+ else {
536
+ str = str + ' ' + '0x' + numstr;
537
+ }
538
+ }
539
+ }
540
+ else {
541
+ if (!asm &&
542
+ (opcodenum === Opcode.OP_PUSHDATA1 ||
543
+ opcodenum === Opcode.OP_PUSHDATA2 ||
544
+ opcodenum === Opcode.OP_PUSHDATA4)) {
545
+ str = str + ' ' + new Opcode(opcodenum).toString();
546
+ }
547
+ if (chunk.len > 0) {
548
+ if (asm) {
549
+ str = str + ' ' + chunk.buf.toString('hex');
550
+ }
551
+ else {
552
+ str = str + ' ' + chunk.len + ' ' + '0x' + chunk.buf.toString('hex');
553
+ }
554
+ }
555
+ }
556
+ return str;
557
+ }
558
+ isPayToPublicKeyHash() {
559
+ return (this.chunks.length === 5 &&
560
+ this.chunks[0].opcodenum === Opcode.OP_DUP &&
561
+ this.chunks[1].opcodenum === Opcode.OP_HASH160 &&
562
+ this.chunks[2].opcodenum === 20 &&
563
+ this.chunks[2].buf.length === 20 &&
564
+ this.chunks[3].opcodenum === Opcode.OP_EQUALVERIFY &&
565
+ this.chunks[4].opcodenum === Opcode.OP_CHECKSIG);
566
+ }
567
+ isPublicKeyHashOut() {
568
+ return !!(this.chunks.length === 5 &&
569
+ this.chunks[0].opcodenum === Opcode.OP_DUP &&
570
+ this.chunks[1].opcodenum === Opcode.OP_HASH160 &&
571
+ this.chunks[2].buf &&
572
+ this.chunks[2].buf.length === 20 &&
573
+ this.chunks[3].opcodenum === Opcode.OP_EQUALVERIFY &&
574
+ this.chunks[4].opcodenum === Opcode.OP_CHECKSIG);
575
+ }
576
+ isPayToScriptHash() {
577
+ return (this.chunks.length === 3 &&
578
+ this.chunks[0].opcodenum === Opcode.OP_HASH160 &&
579
+ this.chunks[1].opcodenum === 20 &&
580
+ this.chunks[1].buf.length === 20 &&
581
+ this.chunks[2].opcodenum === Opcode.OP_EQUAL);
582
+ }
583
+ isScriptHashOut() {
584
+ const buf = this.toBuffer();
585
+ return (buf.length === 23 &&
586
+ buf[0] === Opcode.OP_HASH160 &&
587
+ buf[1] === 0x14 &&
588
+ buf[buf.length - 1] === Opcode.OP_EQUAL);
589
+ }
590
+ isPayToTaproot() {
591
+ const buf = this.toBuffer();
592
+ if (buf.length < TAPROOT_SIZE_WITHOUT_STATE ||
593
+ buf[0] !== Opcode.OP_SCRIPTTYPE ||
594
+ buf[1] !== Opcode.OP_1 ||
595
+ buf[2] !== 33) {
596
+ return false;
597
+ }
598
+ if (buf.length === TAPROOT_SIZE_WITHOUT_STATE) {
599
+ return true;
600
+ }
601
+ return buf.length === TAPROOT_SIZE_WITH_STATE && buf[36] === 32;
602
+ }
603
+ getData() {
604
+ if (this.isScriptHashOut()) {
605
+ if (this.chunks[1] === undefined) {
606
+ return Buffer.alloc(0);
607
+ }
608
+ else {
609
+ return Buffer.from(this.chunks[1].buf);
610
+ }
611
+ }
612
+ if (this.isPublicKeyHashOut()) {
613
+ return Buffer.from(this.chunks[2].buf);
614
+ }
615
+ if (this.isPayToTaproot()) {
616
+ return Buffer.from(this.chunks[2].buf);
617
+ }
618
+ throw new Error('Unrecognized script type to get data from');
619
+ }
620
+ getAddressInfo() {
621
+ if (this._isInput) {
622
+ return this._getInputAddressInfo();
623
+ }
624
+ else if (this._isOutput) {
625
+ return this._getOutputAddressInfo();
626
+ }
627
+ else {
628
+ const info = this._getOutputAddressInfo();
629
+ if (!info) {
630
+ return this._getInputAddressInfo();
631
+ }
632
+ return info;
633
+ }
634
+ }
635
+ _getOutputAddressInfo() {
636
+ const info = {};
637
+ if (this.isPayToTaproot()) {
638
+ const buf = this.toBuffer();
639
+ info.hashBuffer = buf.slice(3, 36);
640
+ info.type = Address.PayToTaproot;
641
+ }
642
+ else if (this.isScriptHashOut()) {
643
+ info.hashBuffer = this.getData();
644
+ info.type = Address.PayToScriptHash;
645
+ }
646
+ else if (this.isPublicKeyHashOut()) {
647
+ info.hashBuffer = this.getData();
648
+ info.type = Address.PayToPublicKeyHash;
649
+ }
650
+ else {
651
+ return null;
652
+ }
653
+ return new Address(info);
654
+ }
655
+ _getInputAddressInfo() {
656
+ const info = {};
657
+ if (this.isPublicKeyHashIn()) {
658
+ info.hashBuffer = Hash.sha256ripemd160(this.chunks[1].buf);
659
+ info.type = Address.PayToPublicKeyHash;
660
+ }
661
+ else if (this.isScriptHashIn()) {
662
+ info.hashBuffer = Hash.sha256ripemd160(this.chunks[this.chunks.length - 1].buf);
663
+ info.type = Address.PayToScriptHash;
664
+ }
665
+ else {
666
+ return null;
667
+ }
668
+ return new Address(info);
669
+ }
670
+ toAddress(network) {
671
+ const info = this.getAddressInfo();
672
+ if (!info) {
673
+ return null;
674
+ }
675
+ if (info instanceof Address) {
676
+ if (network) {
677
+ if (this.isPayToTaproot()) {
678
+ const buf = this.toBuffer();
679
+ const commitment = buf.slice(3, 36);
680
+ return Address.fromTaprootCommitment(commitment, network);
681
+ }
682
+ else if (this.isPublicKeyHashOut()) {
683
+ const hashBuffer = this.getData();
684
+ return Address.fromPublicKeyHash(hashBuffer, network);
685
+ }
686
+ else if (this.isScriptHashOut()) {
687
+ const hashBuffer = this.getData();
688
+ return Address.fromScriptHash(hashBuffer, network);
689
+ }
690
+ }
691
+ return info;
692
+ }
693
+ return null;
694
+ }
695
+ checkMinimalPush(index) {
696
+ if (index >= this.chunks.length) {
697
+ return false;
698
+ }
699
+ const chunk = this.chunks[index];
700
+ const opcodenum = chunk.opcodenum;
701
+ if (opcodenum === undefined) {
702
+ return false;
703
+ }
704
+ if (opcodenum >= 0 && opcodenum <= Opcode.OP_PUSHDATA4) {
705
+ if (!chunk.buf) {
706
+ return opcodenum === Opcode.OP_0;
707
+ }
708
+ const dataLength = chunk.buf.length;
709
+ if (dataLength === 0) {
710
+ return opcodenum === Opcode.OP_0;
711
+ }
712
+ else if (dataLength === 1) {
713
+ return opcodenum === Opcode.OP_1 || opcodenum === Opcode.OP_PUSHDATA1;
714
+ }
715
+ else if (dataLength <= 75) {
716
+ return opcodenum === dataLength;
717
+ }
718
+ else if (dataLength <= 255) {
719
+ return opcodenum === Opcode.OP_PUSHDATA1;
720
+ }
721
+ else if (dataLength <= 65535) {
722
+ return opcodenum === Opcode.OP_PUSHDATA2;
723
+ }
724
+ else {
725
+ return opcodenum === Opcode.OP_PUSHDATA4;
726
+ }
727
+ }
728
+ return true;
729
+ }
730
+ isValid() {
731
+ try {
732
+ return this.chunks.length > 0;
733
+ }
734
+ catch (e) {
735
+ return false;
736
+ }
737
+ }
738
+ clone() {
739
+ const cloned = new Script();
740
+ cloned.chunks = this.chunks.map(chunk => new Chunk({
741
+ opcodenum: chunk.opcodenum,
742
+ buf: chunk.buf ? Buffer.from(chunk.buf) : undefined,
743
+ len: chunk.len,
744
+ }));
745
+ return cloned;
746
+ }
747
+ isPublicKeyHashIn() {
748
+ if (this.chunks.length === 2) {
749
+ const signatureBuf = this.chunks[0].buf;
750
+ const pubkeyBuf = this.chunks[1].buf;
751
+ if (signatureBuf &&
752
+ signatureBuf.length &&
753
+ pubkeyBuf &&
754
+ pubkeyBuf.length) {
755
+ const version = pubkeyBuf[0];
756
+ if ((version === 0x04 || version === 0x06 || version === 0x07) &&
757
+ pubkeyBuf.length === 65) {
758
+ return true;
759
+ }
760
+ else if ((version === 0x03 || version === 0x02) &&
761
+ pubkeyBuf.length === 33) {
762
+ return true;
763
+ }
764
+ }
765
+ }
766
+ return false;
767
+ }
768
+ getPublicKey() {
769
+ Preconditions.checkState(this.isPublicKeyOut(), "Can't retrieve PublicKey from a non-PK output");
770
+ return this.chunks[0].buf;
771
+ }
772
+ getPublicKeyHash() {
773
+ Preconditions.checkState(this.isPublicKeyHashOut(), "Can't retrieve PublicKeyHash from a non-PKH output");
774
+ return this.chunks[2].buf;
775
+ }
776
+ isPublicKeyOut() {
777
+ if (this.chunks.length === 2 &&
778
+ this.chunks[0].buf &&
779
+ this.chunks[0].buf.length &&
780
+ this.chunks[1].opcodenum === Opcode.OP_CHECKSIG) {
781
+ const pubkeyBuf = this.chunks[0].buf;
782
+ const version = pubkeyBuf[0];
783
+ let isVersion = false;
784
+ if ((version === 0x04 || version === 0x06 || version === 0x07) &&
785
+ pubkeyBuf.length === 65) {
786
+ isVersion = true;
787
+ }
788
+ else if ((version === 0x03 || version === 0x02) &&
789
+ pubkeyBuf.length === 33) {
790
+ isVersion = true;
791
+ }
792
+ if (isVersion) {
793
+ return PublicKey.isValid(pubkeyBuf);
794
+ }
795
+ }
796
+ return false;
797
+ }
798
+ isPublicKeyIn() {
799
+ if (this.chunks.length === 1) {
800
+ const signatureBuf = this.chunks[0].buf;
801
+ if (signatureBuf && signatureBuf.length && signatureBuf[0] === 0x30) {
802
+ return true;
803
+ }
804
+ }
805
+ return false;
806
+ }
807
+ isScriptHashIn() {
808
+ if (this.chunks.length <= 1) {
809
+ return false;
810
+ }
811
+ const redeemChunk = this.chunks[this.chunks.length - 1];
812
+ const redeemBuf = redeemChunk.buf;
813
+ if (!redeemBuf) {
814
+ return false;
815
+ }
816
+ let redeemScript;
817
+ try {
818
+ redeemScript = Script.fromBuffer(redeemBuf);
819
+ }
820
+ catch (e) {
821
+ if (e instanceof BitcoreError.Script.InvalidBuffer) {
822
+ return false;
823
+ }
824
+ throw e;
825
+ }
826
+ const type = redeemScript.classify();
827
+ return type !== ScriptTypes.UNKNOWN;
828
+ }
829
+ isMultisigOut() {
830
+ return (this.chunks.length > 3 &&
831
+ this._isSmallIntOp(this.chunks[0].opcodenum) &&
832
+ this.chunks.slice(1, this.chunks.length - 2).every(function (obj) {
833
+ return obj.buf && Buffer.isBuffer(obj.buf);
834
+ }) &&
835
+ this._isSmallIntOp(this.chunks[this.chunks.length - 2].opcodenum) &&
836
+ this.chunks[this.chunks.length - 1].opcodenum === Opcode.OP_CHECKMULTISIG);
837
+ }
838
+ _isSmallIntOp(opcode) {
839
+ return opcode >= Opcode.OP_1 && opcode <= Opcode.OP_16;
840
+ }
841
+ isMultisigIn() {
842
+ return (this.chunks.length >= 2 &&
843
+ this.chunks[0].opcodenum === 0 &&
844
+ this.chunks.slice(1, this.chunks.length).every(function (obj) {
845
+ return obj.buf && Buffer.isBuffer(obj.buf) && Signature.isTxDER(obj.buf);
846
+ }));
847
+ }
848
+ isDataOut() {
849
+ const step1 = this.chunks.length >= 1 &&
850
+ this.chunks[0].opcodenum === Opcode.OP_RETURN &&
851
+ this.toBuffer().length <= 223;
852
+ if (!step1)
853
+ return false;
854
+ const chunks = this.chunks.slice(1);
855
+ const script2 = new Script({ chunks: chunks });
856
+ return script2.isPushOnly();
857
+ }
858
+ isPushOnly() {
859
+ return this.chunks.every(function (chunk) {
860
+ return (chunk.opcodenum <= Opcode.OP_16 ||
861
+ chunk.opcodenum === Opcode.OP_PUSHDATA1 ||
862
+ chunk.opcodenum === Opcode.OP_PUSHDATA2 ||
863
+ chunk.opcodenum === Opcode.OP_PUSHDATA4);
864
+ });
865
+ }
866
+ classify() {
867
+ if (this._isInput) {
868
+ return this.classifyInput();
869
+ }
870
+ else if (this._isOutput) {
871
+ return this.classifyOutput();
872
+ }
873
+ else {
874
+ const outputType = this.classifyOutput();
875
+ return outputType !== ScriptTypes.UNKNOWN
876
+ ? outputType
877
+ : this.classifyInput();
878
+ }
879
+ }
880
+ classifyOutput() {
881
+ const outputIdentifiers = {
882
+ PUBKEY_OUT: this.isPublicKeyOut.bind(this),
883
+ PUBKEYHASH_OUT: this.isPublicKeyHashOut.bind(this),
884
+ MULTISIG_OUT: this.isMultisigOut.bind(this),
885
+ SCRIPTHASH_OUT: this.isScriptHashOut.bind(this),
886
+ DATA_OUT: this.isDataOut.bind(this),
887
+ };
888
+ for (const type in outputIdentifiers) {
889
+ if (outputIdentifiers[type]()) {
890
+ return ScriptTypes[type];
891
+ }
892
+ }
893
+ return ScriptTypes.UNKNOWN;
894
+ }
895
+ classifyInput() {
896
+ const inputIdentifiers = {
897
+ PUBKEY_IN: this.isPublicKeyIn.bind(this),
898
+ PUBKEYHASH_IN: this.isPublicKeyHashIn.bind(this),
899
+ MULTISIG_IN: this.isMultisigIn.bind(this),
900
+ SCRIPTHASH_IN: this.isScriptHashIn.bind(this),
901
+ };
902
+ for (const type in inputIdentifiers) {
903
+ if (inputIdentifiers[type]()) {
904
+ return ScriptTypes[type];
905
+ }
906
+ }
907
+ return ScriptTypes.UNKNOWN;
908
+ }
909
+ isStandard() {
910
+ return this.classify() !== ScriptTypes.UNKNOWN;
911
+ }
912
+ getType() {
913
+ if (this.isPayToTaproot()) {
914
+ const buf = this.toBuffer();
915
+ return buf.length === TAPROOT_SIZE_WITH_STATE
916
+ ? 'p2tr-state'
917
+ : 'p2tr-commitment';
918
+ }
919
+ else if (this.isPublicKeyOut()) {
920
+ return 'p2pk';
921
+ }
922
+ else if (this.isPublicKeyHashOut()) {
923
+ return 'p2pkh';
924
+ }
925
+ else if (this.isScriptHashOut()) {
926
+ return 'p2sh';
927
+ }
928
+ return 'other';
929
+ }
930
+ prepend(obj) {
931
+ this._addByType(obj, true);
932
+ return this;
933
+ }
934
+ equals(script) {
935
+ Preconditions.checkState(script instanceof Script, 'Must provide another script');
936
+ if (this.chunks.length !== script.chunks.length) {
937
+ return false;
938
+ }
939
+ for (let i = 0; i < this.chunks.length; i++) {
940
+ if (Buffer.isBuffer(this.chunks[i].buf) &&
941
+ !Buffer.isBuffer(script.chunks[i].buf)) {
942
+ return false;
943
+ }
944
+ if (Buffer.isBuffer(this.chunks[i].buf) &&
945
+ !BufferUtil.equals(this.chunks[i].buf, script.chunks[i].buf)) {
946
+ return false;
947
+ }
948
+ else if (this.chunks[i].opcodenum !== script.chunks[i].opcodenum) {
949
+ return false;
950
+ }
951
+ }
952
+ return true;
953
+ }
954
+ _addByType(obj, prepend) {
955
+ if (typeof obj === 'string') {
956
+ this._addOpcode(obj, prepend);
957
+ }
958
+ else if (typeof obj === 'number') {
959
+ this._addOpcode(obj, prepend);
960
+ }
961
+ else if (obj instanceof Opcode) {
962
+ this._addOpcode(obj, prepend);
963
+ }
964
+ else if (Buffer.isBuffer(obj)) {
965
+ this._addBuffer(obj, prepend);
966
+ }
967
+ else if (obj instanceof Script) {
968
+ this.chunks = this.chunks.concat(obj.chunks);
969
+ }
970
+ else if (typeof obj === 'object' && obj !== null) {
971
+ this._insertAtPosition(obj, prepend);
972
+ }
973
+ else {
974
+ throw new Error('Invalid script chunk');
975
+ }
976
+ }
977
+ _insertAtPosition(op, prepend) {
978
+ if (prepend) {
979
+ this.chunks.unshift(op);
980
+ }
981
+ else {
982
+ this.chunks.push(op);
983
+ }
984
+ }
985
+ _addOpcode(opcode, prepend) {
986
+ let op;
987
+ if (typeof opcode === 'number') {
988
+ op = opcode;
989
+ }
990
+ else if (opcode instanceof Opcode) {
991
+ op = opcode.num;
992
+ }
993
+ else {
994
+ op = new Opcode(opcode).num;
995
+ }
996
+ this._insertAtPosition({
997
+ opcodenum: op,
998
+ }, prepend);
999
+ }
1000
+ _addBuffer(buf, prepend) {
1001
+ let opcodenum;
1002
+ const len = buf.length;
1003
+ if (len >= 0 && len < Opcode.OP_PUSHDATA1) {
1004
+ opcodenum = len;
1005
+ }
1006
+ else if (len < Math.pow(2, 8)) {
1007
+ opcodenum = Opcode.OP_PUSHDATA1;
1008
+ }
1009
+ else if (len < Math.pow(2, 16)) {
1010
+ opcodenum = Opcode.OP_PUSHDATA2;
1011
+ }
1012
+ else if (len < Math.pow(2, 32)) {
1013
+ opcodenum = Opcode.OP_PUSHDATA4;
1014
+ }
1015
+ else {
1016
+ throw new Error("You can't push that much data");
1017
+ }
1018
+ this._insertAtPosition({
1019
+ buf: buf,
1020
+ len: len,
1021
+ opcodenum: opcodenum,
1022
+ }, prepend);
1023
+ }
1024
+ hasCodeseparators() {
1025
+ return this.chunks.some(chunk => chunk.opcodenum === Opcode.OP_CODESEPARATOR);
1026
+ }
1027
+ removeCodeseparators() {
1028
+ const chunks = [];
1029
+ for (let i = 0; i < this.chunks.length; i++) {
1030
+ if (this.chunks[i].opcodenum !== Opcode.OP_CODESEPARATOR) {
1031
+ chunks.push(this.chunks[i]);
1032
+ }
1033
+ }
1034
+ this.chunks = chunks;
1035
+ return this;
1036
+ }
1037
+ findAndDelete(script) {
1038
+ const buf = script.toBuffer();
1039
+ const hex = buf.toString('hex');
1040
+ for (let i = 0; i < this.chunks.length; i++) {
1041
+ const script2 = new Script({
1042
+ chunks: [this.chunks[i]],
1043
+ });
1044
+ const buf2 = script2.toBuffer();
1045
+ const hex2 = buf2.toString('hex');
1046
+ if (hex === hex2) {
1047
+ this.chunks.splice(i, 1);
1048
+ }
1049
+ }
1050
+ return this;
1051
+ }
1052
+ getSignatureOperationsCount(accurate = true) {
1053
+ let n = 0;
1054
+ let lastOpcode = 0xffff;
1055
+ for (const chunk of this.chunks) {
1056
+ const opcode = chunk.opcodenum;
1057
+ if (opcode === Opcode.OP_CHECKSIG ||
1058
+ opcode === Opcode.OP_CHECKSIGVERIFY) {
1059
+ n++;
1060
+ }
1061
+ else if (opcode === Opcode.OP_CHECKMULTISIG ||
1062
+ opcode === Opcode.OP_CHECKMULTISIGVERIFY) {
1063
+ if (accurate &&
1064
+ lastOpcode >= Opcode.OP_1 &&
1065
+ lastOpcode <= Opcode.OP_16) {
1066
+ n += this._decodeOP_N(lastOpcode);
1067
+ }
1068
+ else {
1069
+ n += 20;
1070
+ }
1071
+ }
1072
+ lastOpcode = opcode;
1073
+ }
1074
+ return n;
1075
+ }
1076
+ _decodeOP_N(opcode) {
1077
+ if (opcode === Opcode.OP_0) {
1078
+ return 0;
1079
+ }
1080
+ else if (opcode >= Opcode.OP_1 && opcode <= Opcode.OP_16) {
1081
+ return opcode - (Opcode.OP_1 - 1);
1082
+ }
1083
+ else {
1084
+ throw new Error('Invalid opcode: ' + JSON.stringify(opcode));
1085
+ }
1086
+ }
1087
+ toScriptHashOut() {
1088
+ return Script.buildScriptHashOut(this);
1089
+ }
1090
+ }
1091
+ export const ScriptTypes = {
1092
+ UNKNOWN: 'Unknown',
1093
+ PUBKEY_OUT: 'Pay to public key',
1094
+ PUBKEY_IN: 'Spend from public key',
1095
+ PUBKEYHASH_OUT: 'Pay to public key hash',
1096
+ PUBKEYHASH_IN: 'Spend from public key hash',
1097
+ SCRIPTHASH_OUT: 'Pay to script hash',
1098
+ SCRIPTHASH_IN: 'Spend from script hash',
1099
+ MULTISIG_OUT: 'Pay to multisig',
1100
+ MULTISIG_IN: 'Spend from multisig',
1101
+ DATA_OUT: 'Data push',
1102
+ };
1103
+ export function toAddress(script, network) {
1104
+ const addr = script.toAddress(network);
1105
+ if (!addr || typeof addr === 'boolean') {
1106
+ throw new Error('Cannot convert script to address');
1107
+ }
1108
+ return addr;
1109
+ }
1110
+ export function empty() {
1111
+ return new Script();
1112
+ }