@smartledger/bsv 7.9.0 → 7.10.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.
Files changed (73) hide show
  1. package/CHANGELOG.md +103 -0
  2. package/README.md +38 -38
  3. package/bsv-covenant.min.js +1 -1
  4. package/bsv-ecies.min.js +1 -1
  5. package/bsv-gdaf.min.js +54 -54
  6. package/bsv-ltp.min.js +58 -85
  7. package/bsv-message.min.js +2 -2
  8. package/bsv-mnemonic.min.js +12 -14
  9. package/bsv-script-helper.min.js +1 -1
  10. package/bsv-shamir.min.js +14 -16
  11. package/bsv-smartcontract.min.js +23 -25
  12. package/bsv.bundle.js +54 -54
  13. package/bsv.min.js +54 -54
  14. package/build/esbuild.js +86 -5
  15. package/docs/MODULE_REFERENCE_COMPLETE.md +27 -27
  16. package/docs/advanced/UTXO_MANAGER_GUIDE.md +1 -1
  17. package/docs/getting-started/INSTALLATION.md +23 -23
  18. package/docs/getting-started/QUICK_START.md +7 -7
  19. package/docs/migration/FROM_BSV_1_5_6.md +5 -5
  20. package/index.js +9 -1
  21. package/lib/covenant/helpers.js +146 -0
  22. package/lib/covenant/index.js +21 -0
  23. package/lib/covenant/pushtx.js +243 -0
  24. package/lib/covenant-interface.js +418 -397
  25. package/lib/custom-script-helper.js +44 -38
  26. package/lib/ecies/bitcore-ecies.js +3 -4
  27. package/lib/ecies/electrum-ecies.js +4 -6
  28. package/lib/ecies/errors.js +1 -1
  29. package/lib/gdaf/attestation-signer.js +7 -7
  30. package/lib/gdaf/attestation-verifier.js +5 -6
  31. package/lib/gdaf/did-resolver.js +10 -9
  32. package/lib/gdaf/smartledger-anchor.js +13 -12
  33. package/lib/gdaf/zk-prover.js +8 -8
  34. package/lib/ltp/anchor.js +2 -3
  35. package/lib/ltp/claim.js +2 -3
  36. package/lib/ltp/index.js +2 -3
  37. package/lib/ltp/obligation.js +9 -9
  38. package/lib/ltp/proof.js +7 -7
  39. package/lib/ltp/registry.js +4 -5
  40. package/lib/ltp/right.js +11 -11
  41. package/lib/message/index.js +5 -4
  42. package/lib/message/message.js +11 -11
  43. package/lib/mnemonic/errors.js +1 -1
  44. package/lib/mnemonic/index.js +5 -4
  45. package/lib/mnemonic/mnemonic.js +22 -10
  46. package/lib/ordinals/bsv20.js +4 -4
  47. package/lib/ordinals/inscription.js +8 -12
  48. package/lib/ordinals/ordlock.js +26 -21
  49. package/lib/smart_contract/authorizers.js +8 -6
  50. package/lib/smart_contract/builder.js +32 -26
  51. package/lib/smart_contract/covenant.js +32 -25
  52. package/lib/smart_contract/covenant_helpers.js +8 -139
  53. package/lib/smart_contract/debugger.js +9 -6
  54. package/lib/smart_contract/dsl.js +5 -6
  55. package/lib/smart_contract/index.js +11 -8
  56. package/lib/smart_contract/locks.js +3 -4
  57. package/lib/smart_contract/opcode_list.js +2 -3
  58. package/lib/smart_contract/pels.js +4 -5
  59. package/lib/smart_contract/preimage.js +11 -7
  60. package/lib/smart_contract/pushtx.js +8 -263
  61. package/lib/smart_contract/script_interpreter.js +112 -105
  62. package/lib/smart_contract/script_tester.js +24 -18
  63. package/lib/smart_contract/script_utils.js +15 -14
  64. package/lib/smart_contract/sighash.js +23 -15
  65. package/lib/smart_contract/stack_examiner.js +70 -63
  66. package/lib/smart_contract/token.js +6 -6
  67. package/lib/smart_contract/utxo_generator.js +21 -15
  68. package/lib/smartutxo.js +27 -21
  69. package/lib/spv/headerchain.js +3 -3
  70. package/lib/spv/merkleproof.js +3 -3
  71. package/package.json +4 -2
  72. package/test/build/bundle_externals.js +116 -0
  73. package/version.js +1 -1
@@ -13,98 +13,105 @@
13
13
  */
14
14
 
