@bsv/templates 1.0.0 → 1.1.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 (36) hide show
  1. package/dist/cjs/mod.js +22 -7
  2. package/dist/cjs/mod.js.map +1 -1
  3. package/dist/cjs/package.json +2 -2
  4. package/dist/cjs/src/Metanet.js +14 -14
  5. package/dist/cjs/src/Metanet.js.map +1 -1
  6. package/dist/cjs/src/MultiPushDrop.js +278 -0
  7. package/dist/cjs/src/MultiPushDrop.js.map +1 -0
  8. package/dist/cjs/src/OpReturn.js +13 -13
  9. package/dist/cjs/src/OpReturn.js.map +1 -1
  10. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  11. package/dist/esm/mod.js +1 -0
  12. package/dist/esm/mod.js.map +1 -1
  13. package/dist/esm/src/Metanet.js +14 -14
  14. package/dist/esm/src/Metanet.js.map +1 -1
  15. package/dist/esm/src/MultiPushDrop.js +275 -0
  16. package/dist/esm/src/MultiPushDrop.js.map +1 -0
  17. package/dist/esm/src/OpReturn.js +13 -13
  18. package/dist/esm/src/OpReturn.js.map +1 -1
  19. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  20. package/dist/types/mod.d.ts +1 -0
  21. package/dist/types/mod.d.ts.map +1 -1
  22. package/dist/types/src/Metanet.d.ts +13 -13
  23. package/dist/types/src/Metanet.d.ts.map +1 -1
  24. package/dist/types/src/MultiPushDrop.d.ts +66 -0
  25. package/dist/types/src/MultiPushDrop.d.ts.map +1 -0
  26. package/dist/types/src/OpReturn.d.ts +12 -12
  27. package/dist/types/src/OpReturn.d.ts.map +1 -1
  28. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  29. package/mod.ts +1 -0
  30. package/package.json +4 -4
  31. package/src/Metanet.ts +37 -37
  32. package/src/MultiPushDrop.ts +317 -0
  33. package/src/OpReturn.ts +32 -32
  34. package/src/__tests/Metanet.test.ts +15 -15
  35. package/src/__tests/MultiPushDrop.test.ts +256 -0
  36. package/src/__tests/OpReturn.test.ts +7 -7
