@bsv/sdk 1.9.3 → 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.
Files changed (60) hide show
  1. package/dist/cjs/package.json +1 -1
  2. package/docs/fast-docs.png +0 -0
  3. package/docs/index.md +49 -44
  4. package/docs/swagger.png +0 -0
  5. package/package.json +1 -1
  6. package/docs/MARKDOWN_VALIDATION_GUIDE.md +0 -175
  7. package/docs/concepts/beef.md +0 -92
  8. package/docs/concepts/chain-tracking.md +0 -134
  9. package/docs/concepts/decentralized-identity.md +0 -221
  10. package/docs/concepts/fees.md +0 -249
  11. package/docs/concepts/identity-certificates.md +0 -307
  12. package/docs/concepts/index.md +0 -77
  13. package/docs/concepts/key-management.md +0 -185
  14. package/docs/concepts/script-templates.md +0 -176
  15. package/docs/concepts/sdk-philosophy.md +0 -80
  16. package/docs/concepts/signatures.md +0 -194
  17. package/docs/concepts/spv-verification.md +0 -118
  18. package/docs/concepts/transaction-encoding.md +0 -167
  19. package/docs/concepts/transaction-structure.md +0 -67
  20. package/docs/concepts/trust-model.md +0 -139
  21. package/docs/concepts/verification.md +0 -250
  22. package/docs/concepts/wallet-integration.md +0 -101
  23. package/docs/guides/development-wallet-setup.md +0 -374
  24. package/docs/guides/direct-transaction-creation.md +0 -147
  25. package/docs/guides/http-client-configuration.md +0 -488
  26. package/docs/guides/index.md +0 -138
  27. package/docs/guides/large-transactions.md +0 -448
  28. package/docs/guides/multisig-transactions.md +0 -792
  29. package/docs/guides/security-best-practices.md +0 -494
  30. package/docs/guides/transaction-batching.md +0 -132
  31. package/docs/guides/transaction-signing-methods.md +0 -419
  32. package/docs/reference/arc-config.md +0 -698
  33. package/docs/reference/brc-100.md +0 -33
  34. package/docs/reference/configuration.md +0 -835
  35. package/docs/reference/debugging.md +0 -705
  36. package/docs/reference/errors.md +0 -597
  37. package/docs/reference/index.md +0 -111
  38. package/docs/reference/network-config.md +0 -914
  39. package/docs/reference/op-codes.md +0 -325
  40. package/docs/reference/transaction-signatures.md +0 -95
  41. package/docs/tutorials/advanced-transaction.md +0 -572
  42. package/docs/tutorials/aes-encryption.md +0 -949
  43. package/docs/tutorials/authfetch-tutorial.md +0 -986
  44. package/docs/tutorials/ecdh-key-exchange.md +0 -549
  45. package/docs/tutorials/elliptic-curve-fundamentals.md +0 -606
  46. package/docs/tutorials/error-handling.md +0 -1216
  47. package/docs/tutorials/first-transaction-low-level.md +0 -205
  48. package/docs/tutorials/first-transaction.md +0 -275
  49. package/docs/tutorials/hashes-and-hmacs.md +0 -788
  50. package/docs/tutorials/identity-management.md +0 -729
  51. package/docs/tutorials/index.md +0 -219
  52. package/docs/tutorials/key-management.md +0 -538
  53. package/docs/tutorials/protowallet-development.md +0 -743
  54. package/docs/tutorials/script-construction.md +0 -690
  55. package/docs/tutorials/spv-merkle-proofs.md +0 -685
  56. package/docs/tutorials/testnet-transactions-low-level.md +0 -359
  57. package/docs/tutorials/transaction-broadcasting.md +0 -538
  58. package/docs/tutorials/transaction-types.md +0 -420
  59. package/docs/tutorials/type-42.md +0 -568
  60. package/docs/tutorials/uhrp-storage.md +0 -599
