@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,419 +0,0 @@
1
- # Transaction Signing Methods
2
-
3
- *This is a How-To guide for different transaction signing approaches with the BSV TypeScript SDK.*
4
-
5
- ## Overview
6
-
7
- This guide demonstrates two different approaches to signing Bitcoin transactions with the BSV TypeScript SDK:
8
-
9
- 1. **Using `WalletClient`** - A high-level approach that abstracts key management and signing details
10
- 2. **Using Low-level APIs** - A direct approach with more control over the transaction signing process
11
-
12
- Each method has its advantages depending on your use case. The `WalletClient` approach is recommended for production applications where security is paramount, while the low-level approach gives you more control and is useful for educational purposes or specialized applications.
13
-
14
- ## Prerequisites
15
-
16
- - Completed the [Key Management and Cryptography tutorial](../tutorials/key-management.md)
17
- - Familiarity with Bitcoin transaction structure
18
- - Understanding of basic cryptographic principles
19
-
20
- > **šŸ“š Related Concepts**: This guide builds on [Digital Signatures](../concepts/signatures.md), [Key Management](../concepts/key-management.md), [Transaction Structure](../concepts/transaction-structure.md), and [Wallet Integration](../concepts/wallet-integration.md).
21
-
22
- ## Method 1: `WalletClient` Signing (Recommended)
23
-
24
- The `WalletClient` provides a secure, high-level interface for managing keys and signing transactions. This approach is recommended for production applications as it:
25
-
26
- - Abstracts away complex key management
27
- - Provides better security by isolating private keys
28
- - Handles transaction construction and signing in a unified way
29
-
30
- ### Example Code
31
-
32
- ```typescript
33
- import { WalletClient, Transaction } from '@bsv/sdk'
34
-
35
- async function walletTransactionDemo() {
36
- console.log('\n=== Transaction Signing with WalletClient ===')
37
-
38
- try {
39
- // 1. WalletClient Key Management
40
- const wallet = new WalletClient('auto', 'localhost')
41
- console.log('\n1. WalletClient Key Management')
42
-
43
- // Define protocol and key identifiers for wallet operations
44
- // Use 1 to represent medium security level
45
- // Cast it to any to bypass strict type checking since we don't have the SecurityLevel enum
46
- const protocolID = [1, 'example'] as any
47
- const keyID = 'transaction-signing-key'
48
-
49
- console.log(`Protocol ID: ${protocolID[0]}-${protocolID[1]}`)
50
- console.log(`Key ID: ${keyID}`)
51
-
52
- // Get a public key from the wallet
53
- // In a real application, this would be a key securely managed by the wallet
54
- const publicKeyResult = await wallet.getPublicKey({ protocolID, keyID })
55
- const publicKeyHex = publicKeyResult.publicKey
56
- console.log(`Public Key: ${publicKeyHex}`)
57
-
58
- // 2. Creating a transaction with WalletClient
59
- console.log('\n2. Creating a transaction with WalletClient')
60
-
61
- // Get our own address to send payment to self (realistic example)
62
- const ourAddress = await wallet.getAddress()
63
- const amountSatoshis = 100
64
-
65
- console.log(`Our wallet address: ${ourAddress}`)
66
-
67
- // Create a proper P2PKH locking script for our address
68
- const lockingScript = new P2PKH().lock(ourAddress)
69
-
70
- // Create a payment action using WalletClient
71
- // This builds a complete transaction structure internally
72
- const actionResult = await wallet.createAction({
73
- description: `Self-payment demonstration`,
74
- // Define outputs for the transaction
75
- outputs: [
76
- {
77
- // Use proper P2PKH script construction
78
- lockingScript: lockingScript.toHex(),
79
- satoshis: amountSatoshis,
80
- basket: 'tutorial',
81
- outputDescription: `Payment to our own address`
82
- }
83
- ],
84
- // Set options to ensure we get a signable transaction
85
- options: {
86
- signAndProcess: false // This ensures we get a signable transaction back
87
- }
88
- })
89
-
90
- console.log('Payment action created:')
91
- if (actionResult.signableTransaction) {
92
- console.log(`- Action Reference: ${actionResult.signableTransaction.reference}`)
93
- } else {
94
- console.log('No signable transaction returned - check wallet configuration')
95
- return
96
- }
97
- console.log(`- Description: Payment demonstration`)
98
- console.log(`- Amount: ${amountSatoshis} satoshis`)
99
- console.log(`- Recipient: ${ourAddress} (our own address)`)
100
-
101
- // 3. Sign the transaction with WalletClient
102
- console.log('\n3. Signing transaction with WalletClient')
103
-
104
- // Request wallet to sign the action/transaction
105
- const signResult = await wallet.signAction({
106
- // Use the reference from the createAction result
107
- reference: actionResult.signableTransaction.reference,
108
- // The spends parameter is a map of input indexes to unlocking scripts
109
- // For wallet-managed keys, we provide an empty map and let the wallet handle it
110
- spends: {}
111
- })
112
-
113
- console.log('Transaction signed successfully!')
114
- if (signResult.txid) {
115
- console.log(`Transaction ID: ${signResult.txid}`)
116
- }
117
-
118
- // 4. Examine the transaction (retrieve it from the network and inspect it)
119
- console.log('\n4. Examining the transaction')
120
-
121
- // Check if we have a transaction ID from the sign result
122
- if (signResult.txid) {
123
- console.log(`Transaction ID: ${signResult.txid}`)
124
- console.log('Transaction was successfully signed and broadcast!')
125
-
126
- // Actually retrieve and inspect the transaction using the wallet
127
- try {
128
- // Wait a moment for the transaction to propagate
129
- await new Promise(resolve => setTimeout(resolve, 1000))
130
-
131
- // Retry logic to find the transaction outputs
132
- const maxRetries = 5 // 30 seconds with 5-second intervals
133
- const retryInterval = 5000 // 5 seconds
134
- let relatedOutputs: any[] = []
135
- let retryCount = 0
136
-
137
- console.log('\nSearching for transaction outputs...')
138
-
139
- while (retryCount < maxRetries && relatedOutputs.length === 0) {
140
- try {
141
- // List our outputs to see the transaction result
142
- const { outputs } = await wallet.listOutputs({ basket: 'tutorial' })
143
-
144
- // Find outputs related to our transaction
145
- // Extract txid from outpoint (format: "txid.outputIndex")
146
- relatedOutputs = outputs.filter(output => {
147
- const [outputTxid] = output.outpoint.split('.')
148
- return outputTxid === signResult.txid
149
- })
150
-
151
- if (relatedOutputs.length > 0) {
152
- console.log('\nTransaction inspection results:')
153
- console.log(`- Found ${relatedOutputs.length} output(s) from this transaction`)
154
-
155
- relatedOutputs.forEach((output, index) => {
156
- console.log(`\nOutput ${index + 1}:`)
157
- console.log(` - Value: ${output.satoshis} satoshis`)
158
- console.log(` - Outpoint: ${output.outpoint}`)
159
- console.log(` - Locking Script: ${output.lockingScript}`)
160
- console.log(` - Spendable: ${output.spendable ? 'Yes' : 'No'}`)
161
- if (output.tags && output.tags.length > 0) {
162
- console.log(` - Tags: ${output.tags.join(', ')}`)
163
- }
164
- })
165
-
166
- // Analyze the locking script
167
- const firstOutput = relatedOutputs[0]
168
- console.log('\nScript Analysis:')
169
- console.log(`- Script Type: P2PKH (Pay-to-Public-Key-Hash)`)
170
- console.log(`- Script validates payment to: ${ourAddress}`)
171
- console.log(`- This output can be spent by providing a valid signature`)
172
-
173
- break // Found the outputs, exit the retry loop
174
- } else {
175
- retryCount++
176
- if (retryCount < maxRetries) {
177
- console.log(`Attempt ${retryCount}/${maxRetries}: Transaction not propagated yet, retrying in ${retryInterval/1000} seconds...`)
178
- await new Promise(resolve => setTimeout(resolve, retryInterval))
179
- }
180
- }
181
- } catch (listError: any) {
182
- retryCount++
183
- if (retryCount < maxRetries) {
184
- console.log(`Attempt ${retryCount}/${maxRetries}: Error listing outputs, retrying in ${retryInterval/1000} seconds...`)
185
- console.log(`Error: ${listError.message}`)
186
- await new Promise(resolve => setTimeout(resolve, retryInterval))
187
- } else {
188
- throw listError // Re-throw on final attempt
189
- }
190
- }
191
- }
192
-
193
- if (relatedOutputs.length === 0) {
194
- console.log('\nTransaction outputs not found after 30 seconds.')
195
- console.log('This might be because:')
196
- console.log('- The outputs went to a different basket')
197
- console.log('- The transaction is taking longer to sync')
198
- console.log('- Network connectivity issues')
199
- console.log('\nYou can check the transaction on WhatsOnChain:')
200
- console.log(`https://whatsonchain.com/tx/${signResult.txid}`)
201
- }
202
-
203
- } catch (inspectionError) {
204
- console.log('\nCould not inspect transaction details:')
205
- console.log('This is normal and can happen because:')
206
- console.log('- Transaction is still propagating through the network')
207
- console.log('- Wallet needs time to sync with the blockchain')
208
- console.log('- Network connectivity issues')
209
- console.log(`\nError details: ${inspectionError.message}`)
210
- }
211
-
212
- } else {
213
- console.log('No transaction ID available - transaction may not have been broadcast')
214
- }
215
- } catch (error) {
216
- console.error('Error during wallet transaction operations:', error)
217
- }
218
- }
219
-
220
- // Run the demo
221
- walletTransactionDemo().catch(console.error)
222
- ```
223
-
224
- ### Key Benefits of the `WalletClient` Approach
225
-
226
- 1. **Security**: Private keys are managed by the wallet service, reducing exposure
227
- 2. **Abstraction**: Complex transaction construction details are handled internally
228
- 3. **Integration**: Designed for integration with secure key management systems
229
- 4. **Consistency**: Provides a standardized approach to transaction creation and signing
230
-
231
- ## Method 2: Transaction Signing with Low-level APIs
232
-
233
- The low-level approach gives you direct control over the transaction signing process. This is useful for:
234
-
235
- - Educational purposes to understand the underlying mechanics
236
- - Specialized applications requiring custom transaction structures
237
- - Custom fee calculation and UTXO management
238
- - Advanced transaction types and complex scripts
239
-
240
- ```typescript
241
- import { PrivateKey, Transaction, P2PKH, Script } from '@bsv/sdk'
242
-
243
- async function lowLevelTransactionDemo() {
244
- console.log('\n=== Low-Level Transaction Signing Demo ===')
245
-
246
- // 1. Generate keys for our demonstration
247
- const privateKey = PrivateKey.fromRandom()
248
- const publicKey = privateKey.toPublicKey()
249
- const address = privateKey.toAddress()
250
-
251
- console.log('\n1. Key Generation:')
252
- console.log(`Private Key (WIF): ${privateKey.toWif()}`)
253
- console.log(`Public Key: ${publicKey.toString()}`)
254
- console.log(`Address: ${address}`)
255
-
256
- // 2. Create a realistic transaction with proper structure
257
- console.log('\n2. Creating Transaction Structure:')
258
-
259
- // Create a transaction that demonstrates real Bitcoin transaction patterns
260
- const tx = new Transaction()
261
-
262
- // For this demo, we'll create a transaction that spends from a P2PKH output
263
- // and creates a new P2PKH output (self-payment) plus an OP_RETURN data output
264
-
265
- // First, create a source transaction that contains funds we can spend
266
- const sourceTransaction = new Transaction()
267
- sourceTransaction.addOutput({
268
- lockingScript: new P2PKH().lock(address),
269
- satoshis: 1000 // Source has 1000 satoshis
270
- })
271
-
272
- // Add input that spends from our source transaction
273
- tx.addInput({
274
- sourceTransaction,
275
- sourceOutputIndex: 0,
276
- unlockingScriptTemplate: new P2PKH().unlock(privateKey)
277
- })
278
-
279
- // Add a P2PKH output (payment to ourselves)
280
- tx.addOutput({
281
- lockingScript: new P2PKH().lock(address),
282
- satoshis: 500
283
- })
284
-
285
- // Add an OP_RETURN data output
286
- tx.addOutput({
287
- lockingScript: Script.fromASM('OP_RETURN 48656c6c6f20426974636f696e21'), // "Hello Bitcoin!" in hex
288
- satoshis: 0
289
- })
290
-
291
- // Add change output
292
- tx.addOutput({
293
- lockingScript: new P2PKH().lock(address),
294
- change: true // Automatically calculates change amount after fees
295
- })
296
-
297
- console.log('Transaction structure created:')
298
- console.log(`- Inputs: ${tx.inputs.length}`)
299
- console.log(`- Outputs: ${tx.outputs.length}`)
300
- console.log(`- Input amount: 1000 satoshis`)
301
- console.log(`- Payment output: 500 satoshis`)
302
- console.log(`- Data output: 0 satoshis (OP_RETURN)`)
303
- console.log(`- Change output: Will be calculated automatically`)
304
-
305
- // 3. Calculate fees and finalize the transaction
306
- console.log('\n3. Fee Calculation and Signing:')
307
-
308
- // Calculate appropriate fees based on transaction size
309
- await tx.fee()
310
-
311
- // Display fee information
312
- const changeOutput = tx.outputs.find(output => output.change)
313
- if (changeOutput && changeOutput.satoshis !== undefined) {
314
- console.log(`Fee calculated: ${1000 - 500 - changeOutput.satoshis} satoshis`)
315
- console.log(`Change amount: ${changeOutput.satoshis} satoshis`)
316
- }
317
-
318
- // Sign the transaction
319
- console.log('\nSigning transaction...')
320
- await tx.sign()
321
-
322
- // 4. Examine the signed transaction
323
- console.log('\n4. Transaction Analysis:')
324
- console.log(`Transaction ID: ${Buffer.from(tx.id()).toString('hex')}`)
325
-
326
- // Check if the input has been properly signed
327
- const input = tx.inputs[0]
328
- if (input.unlockingScript) {
329
- const unlockingASM = input.unlockingScript.toASM()
330
- console.log(`\nUnlocking Script (ASM): ${unlockingASM}`)
331
-
332
- // Parse the signature and public key from the unlocking script
333
- const scriptParts = unlockingASM.split(' ')
334
- if (scriptParts.length >= 2) {
335
- console.log(`- Signature present: āœ“ (${scriptParts[0].length} chars)`)
336
- console.log(`- Public key present: āœ“ (${scriptParts[1].length} chars)`)
337
- }
338
- }
339
-
340
- // 5. Verify the transaction
341
- console.log('\n5. Transaction Verification:')
342
-
343
- try {
344
- const isValid = await tx.verify()
345
- console.log(`Transaction verification: ${isValid ? 'Valid āœ“' : 'Invalid āœ—'}`)
346
-
347
- if (isValid) {
348
- console.log('\nāœ“ Transaction is properly constructed and signed!')
349
- console.log('āœ“ All inputs have valid signatures')
350
- console.log('āœ“ All outputs have valid locking scripts')
351
- console.log('āœ“ Fee calculation is correct')
352
- }
353
- } catch (error: any) {
354
- console.log(`Verification error: ${error.message}`)
355
- }
356
-
357
- // 6. Display transaction hex
358
- const txHex = tx.toHex()
359
- console.log('\n6. Transaction Serialization:')
360
- console.log(`Transaction size: ${txHex.length / 2} bytes`)
361
- console.log(`Transaction hex (first 100 chars): ${txHex.substring(0, 100)}...`)
362
-
363
- // 7. Demonstrate transaction structure analysis
364
- console.log('\n7. Transaction Structure Analysis:')
365
- console.log('Outputs breakdown:')
366
- tx.outputs.forEach((output, index) => {
367
- const script = output.lockingScript
368
- let scriptType = 'Unknown'
369
-
370
- if (script.toASM().startsWith('OP_DUP OP_HASH160')) {
371
- scriptType = 'P2PKH (Pay-to-Public-Key-Hash)'
372
- } else if (script.toASM().startsWith('OP_RETURN')) {
373
- scriptType = 'OP_RETURN (Data)'
374
- }
375
-
376
- console.log(` Output ${index}: ${output.satoshis} satoshis - ${scriptType}`)
377
- if (output.change) {
378
- console.log(` (Change output)`)
379
- }
380
- })
381
-
382
- console.log('\nāœ“ Low-level transaction signing demonstration complete!')
383
- console.log('This transaction demonstrates:')
384
- console.log('- Proper input/output construction')
385
- console.log('- Automatic fee calculation')
386
- console.log('- Digital signature creation and verification')
387
- console.log('- Multiple output types (P2PKH + OP_RETURN)')
388
- console.log('- Change handling')
389
- }
390
-
391
- // Run the demonstration
392
- lowLevelTransactionDemo().catch(console.error)
393
- ```
394
-
395
- ### Key Benefits of the Low-level Approach
396
-
397
- 1. **Control**: Direct control over every aspect of the transaction
398
- 2. **Transparency**: Clear visibility into the transaction structure and signing process
399
- 3. **Flexibility**: Ability to customize transaction construction for specialized use cases
400
- 4. **Educational Value**: Better understanding of the underlying Bitcoin transaction mechanics
401
-
402
- ## Choosing the Right Approach
403
-
404
- Consider the following factors when deciding which approach to use:
405
-
406
- | Factor | `WalletClient` Approach | Low-level Approach |
407
- |--------|----------------------|-------------------|
408
- | Security | Higher (keys managed by wallet) | Lower (direct key handling) |
409
- | Complexity | Lower (abstracted API) | Higher (manual transaction construction) |
410
- | Control | Limited (managed by wallet) | Complete (direct access) |
411
- | Use Case | Production applications | Educational, specialized applications |
412
- | Integration | Better for enterprise systems | Better for custom implementations |
413
-
414
- ## Related Resources
415
-
416
- - [Key Management and Cryptography Tutorial](../tutorials/key-management.md)
417
- - [Advanced Transaction Signing](./advanced-transaction-signing.md)
418
- - [Transaction Signatures Reference](../reference/transaction-signatures.md)
419
- - [Bitcoin Transaction Specification](https://reference.cash/protocol/blockchain/transaction)