@@ -0,0 +1,275 @@
1
+ import { LockingScript, UnlockingScript, OP, Utils, Hash, TransactionSignature, Signature } from '@bsv/sdk';
2
+ // Helper to ensure a value is not null or undefined
3
+ function verifyTruthy(v, err) {
4
+ if (v === null || v === undefined)
5
+ throw new Error(err || 'Value must not be null or undefined');
6
+ return v;
7
+ }
8
+ // Helper to create minimally encoded script chunks (same as in PushDrop)
9
+ const createMinimallyEncodedScriptChunk = (data) => {
10
+ if (data.length === 0)
11
+ return { op: 0 }; // OP_0
12
+ if (data.length === 1 && data[0] === 0)
13
+ return { op: 0 }; // OP_0
14
+ if (data.length === 1 && data[0] > 0 && data[0] <= 16)
15
+ return { op: 0x50 + data[0] }; // OP_1 to OP_16
16
+ if (data.length === 1 && data[0] === 0x81)
17
+ return { op: 0x4f }; // OP_1NEGATE
18
+ if (data.length <= 75)
19
+ return { op: data.length, data };
20
+ if (data.length <= 255)
21
+ return { op: 0x4c, data }; // OP_PUSHDATA1
22
+ if (data.length <= 65535)
23
+ return { op: 0x4d, data }; // OP_PUSHDATA2
24
+ return { op: 0x4e, data }; // OP_PUSHDATA4
25
+ };
26
+ /**
27
+ * MultiPushDrop Script Template
28
+ *
29
+ * This template creates locking scripts that allow spending by any one of multiple
30
+ * specified public keys (1-of-N). It also pushes arbitrary data fields onto the stack,
31
+ * which are dropped after the signature check.
32
+ *
33
+ * When using this among adversarial or non-trusted groups, the MASSIVE caveat is that
34
+ * there is no constraint enforcing that any group members are kept in the loop. Any group
35
+ * member can trivially destroy the token. For more practical non-trusted arrangements,
36
+ * techniques like OP_PUSH_TX should be used instead.
37
+ *
38
+ * There's also a known bug in this implementation where it won't work with over around 120
39
+ * keys but involving more than a few people than just a few into a FULLY TRUST BASED exchange
40
+ * is never a good idea. Use a more robust, application-specific mechanism.
41
+ */
42
+ export default class MultiPushDrop {
43
+ wallet;
44
+ originator;
45
+ /**
46
+ * Decodes a MultiPushDrop locking script back into its data fields and the list of locking public keys.
47
+ * @param script The MultiPushDrop locking script to decode.
48
+ * @returns {MultiPushDropDecoded} An object containing the locking public keys and data fields.
49
+ * @throws {Error} If the script structure is not a valid MultiPushDrop script.
50
+ */
51
+ static decode(script) {
52
+ const chunks = script.chunks;
53
+ let cursor = 0;
54
+ // Decode keys until they stop being 33 bytes long
55
+ const lockingPublicKeys = [];
56
+ while (chunks[cursor].data?.length === 33) {
57
+ const keyChunk = verifyTruthy(chunks[cursor], `Missing public key chunk ${cursor}`);
58
+ const keyData = verifyTruthy(keyChunk.data, `Public key chunk ${cursor} has no data`);
59
+ lockingPublicKeys.push(Utils.toHex(keyData));
60
+ cursor++;
61
+ }
62
+ // Skip the nPublicKeys chunk and opcodes.
63
+ // This amounts to 8 items to skip.
64
+ cursor += 8;
65
+ // Decode Data Fields
66
+ const fields = [];
67
+ for (let i = cursor; i < chunks.length; i++) {
68
+ const nextOpcode = chunks[i + 1]?.op;
69
+ const chunkData = chunks[i].data ?? []; // Use OP code for OP_0-OP_16 etc. if data is null
70
+ let currentField = [];
71
+ if (chunkData.length > 0) {
72
+ currentField = chunkData;
73
+ }
74
+ else if (chunks[i].op >= OP.OP_1 && chunks[i].op <= OP.OP_16) {
75
+ currentField = [chunks[i].op - OP.OP_1 + 1];
76
+ }
77
+ else if (chunks[i].op === OP.OP_0) {
78
+ currentField = []; // Represent OP_0 as empty array
79
+ }
80
+ else if (chunks[i].op === OP.OP_1NEGATE) {
81
+ currentField = [0x81];
82
+ }
83
+ else if (chunks[i].op === OP.OP_DROP || chunks[i].op === OP.OP_2DROP) {
84
+ // Stop before the drops
85
+ break;
86
+ }
87
+ else {
88
+ // Assume it's a data push even if data is empty for some reason
89
+ currentField = chunkData;
90
+ }
91
+ fields.push(currentField);
92
+ // If the next opcode is a DROP, we've found the last field
93
+ if (nextOpcode === OP.OP_DROP || nextOpcode === OP.OP_2DROP) {
94
+ break;
95
+ }
96
+ }
97
+ return {
98
+ lockingPublicKeys,
99
+ fields
100
+ };
101
+ }
102
+ /**
103
+ * Constructs a new instance of the MultiPushDrop class.
104
+ *
105
+ * @param {WalletInterface} wallet - The wallet interface used for deriving keys and signing.
106
+ * @param {string} [originator] - The originator domain for wallet requests.
107
+ */
108
+ constructor(wallet, originator) {
109
+ this.wallet = wallet;
110
+ this.originator = originator;
111
+ }
112
+ /**
113
+ * Creates a MultiPushDrop locking script.
114
+ *
115
+ * @param {number[][]} fields - The arbitrary data fields to include in the script.
116
+ * @param {[SecurityLevel, string]} protocolID - The protocol ID used for key derivation.
117
+ * @param {string} keyID - The key ID used for key derivation.
118
+ * @param {WalletCounterparty[]} counterparties - An array of counterparties ('self' or PubKeyHex) whose derived keys can unlock the script. Must contain at least one.
119
+ * @returns {Promise<LockingScript>} The generated MultiPushDrop locking script.
120
+ * @throws {Error} If counterparties array is empty.
121
+ */
122
+ async lock(fields, protocolID, keyID, counterparties) {
123
+ if (!Array.isArray(counterparties) || counterparties.length === 0) {
124
+ throw new Error('MultiPushDrop requires at least one counterparty.');
125
+ }
126
+ const publicKeys = [];
127
+ for (const counterparty of counterparties) {
128
+ const { publicKey } = await this.wallet.getPublicKey({
129
+ protocolID,
130
+ keyID,
131
+ counterparty
132
+ }, this.originator);
133
+ publicKeys.push(publicKey);
134
+ }
135
+ const nPublicKeys = publicKeys.length;
136
+ const lockPart = [];
137
+ // Push Public Keys
138
+ for (const publicKeyHex of publicKeys) {
139
+ lockPart.push({
140
+ op: publicKeyHex.length / 2, // Length of compressed pubkey is 33 bytes (66 hex)
141
+ data: Utils.toArray(publicKeyHex, 'hex')
142
+ });
143
+ }
144
+ // Pick the value on the stack that's right before the locking script.
145
+ // This should be the index of the key to use in the unlock.
146
+ lockPart.push(createMinimallyEncodedScriptChunk([nPublicKeys]));
147
+ lockPart.push({ op: OP.OP_PICK });
148
+ // Now we use the index to get the actual key.
149
+ lockPart.push({ op: OP.OP_PICK });
150
+ // We pull the signature from the bottom of the stack, no matter the number of keys.
151
+ lockPart.push({ op: OP.OP_DEPTH });
152
+ lockPart.push({ op: OP.OP_1SUB });
153
+ lockPart.push({ op: OP.OP_PICK });
154
+ // We swap the signature and public key so they're in the correct order, then CHECKSIGVERIFY
155
+ lockPart.push({ op: OP.OP_SWAP });
156
+ lockPart.push({ op: OP.OP_CHECKSIGVERIFY });
157
+ // Construct PushDrop Part for fields
158
+ const pushDropPart = [];
159
+ for (const field of fields) {
160
+ pushDropPart.push(createMinimallyEncodedScriptChunk(field));
161
+ }
162
+ // Add Drop Opcodes
163
+ // We need to drop N keys, the number N itself, and M fields after verification succeeds.
164
+ // We also copied the signature itself so we need to drop that.
165
+ // Then we push a single true.
166
+ let itemsToDrop = fields.length + nPublicKeys + 2;
167
+ while (itemsToDrop > 1) {
168
+ pushDropPart.push({ op: OP.OP_2DROP });
169
+ itemsToDrop -= 2;
170
+ }
171
+ if (itemsToDrop === 1) {
172
+ pushDropPart.push({ op: OP.OP_DROP });
173
+ }
174
+ // Combine parts and return
175
+ return new LockingScript([
176
+ ...lockPart,
177
+ ...pushDropPart,
178
+ { op: OP.OP_TRUE }
179
+ ]);
180
+ }
181
+ /**
182
+ * Creates an unlocking script template for spending a MultiPushDrop output.
183
+ *
184
+ * @param {[SecurityLevel, string]} protocolID - The protocol ID used for key derivation.
185
+ * @param {string} keyID - The key ID used for key derivation.
186
+ * @param {WalletCounterparty} creator - The identity key of the person who made the locking script. Could come from one of the fields or be passed off chain.
187
+ * @param {'all' | 'none' | 'single'} [signOutputs='all'] - Specifies which transaction outputs to sign.
188
+ * @param {boolean} [anyoneCanPay=false] - Specifies if the SIGHASH_ANYONECANPAY flag should be used.
189
+ * @returns {ScriptTemplateUnlock} An object containing `sign` and `estimateLength` functions.
190
+ * @throws {Error} If we are not found in the list of keys, or if required signing info (sourceTXID, satoshis, lockingScript) is missing.
191
+ */
192
+ unlock(protocolID, keyID, creator, signOutputs = 'all', anyoneCanPay = false) {
193
+ return {
194
+ sign: async (tx, inputIndex) => {
195
+ // Prepare for signing
196
+ let signatureScope = TransactionSignature.SIGHASH_FORKID;
197
+ if (signOutputs === 'all')
198
+ signatureScope |= TransactionSignature.SIGHASH_ALL;
199
+ else if (signOutputs === 'none')
200
+ signatureScope |= TransactionSignature.SIGHASH_NONE;
201
+ else if (signOutputs === 'single')
202
+ signatureScope |= TransactionSignature.SIGHASH_SINGLE;
203
+ if (anyoneCanPay)
204
+ signatureScope |= TransactionSignature.SIGHASH_ANYONECANPAY;
205
+ const input = tx.inputs[inputIndex];
206
+ const currentSourceTXID = input.sourceTXID ?? input.sourceTransaction?.id('hex');
207
+ const currentSourceSatoshis = input.sourceTransaction?.outputs[input.sourceOutputIndex].satoshis;
208
+ const currentLockingScript = input.sourceTransaction?.outputs[input.sourceOutputIndex]?.lockingScript;
209
+ if (typeof currentSourceTXID !== 'string')
210
+ throw new Error('Input sourceTXID or sourceTransaction required for signing.');
211
+ if (currentSourceSatoshis === undefined)
212
+ throw new Error('Input sourceSatoshis or sourceTransaction required for signing.');
213
+ if (currentLockingScript == null)
214
+ throw new Error('Input lockingScript or sourceTransaction required for signing.');
215
+ const otherInputs = tx.inputs.filter((_, index) => index !== inputIndex);
216
+ const decoded = MultiPushDrop.decode(currentLockingScript);
217
+ // Find the index of the unlocker's public key
218
+ let unlockerIndex = -1;
219
+ const { publicKey: unlockerPubKeyHex } = await this.wallet.getPublicKey({
220
+ protocolID,
221
+ keyID,
222
+ counterparty: creator,
223
+ forSelf: true
224
+ }, this.originator);
225
+ for (let i = 0; i < decoded.lockingPublicKeys.length; i++) {
226
+ if (decoded.lockingPublicKeys[i] === unlockerPubKeyHex) {
227
+ unlockerIndex = i;
228
+ break;
229
+ }
230
+ }
231
+ if (unlockerIndex === -1) {
232
+ throw new Error(`Unlocker key derived for counterparty (creator) "${creator}" not found in the list of locking keys.`);
233
+ }
234
+ unlockerIndex = decoded.lockingPublicKeys.length - 1 - unlockerIndex;
235
+ // Calculate Preimage
236
+ const preimage = TransactionSignature.format({
237
+ sourceTXID: currentSourceTXID,
238
+ sourceOutputIndex: verifyTruthy(input.sourceOutputIndex),
239
+ sourceSatoshis: currentSourceSatoshis,
240
+ transactionVersion: tx.version,
241
+ otherInputs,
242
+ inputIndex,
243
+ outputs: tx.outputs,
244
+ inputSequence: input.sequence ?? 0xffffffff,
245
+ subscript: currentLockingScript,
246
+ lockTime: tx.lockTime,
247
+ scope: signatureScope
248
+ });
249
+ // Create Signature
250
+ const preimageHash = Hash.hash256(preimage);
251
+ const { signature: bareSignature } = await this.wallet.createSignature({
252
+ hashToDirectlySign: preimageHash,
253
+ protocolID,
254
+ keyID,
255
+ counterparty: creator
256
+ }, this.originator);
257
+ const signature = Signature.fromDER([...bareSignature]);
258
+ const txSignature = new TransactionSignature(signature.r, signature.s, signatureScope);
259
+ const sigForScript = txSignature.toChecksigFormat();
260
+ // Create Unlocking Script Chunks: <Signature> <Index>
261
+ const unlockingChunks = [];
262
+ unlockingChunks.push({ op: sigForScript.length, data: sigForScript });
263
+ unlockingChunks.push(createMinimallyEncodedScriptChunk([unlockerIndex]));
264
+ return new UnlockingScript(unlockingChunks);
265
+ },
266
+ // Estimate length: Signature (~71-73 bytes) + Index push (1 byte for 0-15, potentially more)
267
+ estimateLength: async () => {
268
+ // A conservative estimate, usually 73 + 1 = 74
269
+ // Could potentially be larger if index > 15, but that's rare.
270
+ return 74;
271
+ }
272
+ };
273
+ }
274
+ }
275
+ //# sourceMappingURL=MultiPushDrop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MultiPushDrop.js","sourceRoot":"","sources":["../../../src/MultiPushDrop.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,aAAa,EACb,eAAe,EACf,EAAE,EAEF,KAAK,EACL,IAAI,EACJ,oBAAoB,EACpB,SAAS,EAIV,MAAM,UAAU,CAAA;AAEjB,oDAAoD;AACpD,SAAS,YAAY,CAAK,CAAuB,EAAE,GAAY;IAC7D,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,qCAAqC,CAAC,CAAA;IAChG,OAAO,CAAC,CAAA;AACV,CAAC;AAED,yEAAyE;AACzE,MAAM,iCAAiC,GAAG,CACxC,IAAc,EACmB,EAAE;IACnC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,CAAC,EAAE,CAAA,CAAC,OAAO;IAC/C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,CAAC,EAAE,CAAA,CAAC,OAAO;IAChE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA,CAAC,gBAAgB;IACrG,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAA,CAAC,aAAa;IAC5E,IAAI,IAAI,CAAC,MAAM,IAAI,EAAE;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,CAAA;IACvD,IAAI,IAAI,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA,CAAC,eAAe;IACjE,IAAI,IAAI,CAAC,MAAM,IAAI,KAAK;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA,CAAC,eAAe;IACnE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA,CAAC,eAAe;AAC3C,CAAC,CAAA;AAUD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,OAAO,OAAO,aAAa;IAChC,MAAM,CAAiB;IACvB,UAAU,CAAS;IAEnB;;;;;SAKK;IACL,MAAM,CAAC,MAAM,CAAE,MAAqB;QAClC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;QAC5B,IAAI,MAAM,GAAG,CAAC,CAAA;QAEd,kDAAkD;QAClD,MAAM,iBAAiB,GAAgB,EAAE,CAAA;QACzC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,EAAE,EAAE,CAAC;YAC1C,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,4BAA4B,MAAM,EAAE,CAAC,CAAA;YACnF,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,IAAI,EAAE,oBAAoB,MAAM,cAAc,CAAC,CAAA;YACrF,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAA;YAC5C,MAAM,EAAE,CAAA;QACV,CAAC;QAED,0CAA0C;QAC1C,mCAAmC;QACnC,MAAM,IAAI,CAAC,CAAA;QAEX,qBAAqB;QACrB,MAAM,MAAM,GAAe,EAAE,CAAA;QAC7B,KAAK,IAAI,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5C,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAA;YACpC,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAA,CAAC,kDAAkD;YAEzF,IAAI,YAAY,GAAa,EAAE,CAAA;YAC/B,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzB,YAAY,GAAG,SAAS,CAAA;YAC1B,CAAC;iBAAM,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC;gBAC/D,YAAY,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAA;YAC7C,CAAC;iBAAM,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC;gBACpC,YAAY,GAAG,EAAE,CAAA,CAAC,gCAAgC;YACpD,CAAC;iBAAM,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,UAAU,EAAE,CAAC;gBAC1C,YAAY,GAAG,CAAC,IAAI,CAAC,CAAA;YACvB,CAAC;iBAAM,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,OAAO,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,CAAC;gBACvE,wBAAwB;gBACxB,MAAK;YACP,CAAC;iBAAM,CAAC;gBACN,gEAAgE;gBAChE,YAAY,GAAG,SAAS,CAAA;YAC1B,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;YACzB,2DAA2D;YAC3D,IAAI,UAAU,KAAK,EAAE,CAAC,OAAO,IAAI,UAAU,KAAK,EAAE,CAAC,QAAQ,EAAE,CAAC;gBAC5D,MAAK;YACP,CAAC;QACH,CAAC;QAED,OAAO;YACL,iBAAiB;YACjB,MAAM;SACP,CAAA;IACH,CAAC;IAED;;;;;QAKI;IACJ,YAAa,MAAuB,EAAE,UAAmB;QACvD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;IAC9B,CAAC;IAED;;;;;;;;;QASI;IACJ,KAAK,CAAC,IAAI,CACR,MAAkB,EAClB,UAAmC,EACnC,KAAa,EACb,cAAoC;QAEpC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClE,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAA;QACtE,CAAC;QAED,MAAM,UAAU,GAAa,EAAE,CAAA;QAC/B,KAAK,MAAM,YAAY,IAAI,cAAc,EAAE,CAAC;YAC1C,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC;gBACnD,UAAU;gBACV,KAAK;gBACL,YAAY;aACb,EAAE,IAAI,CAAC,UAAU,CAAC,CAAA;YACnB,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QAC5B,CAAC;QAED,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,CAAA;QACrC,MAAM,QAAQ,GAA2C,EAAE,CAAA;QAE3D,mBAAmB;QACnB,KAAK,MAAM,YAAY,IAAI,UAAU,EAAE,CAAC;YACtC,QAAQ,CAAC,IAAI,CAAC;gBACZ,EAAE,EAAE,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,mDAAmD;gBAChF,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,YAAY,EAAE,KAAK,CAAC;aACzC,CAAC,CAAA;QACJ,CAAC;QAED,sEAAsE;QACtE,4DAA4D;QAC5D,QAAQ,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;QAC/D,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,CAAA;QAEjC,8CAA8C;QAC9C,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,CAAA;QAEjC,oFAAoF;QACpF,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAA;QAClC,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,CAAA;QACjC,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,CAAA;QAEjC,4FAA4F;QAC5F,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,CAAA;QACjC,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,iBAAiB,EAAE,CAAC,CAAA;QAE3C,qCAAqC;QACrC,MAAM,YAAY,GAA2C,EAAE,CAAA;QAC/D,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,YAAY,CAAC,IAAI,CAAC,iCAAiC,CAAC,KAAK,CAAC,CAAC,CAAA;QAC7D,CAAC;QAED,mBAAmB;QACnB,yFAAyF;QACzF,+DAA+D;QAC/D,8BAA8B;QAC9B,IAAI,WAAW,GAAG,MAAM,CAAC,MAAM,GAAG,WAAW,GAAG,CAAC,CAAA;QACjD,OAAO,WAAW,GAAG,CAAC,EAAE,CAAC;YACvB,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAA;YACtC,WAAW,IAAI,CAAC,CAAA;QAClB,CAAC;QACD,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;YACtB,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,CAAA;QACvC,CAAC;QAED,2BAA2B;QAC3B,OAAO,IAAI,aAAa,CAAC;YACvB,GAAG,QAAQ;YACX,GAAG,YAAY;YACf,EAAE,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE;SACnB,CAAC,CAAA;IACJ,CAAC;IAED;;;;;;;;;;SAUK;IACL,MAAM,CACJ,UAAmC,EACnC,KAAa,EACb,OAA2B,EAC3B,cAAyC,KAAK,EAC9C,YAAY,GAAG,KAAK;QAEpB,OAAO;YACL,IAAI,EAAE,KAAK,EACT,EAAe,EACf,UAAkB,EACQ,EAAE;gBAC5B,sBAAsB;gBACtB,IAAI,cAAc,GAAG,oBAAoB,CAAC,cAAc,CAAA;gBACxD,IAAI,WAAW,KAAK,KAAK;oBAAE,cAAc,IAAI,oBAAoB,CAAC,WAAW,CAAA;qBACxE,IAAI,WAAW,KAAK,MAAM;oBAAE,cAAc,IAAI,oBAAoB,CAAC,YAAY,CAAA;qBAC/E,IAAI,WAAW,KAAK,QAAQ;oBAAE,cAAc,IAAI,oBAAoB,CAAC,cAAc,CAAA;gBACxF,IAAI,YAAY;oBAAE,cAAc,IAAI,oBAAoB,CAAC,oBAAoB,CAAA;gBAC7E,MAAM,KAAK,GAAG,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;gBACnC,MAAM,iBAAiB,GAAG,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,iBAAiB,EAAE,EAAE,CAAC,KAAK,CAAC,CAAA;gBAChF,MAAM,qBAAqB,GAAG,KAAK,CAAC,iBAAiB,EAAE,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,QAAQ,CAAA;gBAChG,MAAM,oBAAoB,GAAG,KAAK,CAAC,iBAAiB,EAAE,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE,aAAa,CAAA;gBACrG,IAAI,OAAO,iBAAiB,KAAK,QAAQ;oBAAE,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAA;gBACzH,IAAI,qBAAqB,KAAK,SAAS;oBAAE,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAA;gBAC3H,IAAI,oBAAoB,IAAI,IAAI;oBAAE,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAA;gBACnH,MAAM,WAAW,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,UAAU,CAAC,CAAA;gBACxE,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAA;gBAE1D,8CAA8C;gBAC9C,IAAI,aAAa,GAAG,CAAC,CAAC,CAAA;gBACtB,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC;oBACtE,UAAU;oBACV,KAAK;oBACL,YAAY,EAAE,OAAO;oBACrB,OAAO,EAAE,IAAI;iBACd,EAAE,IAAI,CAAC,UAAU,CAAC,CAAA;gBACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC1D,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,KAAK,iBAAiB,EAAE,CAAC;wBACvD,aAAa,GAAG,CAAC,CAAA;wBACjB,MAAK;oBACP,CAAC;gBACH,CAAC;gBACD,IAAI,aAAa,KAAK,CAAC,CAAC,EAAE,CAAC;oBACzB,MAAM,IAAI,KAAK,CAAC,oDAAoD,OAAO,0CAA0C,CAAC,CAAA;gBACxH,CAAC;gBACD,aAAa,GAAG,OAAO,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,GAAG,aAAa,CAAA;gBAEpE,qBAAqB;gBACrB,MAAM,QAAQ,GAAG,oBAAoB,CAAC,MAAM,CAAC;oBAC3C,UAAU,EAAE,iBAAiB;oBAC7B,iBAAiB,EAAE,YAAY,CAAC,KAAK,CAAC,iBAAiB,CAAC;oBACxD,cAAc,EAAE,qBAAqB;oBACrC,kBAAkB,EAAE,EAAE,CAAC,OAAO;oBAC9B,WAAW;oBACX,UAAU;oBACV,OAAO,EAAE,EAAE,CAAC,OAAO;oBACnB,aAAa,EAAE,KAAK,CAAC,QAAQ,IAAI,UAAU;oBAC3C,SAAS,EAAE,oBAAoB;oBAC/B,QAAQ,EAAE,EAAE,CAAC,QAAQ;oBACrB,KAAK,EAAE,cAAc;iBACtB,CAAC,CAAA;gBAEF,mBAAmB;gBACnB,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;gBAC3C,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC;oBACrE,kBAAkB,EAAE,YAAY;oBAChC,UAAU;oBACV,KAAK;oBACL,YAAY,EAAE,OAAO;iBACtB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAA;gBACnB,MAAM,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAA;gBACvD,MAAM,WAAW,GAAG,IAAI,oBAAoB,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,EAAE,cAAc,CAAC,CAAA;gBACtF,MAAM,YAAY,GAAG,WAAW,CAAC,gBAAgB,EAAE,CAAA;gBAEnD,sDAAsD;gBACtD,MAAM,eAAe,GAA2C,EAAE,CAAA;gBAClE,eAAe,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAA;gBACrE,eAAe,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAA;gBACxE,OAAO,IAAI,eAAe,CAAC,eAAe,CAAC,CAAA;YAC7C,CAAC;YACD,6FAA6F;YAC7F,cAAc,EAAE,KAAK,IAAqB,EAAE;gBAC1C,+CAA+C;gBAC/C,8DAA8D;gBAC9D,OAAO,EAAE,CAAA;YACX,CAAC;SACF,CAAA;IACH,CAAC;CACF"}
@@ -6,12 +6,12 @@ import { OP, LockingScript, Utils } from '@bsv/sdk';
6
6
  */
