@bsv/sdk 1.6.11 → 1.6.14
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/README.md +4 -4
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/src/transaction/broadcasters/DefaultBroadcaster.js +1 -1
- package/dist/cjs/src/transaction/broadcasters/DefaultBroadcaster.js.map +1 -1
- package/dist/cjs/src/wallet/WalletClient.js +1 -0
- package/dist/cjs/src/wallet/WalletClient.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/transaction/broadcasters/DefaultBroadcaster.js +1 -1
- package/dist/esm/src/transaction/broadcasters/DefaultBroadcaster.js.map +1 -1
- package/dist/esm/src/wallet/WalletClient.js +1 -0
- package/dist/esm/src/wallet/WalletClient.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/wallet/WalletClient.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/dist/umd/bundle.js +1 -1
- package/docs/MARKDOWN_VALIDATION_GUIDE.md +175 -0
- package/docs/concepts/beef.md +8 -0
- package/docs/concepts/chain-tracking.md +12 -0
- package/docs/concepts/decentralized-identity.md +37 -0
- package/docs/concepts/fees.md +32 -0
- package/docs/concepts/identity-certificates.md +53 -1
- package/docs/concepts/index.md +15 -0
- package/docs/concepts/key-management.md +9 -0
- package/docs/concepts/script-templates.md +13 -0
- package/docs/concepts/sdk-philosophy.md +8 -0
- package/docs/concepts/signatures.md +15 -0
- package/docs/concepts/spv-verification.md +12 -0
- package/docs/concepts/transaction-encoding.md +19 -0
- package/docs/concepts/transaction-structure.md +4 -0
- package/docs/concepts/trust-model.md +16 -0
- package/docs/concepts/verification.md +31 -0
- package/docs/concepts/wallet-integration.md +6 -0
- package/docs/guides/development-wallet-setup.md +374 -0
- package/docs/guides/direct-transaction-creation.md +12 -2
- package/docs/guides/http-client-configuration.md +122 -48
- package/docs/guides/index.md +117 -9
- package/docs/guides/large-transactions.md +448 -0
- package/docs/guides/multisig-transactions.md +792 -0
- package/docs/guides/security-best-practices.md +494 -0
- package/docs/guides/transaction-batching.md +132 -0
- package/docs/guides/transaction-signing-methods.md +230 -79
- package/docs/index.md +0 -2
- package/docs/reference/auth.md +212 -159
- package/docs/reference/compat.md +120 -96
- package/docs/reference/configuration.md +6 -0
- package/docs/reference/debugging.md +5 -0
- package/docs/reference/errors.md +50 -0
- package/docs/reference/identity.md +21 -12
- package/docs/reference/index.md +14 -1
- package/docs/reference/kvstore.md +21 -19
- package/docs/reference/messages.md +3 -0
- package/docs/reference/op-codes.md +20 -1
- package/docs/reference/overlay-tools.md +46 -18
- package/docs/reference/primitives.md +571 -390
- package/docs/reference/registry.md +43 -20
- package/docs/reference/script.md +140 -105
- package/docs/reference/storage.md +32 -12
- package/docs/reference/totp.md +16 -11
- package/docs/reference/transaction-signatures.md +2 -1
- package/docs/reference/transaction.md +201 -120
- package/docs/reference/wallet.md +241 -64
- package/docs/tutorials/advanced-transaction.md +1 -4
- package/docs/tutorials/aes-encryption.md +3 -1
- package/docs/tutorials/authfetch-tutorial.md +29 -0
- package/docs/tutorials/ecdh-key-exchange.md +2 -0
- package/docs/tutorials/elliptic-curve-fundamentals.md +3 -0
- package/docs/tutorials/error-handling.md +1 -0
- package/docs/tutorials/first-transaction-low-level.md +1 -0
- package/docs/tutorials/first-transaction.md +5 -8
- package/docs/tutorials/hashes-and-hmacs.md +5 -31
- package/docs/tutorials/identity-management.md +27 -0
- package/docs/tutorials/index.md +114 -77
- package/docs/tutorials/key-management.md +5 -3
- package/docs/tutorials/protowallet-development.md +27 -0
- package/docs/tutorials/spv-merkle-proofs.md +9 -6
- package/docs/tutorials/testnet-transactions-low-level.md +25 -18
- package/docs/tutorials/transaction-broadcasting.md +10 -7
- package/docs/tutorials/transaction-types.md +5 -4
- package/docs/tutorials/type-42.md +0 -14
- package/docs/tutorials/uhrp-storage.md +23 -3
- package/package.json +1 -1
- package/src/identity/README.md +0 -1
- package/src/primitives/__tests/SymmetricKey.test.ts +45 -0
- package/src/primitives/__tests/SymmetricKeyCompatibility.test.ts +150 -0
- package/src/transaction/__tests/Transaction.test.ts +1 -1
- package/src/transaction/broadcasters/DefaultBroadcaster.ts +1 -1
- package/src/transaction/broadcasters/__tests/ARC.test.ts +1 -1
- package/src/wallet/WalletClient.ts +1 -0
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
**Prerequisites**: Completed "Your First BSV Transaction" tutorial, Node.js, basic TypeScript knowledge
|
|
5
5
|
|
|
6
6
|
## Learning Goals
|
|
7
|
+
|
|
7
8
|
- Generate and manage private/public keys
|
|
8
9
|
- Understand ECDSA signatures
|
|
9
10
|
- Create and verify digital signatures
|
|
@@ -373,7 +374,6 @@ Run the script:
|
|
|
373
374
|
npx ts-node signatures-low-level.ts
|
|
374
375
|
```
|
|
375
376
|
|
|
376
|
-
|
|
377
377
|
### Key Benefits of `WalletClient` for Signatures
|
|
378
378
|
|
|
379
379
|
1. **Enhanced Security**: Private keys never leave the wallet environment
|
|
@@ -383,7 +383,7 @@ npx ts-node signatures-low-level.ts
|
|
|
383
383
|
|
|
384
384
|
## Step 5: Practical Application: Signing Transactions with `WalletClient`
|
|
385
385
|
|
|
386
|
-
Let's put our knowledge to practical use by creating and signing a Bitcoin transaction using the `WalletClient`.
|
|
386
|
+
Let's put our knowledge to practical use by creating and signing a Bitcoin transaction using the `WalletClient`.
|
|
387
387
|
|
|
388
388
|
Create a file called `wallet-transaction-signing.ts`:
|
|
389
389
|
|
|
@@ -502,6 +502,7 @@ npx ts-node wallet-transaction-signing.ts
|
|
|
502
502
|
```
|
|
503
503
|
|
|
504
504
|
This example demonstrates:
|
|
505
|
+
|
|
505
506
|
1. Creating a transaction with inputs and outputs
|
|
506
507
|
2. Getting the transaction hash that needs to be signed
|
|
507
508
|
3. How the `WalletClient` would sign this hash securely
|
|
@@ -525,7 +526,8 @@ Congratulations! You've learned the fundamentals of key management and cryptogra
|
|
|
525
526
|
|
|
526
527
|
These cryptographic concepts form the foundation of Bitcoin and blockchain technology. By understanding how keys and signatures work, you're well-equipped to build secure and robust applications using the BSV TypeScript SDK.
|
|
527
528
|
|
|
528
|
-
For more advanced techniques like different signature hash types (SIGHASH flags), manual signature creation, and multi-signature transactions, refer to the
|
|
529
|
+
For more advanced techniques like different signature hash types (SIGHASH flags), manual signature creation, and multi-signature transactions, refer to the following documents:
|
|
530
|
+
|
|
529
531
|
- [Advanced Transaction Signing](../guides/advanced-transaction-signing.md) (How-To Guide)
|
|
530
532
|
- [Transaction Signatures Reference](../reference/transaction-signatures.md) (Technical Reference)
|
|
531
533
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
**Duration**: 45 minutes
|
|
4
4
|
**Prerequisites**: Node.js, basic TypeScript knowledge, completed "Your First BSV Transaction" tutorial
|
|
5
5
|
**Learning Goals**:
|
|
6
|
+
|
|
6
7
|
- Understand ProtoWallet's role in development and testing
|
|
7
8
|
- Implement cryptographic operations without blockchain interaction
|
|
8
9
|
- Use ProtoWallet for key derivation and signing
|
|
@@ -20,6 +21,7 @@ ProtoWallet is a lightweight wallet implementation designed for development and
|
|
|
20
21
|
## What You'll Build
|
|
21
22
|
|
|
22
23
|
In this tutorial, you'll create a development toolkit using ProtoWallet that includes:
|
|
24
|
+
|
|
23
25
|
- Key generation and management
|
|
24
26
|
- Message signing and verification
|
|
25
27
|
- Symmetric encryption/decryption
|
|
@@ -714,3 +716,28 @@ async function runTestSuite() {
|
|
|
714
716
|
}
|
|
715
717
|
|
|
716
718
|
runTestSuite().catch(console.error)
|
|
719
|
+
```
|
|
720
|
+
|
|
721
|
+
## Conclusion
|
|
722
|
+
|
|
723
|
+
Congratulations! You've successfully built a comprehensive ProtoWallet development framework using the BSV TypeScript SDK. In this tutorial, you've learned how to create, test, and manage prototype wallet implementations for rapid development and testing.
|
|
724
|
+
|
|
725
|
+
### Core Concepts Mastered
|
|
726
|
+
|
|
727
|
+
1. **ProtoWallet Architecture**: Implemented lightweight wallet prototypes for development and testing
|
|
728
|
+
2. **Key Management**: Created deterministic key generation and management systems
|
|
729
|
+
3. **Cryptographic Operations**: Implemented signing, encryption, and HMAC operations
|
|
730
|
+
4. **Protocol Integration**: Built protocol-specific wallet functionality with proper key derivation
|
|
731
|
+
5. **Testing Framework**: Developed comprehensive testing utilities for wallet validation
|
|
732
|
+
|
|
733
|
+
## Next Steps
|
|
734
|
+
|
|
735
|
+
- Learn about [Development Wallet Setup](../guides/development-wallet-setup.md) for production-ready wallet implementation
|
|
736
|
+
- Explore [Key Management](./key-management.md) for advanced cryptographic key handling
|
|
737
|
+
- Understand [Security Best Practices](../guides/security-best-practices.md) for secure wallet development
|
|
738
|
+
|
|
739
|
+
## Additional Resources
|
|
740
|
+
|
|
741
|
+
- [Wallet API Reference](../reference/wallet.md)
|
|
742
|
+
- [Key Management Concepts](../concepts/key-management.md)
|
|
743
|
+
- [BSV Wallet Standards](https://projectbabbage.com/docs/guides/wallet/)
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
Simplified Payment Verification (SPV) is a method for verifying Bitcoin transactions without downloading the entire blockchain. Instead of storing all transaction data, SPV clients only need block headers and merkle proofs to verify that specific transactions are included in the blockchain.
|
|
6
6
|
|
|
7
7
|
This tutorial covers:
|
|
8
|
+
|
|
8
9
|
- Understanding SPV principles and merkle trees
|
|
9
10
|
- Working with merkle proofs using the `MerklePath` class
|
|
10
11
|
- Verifying transactions with the `Transaction.verify()` method
|
|
@@ -85,6 +86,7 @@ runMerkleExample().catch(console.error)
|
|
|
85
86
|
The example above demonstrates the fundamental concepts using a simplified 2-transaction block. In real BSV blockchain scenarios, blocks contain hundreds or thousands of transactions, creating much deeper merkle trees.
|
|
86
87
|
|
|
87
88
|
**Our Working Example:**
|
|
89
|
+
|
|
88
90
|
- **Block Height**: 850000 (arbitrary example height)
|
|
89
91
|
- **Transaction ID**: `ffeff11c25cde7c06d407490d81ef4d0db64aad6ab3d14393530701561a465ef` (from BSV Technical Standards)
|
|
90
92
|
- **Sibling Hash**: `b9ef07a62553ef8b0898a79c291b92c60f7932260888bde0dab2dd2610d8668e` (from BSV Technical Standards)
|
|
@@ -92,6 +94,7 @@ The example above demonstrates the fundamental concepts using a simplified 2-tra
|
|
|
92
94
|
|
|
93
95
|
**Real-World Complexity:**
|
|
94
96
|
In actual BSV blocks, a transaction at index 12 (like in the BSV Technical Standards example) would require a merkle path with multiple levels:
|
|
97
|
+
|
|
95
98
|
- **5 proof levels** for a block with ~32 transactions
|
|
96
99
|
- **10 proof levels** for a block with ~1024 transactions
|
|
97
100
|
- **20 proof levels** for a block with ~1 million transactions
|
|
@@ -116,10 +119,12 @@ The SDK handles the complex offset calculations automatically when parsing from
|
|
|
116
119
|
The BSV TypeScript SDK uses an internal object format for MerklePath construction, while the [BSV Technical Standards](https://tsc.bsvblockchain.org/standards/merkle-proof-standardised-format/) define a binary serialization format. The SDK handles the conversion between these formats internally.
|
|
117
120
|
|
|
118
121
|
**Internal Format (used above):**
|
|
122
|
+
|
|
119
123
|
- Array of levels, each containing leaf objects with `offset`, `hash`, `txid`, and `duplicate` properties
|
|
120
124
|
- Direct construction allows for clear understanding of the merkle tree structure
|
|
121
125
|
|
|
122
126
|
**Binary Format (from standards):**
|
|
127
|
+
|
|
123
128
|
- Compact binary representation for network transmission and storage
|
|
124
129
|
- Can be parsed using `MerklePath.fromHex()` when properly formatted
|
|
125
130
|
|
|
@@ -149,6 +154,7 @@ console.log('Merkle root matches expected:', merkleRoot === '6f0a2a566d54512576b
|
|
|
149
154
|
The merkle root computation follows a specific mathematical process:
|
|
150
155
|
|
|
151
156
|
**For a 2-transaction block (our example):**
|
|
157
|
+
|
|
152
158
|
```
|
|
153
159
|
Level 0 (Leaves): [Transaction A] [Transaction B]
|
|
154
160
|
| |
|
|
@@ -156,12 +162,14 @@ Level 1 (Root): [Hash(A + B)]
|
|
|
156
162
|
```
|
|
157
163
|
|
|
158
164
|
**Step-by-step process:**
|
|
165
|
+
|
|
159
166
|
1. **Start with transaction IDs** (already hashed)
|
|
160
167
|
2. **Concatenate them**: `ffeff11c...465ef` + `b9ef07a6...8668e`
|
|
161
168
|
3. **Double SHA256**: `SHA256(SHA256(concatenated_data))`
|
|
162
169
|
4. **Result**: The merkle root that represents the entire block
|
|
163
170
|
|
|
164
171
|
**For larger blocks (e.g., 4 transactions):**
|
|
172
|
+
|
|
165
173
|
```
|
|
166
174
|
Level 0: [Tx A] [Tx B] [Tx C] [Tx D]
|
|
167
175
|
| | | |
|
|
@@ -653,6 +661,7 @@ SPV and merkle proof verification enable lightweight Bitcoin clients to verify t
|
|
|
653
661
|
- **BEEF**: Efficient SPV data structures
|
|
654
662
|
|
|
655
663
|
Key takeaways:
|
|
664
|
+
|
|
656
665
|
- SPV trades storage for bandwidth and computation
|
|
657
666
|
- Merkle proofs provide cryptographic inclusion proofs
|
|
658
667
|
- Chain trackers ensure merkle roots are valid
|
|
@@ -674,9 +683,3 @@ Understanding of `WalletClient` usage is also important for building robust appl
|
|
|
674
683
|
| **Security** | High | High | High |
|
|
675
684
|
|
|
676
685
|
The `WalletClient` approach is recommended for most applications, while SPV verification is valuable for specialized lightweight applications.
|
|
677
|
-
|
|
678
|
-
```typescript
|
|
679
|
-
// Example usage
|
|
680
|
-
const walletClient = new WalletClient('main')
|
|
681
|
-
const isValid = await walletClient.verifyTransaction(beefHex)
|
|
682
|
-
console.log('Transaction valid:', isValid)
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
**Prerequisites**: Completed "Your First BSV Transaction" tutorial, Node.js, basic TypeScript knowledge
|
|
5
5
|
|
|
6
6
|
## Learning Goals
|
|
7
|
+
|
|
7
8
|
- Set up a BSV testnet environment
|
|
8
9
|
- Obtain and manage testnet coins
|
|
9
10
|
- Create and broadcast real transactions on the testnet
|
|
@@ -136,14 +137,17 @@ After requesting coins from a faucet, you'll need to verify that you received th
|
|
|
136
137
|
6. Click on the transaction ID (txid) to view the full transaction details
|
|
137
138
|
|
|
138
139
|
7. On the transaction details page, find the following information:
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
140
|
+
|
|
141
|
+
- **Transaction ID (txid)**: This is the long hexadecimal string at the top of the page (e.g., `7f4e6ea49a847f557fccd9bf99d4a07ac103e5e8cb3464abb852af552516317e`)
|
|
142
|
+
- **Output Index**: In the "Outputs" section, find your address and note its index number (0-based). If your address is the first output, the index is 0.
|
|
143
|
+
- **Output Amount**: Note the amount sent to your address in this specific output. WhatsOnChain displays amounts in BSV (e.g., 0.00010000 BSV), but our code needs satoshis. To convert:
|
|
144
|
+
|
|
145
|
+
- 1 BSV = 100,000,000 satoshis
|
|
146
|
+
- Example: 0.00010000 BSV = 10,000 satoshis (multiply by 100,000,000)
|
|
147
|
+
- You can use a calculator or simply move the decimal point 8 places to the right
|
|
145
148
|
|
|
146
149
|
8. Write down or copy these three pieces of information:
|
|
150
|
+
|
|
147
151
|
```
|
|
148
152
|
Transaction ID (txid): [your transaction id]
|
|
149
153
|
Output Index: [your output index, usually 0]
|
|
@@ -165,9 +169,10 @@ In the same way, when creating a Bitcoin transaction:
|
|
|
165
169
|
|
|
166
170
|
1. **You spend the entire UTXO** (even if you only want to send a portion of it)
|
|
167
171
|
2. **You specify how to distribute those funds**:
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
172
|
+
|
|
173
|
+
- Some goes to the recipient (the payment)
|
|
174
|
+
- Some goes to the miners (the transaction fee)
|
|
175
|
+
- The remainder comes back to you (the change)
|
|
171
176
|
|
|
172
177
|
### Prerequisites
|
|
173
178
|
|
|
@@ -190,21 +195,21 @@ import https from 'https'
|
|
|
190
195
|
|
|
191
196
|
async function main() {
|
|
192
197
|
try {
|
|
193
|
-
// 1
|
|
198
|
+
// Step 1: Set up your wallet
|
|
194
199
|
const privateKey = PrivateKey.fromWif('your_testnet_private_key_here')
|
|
195
200
|
const myAddress = privateKey.toAddress([0x6f]) // 0x6f is the testnet prefix
|
|
196
201
|
const recipientAddress = 'testnet_address_to_send_coins_to'
|
|
197
202
|
|
|
198
|
-
// 2
|
|
203
|
+
// Step 2: Fetch the full transaction hex
|
|
199
204
|
const txid = 'source_transaction_id_here'
|
|
200
205
|
const response = await fetch(`https://api.whatsonchain.com/v1/bsv/test/tx/${txid}/hex`)
|
|
201
206
|
const sourceTxHex = await response.text()
|
|
202
207
|
console.log(`Retrieved transaction hex (first 50 chars): ${sourceTxHex.substring(0, 50)}...`)
|
|
203
208
|
|
|
204
|
-
// 3
|
|
209
|
+
// Step 3: Create a transaction
|
|
205
210
|
const tx = new Transaction()
|
|
206
211
|
|
|
207
|
-
// 4
|
|
212
|
+
// Step 4: Add the input
|
|
208
213
|
// For testnet, we need the hex of the transaction that contains our UTXO
|
|
209
214
|
tx.addInput({
|
|
210
215
|
sourceTransaction: Transaction.fromHex(sourceTxHex),
|
|
@@ -212,23 +217,23 @@ async function main() {
|
|
|
212
217
|
unlockingScriptTemplate: new P2PKH().unlock(privateKey)
|
|
213
218
|
})
|
|
214
219
|
|
|
215
|
-
// 5
|
|
220
|
+
// Step 5: Add the recipient output
|
|
216
221
|
tx.addOutput({
|
|
217
222
|
lockingScript: new P2PKH().lock(recipientAddress),
|
|
218
223
|
satoshis: 100 // Amount to send (must be less than input amount)
|
|
219
224
|
})
|
|
220
225
|
|
|
221
|
-
// 6
|
|
226
|
+
// Step 6: Add the change output back to our address
|
|
222
227
|
tx.addOutput({
|
|
223
228
|
lockingScript: new P2PKH().lock(myAddress),
|
|
224
229
|
change: true // SDK will automatically calculate the change amount
|
|
225
230
|
})
|
|
226
231
|
|
|
227
|
-
// 7
|
|
232
|
+
// Step 7: Calculate fee and sign the transaction
|
|
228
233
|
await tx.fee()
|
|
229
234
|
await tx.sign()
|
|
230
235
|
|
|
231
|
-
// 8
|
|
236
|
+
// Step 8: Broadcast the transaction to the testnet using ARC
|
|
232
237
|
// You need to provide your Taal API key here
|
|
233
238
|
// Get it by signing up at https://console.taal.com
|
|
234
239
|
const apiKey = 'your_taal_api_key_here' // Replace with your actual API key
|
|
@@ -246,7 +251,7 @@ async function main() {
|
|
|
246
251
|
const result = await tx.broadcast(arc)
|
|
247
252
|
console.log('ARC Response:', JSON.stringify(result, null, 2)) // Log the full response for debugging
|
|
248
253
|
|
|
249
|
-
// 9
|
|
254
|
+
// Step 9: Display the transaction ID
|
|
250
255
|
console.log(`Transaction ID: ${Buffer.from(tx.id()).toString('hex')}`)
|
|
251
256
|
console.log(`View on explorer: https://test.whatsonchain.com/tx/${Buffer.from(tx.id()).toString('hex')}`)
|
|
252
257
|
console.log('Transaction broadcast successfully!')
|
|
@@ -295,11 +300,13 @@ await tx.fee()
|
|
|
295
300
|
```
|
|
296
301
|
|
|
297
302
|
This method automatically calculates the appropriate fee based on:
|
|
303
|
+
|
|
298
304
|
- The size of your transaction (in bytes)
|
|
299
305
|
- Current network fee rates
|
|
300
306
|
- Number of inputs and outputs
|
|
301
307
|
|
|
302
308
|
The `change: true` parameter in our change output works with the fee calculation to:
|
|
309
|
+
|
|
303
310
|
1. Calculate the appropriate fee amount
|
|
304
311
|
2. Subtract that fee from the total input amount
|
|
305
312
|
3. Allocate the remaining balance to the change address
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
**Prerequisites**: Completed "Your First BSV Transaction" tutorial, Node.js, basic TypeScript knowledge
|
|
5
5
|
|
|
6
6
|
## Learning Goals
|
|
7
|
+
|
|
7
8
|
- Understand how transaction broadcasting works in BSV
|
|
8
9
|
- Learn the difference between `WalletClient` and direct broadcasting approaches
|
|
9
10
|
- Configure broadcasting for testnet vs mainnet
|
|
@@ -32,11 +33,12 @@ Your App → WalletClient → Wallet → Mining Services → BSV Network
|
|
|
32
33
|
```
|
|
33
34
|
|
|
34
35
|
The Wallet acts as a proxy that:
|
|
35
|
-
|
|
36
|
+
|
|
37
|
+
- Manages your broadcasting preferences
|
|
36
38
|
- Handles fallback logic between different services
|
|
37
39
|
- Provides a consistent API regardless of the underlying service
|
|
38
40
|
|
|
39
|
-
Due to its simplicity, this is the recommended approach.
|
|
41
|
+
Due to its simplicity, this is the recommended approach.
|
|
40
42
|
|
|
41
43
|
### Direct Broadcasting Flow
|
|
42
44
|
|
|
@@ -47,6 +49,7 @@ Your App → Custom Broadcaster → Mining Service API → BSV Network
|
|
|
47
49
|
```
|
|
48
50
|
|
|
49
51
|
This approach gives you:
|
|
52
|
+
|
|
50
53
|
- Full control over which service to use
|
|
51
54
|
- Direct error handling and response processing
|
|
52
55
|
- Ability to implement custom retry logic
|
|
@@ -56,7 +59,7 @@ Due to its complexity and need to handle the low-level details of the broadcasti
|
|
|
56
59
|
|
|
57
60
|
## Step 1: WalletClient Broadcasting
|
|
58
61
|
|
|
59
|
-
Let's start with the `WalletClient` approach, which is the simplest for most applications. This is the same approach we have seen in the previous tutorials, where we used the `WalletClient` to create and broadcast transactions.
|
|
62
|
+
Let's start with the `WalletClient` approach, which is the simplest for most applications. This is the same approach we have seen in the previous tutorials, where we used the `WalletClient` to create and broadcast transactions.
|
|
60
63
|
|
|
61
64
|
### Basic WalletClient Setup
|
|
62
65
|
|
|
@@ -184,12 +187,11 @@ When you use `WalletClient`:
|
|
|
184
187
|
5. **Response**: You receive either a transaction ID (success) or an error message
|
|
185
188
|
|
|
186
189
|
The key advantage is that **you don't control the broadcasting directly** - the BRC-100 wallet handles it based on its configuration. This means:
|
|
190
|
+
|
|
187
191
|
- ✅ Easy to use - no need to manage API keys or endpoints
|
|
188
192
|
- ✅ Fallback logic built-in
|
|
189
193
|
- ✅ User can configure preferred services through the wallet UI
|
|
190
194
|
|
|
191
|
-
|
|
192
|
-
|
|
193
195
|
## Step 2: Direct Broadcasting with Custom Broadcasters
|
|
194
196
|
|
|
195
197
|
The `WalletClient` approach in step 1 is the recommended approach. However, if you need more control, you can broadcast transactions directly using custom broadcaster implementations. We will demonstrate the main broadcaster implementations in the SDK: ARC and WhatsOnChain.
|
|
@@ -203,6 +205,7 @@ The `WalletClient` approach in step 1 is the recommended approach. However, if y
|
|
|
203
205
|
3. **Manual broadcast**: Use your chosen broadcaster to submit the transaction
|
|
204
206
|
|
|
205
207
|
This approach is useful when you need to:
|
|
208
|
+
|
|
206
209
|
- Use a specific broadcasting service (ARC, WhatsOnChain, etc.)
|
|
207
210
|
- Implement custom retry logic or error handling
|
|
208
211
|
- Broadcast to multiple services for redundancy
|
|
@@ -511,19 +514,19 @@ monitoringExample('your-transaction-id-here')
|
|
|
511
514
|
In this tutorial, you learned about the two main approaches to transaction broadcasting in BSV:
|
|
512
515
|
|
|
513
516
|
### `WalletClient` Approach
|
|
517
|
+
|
|
514
518
|
- ✅ **Simple**: Easy to use with BRC-100 wallets
|
|
515
519
|
- ✅ **Managed**: Wallet handles service selection and fallbacks
|
|
516
520
|
- ✅ **User Control**: Users can configure preferred services
|
|
517
521
|
|
|
518
|
-
|
|
519
522
|
### Direct Broadcasting Approach
|
|
523
|
+
|
|
520
524
|
- ✅ **Full Control**: Choose exactly which service to use
|
|
521
525
|
- ✅ **No Dependencies**: Works without external wallet software
|
|
522
526
|
- ✅ **Custom Logic**: Implement your own retry and fallback logic
|
|
523
527
|
- ✅ **Error Handling**: Direct access to service responses
|
|
524
528
|
- ❌ **More Complex**: Requires more setup and configuration
|
|
525
529
|
|
|
526
|
-
|
|
527
530
|
### Next Steps
|
|
528
531
|
|
|
529
532
|
- Experiment with different broadcaster configurations
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
**Prerequisites**: Completed "Your First BSV Transaction" tutorial, Node.js, basic TypeScript knowledge
|
|
5
5
|
|
|
6
6
|
## Learning Goals
|
|
7
|
+
|
|
7
8
|
- Create transactions with multiple outputs
|
|
8
9
|
- Add data to transactions
|
|
9
10
|
- Work with different output types
|
|
@@ -314,10 +315,10 @@ In the BSV SDK, "baskets" are a powerful UTXO management concept that allows you
|
|
|
314
315
|
|
|
315
316
|
Baskets help with:
|
|
316
317
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
318
|
+
- **UTXO organization**: Group outputs for different purposes or applications
|
|
319
|
+
- **Transaction optimization**: Control which UTXOs are used for specific transaction types
|
|
320
|
+
- **Privacy enhancement**: Segregate UTXOs from different sources or uses
|
|
321
|
+
- **Application-specific management**: Maintain dedicated UTXOs for particular applications
|
|
321
322
|
|
|
322
323
|
The `WalletClient` provides methods for working with baskets to give you fine-grained control over your UTXO management:
|
|
323
324
|
|
|
@@ -566,17 +566,3 @@ Type-42 enables sophisticated cryptographic protocols while maintaining the secu
|
|
|
566
566
|
- [Elliptic Curve Fundamentals Tutorial](./elliptic-curve-fundamentals.md)
|
|
567
567
|
- [BSV Type-42 Documentation](https://docs.bsvblockchain.org/guides/sdks/ts/low-level/type_42)
|
|
568
568
|
- [Messages Reference](../reference/messages.md)
|
|
569
|
-
|
|
570
|
-
## Integration with `WalletClient`
|
|
571
|
-
|
|
572
|
-
For production applications, the `WalletClient` provides secure key management for Type-42 operations:
|
|
573
|
-
|
|
574
|
-
```typescript
|
|
575
|
-
// Usage example
|
|
576
|
-
const walletClient = new WalletClient('https://api.bsvwallet.com/v1')
|
|
577
|
-
const alice = walletClient.getPrivateKey('alice')
|
|
578
|
-
const bob = walletClient.getPrivateKey('bob')
|
|
579
|
-
const invoiceNumber = '2-secure-operation-001'
|
|
580
|
-
|
|
581
|
-
const derivedKey = alice.deriveChild(bob.toPublicKey(), invoiceNumber)
|
|
582
|
-
console.log('Derived key:', derivedKey.toHex().substring(0, 16) + '...')
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
**Duration**: 75 minutes
|
|
4
4
|
**Prerequisites**: Node.js, basic TypeScript knowledge, understanding of decentralized storage and `WalletClient` usage
|
|
5
5
|
**Learning Goals**:
|
|
6
|
+
|
|
6
7
|
- Understand UHRP (Universal Hash Resource Protocol)
|
|
7
8
|
- Upload and download files using StorageUploader/StorageDownloader
|
|
8
9
|
- Implement decentralized file management systems
|
|
@@ -15,17 +16,21 @@ UHRP (Universal Hash Resource Protocol) is a decentralized file storage system t
|
|
|
15
16
|
## Prerequisites
|
|
16
17
|
|
|
17
18
|
### For Upload Operations
|
|
19
|
+
|
|
18
20
|
- **BRC-100 compliant wallet** (such as MetaNet Desktop Wallet) must be installed and running
|
|
19
|
-
- **Wallet connection** accessible via JSON API (typically http://localhost:3321)
|
|
21
|
+
- **Wallet connection** accessible via JSON API (typically <http://localhost:3321>)
|
|
20
22
|
- **Sufficient wallet balance** for transaction fees and storage costs
|
|
21
23
|
- **UHRP storage service** - This tutorial uses `https://nanostore.babbage.systems`
|
|
22
24
|
|
|
23
25
|
### For Download Operations Only
|
|
26
|
+
|
|
24
27
|
- **No wallet connection required** - downloads work independently
|
|
25
28
|
- **Network access** to resolve UHRP URLs via lookup services
|
|
26
29
|
|
|
27
30
|
### Service Availability
|
|
31
|
+
|
|
28
32
|
**Important Note**: This tutorial uses `https://nanostore.babbage.systems`, which is a working UHRP storage service. The examples demonstrate correct SDK usage patterns and will work with:
|
|
33
|
+
|
|
29
34
|
- A running BRC-100 compliant wallet (such as MetaNet Desktop Wallet)
|
|
30
35
|
- Sufficient wallet balance for storage fees
|
|
31
36
|
|
|
@@ -328,6 +333,7 @@ async function demonstrateFileManager() {
|
|
|
328
333
|
}
|
|
329
334
|
|
|
330
335
|
demonstrateFileManager().catch(console.error)
|
|
336
|
+
```
|
|
331
337
|
|
|
332
338
|
## Advanced Features
|
|
333
339
|
|
|
@@ -484,39 +490,49 @@ async function demonstrateBatchOperations() {
|
|
|
484
490
|
}
|
|
485
491
|
|
|
486
492
|
demonstrateBatchOperations().catch(console.error)
|
|
493
|
+
```
|
|
487
494
|
|
|
488
495
|
## Troubleshooting
|
|
489
496
|
|
|
490
497
|
### Common Issues and Solutions
|
|
491
498
|
|
|
492
499
|
#### "No wallet available" Error
|
|
500
|
+
|
|
493
501
|
**Problem**: StorageUploader fails with "No wallet available over any communication substrate"
|
|
494
|
-
**Solution**:
|
|
502
|
+
**Solution**:
|
|
503
|
+
|
|
495
504
|
- Install and run a BRC-100 compliant wallet (e.g., MetaNet Desktop Wallet)
|
|
496
|
-
- Ensure wallet is accessible at http://localhost:3321
|
|
505
|
+
- Ensure wallet is accessible at <http://localhost:3321>
|
|
497
506
|
- Verify wallet is fully synced and has sufficient balance
|
|
498
507
|
|
|
499
508
|
#### "401 Unauthorized" Error
|
|
509
|
+
|
|
500
510
|
**Problem**: Upload operations fail with HTTP 401 errors
|
|
501
511
|
**Solution**:
|
|
512
|
+
|
|
502
513
|
- Verify your wallet is properly authenticated
|
|
503
514
|
- Check that the UHRP storage service is available
|
|
504
515
|
- Ensure your wallet has sufficient balance for storage fees
|
|
505
516
|
|
|
506
517
|
#### "Invalid parameter UHRP url" Error
|
|
518
|
+
|
|
507
519
|
**Problem**: Download operations fail with invalid URL error
|
|
508
520
|
**Solution**:
|
|
521
|
+
|
|
509
522
|
- Verify the UHRP URL format (should start with `uhrp://`)
|
|
510
523
|
- Check that the file hasn’t expired
|
|
511
524
|
- Ensure network connectivity for UHRP lookup services
|
|
512
525
|
|
|
513
526
|
#### Download Works but Upload Fails
|
|
527
|
+
|
|
514
528
|
**Problem**: StorageDownloader works but StorageUploader fails
|
|
515
529
|
**Solution**: This is expected behavior without a wallet connection. StorageDownloader works independently, while StorageUploader requires wallet authentication.
|
|
516
530
|
|
|
517
531
|
#### Service Unavailable
|
|
532
|
+
|
|
518
533
|
**Problem**: UHRP storage service returns errors or is unreachable
|
|
519
534
|
**Solution**:
|
|
535
|
+
|
|
520
536
|
- Try alternative UHRP storage services
|
|
521
537
|
- Check service status and availability
|
|
522
538
|
- Consider setting up your own UHRP storage infrastructure
|
|
@@ -524,21 +540,25 @@ demonstrateBatchOperations().catch(console.error)
|
|
|
524
540
|
## Best Practices
|
|
525
541
|
|
|
526
542
|
### 1. File Management
|
|
543
|
+
|
|
527
544
|
- Use meaningful file names and metadata
|
|
528
545
|
- Implement proper retention policies
|
|
529
546
|
- Tag files for easy organization and retrieval
|
|
530
547
|
|
|
531
548
|
### 2. Error Handling
|
|
549
|
+
|
|
532
550
|
- Always validate file integrity after download
|
|
533
551
|
- Implement retry logic for network failures
|
|
534
552
|
- Handle storage quota and payment requirements
|
|
535
553
|
|
|
536
554
|
### 3. Performance
|
|
555
|
+
|
|
537
556
|
- Use batch operations for multiple files
|
|
538
557
|
- Implement caching for frequently accessed files
|
|
539
558
|
- Monitor file expiration and renewal needs
|
|
540
559
|
|
|
541
560
|
### 4. Security
|
|
561
|
+
|
|
542
562
|
- Encrypt sensitive files before upload
|
|
543
563
|
- Use authenticated storage endpoints
|
|
544
564
|
- Validate file types and sizes
|
package/package.json
CHANGED
package/src/identity/README.md
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import SymmetricKey from '../../primitives/SymmetricKey'
|
|
2
|
+
import PrivateKey from '../../primitives/PrivateKey'
|
|
2
3
|
import vectors from './SymmetricKey.vectors'
|
|
3
4
|
|
|
4
5
|
const KEYS: SymmetricKey[] = [
|
|
@@ -58,4 +59,48 @@ describe('SymmetricKey', () => {
|
|
|
58
59
|
expect(result).toEqual(Buffer.from(vector.plaintext).toString('hex'))
|
|
59
60
|
})
|
|
60
61
|
})
|
|
62
|
+
|
|
63
|
+
describe('31-byte and 32-byte key encryption', () => {
|
|
64
|
+
it('encrypts and decrypts with 31-byte key', () => {
|
|
65
|
+
// Use a private key that generates a 31-byte X coordinate
|
|
66
|
+
const privKey = PrivateKey.fromWif('L4B2postXdaP7TiUrUBYs53Fqzheu7WhSoQVPuY8qBdoBeEwbmZx')
|
|
67
|
+
const pubKey = privKey.toPublicKey()
|
|
68
|
+
|
|
69
|
+
expect(pubKey.x).toBeTruthy()
|
|
70
|
+
const keyArray = pubKey.x!.toArray()
|
|
71
|
+
|
|
72
|
+
// Verify this is indeed a 31-byte key
|
|
73
|
+
expect(keyArray.length).toBe(31)
|
|
74
|
+
|
|
75
|
+
const symKey = new SymmetricKey(keyArray)
|
|
76
|
+
const plaintext = 'test message'
|
|
77
|
+
|
|
78
|
+
// Test encryption and decryption
|
|
79
|
+
const ciphertext = symKey.encrypt(plaintext)
|
|
80
|
+
const decrypted = symKey.decrypt(ciphertext, 'utf8')
|
|
81
|
+
|
|
82
|
+
expect(decrypted).toBe(plaintext)
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
it('encrypts and decrypts with 32-byte key', () => {
|
|
86
|
+
// Use a private key that generates a 32-byte X coordinate
|
|
87
|
+
const privKey = PrivateKey.fromWif('KyLGEhYicSoGchHKmVC2fUx2MRrHzWqvwBFLLT4DZB93Nv5DxVR9')
|
|
88
|
+
const pubKey = privKey.toPublicKey()
|
|
89
|
+
|
|
90
|
+
expect(pubKey.x).toBeTruthy()
|
|
91
|
+
const keyArray = pubKey.x!.toArray()
|
|
92
|
+
|
|
93
|
+
// Verify this is indeed a 32-byte key
|
|
94
|
+
expect(keyArray.length).toBe(32)
|
|
95
|
+
|
|
96
|
+
const symKey = new SymmetricKey(keyArray)
|
|
97
|
+
const plaintext = 'test message'
|
|
98
|
+
|
|
99
|
+
// Test encryption and decryption
|
|
100
|
+
const ciphertext = symKey.encrypt(plaintext)
|
|
101
|
+
const decrypted = symKey.decrypt(ciphertext, 'utf8')
|
|
102
|
+
|
|
103
|
+
expect(decrypted).toBe(plaintext)
|
|
104
|
+
})
|
|
105
|
+
})
|
|
61
106
|
})
|