@bsv/sdk 1.9.2 → 1.9.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/dist/cjs/package.json +1 -1
- package/dist/cjs/src/kvstore/GlobalKVStore.js +116 -98
- package/dist/cjs/src/kvstore/GlobalKVStore.js.map +1 -1
- package/dist/cjs/src/kvstore/types.js.map +1 -1
- package/dist/cjs/src/overlay-tools/index.js +1 -0
- package/dist/cjs/src/overlay-tools/index.js.map +1 -1
- package/dist/cjs/src/overlay-tools/withDoubleSpendRetry.js +55 -0
- package/dist/cjs/src/overlay-tools/withDoubleSpendRetry.js.map +1 -0
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/kvstore/GlobalKVStore.js +117 -99
- package/dist/esm/src/kvstore/GlobalKVStore.js.map +1 -1
- package/dist/esm/src/kvstore/types.js.map +1 -1
- package/dist/esm/src/overlay-tools/index.js +1 -0
- package/dist/esm/src/overlay-tools/index.js.map +1 -1
- package/dist/esm/src/overlay-tools/withDoubleSpendRetry.js +48 -0
- package/dist/esm/src/overlay-tools/withDoubleSpendRetry.js.map +1 -0
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/kvstore/GlobalKVStore.d.ts.map +1 -1
- package/dist/types/src/kvstore/types.d.ts +2 -0
- package/dist/types/src/kvstore/types.d.ts.map +1 -1
- package/dist/types/src/overlay-tools/index.d.ts +1 -0
- package/dist/types/src/overlay-tools/index.d.ts.map +1 -1
- package/dist/types/src/overlay-tools/withDoubleSpendRetry.d.ts +14 -0
- package/dist/types/src/overlay-tools/withDoubleSpendRetry.d.ts.map +1 -0
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/dist/umd/bundle.js +2 -2
- package/dist/umd/bundle.js.map +1 -1
- package/docs/fast-docs.png +0 -0
- package/docs/index.md +49 -44
- package/docs/reference/kvstore.md +9 -0
- package/docs/reference/overlay-tools.md +32 -0
- package/docs/swagger.png +0 -0
- package/package.json +1 -1
- package/src/kvstore/GlobalKVStore.ts +134 -114
- package/src/kvstore/__tests/GlobalKVStore.test.ts +11 -1
- package/src/kvstore/types.ts +2 -0
- package/src/overlay-tools/index.ts +1 -0
- package/src/overlay-tools/withDoubleSpendRetry.ts +71 -0
- package/docs/MARKDOWN_VALIDATION_GUIDE.md +0 -175
- package/docs/concepts/beef.md +0 -92
- package/docs/concepts/chain-tracking.md +0 -134
- package/docs/concepts/decentralized-identity.md +0 -221
- package/docs/concepts/fees.md +0 -249
- package/docs/concepts/identity-certificates.md +0 -307
- package/docs/concepts/index.md +0 -77
- package/docs/concepts/key-management.md +0 -185
- package/docs/concepts/script-templates.md +0 -176
- package/docs/concepts/sdk-philosophy.md +0 -80
- package/docs/concepts/signatures.md +0 -194
- package/docs/concepts/spv-verification.md +0 -118
- package/docs/concepts/transaction-encoding.md +0 -167
- package/docs/concepts/transaction-structure.md +0 -67
- package/docs/concepts/trust-model.md +0 -139
- package/docs/concepts/verification.md +0 -250
- package/docs/concepts/wallet-integration.md +0 -101
- package/docs/guides/development-wallet-setup.md +0 -374
- package/docs/guides/direct-transaction-creation.md +0 -147
- package/docs/guides/http-client-configuration.md +0 -488
- package/docs/guides/index.md +0 -138
- package/docs/guides/large-transactions.md +0 -448
- package/docs/guides/multisig-transactions.md +0 -792
- package/docs/guides/security-best-practices.md +0 -494
- package/docs/guides/transaction-batching.md +0 -132
- package/docs/guides/transaction-signing-methods.md +0 -419
- package/docs/reference/arc-config.md +0 -698
- package/docs/reference/brc-100.md +0 -33
- package/docs/reference/configuration.md +0 -835
- package/docs/reference/debugging.md +0 -705
- package/docs/reference/errors.md +0 -597
- package/docs/reference/index.md +0 -111
- package/docs/reference/network-config.md +0 -914
- package/docs/reference/op-codes.md +0 -325
- package/docs/reference/transaction-signatures.md +0 -95
- package/docs/tutorials/advanced-transaction.md +0 -572
- package/docs/tutorials/aes-encryption.md +0 -949
- package/docs/tutorials/authfetch-tutorial.md +0 -986
- package/docs/tutorials/ecdh-key-exchange.md +0 -549
- package/docs/tutorials/elliptic-curve-fundamentals.md +0 -606
- package/docs/tutorials/error-handling.md +0 -1216
- package/docs/tutorials/first-transaction-low-level.md +0 -205
- package/docs/tutorials/first-transaction.md +0 -275
- package/docs/tutorials/hashes-and-hmacs.md +0 -788
- package/docs/tutorials/identity-management.md +0 -729
- package/docs/tutorials/index.md +0 -219
- package/docs/tutorials/key-management.md +0 -538
- package/docs/tutorials/protowallet-development.md +0 -743
- package/docs/tutorials/script-construction.md +0 -690
- package/docs/tutorials/spv-merkle-proofs.md +0 -685
- package/docs/tutorials/testnet-transactions-low-level.md +0 -359
- package/docs/tutorials/transaction-broadcasting.md +0 -538
- package/docs/tutorials/transaction-types.md +0 -420
- package/docs/tutorials/type-42.md +0 -568
- package/docs/tutorials/uhrp-storage.md +0 -599
|
@@ -1,705 +0,0 @@
|
|
|
1
|
-
# Debugging Reference
|
|
2
|
-
|
|
3
|
-
Complete guide for debugging, logging, and troubleshooting applications built with the BSV TypeScript SDK.
|
|
4
|
-
|
|
5
|
-
## Debug Mode Activation
|
|
6
|
-
|
|
7
|
-
### Environment Variables
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
# Enable debug mode
|
|
11
|
-
export BSV_DEBUG=true
|
|
12
|
-
|
|
13
|
-
# Set debug level
|
|
14
|
-
export BSV_DEBUG_LEVEL=debug
|
|
15
|
-
|
|
16
|
-
# Enable specific debug categories
|
|
17
|
-
export BSV_DEBUG_CATEGORIES=wallet,transaction,network
|
|
18
|
-
|
|
19
|
-
# Enable performance debugging
|
|
20
|
-
export BSV_DEBUG_PERFORMANCE=true
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
### Programmatic Debug Configuration
|
|
24
|
-
|
|
25
|
-
```typescript
|
|
26
|
-
import { SDKConfigBuilder } from '@bsv/sdk'
|
|
27
|
-
|
|
28
|
-
const debugConfig = new SDKConfigBuilder()
|
|
29
|
-
.logging({
|
|
30
|
-
level: 'debug',
|
|
31
|
-
outputs: [
|
|
32
|
-
{ type: 'console', config: {} },
|
|
33
|
-
{ type: 'file', config: { file: './debug.log' } }
|
|
34
|
-
],
|
|
35
|
-
format: {
|
|
36
|
-
timestamp: true,
|
|
37
|
-
level: true,
|
|
38
|
-
component: true,
|
|
39
|
-
structured: true,
|
|
40
|
-
colors: true
|
|
41
|
-
},
|
|
42
|
-
performance: {
|
|
43
|
-
enabled: true,
|
|
44
|
-
threshold: 100, // Log operations taking >100ms
|
|
45
|
-
includeStackTrace: true
|
|
46
|
-
}
|
|
47
|
-
})
|
|
48
|
-
.build()
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
## SDK Logging System
|
|
52
|
-
|
|
53
|
-
### Log Levels
|
|
54
|
-
|
|
55
|
-
```typescript
|
|
56
|
-
enum LogLevel {
|
|
57
|
-
ERROR = 0, // Critical errors only
|
|
58
|
-
WARN = 1, // Warnings and errors
|
|
59
|
-
INFO = 2, // General information
|
|
60
|
-
DEBUG = 3, // Detailed debugging info
|
|
61
|
-
TRACE = 4 // Extremely verbose tracing
|
|
62
|
-
}
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### Logger Interface
|
|
66
|
-
|
|
67
|
-
```typescript
|
|
68
|
-
interface Logger {
|
|
69
|
-
error(message: string, context?: any): void
|
|
70
|
-
warn(message: string, context?: any): void
|
|
71
|
-
info(message: string, context?: any): void
|
|
72
|
-
debug(message: string, context?: any): void
|
|
73
|
-
trace(message: string, context?: any): void
|
|
74
|
-
|
|
75
|
-
// Performance logging
|
|
76
|
-
time(label: string): void
|
|
77
|
-
timeEnd(label: string): void
|
|
78
|
-
|
|
79
|
-
// Structured logging
|
|
80
|
-
log(level: LogLevel, message: string, context: any): void
|
|
81
|
-
}
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
### Creating Custom Loggers
|
|
85
|
-
|
|
86
|
-
```typescript
|
|
87
|
-
class CustomLogger implements Logger {
|
|
88
|
-
private level: LogLevel = LogLevel.INFO
|
|
89
|
-
|
|
90
|
-
constructor(level: LogLevel = LogLevel.INFO) {
|
|
91
|
-
this.level = level
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
error(message: string, context?: any): void {
|
|
95
|
-
if (this.level >= LogLevel.ERROR) {
|
|
96
|
-
console.error(`[ERROR] ${new Date().toISOString()} ${message}`, context)
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
warn(message: string, context?: any): void {
|
|
101
|
-
if (this.level >= LogLevel.WARN) {
|
|
102
|
-
console.warn(`[WARN] ${new Date().toISOString()} ${message}`, context)
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
info(message: string, context?: any): void {
|
|
107
|
-
if (this.level >= LogLevel.INFO) {
|
|
108
|
-
console.info(`[INFO] ${new Date().toISOString()} ${message}`, context)
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
debug(message: string, context?: any): void {
|
|
113
|
-
if (this.level >= LogLevel.DEBUG) {
|
|
114
|
-
console.debug(`[DEBUG] ${new Date().toISOString()} ${message}`, context)
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
trace(message: string, context?: any): void {
|
|
119
|
-
if (this.level >= LogLevel.TRACE) {
|
|
120
|
-
console.trace(`[TRACE] ${new Date().toISOString()} ${message}`, context)
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
time(label: string): void {
|
|
125
|
-
console.time(label)
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
timeEnd(label: string): void {
|
|
129
|
-
console.timeEnd(label)
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
log(level: LogLevel, message: string, context: any): void {
|
|
133
|
-
const methods = [this.error, this.warn, this.info, this.debug, this.trace]
|
|
134
|
-
methods[level]?.call(this, message, context)
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
## Debug Categories
|
|
140
|
-
|
|
141
|
-
### Wallet Debugging
|
|
142
|
-
|
|
143
|
-
```typescript
|
|
144
|
-
// Enable wallet debugging
|
|
145
|
-
const walletDebugger = {
|
|
146
|
-
logConnection: (substrate: string, status: string) => {
|
|
147
|
-
console.debug(`[WALLET] Connection ${status} to ${substrate}`)
|
|
148
|
-
},
|
|
149
|
-
|
|
150
|
-
logAction: (action: string, args: any) => {
|
|
151
|
-
console.debug(`[WALLET] Action: ${action}`, {
|
|
152
|
-
args: JSON.stringify(args, null, 2),
|
|
153
|
-
timestamp: new Date().toISOString()
|
|
154
|
-
})
|
|
155
|
-
},
|
|
156
|
-
|
|
157
|
-
logError: (error: any, context: any) => {
|
|
158
|
-
console.error(`[WALLET] Error:`, {
|
|
159
|
-
error: error.message,
|
|
160
|
-
code: error.code,
|
|
161
|
-
context,
|
|
162
|
-
stack: error.stack
|
|
163
|
-
})
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// Usage in wallet operations
|
|
168
|
-
try {
|
|
169
|
-
walletDebugger.logAction('createAction', { description: 'Test transaction' })
|
|
170
|
-
const result = await wallet.createAction({
|
|
171
|
-
description: 'Test transaction',
|
|
172
|
-
outputs: [{ satoshis: 100, lockingScript: '...' }]
|
|
173
|
-
})
|
|
174
|
-
walletDebugger.logConnection('substrate', 'success')
|
|
175
|
-
} catch (error) {
|
|
176
|
-
walletDebugger.logError(error, { operation: 'createAction' })
|
|
177
|
-
}
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
### Transaction Debugging
|
|
181
|
-
|
|
182
|
-
```typescript
|
|
183
|
-
class TransactionDebugger {
|
|
184
|
-
static logConstruction(tx: Transaction): void {
|
|
185
|
-
console.debug(`[TRANSACTION] Construction:`, {
|
|
186
|
-
inputs: tx.inputs.length,
|
|
187
|
-
outputs: tx.outputs.length,
|
|
188
|
-
totalInput: tx.inputs.reduce((sum, input) => sum + input.satoshis, 0),
|
|
189
|
-
totalOutput: tx.outputs.reduce((sum, output) => sum + output.satoshis, 0),
|
|
190
|
-
fee: tx.getFee(),
|
|
191
|
-
size: tx.toHex().length / 2,
|
|
192
|
-
txid: Buffer.from(tx.id()).toString('hex')
|
|
193
|
-
})
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
static logSigning(tx: Transaction, inputIndex: number): void {
|
|
197
|
-
console.debug(`[TRANSACTION] Signing input ${inputIndex}:`, {
|
|
198
|
-
txid: Buffer.from(tx.id()).toString('hex'),
|
|
199
|
-
input: {
|
|
200
|
-
sourceTXID: tx.inputs[inputIndex].sourceTXID,
|
|
201
|
-
sourceOutputIndex: tx.inputs[inputIndex].sourceOutputIndex,
|
|
202
|
-
unlockingScript: tx.inputs[inputIndex].unlockingScript?.toASM()
|
|
203
|
-
}
|
|
204
|
-
})
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
static logValidation(tx: Transaction, isValid: boolean, errors?: string[]): void {
|
|
208
|
-
console.debug(`[TRANSACTION] Validation:`, {
|
|
209
|
-
txid: Buffer.from(tx.id()).toString('hex'),
|
|
210
|
-
valid: isValid,
|
|
211
|
-
errors: errors || [],
|
|
212
|
-
timestamp: new Date().toISOString()
|
|
213
|
-
})
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
### Network Debugging
|
|
219
|
-
|
|
220
|
-
```typescript
|
|
221
|
-
class NetworkDebugger {
|
|
222
|
-
static logRequest(endpoint: string, method: string, data?: any): void {
|
|
223
|
-
console.debug(`[NETWORK] Request:`, {
|
|
224
|
-
endpoint,
|
|
225
|
-
method,
|
|
226
|
-
data: data ? JSON.stringify(data) : undefined,
|
|
227
|
-
timestamp: new Date().toISOString()
|
|
228
|
-
})
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
static logResponse(endpoint: string, status: number, data?: any): void {
|
|
232
|
-
console.debug(`[NETWORK] Response:`, {
|
|
233
|
-
endpoint,
|
|
234
|
-
status,
|
|
235
|
-
dataSize: data ? JSON.stringify(data).length : 0,
|
|
236
|
-
timestamp: new Date().toISOString()
|
|
237
|
-
})
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
static logError(endpoint: string, error: any): void {
|
|
241
|
-
console.error(`[NETWORK] Error:`, {
|
|
242
|
-
endpoint,
|
|
243
|
-
error: error.message,
|
|
244
|
-
code: error.code,
|
|
245
|
-
stack: error.stack,
|
|
246
|
-
timestamp: new Date().toISOString()
|
|
247
|
-
})
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
## Transaction Inspection Tools
|
|
253
|
-
|
|
254
|
-
### Transaction Analyzer
|
|
255
|
-
|
|
256
|
-
```typescript
|
|
257
|
-
class TransactionAnalyzer {
|
|
258
|
-
static analyze(tx: Transaction): TransactionAnalysis {
|
|
259
|
-
const analysis: TransactionAnalysis = {
|
|
260
|
-
basic: this.analyzeBasic(tx),
|
|
261
|
-
inputs: this.analyzeInputs(tx),
|
|
262
|
-
outputs: this.analyzeOutputs(tx),
|
|
263
|
-
scripts: this.analyzeScripts(tx),
|
|
264
|
-
fees: this.analyzeFees(tx),
|
|
265
|
-
size: this.analyzeSize(tx)
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
return analysis
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
private static analyzeBasic(tx: Transaction): BasicAnalysis {
|
|
272
|
-
return {
|
|
273
|
-
txid: Buffer.from(tx.id()).toString('hex'),
|
|
274
|
-
version: tx.version,
|
|
275
|
-
lockTime: tx.lockTime,
|
|
276
|
-
inputCount: tx.inputs.length,
|
|
277
|
-
outputCount: tx.outputs.length
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
private static analyzeInputs(tx: Transaction): InputAnalysis[] {
|
|
282
|
-
return tx.inputs.map((input, index) => ({
|
|
283
|
-
index,
|
|
284
|
-
sourceTXID: input.sourceTXID,
|
|
285
|
-
sourceOutputIndex: input.sourceOutputIndex,
|
|
286
|
-
satoshis: input.satoshis,
|
|
287
|
-
unlockingScript: {
|
|
288
|
-
asm: input.unlockingScript?.toASM(),
|
|
289
|
-
hex: input.unlockingScript?.toHex(),
|
|
290
|
-
size: input.unlockingScript?.toHex().length / 2
|
|
291
|
-
},
|
|
292
|
-
sequence: input.sequence
|
|
293
|
-
}))
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
private static analyzeOutputs(tx: Transaction): OutputAnalysis[] {
|
|
297
|
-
return tx.outputs.map((output, index) => ({
|
|
298
|
-
index,
|
|
299
|
-
satoshis: output.satoshis,
|
|
300
|
-
lockingScript: {
|
|
301
|
-
asm: output.lockingScript.toASM(),
|
|
302
|
-
hex: output.lockingScript.toHex(),
|
|
303
|
-
size: output.lockingScript.toHex().length / 2,
|
|
304
|
-
type: this.detectScriptType(output.lockingScript)
|
|
305
|
-
}
|
|
306
|
-
}))
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
private static detectScriptType(script: Script): string {
|
|
310
|
-
const asm = script.toASM()
|
|
311
|
-
|
|
312
|
-
if (asm.includes('OP_DUP OP_HASH160') && asm.includes('OP_EQUALVERIFY OP_CHECKSIG')) {
|
|
313
|
-
return 'P2PKH'
|
|
314
|
-
} else if (asm.includes('OP_HASH160') && asm.includes('OP_EQUAL')) {
|
|
315
|
-
return 'P2SH'
|
|
316
|
-
} else if (asm.startsWith('OP_RETURN')) {
|
|
317
|
-
return 'OP_RETURN'
|
|
318
|
-
} else {
|
|
319
|
-
return 'CUSTOM'
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
interface TransactionAnalysis {
|
|
325
|
-
basic: BasicAnalysis
|
|
326
|
-
inputs: InputAnalysis[]
|
|
327
|
-
outputs: OutputAnalysis[]
|
|
328
|
-
scripts: ScriptAnalysis
|
|
329
|
-
fees: FeeAnalysis
|
|
330
|
-
size: SizeAnalysis
|
|
331
|
-
}
|
|
332
|
-
```
|
|
333
|
-
|
|
334
|
-
### Script Debugger
|
|
335
|
-
|
|
336
|
-
```typescript
|
|
337
|
-
class ScriptDebugger {
|
|
338
|
-
static debugScript(script: Script): ScriptDebugInfo {
|
|
339
|
-
const chunks = script.chunks
|
|
340
|
-
const debugInfo: ScriptDebugInfo = {
|
|
341
|
-
chunks: [],
|
|
342
|
-
opcodes: [],
|
|
343
|
-
data: [],
|
|
344
|
-
analysis: {
|
|
345
|
-
isValid: true,
|
|
346
|
-
errors: [],
|
|
347
|
-
warnings: []
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
chunks.forEach((chunk, index) => {
|
|
352
|
-
if (chunk.opcode !== undefined) {
|
|
353
|
-
debugInfo.opcodes.push({
|
|
354
|
-
index,
|
|
355
|
-
opcode: chunk.opcode,
|
|
356
|
-
name: this.getOpcodeName(chunk.opcode),
|
|
357
|
-
description: this.getOpcodeDescription(chunk.opcode)
|
|
358
|
-
})
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
if (chunk.data) {
|
|
362
|
-
debugInfo.data.push({
|
|
363
|
-
index,
|
|
364
|
-
data: chunk.data,
|
|
365
|
-
hex: Buffer.from(chunk.data).toString('hex'),
|
|
366
|
-
size: chunk.data.length
|
|
367
|
-
})
|
|
368
|
-
}
|
|
369
|
-
})
|
|
370
|
-
|
|
371
|
-
return debugInfo
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
private static getOpcodeName(opcode: number): string {
|
|
375
|
-
const opcodeMap: Record<number, string> = {
|
|
376
|
-
0: 'OP_0',
|
|
377
|
-
76: 'OP_PUSHDATA1',
|
|
378
|
-
77: 'OP_PUSHDATA2',
|
|
379
|
-
78: 'OP_PUSHDATA4',
|
|
380
|
-
79: 'OP_1NEGATE',
|
|
381
|
-
81: 'OP_1',
|
|
382
|
-
82: 'OP_2',
|
|
383
|
-
// ... add more opcodes as needed
|
|
384
|
-
118: 'OP_DUP',
|
|
385
|
-
169: 'OP_HASH160',
|
|
386
|
-
136: 'OP_EQUALVERIFY',
|
|
387
|
-
172: 'OP_CHECKSIG'
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
return opcodeMap[opcode] || `OP_UNKNOWN_${opcode}`
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
```
|
|
394
|
-
|
|
395
|
-
## Performance Debugging
|
|
396
|
-
|
|
397
|
-
### Performance Monitor
|
|
398
|
-
|
|
399
|
-
```typescript
|
|
400
|
-
class PerformanceMonitor {
|
|
401
|
-
private static timers = new Map<string, number>()
|
|
402
|
-
private static metrics = new Map<string, PerformanceMetric>()
|
|
403
|
-
|
|
404
|
-
static startTimer(label: string): void {
|
|
405
|
-
this.timers.set(label, performance.now())
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
static endTimer(label: string): number {
|
|
409
|
-
const startTime = this.timers.get(label)
|
|
410
|
-
if (!startTime) {
|
|
411
|
-
console.warn(`Timer '${label}' was not started`)
|
|
412
|
-
return 0
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
const duration = performance.now() - startTime
|
|
416
|
-
this.timers.delete(label)
|
|
417
|
-
|
|
418
|
-
// Update metrics
|
|
419
|
-
const metric = this.metrics.get(label) || {
|
|
420
|
-
count: 0,
|
|
421
|
-
totalTime: 0,
|
|
422
|
-
avgTime: 0,
|
|
423
|
-
minTime: Infinity,
|
|
424
|
-
maxTime: 0
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
metric.count++
|
|
428
|
-
metric.totalTime += duration
|
|
429
|
-
metric.avgTime = metric.totalTime / metric.count
|
|
430
|
-
metric.minTime = Math.min(metric.minTime, duration)
|
|
431
|
-
metric.maxTime = Math.max(metric.maxTime, duration)
|
|
432
|
-
|
|
433
|
-
this.metrics.set(label, metric)
|
|
434
|
-
|
|
435
|
-
console.debug(`[PERFORMANCE] ${label}: ${duration.toFixed(2)}ms`)
|
|
436
|
-
return duration
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
static getMetrics(): Map<string, PerformanceMetric> {
|
|
440
|
-
return new Map(this.metrics)
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
static resetMetrics(): void {
|
|
444
|
-
this.metrics.clear()
|
|
445
|
-
this.timers.clear()
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
interface PerformanceMetric {
|
|
450
|
-
count: number
|
|
451
|
-
totalTime: number
|
|
452
|
-
avgTime: number
|
|
453
|
-
minTime: number
|
|
454
|
-
maxTime: number
|
|
455
|
-
}
|
|
456
|
-
```
|
|
457
|
-
|
|
458
|
-
### Memory Usage Monitoring
|
|
459
|
-
|
|
460
|
-
```typescript
|
|
461
|
-
class MemoryMonitor {
|
|
462
|
-
static logMemoryUsage(label: string): void {
|
|
463
|
-
if (typeof process !== 'undefined' && process.memoryUsage) {
|
|
464
|
-
const usage = process.memoryUsage()
|
|
465
|
-
console.debug(`[MEMORY] ${label}:`, {
|
|
466
|
-
rss: `${Math.round(usage.rss / 1024 / 1024)}MB`,
|
|
467
|
-
heapTotal: `${Math.round(usage.heapTotal / 1024 / 1024)}MB`,
|
|
468
|
-
heapUsed: `${Math.round(usage.heapUsed / 1024 / 1024)}MB`,
|
|
469
|
-
external: `${Math.round(usage.external / 1024 / 1024)}MB`
|
|
470
|
-
})
|
|
471
|
-
} else if (typeof performance !== 'undefined' && (performance as any).memory) {
|
|
472
|
-
const memory = (performance as any).memory
|
|
473
|
-
console.debug(`[MEMORY] ${label}:`, {
|
|
474
|
-
used: `${Math.round(memory.usedJSHeapSize / 1024 / 1024)}MB`,
|
|
475
|
-
total: `${Math.round(memory.totalJSHeapSize / 1024 / 1024)}MB`,
|
|
476
|
-
limit: `${Math.round(memory.jsHeapSizeLimit / 1024 / 1024)}MB`
|
|
477
|
-
})
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
```
|
|
482
|
-
|
|
483
|
-
## Debug Utilities
|
|
484
|
-
|
|
485
|
-
### Hex Dump Utility
|
|
486
|
-
|
|
487
|
-
```typescript
|
|
488
|
-
class HexDump {
|
|
489
|
-
static dump(data: Uint8Array | number[], bytesPerLine: number = 16): string {
|
|
490
|
-
const bytes = Array.from(data)
|
|
491
|
-
let result = ''
|
|
492
|
-
|
|
493
|
-
for (let i = 0; i < bytes.length; i += bytesPerLine) {
|
|
494
|
-
const line = bytes.slice(i, i + bytesPerLine)
|
|
495
|
-
const offset = i.toString(16).padStart(8, '0')
|
|
496
|
-
const hex = line.map(b => b.toString(16).padStart(2, '0')).join(' ')
|
|
497
|
-
const ascii = line.map(b => (b >= 32 && b <= 126) ? String.fromCharCode(b) : '.').join('')
|
|
498
|
-
|
|
499
|
-
result += `${offset}: ${hex.padEnd(bytesPerLine * 3 - 1)} |${ascii}|\n`
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
return result
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
static logDump(data: Uint8Array | number[], label: string): void {
|
|
506
|
-
console.debug(`[HEX DUMP] ${label}:\n${this.dump(data)}`)
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
```
|
|
510
|
-
|
|
511
|
-
### Network Request Inspector
|
|
512
|
-
|
|
513
|
-
```typescript
|
|
514
|
-
class NetworkInspector {
|
|
515
|
-
private static requests = new Map<string, NetworkRequest>()
|
|
516
|
-
|
|
517
|
-
static startRequest(id: string, url: string, method: string, data?: any): void {
|
|
518
|
-
this.requests.set(id, {
|
|
519
|
-
id,
|
|
520
|
-
url,
|
|
521
|
-
method,
|
|
522
|
-
data,
|
|
523
|
-
startTime: Date.now(),
|
|
524
|
-
status: 'pending'
|
|
525
|
-
})
|
|
526
|
-
|
|
527
|
-
console.debug(`[NETWORK] Starting request ${id}:`, {
|
|
528
|
-
url,
|
|
529
|
-
method,
|
|
530
|
-
dataSize: data ? JSON.stringify(data).length : 0
|
|
531
|
-
})
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
static endRequest(id: string, status: number, response?: any): void {
|
|
535
|
-
const request = this.requests.get(id)
|
|
536
|
-
if (!request) return
|
|
537
|
-
|
|
538
|
-
const duration = Date.now() - request.startTime
|
|
539
|
-
request.status = 'completed'
|
|
540
|
-
request.duration = duration
|
|
541
|
-
request.response = response
|
|
542
|
-
|
|
543
|
-
console.debug(`[NETWORK] Completed request ${id}:`, {
|
|
544
|
-
status,
|
|
545
|
-
duration: `${duration}ms`,
|
|
546
|
-
responseSize: response ? JSON.stringify(response).length : 0
|
|
547
|
-
})
|
|
548
|
-
|
|
549
|
-
// Clean up old requests
|
|
550
|
-
setTimeout(() => this.requests.delete(id), 60000)
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
static failRequest(id: string, error: any): void {
|
|
554
|
-
const request = this.requests.get(id)
|
|
555
|
-
if (!request) return
|
|
556
|
-
|
|
557
|
-
const duration = Date.now() - request.startTime
|
|
558
|
-
request.status = 'failed'
|
|
559
|
-
request.duration = duration
|
|
560
|
-
request.error = error
|
|
561
|
-
|
|
562
|
-
console.error(`[NETWORK] Failed request ${id}:`, {
|
|
563
|
-
error: error.message,
|
|
564
|
-
duration: `${duration}ms`
|
|
565
|
-
})
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
static getActiveRequests(): NetworkRequest[] {
|
|
569
|
-
return Array.from(this.requests.values()).filter(r => r.status === 'pending')
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
interface NetworkRequest {
|
|
574
|
-
id: string
|
|
575
|
-
url: string
|
|
576
|
-
method: string
|
|
577
|
-
data?: any
|
|
578
|
-
startTime: number
|
|
579
|
-
duration?: number
|
|
580
|
-
status: 'pending' | 'completed' | 'failed'
|
|
581
|
-
response?: any
|
|
582
|
-
error?: any
|
|
583
|
-
}
|
|
584
|
-
```
|
|
585
|
-
|
|
586
|
-
## Debug Configuration Examples
|
|
587
|
-
|
|
588
|
-
### Development Debug Setup
|
|
589
|
-
|
|
590
|
-
```typescript
|
|
591
|
-
// Enable comprehensive debugging for development
|
|
592
|
-
const devDebugConfig = {
|
|
593
|
-
logging: {
|
|
594
|
-
level: 'debug' as LogLevel,
|
|
595
|
-
outputs: [
|
|
596
|
-
{ type: 'console', config: { colors: true } },
|
|
597
|
-
{ type: 'file', config: { file: './dev-debug.log' } }
|
|
598
|
-
],
|
|
599
|
-
format: {
|
|
600
|
-
timestamp: true,
|
|
601
|
-
level: true,
|
|
602
|
-
component: true,
|
|
603
|
-
structured: true,
|
|
604
|
-
colors: true
|
|
605
|
-
},
|
|
606
|
-
performance: {
|
|
607
|
-
enabled: true,
|
|
608
|
-
threshold: 50,
|
|
609
|
-
includeStackTrace: true
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
}
|
|
613
|
-
```
|
|
614
|
-
|
|
615
|
-
### Production Debug Setup
|
|
616
|
-
|
|
617
|
-
```typescript
|
|
618
|
-
// Minimal debugging for production
|
|
619
|
-
const prodDebugConfig = {
|
|
620
|
-
logging: {
|
|
621
|
-
level: 'warn' as LogLevel,
|
|
622
|
-
outputs: [
|
|
623
|
-
{ type: 'file', config: { file: '/var/log/bsv-app.log', rotation: true } }
|
|
624
|
-
],
|
|
625
|
-
format: {
|
|
626
|
-
timestamp: true,
|
|
627
|
-
level: true,
|
|
628
|
-
component: false,
|
|
629
|
-
structured: true,
|
|
630
|
-
colors: false
|
|
631
|
-
},
|
|
632
|
-
performance: {
|
|
633
|
-
enabled: true,
|
|
634
|
-
threshold: 1000,
|
|
635
|
-
includeStackTrace: false
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
```
|
|
640
|
-
|
|
641
|
-
### Testing Debug Setup
|
|
642
|
-
|
|
643
|
-
```typescript
|
|
644
|
-
// Debug configuration for testing
|
|
645
|
-
const testDebugConfig = {
|
|
646
|
-
logging: {
|
|
647
|
-
level: 'trace' as LogLevel,
|
|
648
|
-
outputs: [
|
|
649
|
-
{ type: 'console', config: {} }
|
|
650
|
-
],
|
|
651
|
-
format: {
|
|
652
|
-
timestamp: false,
|
|
653
|
-
level: true,
|
|
654
|
-
component: true,
|
|
655
|
-
structured: false,
|
|
656
|
-
colors: false
|
|
657
|
-
},
|
|
658
|
-
performance: {
|
|
659
|
-
enabled: false
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
```
|
|
664
|
-
|
|
665
|
-
## Troubleshooting Common Issues
|
|
666
|
-
|
|
667
|
-
### Debug Checklist
|
|
668
|
-
|
|
669
|
-
1. **Enable appropriate logging level**
|
|
670
|
-
|
|
671
|
-
```typescript
|
|
672
|
-
// Set debug level based on issue severity
|
|
673
|
-
const config = { logging: { level: 'debug' } }
|
|
674
|
-
```
|
|
675
|
-
|
|
676
|
-
2. **Check network connectivity**
|
|
677
|
-
|
|
678
|
-
```typescript
|
|
679
|
-
NetworkInspector.startRequest('health-check', 'https://api.whatsonchain.com/v1/bsv/main/chain/info', 'GET')
|
|
680
|
-
```
|
|
681
|
-
|
|
682
|
-
3. **Validate transaction structure**
|
|
683
|
-
|
|
684
|
-
```typescript
|
|
685
|
-
const analysis = TransactionAnalyzer.analyze(transaction)
|
|
686
|
-
console.log('Transaction Analysis:', analysis)
|
|
687
|
-
```
|
|
688
|
-
|
|
689
|
-
4. **Monitor performance**
|
|
690
|
-
|
|
691
|
-
```typescript
|
|
692
|
-
PerformanceMonitor.startTimer('wallet-operation')
|
|
693
|
-
// ... perform operation
|
|
694
|
-
PerformanceMonitor.endTimer('wallet-operation')
|
|
695
|
-
```
|
|
696
|
-
|
|
697
|
-
5. **Check memory usage**
|
|
698
|
-
|
|
699
|
-
```typescript
|
|
700
|
-
MemoryMonitor.logMemoryUsage('before-operation')
|
|
701
|
-
// ... perform operation
|
|
702
|
-
MemoryMonitor.logMemoryUsage('after-operation')
|
|
703
|
-
```
|
|
704
|
-
|
|
705
|
-
This comprehensive debugging reference provides developers with all the tools and techniques needed to effectively debug and troubleshoot applications built with the BSV TypeScript SDK.
|