@@ -1,448 +0,0 @@
1
- # Handling Large Bitcoin Transactions
2
-
3
- This guide provides authoritative patterns and best practices for constructing, signing, and broadcasting large Bitcoin transactions using the BSV TypeScript SDK. All examples are based on actual SDK APIs and have been verified against the source code.
4
-
5
- ## Table of Contents
6
-
7
- 1. [Understanding Large Transactions](#understanding-large-transactions)
8
- 2. [Memory Management Strategies](#memory-management-strategies)
9
- 3. [Efficient Transaction Construction](#efficient-transaction-construction)
10
- 4. [Batch Processing with `WalletClient`](#batch-processing-with-walletclient)
11
- 5. [Fee Calculation for Large Transactions](#fee-calculation-for-large-transactions)
12
- 6. [Signing Optimization](#signing-optimization)
13
- 7. [Broadcasting Strategies](#broadcasting-strategies)
14
- 8. [Error Handling and Recovery](#error-handling-and-recovery)
15
- 9. [Performance Monitoring](#performance-monitoring)
16
- 10. [Complete Example](#complete-example)
17
-
18
- ## Understanding Large Transactions
19
-
20
- Large Bitcoin transactions typically involve:
21
-
22
- - **Many inputs** (50+ UTXOs being consumed)
23
- - **Many outputs** (50+ recipients or complex splitting)
24
- - **Large scripts** (complex locking/unlocking conditions)
25
- - **Chained transactions** (dependent transaction sequences)
26
-
27
- The SDK provides several mechanisms to handle these efficiently.
28
-
29
- ## Memory Management Strategies
30
-
31
- ### Batch Input/Output Addition
32
-
33
- Instead of adding inputs and outputs one by one, batch them to reduce memory allocations:
34
-
35
- ```typescript
36
- import { Transaction, TransactionInput, TransactionOutput, LockingScript, UnlockingScript } from '@bsv/sdk'
37
-
38
- class LargeTransactionBuilder {
39
- private transaction: Transaction
40
- private inputBatch: TransactionInput[] = []
41
- private outputBatch: TransactionOutput[] = []
42
- private batchSize = 100
43
-
44
- constructor() {
45
- this.transaction = new Transaction()
46
- }
47
-
48
- addInputBatch(inputs: TransactionInput[]): void {
49
- this.inputBatch.push(...inputs)
50
-
51
- if (this.inputBatch.length >= this.batchSize) {
52
- this.flushInputs()
53
- }
54
- }
55
-
56
- addOutputBatch(outputs: TransactionOutput[]): void {
57
- this.outputBatch.push(...outputs)
58
-
59
- if (this.outputBatch.length >= this.batchSize) {
60
- this.flushOutputs()
61
- }
62
- }
63
-
64
- private flushInputs(): void {
65
- for (const input of this.inputBatch) {
66
- this.transaction.addInput(input)
67
- }
68
- this.inputBatch = []
69
-
70
- // Hint garbage collection for large batches
71
- if (global.gc) {
72
- global.gc()
73
- }
74
- }
75
-
76
- private flushOutputs(): void {
77
- for (const output of this.outputBatch) {
78
- this.transaction.addOutput(output)
79
- }
80
- this.outputBatch = []
81
-
82
- if (global.gc) {
83
- global.gc()
84
- }
85
- }
86
-
87
- finalize(): Transaction {
88
- this.flushInputs()
89
- this.flushOutputs()
90
- return this.transaction
91
- }
92
- }
93
-
94
- // Example usage with TransactionInput and TransactionOutput creation
95
- async function createLargeTransactionExample() {
96
- const builder = new LargeTransactionBuilder()
97
-
98
- // Create properly formatted inputs with required fields
99
- const inputs: TransactionInput[] = []
100
- for (let i = 0; i < 100; i++) {
101
- inputs.push({
102
- sourceTXID: '0'.repeat(64), // Replace with actual TXID
103
- sourceOutputIndex: i,
104
- unlockingScriptLength: 0,
105
- unlockingScript: new UnlockingScript(), // Will be populated during signing
106
- sequenceNumber: 0xffffffff
107
- } as TransactionInput)
108
- }
109
-
110
- // Create properly formatted outputs
111
- const outputs: TransactionOutput[] = []
112
- for (let i = 0; i < 100; i++) {
113
- outputs.push({
114
- satoshis: 100,
115
- lockingScriptLength: 6,
116
- lockingScript: LockingScript.fromASM('OP_RETURN 74657374') // OP_RETURN "test"
117
- } as TransactionOutput)
118
- }
119
-
120
- builder.addInputBatch(inputs)
121
- builder.addOutputBatch(outputs)
122
-
123
- return builder.finalize()
124
- }
125
- ```
126
-
127
- ### Memory Pool Management
128
-
129
- For extremely large transactions, implement a memory pool to manage object lifecycle:
130
-
131
- ```typescript
132
- class TransactionMemoryPool {
133
- private inputPool: TransactionInput[] = []
134
- private outputPool: TransactionOutput[] = []
135
- private maxPoolSize = 1000
136
-
137
- borrowInput(): TransactionInput {
138
- return this.inputPool.pop() || {} as TransactionInput
139
- }
140
-
141
- borrowOutput(): TransactionOutput {
142
- return this.outputPool.pop() || {} as TransactionOutput
143
- }
144
-
145
- returnInput(input: TransactionInput): void {
146
- if (this.inputPool.length < this.maxPoolSize) {
147
- // Clear the input for reuse
148
- Object.keys(input).forEach(key => delete (input as any)[key])
149
- this.inputPool.push(input)
150
- }
151
- }
152
-
153
- returnOutput(output: TransactionOutput): void {
154
- if (this.outputPool.length < this.maxPoolSize) {
155
- Object.keys(output).forEach(key => delete (output as any)[key])
156
- this.outputPool.push(output)
157
- }
158
- }
159
- }
160
- ```
161
-
162
- ## Efficient Transaction Construction
163
-
164
- ### Using the Transaction Constructor
165
-
166
- The SDK's Transaction constructor accepts arrays of inputs and outputs, which is more efficient than individual additions:
167
-
168
- ```typescript
169
- import { Transaction, TransactionInput, TransactionOutput, LockingScript, UnlockingScript } from '@bsv/sdk'
170
-
171
- function buildLargeTransaction(
172
- inputs: TransactionInput[],
173
- outputs: TransactionOutput[]
174
- ): Transaction {
175
- // More efficient than multiple addInput/addOutput calls
176
- return new Transaction(
177
- 1, // version
178
- inputs,
179
- outputs,
180
- 0, // lockTime
181
- {}, // metadata
182
- undefined // merklePath
183
- )
184
- }
185
-
186
- // Example usage with properly formatted inputs and outputs
187
- function createExampleTransaction(): Transaction {
188
- const inputs: TransactionInput[] = [{
189
- sourceTXID: '0'.repeat(64), // Replace with actual TXID
190
- sourceOutputIndex: 0,
191
- unlockingScriptLength: 0,
192
- unlockingScript: new UnlockingScript(),
193
- sequenceNumber: 0xffffffff
194
- } as TransactionInput]
195
-
196
- const outputs: TransactionOutput[] = [{
197
- satoshis: 100,
198
- lockingScriptLength: 6,
199
- lockingScript: LockingScript.fromASM('OP_RETURN 74657374') // OP_RETURN "test"
200
- } as TransactionOutput]
201
-
202
- return buildLargeTransaction(inputs, outputs)
203
- }
204
- ```
205
-
206
- ### Chunked Processing
207
-
208
- For very large input/output sets, process them in chunks:
209
-
210
- ```typescript
211
- async function processLargeInputSet(
212
- allInputs: TransactionInput[],
213
- chunkSize: number = 50
214
- ): Promise<Transaction[]> {
215
- const transactions: Transaction[] = []
216
-
217
- for (let i = 0; i < allInputs.length; i += chunkSize) {
218
- const chunk = allInputs.slice(i, i + chunkSize)
219
- const tx = new Transaction(1, chunk, [])
220
-
221
- // Process chunk
222
- await tx.fee()
223
- await tx.sign()
224
-
225
- transactions.push(tx)
226
-
227
- // Allow event loop to process other tasks
228
- await new Promise(resolve => setImmediate(resolve))
229
- }
230
-
231
- return transactions
232
- }
233
- ```
234
-
235
- ## Batch Processing with `WalletClient`
236
-
237
- The SDK's `WalletClient` provides built-in batching capabilities for large transaction workflows:
238
-
239
- ### Chained Transaction Batching
240
-
241
- ```typescript
242
- import { WalletClient, CreateActionArgs } from '@bsv/sdk'
243
-
244
- class BatchTransactionProcessor {
245
- private walletClient: WalletClient
246
- private maxRetries: number = 3
247
- private retryDelay: number = 1000
248
-
249
- constructor(walletClient: WalletClient) {
250
- this.walletClient = walletClient
251
- }
252
-
253
- async createChainedBatch(actions: CreateActionArgs[]): Promise<string[]> {
254
- const txids: string[] = []
255
- const batchReferences: string[] = []
256
-
257
- // Create all transactions without sending (noSend: true)
258
- for (let i = 0; i < actions.length; i++) {
259
- const action = {
260
- ...actions[i],
261
- options: {
262
- ...actions[i].options,
263
- noSend: true,
264
- // Include previous transaction outputs as known
265
- knownTxids: txids
266
- }
267
- }
268
-
269
- const result = await this.walletClient.createAction(action)
270
-
271
- if (result.signableTransaction) {
272
- // Sign the transaction
273
- const signResult = await this.walletClient.signAction({
274
- spends: this.generateSpends(action),
275
- reference: result.signableTransaction.reference,
276
- options: { noSend: true }
277
- })
278
-
279
- if (signResult.txid) {
280
- txids.push(signResult.txid)
281
- batchReferences.push(result.signableTransaction.reference)
282
- }
283
- }
284
- }
285
-
286
- // Send all transactions as a batch
287
- if (batchReferences.length > 0) {
288
- await this.walletClient.signAction({
289
- spends: {},
290
- reference: batchReferences[0],
291
- options: {
292
- sendWith: txids
293
- }
294
- })
295
- }
296
-
297
- return txids
298
- }
299
-
300
- private generateSpends(action: CreateActionArgs): Record<number, any> {
301
- const spends: Record<number, any> = {}
302
-
303
- if (action.inputs) {
304
- action.inputs.forEach((input, index) => {
305
- spends[index] = {
306
- unlockingScript: input.unlockingScript || '',
307
- sequenceNumber: input.sequenceNumber || 0xffffffff
308
- }
309
- })
310
- }
311
-
312
- return spends
313
- }
314
- }
315
- ```
316
-
317
- ### Progress Tracking for Large Batches
318
-
319
- ```typescript
320
- interface BatchProgress {
321
- total: number
322
- completed: number
323
- failed: number
324
- currentPhase: 'creating' | 'signing' | 'broadcasting'
325
- }
326
-
327
- class ProgressTrackingBatch {
328
- async processBatchWithProgress(
329
- actions: CreateActionArgs[],
330
- onProgress?: (progress: BatchProgress) => void
331
- ): Promise<string[]> {
332
- this.progress.total = actions.length
333
- this.progress.currentPhase = 'creating'
334
-
335
- const results: string[] = []
336
-
337
- for (let i = 0; i < actions.length; i++) {
338
- try {
339
- const result = await this.walletClient.createAction(actions[i])
340
-
341
- if (result.txid) {
342
- results.push(result.txid)
343
- this.progress.completed++
344
- }
345
- } catch (error) {
346
- console.error(`Failed to process action ${i}:`, error)
347
- this.progress.failed++
348
- }
349
-
350
- if (onProgress) {
351
- onProgress({ ...this.progress })
352
- }
353
-
354
- // Throttle to prevent overwhelming the wallet
355
- if (i % 10 === 0) {
356
- await new Promise(resolve => setTimeout(resolve, 100))
357
- }
358
- }
359
-
360
- return results
361
- }
362
- }
363
- ```
364
-
365
- ## Fee Calculation for Large Transactions
366
-
367
- ### Custom Fee Models
368
-
369
- The SDK provides a `FeeModel` interface and `SatoshisPerKilobyte` implementation:
370
-
371
- ```typescript
372
- import { SatoshisPerKilobyte, Transaction } from '@bsv/sdk'
373
-
374
- // FeeModel interface definition (since it's not exported from SDK)
375
- interface FeeModel {
376
- computeFee(transaction: Transaction): Promise<number>
377
- }
378
-
379
- class OptimizedFeeModel implements FeeModel {
380
- private baseFeeModel: SatoshisPerKilobyte
381
- private largeTxThreshold: number
382
-
383
- constructor(
384
- baseSatPerKb: number = 1,
385
- largeTxThreshold: number = 100000 // 100KB
386
- ) {
387
- this.baseFeeModel = new SatoshisPerKilobyte(baseSatPerKb)
388
- this.largeTxThreshold = largeTxThreshold
389
- }
390
-
391
- async computeFee(transaction: Transaction): Promise<number> {
392
- const baseFee = await this.baseFeeModel.computeFee(transaction)
393
- const txSize = transaction.toBinary().length
394
-
395
- // Apply discount for large transactions
396
- if (txSize > this.largeTxThreshold) {
397
- const discount = Math.min(0.5, (txSize - this.largeTxThreshold) / 1000000)
398
- return Math.floor(baseFee * (1 - discount))
399
- }
400
-
401
- return baseFee
402
- }
403
- }
404
-
405
- // Usage
406
- async function calculateOptimizedFee(transaction: Transaction): Promise<void> {
407
- const feeModel = new OptimizedFeeModel(1, 50000)
408
- await transaction.fee(feeModel)
409
- }
410
- ```
411
-
412
- ### Batch Fee Calculation
413
-
414
- ```typescript
415
- async function calculateFeesInBatch(
416
- transactions: Transaction[],
417
- feeModel: FeeModel
418
- ): Promise<number[]> {
419
- const feePromises = transactions.map(tx => feeModel.computeFee(tx))
420
- return Promise.all(feePromises)
421
- }
422
- ```
423
-
424
- ## Conclusion
425
-
426
- Handling large Bitcoin transactions efficiently requires a comprehensive approach that addresses memory management, performance optimization, and robust error handling. The BSV TypeScript SDK provides powerful tools and patterns to manage these challenges effectively.
427
-
428
- ### Next Steps
429
-
430
- To implement large transaction handling in your application:
431
-
432
- 1. **Start Simple**: Begin with the `LargeTransactionBuilder` pattern for basic batching
433
- 2. **Add Streaming**: Implement `StreamingTransactionBuilder` for memory-constrained scenarios
434
- 3. **Optimize Performance**: Add caching and parallel processing using the optimization patterns
435
- 4. **Enhance Monitoring**: Integrate the monitoring and error handling examples
436
- 5. **Test Thoroughly**: Use the validation patterns to ensure transaction integrity
437
-
438
- ### Related Documentation
439
-
440
- For additional context and complementary patterns, see:
441
-
442
- - [Transaction Batching](./transaction-batching.md) - Efficient multi-output transaction patterns
443
- - [Error Handling](./error-handling.md) - Comprehensive error management strategies
444
- - [Performance Optimization](./performance-optimization.md) - General SDK performance patterns
445
- - [Advanced Transaction Signing](./advanced-transaction-signing.md) - Signing optimization for large transactions
446
- - [Transaction Monitoring](./transaction-monitoring.md) - Monitoring and alerting for transaction operations
447
-
448
- The techniques in this guide enable you to build robust, scalable Bitcoin applications that can handle enterprise-level transaction volumes while maintaining security, performance, and reliability standards.