15
15
  // Browser-safe require
16
- const bsv = (typeof window !== 'undefined' && window.bsv) ? window.bsv : require('../../index.js');
17
- const util = require('util');
16
+ const _global = (typeof window !== 'undefined' && window.bsv) ? window.bsv : null
17
+ const Script = _global ? _global.Script : require('../script')
18
+ const Interpreter = _global ? _global.Script.Interpreter : require('../script/interpreter')
19
+ const Opcode = _global ? _global.Opcode : require('../opcode')
20
+ const Transaction = _global ? _global.Transaction : require('../transaction')
21
+ const Input = _global ? _global.Transaction.Input : require('../transaction/input')
22
+ const Output = _global ? _global.Transaction.Output : require('../transaction/output')
23
+ const BN = _global ? _global.crypto.BN : require('../crypto/bn')
24
+ const util = require('util')
18
25
 
19
- function bufferToHexArray(stack) {
20
- return stack.map((buf) => buf.toString('hex'));
26
+ function bufferToHexArray (stack) {
27
+ return stack.map((buf) => buf.toString('hex'))
21
28
  }
22
29
 
23
30
  /**
24
31
  * Executes a locking/unlocking script and prints intermediate stack states.
25
32
  */
26
- function runScript(lockingHex, unlockingHex) {
27
- console.log("===========================================");
28
- console.log("🔍 STACK EXAMINATION TOOL");
29
- console.log("===========================================\n");
33
+ function runScript (lockingHex, unlockingHex) {
34
+ console.log('===========================================')
35
+ console.log('🔍 STACK EXAMINATION TOOL')
36
+ console.log('===========================================\n')
30
37
 
31
- console.log("🔐 Locking Script:", lockingHex);
32
- console.log("🔓 Unlocking Script:", unlockingHex);
33
- console.log("-------------------------------------------");
38
+ console.log('🔐 Locking Script:', lockingHex)
39
+ console.log('🔓 Unlocking Script:', unlockingHex)
40
+ console.log('-------------------------------------------')
34
41
 
35
42
  try {
36
- const lockingScript = bsv.Script.fromHex(lockingHex);
37
- const unlockingScript = bsv.Script.fromHex(unlockingHex);
43
+ const lockingScript = Script.fromHex(lockingHex)
44
+ const unlockingScript = Script.fromHex(unlockingHex)
38
45
 
39
- const combined = bsv.Script.fromBuffer(
46
+ const combined = Script.fromBuffer(
40
47
  Buffer.concat([unlockingScript.toBuffer(), lockingScript.toBuffer()])
41
- );
48
+ )
49
+
50
+ const interpreter = new Interpreter()
51
+ const tx = new Transaction()
42
52
 
43
- const interpreter = new bsv.Script.Interpreter();
44
- const tx = new bsv.Transaction();
45
-
46
53
  // Create proper transaction context
47
- const dummyInput = new bsv.Transaction.Input({
54
+ const dummyInput = new Input({
48
55
  prevTxId: '0'.repeat(64),
49
56
  outputIndex: 0,
50
- script: bsv.Script.empty()
51
- });
52
-
53
- tx.addInput(dummyInput);
54
- tx.addOutput(new bsv.Transaction.Output({
55
- satoshis: 100000,
56
- script: lockingScript
57
- }));
58
-
59
- const scriptChunks = combined.chunks;
60
- const sandbox = new bsv.Script.Interpreter();
61
- sandbox.script = combined;
62
- sandbox.tx = tx;
63
- sandbox.nIn = 0;
64
- sandbox.flags = bsv.Script.Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID;
57
+ script: Script.empty()
58
+ })
59
+
60
+ tx.addInput(dummyInput)
61
+ tx.addOutput(new Output({
62
+ satoshis: 100000,
63
+ script: lockingScript
64
+ }))
65
+
66
+ const scriptChunks = combined.chunks
67
+ const sandbox = new Interpreter()
68
+ sandbox.script = combined
69
+ sandbox.tx = tx
70
+ sandbox.nIn = 0
71
+ sandbox.flags = Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID
65
72
 
66
73
  // Step through each opcode
67
74
  for (let i = 0; i < scriptChunks.length; i++) {
68
- const chunk = scriptChunks[i];
75
+ const chunk = scriptChunks[i]
69
76
  try {
70
77
  // Check if step method exists (compatibility check)
71
78
  if (typeof sandbox.step === 'function') {
72
- sandbox.step();
79
+ sandbox.step()
73
80
  } else {
74
- console.log("⚠️ Step-by-step execution not supported in this BSV version");
75
- break;
81
+ console.log('⚠️ Step-by-step execution not supported in this BSV version')
82
+ break
76
83
  }
77
-
78
- console.log(`\n🧩 Step ${i + 1}: ${bsv.Opcode.reverseMap[chunk.opcodenum] || 'PUSH'}`);
79
- console.log("Stack:", bufferToHexArray(sandbox.stack));
80
- console.log("AltStack:", bufferToHexArray(sandbox.altstack));
84
+
85
+ console.log(`\n🧩 Step ${i + 1}: ${Opcode.reverseMap[chunk.opcodenum] || 'PUSH'}`)
86
+ console.log('Stack:', bufferToHexArray(sandbox.stack))
87
+ console.log('AltStack:', bufferToHexArray(sandbox.altstack))
81
88
  } catch (err) {
82
- console.log(`⚠️ Error executing opcode ${i + 1}:`, err.message);
83
- break;
89
+ console.log(`⚠️ Error executing opcode ${i + 1}:`, err.message)
90
+ break
84
91
  }
85
92
  }
86
93
 
87
94
  // Final verification with proper satoshis parameter
88
- const satoshisBN = new bsv.crypto.BN(100000);
95
+ const satoshisBN = new BN(100000)
89
96
  const verified = interpreter.verify(
90
97
  unlockingScript,
91
98
  lockingScript,
92
99
  tx,
93
100
  0,
94
- bsv.Script.Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID,
101
+ Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID,
95
102
  satoshisBN
96
- );
97
-
98
- console.log("\n===========================================");
99
- console.log("✅ Final Result:", verified ? "TRUE (Success)" : "❌ FALSE (Failure)");
100
- console.log("Final Stack:", bufferToHexArray(sandbox.stack || []));
101
- console.log("AltStack:", bufferToHexArray(sandbox.altstack || []));
102
- console.log("===========================================");
103
-
104
- return verified;
103
+ )
104
+
105
+ console.log('\n===========================================')
106
+ console.log('✅ Final Result:', verified ? 'TRUE (Success)' : '❌ FALSE (Failure)')
107
+ console.log('Final Stack:', bufferToHexArray(sandbox.stack || []))
108
+ console.log('AltStack:', bufferToHexArray(sandbox.altstack || []))
109
+ console.log('===========================================')
110
+
111
+ return verified
105
112
  } catch (err) {
106
- console.error("❌ Error in script execution:", err.message);
107
- return false;
113
+ console.error('❌ Error in script execution:', err.message)
114
+ return false
108
115
  }
109
116
  }
110
117
 
@@ -113,17 +120,17 @@ function runScript(lockingHex, unlockingHex) {
113
120
  // ============================================
114
121
  if (typeof require !== 'undefined' && require.main === module) {
115
122
  if (process.argv.length < 4) {
116
- console.log("Usage: node stack_examiner.js <locking_script_hex> <unlocking_script_hex>");
117
- process.exit(1);
123
+ console.log('Usage: node stack_examiner.js <locking_script_hex> <unlocking_script_hex>')
124
+ process.exit(1)
118
125
  }
119
126
 
120
- const locking = process.argv[2];
121
- const unlocking = process.argv[3];
122
- runScript(locking, unlocking);
127
+ const locking = process.argv[2]
128
+ const unlocking = process.argv[3]
129
+ runScript(locking, unlocking)
123
130
  }
124
131
 
125
132
  // Export for module usage
126
133
  module.exports = {
127
134
  runScript,
128
135
  bufferToHexArray
129
- };
136
+ }
@@ -39,13 +39,13 @@
39
39
  * Requires post-Genesis limits (SmartContract.enableGenesis()).
40
40
  */
41
41
 
42
- var bsv = require('../..')
43
- var P = require('./pushtx')
44
- var H = require('./covenant_helpers')
42
+ var BN = require('../crypto/bn')
43
+ var P = require('../covenant/pushtx')
44
+ var H = require('../covenant/helpers')
45
45
  var A = require('./authorizers')
46
46
 
47
- var Script = bsv.Script
48
- var Opcode = bsv.Opcode
47
+ var Script = require('../script')
48
+ var Opcode = require('../opcode')
49
49
  var n = H.scriptNum
50
50
 
51
51
  function resolveCommit (owner, auth) {
@@ -285,7 +285,7 @@ function transferOrdinal (signer, newOwnerHash, spend, ordinalSats, lockingScrip
285
285
  function ser (o) { return o.toBufferWriter().toBuffer() }
286
286
  var before = Buffer.concat(outs.slice(0, tokenIndex).map(ser))
287
287
  var after = Buffer.concat(outs.slice(tokenIndex + 1).map(ser))
288
- var tokenValue = new bsv.crypto.BN(ordinalSats).toBuffer({ endian: 'little', size: 8 })
288
+ var tokenValue = new BN(ordinalSats).toBuffer({ endian: 'little', size: 8 })
289
289
 
290
290
  return unlockTransferMulti(signer, newOwnerHash, spend, ordinalSats, lockingScript, {
291
291
  before: before,
@@ -15,7 +15,13 @@
15
15
 
16
16
  'use strict'
17
17
 
18
- var bsv = require('../..')
18
+ var sighash = require('../transaction/sighash')
19
+ var Signature = require('../crypto/signature')
20
+ var BN = require('../crypto/bn')
21
+ var Transaction = require('../transaction')
22
+ var PrivateKey = require('../privatekey')
23
+ var Networks = require('../networks')
24
+ var Script = require('../script')
19
25
  var crypto = require('crypto')
20
26
 
21
27
  /**
@@ -28,14 +34,14 @@ function UTXOGenerator(options) {
28
34
  }
29
35
 
30
36
  this.options = options || {}
31
- this.network = this.options.network || bsv.Networks.mainnet
37
+ this.network = this.options.network || Networks.mainnet
32
38
  this.keyRing = {} // Store generated keys
33
39
  this.utxoPool = [] // Store generated UTXOs
34
40
 
35
41
  // Initialize with SmartUTXO integration via direct require so that
36
42
  // touching this internal integration path doesn't surface the
37
- // bsv.SmartUTXO deprecation warning (the warning is for downstream
38
- // consumers who reach for bsv.SmartUTXO themselves, not for our own
43
+ // SmartUTXO deprecation warning (the warning is for downstream
44
+ // consumers who reach for SmartUTXO themselves, not for our own
39
45
  // internal coupling). Try/catch because smartutxo is Node-only.
40
46
  try {
41
47
  var SmartUTXO = require('../smartutxo')
@@ -51,7 +57,7 @@ function UTXOGenerator(options) {
51
57
  UTXOGenerator.prototype.generateKeypair = function(label) {
52
58
  label = label || 'key_' + Date.now()
53
59
 
54
- var privateKey = bsv.PrivateKey.fromRandom(this.network)
60
+ var privateKey = PrivateKey.fromRandom(this.network)
55
61
  var publicKey = privateKey.toPublicKey()
56
62
  var address = privateKey.toAddress(this.network)
57
63
 
@@ -119,25 +125,25 @@ UTXOGenerator.prototype._createSingleUTXO = function(config) {
119
125
 
120
126
  switch (config.scriptType) {
121
127
  case 'P2PKH':
122
- script = bsv.Script.buildPublicKeyHashOut(config.keypair.address)
128
+ script = Script.buildPublicKeyHashOut(config.keypair.address)
123
129
  scriptHex = script.toHex()
124
130
  break
125
131
 
126
132
  case 'P2SH':
127
133
  // Create a simple multisig for P2SH example
128
- var redeemScript = bsv.Script.buildMultisigOut([config.keypair.publicKey], 1)
129
- script = bsv.Script.buildScriptHashOut(redeemScript)
134
+ var redeemScript = Script.buildMultisigOut([config.keypair.publicKey], 1)
135
+ script = Script.buildScriptHashOut(redeemScript)
130
136
  scriptHex = script.toHex()
131
137
  break
132
138
 
133
139
  case 'CUSTOM':
134
140
  // Allow custom script injection
135
- script = config.customScript || bsv.Script.buildPublicKeyHashOut(config.keypair.address)
141
+ script = config.customScript || Script.buildPublicKeyHashOut(config.keypair.address)
136
142
  scriptHex = script.toHex()
137
143
  break
138
144
 
139
145
  default:
140
- script = bsv.Script.buildPublicKeyHashOut(config.keypair.address)
146
+ script = Script.buildPublicKeyHashOut(config.keypair.address)
141
147
  scriptHex = script.toHex()
142
148
  }
143
149
 
@@ -174,7 +180,7 @@ UTXOGenerator.prototype.createTestTransaction = function(config) {
174
180
  }, 0)
175
181
 
176
182
  // Create transaction
177
- var transaction = new bsv.Transaction()
183
+ var transaction = new Transaction()
178
184
 
179
185
  // Add inputs
180
186
  inputUTXOs.forEach(function(utxo) {
@@ -217,15 +223,15 @@ UTXOGenerator.prototype.createTestTransaction = function(config) {
217
223
 
218
224
  // Preimage generation helper
219
225
  generatePreimage: function(inputIndex, sighashType) {
220
- sighashType = sighashType || bsv.crypto.Signature.SIGHASH_ALL | bsv.crypto.Signature.SIGHASH_FORKID
226
+ sighashType = sighashType || Signature.SIGHASH_ALL | Signature.SIGHASH_FORKID
221
227
  var utxo = inputUTXOs[inputIndex]
222
228
 
223
- return bsv.Transaction.sighash.sighashPreimage(
229
+ return sighash.sighashPreimage(
224
230
  transaction,
225
231
  sighashType,
226
232
  inputIndex,
227
- bsv.Script.fromHex(utxo.script),
228
- new bsv.crypto.BN(utxo.satoshis)
233
+ Script.fromHex(utxo.script),
234
+ new BN(utxo.satoshis)
229
235
  )
230
236
  }
231
237
  }
package/lib/smartutxo.js CHANGED
@@ -35,6 +35,13 @@ const debug = function () {
35
35
  if (enabled) console.log.apply(console, arguments)
36
36
  }
37
37
 
38
+ // Library primitives, required directly rather than through the package root.
39
+ // createMockUTXOs() previously did a lazy `require('../')` to dodge the
40
+ // module-init cycle; with the cycle gone these can be plain top-level imports.
41
+ const Script = require('./script')
42
+ const Address = require('./address')
43
+ const Random = require('./crypto/random')
44
+
38
45
  // Browser-compatible imports
39
46
  let fs, path, crypto, blockchainState
40
47
 
@@ -54,9 +61,9 @@ if (typeof window === 'undefined' && typeof require === 'function') {
54
61
  * Comprehensive UTXO Management System for BSV development
55
62
  */
56
63
  class SmartUTXOManager {
57
- constructor(options = {}) {
64
+ constructor (options = {}) {
58
65
  this.options = options || {}
59
-
66
+
60
67
  // Initialize blockchain state - this creates the file if needed
61
68
  this.loadState()
62
69
  }
@@ -64,7 +71,7 @@ class SmartUTXOManager {
64
71
  /**
65
72
  * Load blockchain state from file (initializes if needed)
66
73
  */
67
- loadState() {
74
+ loadState () {
68
75
  try {
69
76
  const state = blockchainState.loadBlockchainState()
70
77
  return state
@@ -75,9 +82,9 @@ class SmartUTXOManager {
75
82
  }
76
83
 
77
84
  /**
78
- * Save blockchain state to file
85
+ * Save blockchain state to file
79
86
  */
80
- saveState() {
87
+ saveState () {
81
88
  try {
82
89
  const state = blockchainState.loadBlockchainState()
83
90
  blockchainState.saveBlockchainState(state)
@@ -93,15 +100,15 @@ class SmartUTXOManager {
93
100
  * @param {string} address - Bitcoin address
94
101
  * @returns {Array} Array of UTXO objects
95
102
  */
96
- getUTXOsForAddress(address) {
103
+ getUTXOsForAddress (address) {
97
104
  try {
98
105
  const state = blockchainState.loadBlockchainState()
99
-
106
+
100
107
  // Check if wallet exists
101
108
  if (!state.wallets || !state.wallets[address]) {
102
109
  return []
103
110
  }
104
-
111
+
105
112
  // Return the wallet's UTXOs
106
113
  return state.wallets[address].utxos || []
107
114
  } catch (error) {
@@ -114,7 +121,7 @@ class SmartUTXOManager {
114
121
  * Add a new UTXO to the system
115
122
  * @param {Object} utxo - UTXO object {txid, vout, address, satoshis, script}
116
123
  */
117
- addUTXO(utxo) {
124
+ addUTXO (utxo) {
118
125
  try {
119
126
  // Use the correct API: addUTXO(utxo, ownerAddress)
120
127
  blockchainState.addUTXO(utxo, utxo.address)
@@ -128,7 +135,7 @@ class SmartUTXOManager {
128
135
  * @param {Array} inputs - Array of input objects {txid, vout}
129
136
  * @param {string} spentInTx - Optional transaction ID where UTXO was spent
130
137
  */
131
- spendUTXOs(inputs, spentInTx = 'manual-spend') {
138
+ spendUTXOs (inputs, spentInTx = 'manual-spend') {
132
139
  try {
133
140
  for (const input of inputs) {
134
141
  // Use the correct API: spendUTXO(txid, vout, spentInTx)
@@ -153,18 +160,17 @@ class SmartUTXOManager {
153
160
  * @param {number} satoshis - Satoshis per UTXO
154
161
  * @returns {Array} Array of created UTXOs
155
162
  */
156
- createMockUTXOs(address, count = 5, satoshis = 100000) {
163
+ createMockUTXOs (address, count = 5, satoshis = 100000) {
157
164
  // Use bsv's own RNG so this works in both Node and browser builds
158
165
  // (the Node `crypto` import above is undefined in browser context).
159
- const bsv = require('../')
160
- const lockingScriptHex = bsv.Script.buildPublicKeyHashOut(
161
- bsv.Address.fromString(address)
166
+ const lockingScriptHex = Script.buildPublicKeyHashOut(
167
+ Address.fromString(address)
162
168
  ).toHex()
163
169
 
164
170
  const mockUTXOs = []
165
171
  for (let i = 0; i < count; i++) {
166
172
  mockUTXOs.push({
167
- txid: bsv.crypto.Random.getRandomBuffer(32).toString('hex'),
173
+ txid: Random.getRandomBuffer(32).toString('hex'),
168
174
  vout: i,
169
175
  address,
170
176
  satoshis,
@@ -179,15 +185,15 @@ class SmartUTXOManager {
179
185
  * @param {string} address - Bitcoin address
180
186
  * @returns {number} Total satoshis
181
187
  */
182
- getBalance(address) {
188
+ getBalance (address) {
183
189
  try {
184
190
  const state = blockchainState.loadBlockchainState()
185
-
191
+
186
192
  // Check if wallet exists
187
193
  if (!state.wallets || !state.wallets[address]) {
188
194
  return 0
189
195
  }
190
-
196
+
191
197
  // Return the wallet's total value
192
198
  return state.wallets[address].totalValue || 0
193
199
  } catch (error) {
@@ -200,7 +206,7 @@ class SmartUTXOManager {
200
206
  * Get blockchain statistics
201
207
  * @returns {Object} Stats object
202
208
  */
203
- getStats() {
209
+ getStats () {
204
210
  try {
205
211
  const state = blockchainState.getBlockchainStats() // This returns the full state
206
212
  return {
@@ -219,7 +225,7 @@ class SmartUTXOManager {
219
225
  /**
220
226
  * Reset blockchain state
221
227
  */
222
- reset() {
228
+ reset () {
223
229
  try {
224
230
  const statePath = path.join(__dirname, '../utilities/blockchain-state.json')
225
231
  if (fs.existsSync(statePath)) {
@@ -232,4 +238,4 @@ class SmartUTXOManager {
232
238
  }
233
239
  }
234
240
 
235
- module.exports = SmartUTXOManager
241
+ module.exports = SmartUTXOManager
@@ -15,14 +15,14 @@
15
15
  * (or anchor) must match; the headers around it are then real work extending a block
16
16
  * you trust. Full difficulty-retarget validation is intentionally out of scope here.
17
17
  */
18
- var bsv = require('../..')
18
+ var BlockHeader = require('../block/blockheader')
19
19
 
20
20
  function rev (b) { return Buffer.from(b).reverse() }
21
21
 
22
22
  function toHeader (h) {
23
23
  if (h && typeof h.validProofOfWork === 'function') return h
24
- if (Buffer.isBuffer(h)) return bsv.BlockHeader.fromBuffer(h)
25
- if (typeof h === 'string') return bsv.BlockHeader.fromBuffer(Buffer.from(h, 'hex'))
24
+ if (Buffer.isBuffer(h)) return BlockHeader.fromBuffer(h)
25
+ if (typeof h === 'string') return BlockHeader.fromBuffer(Buffer.from(h, 'hex'))
26
26
  throw new Error('each header must be a BlockHeader, an 80-byte Buffer, or hex')
27
27
  }
28
28
 
@@ -15,8 +15,8 @@
15
15
  * lib/block/{block,merkleblock}.js. A node of '*' (or '' / null) means "duplicate the
16
16
  * working hash" — Bitcoin's odd-node rule, per the TSC Merkle Proof standard.
17
17
  */
18
- var bsv = require('../..')
19
- var Hash = bsv.crypto.Hash
18
+ var BlockHeader = require('../block/blockheader')
19
+ var Hash = require('../crypto/hash')
20
20
 
21
21
  var HEX32 = /^[0-9a-fA-F]{64}$/
22
22
 
@@ -81,7 +81,7 @@ function verifyMerkleProof (proof) {
81
81
  function verifyTxInclusion (params) {
82
82
  var header = params.header
83
83
  if (Buffer.isBuffer(header) || typeof header === 'string') {
84
- header = bsv.BlockHeader.fromBuffer(Buffer.isBuffer(header) ? header : Buffer.from(header, 'hex'))
84
+ header = BlockHeader.fromBuffer(Buffer.isBuffer(header) ? header : Buffer.from(header, 'hex'))
85
85
  }
86
86
  if (!header || !header.merkleRoot) throw new Error('a valid block header is required')
87
87
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smartledger/bsv",
3
- "version": "7.9.0",
3
+ "version": "7.10.1",
4
4
  "description": "🚀 Complete Bitcoin SV development framework with legally-recognizable DID:web + W3C VC-JWT toolkit, Legal Token Protocol (LTP), Global Digital Attestation Framework (GDAF), StatusList2021 revocation, and 16 flexible loading options. Standards-based credentials with ES256/ES256K support, on-chain BSV anchoring, and comprehensive Bitcoin SV API. Perfect for legal tokens, verifiable credentials, 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",
@@ -31,6 +31,7 @@
31
31
  "./vcjwt": "./vcjwt-entry.js",
32
32
  "./lib/anchor": "./lib/anchor/index.js",
33
33
  "./lib/block": "./lib/block/index.js",
34
+ "./lib/covenant": "./lib/covenant/index.js",
34
35
  "./lib/didweb": "./lib/didweb/index.js",
35
36
  "./lib/ecies": "./lib/ecies/index.js",
36
37
  "./lib/errors": "./lib/errors/index.js",
@@ -58,6 +59,8 @@
58
59
  "scripts": {
59
60
  "lint": "standard",
60
61
  "check:load-order": "node scripts/check-address-load-order.js",
62
+ "conformance": "node conformance/verify.js",
63
+ "conformance:generate": "node conformance/generate.js",
61
64
  "lint:ratchet": "node scripts/lint-ratchet.js",
62
65
  "lint:ratchet:update": "node scripts/lint-ratchet.js --update",
63
66
  "test": "mocha",
@@ -227,7 +230,6 @@
227
230
  "@noble/ciphers": "2.2.0",
228
231
  "@noble/curves": "2.2.0",
229
232
  "@noble/hashes": "2.2.0",
230
- "aes-js": "^3.1.2",
231
233
  "bn.js": "=4.12.5",
232
234
  "bs58": "=4.0.1",
233
235
  "clone-deep": "^4.0.1",
@@ -0,0 +1,116 @@
1
+ 'use strict'
2
+
3
+ /* global describe, it, before */
4
+
5
+ // Feature bundles must EXTERNALISE the shared primitives, not embed a second copy.
6
+ //
7
+ // Getting this wrong is not a size regression. If a feature bundle ships its own
8
+ // PrivateKey class, a key built by bsv.min.js fails `instanceof` inside that bundle
9
+ // and index.js's versionGuard reports two library instances — a failure that is
10
+ // invisible to every test that stays inside one bundle.
11
+ //
12
+ // build/esbuild.js has always had a `metafile` option whose comment said it was "used
13
+ // to assert" this property. Nothing consumed it: `grep -rn metafile` returned only the
14
+ // option itself. This file is that consumer.
15
+
16
+ require('chai').should()
17
+ var esbuild = require('../../build/esbuild.js')
18
+
19
+ // Bundles that resolve bsv from the global instead of embedding it.
20
+ var EXTERNALISED = esbuild.BUNDLES.filter(function (c) { return c.externalBsv })
21
+
22
+ describe('feature bundles externalise the shared primitives', function () {
23
+ this.timeout(120000)
24
+
25
+ var inputsByBundle = {}
26
+
27
+ before(function () {
28
+ // Build each one in memory (write:false) and keep its module graph.
29
+ return Promise.all(EXTERNALISED.map(function (cfg) {
30
+ return esbuild.buildOne(cfg, { metafile: true, write: false, logLevel: 'silent' })
31
+ .then(function (result) {
32
+ inputsByBundle[cfg.file] = Object.keys(result.metafile.inputs)
33
+ .filter(function (p) { return p.indexOf('lib/') === 0 })
34
+ .sort()
35
+ })
36
+ }))
37
+ })
38
+
39
+ it('has bundles to check', function () {
40
+ EXTERNALISED.length.should.be.above(0)
41
+ Object.keys(inputsByBundle).length.should.equal(EXTERNALISED.length)
42
+ })
43
+
44
+ // The primary assertion, derived from the config rather than hand-maintained: every
45
+ // path in LIB_GLOBALS is a module the build promises to take from the global bsv, so
46
+ // none of them may appear as a bundled input. Because it reads the same table the
47
+ // build uses, it cannot drift out of step with it.
48
+ it('never embeds a module that LIB_GLOBALS maps to the global bsv', function () {
49
+ var mapped = Object.keys(esbuild.LIB_GLOBALS)
50
+ var offences = []
51
+ Object.keys(inputsByBundle).forEach(function (file) {
52
+ inputsByBundle[file].forEach(function (input) {
53
+ // 'lib/privatekey.js' -> 'privatekey'; 'lib/script/index.js' -> 'script/index'
54
+ var key = input.replace(/^lib\//, '').replace(/\.js$/, '')
55
+ if (mapped.indexOf(key) !== -1) {
56
+ offences.push(file + ' embeds ' + input + ' (should come from global bsv.' +
57
+ esbuild.LIB_GLOBALS[key] + ')')
58
+ }
59
+ })
60
+ })
61
+ offences.should.deep.equal([])
62
+ })
63
+
64
+ // LIB_GLOBALS is deliberately not exhaustive — a feature bundle SHOULD contain its own
65
+ // feature code. So the catch-all is to pin what each bundle contains: anything new
66
+ // appearing here is either the feature growing or a primitive leaking in, and a human
67
+ // decides which. Without this, a `require('../mnemonic')` added to a module reachable
68
+ // from an externalised entry would bundle a second copy silently, with every existing
69
+ // test green.
70
+ it('contains only its own feature code, pinned per bundle', function () {
71
+ // Accepted in any bundle: a tiny lodash subset with no library state, deliberately
72
+ // duplicated rather than routed through the global.
73
+ var SHARED = ['lib/util/']
74
+ var EXPECTED = {
75
+ 'bsv-ecies.min.js': ['lib/ecies/'],
76
+ 'bsv-message.min.js': ['lib/message/'],
77
+ 'bsv-mnemonic.min.js': ['lib/mnemonic/'],
78
+ 'bsv-shamir.min.js': ['lib/crypto/'],
79
+ 'bsv-smartcontract.min.js': ['lib/smart_contract/', 'lib/covenant/', 'lib/smartutxo.js'],
80
+ 'bsv-covenant.min.js': ['lib/smart_contract/'],
81
+ 'bsv-script-helper.min.js': ['lib/custom-script-helper.js']
82
+ }
83
+ var unexpected = []
84
+ Object.keys(inputsByBundle).forEach(function (file) {
85
+ var allowed = (EXPECTED[file] || []).concat(SHARED)
86
+ if (!EXPECTED[file]) {
87
+ unexpected.push(file + ' is externalised but has no expected-input list')
88
+ return
89
+ }
90
+ inputsByBundle[file].forEach(function (input) {
91
+ var ok = allowed.some(function (prefix) { return input.indexOf(prefix) === 0 })
92
+ if (!ok) unexpected.push(file + ' unexpectedly embeds ' + input)
93
+ })
94
+ })
95
+ unexpected.should.deep.equal([])
96
+ })
97
+
98
+ it('shares nothing but documented helpers across bundles', function () {
99
+ // A module appearing in two feature bundles is a duplicated copy in the shipped
100
+ // set. Only these are accepted, and each is a deliberate call rather than an
101
+ // accident: lib/util/_.js is a tiny lodash subset, and lib/smart_contract/covenant.js
102
+ // is genuinely the feature of both covenant-flavoured bundles.
103
+ var ACCEPTED_DUPLICATES = ['lib/util/_.js', 'lib/smart_contract/covenant.js']
104
+ var seen = {}
105
+ Object.keys(inputsByBundle).forEach(function (file) {
106
+ inputsByBundle[file].forEach(function (input) {
107
+ (seen[input] = seen[input] || []).push(file)
108
+ })
109
+ })
110
+ var duplicated = Object.keys(seen)
111
+ .filter(function (p) { return seen[p].length > 1 })
112
+ .filter(function (p) { return ACCEPTED_DUPLICATES.indexOf(p) === -1 })
113
+ .sort()
114
+ duplicated.should.deep.equal([])
115
+ })
116
+ })
package/version.js CHANGED
@@ -1,3 +1,3 @@
1
1
  'use strict'
2
2
  // GENERATED by scripts/sync-version.js on `npm version` — do not edit.
3
- module.exports = '7.9.0'
3
+ module.exports = '7.10.1'