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

Exposes client installationId #411

Merged
merged 3 commits into from
Jun 10, 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
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ import kotlin.coroutines.Continuation
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import com.facebook.common.util.Hex
import expo.modules.xmtpreactnativesdk.wrappers.ClientWrapper
import expo.modules.xmtpreactnativesdk.wrappers.MemberWrapper
import org.xmtp.android.library.messages.MessageDeliveryStatus
import org.xmtp.android.library.messages.Topic
Expand Down Expand Up @@ -242,7 +243,7 @@ class XMTPModule : Module() {
clients[address] = client
ContentJson.Companion
signer = null
sendEvent("authed", mapOf("inboxId" to client.inboxId))
sendEvent("authed", ClientWrapper.encodeToObj(client))
}

Function("receiveSignature") { requestID: String, signature: String ->
Expand Down Expand Up @@ -282,10 +283,7 @@ class XMTPModule : Module() {
val randomClient = Client().create(account = privateKey, options = options)
ContentJson.Companion
clients[randomClient.address] = randomClient
mapOf (
"address" to randomClient.address,
"inboxId" to randomClient.inboxId
)
ClientWrapper.encodeToObj(randomClient)
}

AsyncFunction("createFromKeyBundle") { keyBundle: String, environment: String, appVersion: String?, enableAlphaMls: Boolean?, dbEncryptionKey: List<Int>?, dbDirectory: String? ->
Expand Down Expand Up @@ -315,10 +313,7 @@ class XMTPModule : Module() {
val client = Client().buildFromBundle(bundle = bundle, options = options)
ContentJson.Companion
clients[client.address] = client
mapOf (
"address" to client.address,
"inboxId" to client.inboxId
)
ClientWrapper.encodeToObj(client)
} catch (e: Exception) {
throw XMTPException("Failed to create client: $e")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package expo.modules.xmtpreactnativesdk.wrappers

import com.google.gson.GsonBuilder
import org.xmtp.android.library.Client

class ClientWrapper {
companion object {
fun encodeToObj(client: Client): Map<String, String> {
return mapOf(
"inboxId" to client.inboxId,
"address" to client.address,
"installationId" to client.installationId
)
}

fun encode(client: Client): String {
val gson = GsonBuilder().create()
val obj = encodeToObj(client)
return gson.toJson(obj)
}
}
}
10 changes: 10 additions & 0 deletions example/src/tests/groupTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,16 @@ test('can make a MLS V3 client from bundle', async () => {
`clients dont match ${client2.address} and ${client.address}`
)

assert(
client.inboxId === client2.inboxId,
`clients dont match ${client2.inboxId} and ${client.inboxId}`
)

assert(
client.installationId === client2.installationId,
`clients dont match ${client2.installationId} and ${client.installationId}`
)

const randomClient = await Client.createRandom({
env: 'local',
appVersion: 'Testing/0.0.0',
Expand Down
29 changes: 29 additions & 0 deletions ios/Wrappers/ClientWrapper.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// ClientWrapper.swift
// XMTPReactNative
//
// Created by Naomi Plasterer on 6/10/24.
//

import Foundation
import XMTP

// Wrapper around XMTP.Client to allow passing these objects back into react native.
struct ClientWrapper {
static func encodeToObj(_ client: XMTP.Client) throws -> [String: String] {
return [
"inboxId": client.inboxID,
"address": client.address,
"installationId": client.installationID,
]
}

static func encode(_ client: XMTP.Client) throws -> String {
let obj = try encodeToObj(client)
let data = try JSONSerialization.data(withJSONObject: obj)
guard let result = String(data: data, encoding: .utf8) else {
throw WrapperError.encodeError("could not encode client")
}
return result
}
}
2 changes: 1 addition & 1 deletion ios/Wrappers/MemberWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import Foundation
import XMTP

// Wrapper around XMTP.Group to allow passing these objects back into react native.
// Wrapper around XMTP.Member to allow passing these objects back into react native.
struct MemberWrapper {
static func encodeToObj(_ member: XMTP.Member) throws -> [String: Any] {
let permissionString = switch member.permissionLevel {
Expand Down
12 changes: 3 additions & 9 deletions ios/XMTPModule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ public class XMTPModule: Module {
let client = try await XMTP.Client.create(account: signer, options: options)
await clientsManager.updateClient(key: address, client: client)
self.signer = nil
sendEvent("authed", ["inboxId": client.inboxID])
sendEvent("authed", try ClientWrapper.encodeToObj(client))
}

Function("receiveSignature") { (requestID: String, signature: String) in
Expand All @@ -168,10 +168,7 @@ public class XMTPModule: Module {
let client = try await Client.create(account: privateKey, options: options)

await clientsManager.updateClient(key: client.address, client: client)
return [
"address": client.address,
"inboxId": client.inboxID
]
return try ClientWrapper.encodeToObj(client)
}

// Create a client using its serialized key bundle.
Expand All @@ -188,10 +185,7 @@ public class XMTPModule: Module {
let options = createClientConfig(env: environment, appVersion: appVersion, mlsAlpha: enableAlphaMls == true, encryptionKey: encryptionKeyData, dbDirectory: dbDirectory)
let client = try await Client.from(bundle: bundle, options: options)
await clientsManager.updateClient(key: client.address, client: client)
return [
"address": client.address,
"inboxId": client.inboxID
]
return try ClientWrapper.encodeToObj(client)
} catch {
print("ERRO! Failed to create client: \(error)")
throw error
Expand Down
33 changes: 24 additions & 9 deletions src/lib/Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export class Client<
> {
address: string
inboxId: string
installationId: string
conversations: Conversations<ContentTypes>
contacts: Contacts
codecRegistry: { [key: string]: XMTPModule.ContentCodec<unknown> }
Expand Down Expand Up @@ -92,13 +93,23 @@ export class Client<

this.authSubscription = XMTPModule.emitter.addListener(
'authed',
async (message: { inboxId: string }) => {
async (message: {
inboxId: string
address: string
installationId: string
}) => {
this.removeSubscription(enableSubscription)
this.removeSubscription(createSubscription)
this.removeSignSubscription()
this.removeAuthSubscription()
const address = await signer.getAddress()
resolve(new Client(address, message.inboxId, opts?.codecs || []))
resolve(
new Client(
message.address,
message.inboxId,
message.installationId,
opts?.codecs || []
)
)
}
)
await XMTPModule.auth(
Expand Down Expand Up @@ -143,7 +154,7 @@ export class Client<
const options = defaultOptions(opts)
const { enableSubscription, createSubscription } =
this.setupSubscriptions(options)
const addressInboxId = await XMTPModule.createRandom(
const client = await XMTPModule.createRandom(
options.env,
options.appVersion,
Boolean(createSubscription),
Expand All @@ -156,8 +167,9 @@ export class Client<
this.removeSubscription(createSubscription)

return new Client(
addressInboxId['address'],
addressInboxId['inboxId'],
client['address'],
client['inboxId'],
client['installationId'],
opts?.codecs || []
)
}
Expand All @@ -179,7 +191,7 @@ export class Client<
opts?: Partial<ClientOptions> & { codecs?: ContentCodecs }
): Promise<Client<ContentCodecs>> {
const options = defaultOptions(opts)
const addressInboxId = await XMTPModule.createFromKeyBundle(
const client = await XMTPModule.createFromKeyBundle(
keyBundle,
options.env,
options.appVersion,
Expand All @@ -189,8 +201,9 @@ export class Client<
)

return new Client(
addressInboxId['address'],
addressInboxId['inboxId'],
client['address'],
client['inboxId'],
client['installationId'],
opts?.codecs || []
)
}
Expand Down Expand Up @@ -271,10 +284,12 @@ export class Client<
constructor(
address: string,
inboxId: string,
installationId: string,
codecs: XMTPModule.ContentCodec<ContentTypes>[] = []
) {
this.address = address
this.inboxId = inboxId
this.installationId = installationId
this.conversations = new Conversations(this)
this.contacts = new Contacts(this)
this.codecRegistry = {}
Expand Down
Loading