Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Bump Xmtp #1323

Merged
merged 2 commits into from
Dec 9, 2024
Merged

chore: Bump Xmtp #1323

merged 2 commits into from
Dec 9, 2024

Conversation

alexrisch
Copy link
Contributor

@alexrisch alexrisch commented Dec 6, 2024

Bumped XMTP
Fixed types
Removed web3 usage in Swift

Summary by CodeRabbit

  • New Features

    • Enhanced group joining functionality with improved logging and handling of join requests.
    • Simplified message handling across various components, improving type definitions for better clarity and safety.
  • Bug Fixes

    • Streamlined error handling and response processing in profile and spam score calculations.
    • Improved conditions for displaying message previews in pinned conversation components to prevent potential errors.
  • Documentation

    • Updated comments and descriptions to clarify changes and functionality in various modules.
  • Chores

    • Updated dependency versions in package.json and Podfile for improved performance and stability.

@alexrisch alexrisch requested a review from a team as a code owner December 6, 2024 19:34
Copy link
Contributor

coderabbitai bot commented Dec 6, 2024

Walkthrough

The pull request introduces significant type declaration modifications across various components within the chat application. Specifically, the type of the message property in several interfaces has been changed from tuple types to direct type references. This includes updates in ChatGroupUpdatedMessage, MessageRemoteAttachment, MessageReply, MessageSimpleText, and others. Additionally, the JoinGroupClient class has been enhanced to allow more flexible group joining processes, and several utility functions have been updated for improved type safety and error handling.

Changes

File Path Change Summary
components/Chat/ChatGroupUpdatedMessage.tsx Updated message type in IChatGroupUpdatedMessageProps from DecodedMessage<[GroupUpdatedCodec]> to DecodedMessage<GroupUpdatedCodec>.
components/Chat/Message/message-content-types/message-remote-attachment.tsx Updated message type in IMessageRemoteAttachmentProps from DecodedMessage<[RemoteAttachmentCodec]> to DecodedMessage<RemoteAttachmentCodec>.
components/Chat/Message/message-content-types/message-reply.tsx Updated message and replyMessage types in MessageReply and MessageReplyReferenceContent from DecodedMessage<[ReplyCodec]> to DecodedMessage<ReplyCodec>.
components/Chat/Message/message-content-types/message-simple-text.tsx Updated message type in MessageSimpleText from DecodedMessage<[TextCodec]> to DecodedMessage<TextCodec>.
components/Chat/Message/message-content-types/message-static-attachment.tsx Updated message type in IMessageStaticAttachmentProps from DecodedMessage<[StaticAttachmentCodec]> to DecodedMessage<StaticAttachmentCodec>.
components/Chat/Message/message-utils.tsx Updated various message type-checking function signatures to use DecodedMessageWithCodecsType instead of any.
features/GroupInvites/joinGroup/JoinGroup.client.ts Enhanced liveAttemptToJoinGroup method with an optional groupIdFromInvite parameter and improved logging. Updated liveAllowGroup and liveFetchGroupsByAccount methods for dynamic imports.
features/conversation-list/hooks/useMessageText.ts Updated type assertion for messageTyped from DecodedMessage<[ReplyCodec]> to DecodedMessage<ReplyCodec>.
features/conversation/composer/composer.tsx Updated type assertions for replyMessage in ReplyPreviewEndContent and ReplyPreviewMessageContent components.
ios/Converse.xcodeproj/project.pbxproj Added new resource bundles and updated build phases for proper resource management.
ios/ConverseNotificationExtension/Profile.swift Simplified address handling in getProfile function and streamlined error handling in refreshProfileFromBackend.
ios/ConverseNotificationExtension/Spam.swift Updated spam score calculation methods to use client.preferences instead of consentList.
ios/ConverseNotificationExtension/Xmtp/Messages.swift Simplified consent state determination in handleV3Welcome function.
ios/Podfile Updated XMTP pod version from 3.0.6 to 3.0.14 and enforced Swift version and iOS deployment target.
package.json Updated @xmtp/react-native-sdk dependency version from ^3.0.6 to ^3.1.1.
queries/useV3ConversationListQuery.ts Updated conversationListKey method to accept an optional account parameter.
utils/logout/index.tsx Enhanced type safety in executeLogoutTasks and updated logoutAccount for better error handling.
utils/xmtpRN/client.ts Replaced DecodedMessage with DecodedMessageUnion and updated type definitions for message handling.
utils/xmtpRN/contacts.ts Renamed permissionType to state in consent management functions.
utils/xmtpRN/sync.ts Updated asynchronous handling and error management in streaming functions.
components/PinnedConversations/PinnedV3DMConversation.tsx Updated displayMessagePreview condition to check for conversation.lastMessage existence.
components/PinnedConversations/PinnedV3GroupConversation.tsx Updated displayMessagePreview condition to check for group.lastMessage existence.

Possibly related PRs

Suggested labels

2.0.7

Suggested reviewers

  • technoplato

🐰 In the meadow, changes bloom,
Types refined, dispelling gloom.
Messages clear, no more a mess,
In our chat, we now progress!
With each update, we hop and cheer,
For better code, we hold so dear! 🌼


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Outside diff range and nitpick comments (14)
ios/Converse.xcodeproj/project.pbxproj (1)

Line range hint 453-476: Security review recommended for crypto dependencies.

The project now includes several cryptography-related dependencies. While the configuration is correct, it's important to ensure these dependencies are properly vetted.

Consider:

  1. Documenting the security implications of each crypto dependency
  2. Setting up a process for regular security updates of these dependencies
  3. Implementing runtime integrity checks for the crypto modules

Also applies to: 498-502

ios/ConverseNotificationExtension/Profile.swift (2)

Line range hint 19-24: Improve error handling in profile refresh flow

The current implementation silently ignores errors from refreshProfileFromBackend. Consider adding proper error handling to track profile refresh failures.

-  try? await refreshProfileFromBackend(account: account, address: formattedAddress)
+  do {
+    try await refreshProfileFromBackend(account: account, address: formattedAddress)
+  } catch {
+    print("Failed to refresh profile for \(formattedAddress): \(error)")
+    // Consider implementing retry logic or error reporting
+  }

Line range hint 28-50: Enhance API interaction robustness

The current implementation has several areas for improvement:

  1. URL construction could fail silently
  2. Error types are not specific
  3. Response handling could be more structured

Consider these improvements:

