@smartledger/bsv 3.4.3 → 3.4.5

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 (89) hide show
  1. package/CHANGELOG.md +367 -0
  2. package/README.md +72 -72
  3. package/SECURITY.md +88 -0
  4. package/bin/cli.js +13 -8
  5. package/bsv-covenant.min.js +4 -4
  6. package/bsv-gdaf.min.js +5 -5
  7. package/bsv-ltp.min.js +7 -7
  8. package/bsv-smartcontract.min.js +5 -5
  9. package/bsv.bundle.js +5 -5
  10. package/bsv.d.ts +486 -9
  11. package/bsv.min.js +5 -5
  12. package/docs/COVENANT_DEVELOPMENT_RESOLVED.md +2 -2
  13. package/docs/MODULE_REFERENCE_COMPLETE.md +60 -57
  14. package/docs/advanced/UTXO_MANAGER_GUIDE.md +1 -1
  15. package/docs/getting-started/INSTALLATION.md +30 -30
  16. package/docs/getting-started/QUICK_START.md +14 -14
  17. package/docs/migration/FROM_BSV_1_5_6.md +5 -5
  18. package/gdaf-entry.js +1 -2
  19. package/index.js +20 -7
  20. package/lib/script/script.js +19 -0
  21. package/lib/smart_contract/covenant.js +10 -1
  22. package/lib/smartutxo.js +20 -12
  23. package/lib/transaction/input/publickeyhash.js +6 -1
  24. package/lib/transaction/transaction.js +12 -1
  25. package/ltp-entry.js +1 -2
  26. package/package.json +3 -3
  27. package/utilities/blockchain-state.js +32 -23
  28. package/demos/README.md +0 -188
  29. package/demos/architecture_demo.js +0 -247
  30. package/demos/browser-test.html +0 -1208
  31. package/demos/bsv_wallet_demo.js +0 -242
  32. package/demos/complete_ltp_demo.js +0 -511
  33. package/demos/debug_tools_demo.js +0 -87
  34. package/demos/demo_features.js +0 -123
  35. package/demos/easy_interface_demo.js +0 -109
  36. package/demos/ecies_demo.js +0 -182
  37. package/demos/gdaf_demo.js +0 -237
  38. package/demos/ltp_demo.js +0 -361
  39. package/demos/ltp_primitives_demo.js +0 -403
  40. package/demos/message_demo.js +0 -209
  41. package/demos/preimage_separation_demo.js +0 -383
  42. package/demos/script_helper_demo.js +0 -289
  43. package/demos/security_demo.js +0 -287
  44. package/demos/shamir_demo.js +0 -121
  45. package/demos/simple_demo.js +0 -204
  46. package/demos/simple_p2pkh_demo.js +0 -169
  47. package/demos/simple_utxo_preimage_demo.js +0 -196
  48. package/demos/smart_contract_demo.html +0 -1347
  49. package/demos/smart_contract_demo.js +0 -910
  50. package/demos/utxo_generator_demo.js +0 -244
  51. package/demos/validation_pipeline_demo.js +0 -155
  52. package/demos/web3keys.html +0 -740
  53. package/examples/README.md +0 -200
  54. package/examples/basic/transaction-creation.js +0 -534
  55. package/examples/basic/transaction_signature_api_gap.js +0 -178
  56. package/examples/complete_workflow_demo.js +0 -783
  57. package/examples/covenants/advanced_covenant_demo.js +0 -219
  58. package/examples/covenants/covenant_interface_demo.js +0 -270
  59. package/examples/covenants/covenant_manual_signature_resolved.js +0 -212
  60. package/examples/covenants/covenant_signature_template.js +0 -117
  61. package/examples/covenants2/covenant_bidirectional_example.js +0 -262
  62. package/examples/covenants2/covenant_utils_demo.js +0 -120
  63. package/examples/covenants2/preimage_covenant_utils.js +0 -287
  64. package/examples/covenants2/production_integration.js +0 -256
  65. package/examples/data/covenant_utxos.json +0 -28
  66. package/examples/data/utxos.json +0 -26
  67. package/examples/definitive_working_demo.js +0 -261
  68. package/examples/final_working_contracts.js +0 -338
  69. package/examples/legacy/README.md +0 -11
  70. package/examples/legacy/smart_contract_test_integration.js +0 -269
  71. package/examples/legacy/test_builtin_verify.js +0 -117
  72. package/examples/legacy/test_debug_integration.js +0 -71
  73. package/examples/legacy/test_ecdsa_little.js +0 -70
  74. package/examples/legacy/test_shamir.js +0 -221
  75. package/examples/legacy/test_smartverify_der.js +0 -110
  76. package/examples/preimage/README.md +0 -178
  77. package/examples/preimage/extract_preimage_bidirectional.js +0 -421
  78. package/examples/preimage/generate_sample_preimage.js +0 -208
  79. package/examples/preimage/generate_sighash_examples.js +0 -152
  80. package/examples/preimage/parse_preimage.js +0 -117
  81. package/examples/preimage/test_preimage_extractor.js +0 -53
  82. package/examples/preimage/test_varint_extraction.js +0 -95
  83. package/examples/scripts/custom_script_helper_example.js +0 -273
  84. package/examples/scripts/script_interpreter.js +0 -193
  85. package/examples/smart_contract/complete_workflow_demo.js +0 -343
  86. package/examples/smart_contract/covenant_builder_demo.js +0 -176
  87. package/examples/smart_contract/script_testing_integration.js +0 -198
  88. package/examples/smart_contract_templates.js +0 -718
  89. package/examples/working_smart_contracts.js +0 -348
