npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@bsv/p2p

v1.0.13

Published

A client for P2P messaging and payments

Downloads

515

Readme

BSV Peer-to-Peer Messaging & Payment Tools

@bsv/p2p 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 for mutual authentication and identity key management, allowing secure and authenticated exchanges of data and BSV.

Table of Contents

  1. Introduction
  2. Installation
  3. Overview
  4. Quick Start Examples
  5. API Reference
  6. Contributing
  7. License

1. Introduction

The @bsv/p2p library provides two main tools for peer-to-peer interaction:

  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.
  2. PeerPayClient – A higher-level payment client built on top of MessageBoxClient, enabling real-time, peer-to-peer Bitcoin payments on the BSV blockchain.

Both clients use the BRC-103-based authentication model. By integrating with a WalletClient, they can sign and verify messages, ensuring only authorized parties can send and receive.


2. Installation

npm install @bsv/p2p

The package exports both MessageBoxClient and PeerPayClient. You can import them individually in your JavaScript/TypeScript applications.


3. Overview

3.1. MessageBoxClient Overview

MessageBoxClient implements a store-and-forward architecture for P2P messages:

  • Store-and-forward: Messages are posted to a central MessageBoxServer under a named "message box" (like an inbox).
  • Ephemeral storage: Once the recipient acknowledges the messages, they are removed from the server.
  • Mutual authentication: Ensures only authorized peers can read or post messages, using AuthFetch and AuthSocketClient.
  • Flexible transport: Supports both WebSockets (for live, push-style delivery) and HTTP (for polling or fallback).
  • Extensible: Can be the foundation for more advanced workflows (e.g., token-based messaging, invoice/ticket systems, etc.).

Key Features

  1. Secure by default using Auth libraries for signing/verification.
  2. Real-time or delayed delivery with sockets or HTTP.
  3. Easy integration with higher-level protocols and services.

3.2. PeerPayClient Overview

PeerPayClient builds on MessageBoxClient to enable peer-to-peer Bitcoin payments:

  • Secure Payment Delivery: Utilizes the same store-and-forward or live WebSocket approach for delivering payment instructions.
  • Derivation & Signing: Creates a unique output script for each payment, derived from sender + recipient keys.
  • Live or Delayed: Works with web sockets for immediate notifications, or HTTP for an asynchronous flow.
  • Wallet Integration: Accept or reject incoming payments. If accepted, the payment is “internalized” into your BRC-100 compatible wallet automatically.

Key Features

  1. Deterministic derivation of payment information using the SPV-compliant BRC-29 protocol.
  2. Secure transaction passing using the MessageBoxClient infrastructure.
  3. Live or offline support for receiving payments.
  4. Easy acceptance/refunds with built-in methods.

4. Quick Start Examples

Below are two condensed examples: one for basic messaging (MessageBoxClient) and another for peer-to-peer payments (PeerPayClient).

4.1. Using MessageBoxClient

const { WalletClient } = require('@bsv/sdk')
const { MessageBoxClient } = require('@bsv/p2p')

// Example identity key of the recipient (public key in hex)
const johnSmithKey = '022600d2ef37d123fdcac7d25d7a464ada7acd3fb65a0daf85412140ee20884311'

async function main() {
  // 1) Create your WalletClient (this obtains your identity key)
  const myWallet = new WalletClient()

  // 2) Create a MessageBoxClient, pointing to a MessageBoxServer
  const msgBoxClient = new MessageBoxClient({
    host: 'https://messagebox.babbage.systems',
    walletClient: myWallet
  })

  // (Optional) Initialize a WebSocket connection (for real-time listening)
  await msgBoxClient.initializeConnection()

  // 3) Send a message to John's "demo_inbox"
  await msgBoxClient.sendMessage({
    recipient: johnSmithKey,
    messageBox: 'demo_inbox',
    body: 'Hello John! This is a test message.'
  })

  // 4) List messages in "demo_inbox"
  const messages = await msgBoxClient.listMessages({ messageBox: 'demo_inbox' })
  console.log(messages[0].body) // --> "Hello John! This is a test message."

  // 5) Acknowledge (and delete) them from the server
  await msgBoxClient.acknowledgeMessage({
    messageIds: messages.map(msg => msg.messageId.toString())
  })
}

main().catch(console.error)

Listening for Live Messages
If you want push-style message notifications instead of polling:

await msgBoxClient.listenForLiveMessages({
  messageBox: 'demo_inbox',
  onMessage: (msg) => {
    console.log('Received live message in "demo_inbox":', msg.body)
  }
})

4.2. Using PeerPayClient

import { WalletClient } from '@bsv/sdk'
import { PeerPayClient } from '@bsv/p2p'

async function paymentDemo() {
  // 1) Create your wallet instance
  const wallet = new WalletClient()

  // 2) Create a PeerPayClient
  const peerPay = new PeerPayClient({
    walletClient: wallet
  })

  // 3) (Optional) Listen for incoming payments
  await peerPay.listenForLivePayments({
    onPayment: async (payment) => {
      console.log('Received payment:', payment)
      // Accept it into the wallet
      await peerPay.acceptPayment(payment)
    }
  })

  // 4) Send a payment of 50,000 sats to the recipient
  await peerPay.sendLivePayment({
    recipient: '0277a2b...e3f4', // recipient's public key
    amount: 50000
  })
}

