Skip to main content

Rooms

The room command group creates and runs XPKT group chats from the terminal: one admin manages membership, every member sends and reads end-to-end encrypted messages. New members cannot read history from before they joined, and removed members cannot read anything sent after their removal — enforced cryptographically, not by access control.

For the protocol model, see Rooms & Group Messaging. For the SDK, see SDK Rooms.

The admin identity is the configured wallet: room create derives the room admin seed by signing with your keypair, so the room is fully recoverable from the wallet alone — there is no seed file to store.


Prerequisites

Rooms need a BGW params artifact — the public material the group encryption is built on. Configure it once; it is shared by every room. Set it on config init or via environment variables:

# local artifact directory (manifest.json + chunks/*.bin)
packet config init --rpc <url> --keypair ~/.config/solana/id.json \
--bgw-params-dir /path/to/params

# or an HTTP-hosted manifest
packet config init --rpc <url> --keypair ~/.config/solana/id.json \
--bgw-params-url https://<host>/params/manifest.json
SourceConfig flagEnv varTOML key
Local directory--bgw-params-dir <path>PACKET_BGW_PARAMS_DIR[bgw_params] dir
HTTP manifest--bgw-params-url <url>PACKET_BGW_PARAMS_URL[bgw_params] url

Environment variables take precedence over the config file. If no source is configured, room commands fail with a clear error — point the CLI at an artifact (a local directory, or the SDK's public default at https://arweave.net/erEnI-MC4igmd9SpXuWmoVRiz6zfK-tVqyz5yGjmF8M). For hosting or generating your own, see BGW params.


Quick Start — create, add, send, read

# 1. Create a room (you become the admin). Prints the room id and PDA address.
packet room create

# 2. Add members by wallet public key
packet room add <roomId> <memberPubkey>
packet room add <roomId> <anotherMemberPubkey>

# 3. Send a message
packet room send <roomId> "welcome to the room"

# 4. Read + decrypt the latest messages
packet room read <roomId>

<roomId> is the 32-byte room id (hex) printed by room create. The admin is not automatically a member — to send and read as the admin, add your own wallet first: packet room add <room> <yourPubkey>.

Members using the CLI (raw keypairs) need no key registration; the SDK page Member keys covers the browser-wallet case.


Admin Commands

room create

Create a room. Derives the admin seed by signing with the loaded keypair and uses the configured default BGW params.

packet room create [--room-id <hex>] [--json]
FlagDefaultDescription
--room-id <hex>randomExplicit 32-byte room id (64 hex chars). Random when omitted.
--jsonfalsePrint JSON output.

Prints the room address, room id, the pinned BGW params identity (paramsId / paramsRoot), and transaction signatures.

room add

Add (or re-activate) a member and publish the covering header. A new member gets the next slot; a previously removed member keeps their original slot.

packet room add <roomId> <memberPubkey> [--skip-key-check] [--json]
Argument / FlagDefaultDescription
<roomId>required32-byte room id (hex), printed by room create.
<memberPubkey>requiredMember Solana public key.
--skip-key-checkfalseSkip the registered-key lookup and always encrypt to the member's wallet-derived key. Use only for members known to control a raw keypair.
--jsonfalsePrint JSON output.

room remove

Remove a member and publish the covering header. The removed member can no longer send, and cannot read anything sent after the removal.

packet room remove <roomId> <memberPubkey> [--json]
Argument / FlagDefaultDescription
<roomId>required32-byte room id (hex), printed by room create.
<memberPubkey>requiredMember Solana public key.
--jsonfalsePrint JSON output.

room members

List active members and their slots.

packet room members <roomId> [--json]

room info

Show room state: current epoch, member version, next slot, message count, bucket, recipient mode/depth, and the pinned BGW params identity.

packet room info <roomId> [--json]

room admin-recover

Verify zero-state admin recovery: re-derive the admin secret from the loaded keypair, reconstruct the recipient state from the on-chain header chain, and confirm it matches the room's on-chain state root.

packet room admin-recover <roomId> [--json]

Messaging Commands

room send

Send an encrypted message to a room. The configured wallet must be an active member.

packet room send <roomId> <text> [--json]
Argument / FlagDefaultDescription
<roomId>required32-byte room id (hex), printed by room create.
<text>requiredMessage text.
--jsonfalsePrint JSON output.

room read

Read and decrypt room messages, paginated by bucket (100 messages per bucket).

packet room read <roomId> [--limit <n>] [--before-seq <s>] [--no-decrypt] [--json]
FlagDefaultDescription
--limit <n>50Max messages to return.
--before-seq <s>Only messages with global sequence < s (for paging older).
--no-decryptLeave content encrypted.
--jsonfalsePrint JSON output.

Each message is shown with its sequence number, sender, slot, and a status: decrypted, locked (this wallet is not a recipient of that message's epoch — expected for history before you joined), or failed.


Next Steps

  • SDK Rooms — the same workflow in TypeScript, plus depth.
  • BGW params — hosting and generating the params artifact.
  • MCP rooms — the equivalent tools for agent hosts.