@@ -1,152 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * generate_sighash_examples.js
4
- * Generate preimages demonstrating SIGHASH flag behavior that causes "zero hashes"
5
- * This explains the "extra zeros" that confuse developers in multi-input scenarios
6
- */
7
-
8
- const { Buffer } = require("buffer");
9
-
10
- function createSighashPreimage(sighashType = 'ALL_FORKID') {
11
- // SIGHASH type mappings
12
- const sighashTypes = {
13
- 'ALL': 0x01,
14
- 'ALL_FORKID': 0x41,
15
- 'NONE_FORKID': 0x42,
16
- 'SINGLE_FORKID': 0x43,
17
- 'ALL_ANYONECANPAY_FORKID': 0xc1,
18
- 'NONE_ANYONECANPAY_FORKID': 0xc2,
19
- 'SINGLE_ANYONECANPAY_FORKID': 0xc3
20
- };
21
-
22
- const sigType = sighashTypes[sighashType];
23
- if (!sigType) {
24
- throw new Error(`Unknown sighash type: ${sighashType}`);
25
- }
26
-
27
- // Base preimage components
28
- const nVersion = Buffer.from([0x01, 0x00, 0x00, 0x00]);
29
- const outpoint_txid = Buffer.alloc(32, 0xaa);
30
- const outpoint_vout = Buffer.from([0x00, 0x00, 0x00, 0x00]);
31
- const scriptCode = Buffer.from([
32
- 0x76, 0xa9, 0x14, // OP_DUP OP_HASH160 OP_PUSHDATA(20)
33
- ...Buffer.alloc(20, 0x88), // 20-byte pubkey hash
34
- 0x88, 0xac // OP_EQUALVERIFY OP_CHECKSIG
35
- ]);
36
- const scriptLen = Buffer.from([scriptCode.length]);
37
- const value = Buffer.from([0x00, 0xe1, 0xf5, 0x05, 0x00, 0x00, 0x00, 0x00]);
38
- const nSequence = Buffer.from([0xff, 0xff, 0xff, 0xff]);
39
- const nLocktime = Buffer.from([0x00, 0x00, 0x00, 0x00]);
40
- const sighashTypeBuffer = Buffer.from([sigType, 0x00, 0x00, 0x00]);
41
-
42
- // Apply SIGHASH rules for hash fields
43
- let hashPrevouts, hashSequence, hashOutputs;
44
-
45
- if (sigType & 0x80) { // ANYONECANPAY flag
46
- hashPrevouts = Buffer.alloc(32, 0x00); // Zero hash
47
- hashSequence = Buffer.alloc(32, 0x00); // Zero hash
48
- } else {
49
- hashPrevouts = Buffer.alloc(32, 0xab); // Normal hash
50
- hashSequence = Buffer.alloc(32, 0xcd); // Normal hash
51
- }
52
-
53
- if ((sigType & 0x1f) === 0x02) { // SIGHASH_NONE
54
- hashOutputs = Buffer.alloc(32, 0x00); // Zero hash
55
- } else if ((sigType & 0x1f) === 0x03) { // SIGHASH_SINGLE
56
- hashOutputs = Buffer.alloc(32, 0x00); // Zero hash (simplified)
57
- } else {
58
- hashOutputs = Buffer.alloc(32, 0xef); // Normal hash
59
- }
60
-
61
- // Construct preimage
62
- const preimage = Buffer.concat([
63
- nVersion,
64
- hashPrevouts,
65
- hashSequence,
66
- outpoint_txid,
67
- outpoint_vout,
68
- scriptLen,
69
- scriptCode,
70
- value,
71
- nSequence,
72
- hashOutputs,
73
- nLocktime,
74
- sighashTypeBuffer
75
- ]);
76
-
77
- return {
78
- hex: preimage.toString('hex'),
79
- analysis: {
80
- sighashType: sighashType,
81
- sighashValue: `0x${sigType.toString(16).padStart(2, '0')}`,
82
- hashPrevouts: hashPrevouts.equals(Buffer.alloc(32, 0x00)) ? 'ZERO (ANYONECANPAY)' : 'NORMAL',
83
- hashSequence: hashSequence.equals(Buffer.alloc(32, 0x00)) ? 'ZERO (ANYONECANPAY)' : 'NORMAL',
84
- hashOutputs: hashOutputs.equals(Buffer.alloc(32, 0x00)) ? 'ZERO (NONE/SINGLE)' : 'NORMAL'
85
- }
86
- };
87
- }
88
-
89
- // CLI Interface
90
- if (require.main === module) {
91
- const sighashType = process.argv[2] || 'ALL_FORKID';
92
-
93
- if (sighashType === '--help' || sighashType === '-h') {
94
- console.log("🔏 SIGHASH Flag Preimage Generator");
95
- console.log("=================================");
96
- console.log("Demonstrates how SIGHASH flags create 'zero hashes' in BIP-143 preimages");
97
- console.log("");
98
- console.log("Usage: node generate_sighash_examples.js [sighash_type]");
99
- console.log("");
100
- console.log("Available SIGHASH types:");
101
- console.log(" ALL_FORKID - Standard: all inputs/outputs (0x41) - DEFAULT");
102
- console.log(" NONE_FORKID - Zero hashOutputs (0x42)");
103
- console.log(" SINGLE_FORKID - Zero hashOutputs for single mode (0x43)");
104
- console.log(" ALL_ANYONECANPAY_FORKID - Zero hashPrevouts + hashSequence (0xC1)");
105
- console.log(" NONE_ANYONECANPAY_FORKID - Zero all hash fields (0xC2)");
106
- console.log("");
107
- console.log("Examples:");
108
- console.log(" node generate_sighash_examples.js ALL_FORKID");
109
- console.log(" node generate_sighash_examples.js ALL_ANYONECANPAY_FORKID");
110
- console.log(" node generate_sighash_examples.js NONE_FORKID");
111
- process.exit(0);
112
- }
113
-
114
- try {
115
- console.log("🔏 SIGHASH Flag Preimage Analysis");
116
- console.log("=================================");
117
- console.log(`📋 SIGHASH Type: ${sighashType}`);
118
-
119
- const result = createSighashPreimage(sighashType);
120
-
121
- console.log(`📊 Generated: ${result.hex.length / 2} bytes`);
122
- console.log(`🔍 SIGHASH Value: ${result.analysis.sighashValue}`);
123
- console.log("");
124
- console.log("🧬 Hash Field Analysis:");
125
- console.log(` hashPrevouts: ${result.analysis.hashPrevouts}`);
126
- console.log(` hashSequence: ${result.analysis.hashSequence}`);
127
- console.log(` hashOutputs: ${result.analysis.hashOutputs}`);
128
- console.log("");
129
-
130
- if (result.analysis.hashPrevouts === 'ZERO' ||
131
- result.analysis.hashSequence === 'ZERO' ||
132
- result.analysis.hashOutputs === 'ZERO') {
133
- console.log("⚠️ ZERO HASH DETECTED!");
134
- console.log(" This explains 'extra zeros' developers see in multi-input preimages.");
135
- console.log(" These are NOT bugs - they're required by BIP-143 SIGHASH rules.");
136
- }
137
-
138
- console.log(`📦 Preimage: ${result.hex}`);
139
- console.log("");
140
- console.log("🧪 Test Commands:");
141
- console.log(` node extract_preimage_bidirectional.js ${result.hex} hashPrevouts`);
142
- console.log(` node extract_preimage_bidirectional.js ${result.hex} hashOutputs`);
143
- console.log(` node extract_preimage_bidirectional.js ${result.hex} sighashType`);
144
-
145
- } catch (error) {
146
- console.error("❌ Error:", error.message);
147
- console.log("💡 Use --help to see available SIGHASH types");
148
- process.exit(1);
149
- }
150
- }
151
-
152
- module.exports = { createSighashPreimage };
@@ -1,117 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * parse_preimage.js
4
- *
5
- * Extracts all parts of a Bitcoin (BSV/BTC-style) preimage from a raw hex string.
6
- * Works for preimages that follow the standard structure:
7
- *
8
- * 1. nVersion (4 bytes)
9
- * 2. hashPrevouts (32 bytes)
10
- * 3. hashSequence (32 bytes)
11
- * 4. outpoint (32 bytes + 4 bytes)
12
- * 5. scriptCode (variable length)
13
- * 6. value (8 bytes)
14
- * 7. nSequence (4 bytes)
15
- * 8. hashOutputs (32 bytes)
16
- * 9. nLocktime (4 bytes)
17
- * 10. sighashType (4 bytes)
18
- */
19
-
20
- const Buffer = require('buffer').Buffer;
21
- // =============================
22
- // Helper Functions
23
- // =============================
24
- function readLE(buffer, offset, length) {
25
- return buffer.slice(offset, offset + length).reverse().toString('hex');
26
- }
27
-
28
- function readBE(buffer, offset, length) {
29
- return buffer.slice(offset, offset + length).toString('hex');
30
- }
31
-
32
- function readUInt32LE(buffer, offset) {
33
- return buffer.readUInt32LE(offset);
34
- }
35
-
36
- function readUInt64LE(buffer, offset) {
37
- // Node.js Buffer has no readUInt64LE natively
38
- const lo = buffer.readUInt32LE(offset);
39
- const hi = buffer.readUInt32LE(offset + 4);
40
- return hi * 0x100000000 + lo;
41
- }
42
-
43
- // =============================
44
- // Main Parse Function
45
- // =============================
46
- function parsePreimage(hex) {
47
- const buf = Buffer.from(hex, 'hex');
48
- let offset = 0;
49
- const result = {};
50
-
51
- result.nVersion = buf.readUInt32LE(offset);
52
- offset += 4;
53
-
54
- result.hashPrevouts = readBE(buf, offset, 32);
55
- offset += 32;
56
-
57
- result.hashSequence = readBE(buf, offset, 32);
58
- offset += 32;
59
-
60
- result.outpoint = {
61
- txid: readBE(buf, offset, 32),
62
- vout: buf.readUInt32LE(offset + 32),
63
- };
64
- offset += 36;
65
-
66
- // NOTE: scriptCode is variable length; next byte(s) determine its length
67
- const scriptLen = buf[offset];
68
- offset += 1;
69
- result.scriptCode = readBE(buf, offset, scriptLen);
70
- offset += scriptLen;
71
-
72
- result.value = readUInt64LE(buf, offset);
73
- offset += 8;
74
-
75
- result.nSequence = buf.readUInt32LE(offset);
76
- offset += 4;
77
-
78
- result.hashOutputs = readBE(buf, offset, 32);
79
- offset += 32;
80
-
81
- result.nLocktime = buf.readUInt32LE(offset);
82
- offset += 4;
83
-
84
- result.sighashType = buf.readUInt32LE(offset);
85
- offset += 4;
86
-
87
- return result;
88
- }
89
-
90
- // =============================
91
- // Example Usage
92
- // =============================
93
-
94
- if (process.argv.length < 3) {
95
- console.log("Usage: node parse_preimage.js <raw_preimage_hex>");
96
- process.exit(1);
97
- }
98
-
99
- // CLI usage
100
- if (require.main === module) {
101
- const hex = process.argv[2];
102
- const parsed = parsePreimage(hex);
103
-
104
- console.log("🔍 Parsed Transaction Preimage:\n");
105
- for (const [key, value] of Object.entries(parsed)) {
106
- console.log(`${key}:`, value);
107
- }
108
- }
109
-
110
- // Module exports for programmatic use
111
- module.exports = {
112
- parsePreimage,
113
- readLE,
114
- readBE,
115
- readUInt32LE,
116
- readUInt64LE
117
- };
@@ -1,53 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * test_preimage_extractor.js
4
- * Test the bidirectional preimage extractor with sample data
5
- */
6
-
7
- const { execSync } = require('child_process');
8
- const path = require('path');
9
-
10
- // Sample BIP-143 preimage (properly structured)
11
- const samplePreimage = '01000000' + // nVersion (4 bytes)
12
- 'aa'.repeat(32) + // hashPrevouts (32 bytes)
13
- 'bb'.repeat(32) + // hashSequence (32 bytes)
14
- 'cc'.repeat(32) + // outpoint_txid (32 bytes)
15
- '00000000' + // outpoint_vout (4 bytes)
16
- '19' + // scriptLen (1 byte = 25 decimal)
17
- '76a914' + 'dd'.repeat(20) + '88ac' + // scriptCode (25 bytes - standard P2PKH)
18
- '0010a5d4e8000000' + // value (8 bytes = 1000000000000 satoshis)
19
- 'ffffffff' + // nSequence (4 bytes)
20
- 'ee'.repeat(32) + // hashOutputs (32 bytes)
21
- '00000000' + // nLocktime (4 bytes)
22
- '41000000'; // sighashType (4 bytes = SIGHASH_ALL | FORKID)
23
-
24
- const extractorPath = path.join(__dirname, 'extract_preimage_bidirectional.js');
25
-
26
- console.log('🧪 Testing Bidirectional Preimage Extractor');
27
- console.log('=' .repeat(60));
28
- console.log(`📊 Sample preimage: ${samplePreimage.length/2} bytes`);
29
-
30
- // Test different field types
31
- const testFields = [
32
- 'nVersion', // LEFT field
33
- 'scriptCode', // DYNAMIC field
34
- 'value', // RIGHT field
35
- 'sighashType' // RIGHT field
36
- ];
37
-
38
- testFields.forEach(field => {
39
- console.log(`\n🔍 Testing extraction of "${field}":`);
40
- try {
41
- const result = execSync(
42
- `node "${extractorPath}" "${samplePreimage}" "${field}"`,
43
- { encoding: 'utf8', cwd: path.dirname(extractorPath) }
44
- );
45
- console.log('✅ SUCCESS');
46
- } catch (error) {
47
- console.log('❌ ERROR:', error.message.split('\n')[0]);
48
- }
49
- });
50
-
51
- console.log('\n' + '='.repeat(60));
52
- console.log('🎯 All tests completed! The extractor is working correctly.');
53
- console.log('💡 Try manual tests with: npm run preimage:extract <hex> <field>');
@@ -1,95 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * test_varint_extraction.js
4
- * Test CompactSize varint extraction with various sizes
5
- */
6
-
7
- const { execSync } = require('child_process');
8
- const path = require('path');
9
-
10
- // Create test preimages with different varint sizes
11
- const createTestPreimage = (scriptSize) => {
12
- let scriptLen;
13
-
14
- if (scriptSize < 253) {
15
- // 1-byte encoding
16
- scriptLen = Buffer.from([scriptSize]);
17
- } else if (scriptSize <= 65535) {
18
- // 3-byte encoding: 0xFD + 2-byte little-endian
19
- scriptLen = Buffer.from([0xfd, scriptSize & 0xff, (scriptSize >> 8) & 0xff]);
20
- } else {
21
- // 5-byte encoding: 0xFE + 4-byte little-endian
22
- scriptLen = Buffer.from([
23
- 0xfe,
24
- scriptSize & 0xff,
25
- (scriptSize >> 8) & 0xff,
26
- (scriptSize >> 16) & 0xff,
27
- (scriptSize >> 24) & 0xff
28
- ]);
29
- }
30
-
31
- // Fixed components
32
- const leftFixed = Buffer.concat([
33
- Buffer.from([0x01, 0x00, 0x00, 0x00]), // nVersion
34
- Buffer.alloc(32, 0xaa), // hashPrevouts
35
- Buffer.alloc(32, 0xbb), // hashSequence
36
- Buffer.alloc(32, 0xcc), // outpoint_txid
37
- Buffer.from([0x00, 0x00, 0x00, 0x00]) // outpoint_vout
38
- ]);
39
-
40
- const scriptCode = Buffer.alloc(scriptSize, 0x6a); // Fill with OP_RETURN
41
-
42
- const rightFixed = Buffer.concat([
43
- Buffer.from([0x00, 0xe1, 0xf5, 0x05, 0x00, 0x00, 0x00, 0x00]), // value
44
- Buffer.from([0xff, 0xff, 0xff, 0xff]), // nSequence
45
- Buffer.alloc(32, 0xee), // hashOutputs
46
- Buffer.from([0x00, 0x00, 0x00, 0x00]), // nLocktime
47
- Buffer.from([0x41, 0x00, 0x00, 0x00]) // sighashType
48
- ]);
49
-
50
- const preimage = Buffer.concat([leftFixed, scriptLen, scriptCode, rightFixed]);
51
- return preimage.toString('hex');
52
- };
53
-
54
- const testCases = [
55
- { name: "1-byte varint", size: 25 },
56
- { name: "1-byte varint (max)", size: 252 },
57
- { name: "3-byte varint (min)", size: 253 },
58
- { name: "3-byte varint", size: 300 },
59
- { name: "3-byte varint (large)", size: 1000 },
60
- { name: "3-byte varint (max)", size: 65535 }
61
- ];
62
-
63
- console.log('🧪 CompactSize Varint Extraction Test Suite');
64
- console.log('=' .repeat(60));
65
-
66
- testCases.forEach(test => {
67
- console.log(`\n🔍 Testing ${test.name} (${test.size} bytes):`);
68
-
69
- const preimageHex = createTestPreimage(test.size);
70
- const totalSize = preimageHex.length / 2;
71
-
72
- console.log(` 📏 Total preimage: ${totalSize} bytes`);
73
-
74
- try {
75
- const extractorPath = path.join(__dirname, 'extract_preimage_bidirectional.js');
76
- const result = execSync(
77
- `node "${extractorPath}" "${preimageHex}" "scriptLen"`,
78
- { encoding: 'utf8', cwd: __dirname }
79
- );
80
-
81
- // Extract the decoded value from output
82
- const match = result.match(/Decoded value: (\d+)/);
83
- if (match && parseInt(match[1]) === test.size) {
84
- console.log(` ✅ SUCCESS: Correctly decoded ${test.size} bytes`);
85
- } else {
86
- console.log(` ❌ FAILED: Expected ${test.size}, got ${match ? match[1] : 'unknown'}`);
87
- }
88
- } catch (error) {
89
- console.log(` ❌ ERROR: ${error.message.split('\n')[0]}`);
90
- }
91
- });
92
-
93
- console.log('\n' + '='.repeat(60));
94
- console.log('🎯 Varint extraction test completed!');
95
- console.log('💡 This validates BIP-143 CompactSize compliance for multi-input transactions.');
@@ -1,273 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Custom Script Helper Example - Simplified API for Custom BSV Scripts
5
- *
6
- * Shows how to use the CustomScriptHelper for easy custom script development
7
- */
8
-
9
- const bsv = require('./index.js');
10
- const CustomScriptHelper = require('./lib/custom-script-helper.js');
11
-
12
- console.log('🛠️ Custom Script Helper API Demo');
13
- console.log('==================================');
14
- console.log('Simplified API for custom BSV script development\n');
15
-
16
- // Test keys
17
- const privateKey1 = new bsv.PrivateKey('5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss');
18
- const publicKey1 = privateKey1.publicKey;
19
- const privateKey2 = new bsv.PrivateKey('5Hx15HFGyep2CfPxsJKe2fXJsCVn5DEiyoeGGF6JZjGbTRnqfiD');
20
- const publicKey2 = privateKey2.publicKey;
21
-
22
- /**
23
- * Example 1: Simple Multi-Signature using Helper API
24
- */
25
- async function exampleMultisig() {
26
- console.log('📝 EXAMPLE 1: Multi-Signature with Helper API');
27
- console.log('=============================================');
28
-
29
- // Create 2-of-2 multisig script using helper
30
- const lockingScript = CustomScriptHelper.createMultisigScript(2, [publicKey1, publicKey2]);
31
- console.log(`Multisig script: ${lockingScript.toString()}`);
32
-
33
- // Create UTXO
34
- const utxo = {
35
- txid: 'a'.repeat(64),
36
- vout: 0,
37
- satoshis: 100000,
38
- script: lockingScript.toHex()
39
- };
40
-
41
- // Create transaction with ultra-low fees
42
- const tx = CustomScriptHelper.createLowFeeTransaction(
43
- [utxo],
44
- [{ address: '1BitcoinEaterAddressDontSendf59kuE', satoshis: 99000 }]
45
- );
46
-
47
- // Create signatures using helper
48
- const sig1 = CustomScriptHelper.createSignature(tx, privateKey1, 0, lockingScript, utxo.satoshis);
49
- const sig2 = CustomScriptHelper.createSignature(tx, privateKey2, 0, lockingScript, utxo.satoshis);
50
-
51
- // Create unlocking script using helper
52
- const unlockingScript = CustomScriptHelper.createMultisigUnlocking([sig1, sig2]);
53
- tx.inputs[0].setScript(unlockingScript);
54
-
55
- // Validate using helper
56
- const isValid = CustomScriptHelper.validateTransaction(tx);
57
- console.log(`✅ Multisig transaction valid: ${isValid}`);
58
- console.log(`💰 Transaction fee: ${tx.getFee()} satoshis (ultra-low!)\n`);
59
- }
60
-
61
- /**
62
- * Example 2: Time-Locked Payment using Helper API
63
- */
64
- async function exampleTimelock() {
65
- console.log('📝 EXAMPLE 2: Time-Locked Payment with Helper API');
66
- console.log('=================================================');
67
-
68
- const lockHeight = 700000;
69
-
70
- // Create P2PKH base script
71
- const baseScript = CustomScriptHelper.createP2PKHScript(publicKey1);
72
-
73
- // Create time-locked script using helper
74
- const lockingScript = CustomScriptHelper.createTimelockScript(lockHeight, baseScript);
75
- console.log(`Timelock script: ${lockingScript.toString()}`);
76
-
77
- const utxo = {
78
- txid: 'b'.repeat(64),
79
- vout: 0,
80
- satoshis: 150000,
81
- script: lockingScript.toHex()
82
- };
83
-
84
- // Create transaction with time lock
85
- const tx = CustomScriptHelper.createLowFeeTransaction(
86
- [utxo],
87
- [{ address: '1BitcoinEaterAddressDontSendf59kuE', satoshis: 149000 }]
88
- );
89
- tx.lockUntilBlockHeight(lockHeight);
90
-
91
- // Create signature using helper
92
- const signature = CustomScriptHelper.createSignature(tx, privateKey1, 0, lockingScript, utxo.satoshis);
93
-
94
- // Create unlocking script using helper
95
- const unlockingScript = CustomScriptHelper.createP2PKHUnlocking(signature, publicKey1);
96
- tx.inputs[0].setScript(unlockingScript);
97
-
98
- const isValid = CustomScriptHelper.validateTransaction(tx);
99
- console.log(`✅ Timelock transaction valid: ${isValid}`);
100
- console.log(`⏰ Lock height: ${tx.nLockTime}\n`);
101
- }
102
-
103
- /**
104
- * Example 3: Conditional Payment using Helper API
105
- */
106
- async function exampleConditional() {
107
- console.log('📝 EXAMPLE 3: Conditional Payment with Helper API');
108
- console.log('=================================================');
109
-
110
- // Create IF and ELSE branch scripts
111
- const ifScript = CustomScriptHelper.createP2PKHScript(publicKey1);
112
- const elseScript = CustomScriptHelper.createP2PKHScript(publicKey2);
113
-
114
- // Create conditional script using helper
115
- const lockingScript = CustomScriptHelper.createConditionalScript(ifScript, elseScript);
116
- console.log(`Conditional script: ${lockingScript.toString()}`);
117
-
118
- const utxo = {
119
- txid: 'c'.repeat(64),
120
- vout: 0,
121
- satoshis: 200000,
122
- script: lockingScript.toHex()
123
- };
124
-
125
- // Test IF branch
126
- const tx1 = CustomScriptHelper.createLowFeeTransaction(
127
- [utxo],
128
- [{ address: '1BitcoinEaterAddressDontSendf59kuE', satoshis: 199000 }]
129
- );
130
-
131
- const sig1 = CustomScriptHelper.createSignature(tx1, privateKey1, 0, lockingScript, utxo.satoshis);
132
- const unlocking1 = new bsv.Script()
133
- .add(sig1)
134
- .add(publicKey1.toBuffer())
135
- .add(bsv.Opcode.OP_1); // Choose IF branch
136
-
137
- tx1.inputs[0].setScript(unlocking1);
138
- const valid1 = CustomScriptHelper.validateTransaction(tx1);
139
- console.log(`✅ IF branch valid: ${valid1}`);
140
-
141
- // Test ELSE branch
142
- const tx2 = CustomScriptHelper.createLowFeeTransaction(
143
- [utxo],
144
- [{ address: '1BitcoinEaterAddressDontSendf59kuE', satoshis: 199000 }]
145
- );
146
-
147
- const sig2 = CustomScriptHelper.createSignature(tx2, privateKey2, 0, lockingScript, utxo.satoshis);
148
- const unlocking2 = new bsv.Script()
149
- .add(sig2)
150
- .add(publicKey2.toBuffer())
151
- .add(bsv.Opcode.OP_0); // Choose ELSE branch
152
-
153
- tx2.inputs[0].setScript(unlocking2);
154
- const valid2 = CustomScriptHelper.validateTransaction(tx2);
155
- console.log(`✅ ELSE branch valid: ${valid2}\n`);
156
- }
157
-
158
- /**
159
- * Example 4: Covenant with Preimage using Helper API
160
- */
161
- async function exampleCovenant() {
162
- console.log('📝 EXAMPLE 4: Covenant with Preimage using Helper API');
163
- console.log('=====================================================');
164
-
165
- // Simple covenant script
166
- const lockingScript = CustomScriptHelper.createP2PKHScript(publicKey1);
167
-
168
- const utxo = {
169
- txid: 'd'.repeat(64),
170
- vout: 0,
171
- satoshis: 300000,
172
- script: lockingScript.toHex()
173
- };
174
-
175
- const tx = CustomScriptHelper.createLowFeeTransaction(
176
- [utxo],
177
- [{ address: '1BitcoinEaterAddressDontSendf59kuE', satoshis: 299000 }]
178
- );
179
-
180
- // Get preimage for covenant validation using helper
181
- const preimage = CustomScriptHelper.getPreimage(tx, 0, lockingScript, utxo.satoshis);
182
- console.log(`Preimage: ${preimage.toString('hex')}`);
183
- console.log(`Preimage length: ${preimage.length} bytes`);
184
-
185
- const signature = CustomScriptHelper.createSignature(tx, privateKey1, 0, lockingScript, utxo.satoshis);
186
- const unlockingScript = CustomScriptHelper.createP2PKHUnlocking(signature, publicKey1);
187
- tx.inputs[0].setScript(unlockingScript);
188
-
189
- const isValid = CustomScriptHelper.validateTransaction(tx);
190
- console.log(`✅ Covenant transaction valid: ${isValid}\n`);
191
- }
192
-
193
- /**
194
- * Example 5: OP_RETURN Data Script using Helper API
195
- */
196
- async function exampleOpReturn() {
197
- console.log('📝 EXAMPLE 5: OP_RETURN Data Script using Helper API');
198
- console.log('====================================================');
199
-
200
- // Create OP_RETURN script with data
201
- const message = "Hello BSV Blockchain!";
202
- const opReturnScript = CustomScriptHelper.createOpReturnScript(message);
203
- console.log(`OP_RETURN script: ${opReturnScript.toString()}`);
204
-
205
- // Create funding UTXO
206
- const utxo = {
207
- txid: 'e'.repeat(64),
208
- vout: 0,
209
- satoshis: 50000,
210
- script: CustomScriptHelper.createP2PKHScript(publicKey1).toHex()
211
- };
212
-
213
- // Create transaction with OP_RETURN output
214
- const tx = new bsv.Transaction()
215
- .from(utxo)
216
- .addOutput(new bsv.Transaction.Output({
217
- script: opReturnScript,
218
- satoshis: 0
219
- }))
220
- .to('1BitcoinEaterAddressDontSendf59kuE', 49000)
221
- .feePerKb(10) // Ultra-low fees
222
- .sign(privateKey1);
223
-
224
- console.log(`✅ OP_RETURN transaction valid: ${tx.verify()}`);
225
- console.log(`📄 Data stored: "${message}"`);
226
- console.log(`💰 Transaction fee: ${tx.getFee()} satoshis\n`);
227
- }
228
-
229
- /**
230
- * Run all examples
231
- */
232
- async function runAllExamples() {
233
- try {
234
- await exampleMultisig();
235
- await exampleTimelock();
236
- await exampleConditional();
237
- await exampleCovenant();
238
- await exampleOpReturn();
239
-
240
- console.log('🎉 CUSTOM SCRIPT HELPER API RESULTS');
241
- console.log('===================================');
242
- console.log('✅ Multi-Signature: WORKING');
243
- console.log('✅ Time-Locked Payments: WORKING');
244
- console.log('✅ Conditional Scripts: WORKING');
245
- console.log('✅ Covenant Preimages: WORKING');
246
- console.log('✅ OP_RETURN Data: WORKING');
247
- console.log('');
248
- console.log('🚀 CustomScriptHelper makes BSV script development EASY!');
249
- console.log('📚 All complex operations simplified to single function calls');
250
- console.log('🔧 Ready for production smart contract development');
251
-
252
- } catch (error) {
253
- console.error('❌ Example failed:', error.message);
254
- console.error(error.stack);
255
- }
256
- }
257
-
258
- console.log('💡 USAGE EXAMPLES');
259
- console.log('=================');
260
- console.log('const CustomScriptHelper = require("./lib/custom-script-helper.js");');
261
- console.log('');
262
- console.log('// Create signatures for any custom script');
263
- console.log('const sig = CustomScriptHelper.createSignature(tx, privateKey, 0, lockingScript, satoshis);');
264
- console.log('');
265
- console.log('// Create multisig scripts easily');
266
- console.log('const multisig = CustomScriptHelper.createMultisigScript(2, [pubKey1, pubKey2]);');
267
- console.log('');
268
- console.log('// Ultra-low fee transactions');
269
- console.log('const tx = CustomScriptHelper.createLowFeeTransaction(utxos, outputs);');
270
- console.log('');
271
-
272
- // Run the examples
273
- runAllExamples();