+enum ProfileError: Error {
+    case invalidURL
+    case networkError(Error)
+    case decodingError(Error)
+}

 func refreshProfileFromBackend(account: String, address: String) async throws  {
   let apiURI = getApiURI()
-  if (apiURI != nil && !apiURI!.isEmpty) {
+  guard let apiURI = apiURI, !apiURI.isEmpty,
+        let url = URL(string: "\(apiURI)/api/profile") else {
+    throw ProfileError.invalidURL
+  }
 
-    let profileURI = "\(apiURI ?? "")/api/profile"
-    
     let response = try await withUnsafeThrowingContinuation { continuation in
-      AF.request(profileURI, method: .get, parameters: ["address": address]).validate().responseData { response in
+      AF.request(url, method: .get, parameters: ["address": address])
+        .validate()
+        .responseDecodable(of: ProfileSocials.self) { response in
         if let data = response.data {
           continuation.resume(returning: data)
           return
         }
         if let err = response.error {
-          continuation.resume(throwing: err)
+          continuation.resume(throwing: ProfileError.networkError(err))
           return
         }
       }
     }
-    
-    // Create an instance of JSONDecoder
-    let decoder = JSONDecoder()
-    
-    if let socials = try? decoder.decode(ProfileSocials.self, from: response) {
-      saveProfileSocials(account: account, address: address, socials: socials)
-    }
+    saveProfileSocials(account: account, address: address, socials: response)
utils/xmtpRN/sync.ts (2)

Line range hint 120-133: Consider extracting retry configuration and enhancing type safety.

The error handling and retry mechanism are well implemented. However, consider these improvements:

  1. Extract retry configuration to constants/config for easier maintenance
  2. Add type safety to the error handling
+const RETRY_CONFIG = {
+  retries: 5,
+  delay: 1000,
+  factor: 2,
+  maxDelay: 30000,
+} as const;

 await retryWithBackoff({
   fn: () => streamConversations(account),
-  retries: 5,
-  delay: 1000,
-  factor: 2,
-  maxDelay: 30000,
+  ...RETRY_CONFIG,
   context: `streaming conversations for ${account}`,
-}).catch((e) => {
+}).catch((e: Error) => {
   logger.error(e, {
     context: `Failed to stream conversations for ${account} no longer retrying`,
   });
 });

Line range hint 134-146: Consolidate duplicate retry and error handling patterns.

The message streaming code duplicates the retry configuration and error handling pattern from the conversation streaming code. Consider extracting this common pattern into a reusable function.

+const streamWithRetry = async (
+  streamFn: () => Promise<void>,
+  account: string,
+  operationType: string
+) => {
+  return retryWithBackoff({
+    fn: () => streamFn(),
+    ...RETRY_CONFIG,
+    context: `streaming ${operationType} for ${account}`,
+  }).catch((e: Error) => {
+    logger.error(e, {
+      context: `Failed to stream ${operationType} for ${account} no longer retrying`,
+    });
+  });
+};

-await retryWithBackoff({
-  fn: () => streamAllMessages(account),
-  retries: 5,
-  delay: 1000,
-  factor: 2,
-  maxDelay: 30000,
-  context: `streaming all messages for ${account}`,
-}).catch((e) => {
-  logger.error(e, {
-    context: `Failed to stream all messages for ${account} no longer retrying`,
-  });
-});
+await streamWithRetry(
+  () => streamAllMessages(account),
+  account,
+  'all messages'
+);

This refactoring would also apply to the conversation streaming code above.

components/Chat/Message/message-content-types/message-remote-attachment.tsx (1)

Line range hint 15-17: Address TODO comment or document the rationale.

There's an unhandled string content case that returns null. This should either be implemented or documented why it's intentionally skipped.

Would you like me to help implement the string content handling or create an issue to track this?

features/conversation-list/hooks/useMessageText.ts (2)

Line range hint 18-42: Consider refactoring message type handling.

The current implementation has multiple type checks and content handling paths. Consider refactoring to use a more maintainable pattern, such as a message type registry or strategy pattern.

Example approach:

type MessageHandler = (message: DecodedMessage<any>) => string;

const messageHandlers: Record<string, MessageHandler> = {
  reply: (message: DecodedMessage<ReplyCodec>) => {
    const content = message.content();
    return typeof content === "string" ? content : content.content.text;
  },
  staticAttachment: () => "Attachment",
  groupUpdated: () => "conversation updated",
  default: (message) => {
    const content = message.content();
    return typeof content === "string" ? content : message.fallback;
  }
};

// In the hook:
const handler = messageHandlers[getMessageContentType(message.contentTypeId)] || messageHandlers.default;
return handler(message);

Line range hint 41-46: Consider adding error type information to logger.

The error logging could be enhanced with type information to better track type-related issues during the XMTP library update.

- logger.error("Error getting message text", {
-   error: e,
-   contentTypeId: message.contentTypeId,
- });
+ logger.error("Error getting message text", {
+   error: e,
+   errorType: e instanceof Error ? e.constructor.name : typeof e,
+   contentTypeId: message.contentTypeId,
+   messageType: getMessageContentType(message.contentTypeId),
+ });
features/conversation/composer/composer.tsx (1)

379-380: Consider using type predicate for better type safety

While the type assertion is correct, consider using a type predicate to improve type safety:

-const messageTyped =
-  replyMessage as DecodedMessage<RemoteAttachmentCodec>;
+const messageTyped = replyMessage as DecodedMessage<RemoteAttachmentCodec>;
+if (!messageTyped.content()) return null;
ios/ConverseNotificationExtension/Spam.swift (3)

Line range hint 15-19: Avoid using fatalError to prevent application crashes

Using fatalError("should not get here") will crash the application if neither data nor error is received from the network request. It's recommended to handle this case gracefully to prevent unexpected crashes in production.

Apply this diff to handle the unexpected case without crashing:

          if let data = response.data {
            continuation.resume(returning: data)
            return
          }
          if let err = response.error {
            continuation.resume(throwing: err)
            return
          }
-         fatalError("should not get here")
+         let unknownError = NSError(
+           domain: "com.yourdomain.app",
+           code: -1,
+           userInfo: [NSLocalizedDescriptionKey: "Unknown error occurred"]
+         )
+         continuation.resume(throwing: unknownError)

Line range hint 153-199: senderSpamScore is not computed and remains zero

In computeSpamScoreV3Message, the variable senderSpamScore is initialized but never modified within the function, so it always remains zero. This means the sender's spam score isn't contributing to the total spam score as intended. Consider fetching the sender's spam score to include it in the calculation.

Apply this diff to fetch and include the sender's spam score:

     var senderSpamScore: Double = 0
     do {
       
         try await client.preferences.syncConsent()
         let groupDenied = try await client.preferences.conversationState(conversationId: conversation.id) == .denied
         if groupDenied {
           // Network consent will override other checks
           return 1
         }
         let senderInboxId = decodedMessage.senderAddress
         let senderDenied = try await client.preferences.inboxIdState(inboxId: senderInboxId) == .denied
         if senderDenied {
           // Network consent will override other checks
           return 1
         }
         
         let senderAllowed = try await client.preferences.inboxIdState(inboxId: senderInboxId) == .allowed
         if senderAllowed {
           // Network consent will override other checks
           return -1
         }
         
         let convoAllowed = try await client.preferences.conversationState(conversationId: conversation.id) == .allowed
         if convoAllowed {
           // Network consent will override other checks
           return -1
         }
         
         if case .group(let group) = conversation {

             if let senderAddresses = try await group.members.first(where: {$0.inboxId == senderInboxId})?.addresses {
               for address in senderAddresses {
                 if try await client.preferences.addressState(address:address) == .denied {
                   return 1
                 }
               }
               for address in senderAddresses {
                 if try await client.preferences.addressState(address: address) == .allowed {
                   return -1
                 }
               }
             }
         } else if case .dm(let dm) = conversation {
           let peer = try dm.peerInboxId
           
           if try await client.preferences.inboxIdState(inboxId: peer) == .allowed {
             return -1
           }
           if try await client.preferences.inboxIdState(inboxId: peer) == .denied {
             return 1
           }
         }
       } catch {
         //
       }
+      let senderAddress = decodedMessage.senderAddress
+      senderSpamScore = await getSenderSpamScore(address: senderAddress, apiURI: apiURI)
       let contentType = getContentTypeString(type: decodedMessage.encodedContent.type)
       
       let messageContent = String(data: decodedMessage.encodedContent.content, encoding: .utf8)
       let messageSpamScore = getMessageSpamScore(message: messageContent, contentType: contentType)
       
       return senderSpamScore + messageSpamScore

Line range hint 22-199: Refactor repeated consent state checks into helper functions

There are multiple instances where consent states are checked using client.preferences. This repetition can be reduced by refactoring the consent state checks into reusable helper functions, improving code maintainability and readability.

Example refactoring:

// Define helper functions
func isConversationAllowed(client: XMTP.Client, conversationId: String) async throws -> Bool {
  return try await client.preferences.conversationState(conversationId: conversationId) == .allowed
}

func isConversationDenied(client: XMTP.Client, conversationId: String) async throws -> Bool {
  return try await client.preferences.conversationState(conversationId: conversationId) == .denied
}

// Apply in your code
let convoAllowed = try await isConversationAllowed(client: client, conversationId: conversation.id)
let convoDenied = try await isConversationDenied(client: client, conversationId: conversation.id)
ios/ConverseNotificationExtension/Xmtp/Messages.swift (2)

22-23: Optimize by reducing duplicate calls to conversationState

The code calls xmtpClient.preferences.conversationState(conversationId:) twice. To improve efficiency, consider calling it once and storing the result.

Apply this diff:

         // Consent list is loaded in computeSpamScoreGroupWelcome
-        let convoAllowed = try await xmtpClient.preferences.conversationState(conversationId: conversation.id) == .allowed
-        let convoDenied = try await xmtpClient.preferences.conversationState(conversationId: conversation.id) == .denied
+        let convoState = try await xmtpClient.preferences.conversationState(conversationId: conversation.id)
+        let convoAllowed = convoState == .allowed
+        let convoDenied = convoState == .denied

Line range hint 49-58: Ensure proper synchronization before message handling

When handling decoded messages, ensure that the conversation is properly synchronized before processing to avoid missing any messages.

Consider adding a synchronization step if not already present.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between ac1eeaa and 2bfd56b.

⛔ Files ignored due to path filters (2)
  • ios/Podfile.lock is excluded by !**/*.lock
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (20)
  • components/Chat/ChatGroupUpdatedMessage.tsx (1 hunks)
  • components/Chat/Message/message-content-types/message-remote-attachment.tsx (1 hunks)
  • components/Chat/Message/message-content-types/message-reply.tsx (5 hunks)
  • components/Chat/Message/message-content-types/message-simple-text.tsx (1 hunks)
  • components/Chat/Message/message-content-types/message-static-attachment.tsx (1 hunks)
  • components/Chat/Message/message-utils.tsx (2 hunks)
  • features/GroupInvites/joinGroup/JoinGroup.client.ts (0 hunks)
  • features/conversation-list/hooks/useMessageText.ts (1 hunks)
  • features/conversation/composer/composer.tsx (4 hunks)
  • ios/Converse.xcodeproj/project.pbxproj (4 hunks)
  • ios/ConverseNotificationExtension/Profile.swift (1 hunks)
  • ios/ConverseNotificationExtension/Spam.swift (5 hunks)
  • ios/ConverseNotificationExtension/Xmtp/Messages.swift (1 hunks)
  • ios/Podfile (2 hunks)
  • package.json (1 hunks)
  • queries/useV3ConversationListQuery.ts (1 hunks)
  • utils/logout/index.tsx (2 hunks)
  • utils/xmtpRN/client.ts (4 hunks)
  • utils/xmtpRN/contacts.ts (3 hunks)
  • utils/xmtpRN/sync.ts (2 hunks)
💤 Files with no reviewable changes (1)
  • features/GroupInvites/joinGroup/JoinGroup.client.ts
🔇 Additional comments (21)
ios/Converse.xcodeproj/project.pbxproj (1)

Line range hint 426-449: New resource bundles added for enhanced functionality.

The addition of crypto and security-related resource bundles (CryptoSwift, SQLCipher, SwiftProtobuf) aligns with the XMTP library update.

Let's verify the XMTP version and its dependencies:

Also applies to: 490-494

✅ Verification successful

Resource bundles are correctly configured for XMTP integration

The addition of crypto-related resource bundles (CryptoSwift, SQLCipher, SwiftProtobuf) in the project configuration is consistent with the XMTP SDK requirements, as evidenced by the extensive XMTP usage throughout the codebase, particularly in the notification extension service. The bundles are properly configured to support:

  • XMTP message handling and encryption
  • Secure storage with SQLCipher
  • Protocol buffer serialization with SwiftProtobuf
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check XMTP version and related dependencies in Podfile.lock

# Search for XMTP and related crypto dependencies versions
rg -A 3 "XMTP|CryptoSwift|SQLCipher|SwiftProtobuf" Podfile.lock

Length of output: 118


Script:

#!/bin/bash
# Let's try to find the Podfile and any XMTP related configurations
fd -t f "Podfile|podfile"

# Also search for XMTP related imports or configurations in source files
rg -i "xmtp|cryptoswift|sqlcipher|swiftprotobuf" --type swift --type objc

Length of output: 10965

utils/xmtpRN/sync.ts (1)

Line range hint 120-146: Verify compatibility with updated XMTP library version.

Since this PR includes an XMTP library update, please verify that:

  1. The streaming behavior remains consistent with the new version
  2. Error types and handling align with any changes in the library
  3. The retry mechanism is still appropriate for any new failure modes
✅ Verification successful

Based on the search results, I can now generate the final response:

The streaming implementation is compatible with XMTP v11.5.0

The code correctly uses the XMTP client's streaming APIs:

  • streamAllMessages and stream methods are properly implemented with error handling and retries
  • The streaming behavior aligns with the XMTP v11.5.0 client interface
  • Error handling through retryWithBackoff is appropriate for network-related failures
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for XMTP version changes and related streaming API usage
rg -A 3 "@xmtp/xmtp-js" package.json
rg -A 5 "streamConversations|streamAllMessages" --type typescript

Length of output: 266


Script:

#!/bin/bash
# Let's try searching without file type restriction and check implementation details
rg -A 5 'streamConversations|streamAllMessages'

# Also check for any XMTP client initialization and stream usage patterns
rg -A 5 'new Client|\.stream'

# Look for any XMTP-related type definitions or interfaces
ast-grep --pattern 'interface $_ {
  $$$
  stream$_($$$) {
    $$$
  }
  $$$
}'

Length of output: 4417


Script:

#!/bin/bash
# Let's check the XMTP client type and its usage
rg -A 5 "ConverseXmtpClientType"

# Check for any XMTP-related imports and their versions
rg "@xmtp/.*" --type typescript

# Look for any changes in error handling patterns
ast-grep --pattern 'catch($_) {
  $$$
}'

Length of output: 32413

components/Chat/Message/message-content-types/message-remote-attachment.tsx (1)

7-7: LGTM! Type simplification looks good.

The change from tuple type to direct type reference aligns with the broader type improvements across the codebase.

components/Chat/Message/message-content-types/message-simple-text.tsx (1)

13-13: LGTM! Type simplification is consistent.

The type change from DecodedMessage<[TextCodec]> to DecodedMessage<TextCodec> aligns with the broader type improvements and maintains consistency across components.

features/conversation-list/hooks/useMessageText.ts (1)

19-19: LGTM! Type assertion simplified correctly.

The type assertion change from DecodedMessage<[ReplyCodec]> to DecodedMessage<ReplyCodec> aligns with the broader type improvements.

components/Chat/Message/message-content-types/message-static-attachment.tsx (1)

21-21: Type signature update looks good!

The change from DecodedMessage<[StaticAttachmentCodec]> to DecodedMessage<StaticAttachmentCodec> aligns with the broader type refinement effort and correctly represents that this message type uses a single codec rather than a tuple of codecs.

Let's verify consistent type usage across the codebase:

✅ Verification successful

Type signature update is consistent across the codebase

The verification confirms that there are no remaining instances of tuple-style [StaticAttachmentCodec] in the codebase. All usages of StaticAttachmentCodec follow the correct non-tuple type pattern, including in related files like the composer, client, and message utilities.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining tuple-style codec types that might need updating
rg -l '\[StaticAttachmentCodec\]' --type typescript

Length of output: 88


Script:

#!/bin/bash
# Search for any remaining tuple-style codec types that might need updating
# Using ripgrep without file type filter and checking for StaticAttachmentCodec usage
rg '\[StaticAttachmentCodec\]'

# Also search for general StaticAttachmentCodec usage for context
rg 'StaticAttachmentCodec'

Length of output: 873

components/Chat/Message/message-utils.tsx (2)

8-11: Import changes enhance type safety

Good addition of specific type imports that support the broader type refinement effort.


32-76: Type predicate functions properly typed

The update to use DecodedMessageWithCodecsType instead of any improves type safety across all message type checks. The special handling of ReplyCodec and TransactionReferenceCodec with SupportedCodecsType correctly accounts for nested message content.

Let's verify that all message type checks are consistently updated:

✅ Verification successful

Type predicate functions consistently use DecodedMessageWithCodecsType

The verification confirms that:

  • No instances of message: any remain in the codebase
  • DecodedMessageWithCodecsType is consistently used across all message-related functions
  • The type is properly used in message utilities, hooks, and data handling components
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for any remaining 'any' types in message type checks
rg "message:\s*any" --type typescript

# Verify consistent usage of DecodedMessageWithCodecsType
rg "message:\s*DecodedMessageWithCodecsType" --type typescript

Length of output: 174


Script:

#!/bin/bash
# Check for any remaining 'any' types in message type checks
rg "message:\s*any"

# Verify consistent usage of DecodedMessageWithCodecsType
rg "message:\s*DecodedMessageWithCodecsType"

# Look for other message type predicates that might need updating
ast-grep --pattern 'function is$_Message(message: $_) {
  $$$
}'

Length of output: 1628

utils/xmtpRN/client.ts (3)

44-54: Type definition improvement: More precise codec type definition

The explicit tuple type definition for SupportedCodecsType provides better type safety and clearer documentation of supported codecs compared to the previous inferred type.


76-78: Type enhancement: More accurate async type definition

The new type definition using Awaited<ReturnType> better represents the asynchronous nature of the messages method and ensures type safety when working with decoded messages.


166-167: Verify the impact of parameter type change

The change from inboxId to installationId suggests a significant change in how clients are identified and managed.

✅ Verification successful

Parameter type change from inboxId to installationId is a safe refactor

The verification shows that the change is consistent with the codebase's usage:

  • The only caller of dropXmtpClient in utils/logout/index.tsx already uses getInboxId() and casts it to InstallationId
  • The codebase shows a clear separation between inboxId usage (for user identification in conversations/contacts) and installation management
  • No breaking changes are introduced as the type conversion is handled at the call site
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for any remaining uses of inboxId with dropXmtpClient
rg "dropXmtpClient.*inboxId" -A 2

# Check for any documentation or migration guides
fd -t f "MIGRATION|UPGRADE|README" -x cat {} \; | rg -i "xmtp.*installation"

Length of output: 117


Script:

#!/bin/bash
# Let's check for all usages of dropXmtpClient to understand the change impact
rg "dropXmtpClient" -A 2

# Check the Client class implementation to understand the parameter type history
ast-grep --pattern 'class Client {
  $$$
  dropClient($_) {
    $$$
  }
  $$$
}'

# Look for any references to inboxId in the same directory
rg "inboxId" utils/xmtpRN/

Length of output: 2207

components/Chat/ChatGroupUpdatedMessage.tsx (1)

23-23: Type simplification: Improved type clarity

The change from DecodedMessage<[GroupUpdatedCodec]> to DecodedMessage<GroupUpdatedCodec> removes unnecessary tuple wrapping, making the type definition more straightforward while maintaining type safety.

utils/xmtpRN/contacts.ts (2)

128-128: Consistent consent state updates across functions

The same property and value changes have been consistently applied across all consent-related functions (inboxIds and groups), maintaining uniformity in the API.

Also applies to: 136-136, 188-188, 196-196


66-66: API alignment: Updated consent state property names

The change from permissionType to state with values allowed/denied aligns with standard permission terminology and appears to be part of the XMTP library update.

Also applies to: 74-74

✅ Verification successful

Property rename from permissionType to state is consistently applied

The verification confirms that:

  • No remaining instances of the old permissionType property exist in the codebase
  • The new state property with values allowed/denied is consistently used across both XMTP contacts and group invite features
  • The change appears to be fully implemented without any mixed usage
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for any remaining uses of old permission types
rg "permissionType.*:.*['\"](?:allow|deny)['\"]" 

# Check for any documentation about the consent state changes
fd -t f "CHANGELOG|README|UPGRADE" -x cat {} \; | rg -i "consent.*state"

Length of output: 132


Script:

#!/bin/bash
# Search for any remaining instances of permissionType in the codebase
rg "permissionType"

# Search for state with allowed/denied values
rg "state['\"]?\s*:\s*['\"](?:allowed|denied)['\"]"

# Look for any XMTP-related configuration or type definitions
fd -t f "xmtp|XMTP" -x cat {} \; | rg -i "state|permission"

Length of output: 977

queries/useV3ConversationListQuery.ts (1)

17-21: 🛠️ Refactor suggestion

Verify the impact of optional account parameter

The use of optional chaining (?.) on the account parameter could lead to undefined keys in the query cache. This might cause issues with cache management and query invalidation.

Consider adding a guard clause:

export const conversationListKey = (account: string) => [
  QueryKeys.V3_CONVERSATION_LIST,
-  account?.toLowerCase(),
+  account ? account.toLowerCase() : undefined,
];
utils/logout/index.tsx (2)

24-24: LGTM: Type import aligns with XMTP SDK update

The import of InstallationId from the XMTP SDK's build path is correct and matches the library's type definitions.


162-162: Verify type assertion safety

The type assertion to InstallationId is necessary for the XMTP SDK update, but we should ensure that getInboxId always returns a valid InstallationId.

✅ Verification successful

Type assertion is safe and well-implemented

The type assertion to InstallationId is safe because:

  1. getInboxId is a wrapper around Client.getOrCreateInboxId which is part of the XMTP SDK
  2. The environment is properly typed and validated as "dev" | "production" | "local"
  3. The function is consistently used across the codebase for XMTP client operations
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check implementation of getInboxId
ast-grep --pattern 'function getInboxId($_) {
  $$$
}'

Length of output: 56


Script:

#!/bin/bash
# Let's try searching for getInboxId with ripgrep to find its implementation
rg "getInboxId" -A 5

Length of output: 3572


Script:

#!/bin/bash
# Let's check the Client.getOrCreateInboxId implementation and env usage
rg "Client\.getOrCreateInboxId" -A 3
rg "env =" -A 3

Length of output: 5106

components/Chat/Message/message-content-types/message-reply.tsx (1)

27-27: LGTM: Type definitions properly aligned with XMTP SDK

The changes to use direct codec types instead of array types (DecodedMessage<ReplyCodec> instead of DecodedMessage<[ReplyCodec]>) align with the XMTP SDK update and improve type safety.

Also applies to: 166-166, 216-216, 232-237, 250-252

✅ Verification successful

Based on the search results, I can now generate the final response as we have sufficient evidence about the type usage across the codebase.

Type changes are correctly aligned with XMTP SDK

The changes from array codec types to direct codec types (e.g., DecodedMessage<ReplyCodec> instead of DecodedMessage<[ReplyCodec]>) are consistent with the XMTP SDK's type system. The search results confirm that:

  • All other message type usages in the codebase follow the same pattern of using direct codec types
  • No instances of array codec types (DecodedMessage<[...Codec]>) were found
  • The type is used consistently across message handling components and utilities
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for any remaining array codec types that need updating
rg -A 2 "DecodedMessage<\[.*Codec\]>"

# Check for consistent usage of the new type
ast-grep --pattern 'DecodedMessage<$_Codec>'

Length of output: 86


Script:

#!/bin/bash
# Search for DecodedMessage type usage in the codebase
rg -A 2 "DecodedMessage"

# Search for specific codec type usage
rg -A 2 "ReplyCodec"

# Find all TypeScript files that might contain message type definitions
fd -e ts -e tsx --exec grep -l "Codec"

Length of output: 30003

package.json (1)

86-86: Verify compatibility with other XMTP dependencies

The update to @xmtp/react-native-sdk@^3.1.1 looks good, but let's verify compatibility with other XMTP-related dependencies.

✅ Verification successful

Let me verify the compatibility between these XMTP packages by checking their peer dependencies and version requirements.


XMTP dependencies are compatible

The verification shows that all XMTP dependencies are compatible:

  • @xmtp/[email protected] only requires peer dependencies for React ecosystem
  • @xmtp/frames-client requires @xmtp/xmtp-js >9.3.1, which is satisfied by the installed version 11.5.0
  • Other XMTP packages don't have any peer dependency requirements
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check compatibility between XMTP dependencies
# Expected: No conflicting peer dependencies

# Get package details from npm
echo "Checking @xmtp/[email protected] peer dependencies..."
curl -s "https://registry.npmjs.org/@xmtp/react-native-sdk/3.1.1" | jq -r '.peerDependencies'

# List all installed XMTP packages and their versions
echo -e "\nInstalled XMTP packages:"
cat package.json | jq -r '.dependencies | with_entries(select(.key | startswith("@xmtp")))'

Length of output: 805


Script:

#!/bin/bash
# Check peer dependencies of other XMTP packages
echo "Checking @xmtp/[email protected] peer dependencies..."
curl -s "https://registry.npmjs.org/@xmtp/xmtp-js/11.5.0" | jq -r '.peerDependencies'

echo -e "\nChecking @xmtp/[email protected] peer dependencies..."
curl -s "https://registry.npmjs.org/@xmtp/frames-client/0.5.4" | jq -r '.peerDependencies'

echo -e "\nChecking content type packages peer dependencies..."
for pkg in [email protected] [email protected] [email protected] [email protected] [email protected]; do
  echo -e "\n@xmtp/$pkg:"
  curl -s "https://registry.npmjs.org/@xmtp/$pkg" | jq -r '.peerDependencies'
done

Length of output: 2450

features/conversation/composer/composer.tsx (2)

353-353: Type assertion simplified correctly

The type assertion has been correctly updated from array type to direct type, aligning with the new XMTP SDK type system.


419-420: Type assertions in ReplyPreviewMessageContent updated correctly

The type assertions for both StaticAttachmentCodec and ReplyCodec have been correctly updated to use direct types instead of array types, consistent with the new SDK's type system.

Also applies to: 457-457

Comment on lines +13 to +14
let formattedAddress = address.lowercased()
if let profile = profileState?.profiles?[address] ?? profileState?.profiles?[formattedAddress] {
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add address format validation

While removing the web3 dependency simplifies the code, we should still validate the Ethereum address format to prevent invalid addresses from being processed.

Consider adding a simple regex validation:

+func isValidEthereumAddress(_ address: String) -> Bool {
+    let pattern = "^0x[0-9a-fA-F]{40}$"
+    return address.range(of: pattern, options: .regularExpression) != nil
+}

 func getProfile(account: String, address: String) async -> Profile? {
   var profileState = getProfilesStore(account: account)?.state
+  guard isValidEthereumAddress(address) else { return nil }
   let formattedAddress = address.lowercased()

Committable suggestion skipped: line range outside the PR's diff.

@@ -18,7 +18,7 @@ install! 'cocoapods',

# Version must match version from XMTP Podspec (matching @xmtp/react-native-sdk from package.json)
# https://github.com/xmtp/xmtp-react-native/blob/v2.6.2/ios/XMTPReactNative.podspec#L29
$xmtpVersion = '3.0.6'
$xmtpVersion = '3.0.14'
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Version mismatch detected between package.json and Podfile

The XMTP versions are not aligned:

  • package.json: @xmtp/react-native-sdk: ^3.1.1
  • Podfile: XMTP pod version: 3.0.14

This version mismatch could lead to compatibility issues. The Podfile version should be updated to match the SDK version being used in package.json.

🔗 Analysis chain

Verify XMTP version compatibility

The XMTP pod version has been updated to '3.0.14'. Please ensure:

  1. This version is compatible with the @xmtp/react-native-sdk version in package.json
  2. Review the release notes for any breaking changes or security fixes

Let's verify the version compatibility:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check package.json for @xmtp/react-native-sdk version
jq -r '.dependencies["@xmtp/react-native-sdk"]' package.json

# Check GitHub releases for breaking changes
gh api repos/xmtp/xmtp-react-native/releases | jq -r '.[].body' | grep -A 5 "3.0.14"

Length of output: 154


Script:

#!/bin/bash
# Let's check the actual content of package.json to understand the dependency version better
cat package.json | jq '.dependencies'

# Let's also check if there are any direct references to XMTP versions in the codebase
rg "xmtp" -i --type=json --type=podfile -A 2 -B 2

Length of output: 6723


Script:

#!/bin/bash
# Let's check the Podfile content directly
cat ios/Podfile

# Let's also try to find any XMTP version references in the repository
rg "xmtp.*version" -i

Length of output: 3989

Comment on lines +134 to 136
let senderSpamScore = await getSenderSpamScore(address: firstAddress, apiURI: apiURI)
return senderSpamScore
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Handle potential nil value in firstAddress

When accessing inviterAddresses.first, there is a possibility that it could be nil. Ensure to handle this case to prevent unexpected crashes.

Apply this diff to safely unwrap firstAddress:

             if let firstAddress = inviterAddresses.first {
               let senderSpamScore = await getSenderSpamScore(address: firstAddress, apiURI: apiURI)
               return senderSpamScore
+            } else {
+              // Handle the case where inviterAddresses is empty
+              return 0
             }

Committable suggestion skipped: line range outside the PR's diff.

Copy link
Contributor

github-actions bot commented Dec 6, 2024

Performance Comparison Report

  • Current: 53f3c31 - 2024-12-06 19:51:14Z
  • Baseline: release/3.0.0 (ac1eeaa) - 2024-12-06 19:49:35Z

Significant Changes To Duration

There are no entries

Meaningless Changes To Duration

Show entries
Name Type Duration Count
Avatar Image 10 runs render 1.2 ms → 1.3 ms (+0.1 ms, +8.3%) 1 → 1
Avatar Image 50 runs render 1.2 ms → 1.2 ms (+0.0 ms, +3.4%) 1 → 1
Empty Avatar 10 runs render 0.8 ms → 0.7 ms (-0.1 ms, -12.5%) 1 → 1
Empty Avatar 50 runs render 0.7 ms → 0.7 ms 1 → 1
Text Component with color prop - 10 runs render 0.2 ms → 0.2 ms 1 → 1
Text Component with default props - 10 runs render 0.5 ms → 0.4 ms (-0.1 ms, -20.0%) 🟢 1 → 1
Text Component with translation key - 10 runs render 0.2 ms → 0.4 ms (+0.2 ms, +100.0%) 🔴 1 → 1
Text Component with weight and size - 10 runs render 0.3 ms → 0.2 ms (-0.1 ms, -33.3%) 🟢 1 → 1
Show details
Name Type Duration Count
Avatar Image 10 runs render Baseline
Mean: 1.2 ms
Stdev: 0.4 ms (35.1%)
Runs: 1 1 1 2 1 1 1 2 1 1
Warmup runs: 2

Current
Mean: 1.3 ms
Stdev: 0.5 ms (37.2%)
Runs: 2 2 1 1 1 1 1 1 2 1
Warmup runs: 2
Baseline
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1
Render issues:

Current
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1
Render issues:
Avatar Image 50 runs render Baseline
Mean: 1.2 ms
Stdev: 0.4 ms (31.9%)
Runs: 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 2 2 1 2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 2
Warmup runs: 1

Current
Mean: 1.2 ms
Stdev: 0.4 ms (33.7%)
Runs: 2 1 1 1 1 2 1 2 1 1 1 1 1 2 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 2 1 1 2 1 2 1 1 1 1 1 1 1 1 1 1 2 2
Warmup runs: 1
Baseline
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Render issues:

Current
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Render issues:
Empty Avatar 10 runs render Baseline
Mean: 0.8 ms
Stdev: 0.4 ms (52.7%)
Runs: 1 1 0 1 1 1 0 1 1 1
Warmup runs: 3

Current
Mean: 0.7 ms
Stdev: 0.5 ms (69.0%)
Runs: 1 1 0 1 1 1 1 0 0 1
Warmup runs: 3
Baseline
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1
Render issues:

Current
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1
Render issues:
Empty Avatar 50 runs render Baseline
Mean: 0.7 ms
Stdev: 0.5 ms (69.3%)
Runs: 1 1 0 1 1 0 1 1 1 0 0 0 1 1 0 0 0 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 0 1 1 0 1 0 1 0 1 0 1
Warmup runs: 1

Current
Mean: 0.7 ms
Stdev: 0.5 ms (69.3%)
Runs: 1 1 1 1 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0 1 1 1 0 0 0 0 1 0 0 1 1 1 0 1 0 1 1 1 0 0 0 1 1 1
Warmup runs: 1
Baseline
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Render issues:

Current
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Render issues:
Text Component with color prop - 10 runs render Baseline
Mean: 0.2 ms
Stdev: 0.4 ms (210.8%)
Runs: 0 0 1 0 0 0 0 0 1 0
Warmup runs: 0

Current
Mean: 0.2 ms
Stdev: 0.4 ms (210.8%)
Runs: 1 0 0 0 0 0 0 0 1 0
Warmup runs: 0
Baseline
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1
Render issues:

Current
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1
Render issues:
Text Component with default props - 10 runs render Baseline
Mean: 0.5 ms
Stdev: 0.5 ms (105.4%)
Runs: 0 1 1 0 1 0 1 1 0 0
Warmup runs: 0

Current
Mean: 0.4 ms
Stdev: 0.5 ms (129.1%)
Runs: 0 1 0 1 0 0 1 1 0 0
Warmup runs: 1
Baseline
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1
Render issues:

Current
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1
Render issues:
Text Component with translation key - 10 runs render Baseline
Mean: 0.2 ms
Stdev: 0.4 ms (210.8%)
Runs: 0 1 0 1 0 0 0 0 0 0
Warmup runs: 1

Current
Mean: 0.4 ms
Stdev: 0.5 ms (129.1%)
Runs: 0 1 0 0 0 1 0 1 1 0
Warmup runs: 1
Baseline
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1
Render issues:

Current
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1
Render issues:
Text Component with weight and size - 10 runs render Baseline
Mean: 0.3 ms
Stdev: 0.5 ms (161.0%)
Runs: 0 0 0 0 0 1 0 0 1 1
Warmup runs: 0

Current
Mean: 0.2 ms
Stdev: 0.4 ms (210.8%)
Runs: 0 0 1 0 0 0 1 0 0 0
Warmup runs: 0
Baseline
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1
Render issues:

Current
Mean: 1
Stdev: 0 (0.0%)
Runs: 1 1 1 1 1 1 1 1 1 1
Render issues:

Render Count Changes

There are no entries

Render Issues

There are no entries

Added Scenarios

There are no entries

Removed Scenarios

There are no entries

Generated by 🚫 dangerJS against 176d90b

Bumped XMTP
Fixed types
Removed web3 usage in Swift
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (4)
ios/Converse.xcodeproj/project.pbxproj (1)

490-493: Consider security implications of SQLCipher bundle.

The addition of SQLCipher bundle suggests encrypted database usage. This is a good security practice, especially for a messaging app.

components/PinnedConversations/PinnedV3DMConversation.tsx (2)

138-140: Consider extracting shared message preview logic

The message preview logic is duplicated between PinnedV3GroupConversation and PinnedV3DMConversation. Additionally, it has the same type-safety concerns regarding null assertions.

Consider creating a shared hook:

// hooks/useMessagePreview.ts
export function useMessagePreview(message: unknown, isUnread: boolean) {
  return useMemo(() => ({
    shouldDisplay: message != null && isTextMessage(message) && isUnread,
    message: message != null && isTextMessage(message) ? message : null,
  }), [message, isUnread]);
}

Then use it in both components:

- const displayMessagePreview =
-   conversation.lastMessage &&
-   isTextMessage(conversation.lastMessage) &&
-   isUnread;
+ const { shouldDisplay, message: previewMessage } = useMessagePreview(
+   conversation.lastMessage,
+   isUnread
+ );

  // Later in JSX
- {displayMessagePreview && (
-   <PinnedMessagePreview message={conversation.lastMessage!} />
- )}
+ {shouldDisplay && previewMessage && (
+   <PinnedMessagePreview message={previewMessage} />
+ )}

This refactor would:

  1. Eliminate code duplication
  2. Improve type safety by removing non-null assertions
  3. Make the preview logic more maintainable and testable

Line range hint 1-168: Consider implementing component composition for pinned conversations

Both PinnedV3GroupConversation and PinnedV3DMConversation share significant logic and structure. This duplication increases maintenance overhead and the risk of inconsistencies.

Consider implementing a composition-based approach:

  1. Create a base PinnedConversationContainer component that handles common logic (context menu, navigation, preview rendering)
  2. Create separate GroupConversationContent and DMConversationContent components for specific rendering logic
  3. Use composition to combine them

Would you like me to provide a detailed implementation example?

components/Chat/Message/message-utils.tsx (1)

52-55: Consider simplifying the isReplyMessage implementation

The intermediate variable assignment is unnecessary since the function only returns the result of the comparison.

export function isReplyMessage(
  message: DecodedMessageWithCodecsType
): message is DecodedMessage<ReplyCodec, SupportedCodecsType> {
-  const isReply = getMessageContentType(message.contentTypeId) === "reply";
-  return isReply;
+  return getMessageContentType(message.contentTypeId) === "reply";
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 2bfd56b and 176d90b.

⛔ Files ignored due to path filters (2)
  • ios/Podfile.lock is excluded by !**/*.lock
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (22)
  • components/Chat/ChatGroupUpdatedMessage.tsx (1 hunks)
  • components/Chat/Message/message-content-types/message-remote-attachment.tsx (1 hunks)
  • components/Chat/Message/message-content-types/message-reply.tsx (5 hunks)
  • components/Chat/Message/message-content-types/message-simple-text.tsx (1 hunks)
  • components/Chat/Message/message-content-types/message-static-attachment.tsx (1 hunks)
  • components/Chat/Message/message-utils.tsx (2 hunks)
  • components/PinnedConversations/PinnedV3DMConversation.tsx (1 hunks)
  • components/PinnedConversations/PinnedV3GroupConversation.tsx (1 hunks)
  • features/GroupInvites/joinGroup/JoinGroup.client.ts (0 hunks)
  • features/conversation-list/hooks/useMessageText.ts (1 hunks)
  • features/conversation/composer/composer.tsx (4 hunks)
  • ios/Converse.xcodeproj/project.pbxproj (4 hunks)
  • ios/ConverseNotificationExtension/Profile.swift (1 hunks)
  • ios/ConverseNotificationExtension/Spam.swift (5 hunks)
  • ios/ConverseNotificationExtension/Xmtp/Messages.swift (1 hunks)
  • ios/Podfile (2 hunks)
  • package.json (1 hunks)
  • queries/useV3ConversationListQuery.ts (1 hunks)
  • utils/logout/index.tsx (2 hunks)
  • utils/xmtpRN/client.ts (4 hunks)
  • utils/xmtpRN/contacts.ts (3 hunks)
  • utils/xmtpRN/sync.ts (2 hunks)
💤 Files with no reviewable changes (1)
  • features/GroupInvites/joinGroup/JoinGroup.client.ts
🚧 Files skipped from review as they are similar to previous changes (16)
  • ios/ConverseNotificationExtension/Xmtp/Messages.swift
  • utils/xmtpRN/contacts.ts
  • features/conversation-list/hooks/useMessageText.ts
  • components/Chat/Message/message-content-types/message-simple-text.tsx
  • ios/ConverseNotificationExtension/Profile.swift
  • components/Chat/ChatGroupUpdatedMessage.tsx
  • components/Chat/Message/message-content-types/message-remote-attachment.tsx
  • queries/useV3ConversationListQuery.ts
  • package.json
  • components/Chat/Message/message-content-types/message-static-attachment.tsx
  • utils/logout/index.tsx
  • utils/xmtpRN/sync.ts
  • ios/Podfile
  • features/conversation/composer/composer.tsx
  • components/Chat/Message/message-content-types/message-reply.tsx
  • ios/ConverseNotificationExtension/Spam.swift
🔇 Additional comments (8)
ios/Converse.xcodeproj/project.pbxproj (2)

Line range hint 426-449: LGTM: Required resource bundles are properly configured.

The addition of essential bundles like CryptoSwift, SQLCipher, and SwiftProtobuf aligns with the XMTP library requirements and security best practices.

Also applies to: 490-493


Line range hint 426-437: Verify bundle versions compatibility.

The addition of new resource bundles should be checked for version compatibility with the updated XMTP library.

Also applies to: 490-493

✅ Verification successful

Let me try to verify this concern using a different approach by checking the Podfile and related iOS configuration files.


Bundle versions are properly configured and compatible

Based on the Podfile analysis, the XMTP version is explicitly pinned to '3.0.14' and all the related dependencies (CryptoSwift, SQLCipher, SwiftProtobuf) are properly configured in both the main target and notification extension target. The resource bundles are correctly set up in the project.pbxproj with appropriate build configurations and code signing settings. The post-install hooks ensure proper version compatibility and build settings across all pods.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check Podfile.lock for bundle versions
# This helps ensure all added bundles are compatible with the new XMTP version

if [ -f "Podfile.lock" ]; then
  echo "Checking bundle versions in Podfile.lock..."
  grep -A 5 "SPEC CHECKSUMS:" Podfile.lock | grep -E "CryptoSwift|SQLCipher|SwiftProtobuf|XMTP"
else
  echo "Podfile.lock not found"
fi

Length of output: 80


Script:

#!/bin/bash
# Check Podfile and related configuration files
echo "=== Checking Podfile ==="
if [ -f "ios/Podfile" ]; then
    cat ios/Podfile
fi

echo -e "\n=== Checking project.pbxproj for XMTP related configurations ==="
if [ -f "ios/Converse.xcodeproj/project.pbxproj" ]; then
    grep -A 5 "XMTP" ios/Converse.xcodeproj/project.pbxproj
fi

echo -e "\n=== Listing all .bundle references in project.pbxproj ==="
if [ -f "ios/Converse.xcodeproj/project.pbxproj" ]; then
    grep -B 2 -A 2 "\.bundle" ios/Converse.xcodeproj/project.pbxproj
fi

Length of output: 9547

components/Chat/Message/message-utils.tsx (2)

8-11: LGTM: Import changes align with type safety improvements

The addition of DecodedMessageWithCodecsType and SupportedCodecsType imports enhances type safety by replacing any previous usage of any types.


32-33: LGTM: Function signatures consistently use typed parameters

The update of all message type-checking functions to use DecodedMessageWithCodecsType instead of any improves type safety and maintains consistency across the codebase.

Also applies to: 37-38, 42-43, 47-48, 52-53, 58-59, 63-64, 68-69, 75-76

utils/xmtpRN/client.ts (4)

20-20: LGTM: Updated imports align with XMTP SDK changes

The addition of DecodedMessageUnion and InstallationId types from the SDK improves type safety and reflects the library's evolution.

Also applies to: 28-28


44-54: LGTM: Enhanced type safety with explicit codec tuple

The change from a generic type to an explicit tuple type for SupportedCodecsType provides better type checking and autocompletion support.


76-78: LGTM: Improved type definition using Awaited

Using Awaited with the return type of messages() method ensures proper typing for asynchronous operations.


166-167: Verify the impact of InstallationId parameter change

The parameter type change from InboxId to InstallationId in dropXmtpClient might affect existing code that calls this function.

Comment on lines +130 to +131
const displayMessagePreview =
group.lastMessage && isTextMessage(group.lastMessage) && isUnread;
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider handling undefined messages more gracefully

While the null check for group.lastMessage improves safety, there's still a non-null assertion (!) being used when passing the message to PinnedMessagePreview. This could be problematic if the message becomes null between the check and render.

Consider this safer approach:

- const displayMessagePreview =
-   group.lastMessage && isTextMessage(group.lastMessage) && isUnread;
+ const lastMessage = group.lastMessage;
+ const displayMessagePreview =
+   lastMessage != null && isTextMessage(lastMessage) && isUnread;

  // Later in JSX
- {displayMessagePreview && <PinnedMessagePreview message={group.lastMessage!} />}
+ {displayMessagePreview && lastMessage && (
+   <PinnedMessagePreview message={lastMessage} />
+ )}

Committable suggestion skipped: line range outside the PR's diff.

@alexrisch alexrisch merged commit ec9288c into release/3.0.0 Dec 9, 2024
8 checks passed
@alexrisch alexrisch deleted the ar/bump-xmtp branch December 9, 2024 16:27
technoplato pushed a commit that referenced this pull request Dec 17, 2024
* chore: Bump Xmtp

Bumped XMTP
Fixed types
Removed web3 usage in Swift

* rebase and fixed types
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.

2 participants