@smartledger/bsv 3.3.3 → 3.3.4
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 +20 -7
- package/README.md +18 -1
- package/bsv-covenant.min.js +5 -5
- package/bsv-gdaf.min.js +4 -4
- package/bsv-ltp.min.js +4 -4
- package/bsv-mnemonic.min.js +4 -4
- package/bsv-smartcontract.min.js +4 -4
- package/bsv.bundle.js +4 -4
- package/bsv.min.js +4 -4
- package/demos/README.md +188 -0
- package/demos/architecture_demo.js +247 -0
- package/demos/bsv_wallet_demo.js +242 -0
- package/demos/complete_ltp_demo.js +511 -0
- package/demos/debug_tools_demo.js +87 -0
- package/demos/demo_features.js +123 -0
- package/demos/easy_interface_demo.js +109 -0
- package/demos/ecies_demo.js +182 -0
- package/demos/gdaf_core_test.js +131 -0
- package/demos/gdaf_demo.js +237 -0
- package/demos/ltp_demo.js +361 -0
- package/demos/ltp_primitives_demo.js +403 -0
- package/demos/message_demo.js +209 -0
- package/demos/preimage_separation_demo.js +383 -0
- package/demos/script_helper_demo.js +289 -0
- package/demos/security_demo.js +287 -0
- package/demos/shamir_demo.js +121 -0
- package/demos/simple_demo.js +204 -0
- package/demos/simple_p2pkh_demo.js +169 -0
- package/demos/simple_utxo_preimage_demo.js +196 -0
- package/demos/smart_contract_demo.html +1347 -0
- package/demos/smart_contract_demo.js +910 -0
- package/demos/utxo_generator_demo.js +244 -0
- package/demos/validation_pipeline_demo.js +155 -0
- package/demos/web3keys.html +740 -0
- package/docs/BUNDLE_UPDATE_SUMMARY.md +40 -0
- package/docs/FIX_CREATEHMAC_ISSUE.md +91 -0
- package/docs/SMARTLEDGER_BSV_USAGE_ANSWERS.md +477 -0
- package/docs/SMARTLEDGER_BSV_USAGE_EXAMPLES.js +372 -0
- package/docs/SMARTLEDGER_BSV_USAGE_GUIDE.md +555 -0
- package/docs/SMART_CONTRACT_DEVELOPMENT_GUIDE.md +1459 -0
- package/examples/complete_workflow_demo.js +783 -0
- package/examples/definitive_working_demo.js +261 -0
- package/examples/final_working_contracts.js +338 -0
- package/examples/smart_contract_templates.js +718 -0
- package/examples/working_smart_contracts.js +348 -0
- package/lib/mnemonic/pbkdf2.browser.js +69 -0
- package/lib/mnemonic/pbkdf2.js +2 -68
- package/lib/mnemonic/pbkdf2.node.js +68 -0
- package/package.json +16 -5
- package/tests/browser-compatibility/README.md +35 -0
- package/tests/browser-compatibility/test-cdn-vs-local.html +186 -0
- package/tests/browser-compatibility/test-pbkdf2.html +51 -0
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Working Smart Contract Examples - Fixed Version
|
|
3
|
+
* ==============================================
|
|
4
|
+
*
|
|
5
|
+
* This file contains working, tested smart contract examples that properly
|
|
6
|
+
* integrate with smartledger-bsv's preimage validation system.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const bsv = require('../index.js')
|
|
10
|
+
|
|
11
|
+
// Enable colored output if available
|
|
12
|
+
let chalk
|
|
13
|
+
try {
|
|
14
|
+
chalk = require('chalk')
|
|
15
|
+
} catch (e) {
|
|
16
|
+
chalk = {
|
|
17
|
+
green: (text) => `✅ ${text}`,
|
|
18
|
+
red: (text) => `❌ ${text}`,
|
|
19
|
+
yellow: (text) => `⚠️ ${text}`,
|
|
20
|
+
blue: (text) => `ℹ️ ${text}`,
|
|
21
|
+
magenta: (text) => `🔮 ${text}`,
|
|
22
|
+
cyan: (text) => `🌊 ${text}`,
|
|
23
|
+
bold: (text) => `**${text}**`
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
console.log(chalk.bold.blue('\n🔧 Working Smart Contract Examples (Fixed)\n'))
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* WorkingAmountContract - A properly functioning amount validation contract
|
|
31
|
+
*/
|
|
32
|
+
class WorkingAmountContract {
|
|
33
|
+
constructor(expectedAmount) {
|
|
34
|
+
this.expectedAmount = expectedAmount
|
|
35
|
+
this.privateKey = new bsv.PrivateKey()
|
|
36
|
+
|
|
37
|
+
// Create the contract script using the quick covenant method
|
|
38
|
+
this.script = this._createWorkingScript()
|
|
39
|
+
this.address = bsv.SmartContract.utils.createCovenantAddress(this.script)
|
|
40
|
+
|
|
41
|
+
console.log(chalk.green(`✅ WorkingAmountContract created`))
|
|
42
|
+
console.log(chalk.blue(` Expected Amount: ${expectedAmount} satoshis`))
|
|
43
|
+
console.log(chalk.blue(` Contract Address: ${this.address.toString()}`))
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
_createWorkingScript() {
|
|
47
|
+
// Use the createQuickCovenant method which is known to work
|
|
48
|
+
const covenant = bsv.SmartContract.createQuickCovenant('value_lock', {
|
|
49
|
+
value: this.expectedAmount
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
// Convert the ASM to a proper BSV Script
|
|
53
|
+
return bsv.Script.fromASM(covenant.asm)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Test validation with a real preimage
|
|
57
|
+
validatePayment(preimageHex) {
|
|
58
|
+
try {
|
|
59
|
+
console.log(chalk.yellow('🔍 Testing payment validation with working script...'))
|
|
60
|
+
|
|
61
|
+
const result = bsv.SmartContract.testScript(
|
|
62
|
+
preimageHex,
|
|
63
|
+
this.script.toHex(),
|
|
64
|
+
{ verbose: true }
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
if (result.valid) {
|
|
68
|
+
console.log(chalk.green('✅ Payment validation PASSED'))
|
|
69
|
+
} else {
|
|
70
|
+
console.log(chalk.red('❌ Payment validation FAILED'))
|
|
71
|
+
console.log(chalk.red(` Error: ${result.error || 'Unknown error'}`))
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
success: result.valid,
|
|
76
|
+
error: result.error,
|
|
77
|
+
details: result
|
|
78
|
+
}
|
|
79
|
+
} catch (error) {
|
|
80
|
+
console.log(chalk.red('❌ Validation error:', error.message))
|
|
81
|
+
return {
|
|
82
|
+
success: false,
|
|
83
|
+
error: error.message
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Create a proper test preimage for this contract
|
|
89
|
+
createTestPreimage(inputAmount) {
|
|
90
|
+
try {
|
|
91
|
+
console.log(chalk.yellow('📝 Creating test preimage...'))
|
|
92
|
+
|
|
93
|
+
// Create a mock transaction that would spend from this contract
|
|
94
|
+
const mockTx = new bsv.Transaction()
|
|
95
|
+
|
|
96
|
+
// Add input from contract (mock)
|
|
97
|
+
mockTx.addInput({
|
|
98
|
+
prevTxId: 'a'.repeat(64),
|
|
99
|
+
outputIndex: 0,
|
|
100
|
+
script: this.script.toHex(),
|
|
101
|
+
sequenceNumber: 0xffffffff
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
// Add output with the input amount
|
|
105
|
+
mockTx.addOutput({
|
|
106
|
+
script: bsv.Script.buildPublicKeyHashOut(new bsv.Address('1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2')).toHex(),
|
|
107
|
+
satoshis: inputAmount
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
// Generate preimage
|
|
111
|
+
const preimage = bsv.Transaction.sighash.sighashPreimage(
|
|
112
|
+
mockTx,
|
|
113
|
+
bsv.crypto.Signature.SIGHASH_ALL | bsv.crypto.Signature.SIGHASH_FORKID,
|
|
114
|
+
0,
|
|
115
|
+
this.script,
|
|
116
|
+
new bsv.crypto.BN(inputAmount + 1000) // Contract input amount
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
console.log(chalk.blue(` Generated preimage: ${preimage.toString('hex').substring(0, 64)}...`))
|
|
120
|
+
return preimage.toString('hex')
|
|
121
|
+
|
|
122
|
+
} catch (error) {
|
|
123
|
+
console.log(chalk.red('❌ Preimage generation error:', error.message))
|
|
124
|
+
return null
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Complete test of the contract
|
|
129
|
+
runCompleteTest() {
|
|
130
|
+
console.log(chalk.cyan('\n🧪 Running Complete Contract Test'))
|
|
131
|
+
console.log(chalk.cyan('==================================='))
|
|
132
|
+
|
|
133
|
+
// Test with correct amount
|
|
134
|
+
console.log(chalk.yellow('\n1. Testing with CORRECT amount'))
|
|
135
|
+
const correctPreimage = this.createTestPreimage(this.expectedAmount)
|
|
136
|
+
if (correctPreimage) {
|
|
137
|
+
const correctResult = this.validatePayment(correctPreimage)
|
|
138
|
+
console.log(chalk.blue(` Result: ${correctResult.success ? 'PASS' : 'FAIL'}`))
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Test with incorrect amount
|
|
142
|
+
console.log(chalk.yellow('\n2. Testing with INCORRECT amount'))
|
|
143
|
+
const incorrectPreimage = this.createTestPreimage(this.expectedAmount - 10000)
|
|
144
|
+
if (incorrectPreimage) {
|
|
145
|
+
const incorrectResult = this.validatePayment(incorrectPreimage)
|
|
146
|
+
console.log(chalk.blue(` Result: ${incorrectResult.success ? 'UNEXPECTED PASS' : 'EXPECTED FAIL'}`))
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
console.log(chalk.cyan('\n✅ Complete test finished'))
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
getContractInfo() {
|
|
153
|
+
return {
|
|
154
|
+
expectedAmount: this.expectedAmount,
|
|
155
|
+
address: this.address.toString(),
|
|
156
|
+
script: {
|
|
157
|
+
hex: this.script.toHex(),
|
|
158
|
+
asm: this.script.toASM(),
|
|
159
|
+
size: this.script.toBuffer().length
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* SimpleFieldExtractionDemo - Shows how field extraction actually works
|
|
167
|
+
*/
|
|
168
|
+
class SimpleFieldExtractionDemo {
|
|
169
|
+
constructor() {
|
|
170
|
+
console.log(chalk.bold.magenta('\n🔬 Field Extraction Demo\n'))
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
demonstrateFieldExtraction() {
|
|
174
|
+
console.log(chalk.cyan('Testing Field Extraction with Real Preimage'))
|
|
175
|
+
console.log(chalk.cyan('===========================================\n'))
|
|
176
|
+
|
|
177
|
+
// Create a simple transaction to get a real preimage
|
|
178
|
+
try {
|
|
179
|
+
const tx = new bsv.Transaction()
|
|
180
|
+
.from({
|
|
181
|
+
txId: 'a'.repeat(64),
|
|
182
|
+
outputIndex: 0,
|
|
183
|
+
script: bsv.Script.buildPublicKeyHashOut(new bsv.Address('1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2')).toHex(),
|
|
184
|
+
satoshis: 100000
|
|
185
|
+
})
|
|
186
|
+
.to('1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2', 90000)
|
|
187
|
+
|
|
188
|
+
const preimage = bsv.Transaction.sighash.sighashPreimage(
|
|
189
|
+
tx,
|
|
190
|
+
bsv.crypto.Signature.SIGHASH_ALL | bsv.crypto.Signature.SIGHASH_FORKID,
|
|
191
|
+
0,
|
|
192
|
+
bsv.Script.buildPublicKeyHashOut(new bsv.Address('1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2')),
|
|
193
|
+
new bsv.crypto.BN(100000)
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
console.log(chalk.blue(`Generated preimage: ${preimage.toString('hex').substring(0, 64)}...`))
|
|
197
|
+
|
|
198
|
+
// Test field extraction
|
|
199
|
+
const fields = ['value', 'nVersion', 'nLocktime', 'hashOutputs']
|
|
200
|
+
|
|
201
|
+
fields.forEach(field => {
|
|
202
|
+
console.log(chalk.yellow(`\nTesting ${field} extraction:`))
|
|
203
|
+
|
|
204
|
+
try {
|
|
205
|
+
const result = bsv.SmartContract.testFieldExtraction(
|
|
206
|
+
preimage.toString('hex'),
|
|
207
|
+
field
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
if (result.success) {
|
|
211
|
+
console.log(chalk.green(`✅ ${field} extraction successful`))
|
|
212
|
+
if (result.fieldExtraction) {
|
|
213
|
+
console.log(chalk.blue(` Value: ${result.fieldExtraction.value}`))
|
|
214
|
+
if (result.fieldExtraction.interpretation) {
|
|
215
|
+
console.log(chalk.blue(` Interpreted: ${result.fieldExtraction.interpretation.description || result.fieldExtraction.interpretation.satoshis || 'N/A'}`))
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
} else {
|
|
219
|
+
console.log(chalk.red(`❌ ${field} extraction failed`))
|
|
220
|
+
console.log(chalk.red(` Error: ${result.error || 'Unknown error'}`))
|
|
221
|
+
}
|
|
222
|
+
} catch (error) {
|
|
223
|
+
console.log(chalk.red(`❌ ${field} extraction error: ${error.message}`))
|
|
224
|
+
}
|
|
225
|
+
})
|
|
226
|
+
|
|
227
|
+
} catch (error) {
|
|
228
|
+
console.log(chalk.red('❌ Demo error:', error.message))
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* CovenantBuilderTest - Test the covenant builder functionality
|
|
235
|
+
*/
|
|
236
|
+
class CovenantBuilderTest {
|
|
237
|
+
constructor() {
|
|
238
|
+
console.log(chalk.bold.magenta('\n🏗️ Covenant Builder Test\n'))
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
testCovenantBuilder() {
|
|
242
|
+
console.log(chalk.cyan('Testing CovenantBuilder Functionality'))
|
|
243
|
+
console.log(chalk.cyan('===================================\n'))
|
|
244
|
+
|
|
245
|
+
try {
|
|
246
|
+
// Test 1: Simple covenant using CovenantTemplates
|
|
247
|
+
console.log(chalk.yellow('1. Testing CovenantTemplates.valueLock'))
|
|
248
|
+
|
|
249
|
+
const valueLockCovenant = bsv.SmartContract.CovenantTemplates.valueLock('50c3000000000000') // 50000 satoshis in little-endian hex
|
|
250
|
+
const builtCovenant = valueLockCovenant.build()
|
|
251
|
+
|
|
252
|
+
console.log(chalk.blue(` ASM: ${builtCovenant.cleanedASM}`))
|
|
253
|
+
console.log(chalk.blue(` Hex: ${builtCovenant.hex}`))
|
|
254
|
+
console.log(chalk.blue(` Size: ${builtCovenant.size} operations`))
|
|
255
|
+
|
|
256
|
+
// Test 2: Custom covenant using CovenantBuilder
|
|
257
|
+
console.log(chalk.yellow('\n2. Testing Custom CovenantBuilder'))
|
|
258
|
+
|
|
259
|
+
const customBuilder = new bsv.SmartContract.CovenantBuilder()
|
|
260
|
+
const customCovenant = customBuilder
|
|
261
|
+
.comment('Simple value validation')
|
|
262
|
+
.extractField('value')
|
|
263
|
+
.push(100000)
|
|
264
|
+
.greaterThanOrEqual()
|
|
265
|
+
.verify()
|
|
266
|
+
.build()
|
|
267
|
+
|
|
268
|
+
console.log(chalk.blue(` Custom ASM: ${customCovenant.cleanedASM}`))
|
|
269
|
+
console.log(chalk.blue(` Custom Hex: ${customCovenant.hex}`))
|
|
270
|
+
|
|
271
|
+
// Test 3: Quick covenant creation
|
|
272
|
+
console.log(chalk.yellow('\n3. Testing Quick Covenant Creation'))
|
|
273
|
+
|
|
274
|
+
const quickCovenant = bsv.SmartContract.createQuickCovenant('value_lock', {
|
|
275
|
+
value: 75000
|
|
276
|
+
})
|
|
277
|
+
|
|
278
|
+
console.log(chalk.blue(` Quick ASM: ${quickCovenant.asm}`))
|
|
279
|
+
console.log(chalk.blue(` Quick Hex: ${quickCovenant.hex}`))
|
|
280
|
+
|
|
281
|
+
console.log(chalk.green('\n✅ All covenant builder tests completed'))
|
|
282
|
+
|
|
283
|
+
} catch (error) {
|
|
284
|
+
console.log(chalk.red('❌ Covenant builder test error:', error.message))
|
|
285
|
+
console.error(error.stack)
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Main execution function
|
|
292
|
+
*/
|
|
293
|
+
async function main() {
|
|
294
|
+
try {
|
|
295
|
+
console.log(chalk.bold.blue('Working Smart Contract Examples'))
|
|
296
|
+
console.log(chalk.blue('===============================\n'))
|
|
297
|
+
|
|
298
|
+
// 1. Test field extraction first
|
|
299
|
+
const fieldDemo = new SimpleFieldExtractionDemo()
|
|
300
|
+
fieldDemo.demonstrateFieldExtraction()
|
|
301
|
+
|
|
302
|
+
// 2. Test covenant builder
|
|
303
|
+
const builderTest = new CovenantBuilderTest()
|
|
304
|
+
builderTest.testCovenantBuilder()
|
|
305
|
+
|
|
306
|
+
// 3. Test working contract
|
|
307
|
+
console.log(chalk.bold.magenta('\n💰 Working Amount Contract Test\n'))
|
|
308
|
+
|
|
309
|
+
const workingContract = new WorkingAmountContract(100000) // 100k sats
|
|
310
|
+
workingContract.runCompleteTest()
|
|
311
|
+
|
|
312
|
+
// 4. Show contract info
|
|
313
|
+
console.log(chalk.bold.yellow('\n📋 Contract Information'))
|
|
314
|
+
console.log(chalk.yellow('======================='))
|
|
315
|
+
|
|
316
|
+
const info = workingContract.getContractInfo()
|
|
317
|
+
console.log(chalk.blue(`Expected Amount: ${info.expectedAmount} satoshis`))
|
|
318
|
+
console.log(chalk.blue(`Contract Address: ${info.address}`))
|
|
319
|
+
console.log(chalk.blue(`Script Size: ${info.script.size} bytes`))
|
|
320
|
+
console.log(chalk.blue(`Script ASM: ${info.script.asm}`))
|
|
321
|
+
|
|
322
|
+
console.log(chalk.bold.green('\n🎉 All working examples completed successfully!'))
|
|
323
|
+
|
|
324
|
+
// Usage instructions
|
|
325
|
+
console.log(chalk.bold.yellow('\n📚 Key Learnings:'))
|
|
326
|
+
console.log(chalk.yellow('1. Use bsv.SmartContract.createQuickCovenant() for simple contracts'))
|
|
327
|
+
console.log(chalk.yellow('2. Field extraction works with proper preimage format'))
|
|
328
|
+
console.log(chalk.yellow('3. CovenantBuilder.build() returns an object, not a Script'))
|
|
329
|
+
console.log(chalk.yellow('4. Convert covenant ASM to Script using bsv.Script.fromASM()'))
|
|
330
|
+
console.log(chalk.yellow('5. Test with real preimages for accurate validation'))
|
|
331
|
+
|
|
332
|
+
} catch (error) {
|
|
333
|
+
console.error(chalk.bold.red('\nDemo Error:'), error.message)
|
|
334
|
+
console.error(chalk.red('Stack:'), error.stack)
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// Export for use in other modules
|
|
339
|
+
module.exports = {
|
|
340
|
+
WorkingAmountContract,
|
|
341
|
+
SimpleFieldExtractionDemo,
|
|
342
|
+
CovenantBuilderTest
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// Run demo if executed directly
|
|
346
|
+
if (require.main === module) {
|
|
347
|
+
main().catch(console.error)
|
|
348
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Browser-compatible PBKDF2 implementation using BSV crypto
|
|
5
|
+
* Credit to: https://github.com/stayradiated/pbkdf2-sha512
|
|
6
|
+
* Copyright (c) 2014, JP Richardson Copyright (c) 2010-2011 Intalio Pte, All Rights Reserved
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// Import BSV crypto instead of Node.js crypto
|
|
10
|
+
var Hash = require('../crypto/hash')
|
|
11
|
+
|
|
12
|
+
function pbkdf2 (key, salt, iterations, dkLen) {
|
|
13
|
+
var hLen = 64 // SHA512 Mac length
|
|
14
|
+
if (dkLen > (Math.pow(2, 32) - 1) * hLen) {
|
|
15
|
+
throw Error('Requested key length too long')
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (typeof key !== 'string' && !Buffer.isBuffer(key)) {
|
|
19
|
+
throw new TypeError('key must a string or Buffer')
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (typeof salt !== 'string' && !Buffer.isBuffer(salt)) {
|
|
23
|
+
throw new TypeError('salt must a string or Buffer')
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (typeof key === 'string') {
|
|
27
|
+
key = Buffer.from(key)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (typeof salt === 'string') {
|
|
31
|
+
salt = Buffer.from(salt)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
var DK = Buffer.alloc(dkLen)
|
|
35
|
+
var U = Buffer.alloc(hLen)
|
|
36
|
+
var T = Buffer.alloc(hLen)
|
|
37
|
+
var block1 = Buffer.alloc(salt.length + 4)
|
|
38
|
+
|
|
39
|
+
var l = Math.ceil(dkLen / hLen)
|
|
40
|
+
var r = dkLen - (l - 1) * hLen
|
|
41
|
+
|
|
42
|
+
salt.copy(block1, 0, 0, salt.length)
|
|
43
|
+
for (var i = 1; i <= l; i++) {
|
|
44
|
+
block1[salt.length + 0] = (i >> 24 & 0xff)
|
|
45
|
+
block1[salt.length + 1] = (i >> 16 & 0xff)
|
|
46
|
+
block1[salt.length + 2] = (i >> 8 & 0xff)
|
|
47
|
+
block1[salt.length + 3] = (i >> 0 & 0xff)
|
|
48
|
+
|
|
49
|
+
// Use BSV's browser-compatible HMAC instead of Node.js crypto
|
|
50
|
+
U = Hash.sha512hmac(block1, key)
|
|
51
|
+
U.copy(T, 0, 0, hLen)
|
|
52
|
+
|
|
53
|
+
for (var j = 1; j < iterations; j++) {
|
|
54
|
+
U = Hash.sha512hmac(U, key)
|
|
55
|
+
|
|
56
|
+
for (var k = 0; k < hLen; k++) {
|
|
57
|
+
T[k] ^= U[k]
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
var destPos = (i - 1) * hLen
|
|
62
|
+
var len = (i === l ? r : hLen)
|
|
63
|
+
T.copy(DK, destPos, 0, len)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return DK
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
module.exports = pbkdf2
|
package/lib/mnemonic/pbkdf2.js
CHANGED
|
@@ -1,68 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
var crypto = require('crypto')
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* PDKBF2
|
|
7
|
-
* Credit to: https://github.com/stayradiated/pbkdf2-sha512
|
|
8
|
-
* Copyright (c) 2014, JP Richardson Copyright (c) 2010-2011 Intalio Pte, All Rights Reserved
|
|
9
|
-
*/
|
|
10
|
-
function pbkdf2 (key, salt, iterations, dkLen) {
|
|
11
|
-
var hLen = 64 // SHA512 Mac length
|
|
12
|
-
if (dkLen > (Math.pow(2, 32) - 1) * hLen) {
|
|
13
|
-
throw Error('Requested key length too long')
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
if (typeof key !== 'string' && !Buffer.isBuffer(key)) {
|
|
17
|
-
throw new TypeError('key must a string or Buffer')
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
if (typeof salt !== 'string' && !Buffer.isBuffer(salt)) {
|
|
21
|
-
throw new TypeError('salt must a string or Buffer')
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
if (typeof key === 'string') {
|
|
25
|
-
key = Buffer.from(key)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (typeof salt === 'string') {
|
|
29
|
-
salt = Buffer.from(salt)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
var DK = Buffer.alloc(dkLen)
|
|
33
|
-
|
|
34
|
-
var U = Buffer.alloc(hLen)
|
|
35
|
-
var T = Buffer.alloc(hLen)
|
|
36
|
-
var block1 = Buffer.alloc(salt.length + 4)
|
|
37
|
-
|
|
38
|
-
var l = Math.ceil(dkLen / hLen)
|
|
39
|
-
var r = dkLen - (l - 1) * hLen
|
|
40
|
-
|
|
41
|
-
salt.copy(block1, 0, 0, salt.length)
|
|
42
|
-
for (var i = 1; i <= l; i++) {
|
|
43
|
-
block1[salt.length + 0] = (i >> 24 & 0xff)
|
|
44
|
-
block1[salt.length + 1] = (i >> 16 & 0xff)
|
|
45
|
-
block1[salt.length + 2] = (i >> 8 & 0xff)
|
|
46
|
-
block1[salt.length + 3] = (i >> 0 & 0xff)
|
|
47
|
-
|
|
48
|
-
U = crypto.createHmac('sha512', key).update(block1).digest()
|
|
49
|
-
|
|
50
|
-
U.copy(T, 0, 0, hLen)
|
|
51
|
-
|
|
52
|
-
for (var j = 1; j < iterations; j++) {
|
|
53
|
-
U = crypto.createHmac('sha512', key).update(U).digest()
|
|
54
|
-
|
|
55
|
-
for (var k = 0; k < hLen; k++) {
|
|
56
|
-
T[k] ^= U[k]
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
var destPos = (i - 1) * hLen
|
|
61
|
-
var len = (i === l ? r : hLen)
|
|
62
|
-
T.copy(DK, destPos, 0, len)
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return DK
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
module.exports = pbkdf2
|
|
1
|
+
if (process.browser) module.exports = require('./pbkdf2.browser')
|
|
2
|
+
else module.exports = require('./pbkdf2.node')
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
var crypto = require('crypto')
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* PDKBF2
|
|
7
|
+
* Credit to: https://github.com/stayradiated/pbkdf2-sha512
|
|
8
|
+
* Copyright (c) 2014, JP Richardson Copyright (c) 2010-2011 Intalio Pte, All Rights Reserved
|
|
9
|
+
*/
|
|
10
|
+
function pbkdf2 (key, salt, iterations, dkLen) {
|
|
11
|
+
var hLen = 64 // SHA512 Mac length
|
|
12
|
+
if (dkLen > (Math.pow(2, 32) - 1) * hLen) {
|
|
13
|
+
throw Error('Requested key length too long')
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (typeof key !== 'string' && !Buffer.isBuffer(key)) {
|
|
17
|
+
throw new TypeError('key must a string or Buffer')
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (typeof salt !== 'string' && !Buffer.isBuffer(salt)) {
|
|
21
|
+
throw new TypeError('salt must a string or Buffer')
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (typeof key === 'string') {
|
|
25
|
+
key = Buffer.from(key)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (typeof salt === 'string') {
|
|
29
|
+
salt = Buffer.from(salt)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
var DK = Buffer.alloc(dkLen)
|
|
33
|
+
|
|
34
|
+
var U = Buffer.alloc(hLen)
|
|
35
|
+
var T = Buffer.alloc(hLen)
|
|
36
|
+
var block1 = Buffer.alloc(salt.length + 4)
|
|
37
|
+
|
|
38
|
+
var l = Math.ceil(dkLen / hLen)
|
|
39
|
+
var r = dkLen - (l - 1) * hLen
|
|
40
|
+
|
|
41
|
+
salt.copy(block1, 0, 0, salt.length)
|
|
42
|
+
for (var i = 1; i <= l; i++) {
|
|
43
|
+
block1[salt.length + 0] = (i >> 24 & 0xff)
|
|
44
|
+
block1[salt.length + 1] = (i >> 16 & 0xff)
|
|
45
|
+
block1[salt.length + 2] = (i >> 8 & 0xff)
|
|
46
|
+
block1[salt.length + 3] = (i >> 0 & 0xff)
|
|
47
|
+
|
|
48
|
+
U = crypto.createHmac('sha512', key).update(block1).digest()
|
|
49
|
+
|
|
50
|
+
U.copy(T, 0, 0, hLen)
|
|
51
|
+
|
|
52
|
+
for (var j = 1; j < iterations; j++) {
|
|
53
|
+
U = crypto.createHmac('sha512', key).update(U).digest()
|
|
54
|
+
|
|
55
|
+
for (var k = 0; k < hLen; k++) {
|
|
56
|
+
T[k] ^= U[k]
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
var destPos = (i - 1) * hLen
|
|
61
|
+
var len = (i === l ? r : hLen)
|
|
62
|
+
T.copy(DK, destPos, 0, len)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return DK
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
module.exports = pbkdf2
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smartledger/bsv",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.4",
|
|
4
4
|
"description": "🚀 Complete Bitcoin SV development framework with Legal Token Protocol (LTP), Global Digital Attestation Framework (GDAF), Shamir Secret Sharing, and 12 flexible loading options. Includes primitives-only architecture for maximum integration flexibility, SmartContract framework, covenant builder, and comprehensive Bitcoin SV API. Perfect for legal tokens, DeFi, smart contracts, and secure Bitcoin applications.",
|
|
5
5
|
"author": "SmartLedger Technology <hello@smartledger.technology> (https://smartledger.technology)",
|
|
6
6
|
"homepage": "https://github.com/codenlighten/smartledger-bsv#readme",
|
|
@@ -21,6 +21,20 @@
|
|
|
21
21
|
"test:basic": "node examples/basic/transaction-creation.js",
|
|
22
22
|
"test:all": "npm test && npm run test:covenants && npm run test:scripts",
|
|
23
23
|
"coverage": "nyc --reporter=text npm run test",
|
|
24
|
+
"demo": "node demos/smart_contract_demo.js",
|
|
25
|
+
"demo:web": "echo '🌐 Open demos/smart_contract_demo.html in your browser'",
|
|
26
|
+
"demo:basics": "node demos/smart_contract_demo.js --feature basics",
|
|
27
|
+
"demo:covenant": "node demos/smart_contract_demo.js --feature covenant",
|
|
28
|
+
"demo:preimage": "node demos/smart_contract_demo.js --feature preimage",
|
|
29
|
+
"demo:utxo": "node demos/smart_contract_demo.js --feature utxo",
|
|
30
|
+
"demo:scripts": "node demos/smart_contract_demo.js --feature scripts",
|
|
31
|
+
"demo:legacy": "npm run test:covenants",
|
|
32
|
+
"demo:legacy:basic": "npm run test:basic",
|
|
33
|
+
"demo:legacy:scripts": "npm run test:scripts",
|
|
34
|
+
"demo:legacy:preimage": "echo '🧠 BIP-143 Preimage Extractor Demo' && node examples/preimage/extract_preimage_bidirectional.js",
|
|
35
|
+
"smart-contracts": "node examples/smart_contract_templates.js",
|
|
36
|
+
"smart-contracts:working": "node examples/final_working_contracts.js",
|
|
37
|
+
"workflow": "node examples/complete_workflow_demo.js",
|
|
24
38
|
"build-bsv": "NODE_OPTIONS=\"--openssl-legacy-provider\" webpack index.js --config build/webpack.config.js",
|
|
25
39
|
"build-ecies": "NODE_OPTIONS=\"--openssl-legacy-provider\" webpack ecies/index.js --config build/webpack.subproject.config.js --output-library bsvEcies -o bsv-ecies.min.js",
|
|
26
40
|
"build-message": "NODE_OPTIONS=\"--openssl-legacy-provider\" webpack message/index.js --config build/webpack.subproject.config.js --output-library bsvMessage -o bsv-message.min.js",
|
|
@@ -39,10 +53,6 @@
|
|
|
39
53
|
"build-all": "npm run build && npm run build-bundle && npm run build-specialized && npm run build-advanced",
|
|
40
54
|
"test:browser": "echo 'Open tests/standalone-modules-test.html in browser for comprehensive testing'",
|
|
41
55
|
"test:bundle": "echo 'Open tests/bundle-completeness-test.html in browser to verify bundle completeness'",
|
|
42
|
-
"demo": "npm run test:covenants",
|
|
43
|
-
"demo:basic": "npm run test:basic",
|
|
44
|
-
"demo:scripts": "npm run test:scripts",
|
|
45
|
-
"demo:preimage": "echo '🧠 BIP-143 Preimage Extractor Demo' && node examples/preimage/extract_preimage_bidirectional.js",
|
|
46
56
|
"preimage:extract": "node examples/preimage/extract_preimage_bidirectional.js",
|
|
47
57
|
"prepublishOnly": "NODE_OPTIONS=\"--openssl-legacy-provider\" npm run build"
|
|
48
58
|
},
|
|
@@ -80,6 +90,7 @@
|
|
|
80
90
|
"architecture_demo.js",
|
|
81
91
|
"test_standalone_shamir.html",
|
|
82
92
|
"docs/",
|
|
93
|
+
"demos/",
|
|
83
94
|
"examples/",
|
|
84
95
|
"LICENSE",
|
|
85
96
|
"README.md",
|
|
@@ -0,0 +1,35 @@
|
|
|
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.
|