smartledger-bsv 3.3.2 → 3.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +220 -79
- package/README.md +283 -71
- package/bsv-covenant.min.js +26 -3
- package/bsv-gdaf.min.js +11 -9
- package/bsv-ltp.min.js +10 -8
- package/bsv-mnemonic.min.js +4 -4
- package/bsv-script-helper.min.js +2 -2
- package/bsv-security.min.js +3 -24
- package/bsv-shamir.min.js +2 -2
- package/bsv-smartcontract.min.js +10 -8
- package/bsv.bundle.js +9 -9
- package/bsv.min.js +10 -8
- package/build/webpack.bundle.config.js +2 -2
- package/build/webpack.config.js +2 -2
- package/build/webpack.covenant.config.js +2 -2
- package/build/webpack.gdaf.config.js +6 -43
- package/build/webpack.script-helper.config.js +2 -2
- package/build/webpack.security.config.js +2 -2
- package/build/webpack.smartcontract.config.js +2 -2
- package/bundle-entry.js +1 -341
- package/covenant-entry.js +1 -44
- package/demos/README.md +188 -0
- package/{architecture_demo.js → demos/architecture_demo.js} +2 -2
- package/demos/bsv_wallet_demo.js +242 -0
- package/{complete_ltp_demo.js → demos/complete_ltp_demo.js} +1 -1
- package/demos/debug_tools_demo.js +87 -0
- package/demos/demo_features.js +123 -0
- package/demos/easy_interface_demo.js +109 -0
- package/demos/ecies_demo.js +182 -0
- package/demos/gdaf_core_test.js +131 -0
- package/demos/gdaf_demo.js +237 -0
- package/demos/ltp_demo.js +361 -0
- package/demos/ltp_primitives_demo.js +403 -0
- package/demos/message_demo.js +209 -0
- package/demos/preimage_separation_demo.js +383 -0
- package/demos/script_helper_demo.js +289 -0
- package/demos/security_demo.js +287 -0
- package/{shamir_demo.js → demos/shamir_demo.js} +1 -1
- package/{simple_demo.js → demos/simple_demo.js} +1 -1
- package/demos/simple_p2pkh_demo.js +169 -0
- package/demos/simple_utxo_preimage_demo.js +196 -0
- package/demos/smart_contract_demo.html +1347 -0
- package/demos/smart_contract_demo.js +910 -0
- package/demos/utxo_generator_demo.js +244 -0
- package/demos/validation_pipeline_demo.js +155 -0
- package/demos/web3keys.html +740 -0
- package/docs/BUNDLE_UPDATE_SUMMARY.md +40 -0
- package/docs/DOCUMENTATION_REVIEW_REPORT.md +295 -0
- package/docs/FIX_CREATEHMAC_ISSUE.md +91 -0
- package/docs/MODULE_REFERENCE_COMPLETE.md +330 -0
- package/docs/README.md +107 -79
- package/docs/SMARTLEDGER_BSV_USAGE_ANSWERS.md +477 -0
- package/docs/SMARTLEDGER_BSV_USAGE_EXAMPLES.js +372 -0
- package/docs/SMARTLEDGER_BSV_USAGE_GUIDE.md +555 -0
- package/docs/SMART_CONTRACT_DEVELOPMENT_GUIDE.md +1459 -0
- package/docs/advanced/LEGAL_TOKEN_PROTOCOL.md +411 -0
- package/docs/advanced/SMART_CONTRACT_GUIDE.md +1255 -0
- package/docs/advanced/UTXO_MANAGER_GUIDE.md +851 -0
- package/docs/api/LTP.md +334 -0
- package/docs/getting-started/INSTALLATION.md +410 -0
- package/docs/getting-started/QUICK_START.md +180 -0
- package/docs/migration/FROM_BSV_1_5_6.md +260 -0
- package/docs/technical/GDAF_DEVELOPER_INTERFACE.md +187 -0
- package/docs/technical/GDAF_IMPLEMENTATION_COMPLETE.md +190 -0
- package/docs/technical/SHAMIR_INTEGRATION_SUMMARY.md +165 -0
- package/docs/technical/roadmap.md +1250 -0
- package/docs/technical/trust_law.md +142 -0
- package/examples/complete_workflow_demo.js +783 -0
- package/examples/definitive_working_demo.js +261 -0
- package/examples/final_working_contracts.js +338 -0
- package/examples/smart_contract_templates.js +718 -0
- package/examples/working_smart_contracts.js +348 -0
- package/gdaf-entry.js +2 -54
- package/index.js +32 -0
- package/lib/mnemonic/pbkdf2.browser.js +69 -0
- package/lib/mnemonic/pbkdf2.js +2 -68
- package/lib/mnemonic/pbkdf2.node.js +68 -0
- package/ltp-entry.js +2 -92
- package/package.json +21 -8
- package/script-helper-entry.js +1 -49
- package/security-entry.js +1 -70
- package/shamir-entry.js +1 -173
- package/smartcontract-entry.js +1 -133
- package/tests/browser-compatibility/README.md +35 -0
- package/tests/browser-compatibility/test-cdn-vs-local.html +186 -0
- package/tests/browser-compatibility/test-pbkdf2.html +51 -0
- package/tests/test_builtin_verify.js +117 -0
- package/tests/test_debug_integration.js +71 -0
- package/tests/test_ecdsa_little.js +70 -0
- package/tests/test_smartverify_der.js +110 -0
- package/utilities/blockchain-state.js +155 -155
- package/utilities/blockchain-state.json +103293 -5244
- package/utilities/miner-simulator.js +354 -358
- package/utilities/mock-utxo-generator.js +54 -54
- package/utilities/raw-tx-examples.js +120 -122
- package/utilities/success-demo.js +104 -105
- package/utilities/transaction-examples.js +188 -188
- package/utilities/utxo-manager.js +91 -91
- package/utilities/wallet-setup.js +79 -80
- package/utilities/working-signature-demo.js +108 -110
- package/SECURITY.md +0 -75
- package/build/bsv-covenant.min.js +0 -10
- package/build/bsv-script-helper.min.js +0 -10
- package/build/bsv-security.min.js +0 -31
- package/build/bsv-smartcontract.min.js +0 -39
- package/build/bsv.bundle.js +0 -39
- package/build/bsv.min.js +0 -39
- package/validation_test.js +0 -97
- /package/docs/{ADVANCED_COVENANT_DEVELOPMENT.md → advanced/ADVANCED_COVENANT_DEVELOPMENT.md} +0 -0
- /package/docs/{CUSTOM_SCRIPT_DEVELOPMENT.md → advanced/CUSTOM_SCRIPT_DEVELOPMENT.md} +0 -0
- /package/docs/{block.md → api/BLOCKS.md} +0 -0
- /package/docs/{ecies.md → api/ECIES.md} +0 -0
- /package/docs/{networks.md → api/NETWORKS.md} +0 -0
- /package/docs/{script.md → api/SCRIPTS.md} +0 -0
- /package/docs/{transaction.md → api/TRANSACTIONS.md} +0 -0
- /package/docs/{unspentoutput.md → api/UTXO.md} +0 -0
- /package/{test_shamir.js → tests/test_shamir.js} +0 -0
- /package/{test_standalone_shamir.html → tests/test_standalone_shamir.html} +0 -0
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 🌐 BSV Blockchain State Manager
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* Simulates a global blockchain state with multiple wallets and UTXO tracking.
|
|
5
5
|
* Acts as the "blockchain database" for our miner simulator.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
// Browser-compatible imports
|
|
9
|
-
let bsv, fs, path, BLOCKCHAIN_STATE_PATH
|
|
9
|
+
let bsv, fs, path, BLOCKCHAIN_STATE_PATH
|
|
10
10
|
|
|
11
11
|
// Only require Node.js modules in Node.js environment
|
|
12
12
|
if (typeof window === 'undefined' && typeof require === 'function') {
|
|
13
13
|
try {
|
|
14
|
-
bsv = require('../index.js')
|
|
15
|
-
fs = require('fs')
|
|
16
|
-
path = require('path')
|
|
17
|
-
BLOCKCHAIN_STATE_PATH = path.join(__dirname, 'blockchain-state.json')
|
|
14
|
+
// bsv = require('../index.js') // Currently unused
|
|
15
|
+
fs = require('fs')
|
|
16
|
+
path = require('path')
|
|
17
|
+
BLOCKCHAIN_STATE_PATH = path.join(__dirname, 'blockchain-state.json')
|
|
18
18
|
} catch (e) {
|
|
19
|
-
console.warn('BlockchainState: Running in browser mode - persistence disabled')
|
|
19
|
+
console.warn('BlockchainState: Running in browser mode - persistence disabled')
|
|
20
20
|
}
|
|
21
21
|
} else {
|
|
22
22
|
// In browser, try to get bsv from global scope or fallback
|
|
23
|
-
bsv = (typeof window !== 'undefined' && window.bsv) || require('../index.js')
|
|
23
|
+
bsv = (typeof window !== 'undefined' && window.bsv) || require('../index.js')
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* Initialize empty blockchain state
|
|
28
28
|
*/
|
|
29
|
-
function initializeBlockchainState() {
|
|
29
|
+
function initializeBlockchainState () {
|
|
30
30
|
return {
|
|
31
31
|
metadata: {
|
|
32
32
|
createdAt: new Date().toISOString(),
|
|
@@ -36,177 +36,177 @@ function initializeBlockchainState() {
|
|
|
36
36
|
totalValue: 0,
|
|
37
37
|
blockHeight: 0
|
|
38
38
|
},
|
|
39
|
-
wallets: {},
|
|
40
|
-
globalUTXOSet: {},
|
|
41
|
-
spentUTXOs: {},
|
|
39
|
+
wallets: {}, // keyed by address
|
|
40
|
+
globalUTXOSet: {}, // keyed by "txid:vout"
|
|
41
|
+
spentUTXOs: {}, // keyed by "txid:vout"
|
|
42
42
|
transactionHistory: []
|
|
43
|
-
}
|
|
43
|
+
}
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
47
|
* Load blockchain state from file
|
|
48
48
|
*/
|
|
49
|
-
function loadBlockchainState() {
|
|
49
|
+
function loadBlockchainState () {
|
|
50
50
|
try {
|
|
51
51
|
// In browser, use localStorage or return initial state
|
|
52
52
|
if (!fs || !BLOCKCHAIN_STATE_PATH) {
|
|
53
|
-
return initializeBlockchainState()
|
|
53
|
+
return initializeBlockchainState()
|
|
54
54
|
}
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
if (!fs.existsSync(BLOCKCHAIN_STATE_PATH)) {
|
|
57
|
-
console.log('🆕 Creating new blockchain state...')
|
|
58
|
-
const initialState = initializeBlockchainState()
|
|
59
|
-
saveBlockchainState(initialState)
|
|
60
|
-
return initialState
|
|
57
|
+
console.log('🆕 Creating new blockchain state...')
|
|
58
|
+
const initialState = initializeBlockchainState()
|
|
59
|
+
saveBlockchainState(initialState)
|
|
60
|
+
return initialState
|
|
61
61
|
}
|
|
62
|
-
|
|
63
|
-
const state = JSON.parse(fs.readFileSync(BLOCKCHAIN_STATE_PATH, 'utf8'))
|
|
64
|
-
console.log('📖 Loaded existing blockchain state')
|
|
65
|
-
return state
|
|
62
|
+
|
|
63
|
+
const state = JSON.parse(fs.readFileSync(BLOCKCHAIN_STATE_PATH, 'utf8'))
|
|
64
|
+
console.log('📖 Loaded existing blockchain state')
|
|
65
|
+
return state
|
|
66
66
|
} catch (error) {
|
|
67
|
-
console.error('❌ Error loading blockchain state:', error.message)
|
|
68
|
-
return initializeBlockchainState()
|
|
67
|
+
console.error('❌ Error loading blockchain state:', error.message)
|
|
68
|
+
return initializeBlockchainState()
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
/**
|
|
73
73
|
* Save blockchain state to file
|
|
74
74
|
*/
|
|
75
|
-
function saveBlockchainState(state) {
|
|
75
|
+
function saveBlockchainState (state) {
|
|
76
76
|
try {
|
|
77
|
-
state.metadata.lastUpdated = new Date().toISOString()
|
|
78
|
-
|
|
77
|
+
state.metadata.lastUpdated = new Date().toISOString()
|
|
78
|
+
|
|
79
79
|
// Only save to file in Node.js environment
|
|
80
80
|
if (fs && BLOCKCHAIN_STATE_PATH) {
|
|
81
|
-
fs.writeFileSync(BLOCKCHAIN_STATE_PATH, JSON.stringify(state, null, 2))
|
|
82
|
-
console.log('💾 Blockchain state saved')
|
|
81
|
+
fs.writeFileSync(BLOCKCHAIN_STATE_PATH, JSON.stringify(state, null, 2))
|
|
82
|
+
console.log('💾 Blockchain state saved')
|
|
83
83
|
}
|
|
84
84
|
} catch (error) {
|
|
85
|
-
console.error('❌ Error saving blockchain state:', error.message)
|
|
85
|
+
console.error('❌ Error saving blockchain state:', error.message)
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
/**
|
|
90
90
|
* Register a new wallet in the blockchain state
|
|
91
91
|
*/
|
|
92
|
-
function registerWallet(walletAddress, walletData) {
|
|
93
|
-
console.log(`📝 Registering wallet: ${walletAddress}`)
|
|
94
|
-
|
|
95
|
-
const state = loadBlockchainState()
|
|
96
|
-
|
|
92
|
+
function registerWallet (walletAddress, walletData) {
|
|
93
|
+
console.log(`📝 Registering wallet: ${walletAddress}`)
|
|
94
|
+
|
|
95
|
+
const state = loadBlockchainState()
|
|
96
|
+
|
|
97
97
|
if (state.wallets[walletAddress]) {
|
|
98
|
-
console.log('ℹ️ Wallet already exists, updating...')
|
|
98
|
+
console.log('ℹ️ Wallet already exists, updating...')
|
|
99
99
|
}
|
|
100
|
-
|
|
100
|
+
|
|
101
101
|
state.wallets[walletAddress] = {
|
|
102
102
|
address: walletAddress,
|
|
103
103
|
registeredAt: walletData.registeredAt || new Date().toISOString(),
|
|
104
104
|
utxos: walletData.utxos || [],
|
|
105
105
|
totalValue: 0
|
|
106
|
-
}
|
|
107
|
-
|
|
106
|
+
}
|
|
107
|
+
|
|
108
108
|
// Add UTXOs to global set
|
|
109
109
|
if (walletData.utxos) {
|
|
110
110
|
walletData.utxos.forEach(utxo => {
|
|
111
|
-
const utxoKey = `${utxo.txid}:${utxo.vout}
|
|
111
|
+
const utxoKey = `${utxo.txid}:${utxo.vout}`
|
|
112
112
|
state.globalUTXOSet[utxoKey] = {
|
|
113
113
|
...utxo,
|
|
114
114
|
ownerAddress: walletAddress
|
|
115
|
-
}
|
|
116
|
-
})
|
|
115
|
+
}
|
|
116
|
+
})
|
|
117
117
|
}
|
|
118
|
-
|
|
118
|
+
|
|
119
119
|
// Update metadata
|
|
120
|
-
state.metadata.totalWallets = Object.keys(state.wallets).length
|
|
121
|
-
updateBlockchainMetadata(state)
|
|
122
|
-
|
|
123
|
-
saveBlockchainState(state)
|
|
124
|
-
|
|
125
|
-
console.log(`✅ Wallet registered: ${walletAddress}`)
|
|
126
|
-
return state
|
|
120
|
+
state.metadata.totalWallets = Object.keys(state.wallets).length
|
|
121
|
+
updateBlockchainMetadata(state)
|
|
122
|
+
|
|
123
|
+
saveBlockchainState(state)
|
|
124
|
+
|
|
125
|
+
console.log(`✅ Wallet registered: ${walletAddress}`)
|
|
126
|
+
return state
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
/**
|
|
130
130
|
* Get UTXO by key (txid:vout)
|
|
131
131
|
*/
|
|
132
|
-
function getUTXO(txid, vout) {
|
|
133
|
-
const state = loadBlockchainState()
|
|
134
|
-
const utxoKey = `${txid}:${vout}
|
|
135
|
-
|
|
132
|
+
function getUTXO (txid, vout) {
|
|
133
|
+
const state = loadBlockchainState()
|
|
134
|
+
const utxoKey = `${txid}:${vout}`
|
|
135
|
+
|
|
136
136
|
if (state.spentUTXOs[utxoKey]) {
|
|
137
|
-
return { exists: false, spent: true, utxo: state.spentUTXOs[utxoKey] }
|
|
137
|
+
return { exists: false, spent: true, utxo: state.spentUTXOs[utxoKey] }
|
|
138
138
|
}
|
|
139
|
-
|
|
139
|
+
|
|
140
140
|
if (state.globalUTXOSet[utxoKey]) {
|
|
141
|
-
return { exists: true, spent: false, utxo: state.globalUTXOSet[utxoKey] }
|
|
141
|
+
return { exists: true, spent: false, utxo: state.globalUTXOSet[utxoKey] }
|
|
142
142
|
}
|
|
143
|
-
|
|
144
|
-
return { exists: false, spent: false, utxo: null }
|
|
143
|
+
|
|
144
|
+
return { exists: false, spent: false, utxo: null }
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
/**
|
|
148
148
|
* Check if UTXO exists and is unspent
|
|
149
149
|
*/
|
|
150
|
-
function isUTXOAvailable(txid, vout) {
|
|
151
|
-
const result = getUTXO(txid, vout)
|
|
152
|
-
return result.exists && !result.spent
|
|
150
|
+
function isUTXOAvailable (txid, vout) {
|
|
151
|
+
const result = getUTXO(txid, vout)
|
|
152
|
+
return result.exists && !result.spent
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
/**
|
|
156
156
|
* Spend a UTXO (move from available to spent)
|
|
157
157
|
*/
|
|
158
|
-
function spendUTXO(txid, vout, spentInTx) {
|
|
159
|
-
const state = loadBlockchainState()
|
|
160
|
-
const utxoKey = `${txid}:${vout}
|
|
161
|
-
|
|
158
|
+
function spendUTXO (txid, vout, spentInTx) {
|
|
159
|
+
const state = loadBlockchainState()
|
|
160
|
+
const utxoKey = `${txid}:${vout}`
|
|
161
|
+
|
|
162
162
|
if (!state.globalUTXOSet[utxoKey]) {
|
|
163
|
-
throw new Error(`UTXO ${utxoKey} does not exist`)
|
|
163
|
+
throw new Error(`UTXO ${utxoKey} does not exist`)
|
|
164
164
|
}
|
|
165
|
-
|
|
165
|
+
|
|
166
166
|
if (state.spentUTXOs[utxoKey]) {
|
|
167
|
-
throw new Error(`UTXO ${utxoKey} already spent`)
|
|
167
|
+
throw new Error(`UTXO ${utxoKey} already spent`)
|
|
168
168
|
}
|
|
169
|
-
|
|
169
|
+
|
|
170
170
|
// Move UTXO from available to spent
|
|
171
|
-
const utxo = state.globalUTXOSet[utxoKey]
|
|
171
|
+
const utxo = state.globalUTXOSet[utxoKey]
|
|
172
172
|
state.spentUTXOs[utxoKey] = {
|
|
173
173
|
...utxo,
|
|
174
174
|
spentInTx,
|
|
175
175
|
spentAt: new Date().toISOString()
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
delete state.globalUTXOSet[utxoKey]
|
|
179
|
-
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
delete state.globalUTXOSet[utxoKey]
|
|
179
|
+
|
|
180
180
|
// Update wallet's UTXO list
|
|
181
|
-
const wallet = state.wallets[utxo.ownerAddress]
|
|
181
|
+
const wallet = state.wallets[utxo.ownerAddress]
|
|
182
182
|
if (wallet) {
|
|
183
|
-
wallet.utxos = wallet.utxos.filter(u => !(u.txid === txid && u.vout === vout))
|
|
183
|
+
wallet.utxos = wallet.utxos.filter(u => !(u.txid === txid && u.vout === vout))
|
|
184
184
|
}
|
|
185
|
-
|
|
186
|
-
updateBlockchainMetadata(state)
|
|
187
|
-
saveBlockchainState(state)
|
|
188
|
-
console.log(`❌ UTXO spent: ${utxoKey} in tx ${spentInTx}`)
|
|
185
|
+
|
|
186
|
+
updateBlockchainMetadata(state)
|
|
187
|
+
saveBlockchainState(state)
|
|
188
|
+
console.log(`❌ UTXO spent: ${utxoKey} in tx ${spentInTx}`)
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
/**
|
|
192
192
|
* Add new UTXO to the global set
|
|
193
193
|
*/
|
|
194
|
-
function addUTXO(utxo, ownerAddress) {
|
|
195
|
-
const state = loadBlockchainState()
|
|
196
|
-
const utxoKey = `${utxo.txid}:${utxo.vout}
|
|
197
|
-
|
|
194
|
+
function addUTXO (utxo, ownerAddress) {
|
|
195
|
+
const state = loadBlockchainState()
|
|
196
|
+
const utxoKey = `${utxo.txid}:${utxo.vout}`
|
|
197
|
+
|
|
198
198
|
// Check if UTXO already exists
|
|
199
199
|
if (state.globalUTXOSet[utxoKey]) {
|
|
200
|
-
console.log(`⚠️ UTXO ${utxoKey} already exists, skipping`)
|
|
201
|
-
return
|
|
200
|
+
console.log(`⚠️ UTXO ${utxoKey} already exists, skipping`)
|
|
201
|
+
return
|
|
202
202
|
}
|
|
203
|
-
|
|
203
|
+
|
|
204
204
|
state.globalUTXOSet[utxoKey] = {
|
|
205
205
|
...utxo,
|
|
206
206
|
ownerAddress,
|
|
207
207
|
createdAt: new Date().toISOString()
|
|
208
|
-
}
|
|
209
|
-
|
|
208
|
+
}
|
|
209
|
+
|
|
210
210
|
// Add to wallet's UTXO list
|
|
211
211
|
if (!state.wallets[ownerAddress]) {
|
|
212
212
|
state.wallets[ownerAddress] = {
|
|
@@ -214,109 +214,109 @@ function addUTXO(utxo, ownerAddress) {
|
|
|
214
214
|
registeredAt: new Date().toISOString(),
|
|
215
215
|
utxos: [],
|
|
216
216
|
totalValue: 0
|
|
217
|
-
}
|
|
217
|
+
}
|
|
218
218
|
}
|
|
219
|
-
|
|
219
|
+
|
|
220
220
|
// Check if UTXO already exists in wallet's list
|
|
221
|
-
const exists = state.wallets[ownerAddress].utxos.some(existingUTXO =>
|
|
221
|
+
const exists = state.wallets[ownerAddress].utxos.some(existingUTXO =>
|
|
222
222
|
existingUTXO.txid === utxo.txid && existingUTXO.vout === utxo.vout
|
|
223
|
-
)
|
|
224
|
-
|
|
223
|
+
)
|
|
224
|
+
|
|
225
225
|
if (!exists) {
|
|
226
|
-
state.wallets[ownerAddress].utxos.push(utxo)
|
|
226
|
+
state.wallets[ownerAddress].utxos.push(utxo)
|
|
227
227
|
}
|
|
228
|
-
|
|
229
|
-
updateBlockchainMetadata(state)
|
|
230
|
-
saveBlockchainState(state)
|
|
231
|
-
|
|
232
|
-
console.log(`✅ UTXO added: ${utxoKey} for ${ownerAddress}`)
|
|
228
|
+
|
|
229
|
+
updateBlockchainMetadata(state)
|
|
230
|
+
saveBlockchainState(state)
|
|
231
|
+
|
|
232
|
+
console.log(`✅ UTXO added: ${utxoKey} for ${ownerAddress}`)
|
|
233
233
|
}
|
|
234
234
|
|
|
235
235
|
/**
|
|
236
236
|
* Update blockchain metadata
|
|
237
237
|
*/
|
|
238
|
-
function updateBlockchainMetadata(state) {
|
|
239
|
-
const totalUTXOs = Object.keys(state.globalUTXOSet).length
|
|
238
|
+
function updateBlockchainMetadata (state) {
|
|
239
|
+
const totalUTXOs = Object.keys(state.globalUTXOSet).length
|
|
240
240
|
const totalValue = Object.values(state.globalUTXOSet)
|
|
241
|
-
.reduce((sum, utxo) => sum + utxo.satoshis, 0)
|
|
242
|
-
|
|
243
|
-
state.metadata.totalUTXOs = totalUTXOs
|
|
244
|
-
state.metadata.totalValue = totalValue
|
|
245
|
-
|
|
241
|
+
.reduce((sum, utxo) => sum + utxo.satoshis, 0)
|
|
242
|
+
|
|
243
|
+
state.metadata.totalUTXOs = totalUTXOs
|
|
244
|
+
state.metadata.totalValue = totalValue
|
|
245
|
+
|
|
246
246
|
// Update wallet totals
|
|
247
247
|
Object.values(state.wallets).forEach(wallet => {
|
|
248
|
-
wallet.totalValue = wallet.utxos.reduce((sum, utxo) => sum + utxo.satoshis, 0)
|
|
249
|
-
})
|
|
248
|
+
wallet.totalValue = wallet.utxos.reduce((sum, utxo) => sum + utxo.satoshis, 0)
|
|
249
|
+
})
|
|
250
250
|
}
|
|
251
251
|
|
|
252
252
|
/**
|
|
253
253
|
* Get blockchain statistics
|
|
254
254
|
*/
|
|
255
|
-
function getBlockchainStats() {
|
|
256
|
-
const state = loadBlockchainState()
|
|
257
|
-
|
|
258
|
-
console.log('🌐 Blockchain State Statistics:')
|
|
259
|
-
console.log('═══════════════════════════════════════════')
|
|
260
|
-
console.log(`📊 Total Wallets: ${state.metadata.totalWallets}`)
|
|
261
|
-
console.log(`💰 Total UTXOs: ${state.metadata.totalUTXOs}`)
|
|
262
|
-
console.log(`💎 Total Value: ${state.metadata.totalValue} satoshis`)
|
|
263
|
-
console.log(`🏗️ Block Height: ${state.metadata.blockHeight}`)
|
|
264
|
-
console.log(`🕐 Last Updated: ${state.metadata.lastUpdated}\n`)
|
|
265
|
-
|
|
255
|
+
function getBlockchainStats () {
|
|
256
|
+
const state = loadBlockchainState()
|
|
257
|
+
|
|
258
|
+
console.log('🌐 Blockchain State Statistics:')
|
|
259
|
+
console.log('═══════════════════════════════════════════')
|
|
260
|
+
console.log(`📊 Total Wallets: ${state.metadata.totalWallets}`)
|
|
261
|
+
console.log(`💰 Total UTXOs: ${state.metadata.totalUTXOs}`)
|
|
262
|
+
console.log(`💎 Total Value: ${state.metadata.totalValue} satoshis`)
|
|
263
|
+
console.log(`🏗️ Block Height: ${state.metadata.blockHeight}`)
|
|
264
|
+
console.log(`🕐 Last Updated: ${state.metadata.lastUpdated}\n`)
|
|
265
|
+
|
|
266
266
|
if (Object.keys(state.wallets).length > 0) {
|
|
267
|
-
console.log('👛 Registered Wallets:')
|
|
267
|
+
console.log('👛 Registered Wallets:')
|
|
268
268
|
Object.entries(state.wallets).forEach(([address, wallet]) => {
|
|
269
|
-
console.log(` ${address}: ${wallet.utxos.length} UTXOs, ${wallet.totalValue} sats`)
|
|
270
|
-
})
|
|
269
|
+
console.log(` ${address}: ${wallet.utxos.length} UTXOs, ${wallet.totalValue} sats`)
|
|
270
|
+
})
|
|
271
271
|
}
|
|
272
|
-
|
|
273
|
-
return state
|
|
272
|
+
|
|
273
|
+
return state
|
|
274
274
|
}
|
|
275
275
|
|
|
276
276
|
/**
|
|
277
277
|
* Import existing wallet from wallet.json
|
|
278
278
|
*/
|
|
279
|
-
function importWalletFromFile() {
|
|
280
|
-
const walletPath = path.join(__dirname, 'wallet.json')
|
|
281
|
-
|
|
279
|
+
function importWalletFromFile () {
|
|
280
|
+
const walletPath = path.join(__dirname, 'wallet.json')
|
|
281
|
+
|
|
282
282
|
if (!fs.existsSync(walletPath)) {
|
|
283
|
-
console.log('❌ No wallet.json found to import')
|
|
284
|
-
return false
|
|
283
|
+
console.log('❌ No wallet.json found to import')
|
|
284
|
+
return false
|
|
285
285
|
}
|
|
286
|
-
|
|
286
|
+
|
|
287
287
|
try {
|
|
288
|
-
const walletData = JSON.parse(fs.readFileSync(walletPath, 'utf8'))
|
|
289
|
-
|
|
290
|
-
console.log('📥 Importing wallet from wallet.json...')
|
|
291
|
-
|
|
288
|
+
const walletData = JSON.parse(fs.readFileSync(walletPath, 'utf8'))
|
|
289
|
+
|
|
290
|
+
console.log('📥 Importing wallet from wallet.json...')
|
|
291
|
+
|
|
292
292
|
const walletInfo = {
|
|
293
293
|
registeredAt: new Date().toISOString(),
|
|
294
294
|
utxos: walletData.availableUTXOs || [walletData.utxo]
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
registerWallet(walletData.wallet.address, walletInfo)
|
|
298
|
-
|
|
299
|
-
console.log('✅ Wallet imported successfully')
|
|
300
|
-
return true
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
registerWallet(walletData.wallet.address, walletInfo)
|
|
298
|
+
|
|
299
|
+
console.log('✅ Wallet imported successfully')
|
|
300
|
+
return true
|
|
301
301
|
} catch (error) {
|
|
302
|
-
console.error('❌ Error importing wallet:', error.message)
|
|
303
|
-
return false
|
|
302
|
+
console.error('❌ Error importing wallet:', error.message)
|
|
303
|
+
return false
|
|
304
304
|
}
|
|
305
305
|
}
|
|
306
306
|
|
|
307
307
|
// If called directly, show stats or import wallet
|
|
308
308
|
if (require.main === module) {
|
|
309
|
-
const args = process.argv.slice(2)
|
|
310
|
-
|
|
309
|
+
const args = process.argv.slice(2)
|
|
310
|
+
|
|
311
311
|
if (args[0] === 'import') {
|
|
312
|
-
importWalletFromFile()
|
|
312
|
+
importWalletFromFile()
|
|
313
313
|
} else if (args[0] === 'init') {
|
|
314
|
-
const state = initializeBlockchainState()
|
|
315
|
-
saveBlockchainState(state)
|
|
316
|
-
console.log('🆕 Initialized new blockchain state')
|
|
314
|
+
const state = initializeBlockchainState()
|
|
315
|
+
saveBlockchainState(state)
|
|
316
|
+
console.log('🆕 Initialized new blockchain state')
|
|
317
317
|
}
|
|
318
|
-
|
|
319
|
-
getBlockchainStats()
|
|
318
|
+
|
|
319
|
+
getBlockchainStats()
|
|
320
320
|
}
|
|
321
321
|
|
|
322
322
|
module.exports = {
|
|
@@ -329,4 +329,4 @@ module.exports = {
|
|
|
329
329
|
addUTXO,
|
|
330
330
|
getBlockchainStats,
|
|
331
331
|
importWalletFromFile
|
|
332
|
-
}
|
|
332
|
+
}
|