Skip to main content

Inbox

An inbox is an on-chain account that tells the world "I'm open to receiving messages." Without one, senders can still open threads to you — they just can't pay you on first contact or be tracked in a paginated list.

Inboxes are created by the recipient, not the sender.

What an inbox does

  • Registers you as reachable. Senders can look up your inbox address and include it in thread creation, which updates your inbox's thread list on-chain.
  • Enforces payment rules. You can require senders to pay a token amount before their first message is delivered. Funds can go directly to your wallet or into escrow.
  • Paginates incoming threads. The inbox body stores thread IDs in compressed, fixed-size pages that fill up and roll over. This gives you an efficient, fully on-chain conversation list.

Inbox kinds

enum InboxKind {
Standard = 0, // stores thread list in paginated bodies
Ephemeral = 1, // no body; threads are tracked off-chain
}

Use Standard for production inboxes. Ephemeral is for testing or flows where you don't need the on-chain thread list.

Creating an inbox

const { receipt, client: inbox } = await client.createInbox({
inboxId: 1,
inboxKind: InboxKind.Standard,
});

You can have multiple inboxes — each has a numeric inboxId that forms part of its PDA. Most apps create one per user (inboxId: 1).

See Payment Rules to add payment gating.

Loading an inbox

By ID (resolves your own inbox):

const inbox = await client.inbox(1);

By address (someone else's inbox, or an address you already know):

const inbox = await client.inbox(inboxAddress);

The body/page system

A Standard inbox stores thread IDs in a fixed-size compressed account called a body. When a body fills up, a new one is created and the inbox's index increments. Old bodies become archives and are still readable.

This means:

  • inbox.Inbox.index is the current (live) body page number.
  • inbox.Inbox.len is the total number of threads received across all pages.
  • Bodies are numbered 0, 1, 2, ... — index 0 is the oldest.

See Browsing Threads for how to walk pages and load threads.

Editing payment rules

After creation, update or remove the inbox's payment rule with editPayment:

// Update to a new rule
await inbox.editPayment({
payment: {
amount: new BN(10_000_000),
mint: usdcMint,
escrowEnabled: true,
},
});

// Remove the payment rule entirely
await inbox.editPayment({ payment: null });

See Payment Rules for the full field reference.

Returns Promise<TxReceiptWithClient<InboxClient>>


Creating a thread from an inbox

If you already have an InboxClient, use createThread on it directly — it automatically fills in to and targetInbox:

const { client: thread } = await inbox.createThread({
messageType: MessageType.Text,
content: "Hello!",
});

This is equivalent to calling client.createThread({ to: inbox.owner, targetInbox: inbox, ... }).


The Inbox type

interface Inbox {
address: PublicKey;
kind: InboxKind;
owner: PublicKey;
id: BN;
index: BN; // current body page index
len: BN; // total threads received
lastUpdated: number;
paymentRule: PaymentRule | null;
}