Skip to main content

Reading Messages

Last message​

The most common fetch — get the most recent message in a thread:

const message = await thread.loadLastMessage();

if (message) {
const content = await message.loadContent();
console.log(content.text);
}

Returns null if the thread has no messages yet.


Loading a range​

loadMessages walks the sequence number range and returns an array of loaded MessageClient instances.

// Last 20 messages (newest first by default)
const messages = await thread.loadMessages({ limit: 20 });

// Paginate backward from a given seq
const older = await thread.loadMessages({
limit: 20,
fromSeq: 40,
direction: "backward",
});
FieldTypeDefaultDescription
limitnumbertotal message countMax messages to return
fromSeqnumberlastMsgSeqStarting sequence number
direction"backward" | "forward""backward"Walk direction

All fetches in the range are parallelised internally.


Single message by sequence​

const message = await thread.loadMessage(3);

Or build a handle without fetching and load it later:

const handle = thread.getMessage(3);
await handle.load();

Message content​

Call loadContent() to resolve the message body. Inline text stays local; URL/Irys/IPFS/Arweave content is fetched and returned as bytes with optional text.

const result = await message.loadContent();

if (result.kind === "inline") {
console.log(result.text); // Text message stored on-chain
} else {
console.log(result.url); // Gateway/source URL
console.log(result.contentType); // HTTP Content-Type when available
console.log(result.bytes); // Raw bytes
console.log(result.text); // Only set for textual MIME types
}
MessageTypeStorageBehaviour
Text (0)Inline, on-chainReads the buffer directly — no network call.
Url (1)External URLFetches the URL over HTTP.
Ipfs (2)IPFSFetches from the IPFS gateway URL in the message.
Irys (3)Irys / ArweaveFetches from the Irys URL.
Arweave (4)ArweaveSame as Irys.

Binary resources are not force-decoded into strings. For example, an unencrypted uploaded PNG returns bytes and contentType: "image/png", while text stays undefined.


Parsed content​

Use loadParsedContent() when you want the normal Packet reader flow:

const parsed = await message.loadParsedContent({ decrypt: true });

console.log(parsed.encrypted);
console.log(parsed.subject);
console.log(parsed.message);
console.log(parsed.mediaKind); // "text" | "binary"

It loads inline/external content, decrypts textual encrypted JSON when requested, parses the Packet envelope, and returns display text plus raw bytes/text metadata.

For binary Packet envelope parts, parsed.message contains a preview such as [binary image/png, ~24 KB base64], and parsed.parts keeps the structured PacketContent values for download/resource rendering.


MessageClient reference​

Static methods​

MessageClient.Handle({ client, threadId, msgSeq })​

Creates a handle without fetching. Load later with .load().

const handle = MessageClient.Handle({ client, threadId: 42, msgSeq: 3 });
await handle.load();

Returns MessageClient


Instance methods​

MethodDescription
load(force?)Fetch from chain. Skips if already loaded unless force is true.
loadRetrying(retries?, delay?)Fetch with retries — useful right after sending when the tx may not yet be visible.
refresh()Force-reload and clear cached content.
loadContent(force?)Resolve content (inline read or external fetch).
loadParsedContent({ decrypt?, force? })Load, optionally decrypt, parse Packet envelope, and classify text/binary media.

loadRetrying parameters (positional):

ParameterTypeDefaultDescription
retriesnumber3Max retry attempts
delaynumber250Delay between retries in milliseconds

Getters​

GetterTypeDescription
LoadedbooleanWhether message data has been fetched
MessageMessageRaw on-chain data (throws if not loaded)
ContentMessageContentLoadResultResolved content (throws if loadContent not called)

Types​

interface Message {
threadId: number;
msgSeq: number;
senderSide: MessageSenderSide; // 0 = from, 1 = to
timestamp: number;
payment: Payment | null;
messageType: MessageType;
content: Buffer; // raw bytes; URL string for non-Text types
}

type MessageContentLoadResult = {
kind: "inline" | "url";
bytes: Uint8Array;
text?: string;
contentType?: string;
url?: string;
messageContentKind: "text" | "url" | "irys" | "ipfs" | "arweave";
};
enum MessageSenderSide {
From = 0, // the wallet that opened the thread
To = 1, // the wallet that received it
}

Message sequence numbers​

Messages are numbered starting from 1. The thread tracks lastMsgSeq (the highest sent) and totalMsgs. For pagination, walk backward from lastMsgSeq in batches until you reach seq 1.