@bsv/message-box-client 1.1.7

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 ADDED
@@ -0,0 +1,1013 @@
1
+ # BSV Peer-to-Peer Messaging & Payment Tools
2
+
3
+ **@bsv/message-box-client** is a toolkit for **peer-to-peer messaging and payments** on the BSV blockchain. It leverages a server-side **store-and-forward** system for message delivery (via `MessageBoxClient`) and also includes a higher-level **peer-to-peer payment** flow (via `PeerPayClient`). Both functionalities build on [BRC-103](https://github.com/bitcoin-sv/BRCs/blob/master/peer-to-peer/0103.md) for mutual authentication and identity key management, allowing secure and authenticated exchanges of data and BSV.
4
+
5
+ ## Table of Contents
6
+
7
+ 1. [Introduction](#1-introduction)
8
+ 2. [Installation](#2-installation)
9
+ - [Running Integration Tests](#21-running-integration-tests)
10
+ 3. [Overview](#3-overview)
11
+ - [MessageBoxClient](#31-messageboxclient-overview)
12
+ - [PeerPayClient](#32-peerpayclient-overview)
13
+ 4. [Quick Start Examples](#4-quick-start-examples)
14
+ - [Using MessageBoxClient](#41-using-messageboxclient)
15
+ - [Using PeerPayClient](#42-using-peerpayclient)
16
+ 5. [API Reference](#5-api-reference)
17
+ - [MessageBoxClient API](#51-messageboxclient-api)
18
+ - [PeerPayClient API](#52-peerpayclient-api)
19
+ 6. [Contributing](#6-contributing)
20
+ 7. [License](#7-license)
21
+
22
+ ---
23
+
24
+ ## 1. Introduction
25
+
26
+ The **@bsv/message-box-client** library provides two main tools for peer-to-peer interaction:
27
+
28
+ 1. **MessageBoxClient** – A store-and-forward messaging system backed by a "message box" server. It supports authenticated sending, listing, and acknowledging (deleting) messages with a mutual-auth approach.
29
+ 2. **PeerPayClient** – A higher-level payment client built on top of `MessageBoxClient`, enabling real-time, peer-to-peer Bitcoin payments on the BSV blockchain.
30
+
31
+ Both clients use the [BRC-103](https://github.com/bitcoin-sv/BRCs/blob/master/peer-to-peer/0103.md)-based authentication model. By integrating with a [WalletClient](https://github.com/bitcoin-sv), they can sign and verify messages, ensuring only authorized parties can send and receive.
32
+
33
+ ---
34
+
35
+ ## 2. Installation
36
+
37
+ ```bash
38
+ npm install @bsv/message-box-client
39
+ ```
40
+
41
+ The package exports both `MessageBoxClient` and `PeerPayClient`. You can import them individually in your JavaScript/TypeScript applications.
42
+
43
+ ---
44
+
45
+ ### 2.1. Running Integration Tests
46
+ The P2P integration tests verify live communication between the MessageBoxClient and a running instance of the MessageBox Server. To run them, make sure the following are set up:
47
+
48
+ **Prerequisites**
49
+ 1. MessageBox Server Running Locally
50
+ You must have a local instance of the [MessageBox Server](https://github.com/bitcoin-sv/messagebox-server.git) running.
51
+ Follow these steps inside the messagebox-server project:
52
+ ```bash
53
+ git clone https://github.com/bitcoin-sv/messagebox-server.git
54
+ cd messagebox-server
55
+ cp .env.example .env
56
+ npm install
57
+ npm run start # Starts LARS (overlay service on http://localhost:8080)
58
+ npm run dev # Starts MessageBox Server (HTTP API on http://localhost:5001)
59
+ ```
60
+
61
+ 2. Ensure Environment Configuration
62
+ Your .env file in the MessageBox Server must have:
63
+ ```bash
64
+ NODE_ENV=development
65
+ BSV_NETWORK=local
66
+ ENABLE_WEBSOCKETS=true
67
+ ```
68
+ and valid values for:
69
+ - SERVER_PRIVATE_KEY
70
+ - WALLET_STORAGE_URL
71
+ - MONGO_URI and MONGO_DB
72
+ - (Optional) If using MySQL locally, ensure KNEX_DB_CONNECTION is properly set.
73
+
74
+ 3. Wallet Storage Running (optional)
75
+ If your .env points to a local wallet-storage instance, make sure it is also running.
76
+
77
+ ________________________________________
78
+
79
+ **Running the Tests**
80
+ Once the MessageBox Server and overlay service are running:
81
+ ```bash
82
+ npm run test:integration
83
+ ```
84
+
85
+ This will execute all integration tests under src/__tests__/integration/, including HTTP, WebSocket, encryption, and overlay scenarios.
86
+
87
+ ________________________________________
88
+
89
+ **Notes**
90
+ - If the server is not running, tests will fail with network or timeout errors.
91
+ - Integration tests use the local network preset (networkPreset: 'local') and assume the default MessageBox API endpoints (e.g., http://localhost:8080).
92
+ - Some tests may require clearing the database manually between runs if data conflicts occur.
93
+ - Unit tests (non-integration) still run by default with npm test. Integration tests are separated.
94
+
95
+ ________________________________________
96
+
97
+ **Quick Summary**
98
+ - npm run test → unit tests only
99
+ - npm run test:integration → integration tests against a running MessageBox server
100
+
101
+ ________________________________________
102
+
103
+ ## 3. Overview
104
+
105
+ ### 3.1. MessageBoxClient Overview
106
+
107
+ `MessageBoxClient` uses a **store-and-forward** architecture for Peer-to-Peer messages:
108
+
109
+ - **Store-and-forward:** Messages are posted to a MessageBoxServer under a named "message box" (like an inbox).
110
+ - **Ephemeral storage:** Once the recipient acknowledges the messages, they are removed from the server.
111
+ - **Mutual authentication:** Ensures only authorized peers can read or post messages, using [AuthFetch](https://github.com/bitcoin-sv/authfetch) and [AuthSocketClient](https://github.com/bitcoin-sv/authsocket).
112
+ - **Flexible transport:** Supports both **WebSockets** (for live, push-style delivery) and **HTTP** (for polling or fallback).
113
+ - **Extensible:** Can be the foundation for more advanced workflows (e.g., token-based messaging, invoice/ticket systems, etc.).
114
+
115
+ #### Key Features
116
+
117
+ 1. **Secure by default** using Auth libraries for signing/verification.
118
+ 2. **Real-time or delayed** delivery with sockets or HTTP.
119
+ 3. **Easy integration** with higher-level protocols and services.
120
+
121
+ ---
122
+
123
+ #### Important: Initialization Requirement
124
+
125
+ **Important:**
126
+ Starting with version `@bsv/message-box-client@1.2.0`, `MessageBoxClient` **automatically initializes itself** if needed.
127
+
128
+ - If you provide a host during construction, the client will auto-initialize on first use.
129
+ - If no host is provided, the client will anoint a host from the overlay network automatically during initialization.
130
+
131
+ You may still **manually call** `await init()` if you want to control when initialization happens.
132
+
133
+ Example:
134
+
135
+ ```ts
136
+ const client = new MessageBoxClient({ walletClient, host: 'https://messagebox.babbage.systems' })
137
+
138
+ // Manual init (optional but supported)
139
+ await client.init()
140
+
141
+ // Or just start sending — init will auto-run if needed
142
+ await client.sendMessage({ recipient, messageBox: 'inbox', body: 'Hello' })
143
+ ```
144
+
145
+ Example:
146
+
147
+ ```ts
148
+ const client = new MessageBoxClient({ walletClient, host: 'https://messagebox.babbage.systems' })
149
+ await client.init() // Must always call init() before using the client
150
+ await client.sendMessage({ recipient, messageBox: 'inbox', body: 'Hello' })
151
+ ```
152
+ The `init()` method will:
153
+
154
+ - Anoint your messagebox host onto the overlay network if necessary.
155
+
156
+ - Initialize the client’s internal identity and network information.
157
+
158
+ - Ensure that your client can receive messages securely from peers.
159
+
160
+ ---
161
+
162
+ ### 3.2. PeerPayClient Overview
163
+
164
+ `PeerPayClient` builds on `MessageBoxClient` to enable **peer-to-peer Bitcoin payments**:
165
+
166
+ - **Secure Payment Delivery:** Utilizes the same store-and-forward or live WebSocket approach for delivering payment instructions.
167
+ - **Derivation & Signing:** Creates a unique output script for each payment, derived from sender + recipient keys.
168
+ - **Live or Delayed:** Works with web sockets for immediate notifications, or HTTP for an asynchronous flow.
169
+ - **Wallet Integration:** Accept or reject incoming payments. If accepted, the payment is “internalized” into your [BRC-100](https://github.com/bitcoin-sv/BRCs/blob/master/wallet/0100.md) compatible wallet automatically.
170
+
171
+ #### Key Features
172
+
173
+ 1. **Deterministic derivation** of payment information using the SPV-compliant [BRC-29](https://github.com/bitcoin-sv/BRCs/blob/master/payments/0029.md) protocol.
174
+ 2. **Secure transaction passing** using the `MessageBoxClient` infrastructure.
175
+ 3. **Live or offline** support for receiving payments.
176
+ 4. **Easy acceptance/refunds** with built-in methods.
177
+
178
+ ---
179
+
180
+ ## 4. Quick Start Examples
181
+
182
+ Below are two condensed examples: one for basic messaging (MessageBoxClient) and another for peer-to-peer payments (PeerPayClient).
183
+
184
+ ### 4.1. Using MessageBoxClient
185
+
186
+ ```js
187
+ const { WalletClient } = require('@bsv/sdk')
188
+ const { MessageBoxClient } = require('@bsv/message-box-client')
189
+
190
+ // Example identity key of the recipient (public key in hex)
191
+ const johnSmithKey = '022600d2ef37d123fdcac7d25d7a464ada7acd3fb65a0daf85412140ee20884311'
192
+
193
+ async function main() {
194
+ // 1) Create your WalletClient (this obtains your identity key)
195
+ const myWallet = new WalletClient()
196
+
197
+ // 2) Create a MessageBoxClient, pointing to a MessageBoxServer
198
+ const msgBoxClient = new MessageBoxClient({
199
+ host: 'https://messagebox.babbage.systems',
200
+ walletClient: myWallet
201
+ })
202
+
203
+ // 3) (Optional) Initialize the client manually
204
+ await msgBoxClient.init()
205
+
206
+ // (Optional) Initialize a WebSocket connection (for real-time listening)
207
+ await msgBoxClient.initializeConnection()
208
+
209
+ // 4) Send a message to John's "demo_inbox"
210
+ await msgBoxClient.sendMessage({
211
+ recipient: johnSmithKey,
212
+ messageBox: 'demo_inbox',
213
+ body: 'Hello John! This is a test message.'
214
+ })
215
+
216
+ // 5) List messages in "demo_inbox"
217
+ const messages = await msgBoxClient.listMessages({ messageBox: 'demo_inbox' })
218
+ console.log(messages[0].body) // --> "Hello John! This is a test message."
219
+
220
+ // 6) Acknowledge (and delete) them from the server
221
+ await msgBoxClient.acknowledgeMessage({
222
+ messageIds: messages.map(msg => msg.messageId.toString())
223
+ })
224
+ }
225
+
226
+ main().catch(console.error)
227
+ ```
228
+ Note:
229
+ - If you do not manually call `await init()`, the client will automatically initialize itself when you use it.
230
+ - You can still call `await init()` manually if you want explicit control.
231
+ - `init()` ensures your identity is properly registered and discoverable via overlay advertisement if necessary.
232
+
233
+ **Listening for Live Messages**
234
+ If you want push-style message notifications instead of polling:
235
+
236
+ ```ts
237
+ await msgBoxClient.listenForLiveMessages({
238
+ messageBox: 'demo_inbox',
239
+ onMessage: (msg) => {
240
+ console.log('Received live message in "demo_inbox":', msg.body)
241
+ }
242
+ })
243
+ ```
244
+
245
+ ---
246
+
247
+ ### 4.2. Using PeerPayClient
248
+
249
+ ```ts
250
+ import { WalletClient } from '@bsv/sdk'
251
+ import { PeerPayClient } from '@bsv/message-box-client'
252
+
253
+ async function paymentDemo() {
254
+ // 1) Create your wallet instance
255
+ const wallet = new WalletClient()
256
+
257
+ // 2) Create a PeerPayClient
258
+ const peerPay = new PeerPayClient({
259
+ walletClient: wallet
260
+ })
261
+
262
+ // 3) (Optional) Listen for incoming payments
263
+ await peerPay.listenForLivePayments({
264
+ onPayment: async (payment) => {
265
+ console.log('Received payment:', payment)
266
+ // Accept it into the wallet
267
+ await peerPay.acceptPayment(payment)
268
+ }
269
+ })
270
+
271
+ // 4) Send a payment of 50,000 sats to the recipient
272
+ await peerPay.sendLivePayment({
273
+ recipient: '0277a2b...e3f4', // recipient's public key
274
+ amount: 50000
275
+ })
276
+ }
277
+
278
+ paymentDemo().catch(console.error)
279
+ ```
280
+
281
+ **Note:** `sendLivePayment` will try WebSocket first and fall back to HTTP if unavailable.
282
+
283
+ ---
284
+
285
+ ## 5. API Reference
286
+
287
+ ```md
288
+ ### 5.1. MessageBoxClient API
289
+ <!--#region ts2md-api-merged-here-->
290
+
291
+ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes)
292
+
293
+ ##### Interfaces
294
+
295
+ | |
296
+ | --- |
297
+ | [AcknowledgeMessageParams](#interface-acknowledgemessageparams) |
298
+ | [EncryptedMessage](#interface-encryptedmessage) |
299
+ | [ListMessagesParams](#interface-listmessagesparams) |
300
+ | [MessageBoxClientOptions](#interface-messageboxclientoptions) |
301
+ | [PeerMessage](#interface-peermessage) |
302
+ | [SendMessageParams](#interface-sendmessageparams) |
303
+ | [SendMessageResponse](#interface-sendmessageresponse) |
304
+
305
+ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes)
306
+
307
+ ---
308
+
309
+ ###### Interface: AcknowledgeMessageParams
310
+
311
+ Defines the structure of a request to acknowledge messages.
312
+
313
+ Example
314
+
315
+ ```ts
316
+ {
317
+ messageIds: ["abc123", "def456"]
318
+ }
319
+ ```
320
+
321
+ ```ts
322
+ export interface AcknowledgeMessageParams {
323
+ messageIds: string[];
324
+ }
325
+ ```
326
+
327
+ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes)
328
+
329
+ ---
330
+ ###### Interface: EncryptedMessage
331
+
332
+ Encapsulates an AES-256-GCM encrypted message body.
333
+
334
+ Used when transmitting encrypted payloads to the MessageBox server.
335
+
336
+ ```ts
337
+ export interface EncryptedMessage {
338
+ encryptedMessage: Base64String;
339
+ }
340
+ ```
341
+
342
+ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes)
343
+
344
+ ---
345
+ ###### Interface: ListMessagesParams
346
+
347
+ Defines the structure of a request to list messages.
348
+
349
+ Example
350
+
351
+ ```ts
352
+ {
353
+ messageBox: "payment_inbox"
354
+ }
355
+ ```
356
+
357
+ ```ts
358
+ export interface ListMessagesParams {
359
+ messageBox: string;
360
+ }
361
+ ```
362
+
363
+ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes)
364
+
365
+ ---
366
+ ###### Interface: MessageBoxClientOptions
367
+
368
+ Configuration options for initializing a MessageBoxClient.
369
+
370
+ ```ts
371
+ export interface MessageBoxClientOptions {
372
+ walletClient?: WalletClient;
373
+ host?: string;
374
+ enableLogging?: boolean;
375
+ networkPreset?: "local" | "mainnet" | "testnet";
376
+ }
377
+ ```
378
+
379
+ <details>
380
+
381
+ <summary>Interface MessageBoxClientOptions Details</summary>
382
+
383
+ ####### Property enableLogging
384
+
385
+ If true, enables detailed logging to the console.
386
+
387
+ ```ts
388
+ enableLogging?: boolean
389
+ ```
390
+
391
+ ####### Property host
392
+
393
+ Base URL of the MessageBox server.
394
+
395
+ ```ts
396
+ host?: string
397
+ ```
398
+
399
+ ####### Property networkPreset
400
+
401
+ Overlay network preset for routing resolution.
402
+
403
+ ```ts
404
+ networkPreset?: "local" | "mainnet" | "testnet"
405
+ ```
406
+
407
+ ####### Property walletClient
408
+
409
+ Wallet instance used for auth, identity, and encryption.
410
+ If not provided, a new WalletClient will be created.
411
+
412
+ ```ts
413
+ walletClient?: WalletClient
414
+ ```
415
+
416
+ </details>
417
+
418
+ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes)
419
+
420
+ ---
421
+ ###### Interface: PeerMessage
422
+
423
+ Represents a decrypted message received from a MessageBox.
424
+ Includes metadata such as sender identity, timestamps, and optional acknowledgment status.
425
+
426
+ Used in both HTTP and WebSocket message retrieval responses.
427
+
428
+ ```ts
429
+ export interface PeerMessage {
430
+ messageId: string;
431
+ body: string;
432
+ sender: string;
433
+ created_at: string;
434
+ updated_at: string;
435
+ acknowledged?: boolean;
436
+ }
437
+ ```
438
+
439
+ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes)
440
+
441
+ ---
442
+ ###### Interface: SendMessageParams
443
+
444
+ Parameters required to send a message.
445
+ Message content may be a string or object, and encryption is enabled by default.
446
+
447
+ Example
448
+
449
+ ```ts
450
+ {
451
+ recipient: "03abc...",
452
+ messageBox: "payment_inbox",
453
+ body: { type: "ping" },
454
+ skipEncryption: false
455
+ }
456
+ ```
457
+
458
+ ```ts
459
+ export interface SendMessageParams {
460
+ recipient: string;
461
+ messageBox: string;
462
+ body: string | object;
463
+ messageId?: string;
464
+ skipEncryption?: boolean;
465
+ }
466
+ ```
467
+
468
+ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes)
469
+
470
+ ---
471
+ ###### Interface: SendMessageResponse
472
+
473
+ Server response structure for successful message delivery.
474
+
475
+ Returned by both `sendMessage` and `sendLiveMessage`.
476
+
477
+ ```ts
478
+ export interface SendMessageResponse {
479
+ status: string;
480
+ messageId: string;
481
+ }
482
+ ```
483
+
484
+ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes)
485
+
486
+ ---
487
+ ##### Classes
488
+
489
+ | |
490
+ | --- |
491
+ | [Logger](#class-logger) |
492
+ | [MessageBoxClient](#class-messageboxclient) |
493
+
494
+ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes)
495
+
496
+ ---
497
+
498
+ ###### Class: Logger
499
+
500
+ ```ts
501
+ export class Logger {
502
+ static enable(): void
503
+ static disable(): void
504
+ static log(...args: unknown[]): void
505
+ static warn(...args: unknown[]): void
506
+ static error(...args: unknown[]): void
507
+ }
508
+ ```
509
+
510
+ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes)
511
+
512
+ ---
513
+ ###### Class: MessageBoxClient
514
+
515
+ Example
516
+
517
+ ```ts
518
+ const client = new MessageBoxClient({ walletClient, enableLogging: true })
519
+ // Manual init is optional — client will auto-initialize if needed
520
+ await client.init()
521
+ await client.sendMessage({ recipient, messageBox: 'payment_inbox', body: 'Hello world' })
522
+ ```
523
+
524
+ ```ts
525
+ export class MessageBoxClient {
526
+ public readonly authFetch: AuthFetch;
527
+ constructor(options: MessageBoxClientOptions = {})
528
+ async init(targetHost: string = this.host): Promise<void>
529
+ public getJoinedRooms(): Set<string>
530
+ public async getIdentityKey(): Promise<string>
531
+ public get testSocket(): ReturnType<typeof AuthSocketClient> | undefined
532
+ async initializeConnection(): Promise<void>
533
+ async resolveHostForRecipient(identityKey: string): Promise<string>
534
+ async joinRoom(messageBox: string): Promise<void>
535
+ async listenForLiveMessages({ onMessage, messageBox }: {
536
+ onMessage: (message: PeerMessage) => void;
537
+ messageBox: string;
538
+ }): Promise<void>
539
+ async sendLiveMessage({ recipient, messageBox, body, messageId, skipEncryption }: SendMessageParams): Promise<SendMessageResponse>
540
+ async leaveRoom(messageBox: string): Promise<void>
541
+ async disconnectWebSocket(): Promise<void>
542
+ async sendMessage(message: SendMessageParams, overrideHost?: string): Promise<SendMessageResponse>
543
+ async anointHost(host: string): Promise<{
544
+ txid: string;
545
+ }>
546
+ async listMessages({ messageBox }: ListMessagesParams): Promise<PeerMessage[]>
547
+ async acknowledgeMessage({ messageIds }: AcknowledgeMessageParams): Promise<string>
548
+ }
549
+ ```
550
+
551
+ See also: [AcknowledgeMessageParams](#interface-acknowledgemessageparams), [ListMessagesParams](#interface-listmessagesparams), [MessageBoxClientOptions](#interface-messageboxclientoptions), [PeerMessage](#interface-peermessage), [SendMessageParams](#interface-sendmessageparams), [SendMessageResponse](#interface-sendmessageresponse)
552
+
553
+ <details>
554
+
555
+ <summary>Class MessageBoxClient Details</summary>
556
+
557
+ ####### Constructor
558
+
559
+ ```ts
560
+ constructor(options: MessageBoxClientOptions = {})
561
+ ```
562
+ See also: [MessageBoxClientOptions](#interface-messageboxclientoptions)
563
+
564
+ Argument Details
565
+
566
+ + **options**
567
+ + Initialization options for the MessageBoxClient.
568
+
569
+ Example
570
+
571
+ ```ts
572
+ const client = new MessageBoxClient({
573
+ host: 'https://messagebox.example',
574
+ walletClient,
575
+ enableLogging: true,
576
+ networkPreset: 'testnet'
577
+ })
578
+ await client.init()
579
+ ```
580
+
581
+ ####### Method acknowledgeMessage
582
+
583
+ ```ts
584
+ async acknowledgeMessage({ messageIds }: AcknowledgeMessageParams): Promise<string>
585
+ ```
586
+ See also: [AcknowledgeMessageParams](#interface-acknowledgemessageparams)
587
+
588
+ Returns
589
+
590
+ - A string indicating the result, typically `'success'`.
591
+
592
+ Argument Details
593
+
594
+ + **params**
595
+ + An object containing an array of message IDs to acknowledge.
596
+
597
+ Throws
598
+
599
+ If the message ID array is missing or empty, or if the request to the server fails.
600
+
601
+ Example
602
+
603
+ ```ts
604
+ await client.acknowledgeMessage({ messageIds: ['msg123', 'msg456'] })
605
+ ```
606
+
607
+ ####### Method anointHost
608
+
609
+ ```ts
610
+ async anointHost(host: string): Promise<{
611
+ txid: string;
612
+ }>
613
+ ```
614
+
615
+ Returns
616
+
617
+ - The transaction ID of the advertisement broadcast to the overlay network.
618
+
619
+ Argument Details
620
+
621
+ + **host**
622
+ + The full URL of the server you want to designate as your MessageBox host (e.g., "https://mybox.com").
623
+
624
+ Throws
625
+
626
+ If the URL is invalid, the PushDrop creation fails, or the overlay broadcast does not succeed.
627
+
628
+ Example
629
+
630
+ ```ts
631
+ const { txid } = await client.anointHost('https://my-messagebox.io')
632
+ ```
633
+
634
+ ####### Method disconnectWebSocket
635
+
636
+ ```ts
637
+ async disconnectWebSocket(): Promise<void>
638
+ ```
639
+
640
+ Returns
641
+
642
+ Resolves when the WebSocket connection is successfully closed.
643
+
644
+ Example
645
+
646
+ ```ts
647
+ await client.disconnectWebSocket()
648
+ ```
649
+
650
+ ####### Method getIdentityKey
651
+
652
+ ```ts
653
+ public async getIdentityKey(): Promise<string>
654
+ ```
655
+
656
+ Returns
657
+
658
+ The identity public key of the user
659
+
660
+ ####### Method getJoinedRooms
661
+
662
+ ```ts
663
+ public getJoinedRooms(): Set<string>
664
+ ```
665
+
666
+ Returns
667
+
668
+ A set of currently joined WebSocket room IDs
669
+
670
+ ####### Method init
671
+
672
+ ```ts
673
+ async init(targetHost: string = this.host): Promise<void>
674
+ ```
675
+
676
+ Argument Details
677
+
678
+ + **targetHost**
679
+ + Optional host to set or override the default host.
680
+
681
+ Throws
682
+
683
+ If no valid host is provided, or anointing fails.
684
+
685
+ Example
686
+
687
+ ```ts
688
+ const client = new MessageBoxClient({ host: 'https://mybox.example', walletClient })
689
+ await client.init()
690
+ await client.sendMessage({ recipient, messageBox: 'inbox', body: 'Hello' })
691
+ ```
692
+
693
+ ####### Method initializeConnection
694
+
695
+ ```ts
696
+ async initializeConnection(): Promise<void>
697
+ ```
698
+
699
+ Throws
700
+
701
+ If the identity key is unavailable or authentication fails
702
+
703
+ Example
704
+
705
+ ```ts
706
+ const mb = new MessageBoxClient({ walletClient })
707
+ await mb.initializeConnection()
708
+ // WebSocket is now ready for use
709
+ ```
710
+
711
+ ####### Method joinRoom
712
+
713
+ ```ts
714
+ async joinRoom(messageBox: string): Promise<void>
715
+ ```
716
+
717
+ Argument Details
718
+
719
+ + **messageBox**
720
+ + The name of the WebSocket room to join (e.g., "payment_inbox").
721
+
722
+ Example
723
+
724
+ ```ts
725
+ await client.joinRoom('payment_inbox')
726
+ // Now listening for real-time messages in room '028d...-payment_inbox'
727
+ ```
728
+
729
+ ####### Method leaveRoom
730
+
731
+ ```ts
732
+ async leaveRoom(messageBox: string): Promise<void>
733
+ ```
734
+
735
+ Argument Details
736
+
737
+ + **messageBox**
738
+ + The name of the WebSocket room to leave (e.g., `payment_inbox`).
739
+
740
+ Example
741
+
742
+ ```ts
743
+ await client.leaveRoom('payment_inbox')
744
+ ```
745
+
746
+ ####### Method listMessages
747
+
748
+ ```ts
749
+ async listMessages({ messageBox }: ListMessagesParams): Promise<PeerMessage[]>
750
+ ```
751
+ See also: [ListMessagesParams](#interface-listmessagesparams), [PeerMessage](#interface-peermessage)
752
+
753
+ Returns
754
+
755
+ - Returns an array of decrypted `PeerMessage` objects.
756
+
757
+ Argument Details
758
+
759
+ + **params**
760
+ + Contains the name of the messageBox to read from.
761
+
762
+ Throws
763
+
764
+ If no messageBox is specified, the request fails, or the server returns an error.
765
+
766
+ Example
767
+
768
+ ```ts
769
+ const messages = await client.listMessages({ messageBox: 'inbox' })
770
+ messages.forEach(msg => console.log(msg.sender, msg.body))
771
+ ```
772
+
773
+ ####### Method listenForLiveMessages
774
+
775
+ ```ts
776
+ async listenForLiveMessages({ onMessage, messageBox }: {
777
+ onMessage: (message: PeerMessage) => void;
778
+ messageBox: string;
779
+ }): Promise<void>
780
+ ```
781
+ See also: [PeerMessage](#interface-peermessage)
782
+
783
+ Argument Details
784
+
785
+ + **params**
786
+ + Configuration for the live message listener.
787
+
788
+ Example
789
+
790
+ ```ts
791
+ await client.listenForLiveMessages({
792
+ messageBox: 'payment_inbox',
793
+ onMessage: (msg) => console.log('Received live message:', msg)
794
+ })
795
+ ```
796
+
797
+ ####### Method resolveHostForRecipient
798
+
799
+ ```ts
800
+ async resolveHostForRecipient(identityKey: string): Promise<string>
801
+ ```
802
+
803
+ Returns
804
+
805
+ - A fully qualified host URL for the recipient's MessageBox server.
806
+
807
+ Argument Details
808
+
809
+ + **identityKey**
810
+ + The public identity key of the intended recipient.
811
+
812
+ Example
813
+
814
+ ```ts
815
+ const host = await resolveHostForRecipient('028d...') // → returns either overlay host or this.host
816
+ ```
817
+
818
+ ####### Method sendLiveMessage
819
+
820
+ ```ts
821
+ async sendLiveMessage({ recipient, messageBox, body, messageId, skipEncryption }: SendMessageParams): Promise<SendMessageResponse>
822
+ ```
823
+ See also: [SendMessageParams](#interface-sendmessageparams), [SendMessageResponse](#interface-sendmessageresponse)
824
+
825
+ Returns
826
+
827
+ A success response with the generated messageId.
828
+
829
+ Argument Details
830
+
831
+ + **param0**
832
+ + The message parameters including recipient, box name, body, and options.
833
+
834
+ Throws
835
+
836
+ If message validation fails, HMAC generation fails, or both WebSocket and HTTP fail to deliver.
837
+
838
+ Example
839
+
840
+ ```ts
841
+ await client.sendLiveMessage({
842
+ recipient: '028d...',
843
+ messageBox: 'payment_inbox',
844
+ body: { amount: 1000 }
845
+ })
846
+ ```
847
+
848
+ ####### Method sendMessage
849
+
850
+ ```ts
851
+ async sendMessage(message: SendMessageParams, overrideHost?: string): Promise<SendMessageResponse>
852
+ ```
853
+ See also: [SendMessageParams](#interface-sendmessageparams), [SendMessageResponse](#interface-sendmessageresponse)
854
+
855
+ Returns
856
+
857
+ - Resolves with `{ status, messageId }` on success.
858
+
859
+ Argument Details
860
+
861
+ + **message**
862
+ + Contains recipient, messageBox name, message body, optional messageId, and skipEncryption flag.
863
+ + **overrideHost**
864
+ + Optional host to override overlay resolution (useful for testing or private routing).
865
+
866
+ Throws
867
+
868
+ If validation, encryption, HMAC, or network request fails.
869
+
870
+ Example
871
+
872
+ ```ts
873
+ await client.sendMessage({
874
+ recipient: '03abc...',
875
+ messageBox: 'notifications',
876
+ body: { type: 'ping' }
877
+ })
878
+ ```
879
+
880
+ </details>
881
+
882
+ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes)
883
+
884
+ ---
885
+
886
+ <!--#endregion ts2md-api-merged-here-->
887
+ ---
888
+
889
+ ### 5.2. PeerPayClient API
890
+
891
+ ```ts
892
+ import { PeerPayClient } from '@bsv/message-box-client'
893
+ ```
894
+
895
+ #### Constructor
896
+
897
+ ```ts
898
+ new PeerPayClient({
899
+ walletClient: WalletClient,
900
+ messageBoxHost?: string,
901
+ enableLogging?: boolean
902
+ })
903
+ ```
904
+
905
+ - **walletClient**: (Required) Your identity/signing wallet.
906
+ - **messageBoxHost**: (Optional) Base URL of the MessageBoxServer. Defaults to `https://messagebox.babbage.systems`.
907
+ - **enableLogging**: (Optional) Enables verbose debug output.
908
+
909
+ ---
910
+
911
+ #### `sendPayment({ recipient, amount })`
912
+
913
+ ```ts
914
+ await peerPay.sendPayment({
915
+ recipient: '0277a2b...',
916
+ amount: 10000
917
+ })
918
+ ```
919
+
920
+ - Sends a payment using HTTP.
921
+ - Internally derives a public key for the recipient and builds a transaction.
922
+
923
+ ---
924
+
925
+ #### `sendLivePayment({ recipient, amount })`
926
+
927
+ ```ts
928
+ await peerPay.sendLivePayment({
929
+ recipient: '0277a2b...',
930
+ amount: 15000
931
+ })
932
+ ```
933
+
934
+ - Sends a payment using WebSockets, falling back to HTTP if needed.
935
+
936
+ ---
937
+
938
+ #### `listenForLivePayments({ onPayment })`
939
+
940
+ ```ts
941
+ await peerPay.listenForLivePayments({
942
+ onPayment: (payment) => {
943
+ console.log('New live payment:', payment)
944
+ }
945
+ })
946
+ ```
947
+
948
+ - Subscribes to live payments in the `payment_inbox`.
949
+ - Invokes `onPayment` callback with an `IncomingPayment` object:
950
+
951
+ ```ts
952
+ interface IncomingPayment {
953
+ messageId: number;
954
+ sender: string;
955
+ token: {
956
+ customInstructions: {
957
+ derivationPrefix: string;
958
+ derivationSuffix: string;
959
+ };
960
+ transaction: any; // typically your BSV transaction format
961
+ amount: number;
962
+ };
963
+ }
964
+ ```
965
+
966
+ ---
967
+
968
+ #### `acceptPayment(payment)`
969
+
970
+ ```ts
971
+ await peerPay.acceptPayment(payment)
972
+ ```
973
+
974
+ - Accepts (and "internalizes") the payment into your wallet.
975
+ - Acknowledges the message, removing it from the inbox.
976
+
977
+ ---
978
+
979
+ #### `rejectPayment(payment)`
980
+
981
+ ```ts
982
+ await peerPay.rejectPayment(payment)
983
+ ```
984
+
985
+ - Rejects the payment, returning a **refund** to the sender (minus a small fee, e.g. 1000 sats).
986
+ - If the amount is too small to refund, the payment is simply acknowledged and dropped.
987
+
988
+ ---
989
+
990
+ #### `listIncomingPayments()`
991
+
992
+ ```ts
993
+ const payments = await peerPay.listIncomingPayments()
994
+ ```
995
+
996
+ - Lists all incoming payments in the `payment_inbox`.
997
+ - Returns an array of `IncomingPayment` objects.
998
+
999
+ ---
1000
+
1001
+ ## 6. Contributing
1002
+
1003
+ 1. Clone this repository.
1004
+ 2. Install dependencies with `npm install`.
1005
+ 3. Make your changes, write tests, and open a PR.
1006
+
1007
+ We welcome bug reports, feature requests, and community contributions!
1008
+
1009
+ ---
1010
+
1011
+ ## 7. License
1012
+
1013
+ This code is licensed under the [Open BSV License](https://www.bsvlicense.org/). See [LICENSE](./LICENSE) for details.