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

List of inbox states for inbox ids #535

Merged
merged 4 commits into from
Nov 13, 2024
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
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.3"
implementation "org.xmtp:android:3.0.4"
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 @@ -274,6 +274,14 @@ class XMTPModule : Module() {
}
}

AsyncFunction("getInboxStates") Coroutine { inboxId: String, refreshFromNetwork: Boolean, inboxIds: List<String> ->
withContext(Dispatchers.IO) {
val client = clients[inboxId] ?: throw XMTPException("No client")
val inboxStates = client.inboxStatesForInboxIds(refreshFromNetwork, inboxIds)
inboxStates.map { InboxStateWrapper.encode(it) }
}
}

Function("preAuthenticateToInboxCallbackCompleted") {
logV("preAuthenticateToInboxCallbackCompleted")
preAuthenticateToInboxCallbackDeferred?.complete(Unit)
Expand Down Expand Up @@ -531,11 +539,22 @@ class XMTPModule : Module() {
}
}

AsyncFunction("findDmByInboxId") Coroutine { inboxId: String, peerInboxId: String ->
withContext(Dispatchers.IO) {
logV("findDmByInboxId")
val client = clients[inboxId] ?: throw XMTPException("No client")
val dm = client.findDmByInboxId(peerInboxId)
dm?.let {
DmWrapper.encode(client, dm)
}
}
}

