@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,120 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Demonstration of Preimage Covenant Utils
5
- *
6
- * Shows the clean API for proper covenant flow
7
- */
8
-
9
- const bsv = require('../../index.js');
10
- const PreimageCovenantUtils = require('./preimage_covenant_utils');
11
- const fs = require('fs');
12
- const path = require('path');
13
-
14
- console.log('šŸš€ Preimage Covenant Utils Demonstration');
15
- console.log('=======================================\n');
16
-
17
- // Initialize with private key
18
- const privateKey = bsv.PrivateKey.fromWIF('L5JREiiMfP5enqsRuhyNEv8SRjrjnMXNhkQEgNvzDRhGTaHG9ZFm');
19
- const covenantUtils = new PreimageCovenantUtils(privateKey);
20
-
21
- console.log('Wallet:', covenantUtils.address.toString());
22
- console.log('');
23
-
24
- // Load a P2PKH UTXO (from WhatsOnChain in real scenario)
25
- function getP2pkhUtxo() {
26
- const utxoPath = path.join(__dirname, '../data/utxos.json');
27
- const utxos = JSON.parse(fs.readFileSync(utxoPath, 'utf8'));
28
-
29
- const utxo = utxos.find(u => u.status === 'confirmed' && u.satoshis >= 10000);
30
- if (!utxo) {
31
- throw new Error('No suitable P2PKH UTXO found');
32
- }
33
-
34
- return utxo;
35
- }
36
-
37
- // Example broadcast callback (would integrate with WhatsOnChain/etc in production)
38
- function broadcastCallback(tx, phase) {
39
- console.log(`šŸ“” Would broadcast ${phase} transaction:`, tx.id);
40
-
41
- try {
42
- console.log('- Size:', tx.toString('hex').length / 2, 'bytes'); // āœ… Using toString('hex')
43
- console.log('- Fee:', tx.getFee(), 'satoshis');
44
- console.log('- Valid:', tx.verify());
45
- } catch (error) {
46
- console.log('- Validation pending (custom script)');
47
- }
48
- console.log('');
49
-
50
- // In production: POST to WhatsOnChain or other broadcast service
51
- // fetch('https://api.whatsonchain.com/v1/bsv/main/tx/raw', {
52
- // method: 'POST',
53
- // body: tx.toString('hex') // āœ… Using toString('hex')
54
- // });
55
- }
56
-
57
- try {
58
- console.log('Example 1: Complete Covenant Flow');
59
- console.log('=================================');
60
-
61
- const p2pkhUtxo = getP2pkhUtxo();
62
- console.log('šŸ“¦ Using P2PKH UTXO:', p2pkhUtxo.txid);
63
- console.log('');
64
-
65
- const result = covenantUtils.completeCovenantFlow(p2pkhUtxo, broadcastCallback);
66
-
67
- if (result.success) {
68
- console.log('šŸŽ‰ Complete success!\n');
69
- }
70
-
71
- console.log('Example 2: Working with Stored Covenant UTXOs');
72
- console.log('=============================================');
73
-
74
- // List all stored covenant UTXOs
75
- const storedUtxos = covenantUtils.listCovenantUtxos();
76
- console.log('šŸ“‹ Stored covenant UTXOs:', storedUtxos.length);
77
-
78
- storedUtxos.forEach((utxo, i) => {
79
- console.log(`- UTXO ${i + 1}:`);
80
- console.log(` - TXID: ${utxo.txid}`);
81
- console.log(` - Satoshis: ${utxo.satoshis}`);
82
- console.log(` - Created: ${utxo.createdAt}`);
83
- console.log(` - Status: ${utxo.status}`);
84
- });
85
-
86
- console.log('');
87
-
88
- console.log('Example 3: Spending Existing Covenant UTXO');
89
- console.log('==========================================');
90
-
91
- // Load and spend the most recent covenant UTXO
92
- if (storedUtxos.length > 0) {
93
- const latestUtxo = storedUtxos[storedUtxos.length - 1];
94
- console.log('šŸ”“ Spending covenant UTXO:', latestUtxo.txid);
95
-
96
- const spendingTx = covenantUtils.createCovenantSpendingTx(latestUtxo);
97
- const validation = covenantUtils.validateCovenantTx(spendingTx, latestUtxo);
98
-
99
- console.log('- Spending TX:', spendingTx.id);
100
- console.log('- Valid:', validation.valid ? 'āœ… SUCCESS' : 'āŒ FAILED');
101
- console.log('- Error:', validation.error || 'none');
102
-
103
- if (validation.valid) {
104
- broadcastCallback(spendingTx, 'covenant spending');
105
- }
106
- }
107
-
108
- console.log('\nšŸŽÆ Production Integration Notes:');
109
- console.log('==============================');
110
- console.log('āœ… P2PKH UTXOs: Fetch from WhatsOnChain API');
111
- console.log('āœ… Script Reconstruction: Built-in with address');
112
- console.log('āœ… Covenant Storage: Local JSON with custom scripts');
113
- console.log('āœ… Broadcasting: Integrate with WhatsOnChain/other APIs');
114
- console.log('āœ… Preimage Validation: Automatic with original preimage');
115
- console.log('āœ… Signature Context: Proper covenant script signing');
116
-
117
- } catch (error) {
118
- console.log('āŒ Error:', error.message);
119
- console.log('Stack:', error.stack);
120
- }
@@ -1,287 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Preimage Covenant Utilities
5
- *
6
- * Provides clean interfaces for the proper covenant flow:
7
- * 1. P2PKH UTXO → Covenant Creation → Local Storage
8
- * 2. Local Covenant UTXO → Covenant Spending → Broadcast
9
- */
10
-
11
- const bsv = require('../../index.js');
12
- const fs = require('fs');
13
- const path = require('path');
14
-
15
- class PreimageCovenantUtils {
16
- constructor(privateKey) {
17
- this.privateKey = privateKey;
18
- this.publicKey = privateKey.publicKey;
19
- this.address = privateKey.toAddress();
20
- this.covenantUtxoPath = path.join(__dirname, '../data/covenant_utxos.json');
21
- this.sighashType = bsv.crypto.Signature.SIGHASH_ALL | bsv.crypto.Signature.SIGHASH_FORKID;
22
- }
23
-
24
- /**
25
- * šŸ“¦ Reconstruct P2PKH script from address
26
- * (As you mentioned: all UTXOs from WhatsOnChain are P2PKH)
27
- */
28
- static reconstructP2pkhScript(address) {
29
- return bsv.Script.buildPublicKeyHashOut(address).toHex();
30
- }
31
-
32
- /**
33
- * šŸ—ļø Create covenant from P2PKH UTXO
34
- */
35
- createCovenantFromP2pkh(utxo) {
36
- console.log('šŸ—ļø Creating covenant from P2PKH UTXO...');
37
-
38
- // Reconstruct P2PKH script
39
- utxo.script = PreimageCovenantUtils.reconstructP2pkhScript(this.address);
40
-
41
- // Create covenant creation transaction
42
- const creationTx = new bsv.Transaction()
43
- .from({
44
- txId: utxo.txid,
45
- outputIndex: utxo.vout,
46
- script: utxo.script,
47
- satoshis: utxo.satoshis
48
- })
49
- .to(this.address, utxo.satoshis - 1000); // 1000 sat fee
50
-
51
- // Get preimage for covenant creation
52
- const p2pkhScript = bsv.Script.fromHex(utxo.script);
53
- const creationPreimage = bsv.Transaction.sighash.sighash(
54
- creationTx,
55
- this.sighashType,
56
- 0,
57
- p2pkhScript,
58
- new bsv.crypto.BN(utxo.satoshis)
59
- );
60
-
61
- const preimageHash = bsv.crypto.Hash.sha256sha256(creationPreimage);
62
-
63
- // Build covenant locking script with OP_DROP fix
64
- const covenantLockingScript = new bsv.Script()
65
- .add('OP_DUP')
66
- .add('OP_HASH256')
67
- .add(preimageHash)
68
- .add('OP_EQUALVERIFY')
69
- .add('OP_DROP') // āœ… Stack management
70
- .add(this.publicKey.toBuffer())
71
- .add('OP_CHECKSIG');
72
-
73
- // Replace output script with covenant
74
- creationTx.outputs[0].setScript(covenantLockingScript);
75
-
76
- // Sign creation transaction (against P2PKH)
77
- creationTx.sign(this.privateKey);
78
-
79
- console.log('āœ… Covenant creation transaction valid:', creationTx.verify());
80
-
81
- return {
82
- transaction: creationTx,
83
- covenantUtxo: {
84
- txid: creationTx.id,
85
- vout: 0,
86
- satoshis: utxo.satoshis - 1000,
87
- script: covenantLockingScript.toHex(),
88
- scriptPubKey: covenantLockingScript.toHex(),
89
- preimageHash: preimageHash.toString('hex'),
90
- originalPreimage: creationPreimage.toString('hex'),
91
- status: 'local',
92
- createdAt: new Date().toISOString(),
93
- type: 'preimage_covenant'
94
- }
95
- };
96
- }
97
-
98
- /**
99
- * šŸ’¾ Save covenant UTXO to local storage
100
- */
101
- saveCovenantUtxo(covenantUtxo) {
102
- let covenantUtxos = [];
103
- if (fs.existsSync(this.covenantUtxoPath)) {
104
- covenantUtxos = JSON.parse(fs.readFileSync(this.covenantUtxoPath, 'utf8'));
105
- }
106
-
107
- // Ensure data directory exists
108
- const dataDir = path.dirname(this.covenantUtxoPath);
109
- if (!fs.existsSync(dataDir)) {
110
- fs.mkdirSync(dataDir, { recursive: true });
111
- }
112
-
113
- covenantUtxos.push(covenantUtxo);
114
- fs.writeFileSync(this.covenantUtxoPath, JSON.stringify(covenantUtxos, null, 2));
115
- console.log('āœ… Covenant UTXO saved to local storage');
116
- }
117
-
118
- /**
119
- * šŸ“‚ Load covenant UTXO from local storage
120
- */
121
- loadCovenantUtxo(txid = null) {
122
- if (!fs.existsSync(this.covenantUtxoPath)) {
123
- throw new Error('No covenant UTXOs found. Create one first.');
124
- }
125
-
126
- const covenantUtxos = JSON.parse(fs.readFileSync(this.covenantUtxoPath, 'utf8'));
127
-
128
- if (txid) {
129
- const utxo = covenantUtxos.find(u => u.txid === txid);
130
- if (!utxo) {
131
- throw new Error(`Covenant UTXO with TXID ${txid} not found`);
132
- }
133
- return utxo;
134
- } else {
135
- const utxo = covenantUtxos.find(u => u.type === 'preimage_covenant');
136
- if (!utxo) {
137
- throw new Error('No preimage covenant UTXO found');
138
- }
139
- return utxo;
140
- }
141
- }
142
-
143
- /**
144
- * šŸ”“ Create spending transaction for covenant UTXO
145
- */
146
- createCovenantSpendingTx(covenantUtxo, outputAddress = null, outputSatoshis = null) {
147
- console.log('šŸ”“ Creating covenant spending transaction...');
148
-
149
- const outputAddr = outputAddress || this.address;
150
- const outputSats = outputSatoshis || (covenantUtxo.satoshis - 500); // 500 sat fee
151
-
152
- // Create spending transaction - don't use .from() for custom scripts
153
- const spendingTx = new bsv.Transaction();
154
-
155
- // Manually add input for custom covenant script
156
- spendingTx.addInput(new bsv.Transaction.Input({
157
- prevTxId: covenantUtxo.txid,
158
- outputIndex: covenantUtxo.vout,
159
- script: bsv.Script.empty() // Will be set after signing
160
- }), bsv.Script.fromHex(covenantUtxo.script), covenantUtxo.satoshis);
161
-
162
- // Add output
163
- spendingTx.to(outputAddr, outputSats);
164
-
165
- const covenantScript = bsv.Script.fromHex(covenantUtxo.script);
166
-
167
- // Create signature against covenant script (not P2PKH!)
168
- const covenantSignature = bsv.Transaction.sighash.sign(
169
- spendingTx,
170
- this.privateKey,
171
- this.sighashType,
172
- 0,
173
- covenantScript, // āœ… Sign against covenant script
174
- new bsv.crypto.BN(covenantUtxo.satoshis)
175
- );
176
-
177
- const fullSignature = Buffer.concat([
178
- covenantSignature.toDER(),
179
- Buffer.from([this.sighashType])
180
- ]);
181
-
182
- // Use original preimage from covenant creation
183
- const originalPreimage = Buffer.from(covenantUtxo.originalPreimage, 'hex');
184
-
185
- // Create unlocking script
186
- const unlockingScript = new bsv.Script()
187
- .add(fullSignature)
188
- .add(originalPreimage);
189
-
190
- spendingTx.inputs[0].setScript(unlockingScript);
191
-
192
- return spendingTx;
193
- }
194
-
195
- /**
196
- * āœ… Validate covenant transaction with Script.Interpreter
197
- */
198
- validateCovenantTx(spendingTx, covenantUtxo) {
199
- const interpreter = new bsv.Script.Interpreter();
200
- const flags = bsv.Script.Interpreter.SCRIPT_VERIFY_P2SH |
201
- bsv.Script.Interpreter.SCRIPT_VERIFY_STRICTENC |
202
- bsv.Script.Interpreter.SCRIPT_VERIFY_DERSIG |
203
- bsv.Script.Interpreter.SCRIPT_VERIFY_LOW_S |
204
- bsv.Script.Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID;
205
-
206
- const unlockingScript = spendingTx.inputs[0].script;
207
- const lockingScript = bsv.Script.fromHex(covenantUtxo.script);
208
-
209
- const result = interpreter.verify(
210
- unlockingScript,
211
- lockingScript,
212
- spendingTx,
213
- 0,
214
- flags,
215
- new bsv.crypto.BN(covenantUtxo.satoshis)
216
- );
217
-
218
- if (!result) {
219
- console.log('āŒ Validation failed:', interpreter.errstr);
220
- } else {
221
- console.log('āœ… Covenant transaction validated successfully');
222
- }
223
-
224
- return { valid: result, error: interpreter.errstr };
225
- }
226
-
227
- /**
228
- * šŸŽÆ Complete covenant flow: P2PKH → Covenant → Spending
229
- */
230
- completeCovenantFlow(p2pkhUtxo, broadcastCallback = null) {
231
- console.log('šŸŽÆ Starting complete covenant flow...\n');
232
-
233
- try {
234
- // Phase 1: Create covenant from P2PKH
235
- const { transaction: creationTx, covenantUtxo } = this.createCovenantFromP2pkh(p2pkhUtxo);
236
- this.saveCovenantUtxo(covenantUtxo);
237
-
238
- console.log('Phase 1 Complete: P2PKH → Covenant āœ…');
239
- console.log('- Creation TX:', creationTx.id);
240
- console.log('- Covenant UTXO saved locally\n');
241
-
242
- // Optional: Broadcast creation transaction
243
- if (broadcastCallback) {
244
- broadcastCallback(creationTx, 'creation');
245
- }
246
-
247
- // Phase 2: Spend covenant UTXO
248
- const spendingTx = this.createCovenantSpendingTx(covenantUtxo);
249
- const validation = this.validateCovenantTx(spendingTx, covenantUtxo);
250
-
251
- console.log('Phase 2 Complete: Covenant → Spending āœ…');
252
- console.log('- Spending TX:', spendingTx.id);
253
- console.log('- Validation:', validation.valid ? 'āœ… SUCCESS' : 'āŒ FAILED');
254
-
255
- // Optional: Broadcast spending transaction
256
- if (broadcastCallback && validation.valid) {
257
- broadcastCallback(spendingTx, 'covenant spending');
258
- }
259
-
260
- return {
261
- creationTx,
262
- spendingTx,
263
- covenantUtxo,
264
- validation,
265
- success: validation.valid
266
- };
267
-
268
- } catch (error) {
269
- console.log('āŒ Flow failed:', error.message);
270
- throw error;
271
- }
272
- }
273
-
274
- /**
275
- * šŸ“‹ List all stored covenant UTXOs
276
- */
277
- listCovenantUtxos() {
278
- if (!fs.existsSync(this.covenantUtxoPath)) {
279
- return [];
280
- }
281
-
282
- const covenantUtxos = JSON.parse(fs.readFileSync(this.covenantUtxoPath, 'utf8'));
283
- return covenantUtxos;
284
- }
285
- }
286
-
287
- module.exports = PreimageCovenantUtils;
@@ -1,256 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * 🌐 Production-Ready Preimage Covenant Integration
5
- *
6
- * Demonstrates how the covenant flow integrates with:
7
- * 1. WhatsOnChain API for UTXO fetching
8
- * 2. Broadcasting transactions
9
- * 3. Managing multiple covenant types
10
- * 4. Real mainnet scenarios
11
- */
12
-
13
- const bsv = require('../../index.js');
14
- const PreimageCovenantUtils = require('./preimage_covenant_utils.js');
15
-
16
- console.log('🌐 Production Preimage Covenant Integration');
17
- console.log('==========================================\n');
18
-
19
- class ProductionCovenantManager {
20
- constructor(privateKey) {
21
- this.covenantUtils = new PreimageCovenantUtils(privateKey);
22
- this.address = privateKey.toAddress().toString();
23
- }
24
-
25
- /**
26
- * šŸ“” Fetch UTXOs from WhatsOnChain (mainnet integration)
27
- */
28
- async fetchUtxosFromWhatsOnChain() {
29
- console.log('šŸ“” Fetching UTXOs from WhatsOnChain...');
30
-
31
- // In production, this would be:
32
- // const response = await fetch(`https://api.whatsonchain.com/v1/bsv/main/address/${this.address}/unspent`);
33
- // const utxos = await response.json();
34
-
35
- // For demo, simulate the response structure:
36
- const mockUtxos = [
37
- {
38
- "height": 850234,
39
- "tx_pos": 1,
40
- "tx_hash": "98697480789ca50f967b9b324b44838d6b256e0db22206bf5c58f02fa652c864",
41
- "value": 917852
42
- }
43
- ];
44
-
45
- // Convert WhatsOnChain format to our format
46
- const convertedUtxos = mockUtxos.map(utxo => ({
47
- txid: utxo.tx_hash,
48
- vout: utxo.tx_pos,
49
- satoshis: utxo.value,
50
- height: utxo.height,
51
- status: 'confirmed',
52
- // Script will be reconstructed from address (as you mentioned)
53
- script: PreimageCovenantUtils.reconstructP2pkhScript(
54
- bsv.Address.fromString(this.address)
55
- )
56
- }));
57
-
58
- console.log(`āœ… Found ${convertedUtxos.length} UTXOs for address ${this.address}`);
59
- return convertedUtxos;
60
- }
61
-
62
- /**
63
- * šŸ“¤ Broadcast transaction to WhatsOnChain
64
- */
65
- async broadcastTransaction(tx, description) {
66
- console.log(`šŸ“¤ Broadcasting ${description}...`);
67
-
68
- try {
69
- const txHex = tx.toString('hex'); // āœ… Using toString('hex') instead of serialize()
70
- console.log(`- Transaction ID: ${tx.id}`);
71
- console.log(`- Size: ${txHex.length / 2} bytes`);
72
- console.log(`- Fee: ${tx.getFee()} satoshis`);
73
-
74
- // In production, this would be:
75
- // const response = await fetch('https://api.whatsonchain.com/v1/bsv/main/tx/raw', {
76
- // method: 'POST',
77
- // headers: { 'Content-Type': 'application/json' },
78
- // body: JSON.stringify({ txhex: txHex })
79
- // });
80
-
81
- // Simulate successful broadcast
82
- console.log(`āœ… ${description} broadcast successfully`);
83
- console.log(`- Mainnet TXID: ${tx.id}`);
84
-
85
- return { success: true, txid: tx.id };
86
-
87
- } catch (error) {
88
- console.log(`āŒ Broadcast failed: ${error.message}`);
89
- return { success: false, error: error.message };
90
- }
91
- }
92
-
93
- /**
94
- * šŸ­ Create covenant from available UTXOs
95
- */
96
- async createCovenantFromUtxos(minSatoshis = 10000) {
97
- console.log('šŸ­ Creating covenant from available UTXOs...\n');
98
-
99
- const utxos = await this.fetchUtxosFromWhatsOnChain();
100
-
101
- const suitableUtxo = utxos.find(utxo =>
102
- utxo.satoshis >= minSatoshis &&
103
- utxo.status === 'confirmed'
104
- );
105
-
106
- if (!suitableUtxo) {
107
- throw new Error(`No UTXO with at least ${minSatoshis} satoshis found`);
108
- }
109
-
110
- console.log(`šŸ“¦ Selected UTXO: ${suitableUtxo.txid}`);
111
- console.log(`- Satoshis: ${suitableUtxo.satoshis}`);
112
- console.log(`- Height: ${suitableUtxo.height}\n`);
113
-
114
- // Create covenant using utility class
115
- const { transaction: creationTx, covenantUtxo } =
116
- this.covenantUtils.createCovenantFromP2pkh(suitableUtxo);
117
-
118
- // Broadcast covenant creation transaction
119
- const broadcastResult = await this.broadcastTransaction(
120
- creationTx,
121
- 'covenant creation'
122
- );
123
-
124
- if (broadcastResult.success) {
125
- // Update covenant UTXO with broadcast info
126
- covenantUtxo.status = 'broadcast';
127
- covenantUtxo.broadcastTxid = broadcastResult.txid;
128
- covenantUtxo.broadcastAt = new Date().toISOString();
129
-
130
- // Save to local storage
131
- this.covenantUtils.saveCovenantUtxo(covenantUtxo);
132
-
133
- console.log('āœ… Covenant UTXO created and stored with broadcast info\n');
134
- }
135
-
136
- return { creationTx, covenantUtxo, broadcastResult };
137
- }
138
-
139
- /**
140
- * šŸŽÆ Spend covenant with custom output
141
- */
142
- async spendCovenantUtxo(covenantTxid, outputAddress = null, outputSatoshis = null) {
143
- console.log(`šŸŽÆ Spending covenant UTXO: ${covenantTxid}...\n`);
144
-
145
- // Load covenant from storage
146
- const covenantUtxo = this.covenantUtils.loadCovenantUtxo(covenantTxid);
147
-
148
- console.log(`šŸ“¦ Loaded covenant UTXO:`);
149
- console.log(`- Satoshis: ${covenantUtxo.satoshis}`);
150
- console.log(`- Created: ${covenantUtxo.createdAt}`);
151
- console.log(`- Status: ${covenantUtxo.status}\n`);
152
-
153
- // Create spending transaction
154
- const spendingTx = this.covenantUtils.createCovenantSpendingTx(
155
- covenantUtxo,
156
- outputAddress,
157
- outputSatoshis
158
- );
159
-
160
- // Validate covenant spending
161
- const validation = this.covenantUtils.validateCovenantTx(spendingTx, covenantUtxo);
162
-
163
- if (!validation.valid) {
164
- throw new Error(`Covenant validation failed: ${validation.error}`);
165
- }
166
-
167
- console.log('āœ… Covenant spending transaction validated\n');
168
-
169
- // Broadcast spending transaction
170
- const broadcastResult = await this.broadcastTransaction(
171
- spendingTx,
172
- 'covenant spending'
173
- );
174
-
175
- return { spendingTx, validation, broadcastResult };
176
- }
177
-
178
- /**
179
- * šŸ“Š Get covenant portfolio status
180
- */
181
- getCovenantPortfolio() {
182
- const covenants = this.covenantUtils.listCovenantUtxos();
183
-
184
- const portfolio = {
185
- total: covenants.length,
186
- totalValue: covenants.reduce((sum, c) => sum + c.satoshis, 0),
187
- byStatus: {},
188
- recent: covenants.slice(-5) // Last 5 created
189
- };
190
-
191
- // Group by status
192
- covenants.forEach(covenant => {
193
- const status = covenant.status || 'local';
194
- if (!portfolio.byStatus[status]) {
195
- portfolio.byStatus[status] = { count: 0, value: 0 };
196
- }
197
- portfolio.byStatus[status].count++;
198
- portfolio.byStatus[status].value += covenant.satoshis;
199
- });
200
-
201
- return portfolio;
202
- }
203
- }
204
-
205
- // Demo usage
206
- async function demonstrateProductionFlow() {
207
- const privateKey = bsv.PrivateKey.fromWIF('L5JREiiMfP5enqsRuhyNEv8SRjrjnMXNhkQEgNvzDRhGTaHG9ZFm');
208
- const manager = new ProductionCovenantManager(privateKey);
209
-
210
- console.log(`Wallet Address: ${manager.address}\n`);
211
-
212
- try {
213
- console.log('Scenario 1: Create New Covenant from P2PKH UTXO');
214
- console.log('===============================================');
215
-
216
- const creation = await manager.createCovenantFromUtxos(50000);
217
- console.log(`Created covenant: ${creation.covenantUtxo.txid}\n`);
218
-
219
- console.log('Scenario 2: Check Covenant Portfolio');
220
- console.log('===================================');
221
-
222
- const portfolio = manager.getCovenantPortfolio();
223
- console.log('šŸ“Š Covenant Portfolio:');
224
- console.log(`- Total Covenants: ${portfolio.total}`);
225
- console.log(`- Total Value: ${portfolio.totalValue} satoshis`);
226
- console.log('- By Status:');
227
-
228
- Object.entries(portfolio.byStatus).forEach(([status, stats]) => {
229
- console.log(` - ${status}: ${stats.count} covenants, ${stats.value} sats`);
230
- });
231
- console.log('');
232
-
233
- console.log('Scenario 3: Spend Latest Covenant');
234
- console.log('=================================');
235
-
236
- if (portfolio.recent.length > 0) {
237
- const latestCovenant = portfolio.recent[portfolio.recent.length - 1];
238
- const spending = await manager.spendCovenantUtxo(latestCovenant.txid);
239
- console.log(`Spent covenant: ${spending.spendingTx.id}\n`);
240
- }
241
-
242
- console.log('šŸŽ‰ Production integration demonstration complete!');
243
- console.log('\nšŸš€ Ready for mainnet deployment with:');
244
- console.log('āœ… WhatsOnChain API integration');
245
- console.log('āœ… Automatic P2PKH script reconstruction');
246
- console.log('āœ… Local covenant UTXO storage');
247
- console.log('āœ… Broadcast transaction management');
248
- console.log('āœ… Portfolio tracking and management');
249
-
250
- } catch (error) {
251
- console.log('āŒ Error:', error.message);
252
- }
253
- }
254
-
255
- // Run the demonstration
256
- demonstrateProductionFlow();
@@ -1,28 +0,0 @@
1
- [
2
- {
3
- "txid": "8e1ee45889ffe3795867f4aeaed210986ade118a1fd395f3a2236706dbee3423",
4
- "vout": 0,
5
- "satoshis": 916852,
6
- "script": "76aa209888e1517445f2a81880d485cf008819d1cbd78c0a94163e8ac9ab2049606351887521024fbc086ee073b74ecca97e7f39245b268cc3594140fe561f2d4876ebc3631d2aac",
7
- "scriptPubKey": "76aa209888e1517445f2a81880d485cf008819d1cbd78c0a94163e8ac9ab2049606351887521024fbc086ee073b74ecca97e7f39245b268cc3594140fe561f2d4876ebc3631d2aac",
8
- "preimageHash": "9888e1517445f2a81880d485cf008819d1cbd78c0a94163e8ac9ab2049606351",
9
- "originalPreimage": "af93d3d37a5050d450f75b6085a820aa123cafeeafedc01e1f70f4d19a0acbdd",
10
- "status": "local",
11
- "createdAt": "2025-10-20T00:30:10.836Z",
12
- "type": "preimage_covenant"
13
- },
14
- {
15
- "txid": "8e1ee45889ffe3795867f4aeaed210986ade118a1fd395f3a2236706dbee3423",
16
- "vout": 0,
17
- "satoshis": 916852,
18
- "script": "76aa209888e1517445f2a81880d485cf008819d1cbd78c0a94163e8ac9ab2049606351887521024fbc086ee073b74ecca97e7f39245b268cc3594140fe561f2d4876ebc3631d2aac",
19
- "scriptPubKey": "76aa209888e1517445f2a81880d485cf008819d1cbd78c0a94163e8ac9ab2049606351887521024fbc086ee073b74ecca97e7f39245b268cc3594140fe561f2d4876ebc3631d2aac",
20
- "preimageHash": "9888e1517445f2a81880d485cf008819d1cbd78c0a94163e8ac9ab2049606351",
21
- "originalPreimage": "af93d3d37a5050d450f75b6085a820aa123cafeeafedc01e1f70f4d19a0acbdd",
22
- "status": "broadcast",
23
- "createdAt": "2025-10-20T00:30:33.822Z",
24
- "type": "preimage_covenant",
25
- "broadcastTxid": "8e1ee45889ffe3795867f4aeaed210986ade118a1fd395f3a2236706dbee3423",
26
- "broadcastAt": "2025-10-20T00:30:33.823Z"
27
- }
28
- ]