Skip to main content

Threads & Inboxes

Inboxes​

An Inbox is an on-chain account a wallet creates to receive threads. It acts as a public directory: senders look up your inbox to find where to deliver threads and what rules to follow.

Creating an inbox opens on-chain account state and can cost around 1 USD depending on rent and network conditions. You do not need to create a custom inbox just to communicate; create inboxes when you need a named endpoint, metadata, payment rules, escrow rules, or separate routing.

Inbox Kinds​

KindDescription
StandardPersists across uses and keeps a thread directory; the default for most applications
EphemeralLightweight, throwaway-style inbox that does not keep the same long-term directory history

Inbox Metadata​

An inbox can store a name and metadata uri on-chain. The URI can point to an off-chain JSON file describing the inbox further (icon, description, etc.).

Thread Directory​

The inbox maintains a paginated list of all threads addressed to it. The inbox itself is an on-chain account, and each inbox body page is another on-chain account. As body pages fill, older pages are archived/compressed and new bodies continue the directory. Apps walk the pages to display a conversation list.

A wallet can have multiple inboxes (inbox 0, 1, 2, …), each with separate rules and thread lists.


Threads​

A Thread is the conversation container between exactly two wallets. It is created by the sender in the same transaction as the first message.

Thread Lifecycle​

1. Sender calls createThread(to, ...) → Thread account is created on-chain
2. Both parties can send messages (sendMessage)
3. Thread stays open indefinitely — there is no close operation

Thread Identity​

Each thread has:

  • A numeric thread ID (auto-assigned or caller-supplied)
  • On-chain addresses for both from and to wallets
  • A totalMsgs counter
  • An optional escrowPayment balance (if the inbox required escrow)

Messages​

Messages are appended to the thread by either party. Each message has:

  • A sequential msgSeq number
  • A messageType: Text, Url, Ipfs, Irys, or Arweave
  • A content field: inline text or a canonical pointer/ID
  • Optional Packet envelope text that preserves MIME type and encoding for text or binary parts
  • An optional attached payment

Keep large bodies out of the compressed message account. Store URLs/pointers on-chain and upload the body to Irys, IPFS, Arweave, HTTPS, or custom storage. Inline payloads larger than about 128 bytes are not recommended because transactions can fail from size/compute limits.

Loading Threads​

Threads are compressed accounts stored via Light Protocol. Reading them requires querying the Photon RPC indexer rather than the standard Solana RPC.

Messages and activity records also use compressed/indexed state. Inbox and inbox body accounts are normal on-chain accounts because they define receiving endpoints and browsable thread directories.

// Load a thread by numeric ID
const thread = await client.thread(42).load();

// Load all threads in an inbox
const threads = await inbox.loadThreadsAcrossBodies({ limit: 25 });

// Load all threads a wallet has sent or received
const activity = client.activity();
const threads = await activity.loadThreadsAcrossHistory({ limit: 50 });

Addressing​

When creating a thread, the sender must specify which inbox to target:

await client.createThread({
to: recipientPublicKey,
// targetInbox is optional; defaults to the receiver's inbox 0
});

If the receiver has a payment rule on their inbox, the SDK automatically includes the required payment. You can also explicitly specify the inbox:

const targetInbox = await client.inbox(1); // inbox ID 1 of the connected wallet
await client.createThread({ to, targetInbox });

SDK Reference​