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

Re-Enable History Sync #578

Merged
merged 7 commits into from
Jan 2, 2025
Merged
Show file tree
Hide file tree
Changes from all 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
6 changes: 6 additions & 0 deletions .changeset/slimy-pugs-warn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@xmtp/react-native-sdk": patch
---

- Re-Enable History Sync
- Continued Performance improvements
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:3.0.18"
implementation "org.xmtp:android:3.0.19"
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 @@ -59,7 +59,6 @@ import org.xmtp.android.library.messages.PrivateKeyBuilder
import org.xmtp.android.library.messages.Signature
import org.xmtp.android.library.push.Service
import org.xmtp.android.library.push.XMTPPush
import uniffi.xmtpv3.XmtpApiClient
import uniffi.xmtpv3.org.xmtp.android.library.libxmtp.GroupPermissionPreconfiguration
import uniffi.xmtpv3.org.xmtp.android.library.libxmtp.PermissionOption
import java.io.BufferedReader
Expand Down Expand Up @@ -192,7 +191,6 @@ class XMTPModule : Module() {
}

private var clients: MutableMap<String, Client> = mutableMapOf()
private var apiClient: XmtpApiClient? = null
private var xmtpPush: XMTPPush? = null
private var signer: ReactNativeSigner? = null
private val isDebugEnabled = BuildConfig.DEBUG // TODO: consider making this configurable
Expand Down Expand Up @@ -251,13 +249,6 @@ class XMTPModule : Module() {
}
}

AsyncFunction("requestMessageHistorySync") Coroutine { installationId: String ->
withContext(Dispatchers.IO) {
val client = clients[installationId] ?: throw XMTPException("No client")
client.requestMessageHistorySync()
}
}

