pub struct MessageBoxClient<W: WalletInterface + Clone + 'static> { /* private fields */ }Expand description
Authenticated HTTP client for the MessageBox protocol.
MessageBoxClient<W> wraps AuthFetch<W> behind a tokio::sync::Mutex
because AuthFetch::fetch() takes &mut self and must be called from
async context. A std::sync::Mutex held across .await panics under
Tokio — this is load-bearing and must not be changed.
Implementations§
Source§impl<W: WalletInterface + Clone + 'static + Send + Sync> MessageBoxClient<W>
impl<W: WalletInterface + Clone + 'static + Send + Sync> MessageBoxClient<W>
Sourcepub fn new(
host: String,
wallet: W,
originator: Option<String>,
network: Network,
) -> Self
pub fn new( host: String, wallet: W, originator: Option<String>, network: Network, ) -> Self
Construct a new MessageBoxClient.
host— Base URL of the MessageBox server. Trailing whitespace is trimmed so callers do not need to sanitize.wallet— AnyWalletInterfaceimplementation.originator— Optional originator string forwarded to wallet ops.network— Network preset for overlay tools (useNetwork::Localfor localhost).
Sourcepub fn new_mainnet(host: String, wallet: W, originator: Option<String>) -> Self
pub fn new_mainnet(host: String, wallet: W, originator: Option<String>) -> Self
Convenience constructor defaulting to Network::Mainnet.
Sourcepub fn originator(&self) -> Option<&str>
pub fn originator(&self) -> Option<&str>
Return the originator string, if any.
Sourcepub async fn get_identity_key(&self) -> Result<String, MessageBoxError>
pub async fn get_identity_key(&self) -> Result<String, MessageBoxError>
Return the wallet’s identity public key as a DER hex string.
The result is cached in a OnceCell — subsequent calls return the
cached value without calling the wallet again.
Sourcepub async fn init(
&self,
target_host: Option<&str>,
) -> Result<(), MessageBoxError>
pub async fn init( &self, target_host: Option<&str>, ) -> Result<(), MessageBoxError>
Initialize the client — ensures overlay advertisement exists.
User-facing wrapper for assert_initialized. Safe to call multiple times —
the init path runs exactly once due to init_once OnceCell semantics.
target_host: when Some, uses that host for the anoint_host call instead of
self.host(). Matches the TS init(targetHost?) signature.
Sourcepub async fn initialize_connection(
&self,
override_host: Option<&str>,
) -> Result<(), MessageBoxError>
pub async fn initialize_connection( &self, override_host: Option<&str>, ) -> Result<(), MessageBoxError>
Ensure the WebSocket connection is established.
User-facing wrapper for ensure_ws_connected. Mirrors the TS
initializeConnection method. When override_host is Some, the WS
connection uses that host instead of self.host().
Sourcepub fn get_joined_rooms(&self) -> HashSet<String>
pub fn get_joined_rooms(&self) -> HashSet<String>
Returns a clone of the set of currently joined message box room names.
Each entry is a raw room ID of the form {identityKey}-{messageBox}.
Mirrors the TS joinedRooms Map accessor.
Sourcepub async fn is_ws_connected(&self) -> Option<bool>
pub async fn is_ws_connected(&self) -> Option<bool>
Returns the current WebSocket connection state.
None = no WebSocket connected yet. Some(true) = connected and authenticated.
Some(false) = connected but BRC-103 handshake not yet complete.
Async version of test_socket — safe to call from integration tests and any
async context. Mirrors the TS testSocket accessor.
Sourcepub async fn join_room(&self, message_box: &str) -> Result<(), MessageBoxError>
pub async fn join_room(&self, message_box: &str) -> Result<(), MessageBoxError>
Join a Socket.IO room for a message box and track it in joined_rooms.
Constructs the room ID as {identityKey}-{messageBox} (matching TS joinRoom).
Ensures the WebSocket is connected before joining.
No-op if the room is already joined (idempotent like TS joinRoom).
Sourcepub async fn listen_for_live_messages(
&self,
message_box: &str,
on_message: Arc<dyn Fn(PeerMessage) + Send + Sync>,
override_host: Option<&str>,
) -> Result<(), MessageBoxError>
pub async fn listen_for_live_messages( &self, message_box: &str, on_message: Arc<dyn Fn(PeerMessage) + Send + Sync>, override_host: Option<&str>, ) -> Result<(), MessageBoxError>
Listen for live messages on a message box via WebSocket.
Joins the Socket.IO room {identity_key}-{message_box} and registers
the provided callback. Messages can arrive via three paths, all funnelled
through one shared dedup wrapper so the callback fires at most once per id:
- WebSocket push (primary): the BRC-103
general_msg_dispatcherfires the callback when the server broadcasts a signedsendMessage-{roomId}. - WebSocket
on_any(fallback): the same callback, for servers that emit raw (unsigned) room events. - HTTP poll (backstop): a background task that stands down for any
interval in which WS push already delivered (so it does not poll every
2 s when live push is healthy), and otherwise polls
/listMessagesto catch anything the WS paths missed — forcing a catch-up at least everyMAX_POLL_SKIPSintervals. Stops whenleave_roomremoves the room fromjoined_rooms.
All paths deliver PeerMessage with decrypted body to the same callback.
Establishes a WebSocket connection if one is not already active.
override_host is reserved for future multi-host WS routing.
Sourcepub async fn send_live_message(
&self,
recipient: &str,
message_box: &str,
body: &str,
skip_encryption: bool,
check_permissions: bool,
message_id: Option<&str>,
override_host: Option<&str>,
) -> Result<DeliveryMode, MessageBoxError>
pub async fn send_live_message( &self, recipient: &str, message_box: &str, body: &str, skip_encryption: bool, check_permissions: bool, message_id: Option<&str>, override_host: Option<&str>, ) -> Result<DeliveryMode, MessageBoxError>
Send a message via WebSocket with 10-second ack timeout and HTTP fallback.
Mirrors TS sendLiveMessage: auto-connects if needed, joins the sender’s
own room (required for ack routing), then emits. Falls back to HTTP if the
connection cannot be established or the ack times out / fails.
TS parity: HTTP fallback resolves recipient’s host via overlay before sending.
The WS path connects to self.host() — overlay resolution affects the fallback path.
override_host: when Some, the HTTP fallback path sends to that host directly.
Send a message via WebSocket with 10-second ack timeout and HTTP fallback.
Mirrors TS sendLiveMessage(params, overrideHost?) which accepts the full
SendMessageParams including skipEncryption, checkPermissions, and messageId.
skip_encryption: when true, sends body as-is without BRC-78 encryption.check_permissions: when true, the HTTP fallback path fetches quotes and pays fees.message_id: when Some, uses caller-supplied ID instead of HMAC-derived ID.override_host: when Some, the HTTP fallback sends to that host directly.
Sourcepub async fn leave_room(
&self,
message_box: &str,
override_host: Option<&str>,
) -> Result<(), MessageBoxError>
pub async fn leave_room( &self, message_box: &str, override_host: Option<&str>, ) -> Result<(), MessageBoxError>
Leave a Socket.IO room and remove its subscription.
Mirrors TS leaveRoom(messageBox). Constructs the room ID as
{identityKey}-{messageBox} and emits leaveRoom to the server.
No-op if the WebSocket is not connected.
override_host is reserved for future multi-host WS routing.
Sourcepub async fn disconnect_web_socket(&self) -> Result<(), MessageBoxError>
pub async fn disconnect_web_socket(&self) -> Result<(), MessageBoxError>
Disconnect the WebSocket connection and clear its state.
Safe to call when no connection is active (no-op).
Source§impl<W: WalletInterface + Clone + 'static + Send + Sync> MessageBoxClient<W>
impl<W: WalletInterface + Clone + 'static + Send + Sync> MessageBoxClient<W>
Sourcepub async fn query_advertisements(
&self,
identity_key: Option<&str>,
host: Option<&str>,
) -> Result<Vec<AdvertisementToken>, MessageBoxError>
pub async fn query_advertisements( &self, identity_key: Option<&str>, host: Option<&str>, ) -> Result<Vec<AdvertisementToken>, MessageBoxError>
Query the ls_messagebox overlay service for host advertisement tokens.
Returns all matching AdvertisementTokens. Malformed outputs are silently
skipped. The ENTIRE method is wrapped in error recovery that returns an empty
Vec — matching the TypeScript queryAdvertisements which wraps everything in
try/catch and returns [] on any error, including overlay unreachability.
TS parity:
} catch (err) { Logger.error('failed:', err); }
return hosts // always returns, never throwsSourcepub async fn resolve_host_for_recipient(
&self,
recipient: &str,
) -> Result<String, MessageBoxError>
pub async fn resolve_host_for_recipient( &self, recipient: &str, ) -> Result<String, MessageBoxError>
Resolve the MessageBox host for a given recipient identity key.
Queries the overlay for the recipient’s advertisements and returns the
first matching host. Falls back to self.host when:
- No advertisements exist for the recipient, or
- The overlay is unreachable (query_advertisements always returns Ok)
Sourcepub async fn anoint_host(&self, host: &str) -> Result<String, MessageBoxError>
pub async fn anoint_host(&self, host: &str) -> Result<String, MessageBoxError>
Broadcast a host advertisement to the tm_messagebox overlay topic.
Builds a PushDrop transaction with:
- fields[0] = identity key bytes (hex-decoded from identity key string)
- fields[1] = host URL bytes (UTF-8)
Returns the txid of the broadcast transaction, matching TS anointHost
which returns { txid }.
Sourcepub async fn register_device(
&self,
fcm_token: &str,
device_id: Option<&str>,
platform: Option<&str>,
override_host: Option<&str>,
) -> Result<RegisterDeviceResponse, MessageBoxError>
pub async fn register_device( &self, fcm_token: &str, device_id: Option<&str>, platform: Option<&str>, override_host: Option<&str>, ) -> Result<RegisterDeviceResponse, MessageBoxError>
Register a device for FCM push notifications.
POSTs {"fcmToken": ..., "deviceId": ..., "platform": ...} (camelCase) to
{host}/registerDevice. Returns RegisterDeviceResponse { status, message, deviceId }.
TS parity: registerDevice returns the full response object including deviceId.
Sourcepub async fn list_registered_devices(
&self,
override_host: Option<&str>,
) -> Result<Vec<RegisteredDevice>, MessageBoxError>
pub async fn list_registered_devices( &self, override_host: Option<&str>, ) -> Result<Vec<RegisteredDevice>, MessageBoxError>
List all registered devices for this identity.
GETs {host}/devices and returns Vec<RegisteredDevice>.
All 8 server fields (id, deviceId, fcmToken, platform, active,
createdAt, updatedAt, lastUsed) are captured.
Sourcepub async fn revoke_host_advertisement(
&self,
token: &AdvertisementToken,
) -> Result<String, MessageBoxError>
pub async fn revoke_host_advertisement( &self, token: &AdvertisementToken, ) -> Result<String, MessageBoxError>
Revoke an existing host advertisement by spending its UTXO.
Two-step create+sign pattern:
create_actionwithinput_beef+ input pointing to the advertisement UTXO. Returns a signable transaction with areferencefor the sign step.- Derive sighash preimage from the partial transaction.
create_signaturewith the advertisement protocol to produce a DER signature.sign_actionwith the DER+sighash-type unlock script.- Broadcast the signed transaction via TopicBroadcaster.
Returns the txid of the spending transaction.
Source§impl<W: WalletInterface + Clone + 'static + Send + Sync> MessageBoxClient<W>
impl<W: WalletInterface + Clone + 'static + Send + Sync> MessageBoxClient<W>
Sourcepub async fn send_message(
&self,
recipient: &str,
message_box: &str,
body: &str,
skip_encryption: bool,
check_permissions: bool,
message_id: Option<&str>,
override_host: Option<&str>,
) -> Result<String, MessageBoxError>
pub async fn send_message( &self, recipient: &str, message_box: &str, body: &str, skip_encryption: bool, check_permissions: bool, message_id: Option<&str>, override_host: Option<&str>, ) -> Result<String, MessageBoxError>
Send a message to a recipient’s inbox.
CRITICAL TS PARITY: resolves the recipient’s MessageBox host via overlay
(resolveHostForRecipient) before sending — matching TS line 952:
const finalHost = overrideHost ?? await this.resolveHostForRecipient(message.recipient)
When override_host is Some, it is used directly without overlay resolution.
- Asserts the client is initialized.
- Resolves recipient’s host via overlay (falls back to self.host if unreachable).
- Delegates to
send_message_to_hostwith the resolved host.
Sourcepub async fn send_message_to_recipients(
&self,
params: &SendListParams,
override_host: Option<&str>,
) -> Result<SendListResult, MessageBoxError>
pub async fn send_message_to_recipients( &self, params: &SendListParams, override_host: Option<&str>, ) -> Result<SendListResult, MessageBoxError>
Send a message to a list of recipients in a single batch operation.
Matches the TS sendMesagetoRecepients behavior (note the TS typo — Rust uses corrected name):
- Gets multi-recipient quote; blocked recipients are separated out.
- Creates a single batch payment transaction covering all payable recipients.
- Loops individual
send_message_to_hostcalls sharing the batch payment.
Sourcepub async fn list_messages_lite(
&self,
message_box: &str,
override_host: Option<&str>,
) -> Result<Vec<ServerPeerMessage>, MessageBoxError>
pub async fn list_messages_lite( &self, message_box: &str, override_host: Option<&str>, ) -> Result<Vec<ServerPeerMessage>, MessageBoxError>
Retrieve messages from an inbox without payment internalization.
Calls /listMessages and auto-decrypts each message body.
PARITY: passes originator: None to try_decrypt_message, matching
the TS listMessagesLite which omits originator (Pitfall 4).
Sourcepub async fn list_messages(
&self,
message_box: &str,
accept_payments: bool,
override_host: Option<&str>,
) -> Result<Vec<PeerMessage>, MessageBoxError>
pub async fn list_messages( &self, message_box: &str, accept_payments: bool, override_host: Option<&str>, ) -> Result<Vec<PeerMessage>, MessageBoxError>
Retrieve messages from an inbox with optional server payment internalization.
Unlike list_messages_lite, this method:
- Returns
Vec<PeerMessage>(notVec<ServerPeerMessage>) withrecipientpopulated fromget_identity_key()andmessage_boxfrom the parameter. - Parses the server’s
{ message, payment }wrapper body format. - When
accept_paymentsis true, internalizes the server delivery-fee payment viawallet.internalize_action. Errors are logged/ignored (TS parity).
Multi-host: queries all hosts advertised by this identity concurrently and
deduplicates results by message_id. Matches TS Promise.allSettled semantics:
if at least one host succeeds, partial results are returned.
NOTE: This handles the server delivery-fee payment wrapper, NOT PeerPay
PaymentTokens (peer-to-peer). PeerPay tokens are handled by list_incoming_payments.
Sourcepub async fn acknowledge_message(
&self,
message_ids: Vec<String>,
override_host: Option<&str>,
) -> Result<(), MessageBoxError>
pub async fn acknowledge_message( &self, message_ids: Vec<String>, override_host: Option<&str>, ) -> Result<(), MessageBoxError>
Mark messages as acknowledged (read) by their IDs.
TS PARITY: When override_host is None, fans out to ALL advertised hosts in parallel
(same join_all pattern as list_messages). Returns Ok if ANY host succeeds.
When override_host is Some, acks on that single host only.
Source§impl<W: WalletInterface + Clone + 'static + Send + Sync> MessageBoxClient<W>
impl<W: WalletInterface + Clone + 'static + Send + Sync> MessageBoxClient<W>
Sourcepub async fn request_payment(
&self,
recipient: &str,
amount: u64,
description: &str,
expires_at: u64,
) -> Result<PaymentRequestResult, MessageBoxError>
pub async fn request_payment( &self, recipient: &str, amount: u64, description: &str, expires_at: u64, ) -> Result<PaymentRequestResult, MessageBoxError>
Send a payment request to recipient for amount satoshis.
Generates a unique request ID and HMAC proof tying the request to the sender’s identity. Returns the request ID and proof (needed for cancellation).
Matches TS PeerPayClient.requestPayment().
Sourcepub async fn cancel_payment_request(
&self,
recipient: &str,
request_id: &str,
request_proof: &str,
host_override: Option<&str>,
) -> Result<(), MessageBoxError>
pub async fn cancel_payment_request( &self, recipient: &str, request_id: &str, request_proof: &str, host_override: Option<&str>, ) -> Result<(), MessageBoxError>
Cancel a previously sent payment request.
Requires the original request_id and request_proof returned from
request_payment(). Sends a cancellation message to the recipient’s
payment_requests inbox.
Matches TS PeerPayClient.cancelPaymentRequest().
Sourcepub async fn list_incoming_payment_requests(
&self,
host_override: Option<&str>,
limits: Option<PaymentRequestLimits>,
) -> Result<Vec<IncomingPaymentRequest>, MessageBoxError>
pub async fn list_incoming_payment_requests( &self, host_override: Option<&str>, limits: Option<PaymentRequestLimits>, ) -> Result<Vec<IncomingPaymentRequest>, MessageBoxError>
List active incoming payment requests with automatic filtering.
Performs multi-stage filtering matching TS listIncomingPaymentRequests:
- Parse and validate all messages
- Collect and verify cancellations (HMAC proof check)
- Filter: expired, cancelled, out-of-range, invalid proof
- Auto-acknowledge filtered messages
Returns only valid, active, in-range requests.
Sourcepub async fn fulfill_payment_request(
&self,
request: &IncomingPaymentRequest,
note: Option<&str>,
host_override: Option<&str>,
) -> Result<(), MessageBoxError>
pub async fn fulfill_payment_request( &self, request: &IncomingPaymentRequest, note: Option<&str>, host_override: Option<&str>, ) -> Result<(), MessageBoxError>
Fulfill a payment request — send payment and notify the requester.
- Sends the requested amount via PeerPay
- Sends a “paid” response to the requester’s response inbox
- Acknowledges the original request
Matches TS PeerPayClient.fulfillPaymentRequest().
Sourcepub async fn decline_payment_request(
&self,
request: &IncomingPaymentRequest,
note: Option<&str>,
host_override: Option<&str>,
) -> Result<(), MessageBoxError>
pub async fn decline_payment_request( &self, request: &IncomingPaymentRequest, note: Option<&str>, host_override: Option<&str>, ) -> Result<(), MessageBoxError>
Decline a payment request — notify the requester without sending payment.
Matches TS PeerPayClient.declinePaymentRequest().
Sourcepub async fn listen_for_live_payment_requests(
&self,
on_request: Arc<dyn Fn(IncomingPaymentRequest) + Send + Sync>,
override_host: Option<&str>,
) -> Result<(), MessageBoxError>
pub async fn listen_for_live_payment_requests( &self, on_request: Arc<dyn Fn(IncomingPaymentRequest) + Send + Sync>, override_host: Option<&str>, ) -> Result<(), MessageBoxError>
Listen for live payment requests via WebSocket.
Wraps listen_for_live_messages on the payment_requests inbox.
Cancellation messages are silently skipped.
Matches TS PeerPayClient.listenForLivePaymentRequests().
Sourcepub async fn list_payment_request_responses(
&self,
host_override: Option<&str>,
) -> Result<Vec<PaymentRequestResponse>, MessageBoxError>
pub async fn list_payment_request_responses( &self, host_override: Option<&str>, ) -> Result<Vec<PaymentRequestResponse>, MessageBoxError>
List responses to payment requests we’ve sent.
Returns all parsed responses from the payment_request_responses inbox.
Unparseable messages are silently skipped (safeParse behavior).
Matches TS PeerPayClient.listPaymentRequestResponses().
Sourcepub async fn listen_for_live_payment_request_responses(
&self,
on_response: Arc<dyn Fn(PaymentRequestResponse) + Send + Sync>,
override_host: Option<&str>,
) -> Result<(), MessageBoxError>
pub async fn listen_for_live_payment_request_responses( &self, on_response: Arc<dyn Fn(PaymentRequestResponse) + Send + Sync>, override_host: Option<&str>, ) -> Result<(), MessageBoxError>
Listen for live payment request responses via WebSocket.
Wraps listen_for_live_messages on the payment_request_responses inbox.
Unparseable messages are silently skipped (safeParse behavior).
Matches TS PeerPayClient.listenForLivePaymentRequestResponses().
Sourcepub async fn allow_payment_requests_from(
&self,
identity_key: &str,
host_override: Option<&str>,
) -> Result<(), MessageBoxError>
pub async fn allow_payment_requests_from( &self, identity_key: &str, host_override: Option<&str>, ) -> Result<(), MessageBoxError>
Allow payment requests from a specific identity key.
Sets recipient_fee to 0 (always allow) for the payment_requests inbox.
Matches TS PeerPayClient.allowPaymentRequestsFrom().
Sourcepub async fn block_payment_requests_from(
&self,
identity_key: &str,
host_override: Option<&str>,
) -> Result<(), MessageBoxError>
pub async fn block_payment_requests_from( &self, identity_key: &str, host_override: Option<&str>, ) -> Result<(), MessageBoxError>
Block payment requests from a specific identity key.
Sets recipient_fee to -1 (blocked) for the payment_requests inbox.
Matches TS PeerPayClient.blockPaymentRequestsFrom().
Sourcepub async fn list_payment_request_permissions(
&self,
host_override: Option<&str>,
) -> Result<Vec<(String, bool)>, MessageBoxError>
pub async fn list_payment_request_permissions( &self, host_override: Option<&str>, ) -> Result<Vec<(String, bool)>, MessageBoxError>
List payment request permissions.
Returns a list of (identity_key, allowed) pairs for the
payment_requests inbox.
Matches TS PeerPayClient.listPaymentRequestPermissions().
Source§impl<W: WalletInterface + Clone + 'static + Send + Sync> MessageBoxClient<W>
impl<W: WalletInterface + Clone + 'static + Send + Sync> MessageBoxClient<W>
Sourcepub async fn create_payment_token(
&self,
recipient: &str,
amount: u64,
) -> Result<PaymentToken, MessageBoxError>
pub async fn create_payment_token( &self, recipient: &str, amount: u64, ) -> Result<PaymentToken, MessageBoxError>
Create a PeerPay payment token for recipient worth amount satoshis.
Steps:
- Generate two nonces (prefix, suffix) via
create_nonce. - Derive a P2PKH locking key via
get_public_keywith protocol[2, "3241645161d8"]. - Build a P2PKH locking script from the derived key hash.
- Call
create_actionwithrandomize_outputs: falseso output_index=0 is stable. - Return
PaymentTokenwithoutput_index: None— the TS convention is to set it only at accept time (defaulted to 0 via unwrap_or(0)).
Sourcepub async fn send_payment(
&self,
recipient: &str,
amount: u64,
) -> Result<String, MessageBoxError>
pub async fn send_payment( &self, recipient: &str, amount: u64, ) -> Result<String, MessageBoxError>
Send a payment to recipient by creating a token and posting it to their payment_inbox.
Returns the message ID assigned by the server (or the HMAC-derived ID).
Sourcepub async fn send_live_payment(
&self,
recipient: &str,
amount: u64,
) -> Result<String, MessageBoxError>
pub async fn send_live_payment( &self, recipient: &str, amount: u64, ) -> Result<String, MessageBoxError>
Send a payment to recipient over WebSocket with HTTP fallback.
Creates a payment token via create_payment_token, serializes it as JSON,
and sends via send_live_message (which handles WS timeout + HTTP fallback).
Thin wrapper — matches TS PeerPayClient.sendLivePayment.
Returns the message ID regardless of whether delivery was live or persisted.
Callers that need to distinguish live vs persisted should call
send_live_message directly and inspect DeliveryMode.
Sourcepub async fn listen_for_live_payments(
&self,
on_payment: Arc<dyn Fn(IncomingPayment) + Send + Sync>,
) -> Result<(), MessageBoxError>
pub async fn listen_for_live_payments( &self, on_payment: Arc<dyn Fn(IncomingPayment) + Send + Sync>, ) -> Result<(), MessageBoxError>
Subscribe to live payment notifications on the payment_inbox.
Wraps listen_for_live_messages with a callback that parses the message
body as a PaymentToken and constructs an IncomingPayment. Messages
whose bodies are not valid payment tokens are silently ignored (matches
TS safeParse behavior).
Sourcepub async fn accept_payment(
&self,
payment: &IncomingPayment,
) -> Result<(), MessageBoxError>
pub async fn accept_payment( &self, payment: &IncomingPayment, ) -> Result<(), MessageBoxError>
Internalize a received payment and acknowledge the message.
Base64-decodes derivation_prefix/suffix back to raw bytes so the SDK’s bytes_as_base64 serde re-encodes them to the original base64 strings that BSV Desktop expects.
Sourcepub async fn reject_payment(
&self,
payment: &IncomingPayment,
) -> Result<(), MessageBoxError>
pub async fn reject_payment( &self, payment: &IncomingPayment, ) -> Result<(), MessageBoxError>
Reject a received payment.
- If
amount < 2000: only acknowledges (refund after fee would be ≤ 0). - If
amount >= 2000: accepts (internalizes), sends a refund ofamount - 1000, then double-acknowledges (intentional TS parity — server is idempotent).
TS parity: 401 auth errors are silently swallowed (logged but not propagated). All other errors propagate normally.
Sourcepub async fn list_incoming_payments(
&self,
) -> Result<Vec<IncomingPayment>, MessageBoxError>
pub async fn list_incoming_payments( &self, ) -> Result<Vec<IncomingPayment>, MessageBoxError>
List all incoming payments from the payment_inbox.
Uses the full multi-host list_messages path (matching TS listIncomingPayments
which calls this.listMessages), so payments on all advertised hosts are returned.
Silently skips messages whose bodies are not valid JSON payment tokens
(mirrors TS safeParse behavior).
Sourcepub async fn acknowledge_notification(
&self,
message: &PeerMessage,
) -> Result<bool, MessageBoxError>
pub async fn acknowledge_notification( &self, message: &PeerMessage, ) -> Result<bool, MessageBoxError>
Acknowledge a notification message, internalizing any embedded delivery-fee payment.
Matches TS acknowledgeNotification exactly:
- Acknowledges the message FIRST (removes from server queue).
- Parses body for a
{ message, payment }delivery-fee wrapper (NOT a PeerPay token). - If a delivery-fee payment exists with
wallet paymentoutputs, internalizes it. - Returns true if payment was internalized, false otherwise.
Source§impl<W: WalletInterface + Clone + 'static + Send + Sync> MessageBoxClient<W>
impl<W: WalletInterface + Clone + 'static + Send + Sync> MessageBoxClient<W>
Sourcepub async fn set_message_box_permission(
&self,
params: SetPermissionParams,
override_host: Option<&str>,
) -> Result<(), MessageBoxError>
pub async fn set_message_box_permission( &self, params: SetPermissionParams, override_host: Option<&str>, ) -> Result<(), MessageBoxError>
Set a permission rule for a message box.
POSTs camelCase JSON to /permissions/set. The server returns HTTP 200
even for logical errors — use check_status_error to detect them.
Sourcepub async fn get_message_box_permission(
&self,
recipient: &str,
message_box: &str,
sender: Option<&str>,
override_host: Option<&str>,
) -> Result<Option<MessageBoxPermission>, MessageBoxError>
pub async fn get_message_box_permission( &self, recipient: &str, message_box: &str, sender: Option<&str>, override_host: Option<&str>, ) -> Result<Option<MessageBoxPermission>, MessageBoxError>
Retrieve a single permission record.
GETs /permissions/get with camelCase query params (recipient, messageBox,
optional sender). Returns None when the server responds with
{"permission": null}.
Sourcepub async fn list_message_box_permissions(
&self,
message_box: Option<&str>,
limit: Option<u32>,
offset: Option<u32>,
override_host: Option<&str>,
) -> Result<Vec<MessageBoxPermission>, MessageBoxError>
pub async fn list_message_box_permissions( &self, message_box: Option<&str>, limit: Option<u32>, offset: Option<u32>, override_host: Option<&str>, ) -> Result<Vec<MessageBoxPermission>, MessageBoxError>
List permission records for this identity key.
GETs /permissions/list with snake_case message_box query param —
this is the unique endpoint that uses snake_case for its query key
(Pitfall 1: do NOT use messageBox here).
Sourcepub async fn get_message_box_quote(
&self,
recipient: &str,
message_box: &str,
override_host: Option<&str>,
) -> Result<MessageBoxQuote, MessageBoxError>
pub async fn get_message_box_quote( &self, recipient: &str, message_box: &str, override_host: Option<&str>, ) -> Result<MessageBoxQuote, MessageBoxError>
Get a delivery quote for sending a message to recipient’s message_box.
The response body is wrapped ({"quote": {...}}). The delivery agent’s
identity key comes from the x-bsv-auth-identity-key response header —
NOT from the JSON body (Pitfall 2).
Sourcepub async fn allow_notifications_from_peer(
&self,
sender: &str,
recipient_fee: i64,
override_host: Option<&str>,
) -> Result<(), MessageBoxError>
pub async fn allow_notifications_from_peer( &self, sender: &str, recipient_fee: i64, override_host: Option<&str>, ) -> Result<(), MessageBoxError>
Allow a peer to send notifications by granting them access to the
"notifications" message box with the given recipient_fee.
Sourcepub async fn deny_notifications_from_peer(
&self,
sender: &str,
override_host: Option<&str>,
) -> Result<(), MessageBoxError>
pub async fn deny_notifications_from_peer( &self, sender: &str, override_host: Option<&str>, ) -> Result<(), MessageBoxError>
Block a peer from the "notifications" message box by setting
recipient_fee = -1.
Sourcepub async fn check_peer_notification_status(
&self,
peer: &str,
override_host: Option<&str>,
) -> Result<Option<MessageBoxPermission>, MessageBoxError>
pub async fn check_peer_notification_status( &self, peer: &str, override_host: Option<&str>, ) -> Result<Option<MessageBoxPermission>, MessageBoxError>
Check whether peer has notification access from this identity’s
perspective.
Uses get_identity_key() for recipient — the check is always
performed against the local identity.
Sourcepub async fn list_peer_notifications(
&self,
override_host: Option<&str>,
) -> Result<Vec<MessageBoxPermission>, MessageBoxError>
pub async fn list_peer_notifications( &self, override_host: Option<&str>, ) -> Result<Vec<MessageBoxPermission>, MessageBoxError>
List all permission records in the "notifications" message box.
Sourcepub async fn send_notification(
&self,
recipient: &str,
body: &str,
override_host: Option<&str>,
) -> Result<String, MessageBoxError>
pub async fn send_notification( &self, recipient: &str, body: &str, override_host: Option<&str>, ) -> Result<String, MessageBoxError>
Send a notification body to recipient’s "notifications" inbox.
Delegates to send_message with message_box = "notifications" and
check_permissions = true — matching TS which passes checkPermissions: true
so that fee quotes are fetched and payments created if required.
Sourcepub async fn get_message_box_quote_multi(
&self,
recipients: &[&str],
message_box: &str,
override_host: Option<&str>,
) -> Result<MessageBoxMultiQuote, MessageBoxError>
pub async fn get_message_box_quote_multi( &self, recipients: &[&str], message_box: &str, override_host: Option<&str>, ) -> Result<MessageBoxMultiQuote, MessageBoxError>
Get delivery quotes for multiple recipients in one logical call.
Groups recipients by resolved host, requests quotes from each host,
then aggregates into a MessageBoxMultiQuote with per-recipient breakdown
and delivery agent identity keys per host.
Sourcepub async fn send_notification_to_recipients(
&self,
recipients: &[&str],
body: &str,
override_host: Option<&str>,
) -> Result<SendListResult, MessageBoxError>
pub async fn send_notification_to_recipients( &self, recipients: &[&str], body: &str, override_host: Option<&str>, ) -> Result<SendListResult, MessageBoxError>
Send a notification to multiple recipients at once.
Delegates to send_message_to_recipients with message_box = "notifications".
Matches the TS sendNotification overload that accepts PubKeyHex[].