7
7
  export default class OpReturn {
8
8
  /**
9
- * Creates an OpReturn script
10
- *
11
- * @param {string | string[] | number[]} data The data or array of data to push after OP_RETURN.
12
- * @param {('hex' | 'utf8' | 'base64')} enc The data encoding type, defaults to utf8.
13
- * @returns {LockingScript} - An OpReturn locking script.
14
- */
9
+ * Creates an OpReturn script
10
+ *
11
+ * @param {string | string[] | number[]} data The data or array of data to push after OP_RETURN.
12
+ * @param {('hex' | 'utf8' | 'base64')} enc The data encoding type, defaults to utf8.
13
+ * @returns {LockingScript} - An OpReturn locking script.
14
+ */
15
15
  lock(data, enc) {
16
16
  const script = [
17
17
  { op: OP.OP_FALSE },
@@ -20,7 +20,7 @@ export default class OpReturn {
20
20
  if (typeof data === 'string') {
21
21
  data = [data];
22
22
  }
23
- if (data.length && typeof data[0] === 'number') {
23
+ if ((data.length > 0) && typeof data[0] === 'number') {
24
24
  script.push({ op: data.length, data: data });
25
25
  }
26
26
  else {
@@ -32,16 +32,16 @@ export default class OpReturn {
32
32
  return new LockingScript(script);
33
33
  }
34
34
  /**
35
- * Unlock method is not available for OpReturn scripts, throws exception.
36
- */
35
+ * Unlock method is not available for OpReturn scripts, throws exception.
36
+ */
37
37
  unlock() {
38
38
  throw new Error('Unlock is not supported for OpReturn scripts');
39
39
  }
40
40
  /**
41
- * Decodes an OpReturn script data to utf8
42
- * @param script The opreturn script
43
- * @returns An array of UTF8 encoded strings
44
- */
41
+ * Decodes an OpReturn script data to utf8
42
+ * @param script The opreturn script
43
+ * @returns An array of UTF8 encoded strings
44
+ */
45
45
  static decode(script) {
46
46
  const tokens = script.toASM().split(' ').slice(2);
47
47
  return tokens.map(token => Utils.toUTF8(Utils.toArray(token, 'hex')));
@@ -1 +1 @@
1
- {"version":3,"file":"OpReturn.js","sourceRoot":"","sources":["../../../src/OpReturn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAA0B,aAAa,EAAgC,KAAK,EAAE,MAAM,UAAU,CAAA;AAEzG;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,QAAQ;IACzB;;;;;;OAMG;IACH,IAAI,CAAC,IAAkC,EAAE,GAA+B;QACpE,MAAM,MAAM,GAAsC;YAC9C,EAAE,EAAE,EAAE,EAAE,CAAC,QAAQ,EAAE;YACnB,EAAE,EAAE,EAAE,EAAE,CAAC,SAAS,EAAE;SACvB,CAAA;QAED,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC3B,IAAI,GAAG,CAAC,IAAI,CAAC,CAAA;QACjB,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;YAC7C,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,IAAgB,EAAE,CAAC,CAAA;QAC5D,CAAC;aAAM,CAAC;YACJ,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;gBACvC,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;gBACrC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAA;YAC9C,CAAC;QACL,CAAC;QAED,OAAO,IAAI,aAAa,CAAC,MAAM,CAAC,CAAA;IACpC,CAAC;IAED;;OAEG;IACH,MAAM;QAIF,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAA;IACnE,CAAC;IAED;;;;GAID;IACC,MAAM,CAAC,MAAM,CAAC,MAAc;QACxB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QACjD,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAA;IACzE,CAAC;CACJ"}
1
+ {"version":3,"file":"OpReturn.js","sourceRoot":"","sources":["../../../src/OpReturn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAA0B,aAAa,EAAgC,KAAK,EAAE,MAAM,UAAU,CAAA;AAEzG;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,QAAQ;IAC3B;;;;;;SAMK;IACL,IAAI,CAAE,IAAkC,EAAE,GAA+B;QACvE,MAAM,MAAM,GAA2C;YACrD,EAAE,EAAE,EAAE,EAAE,CAAC,QAAQ,EAAE;YACnB,EAAE,EAAE,EAAE,EAAE,CAAC,SAAS,EAAE;SACrB,CAAA;QAED,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC7B,IAAI,GAAG,CAAC,IAAI,CAAC,CAAA;QACf,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;YACrD,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,IAAgB,EAAE,CAAC,CAAA;QAC1D,CAAC;aAAM,CAAC;YACN,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;gBACzC,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;gBACrC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAA;YAC5C,CAAC;QACH,CAAC;QAED,OAAO,IAAI,aAAa,CAAC,MAAM,CAAC,CAAA;IAClC,CAAC;IAED;;SAEK;IACL,MAAM;QAIJ,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAA;IACjE,CAAC;IAED;;;;KAIC;IACD,MAAM,CAAC,MAAM,CAAE,MAAc;QAC3B,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QACjD,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAA;IACvE,CAAC;CACF"}