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

Add ability to specify dbDirectory #405

Merged
merged 4 commits into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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 @@ -209,7 +209,7 @@ class XMTPModule : Module() {
//
// Auth functions
//
AsyncFunction("auth") { address: String, environment: String, appVersion: String?, hasCreateIdentityCallback: Boolean?, hasEnableIdentityCallback: Boolean?, enableAlphaMls: Boolean?, dbEncryptionKey: List<Int>? ->
AsyncFunction("auth") { address: String, environment: String, appVersion: String?, hasCreateIdentityCallback: Boolean?, hasEnableIdentityCallback: Boolean?, enableAlphaMls: Boolean?, dbEncryptionKey: List<Int>?, dbDirectory: String? ->
logV("auth")
requireNotProductionEnvForAlphaMLS(enableAlphaMls, environment)
val reactSigner = ReactNativeSigner(module = this@XMTPModule, address = address)
Expand All @@ -236,6 +236,7 @@ class XMTPModule : Module() {
enableAlphaMls = enableAlphaMls == true,
appContext = context,
dbEncryptionKey = encryptionKeyBytes,
dbDirectory = dbDirectory
)
val client = Client().create(account = reactSigner, options = options)
clients[address] = client
Expand All @@ -250,7 +251,7 @@ class XMTPModule : Module() {
}

// Generate a random wallet and set the client to that
AsyncFunction("createRandom") { environment: String, appVersion: String?, hasCreateIdentityCallback: Boolean?, hasEnableIdentityCallback: Boolean?, enableAlphaMls: Boolean?, dbEncryptionKey: List<Int>? ->
AsyncFunction("createRandom") { environment: String, appVersion: String?, hasCreateIdentityCallback: Boolean?, hasEnableIdentityCallback: Boolean?, enableAlphaMls: Boolean?, dbEncryptionKey: List<Int>?, dbDirectory: String? ->
logV("createRandom")
requireNotProductionEnvForAlphaMLS(enableAlphaMls, environment)
val privateKey = PrivateKeyBuilder()
Expand All @@ -276,6 +277,7 @@ class XMTPModule : Module() {
enableAlphaMls = enableAlphaMls == true,
appContext = context,
dbEncryptionKey = encryptionKeyBytes,
dbDirectory = dbDirectory
)
val randomClient = Client().create(account = privateKey, options = options)
ContentJson.Companion
Expand All @@ -286,7 +288,7 @@ class XMTPModule : Module() {
)
}

AsyncFunction("createFromKeyBundle") { keyBundle: String, environment: String, appVersion: String?, enableAlphaMls: Boolean?, dbEncryptionKey: List<Int>? ->
AsyncFunction("createFromKeyBundle") { keyBundle: String, environment: String, appVersion: String?, enableAlphaMls: Boolean?, dbEncryptionKey: List<Int>?, dbDirectory: String? ->
logV("createFromKeyBundle")
requireNotProductionEnvForAlphaMLS(enableAlphaMls, environment)

Expand All @@ -301,6 +303,7 @@ class XMTPModule : Module() {
enableAlphaMls = enableAlphaMls == true,
appContext = context,
dbEncryptionKey = encryptionKeyBytes,
dbDirectory = dbDirectory
)
val bundle =
PrivateKeyOuterClass.PrivateKeyBundle.parseFrom(
Expand Down
54 changes: 54 additions & 0 deletions example/src/tests/groupTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,60 @@ test('can delete a local database', async () => {
return true
})

test('can make a MLS V3 client with encryption key and database directory', async () => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const dbDir = 'xmtp_db'

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',
enableAlphaMls: true,
dbEncryptionKey: key,
dbDirectory: dbDir,
})

const anotherClient = await Client.createRandom({
env: 'local',
appVersion: 'Testing/0.0.0',
enableAlphaMls: true,
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 bundle = await client.exportKeyBundle()
const clientFromBundle = await Client.createFromKeyBundle(bundle, {
env: 'local',
appVersion: 'Testing/0.0.0',
enableAlphaMls: true,
dbEncryptionKey: key,
dbDirectory: dbDir,
})

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)

Expand Down
20 changes: 10 additions & 10 deletions ios/XMTPModule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public class XMTPModule: Module {
//
// Auth functions
//
AsyncFunction("auth") { (address: String, environment: String, appVersion: String?, hasCreateIdentityCallback: Bool?, hasEnableIdentityCallback: Bool?, enableAlphaMls: Bool?, dbEncryptionKey: [UInt8]?) in
AsyncFunction("auth") { (address: String, environment: String, appVersion: String?, hasCreateIdentityCallback: Bool?, hasEnableIdentityCallback: Bool?, enableAlphaMls: Bool?, dbEncryptionKey: [UInt8]?, dbDirectory: String?) in
try requireNotProductionEnvForAlphaMLS(enableAlphaMls: enableAlphaMls, environment: environment)

let signer = ReactNativeSigner(module: self, address: address)
Expand All @@ -138,7 +138,7 @@ public class XMTPModule: Module {
let preEnableIdentityCallback: PreEventCallback? = hasEnableIdentityCallback ?? false ? self.preEnableIdentityCallback : nil
let encryptionKeyData = dbEncryptionKey == nil ? nil : Data(dbEncryptionKey!)

let options = createClientConfig(env: environment, appVersion: appVersion, preEnableIdentityCallback: preEnableIdentityCallback, preCreateIdentityCallback: preCreateIdentityCallback, mlsAlpha: enableAlphaMls == true, encryptionKey: encryptionKeyData)
let options = createClientConfig(env: environment, appVersion: appVersion, preEnableIdentityCallback: preEnableIdentityCallback, preCreateIdentityCallback: preCreateIdentityCallback, mlsAlpha: enableAlphaMls == true, encryptionKey: encryptionKeyData, dbDirectory: dbDirectory)
let client = try await XMTP.Client.create(account: signer, options: options)
await clientsManager.updateClient(key: address, client: client)
self.signer = nil
Expand All @@ -150,7 +150,7 @@ public class XMTPModule: Module {
}

// Generate a random wallet and set the client to that
AsyncFunction("createRandom") { (environment: String, appVersion: String?, hasCreateIdentityCallback: Bool?, hasEnableIdentityCallback: Bool?, enableAlphaMls: Bool?, dbEncryptionKey: [UInt8]?) -> [String: String] in
AsyncFunction("createRandom") { (environment: String, appVersion: String?, hasCreateIdentityCallback: Bool?, hasEnableIdentityCallback: Bool?, enableAlphaMls: Bool?, dbEncryptionKey: [UInt8]?, dbDirectory: String?) -> [String: String] in
try requireNotProductionEnvForAlphaMLS(enableAlphaMls: enableAlphaMls, environment: environment)

let privateKey = try PrivateKey.generate()
Expand All @@ -164,7 +164,7 @@ public class XMTPModule: Module {
let preEnableIdentityCallback: PreEventCallback? = hasEnableIdentityCallback ?? false ? self.preEnableIdentityCallback : nil
let encryptionKeyData = dbEncryptionKey == nil ? nil : Data(dbEncryptionKey!)

let options = createClientConfig(env: environment, appVersion: appVersion, preEnableIdentityCallback: preEnableIdentityCallback, preCreateIdentityCallback: preCreateIdentityCallback, mlsAlpha: enableAlphaMls == true, encryptionKey: encryptionKeyData)
let options = createClientConfig(env: environment, appVersion: appVersion, preEnableIdentityCallback: preEnableIdentityCallback, preCreateIdentityCallback: preCreateIdentityCallback, mlsAlpha: enableAlphaMls == true, encryptionKey: encryptionKeyData, dbDirectory: dbDirectory)
let client = try await Client.create(account: privateKey, options: options)

await clientsManager.updateClient(key: client.address, client: client)
Expand All @@ -175,7 +175,7 @@ public class XMTPModule: Module {
}

// Create a client using its serialized key bundle.
AsyncFunction("createFromKeyBundle") { (keyBundle: String, environment: String, appVersion: String?, enableAlphaMls: Bool?, dbEncryptionKey: [UInt8]?) -> [String: String] in
AsyncFunction("createFromKeyBundle") { (keyBundle: String, environment: String, appVersion: String?, enableAlphaMls: Bool?, dbEncryptionKey: [UInt8]?, dbDirectory: String?) -> [String: String] in
try requireNotProductionEnvForAlphaMLS(enableAlphaMls: enableAlphaMls, environment: environment)

do {
Expand All @@ -185,7 +185,7 @@ public class XMTPModule: Module {
throw Error.invalidKeyBundle
}
let encryptionKeyData = dbEncryptionKey == nil ? nil : Data(dbEncryptionKey!)
let options = createClientConfig(env: environment, appVersion: appVersion, mlsAlpha: enableAlphaMls == true, encryptionKey: encryptionKeyData)
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 [
Expand Down Expand Up @@ -1198,27 +1198,27 @@ public class XMTPModule: Module {
// Helpers
//

func createClientConfig(env: String, appVersion: String?, preEnableIdentityCallback: PreEventCallback? = nil, preCreateIdentityCallback: PreEventCallback? = nil, mlsAlpha: Bool = false, encryptionKey: Data? = nil) -> XMTP.ClientOptions {
func createClientConfig(env: String, appVersion: String?, preEnableIdentityCallback: PreEventCallback? = nil, preCreateIdentityCallback: PreEventCallback? = nil, mlsAlpha: Bool = false, encryptionKey: Data? = nil, dbDirectory: String? = 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, mlsAlpha: mlsAlpha, mlsEncryptionKey: encryptionKey)
), preEnableIdentityCallback: preEnableIdentityCallback, preCreateIdentityCallback: preCreateIdentityCallback, mlsAlpha: mlsAlpha, mlsEncryptionKey: encryptionKey, mlsDbDirectory: dbDirectory)
case "production":
return XMTP.ClientOptions(api: XMTP.ClientOptions.Api(
env: XMTP.XMTPEnvironment.production,
isSecure: true,
appVersion: appVersion
), preEnableIdentityCallback: preEnableIdentityCallback, preCreateIdentityCallback: preCreateIdentityCallback, mlsAlpha: false, mlsEncryptionKey: encryptionKey)
), preEnableIdentityCallback: preEnableIdentityCallback, preCreateIdentityCallback: preCreateIdentityCallback, mlsAlpha: false, mlsEncryptionKey: encryptionKey, mlsDbDirectory: dbDirectory)
default:
return XMTP.ClientOptions(api: XMTP.ClientOptions.Api(
env: XMTP.XMTPEnvironment.dev,
isSecure: true,
appVersion: appVersion
), preEnableIdentityCallback: preEnableIdentityCallback, preCreateIdentityCallback: preCreateIdentityCallback, mlsAlpha: mlsAlpha, mlsEncryptionKey: encryptionKey)
), preEnableIdentityCallback: preEnableIdentityCallback, preCreateIdentityCallback: preCreateIdentityCallback, mlsAlpha: mlsAlpha, mlsEncryptionKey: encryptionKey, mlsDbDirectory: dbDirectory)
}
}

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", "= 0.11.2"
s.dependency "XMTP", "= 0.11.3"
end
18 changes: 12 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ export async function auth(
hasCreateIdentityCallback?: boolean | undefined,
hasEnableIdentityCallback?: boolean | undefined,
enableAlphaMls?: boolean | undefined,
dbEncryptionKey?: Uint8Array | undefined
dbEncryptionKey?: Uint8Array | undefined,
dbDirectory?: string | undefined
) {
return await XMTPModule.auth(
address,
Expand All @@ -73,7 +74,8 @@ export async function auth(
hasCreateIdentityCallback,
hasEnableIdentityCallback,
enableAlphaMls,
dbEncryptionKey ? Array.from(dbEncryptionKey) : undefined
dbEncryptionKey ? Array.from(dbEncryptionKey) : undefined,
dbDirectory
)
}

Expand All @@ -87,15 +89,17 @@ export async function createRandom(
hasCreateIdentityCallback?: boolean | undefined,
hasEnableIdentityCallback?: boolean | undefined,
enableAlphaMls?: boolean | undefined,
dbEncryptionKey?: Uint8Array | undefined
dbEncryptionKey?: Uint8Array | undefined,
dbDirectory?: string | undefined
): Promise<string> {
return await XMTPModule.createRandom(
environment,
appVersion,
hasCreateIdentityCallback,
hasEnableIdentityCallback,
enableAlphaMls,
dbEncryptionKey ? Array.from(dbEncryptionKey) : undefined
dbEncryptionKey ? Array.from(dbEncryptionKey) : undefined,
dbDirectory
)
}

Expand All @@ -104,14 +108,16 @@ export async function createFromKeyBundle(
environment: 'local' | 'dev' | 'production',
appVersion?: string | undefined,
enableAlphaMls?: boolean | undefined,
dbEncryptionKey?: Uint8Array | undefined
dbEncryptionKey?: Uint8Array | undefined,
dbDirectory?: string | undefined
): Promise<string> {
return await XMTPModule.createFromKeyBundle(
keyBundle,
environment,
appVersion,
enableAlphaMls,
dbEncryptionKey ? Array.from(dbEncryptionKey) : undefined
dbEncryptionKey ? Array.from(dbEncryptionKey) : undefined,
dbDirectory
)
}

Expand Down
14 changes: 11 additions & 3 deletions src/lib/Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ export class Client<
Boolean(createSubscription),
Boolean(enableSubscription),
Boolean(options.enableAlphaMls),
options.dbEncryptionKey
options.dbEncryptionKey,
options.dbDirectory
)
})().catch((error) => {
console.error('ERROR in create: ', error)
Expand Down Expand Up @@ -148,7 +149,8 @@ export class Client<
Boolean(createSubscription),
Boolean(enableSubscription),
Boolean(options.enableAlphaMls),
options.dbEncryptionKey
options.dbEncryptionKey,
options.dbDirectory
)
this.removeSubscription(enableSubscription)
this.removeSubscription(createSubscription)
Expand Down Expand Up @@ -182,7 +184,8 @@ export class Client<
options.env,
options.appVersion,
Boolean(options.enableAlphaMls),
options.dbEncryptionKey
options.dbEncryptionKey,
options.dbDirectory
)

return new Client(
Expand Down Expand Up @@ -468,6 +471,10 @@ export type ClientOptions = {
* OPTIONAL specify the encryption key for the database. The encryption key must be exactly 32 bytes.
*/
dbEncryptionKey?: Uint8Array
/**
* OPTIONAL specify the XMTP managed database directory
*/
dbDirectory?: string
}

export type KeyType = {
Expand All @@ -485,6 +492,7 @@ export function defaultOptions(opts?: Partial<ClientOptions>): ClientOptions {
env: 'dev',
enableAlphaMls: false,
dbEncryptionKey: undefined,
dbDirectory: undefined,
}

return { ..._defaultOptions, ...opts } as ClientOptions
Expand Down
Loading