@bsv/sdk 1.6.8 → 1.6.10

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 (92) hide show
  1. package/README.md +9 -4
  2. package/dist/cjs/package.json +7 -5
  3. package/dist/cjs/src/wallet/substrates/HTTPWalletJSON.js +11 -3
  4. package/dist/cjs/src/wallet/substrates/HTTPWalletJSON.js.map +1 -1
  5. package/dist/cjs/src/wallet/substrates/WalletWireProcessor.js +1 -1
  6. package/dist/cjs/src/wallet/substrates/WalletWireProcessor.js.map +1 -1
  7. package/dist/cjs/src/wallet/substrates/utils/toOriginHeader.js +21 -0
  8. package/dist/cjs/src/wallet/substrates/utils/toOriginHeader.js.map +1 -0
  9. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  10. package/dist/esm/src/wallet/substrates/HTTPWalletJSON.js +9 -1
  11. package/dist/esm/src/wallet/substrates/HTTPWalletJSON.js.map +1 -1
  12. package/dist/esm/src/wallet/substrates/WalletWireProcessor.js +1 -1
  13. package/dist/esm/src/wallet/substrates/WalletWireProcessor.js.map +1 -1
  14. package/dist/esm/src/wallet/substrates/utils/toOriginHeader.js +17 -0
  15. package/dist/esm/src/wallet/substrates/utils/toOriginHeader.js.map +1 -0
  16. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  17. package/dist/types/src/wallet/substrates/HTTPWalletJSON.d.ts.map +1 -1
  18. package/dist/types/src/wallet/substrates/utils/toOriginHeader.d.ts +2 -0
  19. package/dist/types/src/wallet/substrates/utils/toOriginHeader.d.ts.map +1 -0
  20. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  21. package/dist/umd/bundle.js +1 -1
  22. package/docs/concepts/beef.md +84 -0
  23. package/docs/concepts/chain-tracking.md +122 -0
  24. package/docs/concepts/decentralized-identity.md +184 -0
  25. package/docs/concepts/fees.md +217 -0
  26. package/docs/concepts/identity-certificates.md +255 -0
  27. package/docs/concepts/index.md +62 -0
  28. package/docs/concepts/key-management.md +176 -0
  29. package/docs/concepts/script-templates.md +163 -0
  30. package/docs/concepts/sdk-philosophy.md +72 -0
  31. package/docs/concepts/signatures.md +179 -0
  32. package/docs/concepts/spv-verification.md +106 -0
  33. package/docs/concepts/transaction-encoding.md +148 -0
  34. package/docs/concepts/transaction-structure.md +63 -0
  35. package/docs/concepts/trust-model.md +123 -0
  36. package/docs/concepts/verification.md +219 -0
  37. package/docs/concepts/wallet-integration.md +95 -0
  38. package/docs/guides/direct-transaction-creation.md +137 -0
  39. package/docs/guides/http-client-configuration.md +414 -0
  40. package/docs/guides/index.md +30 -0
  41. package/docs/guides/transaction-signing-methods.md +268 -0
  42. package/docs/index.md +74 -0
  43. package/docs/reference/arc-config.md +698 -0
  44. package/docs/reference/brc-100.md +33 -0
  45. package/docs/reference/configuration.md +829 -0
  46. package/docs/reference/debugging.md +700 -0
  47. package/docs/reference/errors.md +547 -0
  48. package/docs/reference/index.md +98 -0
  49. package/docs/reference/network-config.md +914 -0
  50. package/docs/reference/op-codes.md +306 -0
  51. package/docs/reference/transaction-signatures.md +94 -0
  52. package/docs/{wallet.md → reference/wallet.md} +9 -0
  53. package/docs/requirements.txt +3 -0
  54. package/docs/tutorials/advanced-transaction.md +575 -0
  55. package/docs/tutorials/aes-encryption.md +947 -0
  56. package/docs/tutorials/authfetch-tutorial.md +957 -0
  57. package/docs/tutorials/ecdh-key-exchange.md +547 -0
  58. package/docs/tutorials/elliptic-curve-fundamentals.md +603 -0
  59. package/docs/tutorials/error-handling.md +1215 -0
  60. package/docs/tutorials/first-transaction-low-level.md +204 -0
  61. package/docs/tutorials/first-transaction.md +278 -0
  62. package/docs/tutorials/hashes-and-hmacs.md +814 -0
  63. package/docs/tutorials/identity-management.md +702 -0
  64. package/docs/tutorials/index.md +182 -0
  65. package/docs/tutorials/key-management.md +536 -0
  66. package/docs/tutorials/protowallet-development.md +716 -0
  67. package/docs/tutorials/script-construction.md +690 -0
  68. package/docs/tutorials/spv-merkle-proofs.md +682 -0
  69. package/docs/tutorials/testnet-transactions-low-level.md +352 -0
  70. package/docs/tutorials/transaction-broadcasting.md +535 -0
  71. package/docs/tutorials/transaction-types.md +419 -0
  72. package/docs/tutorials/type-42.md +582 -0
  73. package/docs/tutorials/uhrp-storage.md +579 -0
  74. package/package.json +7 -5
  75. package/src/transaction/__tests/Transaction.test.ts +1 -1
  76. package/src/wallet/substrates/HTTPWalletJSON.ts +11 -1
  77. package/src/wallet/substrates/WalletWireProcessor.ts +1 -1
  78. package/src/wallet/substrates/__tests/toOriginHeader.test.ts +34 -0
  79. package/src/wallet/substrates/utils/toOriginHeader.ts +15 -0
  80. package/docs/README.md +0 -21
  81. /package/docs/{auth.md → reference/auth.md} +0 -0
  82. /package/docs/{compat.md → reference/compat.md} +0 -0
  83. /package/docs/{identity.md → reference/identity.md} +0 -0
  84. /package/docs/{kvstore.md → reference/kvstore.md} +0 -0
  85. /package/docs/{messages.md → reference/messages.md} +0 -0
  86. /package/docs/{overlay-tools.md → reference/overlay-tools.md} +0 -0
  87. /package/docs/{primitives.md → reference/primitives.md} +0 -0
  88. /package/docs/{registry.md → reference/registry.md} +0 -0
  89. /package/docs/{script.md → reference/script.md} +0 -0
  90. /package/docs/{storage.md → reference/storage.md} +0 -0
  91. /package/docs/{totp.md → reference/totp.md} +0 -0
  92. /package/docs/{transaction.md → reference/transaction.md} +0 -0