paymentDemo().catch(console.error)

Note: sendLivePayment will try WebSocket first and fall back to HTTP if unavailable.


5. API Reference

5.1. MessageBoxClient API

import { MessageBoxClient } from '@bsv/p2p'

Constructor

new MessageBoxClient({
  host?: string,
  walletClient: WalletClient
})
  • host: (Optional) Base URL of the MessageBoxServer. Defaults to https://messagebox.babbage.systems.
  • walletClient: A WalletClient instance for identity key and signing.

initializeConnection()

await msgBoxClient.initializeConnection()
  • Establishes a WebSocket connection to host.
  • Authenticates with your wallet’s identity key.

listenForLiveMessages({ messageBox, onMessage })

await msgBoxClient.listenForLiveMessages({
  messageBox: 'demo_inbox',
  onMessage: (msg) => {
    console.log('New message in "demo_inbox":', msg)
  }
})
  • Joins a WebSocket "room" for the specified messageBox.
  • Executes onMessage callback whenever a new message arrives.

sendLiveMessage({ recipient, messageBox, body })

const result = await msgBoxClient.sendLiveMessage({
  recipient: johnSmithKey,
  messageBox: 'demo_inbox',
  body: 'Hello in real-time!'
})
  • Sends a message via WebSockets (falls back to HTTP if the socket is not connected).
  • recipient: Hex-encoded public key of the recipient.
  • messageBox: Name of the box (e.g., "demo_inbox").
  • body: Message payload (string or object).

Returns a SendMessageResponse with { status: 'success', messageId } on success.


sendMessage({ recipient, messageBox, body })

const response = await msgBoxClient.sendMessage({
  recipient: johnSmithKey,
  messageBox: 'demo_inbox',
  body: 'Hello via HTTP!'
})
  • Sends the message via HTTP only.
  • recipient: Recipient's identity key.
  • messageBox: Name of the box.
  • body: Message content (string or object).

Returns { status: 'success', messageId } on success.


listMessages({ messageBox })

const messages = await msgBoxClient.listMessages({ messageBox: 'demo_inbox' })
  • Lists messages in the specified messageBox.
  • Returns an array of PeerMessage.
interface PeerMessage {
  messageId: number;
  body: string;
  sender: string;
  created_at: string;
  updated_at: string;
  acknowledged?: boolean;
}

acknowledgeMessage({ messageIds })

await msgBoxClient.acknowledgeMessage({
  messageIds: ['1234', '5678']
})
  • Acknowledges (and deletes) the specified messages from the server.
  • messageIds: Array of message IDs (as strings).

5.2. PeerPayClient API

import { PeerPayClient } from '@bsv/p2p'

Constructor

new PeerPayClient({
  walletClient: WalletClient,
  messageBoxHost?: string,
  enableLogging?: boolean
})
  • walletClient: (Required) Your identity/signing wallet.
  • messageBoxHost: (Optional) Base URL of the MessageBoxServer. Defaults to https://messagebox.babbage.systems.
  • enableLogging: (Optional) Enables verbose debug output.

sendPayment({ recipient, amount })

await peerPay.sendPayment({
  recipient: '0277a2b...',
  amount: 10000
})
  • Sends a payment using HTTP.
  • Internally derives a public key for the recipient and builds a transaction.

sendLivePayment({ recipient, amount })

await peerPay.sendLivePayment({
  recipient: '0277a2b...',
  amount: 15000
})
  • Sends a payment using WebSockets, falling back to HTTP if needed.

listenForLivePayments({ onPayment })

await peerPay.listenForLivePayments({
  onPayment: (payment) => {
    console.log('New live payment:', payment)
  }
})
  • Subscribes to live payments in the payment_inbox.
  • Invokes onPayment callback with an IncomingPayment object:
interface IncomingPayment {
  messageId: number;
  sender: string;
  token: {
    customInstructions: {
      derivationPrefix: string;
      derivationSuffix: string;
    };
    transaction: any; // typically your BSV transaction format
    amount: number;
  };
}

acceptPayment(payment)

await peerPay.acceptPayment(payment)
  • Accepts (and "internalizes") the payment into your wallet.
  • Acknowledges the message, removing it from the inbox.

rejectPayment(payment)

await peerPay.rejectPayment(payment)
  • Rejects the payment, returning a refund to the sender (minus a small fee, e.g. 1000 sats).
  • If the amount is too small to refund, the payment is simply acknowledged and dropped.

listIncomingPayments()

const payments = await peerPay.listIncomingPayments()
  • Lists all incoming payments in the payment_inbox.
  • Returns an array of IncomingPayment objects.

6. Contributing

  1. Clone this repository.
  2. Install dependencies with npm install.
  3. Make your changes, write tests, and open a PR.

We welcome bug reports, feature requests, and community contributions!


7. License

This code is licensed under the Open BSV License. See LICENSE for details.