Skip to content

Commit

Permalink
Merge pull request #177 from xmtp/feat/pre-callback-events
Browse files Browse the repository at this point in the history
feat: add preCreateIdentityCallback & preEnableIdentityCallback
  • Loading branch information
nplasterer authored Dec 16, 2023
2 parents 9e6c8d2 + ca6e140 commit c51dbba
Show file tree
Hide file tree
Showing 8 changed files with 220 additions and 52 deletions.
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ repositories {
dependencies {
implementation project(':expo-modules-core')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
implementation "org.xmtp:android:0.6.20"
implementation "org.xmtp:android:0.7.0"
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 @@ -27,6 +27,7 @@ import org.xmtp.android.library.Client
import org.xmtp.android.library.ClientOptions
import org.xmtp.android.library.ConsentState
import org.xmtp.android.library.Conversation
import org.xmtp.android.library.PreEventCallback
import org.xmtp.android.library.PreparedMessage
import org.xmtp.android.library.SendOptions
import org.xmtp.android.library.SigningKey
Expand Down Expand Up @@ -128,7 +129,14 @@ class XMTPModule : Module() {

override fun definition() = ModuleDefinition {
Name("XMTP")
Events("sign", "authed", "conversation", "message")
Events(
"sign",
"authed",
"conversation",
"message",
"preEnableIdentityCallback",
"preCreateIdentityCallback"
)

Function("address") { clientAddress: String ->
logV("address")
Expand All @@ -139,11 +147,19 @@ class XMTPModule : Module() {
//
// Auth functions
//
AsyncFunction("auth") { address: String, environment: String, appVersion: String? ->
AsyncFunction("auth") { address: String, environment: String, appVersion: String?, hasCreateIdentityCallback: Boolean?, hasEnableIdentityCallback: Boolean? ->
logV("auth")
val reactSigner = ReactNativeSigner(module = this@XMTPModule, address = address)
signer = reactSigner
val options = ClientOptions(api = apiEnvironments(environment, appVersion))
val preCreateIdentityCallback: PreEventCallback? =
preCreateIdentityCallback.takeIf { hasCreateIdentityCallback == true }
val preEnableIdentityCallback: PreEventCallback? =
preEnableIdentityCallback.takeIf { hasEnableIdentityCallback == true }
val options = ClientOptions(
api = apiEnvironments(environment, appVersion),
preCreateIdentityCallback = preCreateIdentityCallback,
preEnableIdentityCallback = preEnableIdentityCallback
)
clients[address] = Client().create(account = reactSigner, options = options)
ContentJson.Companion
signer = null
Expand All @@ -156,10 +172,19 @@ class XMTPModule : Module() {
}

// Generate a random wallet and set the client to that
AsyncFunction("createRandom") { environment: String, appVersion: String? ->
AsyncFunction("createRandom") { environment: String, appVersion: String?, hasCreateIdentityCallback: Boolean?, hasEnableIdentityCallback: Boolean? ->
logV("createRandom")
val privateKey = PrivateKeyBuilder()
val options = ClientOptions(api = apiEnvironments(environment, appVersion))
val preCreateIdentityCallback: PreEventCallback? =
preCreateIdentityCallback.takeIf { hasCreateIdentityCallback == true }
val preEnableIdentityCallback: PreEventCallback? =
preEnableIdentityCallback.takeIf { hasEnableIdentityCallback == true }

val options = ClientOptions(
api = apiEnvironments(environment, appVersion),
preCreateIdentityCallback = preCreateIdentityCallback,
preEnableIdentityCallback = preEnableIdentityCallback
)
val randomClient = Client().create(account = privateKey, options = options)
ContentJson.Companion
clients[randomClient.address] = randomClient
Expand Down Expand Up @@ -687,6 +712,14 @@ class XMTPModule : Module() {
Log.v("XMTPModule", msg)
}
}

private val preEnableIdentityCallback: suspend () -> Unit = {
sendEvent("preEnableIdentityCallback")
}

private val preCreateIdentityCallback: suspend () -> Unit = {
sendEvent("preCreateIdentityCallback")
}
}


10 changes: 5 additions & 5 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -411,15 +411,15 @@ PODS:
- GenericJSON (~> 2.0)
- Logging (~> 1.0.0)
- secp256k1.swift (~> 0.1)
- XMTP (0.7.2-alpha0):
- XMTP (0.7.3-alpha0):
- Connect-Swift (= 0.3.0)
- GzipSwift
- web3.swift
- XMTPRust (= 0.3.7-beta0)
- XMTPReactNative (0.1.0):
- ExpoModulesCore
- MessagePacker
- XMTP (= 0.7.2-alpha0)
- XMTP (= 0.7.3-alpha0)
- XMTPRust (0.3.7-beta0)
- Yoga (1.14.0)

Expand Down Expand Up @@ -668,11 +668,11 @@ SPEC CHECKSUMS:
secp256k1.swift: a7e7a214f6db6ce5db32cc6b2b45e5c4dd633634
SwiftProtobuf: b02b5075dcf60c9f5f403000b3b0c202a11b6ae1
web3.swift: 2263d1e12e121b2c42ffb63a5a7beb1acaf33959
XMTP: 4930b80dc99a6a8ebcf1f292a162c1f316f78c50
XMTPReactNative: 68c723488857950d10fc8ee969de0baae8f9b2ca
XMTP: dc02c96b475e326a4a7b3d3912cc45cf3527bd0b
XMTPReactNative: 5c1111c5bd3456e75b3fa67d1ddccabb7a01df11
XMTPRust: 8848a2ba761b2c961d666632f2ad27d1082faa93
Yoga: e71803b4c1fff832ccf9b92541e00f9b873119b9

PODFILE CHECKSUM: 522d88edc2d5fac4825e60a121c24abc18983367

COCOAPODS: 1.14.3
COCOAPODS: 1.13.0
34 changes: 34 additions & 0 deletions example/src/tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -751,3 +751,37 @@ test('register and use custom content types', async () => {

return true
})

test('calls preCreateIdentityCallback when supplied', async () => {
let isCallbackCalled = false
const preCreateIdentityCallback = () => {
isCallbackCalled = true
}
await Client.createRandom({
env: 'local',
preCreateIdentityCallback,
})

if (!isCallbackCalled) {
throw new Error('preCreateIdentityCallback not called')
}

return isCallbackCalled
})

test('calls preEnableIdentityCallback when supplied', async () => {
let isCallbackCalled = false
const preEnableIdentityCallback = () => {
isCallbackCalled = true
}
await Client.createRandom({
env: 'local',
preEnableIdentityCallback,
})

if (!isCallbackCalled) {
throw new Error('preEnableIdentityCallback not called')
}

return isCallbackCalled
})
77 changes: 45 additions & 32 deletions ios/XMTPModule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public class XMTPModule: Module {
public func definition() -> ModuleDefinition {
Name("XMTP")

Events("sign", "authed", "conversation", "message")
Events("sign", "authed", "conversation", "message", "preEnableIdentityCallback", "preCreateIdentityCallback")

AsyncFunction("address") { (clientAddress: String) -> String in
if let client = await clientsManager.getClient(key: clientAddress) {
Expand All @@ -64,10 +64,12 @@ public class XMTPModule: Module {
//
// Auth functions
//
AsyncFunction("auth") { (address: String, environment: String, appVersion: String?) in
AsyncFunction("auth") { (address: String, environment: String, appVersion: String?, hasCreateIdentityCallback: Bool?, hasEnableIdentityCallback: Bool?) in
let signer = ReactNativeSigner(module: self, address: address)
self.signer = signer
let options = createClientConfig(env: environment, appVersion: appVersion)
let preCreateIdentityCallback: PreEventCallback? = hasCreateIdentityCallback ?? false ? self.preCreateIdentityCallback : nil
let preEnableIdentityCallback: PreEventCallback? = hasEnableIdentityCallback ?? false ? self.preEnableIdentityCallback : nil
let options = createClientConfig(env: environment, appVersion: appVersion, preEnableIdentityCallback: preEnableIdentityCallback, preCreateIdentityCallback: preCreateIdentityCallback)
try await clientsManager.updateClient(key: address, client: await XMTP.Client.create(account: signer, options: options))
self.signer = nil
sendEvent("authed")
Expand All @@ -78,9 +80,12 @@ public class XMTPModule: Module {
}

// Generate a random wallet and set the client to that
AsyncFunction("createRandom") { (environment: String, appVersion: String?) -> String in
AsyncFunction("createRandom") { (environment: String, appVersion: String?, hasCreateIdentityCallback: Bool?, hasEnableIdentityCallback: Bool?) -> String in
let privateKey = try PrivateKey.generate()
let options = createClientConfig(env: environment, appVersion: appVersion)
let preCreateIdentityCallback: PreEventCallback? = hasCreateIdentityCallback ?? false ? self.preCreateIdentityCallback : nil
let preEnableIdentityCallback: PreEventCallback? = hasEnableIdentityCallback ?? false ? self.preEnableIdentityCallback : nil

let options = createClientConfig(env: environment, appVersion: appVersion, preEnableIdentityCallback: preEnableIdentityCallback, preCreateIdentityCallback: preCreateIdentityCallback)
let client = try await Client.create(account: privateKey, options: options)

await clientsManager.updateClient(key: client.address, client: client)
Expand Down Expand Up @@ -146,14 +151,14 @@ public class XMTPModule: Module {
return try await client.canMessage(peerAddress)
}

AsyncFunction("staticCanMessage") { (peerAddress: String, environment: String, appVersion: String?) -> Bool in
do {
let options = createClientConfig(env: environment, appVersion: appVersion)
return try await XMTP.Client.canMessage(peerAddress, options: options)
} catch {
throw Error.noClient
}
}
AsyncFunction("staticCanMessage") { (peerAddress: String, environment: String, appVersion: String?) -> Bool in
do {
let options = createClientConfig(env: environment, appVersion: appVersion)
return try await XMTP.Client.canMessage(peerAddress, options: options)
} catch {
throw Error.noClient
}
}

AsyncFunction("encryptAttachment") { (clientAddress: String, fileJson: String) -> String in
guard let client = await clientsManager.getClient(key: clientAddress) else {
Expand Down Expand Up @@ -506,56 +511,56 @@ public class XMTPModule: Module {
throw Error.noClient
}
let consentList = try await client.contacts.refreshConsentList()
return try consentList.entries.compactMap { entry in
try ConsentWrapper.encode(entry.value)
}

return try consentList.entries.compactMap { entry in
try ConsentWrapper.encode(entry.value)
}
}

AsyncFunction("conversationConsentState") { (clientAddress: String, conversationTopic: String) -> String in
guard let conversation = try await findConversation(clientAddress: clientAddress, topic: conversationTopic) else {
throw Error.conversationNotFound(conversationTopic)
}
return ConsentWrapper.consentStateToString(state: await conversation.consentState())
return ConsentWrapper.consentStateToString(state: await conversation.consentState())
}

AsyncFunction("consentList") { (clientAddress: String) -> [String] in
guard let client = await clientsManager.getClient(key: clientAddress) else {
throw Error.noClient
}
let entries = await client.contacts.consentList.entries
return try entries.compactMap { entry in
try ConsentWrapper.encode(entry.value)
}
}
AsyncFunction("consentList") { (clientAddress: String) -> [String] in
guard let client = await clientsManager.getClient(key: clientAddress) else {
throw Error.noClient
}
let entries = await client.contacts.consentList.entries

return try entries.compactMap { entry in
try ConsentWrapper.encode(entry.value)
}
}
}

//
// Helpers
//

func createClientConfig(env: String, appVersion: String?) -> XMTP.ClientOptions {
func createClientConfig(env: String, appVersion: String?, preEnableIdentityCallback: PreEventCallback? = nil, preCreateIdentityCallback: PreEventCallback? = nil) -> XMTP.ClientOptions {
// Ensure that all codecs have been registered.
switch env {
case "local":
return XMTP.ClientOptions(api: XMTP.ClientOptions.Api(
env: XMTP.XMTPEnvironment.local,
isSecure: false,
appVersion: appVersion
))
), preEnableIdentityCallback: preEnableIdentityCallback, preCreateIdentityCallback: preCreateIdentityCallback)
case "production":
return XMTP.ClientOptions(api: XMTP.ClientOptions.Api(
env: XMTP.XMTPEnvironment.production,
isSecure: true,
appVersion: appVersion
))
), preEnableIdentityCallback: preEnableIdentityCallback, preCreateIdentityCallback: preCreateIdentityCallback)
default:
return XMTP.ClientOptions(api: XMTP.ClientOptions.Api(
env: XMTP.XMTPEnvironment.dev,
isSecure: true,
appVersion: appVersion
))
), preEnableIdentityCallback: preEnableIdentityCallback, preCreateIdentityCallback: preCreateIdentityCallback)
}
}

Expand Down Expand Up @@ -665,4 +670,12 @@ public class XMTPModule: Module {
func getConversationsKey(clientAddress: String) -> String {
return "conversations:\(clientAddress)"
}

func preEnableIdentityCallback() {
sendEvent("preEnableIdentityCallback")
}

func preCreateIdentityCallback() {
sendEvent("preCreateIdentityCallback")
}
}
2 changes: 1 addition & 1 deletion ios/XMTPReactNative.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@ Pod::Spec.new do |s|

s.source_files = "**/*.{h,m,swift}"
s.dependency "MessagePacker"
s.dependency "XMTP", "= 0.7.2-alpha0"
s.dependency "XMTP", "= 0.7.3-alpha0"
end
23 changes: 19 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,17 @@ export function address(): string {
export async function auth(
address: string,
environment: 'local' | 'dev' | 'production',
appVersion?: string | undefined
appVersion?: string | undefined,
hasCreateIdentityCallback?: boolean | undefined,
hasEnableIdentityCallback?: boolean | undefined
) {
return await XMTPModule.auth(address, environment, appVersion)
return await XMTPModule.auth(
address,
environment,
appVersion,
hasCreateIdentityCallback,
hasEnableIdentityCallback
)
}

export async function receiveSignature(requestID: string, signature: string) {
Expand All @@ -44,9 +52,16 @@ export async function receiveSignature(requestID: string, signature: string) {

export async function createRandom(
environment: 'local' | 'dev' | 'production',
appVersion?: string | undefined
appVersion?: string | undefined,
hasCreateIdentityCallback?: boolean | undefined,
hasEnableIdentityCallback?: boolean | undefined
): Promise<string> {
return await XMTPModule.createRandom(environment, appVersion)
return await XMTPModule.createRandom(
environment,
appVersion,
hasCreateIdentityCallback,
hasEnableIdentityCallback
)
}

export async function createFromKeyBundle(
Expand Down
Loading

0 comments on commit c51dbba

Please sign in to comment.