@smartledger/bsv 7.9.0 → 7.10.0
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 +59 -0
- package/README.md +38 -38
- package/bsv-covenant.min.js +1 -1
- package/bsv-ecies.min.js +1 -1
- package/bsv-gdaf.min.js +54 -54
- package/bsv-ltp.min.js +58 -85
- package/bsv-message.min.js +2 -2
- package/bsv-mnemonic.min.js +12 -14
- package/bsv-script-helper.min.js +1 -1
- package/bsv-shamir.min.js +14 -16
- package/bsv-smartcontract.min.js +23 -25
- package/bsv.bundle.js +54 -54
- package/bsv.min.js +54 -54
- package/build/esbuild.js +84 -4
- package/docs/MODULE_REFERENCE_COMPLETE.md +27 -27
- package/docs/advanced/UTXO_MANAGER_GUIDE.md +1 -1
- package/docs/getting-started/INSTALLATION.md +23 -23
- package/docs/getting-started/QUICK_START.md +7 -7
- package/docs/migration/FROM_BSV_1_5_6.md +5 -5
- package/index.js +9 -1
- package/lib/covenant/helpers.js +146 -0
- package/lib/covenant/index.js +21 -0
- package/lib/covenant/pushtx.js +243 -0
- package/lib/covenant-interface.js +408 -397
- package/lib/custom-script-helper.js +44 -38
- package/lib/ecies/bitcore-ecies.js +3 -4
- package/lib/ecies/electrum-ecies.js +4 -6
- package/lib/ecies/errors.js +1 -1
- package/lib/gdaf/attestation-signer.js +7 -7
- package/lib/gdaf/attestation-verifier.js +5 -6
- package/lib/gdaf/did-resolver.js +10 -9
- package/lib/gdaf/smartledger-anchor.js +13 -12
- package/lib/gdaf/zk-prover.js +8 -8
- package/lib/ltp/anchor.js +2 -3
- package/lib/ltp/claim.js +2 -3
- package/lib/ltp/index.js +2 -3
- package/lib/ltp/obligation.js +9 -9
- package/lib/ltp/proof.js +7 -7
- package/lib/ltp/registry.js +4 -5
- package/lib/ltp/right.js +11 -11
- package/lib/message/index.js +5 -4
- package/lib/message/message.js +11 -11
- package/lib/mnemonic/errors.js +1 -1
- package/lib/mnemonic/index.js +5 -4
- package/lib/mnemonic/mnemonic.js +22 -10
- package/lib/ordinals/bsv20.js +4 -4
- package/lib/ordinals/inscription.js +8 -12
- package/lib/ordinals/ordlock.js +26 -21
- package/lib/smart_contract/authorizers.js +8 -6
- package/lib/smart_contract/builder.js +32 -26
- package/lib/smart_contract/covenant.js +32 -25
- package/lib/smart_contract/covenant_helpers.js +8 -139
- package/lib/smart_contract/debugger.js +9 -6
- package/lib/smart_contract/dsl.js +5 -6
- package/lib/smart_contract/index.js +11 -8
- package/lib/smart_contract/locks.js +3 -4
- package/lib/smart_contract/opcode_list.js +2 -3
- package/lib/smart_contract/pels.js +4 -5
- package/lib/smart_contract/preimage.js +11 -7
- package/lib/smart_contract/pushtx.js +8 -263
- package/lib/smart_contract/script_interpreter.js +112 -105
- package/lib/smart_contract/script_tester.js +24 -18
- package/lib/smart_contract/script_utils.js +15 -14
- package/lib/smart_contract/sighash.js +23 -15
- package/lib/smart_contract/stack_examiner.js +70 -63
- package/lib/smart_contract/token.js +6 -6
- package/lib/smart_contract/utxo_generator.js +21 -15
- package/lib/smartutxo.js +27 -21
- package/lib/spv/headerchain.js +3 -3
- package/lib/spv/merkleproof.js +3 -3
- package/package.json +4 -2
- package/version.js +1 -1
|
@@ -13,98 +13,105 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
// Browser-safe require
|
|
16
|
-
const
|
|
17
|
-
const
|
|
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(
|
|
29
|
-
console.log(
|
|
33
|
+
function runScript (lockingHex, unlockingHex) {
|
|
34
|
+
console.log('===========================================')
|
|
35
|
+
console.log('🔍 STACK EXAMINATION TOOL')
|
|
36
|
+
console.log('===========================================\n')
|
|
30
37
|
|
|
31
|
-
console.log(
|
|
32
|
-
console.log(
|
|
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 =
|
|
37
|
-
const unlockingScript =
|
|
43
|
+
const lockingScript = Script.fromHex(lockingHex)
|
|
44
|
+
const unlockingScript = Script.fromHex(unlockingHex)
|
|
38
45
|
|
|
39
|
-
const combined =
|
|
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
|
|
54
|
+
const dummyInput = new Input({
|
|
48
55
|
prevTxId: '0'.repeat(64),
|
|
49
56
|
outputIndex: 0,
|
|
50
|
-
script:
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
tx.addInput(dummyInput)
|
|
54
|
-
tx.addOutput(new
|
|
55
|
-
satoshis: 100000,
|
|
56
|
-
script: lockingScript
|
|
57
|
-
}))
|
|
58
|
-
|
|
59
|
-
const scriptChunks = combined.chunks
|
|
60
|
-
const sandbox = new
|
|
61
|
-
sandbox.script = combined
|
|
62
|
-
sandbox.tx = tx
|
|
63
|
-
sandbox.nIn = 0
|
|
64
|
-
sandbox.flags =
|
|
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(
|
|
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}: ${
|
|
79
|
-
console.log(
|
|
80
|
-
console.log(
|
|
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
|
|
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
|
-
|
|
101
|
+
Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID,
|
|
95
102
|
satoshisBN
|
|
96
|
-
)
|
|
97
|
-
|
|
98
|
-
console.log(
|
|
99
|
-
console.log(
|
|
100
|
-
console.log(
|
|
101
|
-
console.log(
|
|
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(
|
|
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(
|
|
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
|
|
43
|
-
var P = require('
|
|
44
|
-
var H = require('
|
|
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 =
|
|
48
|
-
var 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
|
|
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
|
|
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 ||
|
|
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
|
-
//
|
|
38
|
-
// consumers who reach for
|
|
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 =
|
|
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 =
|
|
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 =
|
|
129
|
-
script =
|
|
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 ||
|
|
141
|
+
script = config.customScript || Script.buildPublicKeyHashOut(config.keypair.address)
|
|
136
142
|
scriptHex = script.toHex()
|
|
137
143
|
break
|
|
138
144
|
|
|
139
145
|
default:
|
|
140
|
-
script =
|
|
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
|
|
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 ||
|
|
226
|
+
sighashType = sighashType || Signature.SIGHASH_ALL | Signature.SIGHASH_FORKID
|
|
221
227
|
var utxo = inputUTXOs[inputIndex]
|
|
222
228
|
|
|
223
|
-
return
|
|
229
|
+
return sighash.sighashPreimage(
|
|
224
230
|
transaction,
|
|
225
231
|
sighashType,
|
|
226
232
|
inputIndex,
|
|
227
|
-
|
|
228
|
-
new
|
|
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
|
|
160
|
-
|
|
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:
|
|
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
|
package/lib/spv/headerchain.js
CHANGED
|
@@ -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
|
|
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
|
|
25
|
-
if (typeof h === 'string') return
|
|
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
|
|
package/lib/spv/merkleproof.js
CHANGED
|
@@ -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
|
|
19
|
-
var 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 =
|
|
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.
|
|
3
|
+
"version": "7.10.0",
|
|
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",
|
package/version.js
CHANGED