AsyncFunction("getInboxState") Coroutine { installationId: String, refreshFromNetwork: Boolean ->
withContext(Dispatchers.IO) {
val client = clients[installationId] ?: throw XMTPException("No client")
Expand Down Expand Up @@ -292,15 +283,6 @@ class XMTPModule : Module() {
signer?.handleSCW(id = requestID, signature = signature)
}

AsyncFunction("connectToApiBackend") Coroutine { environment: String ->
withContext(Dispatchers.IO) {
logV("connectToApiBackend")
val api = apiEnvironments(environment, null)
val xmtpApiClient = Client.connectToApiBackend(api)
apiClient = xmtpApiClient
}
}

AsyncFunction("createRandom") Coroutine { hasPreAuthenticateToInboxCallback: Boolean?, dbEncryptionKey: List<Int>, authParams: String ->
withContext(Dispatchers.IO) {
logV("createRandom")
Expand All @@ -311,11 +293,10 @@ class XMTPModule : Module() {
hasPreAuthenticateToInboxCallback,
)
val randomClient =
Client().create(account = privateKey, options = options, apiClient = apiClient)
Client().create(account = privateKey, options = options)

ContentJson.Companion
clients[randomClient.installationId] = randomClient
apiClient = randomClient.apiClient
ClientWrapper.encodeToObj(randomClient)
}
}
Expand All @@ -338,9 +319,8 @@ class XMTPModule : Module() {
hasAuthInboxCallback,
)
val client =
Client().create(account = reactSigner, options = options, apiClient = apiClient)
Client().create(account = reactSigner, options = options)
clients[client.installationId] = client
apiClient = client.apiClient
ContentJson.Companion
signer = null
sendEvent("authed", ClientWrapper.encodeToObj(client))
Expand All @@ -358,11 +338,9 @@ class XMTPModule : Module() {
address = address,
options = options,
inboxId = inboxId,
apiClient = apiClient
)
ContentJson.Companion
clients[client.installationId] = client
apiClient = client.apiClient
ClientWrapper.encodeToObj(client)
}
}
Expand Down Expand Up @@ -472,7 +450,6 @@ class XMTPModule : Module() {
peerAddresses,
context,
apiEnvironments(environment, null),
apiClient = apiClient
)
}
}
Expand All @@ -482,7 +459,7 @@ class XMTPModule : Module() {
try {
logV("getOrCreateInboxId")
Client.getOrCreateInboxId(
environment = apiEnvironments(environment, null),
api = apiEnvironments(environment, null),
address = address
)
} catch (e: Exception) {
Expand Down
16 changes: 8 additions & 8 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ PODS:
- hermes-engine/Pre-built (= 0.71.14)
- hermes-engine/Pre-built (0.71.14)
- libevent (2.1.12)
- LibXMTP (3.0.13)
- LibXMTP (3.0.15)
- MessagePacker (0.4.7)
- MMKV (2.0.0):
- MMKVCore (~> 2.0.0)
Expand Down Expand Up @@ -448,18 +448,18 @@ PODS:
- SQLCipher/standard (4.5.7):
- SQLCipher/common
- SwiftProtobuf (1.28.2)
- XMTP (3.0.19):
- XMTP (3.0.21):
- Connect-Swift (= 1.0.0)
- CryptoSwift (= 1.8.3)
- CSecp256k1 (~> 0.2)
- LibXMTP (= 3.0.13)
- LibXMTP (= 3.0.15)
- SQLCipher (= 4.5.7)
- XMTPReactNative (3.1.3):
- XMTPReactNative (3.1.4):
- CSecp256k1 (~> 0.2)
- ExpoModulesCore
- MessagePacker
- SQLCipher (= 4.5.7)
- XMTP (= 3.0.19)
- XMTP (= 3.0.21)
- Yoga (1.14.0)

DEPENDENCIES:
Expand Down Expand Up @@ -711,7 +711,7 @@ SPEC CHECKSUMS:
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
hermes-engine: d7cc127932c89c53374452d6f93473f1970d8e88
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
LibXMTP: 3b4b45c0edd404de164e26c7920af5ea0ebb3e17
LibXMTP: ad2c28778d7273c499b12dbf5493978c58d76858
MessagePacker: ab2fe250e86ea7aedd1a9ee47a37083edd41fd02
MMKV: f7d1d5945c8765f97f39c3d121f353d46735d801
MMKVCore: c04b296010fcb1d1638f2c69405096aac12f6390
Expand Down Expand Up @@ -762,8 +762,8 @@ SPEC CHECKSUMS:
RNSVG: d00c8f91c3cbf6d476451313a18f04d220d4f396
SQLCipher: 5e6bfb47323635c8b657b1b27d25c5f1baf63bf5
SwiftProtobuf: 4dbaffec76a39a8dc5da23b40af1a5dc01a4c02d
XMTP: b5311154b2a3cda7c07ce78ae9fa6d111bac979d
XMTPReactNative: 0d7f1d9b444eaeb3ffaf0fd29c6b71a0d6b6a29a
XMTP: 2c5dd2116778d1b547ac99b5b2396318d02c24d1
XMTPReactNative: 7745410f6367ed23198e546409d84987c6c5fea9
Yoga: e71803b4c1fff832ccf9b92541e00f9b873119b9

PODFILE CHECKSUM: 0e6fe50018f34e575d38dc6a1fdf1f99c9596cdd
Expand Down
10 changes: 5 additions & 5 deletions example/src/tests/conversationTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
type EncodedContent = content.EncodedContent
type ContentTypeId = content.ContentTypeId

const { fs } = ReactNativeBlobUtil

Check warning on line 28 in example/src/tests/conversationTests.ts

View workflow job for this annotation

GitHub Actions / lint

'fs' is assigned a value but never used

const ContentTypeNumber: ContentTypeId = {
authorityId: 'org',
Expand Down Expand Up @@ -415,14 +415,14 @@
const boConvosFilteredUnknown =
await boClient.conversations.syncAllConversations('unknown')

assert(boConvos === 4, `Conversation length should be 4 but was ${boConvos}`)
assert(boConvos === 5, `Conversation length should be 5 but was ${boConvos}`)
assert(
boConvosFilteredAllowed === 2,
`Conversation length should be 2 but was ${boConvosFilteredAllowed}`
boConvosFilteredAllowed === 3,
`Conversation length should be 3 but was ${boConvosFilteredAllowed}`
)
assert(
boConvosFilteredUnknown === 2,
`Conversation length should be 2 but was ${boConvosFilteredUnknown}`
boConvosFilteredUnknown === 3,
`Conversation length should be 3 but was ${boConvosFilteredUnknown}`
)

return true
Expand Down
141 changes: 118 additions & 23 deletions example/src/tests/groupPerformanceTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
StaticAttachmentCodec,
} from 'xmtp-react-native-sdk'

import { Test, assert } from './test-utils'
import { Test, assert, createClients } from './test-utils'

export const groupPerformanceTests: Test[] = []
let counter = 1
Expand Down Expand Up @@ -88,26 +88,6 @@ test('building and creating', async () => {
const end3 = performance.now()
console.log(`Built a client with inboxId in ${end3 - start3}ms`)

await Client.connectToApiBackend('dev')
const start4 = performance.now()
await Client.createRandom({
env: 'dev',
appVersion: 'Testing/0.0.0',
dbEncryptionKey: keyBytes,
dbDirectory: dbDirPath,
codecs: [
new ReactionCodec(),
new ReplyCodec(),
new GroupUpdatedCodec(),
new StaticAttachmentCodec(),
new RemoteAttachmentCodec(),
],
})
const end4 = performance.now()
console.log(
`Created a client after connecting to backend in ${end4 - start4}ms`
)

assert(
end2 - start2 < end1 - start1,
'building a client should be faster than creating one'
Expand All @@ -120,10 +100,125 @@ test('building and creating', async () => {
end3 - start3 < end2 - start2,
'building a client with an inboxId should be faster than building without'
)

return true
})

test('creating a new conversation', async () => {
const [alixClient, boClient, caroClient] = await createClients(3, 'dev')

const start1 = performance.now()
await alixClient.conversations.newConversation(boClient.address)
const end1 = performance.now()
console.log(`Alix created a dm with Bo in ${end1 - start1}ms`)

await boClient.conversations.syncAllConversations()
const start2 = performance.now()
await boClient.conversations.newConversation(alixClient.address)
const end2 = performance.now()
console.log(`Bo found a dm with Alix in ${end2 - start2}ms`)

const start3 = performance.now()
await alixClient.conversations.newGroup([
boClient.address,
caroClient.address,
])
const end3 = performance.now()
console.log(`Alix created a group with Bo and Caro in ${end3 - start3}ms`)

const start4 = performance.now()
await alixClient.conversations.newGroup(
[boClient.address, caroClient.address],
{
permissionLevel: 'admin_only',
name: 'Group Name',
imageUrlSquare: 'imageurl.com',
description: 'group description',
pinnedFrameUrl: 'pinnedframe.com',
}
)
const end4 = performance.now()
console.log(
`Alix created a group with Bo and Caro with metadata in ${end4 - start4}ms`
)
assert(
end4 - start4 < end1 - start1,
'creating a client with an apiClient cached should be faster than creating one without'
end1 - start1 < 1000,
`Creating a new dm should be less than a second but was ${end1 - start1}`
)
assert(
end2 - start2 < 1000,
`Finding a existing dm should be less than a second but was ${end2 - start2}`
)
assert(
end3 - start3 < 1000,
`Creating a new group without metadata should be less than a second but was ${end3 - start3}`
)
assert(
end4 - start4 < 1000,
`Creating a new group with metadata should be less than a second but was ${end4 - start4}`
)
return true
})

test('sending messages in conversations', async () => {
const [alixClient, boClient, caroClient] = await createClients(10, 'local')
const alixDm = await alixClient.conversations.newConversation(
boClient.address
)
const alixGroup = await alixClient.conversations.newGroup([
boClient.address,
caroClient.address,
])
await boClient.conversations.syncAllConversations()
await caroClient.conversations.syncAllConversations()
const boDm = await alixClient.conversations.findConversation(alixDm.id)
const boGroup = await alixClient.conversations.findGroup(alixGroup.id)
const caroGroup = await alixClient.conversations.findConversation(
alixGroup.id
)

const start1 = performance.now()
await boDm?.send('message 1')
const end1 = performance.now()
console.log(`Bo sent message to dm in ${end1 - start1}ms`)

const start2 = performance.now()
await alixDm.send('message 2')
const end2 = performance.now()
console.log(`Alix sent message to dm in ${end2 - start2}ms`)

const start3 = performance.now()
await alixGroup.send('message 1')
const end3 = performance.now()
console.log(`Alix sent message to group in ${end3 - start3}ms`)

const start4 = performance.now()
await caroGroup?.send('message 2')
const end4 = performance.now()
console.log(`Caro sent message to group in ${end4 - start4}ms`)
const start5 = performance.now()
await boGroup?.send('message 3')
const end5 = performance.now()
console.log(`Bo sent message to group in ${end5 - start5}ms`)
assert(
end1 - start1 < 500,
`Sending message to dm should take less than .5s but was ${end1 - start1}`
)
assert(
end2 - start2 < 500,
`Sending message to dm should take less than .5s but was ${end2 - start2}`
)
assert(
end3 - start3 < 500,
`Sending message to group should take less than .5s but was ${end3 - start3}`
)
assert(
end4 - start4 < 500,
`Sending message to grop should take less than .5s but was ${end4 - start4}`
)
assert(
end5 - start5 < 500,
`Sending message to grop should take less than .5s but was ${end5 - start5}`
)
return true
})
8 changes: 6 additions & 2 deletions example/src/tests/test-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
GroupUpdatedCodec,
Group,
RemoteAttachmentCodec,
XMTPEnvironment,
} from 'xmtp-react-native-sdk'

export type Test = {
Expand All @@ -26,7 +27,10 @@ export function assert(condition: boolean, msg: string) {
}
}

export async function createClients(numClients: number): Promise<Client[]> {
export async function createClients(
numClients: number,
env?: XMTPEnvironment | undefined
): Promise<Client[]> {
const clients = []
for (let i = 0; i < numClients; i++) {
const keyBytes = new Uint8Array([
Expand All @@ -35,7 +39,7 @@ export async function createClients(numClients: number): Promise<Client[]> {
145,
])
const client = await Client.createRandom({
env: 'local',
env: env ?? 'local',
dbEncryptionKey: keyBytes,
})
client.register(new GroupUpdatedCodec())
Expand Down
Loading
Loading