Skip to content

Release 4.6.2#625

Merged
neekolas merged 7 commits intomainfrom
release/v1.6.2
Dec 2, 2025
Merged

Release 4.6.2#625
neekolas merged 7 commits intomainfrom
release/v1.6.2

Conversation

@neekolas
Copy link
Contributor

@neekolas neekolas commented Nov 26, 2025

Update to libxmtp 4.6.2-rc1

@claude
Copy link

claude bot commented Nov 26, 2025

Claude finished @neekolas's task —— View job


Code Review Complete

I've completed a thorough review of this PR. Below are my findings organized by category.


Positive Aspects

  1. Well-structured libXMTP upgrade: The update to libxmtp 4.6.2-rc1 appears systematic with proper FFI bindings regeneration
  2. Good test coverage: New features like appData(), message sorting, and insertion-time filters have corresponding tests
  3. Backward compatibility: The ReactionCodec maintains legacy decoding support
  4. Type safety: New enums like MessageSortBy provide type-safe APIs

🐛 Bugs and Issues

1. Data Loss in ReactionCodec Legacy Decode (High Priority)

Location: Sources/XMTPiOS/Codecs/ReactionCodec.swift:99

The legacy decode path hardcodes referenceInboxId: "" instead of reading it from parameters, potentially losing data. This was flagged by macroscopeapp's review.

// Current (line 94-100):
return Reaction(
    reference: content.parameters["reference"] ?? "",
    action: ReactionAction(rawValue: content.parameters["action"] ?? ""),
    content: String(data: content.content, encoding: .utf8) ?? "",
    schema: ReactionSchema(rawValue: content.parameters["schema"] ?? ""),
    referenceInboxId: ""  // ❌ Hardcoded empty string
)

Recommendation: Read from parameters to prevent data loss:

referenceInboxId: content.parameters["referenceInboxId"] ?? ""

2. Nil Handling in revokeAllOtherInstallations (Medium Priority)

Location: Sources/XMTPiOS/Client.swift:758-761

The implementation silently returns when FFI returns nil, which could mask issues:

public func revokeAllOtherInstallations(signingKey: SigningKey) async throws {
    guard let signatureRequest = try await ffiRevokeAllOtherInstallations() else {
        // No other installations to revoke – nothing to do.
        return  // ⚠️ Silent no-op
    }
    // ...
}

Recommendation: Consider logging this case or documenting more explicitly that this is expected behavior when there are no other installations.


Performance Considerations

  1. Message Filtering Options: The new insertedAfterNs/insertedBeforeNs parameters in FfiListMessagesOptions look well-designed for efficient database queries
  2. Sort Options: The MessageSortBy enum allows clients to optimize queries based on their use case (sent time vs insertion time)

🔒 Security Concerns

No significant security issues identified. The changes maintain existing security patterns:

  • Database encryption continues to be required
  • Signing key flows remain unchanged
  • No new credential exposure vectors

📋 Code Quality

Strengths:

  • Consistent Swift naming conventions
  • Proper use of Swift actors for thread safety (ApiClientCache)
  • Good separation of concerns between FFI layer and Swift API

Areas for Improvement:

  1. Missing Documentation: New public APIs lack doc comments:

    • appData() and updateAppData() in Group.swift:205-227
    • MessageSortBy enum in DecodedMessage.swift:61-82
    • insertedAt and insertedAtNs properties in DecodedMessage.swift:116-125
  2. Optional Handling: Several force-unwraps in FFI code could be safer with explicit error handling, though this may be acceptable for autogenerated code

  3. Code Duplication: The messages(), messagesWithReactions(), and enrichedMessages() methods in Group.swift (lines 510-736) have significant duplication in options building logic. Consider extracting to a shared helper.


🧪 Test Coverage

Well-Tested:

  • ✅ Reaction codec V1/V2 compatibility (ReactionTests.swift)
  • ✅ Mixed reaction types handling
  • ✅ Legacy form decoding
  • ✅ Basic group operations