AsyncFunction("findDmByAddress") Coroutine { inboxId: String, peerAddress: String ->
withContext(Dispatchers.IO) {
logV("findDmByAddress")
val client = clients[inboxId] ?: throw XMTPException("No client")
val dm = client.findDm(peerAddress)
val dm = client.findDmByAddress(peerAddress)
dm?.let {
DmWrapper.encode(client, dm)
}
Expand Down
8 changes: 4 additions & 4 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ PODS:
- GenericJSON (~> 2.0)
- Logging (~> 1.0.0)
- secp256k1.swift (~> 0.1)
- XMTP (3.0.3):
- XMTP (3.0.4):
- Connect-Swift (= 0.12.0)
- GzipSwift
- LibXMTP (= 3.0.0)
Expand All @@ -458,7 +458,7 @@ PODS:
- ExpoModulesCore
- MessagePacker
- secp256k1.swift
- XMTP (= 3.0.3)
- XMTP (= 3.0.4)
- Yoga (1.14.0)

DEPENDENCIES:
Expand Down Expand Up @@ -763,8 +763,8 @@ SPEC CHECKSUMS:
secp256k1.swift: a7e7a214f6db6ce5db32cc6b2b45e5c4dd633634
SwiftProtobuf: 407a385e97fd206c4fbe880cc84123989167e0d1
web3.swift: 2263d1e12e121b2c42ffb63a5a7beb1acaf33959
XMTP: ab14d9456330823f1c52b08ce5281d1e20c03f7f
XMTPReactNative: f7c9dc2eadef5c7d9590d2b7764ab805d16c7a5e
XMTP: dba23b4f3bcee464ca2f7569e1dc05fd9f4c0148
XMTPReactNative: 117d8a00b063044029c11f50320a6b9c8abcdea7
Yoga: e71803b4c1fff832ccf9b92541e00f9b873119b9

PODFILE CHECKSUM: 0e6fe50018f34e575d38dc6a1fdf1f99c9596cdd
Expand Down
16 changes: 16 additions & 0 deletions example/src/tests/clientTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -281,3 +281,19 @@ test('production client creation does not error', async () => {
}
return true
})

test('can find others inbox states', async () => {
const [alix, bo, caro] = await createClients(3)

const states = await alix.inboxStates(true, [bo.inboxId, caro.inboxId])
assert(
states[0].recoveryAddress.toLowerCase === bo.address.toLowerCase,
`addresses dont match ${states[0].recoveryAddress} and ${bo.address}`
)
assert(
states[1].addresses[0].toLowerCase === caro.address.toLowerCase,
`clients dont match ${states[1].addresses[0]} and ${caro.address}`
)

return true
})
15 changes: 15 additions & 0 deletions example/src/tests/conversationTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,21 @@ test('can find a conversation by topic', async () => {
return true
})

test('can find a dm by inbox id', async () => {
const [alixClient, boClient] = await createClients(2)
const alixDm = await alixClient.conversations.findOrCreateDm(boClient.address)

await boClient.conversations.sync()
const boDm = await boClient.conversations.findDmByInboxId(alixClient.inboxId)

assert(
boDm?.id === alixDm.id,
`bo dm id ${boDm?.id} does not match alix dm id ${alixDm.id}`
)

return true
})

test('can find a dm by address', async () => {
const [alixClient, boClient] = await createClients(2)
const alixDm = await alixClient.conversations.findOrCreateDm(boClient.address)
Expand Down
45 changes: 38 additions & 7 deletions ios/XMTPModule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,18 @@ public class XMTPModule: Module {
return try InboxStateWrapper.encode(inboxState)
}

AsyncFunction("getInboxStates") {
(inboxId: String, refreshFromNetwork: Bool, inboxIds: [String])
-> [String] in
guard let client = await clientsManager.getClient(key: inboxId)
else {
throw Error.noClient
}
let inboxStates = try await client.inboxStatesForInboxIds(
refreshFromNetwork: refreshFromNetwork, inboxIds: inboxIds)
return try inboxStates.map { try InboxStateWrapper.encode($0) }
}

Function("preAuthenticateToInboxCallbackCompleted") {
DispatchQueue.global().async {
self.preAuthenticateToInboxCallbackDeferred?.signal()
Expand Down Expand Up @@ -545,13 +557,26 @@ public class XMTPModule: Module {
}
}

AsyncFunction("findDmByInboxId") {
(inboxId: String, peerInboxId: String) -> String? in
guard let client = await clientsManager.getClient(key: inboxId)
else {
throw Error.noClient
}
if let dm = try client.findDmByInboxId(inboxId: peerInboxId) {
return try await DmWrapper.encode(dm, client: client)
} else {
return nil
}
}

AsyncFunction("findDmByAddress") {
(inboxId: String, peerAddress: String) -> String? in
guard let client = await clientsManager.getClient(key: inboxId)
else {
throw Error.noClient
}
if let dm = try await client.findDm(address: peerAddress) {
if let dm = try await client.findDmByAddress(address: peerAddress) {
return try await DmWrapper.encode(dm, client: client)
} else {
return nil
Expand Down Expand Up @@ -1001,7 +1026,8 @@ public class XMTPModule: Module {

AsyncFunction("isAdmin") {
(clientInboxId: String, id: String, inboxId: String) -> Bool in
guard let client = await clientsManager.getClient(key: clientInboxId)
guard
let client = await clientsManager.getClient(key: clientInboxId)
else {
throw Error.noClient
}
Expand All @@ -1014,7 +1040,8 @@ public class XMTPModule: Module {

AsyncFunction("isSuperAdmin") {
(clientInboxId: String, id: String, inboxId: String) -> Bool in
guard let client = await clientsManager.getClient(key: clientInboxId)
guard
let client = await clientsManager.getClient(key: clientInboxId)
else {
throw Error.noClient
}
Expand Down Expand Up @@ -1053,7 +1080,8 @@ public class XMTPModule: Module {

AsyncFunction("addAdmin") {
(clientInboxId: String, id: String, inboxId: String) in
guard let client = await clientsManager.getClient(key: clientInboxId)
guard
let client = await clientsManager.getClient(key: clientInboxId)
else {
throw Error.noClient
}
Expand All @@ -1066,7 +1094,8 @@ public class XMTPModule: Module {

AsyncFunction("addSuperAdmin") {
(clientInboxId: String, id: String, inboxId: String) in
guard let client = await clientsManager.getClient(key: clientInboxId)
guard
let client = await clientsManager.getClient(key: clientInboxId)
else {
throw Error.noClient
}
Expand All @@ -1079,7 +1108,8 @@ public class XMTPModule: Module {

AsyncFunction("removeAdmin") {
(clientInboxId: String, id: String, inboxId: String) in
guard let client = await clientsManager.getClient(key: clientInboxId)
guard
let client = await clientsManager.getClient(key: clientInboxId)
else {
throw Error.noClient
}
Expand All @@ -1092,7 +1122,8 @@ public class XMTPModule: Module {

AsyncFunction("removeSuperAdmin") {
(clientInboxId: String, id: String, inboxId: String) in
guard let client = await clientsManager.getClient(key: clientInboxId)
guard
let client = await clientsManager.getClient(key: clientInboxId)
else {
throw Error.noClient
}
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", "= 3.0.3"
s.dependency "XMTP", "= 3.0.4"
end
26 changes: 26 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,17 @@
return InboxState.from(inboxState)
}

export async function getInboxStates(
inboxId: InboxId,
refreshFromNetwork: boolean,
inboxIds: InboxId[],

Check warning on line 91 in src/index.ts

View workflow job for this annotation

GitHub Actions / lint

Delete `,`
): Promise<InboxState[]> {
const inboxStates = await XMTPModule.getInboxStates(inboxId, refreshFromNetwork, inboxIds)

Check warning on line 93 in src/index.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `inboxId,·refreshFromNetwork,·inboxIds` with `⏎····inboxId,⏎····refreshFromNetwork,⏎····inboxIds⏎··`
return inboxStates.map((json: string) => {
return InboxState.from(json)
})
}

export function preAuthenticateToInboxCallbackCompleted() {
XMTPModule.preAuthenticateToInboxCallbackCompleted()
}
Expand Down Expand Up @@ -374,6 +385,21 @@
}
}

export async function findDmByInboxId<
ContentTypes extends DefaultContentTypes = DefaultContentTypes,
>(
client: Client<ContentTypes>,
peerInboxId: InboxId
): Promise<Dm<ContentTypes> | undefined> {
const json = await XMTPModule.findDmByInboxId(client.inboxId, peerInboxId)
const dm = JSON.parse(json)
if (!dm || Object.keys(dm).length === 0) {
return undefined
}

return new Dm(client, dm)
}

export async function findDmByAddress<
ContentTypes extends DefaultContentTypes = DefaultContentTypes,
>(
Expand Down
13 changes: 12 additions & 1 deletion src/lib/Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@
}

/**
* Make a request for a inboxs state.
* Make a request for your inbox state.
*
* @param {boolean} refreshFromNetwork - If you want to refresh the current state of in the inbox from the network or not.
* @returns {Promise<InboxState>} A Promise resolving to a InboxState.
Expand All @@ -402,6 +402,17 @@
return await XMTPModule.getInboxState(this.inboxId, refreshFromNetwork)
}

/**
* Make a request for a list of inbox states.
*
* @param {InboxId[]} inboxIds - The inboxIds to get the associate inbox states for.
* @param {boolean} refreshFromNetwork - If you want to refresh the current state the inbox from the network or not.
* @returns {Promise<InboxState[]>} A Promise resolving to a list of InboxState.
*/
async inboxStates(refreshFromNetwork: boolean, inboxIds: InboxId[]): Promise<InboxState[]> {

Check warning on line 412 in src/lib/Client.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `refreshFromNetwork:·boolean,·inboxIds:·InboxId[]` with `⏎····refreshFromNetwork:·boolean,⏎····inboxIds:·InboxId[]⏎··`
return await XMTPModule.getInboxStates(this.inboxId, refreshFromNetwork, inboxIds)

Check warning on line 413 in src/lib/Client.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `this.inboxId,·refreshFromNetwork,·inboxIds` with `⏎······this.inboxId,⏎······refreshFromNetwork,⏎······inboxIds⏎····`
}

/**
* Determines whether the current user can send messages to the specified peers over groups.
*
Expand Down
14 changes: 13 additions & 1 deletion src/lib/Conversations.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Client } from './Client'
import { Client, InboxId } from './Client'
import { ConversationVersion } from './Conversation'
import { DecodedMessage } from './DecodedMessage'
import { Dm, DmParams } from './Dm'
Expand Down Expand Up @@ -105,6 +105,18 @@ export default class Conversations<
return await XMTPModule.findGroup(this.client, groupId)
}

/**
* This method returns a Dm by the inboxId if that dm exists in the local database.
* To get the latest list of dms from the network, call sync() first.
*
* @returns {Promise<Dm>} A Promise that resolves to a Dm or undefined if not found.
*/
async findDmByInboxId(
inboxId: InboxId
): Promise<Dm<ContentTypes> | undefined> {
return await XMTPModule.findDmByInboxId(this.client, inboxId)
}

/**
* This method returns a Dm by the address if that dm exists in the local database.
* To get the latest list of dms from the network, call sync() first.
Expand Down
Loading