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

fix: Add created at to the installation #502

Merged
merged 9 commits into from
Sep 29, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ repositories {
dependencies {
implementation project(':expo-modules-core')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
implementation "org.xmtp:android:0.15.10"
implementation "org.xmtp:android:0.15.11"
implementation 'com.google.code.gson:gson:2.10.1'
implementation 'com.facebook.react:react-native:0.71.3'
implementation "com.daveanthonythomas.moshipack:moshipack:1.0.1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import org.xmtp.android.library.Conversation
class ConversationContainerWrapper {

companion object {
fun encodeToObj(client: Client, conversation: Conversation): Map<String, Any?> {
suspend fun encodeToObj(client: Client, conversation: Conversation): Map<String, Any?> {
when (conversation.version) {
Conversation.Version.GROUP -> {
val group = (conversation as Conversation.Group).group
Expand All @@ -20,7 +20,7 @@ class ConversationContainerWrapper {
}
}

fun encode(client: Client, conversation: Conversation): String {
suspend fun encode(client: Client, conversation: Conversation): String {
val gson = GsonBuilder().create()
val obj = ConversationContainerWrapper.encodeToObj(client, conversation)
return gson.toJson(obj)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import org.xmtp.android.library.toHex
class GroupWrapper {

companion object {
fun encodeToObj(client: Client, group: Group): Map<String, Any> {
suspend fun encodeToObj(client: Client, group: Group): Map<String, Any> {
return mapOf(
"clientAddress" to client.address,
"id" to group.id,
Expand All @@ -26,7 +26,7 @@ class GroupWrapper {
)
}

fun encode(client: Client, group: Group): String {
suspend fun encode(client: Client, group: Group): String {
val gson = GsonBuilder().create()
val obj = encodeToObj(client, group)
return gson.toJson(obj)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
package expo.modules.xmtpreactnativesdk.wrappers

import com.google.gson.Gson
import com.google.gson.GsonBuilder
import uniffi.xmtpv3.org.xmtp.android.library.libxmtp.InboxState

class InboxStateWrapper {
companion object {
val gson: Gson = GsonBuilder().create()
fun encodeToObj(inboxState: InboxState): Map<String, Any> {
return mapOf(
"inboxId" to inboxState.inboxId,
"addresses" to inboxState.addresses,
"installationIds" to inboxState.installationIds,
"installations" to inboxState.installations.map {
gson.toJson(
mapOf(
"id" to it.installationId,
"createdAt" to it.createdAt?.time
)
)
},
"recoveryAddress" to inboxState.recoveryAddress
)
}

fun encode(inboxState: InboxState): String {
val gson = GsonBuilder().create()
val obj = encodeToObj(inboxState)
return gson.toJson(obj)
}
Expand Down
14 changes: 7 additions & 7 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ PODS:
- hermes-engine/Pre-built (= 0.71.14)
- hermes-engine/Pre-built (0.71.14)
- libevent (2.1.12)
- LibXMTP (0.5.8-beta6)
- LibXMTP (0.5.8-beta7)
- Logging (1.0.0)
- MessagePacker (0.4.7)
- MMKV (1.3.9):
Expand Down Expand Up @@ -449,16 +449,16 @@ PODS:
- GenericJSON (~> 2.0)
- Logging (~> 1.0.0)
- secp256k1.swift (~> 0.1)
- XMTP (0.14.14):
- XMTP (0.14.17):
- Connect-Swift (= 0.12.0)
- GzipSwift
- LibXMTP (= 0.5.8-beta6)
- LibXMTP (= 0.5.8-beta7)
- web3.swift
- XMTPReactNative (0.1.0):
- ExpoModulesCore
- MessagePacker
- secp256k1.swift
- XMTP (= 0.14.14)
- XMTP (= 0.14.17)
- Yoga (1.14.0)

DEPENDENCIES:
Expand Down Expand Up @@ -711,7 +711,7 @@ SPEC CHECKSUMS:
GzipSwift: 893f3e48e597a1a4f62fafcb6514220fcf8287fa
hermes-engine: d7cc127932c89c53374452d6f93473f1970d8e88
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
LibXMTP: c7338cace222bed90f950579300725325a2c0bfd
LibXMTP: 693447f2c1242dd2f5b2146828c52dbb2bd92d6f
Logging: 9ef4ecb546ad3169398d5a723bc9bea1c46bef26
MessagePacker: ab2fe250e86ea7aedd1a9ee47a37083edd41fd02
MMKV: 817ba1eea17421547e01e087285606eb270a8dcb
Expand Down Expand Up @@ -763,8 +763,8 @@ SPEC CHECKSUMS:
secp256k1.swift: a7e7a214f6db6ce5db32cc6b2b45e5c4dd633634
SwiftProtobuf: 407a385e97fd206c4fbe880cc84123989167e0d1
web3.swift: 2263d1e12e121b2c42ffb63a5a7beb1acaf33959
XMTP: 37621f1258b12629af305e6697414ccb2fbd4ea8
XMTPReactNative: 7bec275ed26997e6a73f06a678c328e6ba852cd5
XMTP: 64600a3216ef8bfb074a128cffe37458b23c52fd
XMTPReactNative: 39e85c5215efa8cb7900285dc95319402758d85b
Yoga: e71803b4c1fff832ccf9b92541e00f9b873119b9

PODFILE CHECKSUM: 0e6fe50018f34e575d38dc6a1fdf1f99c9596cdd
Expand Down
63 changes: 9 additions & 54 deletions example/src/tests/groupTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,28 +21,6 @@ function test(name: string, perform: () => Promise<boolean>) {
groupTests.push({ name: String(counter++) + '. ' + name, run: perform })
}

async function createGroups(
client: Client,
peers: Client[],
numGroups: number,
numMessages: number
): Promise<Group[]> {
const groups = []
const addresses: string[] = peers.map((client) => client.address)
for (let i = 0; i < numGroups; i++) {
const group = await client.conversations.newGroup(addresses, {
name: `group ${i}`,
imageUrlSquare: `www.group${i}.com`,
description: `group ${i}`,
})
groups.push(group)
for (let i = 0; i < numMessages; i++) {
await group.send({ text: `Message ${i}` })
}
}
return groups
}

test('can make a MLS V3 client', async () => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const keyBytes = new Uint8Array([
Expand Down Expand Up @@ -91,16 +69,21 @@ test('can revoke all other installations', async () => {

const inboxState = await alix2.inboxState(true)
assert(
inboxState.installationIds.length === 2,
`installationIds length should be 2 but was ${inboxState.installationIds.length}`
inboxState.installations.length === 2,
`installations length should be 2 but was ${inboxState.installations.length}`
)

await alix2.revokeAllOtherInstallations(alixWallet)

const inboxState2 = await alix2.inboxState(true)
assert(
inboxState2.installationIds.length === 1,
`installationIds length should be 1 but was ${inboxState2.installationIds.length}`
inboxState2.installations.length === 1,
`installations length should be 1 but was ${inboxState2.installations.length}`
)

assert(
inboxState2.installations[0].createdAt !== undefined,
`installations createdAt should not be undefined`
)
return true
})
Expand Down Expand Up @@ -240,34 +223,6 @@ test('can make a MLS V3 client with encryption key and database directory', asyn
return true
})

test('testing large group listing with metadata performance', async () => {
const [alixClient, boClient] = await createClients(2)

await createGroups(alixClient, [boClient], 50, 10)

let start = Date.now()
let groups = await alixClient.conversations.listGroups()
let end = Date.now()
console.log(`Alix loaded ${groups.length} groups in ${end - start}ms`)

start = Date.now()
await alixClient.conversations.syncGroups()
end = Date.now()
console.log(`Alix synced ${groups.length} groups in ${end - start}ms`)

start = Date.now()
await boClient.conversations.syncGroups()
end = Date.now()
console.log(`Bo synced ${groups.length} groups in ${end - start}ms`)

start = Date.now()
groups = await boClient.conversations.listGroups()
end = Date.now()
console.log(`Bo loaded ${groups.length} groups in ${end - start}ms`)

return true
})

test('can drop a local database', async () => {
const [client, anotherClient] = await createClients(2)

Expand Down
8 changes: 4 additions & 4 deletions ios/Wrappers/ConversationContainerWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ import XMTP

// Wrapper around XMTP.ConversationContainer to allow passing these objects back into react native.
struct ConversationContainerWrapper {
static func encodeToObj(_ conversation: XMTP.Conversation, client: XMTP.Client) throws -> [String: Any] {
static func encodeToObj(_ conversation: XMTP.Conversation, client: XMTP.Client) async throws -> [String: Any] {
switch conversation {
case .group(let group):
return try GroupWrapper.encodeToObj(group, client: client)
return try await GroupWrapper.encodeToObj(group, client: client)
default:
return try ConversationWrapper.encodeToObj(conversation, client: client)
}
}

static func encode(_ conversation: XMTP.Conversation, client: XMTP.Client) throws -> String {
let obj = try encodeToObj(conversation, client: client)
static func encode(_ conversation: XMTP.Conversation, client: XMTP.Client) async throws -> String {
let obj = try await encodeToObj(conversation, client: client)
let data = try JSONSerialization.data(withJSONObject: obj)
guard let result = String(data: data, encoding: .utf8) else {
throw WrapperError.encodeError("could not encode conversation")
Expand Down
8 changes: 4 additions & 4 deletions ios/Wrappers/GroupWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ import XMTP

// Wrapper around XMTP.Group to allow passing these objects back into react native.
struct GroupWrapper {
static func encodeToObj(_ group: XMTP.Group, client: XMTP.Client) throws -> [String: Any] {
static func encodeToObj(_ group: XMTP.Group, client: XMTP.Client) async throws -> [String: Any] {
return [
"clientAddress": client.address,
"id": group.id,
"createdAt": UInt64(group.createdAt.timeIntervalSince1970 * 1000),
"members": try group.members.compactMap { member in return try MemberWrapper.encode(member) },
"members": try await group.members.compactMap { member in return try MemberWrapper.encode(member) },
"version": "GROUP",
"topic": group.topic,
"creatorInboxId": try group.creatorInboxId(),
Expand All @@ -28,8 +28,8 @@ struct GroupWrapper {
]
}

static func encode(_ group: XMTP.Group, client: XMTP.Client) throws -> String {
let obj = try encodeToObj(group, client: client)
static func encode(_ group: XMTP.Group, client: XMTP.Client) async throws -> String {
let obj = try await encodeToObj(group, client: client)
let data = try JSONSerialization.data(withJSONObject: obj)
guard let result = String(data: data, encoding: .utf8) else {
throw WrapperError.encodeError("could not encode group")
Expand Down
11 changes: 10 additions & 1 deletion ios/Wrappers/InboxStateWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ struct InboxStateWrapper {
return [
"inboxId": inboxState.inboxId,
"addresses": inboxState.addresses,
"installationIds": inboxState.installationIds,
"installations": inboxState.installations.map { Installation.encodeInstallation(installation: $0) },
"recoveryAddress": inboxState.recoveryAddress
]
}
Expand All @@ -28,3 +28,12 @@ struct InboxStateWrapper {
return result
}
}

struct Installation {
static func encodeInstallation(installation: XMTP.Installation) -> [String: Any] {
return [
"id": installation.id,
"createdAt": installation.createdAt?.timeIntervalSince1970 ?? NSNull()
]
}
}
20 changes: 10 additions & 10 deletions ios/XMTPModule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,7 @@ public class XMTPModule: Module {
var results: [String] = []
for group in groupList {
await self.groupsManager.set(group.cacheKey(inboxId), group)
let encodedGroup = try GroupWrapper.encode(group, client: client)
let encodedGroup = try await GroupWrapper.encode(group, client: client)
results.append(encodedGroup)
}

Expand All @@ -557,7 +557,7 @@ public class XMTPModule: Module {
var results: [String] = []
for conversation in conversationContainerList {
await self.conversationsManager.set(conversation.cacheKey(inboxId), conversation)
let encodedConversationContainer = try ConversationContainerWrapper.encode(conversation, client: client)
let encodedConversationContainer = try await ConversationContainerWrapper.encode(conversation, client: client)
results.append(encodedConversationContainer)
}

Expand Down Expand Up @@ -644,7 +644,7 @@ public class XMTPModule: Module {
throw Error.noClient
}
if let group = try client.findGroup(groupId: groupId) {
return try GroupWrapper.encode(group, client: client)
return try await GroupWrapper.encode(group, client: client)
} else {
return nil
}
Expand Down Expand Up @@ -878,7 +878,7 @@ public class XMTPModule: Module {
description: createGroupParams.groupDescription,
pinnedFrameUrl: createGroupParams.groupPinnedFrameUrl
)
return try GroupWrapper.encode(group, client: client)
return try await GroupWrapper.encode(group, client: client)
} catch {
print("ERRRO!: \(error.localizedDescription)")
throw error
Expand All @@ -900,7 +900,7 @@ public class XMTPModule: Module {
description: createGroupParams.groupDescription,
pinnedFrameUrl: createGroupParams.groupPinnedFrameUrl
)
return try GroupWrapper.encode(group, client: client)
return try await GroupWrapper.encode(group, client: client)
} catch {
print("ERRRO!: \(error.localizedDescription)")
throw error
Expand All @@ -915,7 +915,7 @@ public class XMTPModule: Module {
guard let group = try await findGroup(inboxId: inboxId, id: groupId) else {
throw Error.conversationNotFound("no group found for \(groupId)")
}
return try group.members.map(\.inboxId)
return try await group.members.map(\.inboxId)
}

AsyncFunction("listGroupMembers") { (inboxId: String, groupId: String) -> [String] in
Expand All @@ -926,7 +926,7 @@ public class XMTPModule: Module {
guard let group = try await findGroup(inboxId: inboxId, id: groupId) else {
throw Error.conversationNotFound("no group found for \(groupId)")
}
return try group.members.compactMap { member in
return try await group.members.compactMap { member in
return try MemberWrapper.encode(member)
}
}
Expand Down Expand Up @@ -1333,7 +1333,7 @@ public class XMTPModule: Module {
throw Error.conversationNotFound("no group found")
}

return try GroupWrapper.encode(group, client: client)
return try await GroupWrapper.encode(group, client: client)
}

AsyncFunction("subscribeToConversations") { (inboxId: String) in
Expand Down Expand Up @@ -1811,7 +1811,7 @@ public class XMTPModule: Module {
await subscriptionsManager.set(getGroupsKey(inboxId: client.inboxID), Task {
do {
for try await group in try await client.conversations.streamGroups() {
try sendEvent("group", [
try await sendEvent("group", [
"inboxId": inboxId,
"group": GroupWrapper.encodeToObj(group, client: client),
])
Expand All @@ -1832,7 +1832,7 @@ public class XMTPModule: Module {
await subscriptionsManager.set(getConversationsKey(inboxId: inboxId), Task {
do {
for try await conversation in await client.conversations.streamAll() {
try sendEvent("conversationContainer", [
try await sendEvent("conversationContainer", [
"inboxId": inboxId,
"conversationContainer": ConversationContainerWrapper.encodeToObj(conversation, client: client),
])
Expand Down
2 changes: 1 addition & 1 deletion ios/XMTPReactNative.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ Pod::Spec.new do |s|
s.source_files = "**/*.{h,m,swift}"
s.dependency 'secp256k1.swift'
s.dependency "MessagePacker"
s.dependency "XMTP", "= 0.14.14"
s.dependency "XMTP", "= 0.14.17"
end
Loading
Loading