@@ -0,0 +1,716 @@
1
+ # Working with ProtoWallet for Development
2
+
3
+ **Duration**: 45 minutes
4
+ **Prerequisites**: Node.js, basic TypeScript knowledge, completed "Your First BSV Transaction" tutorial
5
+ **Learning Goals**:
6
+ - Understand ProtoWallet's role in development and testing
7
+ - Implement cryptographic operations without blockchain interaction
8
+ - Use ProtoWallet for key derivation and signing
9
+ - Build development tools and testing frameworks
10
+
11
+ ## Introduction
12
+
13
+ ProtoWallet is a lightweight wallet implementation designed for development and testing scenarios. Unlike full wallets, ProtoWallet focuses purely on cryptographic operations without blockchain interaction, making it perfect for:
14
+
15
+ - Development and testing environments
16
+ - Cryptographic operation prototyping
17
+ - Key derivation and signing operations
18
+ - Building wallet-like functionality without full wallet complexity
19
+
20
+ ## What You'll Build
21
+
22
+ In this tutorial, you'll create a development toolkit using ProtoWallet that includes:
23
+ - Key generation and management
24
+ - Message signing and verification
25
+ - Symmetric encryption/decryption
26
+ - HMAC creation and verification
27
+
28
+ ## Setting Up ProtoWallet
29
+
30
+ ### Basic ProtoWallet Creation
31
+
32
+ ```typescript
33
+ import { ProtoWallet, PrivateKey } from '@bsv/sdk'
34
+
35
+ async function createProtoWallet() {
36
+ // Create with a random private key
37
+ const randomWallet = new ProtoWallet(PrivateKey.fromRandom())
38
+
39
+ // Create with a specific private key
40
+ const privateKey = PrivateKey.fromRandom()
41
+ const specificWallet = new ProtoWallet(privateKey)
42
+
43
+ // Create with 'anyone' key (for testing)
44
+ const anyoneWallet = new ProtoWallet('anyone')
45
+
46
+ console.log('ProtoWallet instances created successfully')
47
+ return { randomWallet, specificWallet, anyoneWallet }
48
+ }
49
+
50
+ createProtoWallet().catch(console.error)
51
+ ```
52
+
53
+ ### Getting Public Keys
54
+
55
+ ```typescript
56
+ import { ProtoWallet } from '@bsv/sdk'
57
+
58
+ async function demonstratePublicKeys() {
59
+ const wallet = new ProtoWallet(PrivateKey.fromRandom())
60
+
61
+ // Get identity public key
62
+ const { publicKey: identityKey } = await wallet.getPublicKey({
63
+ identityKey: true
64
+ })
65
+ console.log('Identity Key:', identityKey)
66
+
67
+ // Get derived public key for a protocol
68
+ const { publicKey: protocolKey } = await wallet.getPublicKey({
69
+ protocolID: [1, 'my-app'],
70
+ keyID: 'user-signing-key'
71
+ })
72
+ console.log('Protocol Key:', protocolKey)
73
+
74
+ // Get public key for counterparty communication
75
+ const { publicKey: counterpartyKey } = await wallet.getPublicKey({
76
+ protocolID: [1, 'messaging'],
77
+ keyID: 'chat-key',
78
+ counterparty: identityKey
79
+ })
80
+ console.log('Counterparty Key:', counterpartyKey)
81
+ }
82
+
83
+ demonstratePublicKeys().catch(console.error)
84
+ ```
85
+
86
+ ## Digital Signatures with ProtoWallet
87
+
88
+ ### Creating and Verifying Signatures
89
+
90
+ ```typescript
91
+ import { ProtoWallet, Utils } from '@bsv/sdk'
92
+
93
+ async function demonstrateSignatures() {
94
+ const wallet = new ProtoWallet(PrivateKey.fromRandom())
95
+
96
+ // Message to sign
97
+ const message = 'Hello, BSV development!'
98
+ const messageBytes = Utils.toArray(message, 'utf8')
99
+
100
+ // Create signature
101
+ const { signature } = await wallet.createSignature({
102
+ data: messageBytes,
103
+ protocolID: [1, 'document signing'],
104
+ keyID: 'doc-key',
105
+ counterparty: 'self'
106
+ })
107
+
108
+ console.log('Message:', message)
109
+ console.log('Signature:', Utils.toBase64(signature))
110
+
111
+ // Verify signature
112
+ const { valid } = await wallet.verifySignature({
113
+ data: messageBytes,
114
+ signature,
115
+ protocolID: [1, 'document signing'],
116
+ keyID: 'doc-key',
117
+ counterparty: 'self'
118
+ })
119
+
120
+ console.log('Signature valid:', valid)
121
+
122
+ return { message, signature, valid }
123
+ }
124
+
125
+ demonstrateSignatures().catch(console.error)
126
+ ```
127
+
128
+ ### Advanced Signature Scenarios
129
+
130
+ ```typescript
131
+ import { ProtoWallet, Utils } from '@bsv/sdk'
132
+
133
+ class DocumentSigner {
134
+ private wallet: ProtoWallet
135
+
136
+ constructor() {
137
+ this.wallet = new ProtoWallet(PrivateKey.fromRandom())
138
+ }
139
+
140
+ async signDocument(content: string, documentId: string): Promise<{
141
+ signature: number[]
142
+ publicKey: string
143
+ timestamp: number
144
+ }> {
145
+ const timestamp = Date.now()
146
+ const documentData = {
147
+ content,
148
+ documentId,
149
+ timestamp
150
+ }
151
+
152
+ const dataToSign = Utils.toArray(JSON.stringify(documentData), 'utf8')
153
+
154
+ const { signature } = await this.wallet.createSignature({
155
+ data: dataToSign,
156
+ protocolID: [1, 'document system'],
157
+ keyID: `doc-${documentId}`,
158
+ counterparty: 'self'
159
+ })
160
+
161
+ const { publicKey } = await this.wallet.getPublicKey({
162
+ protocolID: [1, 'document system'],
163
+ keyID: `doc-${documentId}`
164
+ })
165
+
166
+ return { signature, publicKey, timestamp }
167
+ }
168
+
169
+ async verifyDocument(
170
+ content: string,
171
+ documentId: string,
172
+ signature: number[],
173
+ timestamp: number
174
+ ): Promise<boolean> {
175
+ const documentData = {
176
+ content,
177
+ documentId,
178
+ timestamp
179
+ }
180
+
181
+ const dataToVerify = Utils.toArray(JSON.stringify(documentData), 'utf8')
182
+
183
+ const { valid } = await this.wallet.verifySignature({
184
+ data: dataToVerify,
185
+ signature,
186
+ protocolID: [1, 'document system'],
187
+ keyID: `doc-${documentId}`,
188
+ counterparty: 'self'
189
+ })
190
+
191
+ return valid
192
+ }
193
+ }
194
+
195
+ async function demonstrateDocumentSigning() {
196
+ const signer = new DocumentSigner()
197
+
198
+ const document = {
199
+ content: 'This is a confidential document requiring digital signature.',
200
+ id: 'contract-2024-001'
201
+ }
202
+
203
+ // Sign document
204
+ const signatureData = await signer.signDocument(document.content, document.id)
205
+ console.log('Document signed:', {
206
+ documentId: document.id,
207
+ publicKey: signatureData.publicKey,
208
+ timestamp: new Date(signatureData.timestamp).toISOString()
209
+ })
210
+
211
+ // Verify document
212
+ const isValid = await signer.verifyDocument(
213
+ document.content,
214
+ document.id,
215
+ signatureData.signature,
216
+ signatureData.timestamp
217
+ )
218
+
219
+ console.log('Document verification:', isValid ? 'VALID' : 'INVALID')
220
+
221
+ return { signatureData, isValid }
222
+ }
223
+
224
+ demonstrateDocumentSigning().catch(console.error)
225
+ ```
226
+
227
+ ## Encryption and Decryption
228
+
229
+ ### Symmetric Encryption
230
+
231
+ ```typescript
232
+ import { ProtoWallet, Utils } from '@bsv/sdk'
233
+
234
+ async function demonstrateEncryption() {
235
+ const wallet = new ProtoWallet(PrivateKey.fromRandom())
236
+
237
+ // Data to encrypt
238
+ const secretMessage = 'This is confidential development data'
239
+ const plaintext = Utils.toArray(secretMessage, 'utf8')
240
+
241
+ // Encrypt data
242
+ const { ciphertext } = await wallet.encrypt({
243
+ plaintext,
244
+ protocolID: [1, 'secure storage'],
245
+ keyID: 'data-encryption-key'
246
+ })
247
+
248
+ console.log('Original message:', secretMessage)
249
+ console.log('Encrypted (base64):', Utils.toBase64(ciphertext))
250
+
251
+ // Decrypt data
252
+ const { plaintext: decrypted } = await wallet.decrypt({
253
+ ciphertext,
254
+ protocolID: [1, 'secure storage'],
255
+ keyID: 'data-encryption-key'
256
+ })
257
+
258
+ const decryptedMessage = Utils.toUTF8(decrypted)
259
+ console.log('Decrypted message:', decryptedMessage)
260
+
261
+ return { original: secretMessage, decrypted: decryptedMessage }
262
+ }
263
+
264
+ demonstrateEncryption().catch(console.error)
265
+ ```
266
+
267
+ ### Counterparty Encryption
268
+
269
+ ```typescript
270
+ import { ProtoWallet, Utils } from '@bsv/sdk'
271
+
272
+ class SecureMessaging {
273
+ private aliceWallet: ProtoWallet
274
+ private bobWallet: ProtoWallet
275
+ private aliceIdentity: string
276
+ private bobIdentity: string
277
+
278
+ constructor() {
279
+ this.aliceWallet = new ProtoWallet(PrivateKey.fromRandom())
280
+ this.bobWallet = new ProtoWallet(PrivateKey.fromRandom())
281
+ }
282
+
283
+ async initialize() {
284
+ // Get identity keys for both parties
285
+ const aliceKey = await this.aliceWallet.getPublicKey({ identityKey: true })
286
+ const bobKey = await this.bobWallet.getPublicKey({ identityKey: true })
287
+
288
+ this.aliceIdentity = aliceKey.publicKey
289
+ this.bobIdentity = bobKey.publicKey
290
+
291
+ console.log('Alice Identity:', this.aliceIdentity.substring(0, 20) + '...')
292
+ console.log('Bob Identity:', this.bobIdentity.substring(0, 20) + '...')
293
+ }
294
+
295
+ async aliceSendsToBob(message: string): Promise<string> {
296
+ const plaintext = Utils.toArray(message, 'utf8')
297
+
298
+ const { ciphertext } = await this.aliceWallet.encrypt({
299
+ plaintext,
300
+ protocolID: [1, 'secure chat'],
301
+ keyID: 'message-key',
302
+ counterparty: this.bobIdentity
303
+ })
304
+
305
+ console.log('Alice encrypts message for Bob')
306
+ return Utils.toBase64(ciphertext)
307
+ }
308
+
309
+ async bobReceivesFromAlice(ciphertext: string): Promise<string> {
310
+ const ciphertextBytes = Utils.toArray(ciphertext, 'base64')
311
+
312
+ const { plaintext } = await this.bobWallet.decrypt({
313
+ ciphertext: ciphertextBytes,
314
+ protocolID: [1, 'secure chat'],
315
+ keyID: 'message-key',
316
+ counterparty: this.aliceIdentity
317
+ })
318
+
319
+ const message = Utils.toUTF8(plaintext)
320
+ console.log('Bob decrypts message from Alice')
321
+ return message
322
+ }
323
+ }
324
+
325
+ async function demonstrateSecureMessaging() {
326
+ const messaging = new SecureMessaging()
327
+ await messaging.initialize()
328
+
329
+ const originalMessage = 'Hello Bob, this is a secure message from Alice!'
330
+
331
+ // Alice encrypts and sends
332
+ const encryptedMessage = await messaging.aliceSendsToBob(originalMessage)
333
+ console.log('Encrypted message length:', encryptedMessage.length, 'bytes')
334
+
335
+ // Bob receives and decrypts
336
+ const decryptedMessage = await messaging.bobReceivesFromAlice(encryptedMessage)
337
+
338
+ console.log('Original:', originalMessage)
339
+ console.log('Decrypted:', decryptedMessage)
340
+ console.log('Messages match:', originalMessage === decryptedMessage)
341
+
342
+ return { originalMessage, decryptedMessage }
343
+ }
344
+
345
+ demonstrateSecureMessaging().catch(console.error)
346
+ ```
347
+
348
+ ## HMAC Operations
349
+
350
+ ### Creating and Verifying HMACs
351
+
352
+ ```typescript
353
+ import { ProtoWallet, Utils } from '@bsv/sdk'
354
+
355
+ async function demonstrateHMAC() {
356
+ const wallet = new ProtoWallet(PrivateKey.fromRandom())
357
+
358
+ // Data to authenticate
359
+ const data = Utils.toArray('Important data requiring integrity verification', 'utf8')
360
+
361
+ // Create HMAC
362
+ const { hmac } = await wallet.createHmac({
363
+ data,
364
+ protocolID: [1, 'data integrity'],
365
+ keyID: 'hmac-key'
366
+ })
367
+
368
+ console.log('Data:', Utils.toUTF8(data))
369
+ console.log('HMAC:', Utils.toHex(hmac))
370
+
371
+ // Verify HMAC
372
+ const { valid } = await wallet.verifyHmac({
373
+ data,
374
+ hmac,
375
+ protocolID: [1, 'data integrity'],
376
+ keyID: 'hmac-key'
377
+ })
378
+
379
+ console.log('HMAC valid:', valid)
380
+
381
+ // Test with tampered data
382
+ const tamperedData = Utils.toArray('Tampered data requiring integrity verification', 'utf8')
383
+ const { valid: tamperedValid } = await wallet.verifyHmac({
384
+ data: tamperedData,
385
+ hmac,
386
+ protocolID: [1, 'data integrity'],
387
+ keyID: 'hmac-key'
388
+ })
389
+
390
+ console.log('Tampered data HMAC valid:', tamperedValid)
391
+
392
+ return { valid, tamperedValid }
393
+ }
394
+
395
+ demonstrateHMAC().catch(console.error)
396
+ ```
397
+
398
+ ## Building a Development Toolkit
399
+
400
+ ### Complete ProtoWallet Utility Class
401
+
402
+ ```typescript
403
+ import { ProtoWallet, PrivateKey, Utils } from '@bsv/sdk'
404
+
405
+ export class DevelopmentWallet {
406
+ private wallet: ProtoWallet
407
+ private identityKey: string | null = null
408
+
409
+ constructor(privateKey?: PrivateKey) {
410
+ this.wallet = new ProtoWallet(privateKey)
411
+ }
412
+
413
+ async getIdentity(): Promise<string> {
414
+ if (!this.identityKey) {
415
+ const { publicKey } = await this.wallet.getPublicKey({ identityKey: true })
416
+ this.identityKey = publicKey
417
+ }
418
+ return this.identityKey
419
+ }
420
+
421
+ async signData(data: string, protocolId: string, keyId: string): Promise<{
422
+ signature: string
423
+ publicKey: string
424
+ data: string
425
+ }> {
426
+ const dataBytes = Utils.toArray(data, 'utf8')
427
+
428
+ const { signature } = await this.wallet.createSignature({
429
+ data: dataBytes,
430
+ protocolID: [1, protocolId],
431
+ keyID: keyId,
432
+ counterparty: 'self'
433
+ })
434
+
435
+ const { publicKey } = await this.wallet.getPublicKey({
436
+ protocolID: [1, protocolId],
437
+ keyID: keyId
438
+ })
439
+
440
+ return {
441
+ signature: Utils.toBase64(signature),
442
+ publicKey,
443
+ data
444
+ }
445
+ }
446
+
447
+ async verifyData(
448
+ data: string,
449
+ signature: string,
450
+ protocolId: string,
451
+ keyId: string
452
+ ): Promise<boolean> {
453
+ const dataBytes = Utils.toArray(data, 'utf8')
454
+ const signatureBytes = Utils.toArray(signature, 'base64')
455
+
456
+ const { valid } = await this.wallet.verifySignature({
457
+ data: dataBytes,
458
+ signature: signatureBytes,
459
+ protocolID: [1, protocolId],
460
+ keyID: keyId,
461
+ counterparty: 'self'
462
+ })
463
+
464
+ return valid
465
+ }
466
+
467
+ async encryptForSelf(data: string, protocolId: string, keyId: string): Promise<string> {
468
+ const plaintext = Utils.toArray(data, 'utf8')
469
+
470
+ const { ciphertext } = await this.wallet.encrypt({
471
+ plaintext,
472
+ protocolID: [1, protocolId],
473
+ keyID: keyId
474
+ })
475
+
476
+ return Utils.toBase64(ciphertext)
477
+ }
478
+
479
+ async decryptFromSelf(
480
+ encryptedData: string,
481
+ protocolId: string,
482
+ keyId: string
483
+ ): Promise<string> {
484
+ const ciphertext = Utils.toArray(encryptedData, 'base64')
485
+
486
+ const { plaintext } = await this.wallet.decrypt({
487
+ ciphertext,
488
+ protocolID: [1, protocolId],
489
+ keyID: keyId
490
+ })
491
+
492
+ return Utils.toUTF8(plaintext)
493
+ }
494
+
495
+ async createDataIntegrityTag(data: string, protocolId: string, keyId: string): Promise<string> {
496
+ const dataBytes = Utils.toArray(data, 'utf8')
497
+
498
+ const { hmac } = await this.wallet.createHmac({
499
+ data: dataBytes,
500
+ protocolID: [1, protocolId],
501
+ keyID: keyId
502
+ })
503
+
504
+ return Utils.toHex(hmac)
505
+ }
506
+
507
+ async verifyDataIntegrity(
508
+ data: string,
509
+ integrityTag: string,
510
+ protocolId: string,
511
+ keyId: string
512
+ ): Promise<boolean> {
513
+ const dataBytes = Utils.toArray(data, 'utf8')
514
+ const hmac = Utils.toArray(integrityTag, 'hex')
515
+
516
+ const { valid } = await this.wallet.verifyHmac({
517
+ data: dataBytes,
518
+ hmac,
519
+ protocolID: [1, protocolId],
520
+ keyID: keyId
521
+ })
522
+
523
+ return valid
524
+ }
525
+ }
526
+
527
+ async function demonstrateDevelopmentToolkit() {
528
+ const devWallet = new DevelopmentWallet()
529
+
530
+ console.log('=== Development Wallet Toolkit Demo ===')
531
+
532
+ // Get identity
533
+ const identity = await devWallet.getIdentity()
534
+ console.log('Wallet Identity:', identity.substring(0, 20) + '...')
535
+
536
+ // Sign and verify data
537
+ const testData = 'Development test data for signing'
538
+ const signatureResult = await devWallet.signData(testData, 'dev-tools', 'test-key')
539
+ console.log('Data signed successfully')
540
+
541
+ const isValid = await devWallet.verifyData(
542
+ testData,
543
+ signatureResult.signature,
544
+ 'dev-tools',
545
+ 'test-key'
546
+ )
547
+ console.log('Signature verification:', isValid ? 'PASSED' : 'FAILED')
548
+
549
+ // Encrypt and decrypt data
550
+ const secretData = 'Confidential development information'
551
+ const encrypted = await devWallet.encryptForSelf(secretData, 'dev-storage', 'secret-key')
552
+ console.log('Data encrypted successfully')
553
+
554
+ const decrypted = await devWallet.decryptFromSelf(encrypted, 'dev-storage', 'secret-key')
555
+ console.log('Decryption result:', secretData === decrypted ? 'PASSED' : 'FAILED')
556
+
557
+ // Create and verify integrity tag
558
+ const importantData = 'Critical development configuration'
559
+ const integrityTag = await devWallet.createDataIntegrityTag(
560
+ importantData,
561
+ 'dev-integrity',
562
+ 'config-key'
563
+ )
564
+ console.log('Integrity tag created')
565
+
566
+ const integrityValid = await devWallet.verifyDataIntegrity(
567
+ importantData,
568
+ integrityTag,
569
+ 'dev-integrity',
570
+ 'config-key'
571
+ )
572
+ console.log('Integrity verification:', integrityValid ? 'PASSED' : 'FAILED')
573
+
574
+ return {
575
+ identity,
576
+ signatureValid: isValid,
577
+ decryptionValid: secretData === decrypted,
578
+ integrityValid
579
+ }
580
+ }
581
+
582
+ demonstrateDevelopmentToolkit().catch(console.error)
583
+ ```
584
+
585
+ ## Testing Framework Integration
586
+
587
+ ### ProtoWallet Test Utilities
588
+
589
+ ```typescript
590
+ import { ProtoWallet, PrivateKey, Utils } from '@bsv/sdk'
591
+
592
+ export class ProtoWalletTestUtils {
593
+ static createTestWallet(seed?: string): ProtoWallet {
594
+ if (seed) {
595
+ // Create deterministic wallet for testing
596
+ const hash = Utils.toArray(seed, 'utf8')
597
+ const privateKey = PrivateKey.fromString(Utils.toHex(hash).padEnd(64, '0'))
598
+ return new ProtoWallet(privateKey)
599
+ }
600
+ return new ProtoWallet(PrivateKey.fromRandom())
601
+ }
602
+
603
+ static async createTestIdentities(count: number): Promise<{
604
+ wallets: ProtoWallet[]
605
+ identities: string[]
606
+ }> {
607
+ const wallets: ProtoWallet[] = []
608
+ const identities: string[] = []
609
+
610
+ for (let i = 0; i < count; i++) {
611
+ const wallet = this.createTestWallet(`test-identity-${i}`)
612
+ const { publicKey } = await wallet.getPublicKey({ identityKey: true })
613
+
614
+ wallets.push(wallet)
615
+ identities.push(publicKey)
616
+ }
617
+
618
+ return { wallets, identities }
619
+ }
620
+
621
+ static async testCryptographicRoundTrip(
622
+ wallet: ProtoWallet,
623
+ data: string,
624
+ protocolId: string,
625
+ keyId: string
626
+ ): Promise<{
627
+ signatureValid: boolean
628
+ encryptionValid: boolean
629
+ hmacValid: boolean
630
+ }> {
631
+ const dataBytes = Utils.toArray(data, 'utf8')
632
+
633
+ // Test signature round trip
634
+ const { signature } = await wallet.createSignature({
635
+ data: dataBytes,
636
+ protocolID: [1, protocolId],
637
+ keyID: keyId,
638
+ counterparty: 'self'
639
+ })
640
+
641
+ const { valid: signatureValid } = await wallet.verifySignature({
642
+ data: dataBytes,
643
+ signature,
644
+ protocolID: [1, protocolId],
645
+ keyID: keyId,
646
+ counterparty: 'self'
647
+ })
648
+
649
+ // Test encryption round trip
650
+ const { ciphertext } = await wallet.encrypt({
651
+ plaintext: dataBytes,
652
+ protocolID: [1, protocolId],
653
+ keyID: keyId
654
+ })
655
+
656
+ const { plaintext } = await wallet.decrypt({
657
+ ciphertext,
658
+ protocolID: [1, protocolId],
659
+ keyID: keyId
660
+ })
661
+
662
+ const encryptionValid = Utils.toUTF8(plaintext) === data
663
+
664
+ // Test HMAC round trip
665
+ const { hmac } = await wallet.createHmac({
666
+ data: dataBytes,
667
+ protocolID: [1, protocolId],
668
+ keyID: keyId
669
+ })
670
+
671
+ const { valid: hmacValid } = await wallet.verifyHmac({
672
+ data: dataBytes,
673
+ hmac,
674
+ protocolID: [1, protocolId],
675
+ keyID: keyId
676
+ })
677
+
678
+ return { signatureValid, encryptionValid, hmacValid }
679
+ }
680
+ }
681
+
682
+ async function runTestSuite() {
683
+ console.log('=== ProtoWallet Test Suite ===')
684
+
685
+ // Test deterministic wallet creation
686
+ const wallet1 = ProtoWalletTestUtils.createTestWallet('test-seed-123')
687
+ const wallet2 = ProtoWalletTestUtils.createTestWallet('test-seed-123')
688
+
689
+ const identity1 = await wallet1.getPublicKey({ identityKey: true })
690
+ const identity2 = await wallet2.getPublicKey({ identityKey: true })
691
+
692
+ console.log('Deterministic wallet test:',
693
+ identity1.publicKey === identity2.publicKey ? 'PASSED' : 'FAILED')
694
+
695
+ // Test multiple identities
696
+ const { wallets, identities } = await ProtoWalletTestUtils.createTestIdentities(3)
697
+ console.log('Created test identities:', identities.length)
698
+
699
+ // Test cryptographic operations
700
+ const testData = 'Test data for cryptographic operations'
701
+ const results = await ProtoWalletTestUtils.testCryptographicRoundTrip(
702
+ wallets[0],
703
+ testData,
704
+ 'test-protocol',
705
+ 'test-key'
706
+ )
707
+
708
+ console.log('Cryptographic tests:')
709
+ console.log(' Signature:', results.signatureValid ? 'PASSED' : 'FAILED')
710
+ console.log(' Encryption:', results.encryptionValid ? 'PASSED' : 'FAILED')
711
+ console.log(' HMAC:', results.hmacValid ? 'PASSED' : 'FAILED')
712
+
713
+ return results
714
+ }
715
+
716
+ runTestSuite().catch(console.error)