Skip to content

Commit

Permalink
clean up and align all the bindings with index
Browse files Browse the repository at this point in the history
  • Loading branch information
nplasterer committed Nov 11, 2024
1 parent fc63b39 commit caa0005
Show file tree
Hide file tree
Showing 17 changed files with 873 additions and 1,107 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -172,14 +172,12 @@ class XMTPModule : Module() {
dbEncryptionKey.foldIndexed(ByteArray(dbEncryptionKey.size)) { i, a, v ->
a.apply { set(i, v.toByte()) }
}

val historySyncUrl = authOptions.historySyncUrl
?: when (authOptions.environment) {
"production" -> "https://message-history.production.ephemera.network/"
"local" -> "http://0.0.0.0:5558"
else -> "https://message-history.dev.ephemera.network/"
}

return ClientOptions(
api = apiEnvironments(authOptions.environment, authOptions.appVersion),
preAuthenticateToInboxCallback = preAuthenticateToInboxCallback,
Expand Down Expand Up @@ -533,9 +531,9 @@ class XMTPModule : Module() {
}
}

AsyncFunction("findDm") Coroutine { inboxId: String, peerAddress: String ->
AsyncFunction("findDmByAddress") Coroutine { inboxId: String, peerAddress: String ->
withContext(Dispatchers.IO) {
logV("findDm")
logV("findDmByAddress")
val client = clients[inboxId] ?: throw XMTPException("No client")
val dm = client.findDm(peerAddress)
dm?.let {
Expand Down
10 changes: 0 additions & 10 deletions example/src/LaunchScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -173,16 +173,6 @@ export default function LaunchScreen(
}
/>
</View>
<View style={styles.row}>
<Text style={styles.label}>Enable Groups:</Text>
<ModalSelector
selectStyle={styles.modalSelector}
initValueTextStyle={styles.modalSelectText}
selectTextStyle={styles.modalSelectText}
backdropPressToClose
data={groupOptions}
/>
</View>
<View style={styles.row}>
<Text style={styles.label}>External Wallet:</Text>
<ConnectWallet theme="dark" />
Expand Down
11 changes: 9 additions & 2 deletions example/src/TestScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useRoute } from '@react-navigation/native'
import React, { useEffect, useState } from 'react'
import { View, Text, Button, ScrollView } from 'react-native'

import { clientTests } from './tests/clientTests'
import { conversationTests } from './tests/conversationTests'
import { dmTests } from './tests/dmTests'
import { groupPerformanceTests } from './tests/groupPerformanceTests'
Expand Down Expand Up @@ -106,9 +107,10 @@ function TestView({

export enum TestCategory {
all = 'all',
conversation = 'conversation',
group = 'group',
client = 'client',
dm = 'dm',
group = 'group',
conversation = 'conversation',
restartStreans = 'restartStreams',
groupPermissions = 'groupPermissions',
groupPerformance = 'groupPerformance',
Expand All @@ -121,6 +123,7 @@ export default function TestScreen(): JSX.Element {
testSelection: TestCategory
}
const allTests = [
...clientTests,
...dmTests,
...groupTests,
...conversationTests,
Expand All @@ -133,6 +136,10 @@ export default function TestScreen(): JSX.Element {
activeTests = allTests
title = 'All Unit Tests'
break
case TestCategory.client:
activeTests = clientTests
title = 'Client Unit Tests'
break
case TestCategory.dm:
activeTests = dmTests
title = 'Dm Unit Tests'
Expand Down
283 changes: 283 additions & 0 deletions example/src/tests/clientTests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,283 @@
import { Test, assert, createClients, delayToPropogate } from './test-utils'
import { Client, Conversation, ConversationId, ConversationVersion } from '../../../src/index'
import { Wallet } from 'ethers'
import RNFS from 'react-native-fs'

export const clientTests: Test[] = []
let counter = 1
function test(name: string, perform: () => Promise<boolean>) {
clientTests.push({
name: String(counter++) + '. ' + name,
run: perform,
})
}


test('can make a client', async () => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const keyBytes = new Uint8Array([
233, 120, 198, 96, 154, 65, 132, 17, 132, 96, 250, 40, 103, 35, 125, 64,
166, 83, 208, 224, 254, 44, 205, 227, 175, 49, 234, 129, 74, 252, 135, 145,
])
const client = await Client.createRandom({
env: 'local',
appVersion: 'Testing/0.0.0',
dbEncryptionKey: keyBytes,
})

const inboxId = await Client.getOrCreateInboxId(client.address, 'local')

assert(
client.inboxId === inboxId,
`inboxIds should match but were ${client.inboxId} and ${inboxId}`
)
return true
})

test('can revoke all other installations', async () => {
const keyBytes = new Uint8Array([
233, 120, 198, 96, 154, 65, 132, 17, 132, 96, 250, 40, 103, 35, 125, 64,
166, 83, 208, 224, 254, 44, 205, 227, 175, 49, 234, 129, 74, 252, 135, 145,
])
const alixWallet = Wallet.createRandom()

// create a v3 client
const alix = await Client.create(alixWallet, {
env: 'local',
appVersion: 'Testing/0.0.0',
dbEncryptionKey: keyBytes,
})

await alix.deleteLocalDatabase()

const alix2 = await Client.create(alixWallet, {
env: 'local',
appVersion: 'Testing/0.0.0',
dbEncryptionKey: keyBytes,
})

const alix2Build = await Client.build(alix2.address, {
env: 'local',
appVersion: 'Testing/0.0.0',
dbEncryptionKey: keyBytes,
})

await alix2.deleteLocalDatabase()

const alix3 = await Client.create(alixWallet, {
env: 'local',
appVersion: 'Testing/0.0.0',
dbEncryptionKey: keyBytes,
})

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

await alix3.revokeAllOtherInstallations(alixWallet)

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

assert(
inboxState3.installations[0].createdAt !== undefined,
`installations createdAt should not be undefined`
)
return true
})

test('calls preAuthenticateToInboxCallback when supplied', async () => {
let isCallbackCalled = 0
let isPreAuthCalled = false
const preAuthenticateToInboxCallback = () => {
isCallbackCalled++
isPreAuthCalled = true
}

const keyBytes = new Uint8Array([
233, 120, 198, 96, 154, 65, 132, 17, 132, 96, 250, 40, 103, 35, 125, 64,
166, 83, 208, 224, 254, 44, 205, 227, 175, 49, 234, 129, 74, 252, 135, 145,
])

await Client.createRandom({
env: 'local',
preAuthenticateToInboxCallback,
dbEncryptionKey: keyBytes,
})

assert(
isCallbackCalled === 1,
`callback should be called 1 times but was ${isCallbackCalled}`
)

if (!isPreAuthCalled) {
throw new Error('preAuthenticateToInboxCallback not called')
}

return true
})

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

await client.conversations.newGroup([anotherClient.address])
await client.conversations.sync()
assert(
(await client.conversations.listGroups()).length === 1,
`should have a group size of 1 but was ${
(await client.conversations.listGroups()).length
}`
)

assert(
client.dbPath !== '',
`client dbPath should be set but was ${client.dbPath}`
)
await client.deleteLocalDatabase()
client = await Client.createRandom({
env: 'local',
appVersion: 'Testing/0.0.0',
dbEncryptionKey: new Uint8Array([
233, 120, 198, 96, 154, 65, 132, 17, 132, 96, 250, 40, 103, 35, 125, 64,
166, 83, 208, 224, 254, 44, 205, 227, 175, 49, 234, 129, 74, 252, 135,
145,
]),
})
await client.conversations.sync()
assert(
(await client.conversations.listGroups()).length === 0,
`should have a group size of 0 but was ${
(await client.conversations.listGroups()).length
}`
)

return true
})

test('can make a client with encryption key and database directory', async () => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const dbDirPath = `${RNFS.DocumentDirectoryPath}/xmtp_db`
const directoryExists = await RNFS.exists(dbDirPath)
if (!directoryExists) {
await RNFS.mkdir(dbDirPath)
}
const key = new Uint8Array([
233, 120, 198, 96, 154, 65, 132, 17, 132, 96, 250, 40, 103, 35, 125, 64,
166, 83, 208, 224, 254, 44, 205, 227, 175, 49, 234, 129, 74, 252, 135, 145,
])

const client = await Client.createRandom({
env: 'local',
appVersion: 'Testing/0.0.0',
dbEncryptionKey: key,
dbDirectory: dbDirPath,
})

const anotherClient = await Client.createRandom({
env: 'local',
appVersion: 'Testing/0.0.0',
dbEncryptionKey: key,
})

await client.conversations.newGroup([anotherClient.address])
assert(
(await client.conversations.listGroups()).length === 1,
`should have a group size of 1 but was ${
(await client.conversations.listGroups()).length
}`
)

const clientFromBundle = await Client.build(client.address, {
env: 'local',
appVersion: 'Testing/0.0.0',
dbEncryptionKey: key,
dbDirectory: dbDirPath,
})

assert(
clientFromBundle.address === client.address,
`clients dont match ${client.address} and ${clientFromBundle.address}`
)

assert(
(await clientFromBundle.conversations.listGroups()).length === 1,
`should have a group size of 1 but was ${
(await clientFromBundle.conversations.listGroups()).length
}`
)
return true
})

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

const group = await client.conversations.newGroup([anotherClient.address])
await client.conversations.sync()
assert(
(await client.conversations.listGroups()).length === 1,
`should have a group size of 1 but was ${
(await client.conversations.listGroups()).length
}`
)

await client.dropLocalDatabaseConnection()

try {
await group.send('hi')
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (error) {
await client.reconnectLocalDatabase()
await group.send('hi')
return true
}
throw new Error('should throw when local database not connected')
})

test('can drop client from memory', async () => {
const [client, anotherClient] = await createClients(2)
await client.dropLocalDatabaseConnection()
await anotherClient.dropLocalDatabaseConnection()

await client.reconnectLocalDatabase()
await Client.dropClient(anotherClient.inboxId)
try {
await anotherClient.reconnectLocalDatabase()
return false
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (error) {
// We cannot reconnect anotherClient because it was successfully dropped
return true
}
})

test('can get a inboxId from an address', async () => {
const [alix, bo] = await createClients(2)

const boInboxId = await alix.findInboxIdFromAddress(bo.address)
assert(boInboxId === bo.inboxId, `${boInboxId} should match ${bo.inboxId}`)
return true
})

test('production client creation does not error', async () => {
const key = new Uint8Array([
233, 120, 198, 96, 154, 65, 132, 17, 132, 96, 250, 40, 103, 35, 125, 64,
166, 83, 208, 224, 254, 44, 205, 227, 175, 49, 234, 129, 74, 252, 135, 145,
])

try {
await Client.createRandom({
env: 'production',
appVersion: 'Testing/0.0.0',
dbEncryptionKey: key,
})
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (error) {
throw error
}
return true
})
Loading

0 comments on commit caa0005

Please sign in to comment.