@smartledger/bsv 3.0.2 → 3.1.1

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.
package/index.js CHANGED
@@ -102,6 +102,7 @@ if (typeof window === 'undefined' && typeof require === 'function') {
102
102
  try {
103
103
  bsv.SmartUTXO = require('./lib/smartutxo')
104
104
  bsv.SmartMiner = require('./lib/smartminer')
105
+ bsv.CustomScriptHelper = require('./lib/custom-script-helper')
105
106
  } catch (e) {
106
107
  // Browser environment - these tools not available
107
108
  }
@@ -0,0 +1,249 @@
1
+ /**
2
+ * SmartLedger BSV Custom Script Helper
3
+ * Simplified API for custom script development
4
+ */
5
+
6
+ const bsv = require('../index.js');
7
+
8
+ class CustomScriptHelper {
9
+
10
+ /**
11
+ * Create a signature for any custom script
12
+ * @param {Transaction} transaction - The transaction object
13
+ * @param {PrivateKey} privateKey - Private key to sign with
14
+ * @param {number} inputIndex - Input index (0 for first input)
15
+ * @param {Script} lockingScript - The locking script being spent
16
+ * @param {number} satoshis - Amount in satoshis
17
+ * @param {number} sighashType - Signature hash type
18
+ * @returns {Buffer} Complete signature with sighash type
19
+ */
20
+ static createSignature(transaction, privateKey, inputIndex, lockingScript, satoshis, sighashType = null) {
21
+ sighashType = sighashType || (bsv.crypto.Signature.SIGHASH_ALL | bsv.crypto.Signature.SIGHASH_FORKID);
22
+
23
+ const signature = bsv.Transaction.sighash.sign(
24
+ transaction,
25
+ privateKey,
26
+ sighashType,
27
+ inputIndex,
28
+ lockingScript,
29
+ new bsv.crypto.BN(satoshis)
30
+ );
31
+
32
+ return Buffer.concat([signature.toDER(), Buffer.from([sighashType])]);
33
+ }
34
+
35
+ /**
36
+ * Create a multi-signature locking script
37
+ * @param {number} m - Required signatures
38
+ * @param {PublicKey[]} publicKeys - Array of public keys
39
+ * @returns {Script} Multi-signature locking script
40
+ */
41
+ static createMultisigScript(m, publicKeys) {
42
+ let script = new bsv.Script().add(bsv.Opcode[`OP_${m}`]);
43
+
44
+ for (const pubKey of publicKeys) {
45
+ script = script.add(pubKey.toBuffer());
46
+ }
47
+
48
+ return script
49
+ .add(bsv.Opcode[`OP_${publicKeys.length}`])
50
+ .add(bsv.Opcode.OP_CHECKMULTISIG);
51
+ }
52
+
53
+ /**
54
+ * Create an unlocking script for multi-signature
55
+ * @param {Buffer[]} signatures - Array of signatures
56
+ * @returns {Script} Unlocking script for multisig
57
+ */
58
+ static createMultisigUnlocking(signatures) {
59
+ let script = new bsv.Script().add(bsv.Opcode.OP_0); // CHECKMULTISIG bug
60
+
61
+ for (const sig of signatures) {
62
+ script = script.add(sig);
63
+ }
64
+
65
+ return script;
66
+ }
67
+
68
+ /**
69
+ * Create a time-locked script (CHECKLOCKTIMEVERIFY)
70
+ * @param {number} lockTime - Block height or timestamp
71
+ * @param {Script} baseScript - Base script to execute after time lock
72
+ * @returns {Script} Time-locked script
73
+ */
74
+ static createTimelockScript(lockTime, baseScript) {
75
+ const lockTimeBuffer = Buffer.from(lockTime.toString(16).padStart(8, '0'), 'hex').reverse();
76
+
77
+ return new bsv.Script()
78
+ .add(lockTimeBuffer)
79
+ .add(bsv.Opcode.OP_CHECKLOCKTIMEVERIFY)
80
+ .add(bsv.Opcode.OP_DROP)
81
+ .add(baseScript.toBuffer());
82
+ }
83
+
84
+ /**
85
+ * Create a conditional script (IF/ELSE/ENDIF)
86
+ * @param {Script} ifScript - Script to execute if condition is true
87
+ * @param {Script} elseScript - Script to execute if condition is false
88
+ * @returns {Script} Conditional script
89
+ */
90
+ static createConditionalScript(ifScript, elseScript = null) {
91
+ let script = new bsv.Script()
92
+ .add(bsv.Opcode.OP_IF)
93
+ .add(ifScript.toBuffer());
94
+
95
+ if (elseScript) {
96
+ script = script
97
+ .add(bsv.Opcode.OP_ELSE)
98
+ .add(elseScript.toBuffer());
99
+ }
100
+
101
+ return script.add(bsv.Opcode.OP_ENDIF);
102
+ }
103
+
104
+ /**
105
+ * Create P2PKH script for a public key
106
+ * @param {PublicKey} publicKey - Public key
107
+ * @returns {Script} P2PKH locking script
108
+ */
109
+ static createP2PKHScript(publicKey) {
110
+ return new bsv.Script()
111
+ .add(bsv.Opcode.OP_DUP)
112
+ .add(bsv.Opcode.OP_HASH160)
113
+ .add(publicKey.toAddress().hashBuffer)
114
+ .add(bsv.Opcode.OP_EQUALVERIFY)
115
+ .add(bsv.Opcode.OP_CHECKSIG);
116
+ }
117
+
118
+ /**
119
+ * Create P2PKH unlocking script
120
+ * @param {Buffer} signature - Signature
121
+ * @param {PublicKey} publicKey - Public key
122
+ * @returns {Script} P2PKH unlocking script
123
+ */
124
+ static createP2PKHUnlocking(signature, publicKey) {
125
+ return new bsv.Script()
126
+ .add(signature)
127
+ .add(publicKey.toBuffer());
128
+ }
129
+
130
+ /**
131
+ * Get transaction preimage for covenant scripts
132
+ * @param {Transaction} transaction - The transaction
133
+ * @param {number} inputIndex - Input index
134
+ * @param {Script} lockingScript - Locking script
135
+ * @param {number} satoshis - Amount in satoshis
136
+ * @param {number} sighashType - Signature hash type
137
+ * @returns {Buffer} Transaction preimage
138
+ */
139
+ static getPreimage(transaction, inputIndex, lockingScript, satoshis, sighashType = null) {
140
+ sighashType = sighashType || (bsv.crypto.Signature.SIGHASH_ALL | bsv.crypto.Signature.SIGHASH_FORKID);
141
+
142
+ return bsv.Transaction.sighash.sighash(
143
+ transaction,
144
+ sighashType,
145
+ inputIndex,
146
+ lockingScript,
147
+ new bsv.crypto.BN(satoshis)
148
+ );
149
+ }
150
+
151
+ /**
152
+ * Create a simple data push script
153
+ * @param {Buffer|string} data - Data to push
154
+ * @returns {Script} Data push script
155
+ */
156
+ static createDataScript(data) {
157
+ if (typeof data === 'string') {
158
+ data = Buffer.from(data, 'utf8');
159
+ }
160
+ return new bsv.Script().add(data);
161
+ }
162
+
163
+ /**
164
+ * Create OP_RETURN data script
165
+ * @param {Buffer|string} data - Data for OP_RETURN
166
+ * @returns {Script} OP_RETURN script
167
+ */
168
+ static createOpReturnScript(data) {
169
+ if (typeof data === 'string') {
170
+ data = Buffer.from(data, 'utf8');
171
+ }
172
+ return new bsv.Script()
173
+ .add(bsv.Opcode.OP_FALSE)
174
+ .add(bsv.Opcode.OP_RETURN)
175
+ .add(data);
176
+ }
177
+
178
+ /**
179
+ * Validate a transaction with custom scripts
180
+ * @param {Transaction} transaction - Transaction to validate
181
+ * @returns {boolean} True if valid
182
+ */
183
+ static validateTransaction(transaction) {
184
+ try {
185
+ return transaction.verify();
186
+ } catch (error) {
187
+ console.error('Transaction validation error:', error.message);
188
+ return false;
189
+ }
190
+ }
191
+
192
+ /**
193
+ * Validate a specific input script
194
+ * @param {Script} unlockingScript - Unlocking script
195
+ * @param {Script} lockingScript - Locking script
196
+ * @param {Transaction} transaction - Transaction
197
+ * @param {number} inputIndex - Input index
198
+ * @returns {boolean} True if script is valid
199
+ */
200
+ static validateScript(unlockingScript, lockingScript, transaction, inputIndex) {
201
+ try {
202
+ const interpreter = new bsv.Script.Interpreter();
203
+ return interpreter.verify(
204
+ unlockingScript,
205
+ lockingScript,
206
+ transaction,
207
+ inputIndex,
208
+ bsv.Script.Interpreter.SCRIPT_VERIFY_P2SH |
209
+ bsv.Script.Interpreter.SCRIPT_VERIFY_STRICTENC |
210
+ bsv.Script.Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID |
211
+ bsv.Script.Interpreter.SCRIPT_ENABLE_MAGNETIC_OPCODES |
212
+ bsv.Script.Interpreter.SCRIPT_ENABLE_MONOLITH_OPCODES
213
+ );
214
+ } catch (error) {
215
+ console.error('Script validation error:', error.message);
216
+ return false;
217
+ }
218
+ }
219
+
220
+ /**
221
+ * Create a transaction with ultra-low fees
222
+ * @param {Object[]} utxos - Array of UTXOs
223
+ * @param {Object[]} outputs - Array of outputs
224
+ * @param {number} feePerKb - Fee per KB (default: 10 sats = 0.01 sats/byte)
225
+ * @returns {Transaction} Transaction with ultra-low fees
226
+ */
227
+ static createLowFeeTransaction(utxos, outputs, feePerKb = 10) {
228
+ let tx = new bsv.Transaction().feePerKb(feePerKb);
229
+
230
+ // Add inputs
231
+ for (const utxo of utxos) {
232
+ tx = tx.from(utxo);
233
+ }
234
+
235
+ // Add outputs
236
+ for (const output of outputs) {
237
+ tx = tx.to(output.address, output.satoshis);
238
+ }
239
+
240
+ return tx;
241
+ }
242
+ }
243
+
244
+ // Common signature hash types
245
+ CustomScriptHelper.SIGHASH_ALL = bsv.crypto.Signature.SIGHASH_ALL | bsv.crypto.Signature.SIGHASH_FORKID;
246
+ CustomScriptHelper.SIGHASH_NONE = bsv.crypto.Signature.SIGHASH_NONE | bsv.crypto.Signature.SIGHASH_FORKID;
247
+ CustomScriptHelper.SIGHASH_SINGLE = bsv.crypto.Signature.SIGHASH_SINGLE | bsv.crypto.Signature.SIGHASH_FORKID;
248
+
249
+ module.exports = CustomScriptHelper;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@smartledger/bsv",
3
- "version": "3.0.2",
4
- "description": "Security-hardened Bitcoin SV library - Complete drop-in replacement for bsv@1.5.6 with zero vulnerabilities",
3
+ "version": "3.1.1",
4
+ "description": "Security-hardened Bitcoin SV library with custom script framework - Complete drop-in replacement for bsv@1.5.6 with zero vulnerabilities",
5
5
  "author": "SmartLedger Technology <hello@smartledger.technology> (https://smartledger.technology)",
6
6
  "homepage": "https://github.com/codenlighten/smartledger-bsv#readme",
7
7
  "bugs": {