@bsv/message-box-client
Version:
A client for P2P messaging and payments
743 lines • 34.7 kB
TypeScript
/**
* @file MessageBoxClient.ts
* @description
* Provides the `MessageBoxClient` class — a secure client library for sending and receiving messages
* via a Message Box Server over HTTP and WebSocket. Messages are authenticated, optionally encrypted,
* and routed using identity-based addressing based on BRC-2/BRC-42/BRC-43 protocols.
*
* Core Features:
* - Authenticated message transport using identity keys
* - Deterministic message ID generation via HMAC (BRC-2)
* - AES-256-GCM encryption using ECDH shared secrets derived via BRC-42/BRC-43
* - Support for sending messages to self (`counterparty: 'self'`)
* - Live message streaming using WebSocket rooms
* - Optional plaintext messaging with `skipEncryption`
* - Overlay host discovery and advertisement broadcasting via SHIP
* - MessageBox-based organization and acknowledgment system
*
* See BRC-2 for details on the encryption scheme: https://github.com/bitcoin-sv/BRCs/blob/master/wallet/0002.md
*
* @module MessageBoxClient
* @author Project Babbage
* @license Open BSV License
*/
import { AuthFetch, PubKeyHex, OriginatorDomainNameStringUnder250Bytes } from '@bsv/sdk';
import { AuthSocketClient } from '@bsv/authsocket-client';
import { AcknowledgeMessageParams, AdvertisementToken, ListMessagesParams, MessageBoxClientOptions, PeerMessage, SendMessageParams, SendMessageResponse, DeviceRegistrationParams, DeviceRegistrationResponse, RegisteredDevice } from './types.js';
import { SetMessageBoxPermissionParams, GetMessageBoxPermissionParams, MessageBoxPermission, MessageBoxQuote, ListPermissionsParams, GetQuoteParams } from './types/permissions.js';
/**
* @class MessageBoxClient
* @description
* A secure client for sending and receiving authenticated, encrypted messages
* through a MessageBox server over HTTP and WebSocket.
*
* Core Features:
* - Identity-authenticated message transport (BRC-2)
* - AES-256-GCM end-to-end encryption with BRC-42/BRC-43 key derivation
* - HMAC-based message ID generation for deduplication
* - Live WebSocket messaging with room-based subscription management
* - Overlay network discovery and host advertisement broadcasting (SHIP protocol)
* - Fallback to HTTP messaging when WebSocket is unavailable
*
* **Important:**
* The MessageBoxClient automatically calls `await init()` if needed.
* Manual initialization is optional but still supported.
*
* You may call `await init()` manually for explicit control, but you can also use methods
* like `sendMessage()` or `listenForLiveMessages()` directly — the client will initialize itself
* automatically if not yet ready.
*
* @example
* const client = new MessageBoxClient({ walletClient, enableLogging: true })
* await client.init() // <- Required before using the client
* await client.sendMessage({ recipient, messageBox: 'payment_inbox', body: 'Hello world' })
*/
export declare class MessageBoxClient {
private host;
readonly authFetch: AuthFetch;
private readonly walletClient;
private socket?;
private myIdentityKey?;
private readonly joinedRooms;
private readonly lookupResolver;
private readonly networkPreset;
private initialized;
protected originator?: OriginatorDomainNameStringUnder250Bytes;
/**
* @constructor
* @param {Object} options - Initialization options for the MessageBoxClient.
* @param {string} [options.host] - The base URL of the MessageBox server. If omitted, defaults to mainnet/testnet hosts.
* @param {WalletInterface} options.walletClient - Wallet instance used for authentication, signing, and encryption.
* @param {boolean} [options.enableLogging=false] - Whether to enable detailed debug logging to the console.
* @param {'local' | 'mainnet' | 'testnet'} [options.networkPreset='mainnet'] - Overlay network preset used for routing and advertisement lookup.
*
* @description
* Constructs a new MessageBoxClient.
*
* **Note:**
* Passing a `host` during construction sets the default server.
* If you do not manually call `await init()`, the client will automatically initialize itself on first use.
*
* @example
* const client = new MessageBoxClient({
* host: 'https://messagebox.example',
* walletClient,
* enableLogging: true,
* networkPreset: 'testnet'
* })
* await client.init()
*/
constructor(options?: MessageBoxClientOptions);
/**
* @method init
* @async
* @param {string} [targetHost] - Optional host to set or override the default host.
* @param {string} [originator] - Optional originator to use with walletClient.
* @returns {Promise<void>}
*
* @description
* Initializes the MessageBoxClient by setting or anointing a MessageBox host.
*
* - If the client was constructed with a host, it uses that unless a different targetHost is provided.
* - If no prior advertisement exists for the identity key and host, it automatically broadcasts a new advertisement.
* - After calling init(), the client becomes ready to send, receive, and acknowledge messages.
*
* This method can be called manually for explicit control,
* but will be automatically invoked if omitted.
* @throws {Error} If no valid host is provided, or anointing fails.
*
* @example
* const client = new MessageBoxClient({ host: 'https://mybox.example', walletClient })
* await client.init()
* await client.sendMessage({ recipient, messageBox: 'inbox', body: 'Hello' })
*/
init(targetHost?: string): Promise<void>;
/**
* @method assertInitialized
* @private
* @description
* Ensures that the MessageBoxClient has completed initialization before performing sensitive operations
* like sending, receiving, or acknowledging messages.
*
* If the client is not yet initialized, it will automatically call `await init()` to complete setup.
*
* Used automatically by all public methods that require initialization.
*/
private assertInitialized;
/**
* @method getJoinedRooms
* @returns {Set<string>} A set of currently joined WebSocket room IDs
* @description
* Returns a live list of WebSocket rooms the client is subscribed to.
* Useful for inspecting state or ensuring no duplicates are joined.
*/
getJoinedRooms(): Set<string>;
/**
* @method getIdentityKey
* @param {string} [originator] - Optional originator to use for identity key lookup
* @returns {Promise<string>} The identity public key of the user
* @description
* Returns the client's identity key, used for signing, encryption, and addressing.
* If not already loaded, it will fetch and cache it.
*/
getIdentityKey(): Promise<string>;
/**
* @property testSocket
* @readonly
* @returns {AuthSocketClient | undefined} The internal WebSocket client (or undefined if not connected).
* @description
* Exposes the underlying Authenticated WebSocket client used for live messaging.
* This is primarily intended for debugging, test frameworks, or direct inspection.
*
* Note: Do not interact with the socket directly unless necessary.
* Use the provided `sendLiveMessage`, `listenForLiveMessages`, and related methods.
*/
get testSocket(): ReturnType<typeof AuthSocketClient> | undefined;
/**
* @method initializeConnection
* @param {string} [originator] - Optional originator to use for authentication.
* @async
* @returns {Promise<void>}
* @description
* Establishes an authenticated WebSocket connection to the configured MessageBox server.
* Enables live message streaming via room-based channels tied to identity keys.
*
* This method:
* 1. Retrieves the user’s identity key if not already set
* 2. Initializes a secure AuthSocketClient WebSocket connection
* 3. Authenticates the connection using the identity key
* 4. Waits up to 5 seconds for authentication confirmation
*
* If authentication fails or times out, the connection is rejected.
*
* @throws {Error} If the identity key is unavailable or authentication fails
*
* @example
* const mb = new MessageBoxClient({ walletClient })
* await mb.initializeConnection()
* // WebSocket is now ready for use
*/
initializeConnection(overrideHost?: string): Promise<void>;
/**
* @method resolveHostForRecipient
* @async
* @param {string} identityKey - The public identity key of the intended recipient.
* @param {string} [originator] - The originator to use for the WalletClient.
* @returns {Promise<string>} - A fully qualified host URL for the recipient's MessageBox server.
*
* @description
* Attempts to resolve the most recently anointed MessageBox host for the given identity key
* using the BSV overlay network and the `ls_messagebox` LookupResolver.
*
* If no advertisements are found, or if resolution fails, the client will fall back
* to its own configured `host`. This allows seamless operation in both overlay and non-overlay environments.
*
* This method guarantees a non-null return value and should be used directly when routing messages.
*
* @example
* const host = await resolveHostForRecipient('028d...') // → returns either overlay host or this.host
*/
resolveHostForRecipient(identityKey: string): Promise<string>;
/**
* Core lookup: ask the LookupResolver (optionally filtered by host),
* decode every PushDrop output, and collect all the host URLs you find.
*
* @param identityKey the recipient’s public key
* @param host? if passed, only look for adverts anointed at that host
* @returns 0-length array if nothing valid was found
*/
queryAdvertisements(identityKey?: string, host?: string): Promise<AdvertisementToken[]>;
/**
* @method joinRoom
* @async
* @param {string} messageBox - The name of the WebSocket room to join (e.g., "payment_inbox").
* @returns {Promise<void>}
*
* @description
* Joins a WebSocket room that corresponds to the user’s identity key and the specified message box.
* This is required to receive real-time messages via WebSocket for a specific type of communication.
*
* If the WebSocket connection is not already established, this method will first initialize the connection.
* It also ensures the room is only joined once, and tracks all joined rooms in an internal set.
*
* Room ID format: `${identityKey}-${messageBox}`
*
* @example
* await client.joinRoom('payment_inbox')
* // Now listening for real-time messages in room '028d...-payment_inbox'
*/
joinRoom(messageBox: string, overrideHost?: string): Promise<void>;
/**
* @method listenForLiveMessages
* @async
* @param {Object} params - Configuration for the live message listener.
* @param {function} params.onMessage - A callback function that will be triggered when a new message arrives.
* @param {string} params.messageBox - The messageBox name (e.g., `payment_inbox`) to listen for.
* @returns {Promise<void>}
*
* @description
* Subscribes the client to live messages over WebSocket for a specific messageBox.
*
* This method:
* - Ensures the WebSocket connection is initialized and authenticated.
* - Joins the correct room formatted as `${identityKey}-${messageBox}`.
* - Listens for messages broadcast to the room.
* - Automatically attempts to parse and decrypt message bodies.
* - Emits the final message (as a `PeerMessage`) to the supplied `onMessage` handler.
*
* If the incoming message is encrypted, the client decrypts it using AES-256-GCM via
* ECDH shared secrets derived from identity keys as defined in [BRC-2](https://github.com/bitcoin-sv/BRCs/blob/master/wallet/0002.md).
* Messages sent by the client to itself are decrypted using `counterparty = 'self'`.
*
* @example
* await client.listenForLiveMessages({
* messageBox: 'payment_inbox',
* onMessage: (msg) => console.log('Received live message:', msg)
* })
*/
listenForLiveMessages({ onMessage, messageBox, overrideHost }: {
onMessage: (message: PeerMessage) => void;
messageBox: string;
overrideHost?: string;
}): Promise<void>;
/**
* @method sendLiveMessage
* @async
* @param {SendMessageParams} param0 - The message parameters including recipient, box name, body, and options.
* @returns {Promise<SendMessageResponse>} A success response with the generated messageId.
*
* @description
* Sends a message in real time using WebSocket with authenticated delivery and overlay fallback.
*
* This method:
* - Ensures the WebSocket connection is open and joins the correct room.
* - Derives a unique message ID using an HMAC of the message body and counterparty identity key.
* - Encrypts the message body using AES-256-GCM based on the ECDH shared secret between derived keys, per [BRC-2](https://github.com/bitcoin-sv/BRCs/blob/master/wallet/0002.md),
* unless `skipEncryption` is explicitly set to `true`.
* - Sends the message to a WebSocket room in the format `${recipient}-${messageBox}`.
* - Waits for acknowledgment (`sendMessageAck-${roomId}`).
* - If no acknowledgment is received within 10 seconds, falls back to `sendMessage()` over HTTP.
*
* This hybrid delivery strategy ensures reliability in both real-time and offline-capable environments.
*
* @throws {Error} If message validation fails, HMAC generation fails, or both WebSocket and HTTP fail to deliver.
*
* @example
* await client.sendLiveMessage({
* recipient: '028d...',
* messageBox: 'payment_inbox',
* body: { amount: 1000 }
* })
*/
sendLiveMessage({ recipient, messageBox, body, messageId, skipEncryption, checkPermissions, }: SendMessageParams, overrideHost?: string): Promise<SendMessageResponse>;
/**
* @method leaveRoom
* @async
* @param {string} messageBox - The name of the WebSocket room to leave (e.g., `payment_inbox`).
* @returns {Promise<void>}
*
* @description
* Leaves a previously joined WebSocket room associated with the authenticated identity key.
* This helps reduce unnecessary message traffic and memory usage.
*
* If the WebSocket is not connected or the identity key is missing, the method exits gracefully.
*
* @example
* await client.leaveRoom('payment_inbox')
*/
leaveRoom(messageBox: string): Promise<void>;
/**
* @method disconnectWebSocket
* @async
* @returns {Promise<void>} Resolves when the WebSocket connection is successfully closed.
*
* @description
* Gracefully disconnects the WebSocket connection to the MessageBox server.
* This should be called when the client is shutting down, logging out, or no longer
* needs real-time communication to conserve system resources.
*
* @example
* await client.disconnectWebSocket()
*/
disconnectWebSocket(): Promise<void>;
/**
* @method sendMessage
* @async
* @param {SendMessageParams} message - Contains recipient, messageBox name, message body, optional messageId, and skipEncryption flag.
* @param {string} [overrideHost] - Optional host to override overlay resolution (useful for testing or private routing).
* @returns {Promise<SendMessageResponse>} - Resolves with `{ status, messageId }` on success.
*
* @description
* Sends a message over HTTP to a recipient's messageBox. This method:
*
* - Derives a deterministic `messageId` using an HMAC of the message body and recipient key.
* - Encrypts the message body using AES-256-GCM, derived from a shared secret using BRC-2-compliant key derivation and ECDH, unless `skipEncryption` is set to true.
* - Automatically resolves the host via overlay LookupResolver unless an override is provided.
* - Authenticates the request using the current identity key with `AuthFetch`.
*
* This is the fallback mechanism for `sendLiveMessage` when WebSocket delivery fails.
* It is also used for message types that do not require real-time delivery.
*
* @throws {Error} If validation, encryption, HMAC, or network request fails.
*
* @example
* await client.sendMessage({
* recipient: '03abc...',
* messageBox: 'notifications',
* body: { type: 'ping' }
* })
*/
sendMessage(message: SendMessageParams, overrideHost?: string): Promise<SendMessageResponse>;
/**
* @method anointHost
* @async
* @param {string} host - The full URL of the server you want to designate as your MessageBox host (e.g., "https://mybox.com").
* @returns {Promise<{ txid: string }>} - The transaction ID of the advertisement broadcast to the overlay network.
*
* @description
* Broadcasts a signed overlay advertisement using a PushDrop output under the `tm_messagebox` topic.
* This advertisement announces that the specified `host` is now authorized to receive and route
* messages for the sender’s identity key.
*
* The broadcasted message includes:
* - The identity key
* - The chosen host URL
*
* This is essential for enabling overlay-based message delivery via SHIP and LookupResolver.
* The recipient’s host must advertise itself for message routing to succeed in a decentralized manner.
*
* @throws {Error} If the URL is invalid, the PushDrop creation fails, or the overlay broadcast does not succeed.
*
* @example
* const { txid } = await client.anointHost('https://my-messagebox.io')
*/
anointHost(host: string): Promise<{
txid: string;
}>;
/**
* @method revokeHostAdvertisement
* @async
* @param {AdvertisementToken} advertisementToken - The advertisement token containing the messagebox host to revoke.
* @param {string} [originator] - Optional originator to use with walletClient.
* @returns {Promise<{ txid: string }>} - The transaction ID of the revocation broadcast to the overlay network.
*
* @description
* Broadcasts a signed revocation transaction indicating the advertisement token should be removed
* and no longer tracked by lookup services.
*
* @example
* const { txid } = await client.revokeHost('https://my-messagebox.io')
*/
revokeHostAdvertisement(advertisementToken: AdvertisementToken): Promise<{
txid: string;
}>;
/**
* @method listMessages
* @async
* @param {ListMessagesParams} params - Contains the name of the messageBox to read from.
* @returns {Promise<PeerMessage[]>} - Returns an array of decrypted `PeerMessage` objects.
*
* @description
* Retrieves all messages from the specified `messageBox` assigned to the current identity key.
* Unless a host override is provided, messages are fetched from the resolved overlay host (via LookupResolver) or the default host if no advertisement is found.
*
* Each message is:
* - Parsed and, if encrypted, decrypted using AES-256-GCM via BRC-2-compliant ECDH key derivation and symmetric encryption.
* - Automatically processed for payments: if the message includes recipient fee payments, they are internalized using `walletClient.internalizeAction()`.
* - Returned as a normalized `PeerMessage` with readable string body content.
*
* Payment Processing:
* - Detects messages that include payment data (from paid message delivery).
* - Automatically internalizes recipient payment outputs, allowing you to receive payments without additional API calls.
* - Only recipient payments are stored with messages - delivery fees are already processed by the server.
* - Continues processing messages even if payment internalization fails.
*
* Decryption automatically derives a shared secret using the sender's identity key and the receiver's child private key.
* If the sender is the same as the recipient, the `counterparty` is set to `'self'`.
*
* @throws {Error} If no messageBox is specified, the request fails, or the server returns an error.
*
* @example
* const messages = await client.listMessages({ messageBox: 'inbox' })
* messages.forEach(msg => console.log(msg.sender, msg.body))
* // Payments included with messages are automatically received
*/
listMessages({ messageBox, host, acceptPayments }: ListMessagesParams): Promise<PeerMessage[]>;
/**
* @method listMessagesLite
* @async
* @param {ListMessagesParams} params - Contains the `messageBox` to read from and the `host` to query.
* @returns {Promise<PeerMessage[]>} - Returns an array of decrypted `PeerMessage` objects with minimal processing.
*
* @description
* A lightweight variant of {@link listMessages} that fetches and decrypts messages
* from a specific host without performing:
* - Overlay host resolution
* - Payment acceptance or internalization
* - Cross-host deduplication
*
* This method:
* - Sends a direct POST request to the specified host's `/listMessages` endpoint.
* - Parses message bodies as JSON when possible.
* - Decrypts messages if they contain an `encryptedMessage` field, using AES-256-GCM via BRC-2-compliant ECDH key derivation.
* - Returns messages in the order provided by the host.
*
* This is intended for cases where you already know the host and need faster,
* simpler retrieval without the additional processing overhead of `listMessages`.
*
* @throws {Error} If the host returns an error status or decryption fails.
*
* @example
* const messages = await client.listMessagesLite({
* messageBox: 'notifications',
* host: 'https://messagebox.babbage.systems'
* })
* console.log(messages)
*/
listMessagesLite({ messageBox, host }: ListMessagesParams): Promise<PeerMessage[]>;
/**
* @method tryParse
* @private
* @param {string} raw - A raw string value that may contain JSON.
* @returns {any} - The parsed JavaScript object if valid JSON, or the original string if parsing fails.
*
* @description
* Attempts to parse a string as JSON. If the string is valid JSON, returns the parsed object;
* otherwise returns the original string unchanged.
*
* This method is used throughout the client to safely handle message bodies that may or may not be
* JSON-encoded without throwing parsing errors.
*
* @example
* tryParse('{"hello":"world"}') // → { hello: "world" }
* tryParse('plain text') // → "plain text"
*/
tryParse(raw: string): any;
/**
* @method acknowledgeNotification
* @async
* @param {PeerMessage} message - The peer message object to acknowledge.
* @returns {Promise<boolean>} - Resolves to `true` if the message included a recipient payment and it was successfully internalized, otherwise `false`.
*
* @description
* Acknowledges receipt of a specific notification message and, if applicable, processes any recipient
* payment contained within it.
*
* This method:
* 1. Calls `acknowledgeMessage()` to remove the message from the server's queue.
* 2. Checks the message body for embedded payment data.
* 3. If a recipient payment exists, attempts to internalize it into the wallet.
*
* This is a convenience wrapper for acknowledgment and payment handling specifically for messages
* representing notifications.
*
* @example
* const success = await client.acknowledgeNotification(message)
* console.log(success ? 'Payment received' : 'No payment or failed')
*/
acknowledgeNotification(message: PeerMessage): Promise<boolean>;
/**
* @method acknowledgeMessage
* @async
* @param {AcknowledgeMessageParams} params - An object containing an array of message IDs to acknowledge.
* @returns {Promise<string>} - A string indicating the result, typically `'success'`.
*
* @description
* Notifies the MessageBox server(s) that one or more messages have been
* successfully received and processed by the client. Once acknowledged, these messages are removed
* from the recipient's inbox on the server(s).
*
* This operation is essential for proper message lifecycle management and prevents duplicate
* processing or delivery.
*
* Acknowledgment supports providing a host override, or will use overlay routing to find the appropriate server the received the given message.
*
* @throws {Error} If the message ID array is missing or empty, or if the request to the server fails.
*
* @example
* await client.acknowledgeMessage({ messageIds: ['msg123', 'msg456'] })
*/
acknowledgeMessage({ messageIds, host }: AcknowledgeMessageParams): Promise<string>;
/**
* @method setMessageBoxPermission
* @async
* @param {SetMessageBoxPermissionParams} params - Permission configuration
* @param {string} [overrideHost] - Optional host override
* @returns {Promise<void>} Permission status after setting
*
* @description
* Sets permission for receiving messages in a specific messageBox.
* Can set sender-specific permissions or box-wide defaults.
*
* @example
* // Set box-wide default: allow notifications for 10 sats
* await client.setMessageBoxPermission({ messageBox: 'notifications', recipientFee: 10 })
*
* // Block specific sender
* await client.setMessageBoxPermission({
* messageBox: 'notifications',
* sender: '03abc123...',
* recipientFee: -1
* })
*/
setMessageBoxPermission(params: SetMessageBoxPermissionParams, overrideHost?: string): Promise<void>;
/**
* @method getMessageBoxPermission
* @async
* @param {GetMessageBoxPermissionParams} params - Permission query parameters
* @param {string} [overrideHost] - Optional host override
* @returns {Promise<MessageBoxPermission | null>} Permission data (null if not set)
*
* @description
* Gets current permission data for a sender/messageBox combination.
* Returns null if no permission is set.
*
* @example
* const status = await client.getMessageBoxPermission({
* recipient: '03def456...',
* messageBox: 'notifications',
* sender: '03abc123...'
* })
*/
getMessageBoxPermission(params: GetMessageBoxPermissionParams, overrideHost?: string): Promise<MessageBoxPermission | null>;
/**
* @method getMessageBoxQuote
* @async
* @param {GetQuoteParams} params - Quote request parameters
* @returns {Promise<MessageBoxQuote>} Fee quote and permission status
*
* @description
* Gets a fee quote for sending a message, including delivery and recipient fees.
*
* @example
* const quote = await client.getMessageBoxQuote({
* recipient: '03def456...',
* messageBox: 'notifications'
* })
*/
getMessageBoxQuote(params: GetQuoteParams, overrideHost?: string): Promise<MessageBoxQuote>;
/**
* @method listMessageBoxPermissions
* @async
* @param {ListPermissionsParams} [params] - Optional filtering and pagination parameters
* @returns {Promise<MessageBoxPermission[]>} List of current permissions
*
* @description
* Lists permissions for the authenticated user's messageBoxes with optional pagination.
*
* @example
* // List all permissions
* const all = await client.listMessageBoxPermissions()
*
* // List only notification permissions with pagination
* const notifications = await client.listMessageBoxPermissions({
* messageBox: 'notifications',
* limit: 50,
* offset: 0
* })
*/
listMessageBoxPermissions(params?: ListPermissionsParams, overrideHost?: string): Promise<MessageBoxPermission[]>;
/**
* @method allowNotificationsFromPeer
* @async
* @param {PubKeyHex} identityKey - Sender's identity key to allow
* @param {number} [recipientFee=0] - Fee to charge (0 for always allow)
* @param {string} [overrideHost] - Optional host override
* @returns {Promise<void>} Permission status after allowing
*
* @description
* Convenience method to allow notifications from a specific peer.
*
* @example
* await client.allowNotificationsFromPeer('03abc123...') // Always allow
* await client.allowNotificationsFromPeer('03def456...', 5) // Allow for 5 sats
*/
allowNotificationsFromPeer(identityKey: PubKeyHex, recipientFee?: number, overrideHost?: string): Promise<void>;
/**
* @method denyNotificationsFromPeer
* @async
* @param {PubKeyHex} identityKey - Sender's identity key to block
* @returns {Promise<void>} Permission status after denying
*
* @description
* Convenience method to block notifications from a specific peer.
*
* @example
* await client.denyNotificationsFromPeer('03spam123...')
*/
denyNotificationsFromPeer(identityKey: PubKeyHex, overrideHost?: string): Promise<void>;
/**
* @method checkPeerNotificationStatus
* @async
* @param {PubKeyHex} identityKey - Sender's identity key to check
* @returns {Promise<MessageBoxPermission>} Current permission status
*
* @description
* Convenience method to check notification permission for a specific peer.
*
* @example
* const status = await client.checkPeerNotificationStatus('03abc123...')
* console.log(status.allowed) // true/false
*/
checkPeerNotificationStatus(identityKey: PubKeyHex, overrideHost?: string): Promise<MessageBoxPermission | null>;
/**
* @method listPeerNotifications
* @async
* @returns {Promise<MessageBoxPermission[]>} List of notification permissions
*
* @description
* Convenience method to list all notification permissions.
*
* @example
* const notifications = await client.listPeerNotifications()
*/
listPeerNotifications(overrideHost?: string): Promise<MessageBoxPermission[]>;
/**
* @method sendNotification
* @async
* @param {PubKeyHex} recipient - Recipient's identity key
* @param {string | object} body - Notification content
* @param {string} [overrideHost] - Optional host override
* @returns {Promise<SendMessageResponse>} Send result
*
* @description
* Convenience method to send a notification with automatic quote fetching and payment handling.
* Automatically determines the required payment amount and creates the payment if needed.
*
* @example
* // Send notification (auto-determines payment needed)
* await client.sendNotification('03def456...', 'Hello!')
*
* // Send with maximum payment limit for safety
* await client.sendNotification('03def456...', { title: 'Alert', body: 'Important update' }, 50)
*/
sendNotification(recipient: PubKeyHex, body: string | object, overrideHost?: string): Promise<SendMessageResponse>;
/**
* Register a device for FCM push notifications.
*
* @async
* @param {DeviceRegistrationParams} params - Device registration parameters
* @param {string} [overrideHost] - Optional host override
* @returns {Promise<DeviceRegistrationResponse>} Registration response
*
* @description
* Registers a device with the message box server to receive FCM push notifications.
* The FCM token is obtained from Firebase SDK on the client side.
*
* @example
* const result = await client.registerDevice({
* fcmToken: 'eBo8F...',
* platform: 'ios',
* deviceId: 'iPhone15Pro'
* })
*/
registerDevice(params: DeviceRegistrationParams, overrideHost?: string): Promise<DeviceRegistrationResponse>;
/**
* List all registered devices for push notifications.
*
* @async
* @param {string} [overrideHost] - Optional host override
* @returns {Promise<RegisteredDevice[]>} Array of registered devices
*
* @description
* Retrieves all devices registered by the authenticated user for FCM push notifications.
* Only shows devices belonging to the current user (authenticated via AuthFetch).
*
* @example
* const devices = await client.listRegisteredDevices()
* console.log(`Found ${devices.length} registered devices`)
* devices.forEach(device => {
* console.log(`Device: ${device.platform} - ${device.fcmToken}`)
* })
*/
listRegisteredDevices(overrideHost?: string): Promise<RegisteredDevice[]>;
private static getStatusFromFee;
/**
* @method createMessagePayment
* @private
* @param {string} recipient - Recipient's identity key.
* @param {MessageBoxQuote} quote - Quote object containing recipient and delivery fees.
* @param {string} [description='MessageBox delivery payment'] - Description for the payment action.
* @param {string} [originator] - Optional originator to use for wallet operations.
* @returns {Promise<Payment>} - Payment data including the transaction and remittance outputs.
*
* @description
* Constructs and signs a payment transaction covering both delivery and recipient fees for
* message delivery, based on a previously obtained quote.
*
* The transaction includes:
* - An optional delivery fee output for the MessageBox server.
* - An optional recipient fee output for the message recipient.
*
* Payment remittance metadata (derivation prefix/suffix, sender identity) is embedded to allow
* the payee to derive their private key and spend the output.
*
* @throws {Error} If no payment is required, key derivation fails, or the action creation fails.
*
* @example
* const payment = await client.createMessagePayment(recipientKey, quote)
* await client.sendMessage({ recipient, messageBox, body, payment })
*/
private createMessagePayment;
}
//# sourceMappingURL=MessageBoxClient.d.ts.map