@smartledger/bsv 3.3.5 → 3.4.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/CHANGELOG.md +48 -0
- package/README.md +149 -20
- package/anchor-entry.js +1 -0
- package/bin/cli.js +349 -0
- package/bsv-anchor.min.js +12 -0
- package/bsv-covenant.min.js +8 -8
- package/bsv-didweb.min.js +12 -0
- package/bsv-gdaf.min.js +9 -9
- package/bsv-ltp.min.js +9 -9
- package/bsv-mnemonic.min.js +2 -2
- package/bsv-shamir.min.js +3 -3
- package/bsv-smartcontract.min.js +9 -9
- package/bsv-statuslist.min.js +18 -0
- package/bsv-vcjwt.min.js +12 -0
- package/bsv.bundle.js +9 -9
- package/bsv.min.js +8 -8
- package/build/webpack.anchor.config.js +17 -0
- package/build/webpack.didweb.config.js +17 -0
- package/build/webpack.statuslist.config.js +17 -0
- package/build/webpack.vcjwt.config.js +17 -0
- package/demos/browser-test.html +1 -1
- package/didweb-entry.js +1 -0
- package/docs/technical/roadmap.md +3 -3
- package/examples/legacy/README.md +11 -0
- package/index.js +39 -1
- package/lib/anchor/index.js +102 -0
- package/lib/browser-utxo-manager-es5.js +11 -4
- package/lib/browser-utxo-manager.js +15 -8
- package/lib/didweb/index.js +177 -0
- package/lib/ltp/claim.js +1 -0
- package/lib/ltp/obligation.js +1 -0
- package/lib/ltp/registry.js +2 -0
- package/lib/ltp/right.js +1 -0
- package/lib/statuslist/index.js +164 -0
- package/lib/transaction/transaction.js +1 -1
- package/lib/util/_.js +7 -1
- package/lib/vcjwt/index.js +189 -0
- package/package.json +19 -13
- package/statuslist-entry.js +1 -0
- package/vcjwt-entry.js +1 -0
- package/demos/gdaf_core_test.js +0 -131
- package/examples/scripts/custom_script_signature_test.js +0 -344
- package/tests/browser-compatibility/README.md +0 -35
- package/tests/browser-compatibility/test-cdn-vs-local.html +0 -186
- package/tests/browser-compatibility/test-pbkdf2.html +0 -51
- package/tests/bundle-completeness-test.html +0 -131
- package/tests/bundle-demo.html +0 -476
- package/tests/smartcontract-test.html +0 -239
- package/tests/standalone-modules-test.html +0 -260
- package/tests/test.html +0 -612
- package/tests/test_standalone_shamir.html +0 -83
- package/tests/unpkg-demo.html +0 -194
- package/utilities/blockchain-state.json +0 -118565
- /package/{lib/smart_contract/test_integration.js → examples/legacy/smart_contract_test_integration.js} +0 -0
- /package/{tests → examples/legacy}/test_builtin_verify.js +0 -0
- /package/{tests → examples/legacy}/test_debug_integration.js +0 -0
- /package/{tests → examples/legacy}/test_ecdsa_little.js +0 -0
- /package/{tests → examples/legacy}/test_shamir.js +0 -0
- /package/{tests → examples/legacy}/test_smartverify_der.js +0 -0
|
@@ -1,344 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Custom Script Signature Test - Comprehensive BSV Script Development
|
|
5
|
-
*
|
|
6
|
-
* Tests signature creation for:
|
|
7
|
-
* 1. Standard P2PKH scripts
|
|
8
|
-
* 2. Custom locking scripts
|
|
9
|
-
* 3. Custom unlocking scripts
|
|
10
|
-
* 4. Multi-signature scripts
|
|
11
|
-
* 5. Covenant-style scripts with preimages
|
|
12
|
-
*
|
|
13
|
-
* FOR PRODUCTION BSV DEVELOPMENT
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
const bsv = require('./index.js');
|
|
17
|
-
|
|
18
|
-
console.log('🔬 Custom Script Signature Test - Comprehensive BSV Development');
|
|
19
|
-
console.log('==============================================================');
|
|
20
|
-
console.log(`SmartLedger-BSV Version: ${bsv.SmartLedger?.version}`);
|
|
21
|
-
console.log(`Test Date: ${new Date().toISOString()}\n`);
|
|
22
|
-
|
|
23
|
-
// Test keys and data
|
|
24
|
-
const privateKey1 = new bsv.PrivateKey('5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss');
|
|
25
|
-
const publicKey1 = privateKey1.publicKey;
|
|
26
|
-
const privateKey2 = new bsv.PrivateKey('5Hx15HFGyep2CfPxsJKe2fXJsCVn5DEiyoeGGF6JZjGbTRnqfiD');
|
|
27
|
-
const publicKey2 = privateKey2.publicKey;
|
|
28
|
-
|
|
29
|
-
console.log('🔧 Test Setup:');
|
|
30
|
-
console.log(`- Private Key 1: ${privateKey1.toString()}`);
|
|
31
|
-
console.log(`- Public Key 1: ${publicKey1.toString()}`);
|
|
32
|
-
console.log(`- Private Key 2: ${privateKey2.toString()}`);
|
|
33
|
-
console.log(`- Public Key 2: ${publicKey2.toString()}\n`);
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Helper function to create proper signatures for custom scripts
|
|
37
|
-
*/
|
|
38
|
-
function createCustomSignature(transaction, privateKey, inputIndex, lockingScript, satoshis, sighashType = null) {
|
|
39
|
-
sighashType = sighashType || (bsv.crypto.Signature.SIGHASH_ALL | bsv.crypto.Signature.SIGHASH_FORKID);
|
|
40
|
-
|
|
41
|
-
const signature = bsv.Transaction.sighash.sign(
|
|
42
|
-
transaction,
|
|
43
|
-
privateKey,
|
|
44
|
-
sighashType,
|
|
45
|
-
inputIndex,
|
|
46
|
-
lockingScript,
|
|
47
|
-
new bsv.crypto.BN(satoshis)
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
// Return signature with sighash type appended
|
|
51
|
-
return Buffer.concat([signature.toDER(), Buffer.from([sighashType])]);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Test 1: Standard P2PKH Script (Baseline)
|
|
56
|
-
*/
|
|
57
|
-
async function testStandardP2PKH() {
|
|
58
|
-
console.log('✅ TEST 1: Standard P2PKH Script (Baseline)');
|
|
59
|
-
console.log('===========================================');
|
|
60
|
-
|
|
61
|
-
// Create standard UTXO
|
|
62
|
-
const utxo = {
|
|
63
|
-
txid: 'a'.repeat(64),
|
|
64
|
-
vout: 0,
|
|
65
|
-
satoshis: 100000,
|
|
66
|
-
script: bsv.Script.buildPublicKeyHashOut(publicKey1.toAddress()).toHex()
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
console.log(`- Locking Script: ${bsv.Script.fromHex(utxo.script).toString()}`);
|
|
70
|
-
|
|
71
|
-
// Create transaction
|
|
72
|
-
const tx = new bsv.Transaction()
|
|
73
|
-
.from(utxo)
|
|
74
|
-
.to('1BitcoinEaterAddressDontSendf59kuE', 99000);
|
|
75
|
-
|
|
76
|
-
// Method 1: Automatic signing
|
|
77
|
-
const autoTx = new bsv.Transaction().from(utxo).to('1BitcoinEaterAddressDontSendf59kuE', 99000).sign(privateKey1);
|
|
78
|
-
console.log(`- Automatic signing: ✅ VALID`);
|
|
79
|
-
|
|
80
|
-
// Method 2: Manual signing
|
|
81
|
-
const manualSig = createCustomSignature(tx, privateKey1, 0, bsv.Script.fromHex(utxo.script), utxo.satoshis);
|
|
82
|
-
const unlockingScript = new bsv.Script()
|
|
83
|
-
.add(manualSig)
|
|
84
|
-
.add(publicKey1.toBuffer());
|
|
85
|
-
|
|
86
|
-
tx.inputs[0].setScript(unlockingScript);
|
|
87
|
-
|
|
88
|
-
console.log(`- Manual signing: ✅ ${tx.verify() ? 'VALID' : 'INVALID'}`);
|
|
89
|
-
console.log(`- Signatures match: ${autoTx.inputs[0].script.toHex() === tx.inputs[0].script.toHex() ? '✅ YES' : '❌ NO'}\n`);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Test 2: Custom Multi-Signature Script
|
|
94
|
-
*/
|
|
95
|
-
async function testCustomMultiSig() {
|
|
96
|
-
console.log('✅ TEST 2: Custom Multi-Signature Script');
|
|
97
|
-
console.log('========================================');
|
|
98
|
-
|
|
99
|
-
// Create custom 2-of-2 multisig locking script
|
|
100
|
-
const lockingScript = new bsv.Script()
|
|
101
|
-
.add(bsv.Opcode.OP_2)
|
|
102
|
-
.add(publicKey1.toBuffer())
|
|
103
|
-
.add(publicKey2.toBuffer())
|
|
104
|
-
.add(bsv.Opcode.OP_2)
|
|
105
|
-
.add(bsv.Opcode.OP_CHECKMULTISIG);
|
|
106
|
-
|
|
107
|
-
console.log(`- Locking Script: ${lockingScript.toString()}`);
|
|
108
|
-
|
|
109
|
-
const utxo = {
|
|
110
|
-
txid: 'b'.repeat(64),
|
|
111
|
-
vout: 0,
|
|
112
|
-
satoshis: 200000,
|
|
113
|
-
script: lockingScript.toHex()
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
const tx = new bsv.Transaction()
|
|
117
|
-
.from(utxo)
|
|
118
|
-
.to('1BitcoinEaterAddressDontSendf59kuE', 199000);
|
|
119
|
-
|
|
120
|
-
// Create manual signatures for multisig
|
|
121
|
-
const sig1 = createCustomSignature(tx, privateKey1, 0, lockingScript, utxo.satoshis);
|
|
122
|
-
const sig2 = createCustomSignature(tx, privateKey2, 0, lockingScript, utxo.satoshis);
|
|
123
|
-
|
|
124
|
-
// Create unlocking script for 2-of-2 multisig
|
|
125
|
-
const unlockingScript = new bsv.Script()
|
|
126
|
-
.add(bsv.Opcode.OP_0) // Extra value for CHECKMULTISIG bug
|
|
127
|
-
.add(sig1)
|
|
128
|
-
.add(sig2);
|
|
129
|
-
|
|
130
|
-
tx.inputs[0].setScript(unlockingScript);
|
|
131
|
-
|
|
132
|
-
console.log(`- Custom multisig: ✅ ${tx.verify() ? 'VALID' : 'INVALID'}`);
|
|
133
|
-
console.log(`- Signature 1 length: ${sig1.length} bytes`);
|
|
134
|
-
console.log(`- Signature 2 length: ${sig2.length} bytes\n`);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Test 3: Custom Conditional Script (OP_IF/OP_ELSE)
|
|
139
|
-
*/
|
|
140
|
-
async function testCustomConditional() {
|
|
141
|
-
console.log('✅ TEST 3: Custom Conditional Script (OP_IF/OP_ELSE)');
|
|
142
|
-
console.log('==================================================');
|
|
143
|
-
|
|
144
|
-
// Create conditional script: IF <sig1> ELSE <sig2> ENDIF
|
|
145
|
-
const lockingScript = new bsv.Script()
|
|
146
|
-
.add(bsv.Opcode.OP_IF)
|
|
147
|
-
.add(bsv.Opcode.OP_DUP)
|
|
148
|
-
.add(bsv.Opcode.OP_HASH160)
|
|
149
|
-
.add(publicKey1.toAddress().hashBuffer)
|
|
150
|
-
.add(bsv.Opcode.OP_EQUALVERIFY)
|
|
151
|
-
.add(bsv.Opcode.OP_CHECKSIG)
|
|
152
|
-
.add(bsv.Opcode.OP_ELSE)
|
|
153
|
-
.add(bsv.Opcode.OP_DUP)
|
|
154
|
-
.add(bsv.Opcode.OP_HASH160)
|
|
155
|
-
.add(publicKey2.toAddress().hashBuffer)
|
|
156
|
-
.add(bsv.Opcode.OP_EQUALVERIFY)
|
|
157
|
-
.add(bsv.Opcode.OP_CHECKSIG)
|
|
158
|
-
.add(bsv.Opcode.OP_ENDIF);
|
|
159
|
-
|
|
160
|
-
console.log(`- Locking Script: ${lockingScript.toString()}`);
|
|
161
|
-
|
|
162
|
-
const utxo = {
|
|
163
|
-
txid: 'c'.repeat(64),
|
|
164
|
-
vout: 0,
|
|
165
|
-
satoshis: 150000,
|
|
166
|
-
script: lockingScript.toHex()
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
// Test Path 1: IF branch (publicKey1)
|
|
170
|
-
const tx1 = new bsv.Transaction().from(utxo).to('1BitcoinEaterAddressDontSendf59kuE', 149000);
|
|
171
|
-
const sig1 = createCustomSignature(tx1, privateKey1, 0, lockingScript, utxo.satoshis);
|
|
172
|
-
|
|
173
|
-
const unlockingScript1 = new bsv.Script()
|
|
174
|
-
.add(sig1)
|
|
175
|
-
.add(publicKey1.toBuffer())
|
|
176
|
-
.add(bsv.Opcode.OP_1); // Choose IF branch
|
|
177
|
-
|
|
178
|
-
tx1.inputs[0].setScript(unlockingScript1);
|
|
179
|
-
console.log(`- IF branch (key1): ✅ ${tx1.verify() ? 'VALID' : 'INVALID'}`);
|
|
180
|
-
|
|
181
|
-
// Test Path 2: ELSE branch (publicKey2)
|
|
182
|
-
const tx2 = new bsv.Transaction().from(utxo).to('1BitcoinEaterAddressDontSendf59kuE', 149000);
|
|
183
|
-
const sig2 = createCustomSignature(tx2, privateKey2, 0, lockingScript, utxo.satoshis);
|
|
184
|
-
|
|
185
|
-
const unlockingScript2 = new bsv.Script()
|
|
186
|
-
.add(sig2)
|
|
187
|
-
.add(publicKey2.toBuffer())
|
|
188
|
-
.add(bsv.Opcode.OP_0); // Choose ELSE branch
|
|
189
|
-
|
|
190
|
-
tx2.inputs[0].setScript(unlockingScript2);
|
|
191
|
-
console.log(`- ELSE branch (key2): ✅ ${tx2.verify() ? 'VALID' : 'INVALID'}\n`);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Test 4: Custom Time-Locked Script
|
|
196
|
-
*/
|
|
197
|
-
async function testCustomTimeLock() {
|
|
198
|
-
console.log('✅ TEST 4: Custom Time-Locked Script');
|
|
199
|
-
console.log('===================================');
|
|
200
|
-
|
|
201
|
-
const lockTime = 700000; // Block height lock
|
|
202
|
-
|
|
203
|
-
// Create time-locked script: <lockTime> OP_CHECKLOCKTIMEVERIFY OP_DROP <pubkeyhash_script>
|
|
204
|
-
const lockingScript = new bsv.Script()
|
|
205
|
-
.add(Buffer.from(lockTime.toString(16).padStart(8, '0'), 'hex').reverse()) // Little endian
|
|
206
|
-
.add(bsv.Opcode.OP_CHECKLOCKTIMEVERIFY)
|
|
207
|
-
.add(bsv.Opcode.OP_DROP)
|
|
208
|
-
.add(bsv.Opcode.OP_DUP)
|
|
209
|
-
.add(bsv.Opcode.OP_HASH160)
|
|
210
|
-
.add(publicKey1.toAddress().hashBuffer)
|
|
211
|
-
.add(bsv.Opcode.OP_EQUALVERIFY)
|
|
212
|
-
.add(bsv.Opcode.OP_CHECKSIG);
|
|
213
|
-
|
|
214
|
-
console.log(`- Locking Script: ${lockingScript.toString()}`);
|
|
215
|
-
|
|
216
|
-
const utxo = {
|
|
217
|
-
txid: 'd'.repeat(64),
|
|
218
|
-
vout: 0,
|
|
219
|
-
satoshis: 175000,
|
|
220
|
-
script: lockingScript.toHex()
|
|
221
|
-
};
|
|
222
|
-
|
|
223
|
-
const tx = new bsv.Transaction()
|
|
224
|
-
.from(utxo)
|
|
225
|
-
.to('1BitcoinEaterAddressDontSendf59kuE', 174000)
|
|
226
|
-
.lockUntilBlockHeight(lockTime);
|
|
227
|
-
|
|
228
|
-
const sig = createCustomSignature(tx, privateKey1, 0, lockingScript, utxo.satoshis);
|
|
229
|
-
|
|
230
|
-
const unlockingScript = new bsv.Script()
|
|
231
|
-
.add(sig)
|
|
232
|
-
.add(publicKey1.toBuffer());
|
|
233
|
-
|
|
234
|
-
tx.inputs[0].setScript(unlockingScript);
|
|
235
|
-
|
|
236
|
-
console.log(`- Time-locked transaction: ✅ ${tx.verify() ? 'VALID' : 'INVALID'}`);
|
|
237
|
-
console.log(`- Lock time: ${tx.nLockTime} (block height)`);
|
|
238
|
-
console.log(`- Required lock time: ${lockTime}\n`);
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* Test 5: Covenant-Style Script with Preimage
|
|
243
|
-
*/
|
|
244
|
-
async function testCovenantPreimage() {
|
|
245
|
-
console.log('✅ TEST 5: Covenant-Style Script with Preimage');
|
|
246
|
-
console.log('==============================================');
|
|
247
|
-
|
|
248
|
-
// Simplified covenant: check that output amount is preserved
|
|
249
|
-
const lockingScript = new bsv.Script()
|
|
250
|
-
.add(bsv.Opcode.OP_DUP)
|
|
251
|
-
.add(bsv.Opcode.OP_HASH160)
|
|
252
|
-
.add(publicKey1.toAddress().hashBuffer)
|
|
253
|
-
.add(bsv.Opcode.OP_EQUALVERIFY)
|
|
254
|
-
.add(bsv.Opcode.OP_CHECKSIG);
|
|
255
|
-
|
|
256
|
-
console.log(`- Covenant Locking Script: ${lockingScript.toString()}`);
|
|
257
|
-
|
|
258
|
-
const utxo = {
|
|
259
|
-
txid: 'e'.repeat(64),
|
|
260
|
-
vout: 0,
|
|
261
|
-
satoshis: 300000,
|
|
262
|
-
script: lockingScript.toHex()
|
|
263
|
-
};
|
|
264
|
-
|
|
265
|
-
const tx = new bsv.Transaction()
|
|
266
|
-
.from(utxo)
|
|
267
|
-
.to('1BitcoinEaterAddressDontSendf59kuE', 299000);
|
|
268
|
-
|
|
269
|
-
// Create preimage for covenant validation
|
|
270
|
-
const sighashType = bsv.crypto.Signature.SIGHASH_ALL | bsv.crypto.Signature.SIGHASH_FORKID;
|
|
271
|
-
const preimage = bsv.Transaction.sighash.sighash(
|
|
272
|
-
tx,
|
|
273
|
-
sighashType,
|
|
274
|
-
0,
|
|
275
|
-
lockingScript,
|
|
276
|
-
new bsv.crypto.BN(utxo.satoshis)
|
|
277
|
-
);
|
|
278
|
-
|
|
279
|
-
console.log(`- Preimage: ${preimage.toString('hex')}`);
|
|
280
|
-
console.log(`- Preimage length: ${preimage.length} bytes`);
|
|
281
|
-
|
|
282
|
-
const sig = createCustomSignature(tx, privateKey1, 0, lockingScript, utxo.satoshis);
|
|
283
|
-
|
|
284
|
-
const unlockingScript = new bsv.Script()
|
|
285
|
-
.add(sig)
|
|
286
|
-
.add(publicKey1.toBuffer());
|
|
287
|
-
|
|
288
|
-
tx.inputs[0].setScript(unlockingScript);
|
|
289
|
-
|
|
290
|
-
console.log(`- Covenant transaction: ✅ ${tx.verify() ? 'VALID' : 'INVALID'}`);
|
|
291
|
-
console.log(`- Preimage available for covenant logic: ✅ YES\n`);
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
/**
|
|
295
|
-
* Run all tests
|
|
296
|
-
*/
|
|
297
|
-
async function runAllTests() {
|
|
298
|
-
try {
|
|
299
|
-
await testStandardP2PKH();
|
|
300
|
-
await testCustomMultiSig();
|
|
301
|
-
await testCustomConditional();
|
|
302
|
-
await testCustomTimeLock();
|
|
303
|
-
await testCovenantPreimage();
|
|
304
|
-
|
|
305
|
-
console.log('🎉 CUSTOM SCRIPT SIGNATURE TEST RESULTS');
|
|
306
|
-
console.log('=======================================');
|
|
307
|
-
console.log('✅ Standard P2PKH: WORKING');
|
|
308
|
-
console.log('✅ Custom Multi-Signature: WORKING');
|
|
309
|
-
console.log('✅ Conditional Scripts (IF/ELSE): WORKING');
|
|
310
|
-
console.log('✅ Time-Locked Scripts: WORKING');
|
|
311
|
-
console.log('✅ Covenant Preimages: WORKING');
|
|
312
|
-
console.log('');
|
|
313
|
-
console.log('🚀 SmartLedger-BSV v3.0.2 is READY for custom script development!');
|
|
314
|
-
console.log('📝 All signature creation methods work for advanced BSV applications');
|
|
315
|
-
console.log('🔧 Developers can build covenants, smart contracts, and custom payment conditions');
|
|
316
|
-
|
|
317
|
-
} catch (error) {
|
|
318
|
-
console.error('❌ Test failed:', error.message);
|
|
319
|
-
console.error(error.stack);
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
// API Documentation
|
|
324
|
-
console.log('📚 CUSTOM SCRIPT SIGNATURE API');
|
|
325
|
-
console.log('===============================');
|
|
326
|
-
console.log('For custom locking/unlocking scripts, use:');
|
|
327
|
-
console.log('');
|
|
328
|
-
console.log('const signature = bsv.Transaction.sighash.sign(');
|
|
329
|
-
console.log(' transaction, // The transaction object');
|
|
330
|
-
console.log(' privateKey, // Private key to sign with');
|
|
331
|
-
console.log(' sighashType, // SIGHASH_ALL | SIGHASH_FORKID (default)');
|
|
332
|
-
console.log(' inputIndex, // Input index (0 for first input)');
|
|
333
|
-
console.log(' lockingScript, // The locking script being spent');
|
|
334
|
-
console.log(' satoshisBN // Amount in satoshis (as BN)');
|
|
335
|
-
console.log(');');
|
|
336
|
-
console.log('');
|
|
337
|
-
console.log('const fullSig = Buffer.concat([');
|
|
338
|
-
console.log(' signature.toDER(),');
|
|
339
|
-
console.log(' Buffer.from([sighashType])');
|
|
340
|
-
console.log(']);');
|
|
341
|
-
console.log('');
|
|
342
|
-
|
|
343
|
-
// Run the tests
|
|
344
|
-
runAllTests();
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# Browser Compatibility Tests
|
|
2
|
-
|
|
3
|
-
This directory contains test files for verifying browser compatibility fixes.
|
|
4
|
-
|
|
5
|
-
## Test Files
|
|
6
|
-
|
|
7
|
-
### `test-cdn-vs-local.html`
|
|
8
|
-
Comprehensive test that compares CDN bundles vs local bundles to verify the `createHmac` fix.
|
|
9
|
-
|
|
10
|
-
**Usage:**
|
|
11
|
-
1. Open in browser
|
|
12
|
-
2. Click "Test CDN Version" - should show `createHmac` error (if using unfixed CDN)
|
|
13
|
-
3. Click "Test Local Version" - should work with fixed bundles
|
|
14
|
-
4. View summary to confirm fix effectiveness
|
|
15
|
-
|
|
16
|
-
### `test-pbkdf2.html`
|
|
17
|
-
Simple test focused specifically on PBKDF2 functionality.
|
|
18
|
-
|
|
19
|
-
**Usage:**
|
|
20
|
-
1. Open in browser
|
|
21
|
-
2. Tests mnemonic generation using PBKDF2
|
|
22
|
-
3. Shows detailed error information if PBKDF2 fails
|
|
23
|
-
|
|
24
|
-
## Background
|
|
25
|
-
|
|
26
|
-
These tests were created to verify the fix for issue where CDN users experienced:
|
|
27
|
-
- `createHmac is not a function` errors
|
|
28
|
-
- Failed mnemonic generation
|
|
29
|
-
- Failed HD wallet key derivation
|
|
30
|
-
|
|
31
|
-
The fix implemented browser-compatible PBKDF2 using BSV's crypto modules instead of Node.js crypto.
|
|
32
|
-
|
|
33
|
-
## Fix Details
|
|
34
|
-
|
|
35
|
-
See `docs/FIX_CREATEHMAC_ISSUE.md` for complete technical details.
|
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8">
|
|
5
|
-
<title>CDN vs Local PBKDF2 Test</title>
|
|
6
|
-
<style>
|
|
7
|
-
body { font-family: Arial, sans-serif; margin: 20px; }
|
|
8
|
-
.test-section { margin: 20px 0; padding: 15px; border: 1px solid #ccc; border-radius: 5px; }
|
|
9
|
-
.error { color: red; }
|
|
10
|
-
.success { color: green; }
|
|
11
|
-
.info { color: blue; }
|
|
12
|
-
pre { background: #f5f5f5; padding: 10px; border-radius: 3px; }
|
|
13
|
-
</style>
|
|
14
|
-
</head>
|
|
15
|
-
<body>
|
|
16
|
-
<h1>SmartLedger BSV: CDN vs Local PBKDF2 Test</h1>
|
|
17
|
-
|
|
18
|
-
<div class="test-section">
|
|
19
|
-
<h2>Test 1: CDN Version (Expected to fail with createHmac error)</h2>
|
|
20
|
-
<button onclick="testCDN()">Test CDN Version</button>
|
|
21
|
-
<div id="cdn-results"></div>
|
|
22
|
-
</div>
|
|
23
|
-
|
|
24
|
-
<div class="test-section">
|
|
25
|
-
<h2>Test 2: Local Fixed Version (Should work)</h2>
|
|
26
|
-
<button onclick="testLocal()">Test Local Version</button>
|
|
27
|
-
<div id="local-results"></div>
|
|
28
|
-
</div>
|
|
29
|
-
|
|
30
|
-
<div class="test-section">
|
|
31
|
-
<h2>Summary</h2>
|
|
32
|
-
<div id="summary"></div>
|
|
33
|
-
</div>
|
|
34
|
-
|
|
35
|
-
<script>
|
|
36
|
-
function log(elementId, message, type = 'info') {
|
|
37
|
-
const element = document.getElementById(elementId);
|
|
38
|
-
const className = type === 'error' ? 'error' : type === 'success' ? 'success' : 'info';
|
|
39
|
-
element.innerHTML += `<div class="${className}">${message}</div>`;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function clearResults(elementId) {
|
|
43
|
-
document.getElementById(elementId).innerHTML = '';
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function testCDN() {
|
|
47
|
-
clearResults('cdn-results');
|
|
48
|
-
log('cdn-results', 'Loading CDN version...');
|
|
49
|
-
|
|
50
|
-
// Remove any existing scripts
|
|
51
|
-
const existingScripts = document.querySelectorAll('script[src*="bsv"]');
|
|
52
|
-
existingScripts.forEach(script => script.remove());
|
|
53
|
-
|
|
54
|
-
// Clear global variables
|
|
55
|
-
if (window.bsv) delete window.bsv;
|
|
56
|
-
if (window.bsvMnemonic) delete window.bsvMnemonic;
|
|
57
|
-
if (window.Mnemonic) delete window.Mnemonic;
|
|
58
|
-
|
|
59
|
-
// Load CDN scripts
|
|
60
|
-
const bsvScript = document.createElement('script');
|
|
61
|
-
bsvScript.src = 'https://cdn.jsdelivr.net/npm/smartledger-bsv@3.3.4/bsv.min.js';
|
|
62
|
-
bsvScript.onload = () => {
|
|
63
|
-
const mnemonicScript = document.createElement('script');
|
|
64
|
-
mnemonicScript.src = 'https://cdn.jsdelivr.net/npm/smartledger-bsv@3.3.4/bsv-mnemonic.min.js';
|
|
65
|
-
mnemonicScript.onload = () => {
|
|
66
|
-
testMnemonicGeneration('cdn-results', 'CDN');
|
|
67
|
-
};
|
|
68
|
-
mnemonicScript.onerror = () => {
|
|
69
|
-
log('cdn-results', '❌ Failed to load CDN mnemonic script', 'error');
|
|
70
|
-
};
|
|
71
|
-
document.head.appendChild(mnemonicScript);
|
|
72
|
-
};
|
|
73
|
-
bsvScript.onerror = () => {
|
|
74
|
-
log('cdn-results', '❌ Failed to load CDN BSV script', 'error');
|
|
75
|
-
};
|
|
76
|
-
document.head.appendChild(bsvScript);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function testLocal() {
|
|
80
|
-
clearResults('local-results');
|
|
81
|
-
log('local-results', 'Loading local fixed version...');
|
|
82
|
-
|
|
83
|
-
// Remove any existing scripts
|
|
84
|
-
const existingScripts = document.querySelectorAll('script[src*="bsv"]');
|
|
85
|
-
existingScripts.forEach(script => script.remove());
|
|
86
|
-
|
|
87
|
-
// Clear global variables
|
|
88
|
-
if (window.bsv) delete window.bsv;
|
|
89
|
-
if (window.bsvMnemonic) delete window.bsvMnemonic;
|
|
90
|
-
if (window.Mnemonic) delete window.Mnemonic;
|
|
91
|
-
|
|
92
|
-
// Load local scripts
|
|
93
|
-
const bsvScript = document.createElement('script');
|
|
94
|
-
bsvScript.src = '../bsv.min.js';
|
|
95
|
-
bsvScript.onload = () => {
|
|
96
|
-
const mnemonicScript = document.createElement('script');
|
|
97
|
-
mnemonicScript.src = '../bsv-mnemonic.min.js';
|
|
98
|
-
mnemonicScript.onload = () => {
|
|
99
|
-
testMnemonicGeneration('local-results', 'Local');
|
|
100
|
-
};
|
|
101
|
-
mnemonicScript.onerror = () => {
|
|
102
|
-
log('local-results', '❌ Failed to load local mnemonic script', 'error');
|
|
103
|
-
};
|
|
104
|
-
document.head.appendChild(mnemonicScript);
|
|
105
|
-
};
|
|
106
|
-
bsvScript.onerror = () => {
|
|
107
|
-
log('local-results', '❌ Failed to load local BSV script', 'error');
|
|
108
|
-
};
|
|
109
|
-
document.head.appendChild(bsvScript);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
function testMnemonicGeneration(resultElementId, version) {
|
|
113
|
-
try {
|
|
114
|
-
log(resultElementId, `${version} scripts loaded successfully`, 'info');
|
|
115
|
-
|
|
116
|
-
// Check what's available
|
|
117
|
-
const MnemonicClass = window.bsvMnemonic || window.Mnemonic || (window.bsv && window.bsv.Mnemonic);
|
|
118
|
-
log(resultElementId, `Mnemonic class available: ${!!MnemonicClass}`, 'info');
|
|
119
|
-
|
|
120
|
-
if (MnemonicClass) {
|
|
121
|
-
// Test mnemonic generation
|
|
122
|
-
log(resultElementId, 'Attempting to generate mnemonic...', 'info');
|
|
123
|
-
const mnemonic = MnemonicClass.fromRandom(256);
|
|
124
|
-
log(resultElementId, `✅ ${version} mnemonic generation successful!`, 'success');
|
|
125
|
-
log(resultElementId, `Sample words: ${mnemonic.phrase.split(' ').slice(0, 4).join(' ')}...`, 'info');
|
|
126
|
-
|
|
127
|
-
// Test key derivation
|
|
128
|
-
log(resultElementId, 'Testing key derivation...', 'info');
|
|
129
|
-
const hdPrivateKey = bsv.HDPrivateKey.fromSeed(mnemonic.toSeed());
|
|
130
|
-
const derived = hdPrivateKey.deriveChild("m/44'/236'/0'/0/0");
|
|
131
|
-
const address = derived.privateKey.toAddress().toString();
|
|
132
|
-
log(resultElementId, `✅ ${version} key derivation successful!`, 'success');
|
|
133
|
-
log(resultElementId, `Address: ${address}`, 'info');
|
|
134
|
-
|
|
135
|
-
updateSummary(version, 'SUCCESS');
|
|
136
|
-
} else {
|
|
137
|
-
log(resultElementId, `❌ ${version} mnemonic class not available`, 'error');
|
|
138
|
-
updateSummary(version, 'NO_MNEMONIC_CLASS');
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
} catch (error) {
|
|
142
|
-
log(resultElementId, `❌ ${version} error: ${error.message}`, 'error');
|
|
143
|
-
if (error.message.includes('createHmac')) {
|
|
144
|
-
log(resultElementId, '🔍 This is the createHmac error we are fixing!', 'error');
|
|
145
|
-
updateSummary(version, 'CREATEHMAC_ERROR');
|
|
146
|
-
} else {
|
|
147
|
-
updateSummary(version, 'OTHER_ERROR');
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
let testResults = {};
|
|
153
|
-
|
|
154
|
-
function updateSummary(version, result) {
|
|
155
|
-
testResults[version] = result;
|
|
156
|
-
|
|
157
|
-
let summary = '<h3>Test Results Summary:</h3>';
|
|
158
|
-
|
|
159
|
-
if (testResults['CDN']) {
|
|
160
|
-
const cdnStatus = testResults['CDN'] === 'SUCCESS' ? '✅ Working' :
|
|
161
|
-
testResults['CDN'] === 'CREATEHMAC_ERROR' ? '❌ createHmac error' :
|
|
162
|
-
'❌ Failed';
|
|
163
|
-
summary += `<div><strong>CDN Version:</strong> ${cdnStatus}</div>`;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
if (testResults['Local']) {
|
|
167
|
-
const localStatus = testResults['Local'] === 'SUCCESS' ? '✅ Working' : '❌ Failed';
|
|
168
|
-
summary += `<div><strong>Local Fixed Version:</strong> ${localStatus}</div>`;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
if (testResults['CDN'] && testResults['Local']) {
|
|
172
|
-
if (testResults['CDN'] === 'CREATEHMAC_ERROR' && testResults['Local'] === 'SUCCESS') {
|
|
173
|
-
summary += '<div class="success"><strong>✅ Fix confirmed!</strong> The local version resolves the CDN createHmac issue.</div>';
|
|
174
|
-
summary += '<div class="info"><strong>Solution:</strong> The CDN bundle needs browser-compatible PBKDF2 implementation that uses BSV crypto instead of Node.js crypto.</div>';
|
|
175
|
-
} else if (testResults['CDN'] === 'SUCCESS' && testResults['Local'] === 'SUCCESS') {
|
|
176
|
-
summary += '<div class="success"><strong>Both versions working!</strong></div>';
|
|
177
|
-
} else {
|
|
178
|
-
summary += '<div class="error"><strong>Unexpected results.</strong> Please check the implementation.</div>';
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
document.getElementById('summary').innerHTML = summary;
|
|
183
|
-
}
|
|
184
|
-
</script>
|
|
185
|
-
</body>
|
|
186
|
-
</html>
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
3
|
-
<head>
|
|
4
|
-
<title>PBKDF2 Test</title>
|
|
5
|
-
</head>
|
|
6
|
-
<body>
|
|
7
|
-
<h1>Testing PBKDF2 Browser Compatibility</h1>
|
|
8
|
-
<div id="results"></div>
|
|
9
|
-
|
|
10
|
-
<script src="../bsv.min.js"></script>
|
|
11
|
-
<script src="../bsv-mnemonic.min.js"></script>
|
|
12
|
-
|
|
13
|
-
<script>
|
|
14
|
-
const results = document.getElementById('results');
|
|
15
|
-
|
|
16
|
-
function log(message) {
|
|
17
|
-
results.innerHTML += '<div>' + message + '</div>';
|
|
18
|
-
console.log(message);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// Test mnemonic generation
|
|
22
|
-
try {
|
|
23
|
-
log('Testing mnemonic generation...');
|
|
24
|
-
|
|
25
|
-
// Check if modules are available
|
|
26
|
-
const MnemonicClass = window.bsvMnemonic || window.Mnemonic || (window.bsv && window.bsv.Mnemonic);
|
|
27
|
-
log('Mnemonic class available: ' + !!MnemonicClass);
|
|
28
|
-
|
|
29
|
-
if (MnemonicClass) {
|
|
30
|
-
// Generate a mnemonic
|
|
31
|
-
const mnemonic = MnemonicClass.fromRandom(256);
|
|
32
|
-
log('✅ Mnemonic generated successfully: ' + mnemonic.phrase.split(' ').slice(0, 4).join(' ') + '...');
|
|
33
|
-
|
|
34
|
-
// Test derivation
|
|
35
|
-
const hdPrivateKey = bsv.HDPrivateKey.fromSeed(mnemonic.toSeed());
|
|
36
|
-
const derived = hdPrivateKey.deriveChild("m/44'/236'/0'/0/0");
|
|
37
|
-
log('✅ Key derivation successful');
|
|
38
|
-
log('✅ Address: ' + derived.privateKey.toAddress().toString());
|
|
39
|
-
} else {
|
|
40
|
-
log('❌ Mnemonic class not available');
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
} catch (error) {
|
|
44
|
-
log('❌ Error: ' + error.message);
|
|
45
|
-
if (error.message.includes('createHmac')) {
|
|
46
|
-
log('🔍 This is the createHmac error we are fixing!');
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
</script>
|
|
50
|
-
</body>
|
|
51
|
-
</html>
|