Missing/Unclear:

  • ❓ No visible tests for insertedAfterNs/insertedBeforeNs filtering
  • ❓ No tests for MessageSortBy.insertedAt vs MessageSortBy.sentAt
  • ❓ Limited tests for appData() / updateAppData() functionality
  • ❓ Archive with excludeDisappearingMessages option not tested

Recommendation: Add integration tests for the new filtering and sorting capabilities to ensure they work correctly with the FFI layer.


📦 Architecture and Design

  1. Good: The enum-based approach for Conversation (Group vs DM) maintains clean API surface
  2. Good: FFI abstraction keeps Rust implementation details isolated
  3. Concern: Growing parameter lists in messages() methods (10+ parameters) suggest need for options builder pattern

Recommendation: Consider introducing a MessageQueryOptions struct to reduce parameter count:

struct MessageQueryOptions {
    var beforeNs: Int64?
    var afterNs: Int64?
    var limit: Int?
    var direction: SortDirection?
    var deliveryStatus: MessageDeliveryStatus
    var excludeContentTypes: [StandardContentType]?
    var excludeSenderInboxIds: [String]?
    var sortBy: MessageSortBy?
    var insertedAfterNs: Int64?
    var insertedBeforeNs: Int64?
}

🎯 Summary and Recommendations

Priority Issues to Address:

  1. Fix the data loss bug in ReactionCodec.swift:99 (referenceInboxId)
  2. Add documentation for new public APIs
  3. Add tests for insertion-time filtering and sorting features

Nice-to-Haves:

  • Refactor duplicated options-building code in message query methods
  • Consider options builder pattern for message queries
  • Add explicit logging for nil signature request case

Overall Assessment: This is a solid release that adds valuable features (message sorting, insertion-time filters, appData) while maintaining backward compatibility. The main issue is the data loss bug in the legacy reaction decoder which should be fixed before merging.


Copy link
Contributor Author

neekolas commented Nov 26, 2025

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

@neekolas neekolas changed the title Update to libxmtp 4.7.0-dev.f5bec47 4.6.2-rc1 Nov 26, 2025
@macroscopeapp
Copy link

macroscopeapp bot commented Nov 26, 2025

Release 4.6.2 and add message insertion-time sorting/filters, group appData APIs, optional revoke flow, and auth callback/handle in connectToBackend across iOS and FFI layers

This release introduces insertion-time (insertedAtNs) fields and sort options end-to-end, adds group appData()/updateAppData(appData:), wires optional revoke with Client.ffiRevokeAllOtherInstallations() -> SignatureRequest?, and extends connectToBackend(clientMode:appVersion:authCallback:authHandle:) with auth callback/handle and client mode. It also adds intent/actions content variants, a excludeDisappearingMessages archive flag, and updates Reaction V2 to use Reaction with referenceInboxId. Binary targets and podspec versions are updated.

📍Where to Start

Start with the FFI surface changes in connectToBackend(clientMode:appVersion:authCallback:authHandle:) and new sort/filter types in Sources/XMTPiOS/Libxmtp/xmtpv3.swift, then follow their usage in Sources/XMTPiOS/Client.swift, Sources/XMTPiOS/Conversation.swift, Sources/XMTPiOS/Group.swift, and Sources/XMTPiOS/Dm.swift.


Macroscope summarized f97b28f.

Co-authored-by: GitHub Actions Bot <actions@github.com>
@neekolas neekolas mentioned this pull request Nov 26, 2025
@neekolas neekolas force-pushed the release/v1.6.2 branch 6 times, most recently from aa524d5 to 42efd64 Compare November 26, 2025 23:58
@neekolas neekolas marked this pull request as ready for review November 27, 2025 00:41
@neekolas neekolas requested a review from a team as a code owner November 27, 2025 00:41
@neekolas neekolas changed the title 4.6.2-rc1 Release 4.6.2 Nov 27, 2025
@neekolas neekolas merged commit 896e637 into main Dec 2, 2025
8 of 9 checks passed
@neekolas neekolas deleted the release/v1.6.2 branch December 2, 2025 23: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.

3 participants