Skip to content

Conversation

@neekolas
Copy link
Contributor

@neekolas neekolas commented Nov 19, 2025

TL;DR

Update XMTP SDK to support message sorting by insertion time and message counting functionality.

What changed?

  • Updated XMTP native dependencies:
    • Android: org.xmtp:android:4.6.1-rc14.7.0-dev.252eebc
    • iOS: XMTP: 4.6.1-rc34.7.0-dev.ff66c0f
  • Added support for sorting messages by insertion time with new parameters:
    • insertedAfterNs
    • insertedBeforeNs
    • sortBy (with options SENT or INSERTED)
  • Added insertedAtNs field to message objects
  • Implemented new countMessages function to get message counts without fetching full messages
  • Updated message query interfaces across Android and iOS implementations

How to test?

  1. Test the new message sorting functionality:
// Sort by insertion time
const messages = await conversation.messages({
  sortBy: "INSERTED",
  insertedAfterNs: timestamp1,
  insertedBeforeNs: timestamp2
});
  1. Test the new message counting functionality:
// Count messages in a conversation
const count = await conversation.countMessages(
  beforeNs, // optional
  afterNs, // optional
  insertedAfterNs, // optional
  insertedBeforeNs // optional
);
  1. Verify that the insertedAtNs field is available on message objects:
const message = await conversation.messages({ limit: 1 });
console.log(message[0].insertedAtNs);

Why make this change?

This change provides developers with more flexibility in how they query and display messages:

  1. Sorting by insertion time allows for more accurate chronological display of messages as they were received by the client, rather than when they were sent.

  2. The message counting functionality enables pagination and UI features that need to know the total count without fetching all messages, improving performance for conversations with many messages.

  3. The insertedAtNs timestamp provides additional metadata that can be useful for tracking when messages were actually received by the client versus when they were sent.

@changeset-bot
Copy link

changeset-bot bot commented Nov 19, 2025

⚠️ No Changeset found

Latest commit: 1253152

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@macroscopeapp
Copy link

macroscopeapp bot commented Nov 19, 2025

Add insertedAtNs to encoded messages and extend XMTPModule.conversationMessages/conversationMessagesWithReactions and JS APIs to accept insertedAfterNs, insertedBeforeNs, and sortBy for insertion-time filtering and sorting

Upgrade native XMTP dependencies and add insertion-time fields and sorting across Android, iOS, and JS bridges, including a new countMessages API and DecodedMessage.insertedAtNs.

📍Where to Start

Start with the query param handling in src/index.ts, then follow native bridges in android/src/main/java/expo/modules/xmtpreactnativesdk/XMTPModule.kt and ios/XMTPModule.swift.


📊 Macroscope summarized 1253152. 11 files reviewed, 52 issues evaluated, 51 issues filtered, 0 comments posted. View details

@neekolas neekolas force-pushed the 11-19-add_insertedat_field_and_sortby_options branch from b7ab021 to a49d162 Compare November 19, 2025 22:45
decoded.contentTypeId,
decoded.senderInboxId,
decoded.sentNs,
decoded.insertedAtNs,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from doesn’t default insertedAtNs. If it’s missing in JSON, this.insertedAtNs becomes undefined, unlike fromObject. Consider defaulting to decoded.sentNs here to keep it a number.

Suggested change
decoded.insertedAtNs,
decoded.insertedAtNs ?? decoded.sentNs,

🚀 Reply to ask Macroscope to explain or update this suggestion.

👍 Helpful? React to give us feedback.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue on line in ios/XMTPModule.swift:388:

Casting chainId to UInt64 can trap for negatives. Suggest validating chainId >= 0 everywhere before casting and failing early with a clear error if invalid.

🚀 Reply to ask Macroscope to explain or update this suggestion.

👍 Helpful? React to give us feedback.

try? encodeToObj(childMessage)
}
]
"childMessages": model.childMessages?.map { childMessage in
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"childMessages" may be an Optional and may contain nil entries due to try?, which breaks JSON encoding. Consider using compactMap to drop nils and defaulting to a concrete array (or omit the key / use NSNull() if no children). You might also consider propagating child encode errors instead of silently dropping them.

-            "childMessages": model.childMessages?.map { childMessage in
-                try? encodeToObj(childMessage)
-            },
+            "childMessages": model.childMessages?.compactMap { try? encodeToObj($0) } ?? [],

🚀 Reply to ask Macroscope to explain or update this suggestion.

👍 Helpful? React to give us feedback.

@neekolas neekolas force-pushed the 11-19-add_insertedat_field_and_sortby_options branch from a49d162 to d7c5aeb Compare November 19, 2025 22:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant