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 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 @@ -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
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 (0.11.2):
- XMTP (0.11.3):
- Connect-Swift (= 0.12.0)
- GzipSwift
- LibXMTP (= 0.5.1-beta0)
Expand All @@ -458,7 +458,7 @@ PODS:
- ExpoModulesCore
- MessagePacker
- secp256k1.swift
- XMTP (= 0.11.2)
- XMTP (= 0.11.3)
- Yoga (1.14.0)

DEPENDENCIES:
Expand Down Expand Up @@ -763,8 +763,8 @@ SPEC CHECKSUMS:
secp256k1.swift: a7e7a214f6db6ce5db32cc6b2b45e5c4dd633634
SwiftProtobuf: 407a385e97fd206c4fbe880cc84123989167e0d1
web3.swift: 2263d1e12e121b2c42ffb63a5a7beb1acaf33959
XMTP: 9c447c0e2df1e7aab5e4ebded23e972259c6e930
XMTPReactNative: 44c04dd6954e4ba370002387b3bbc37ebeaa728f
XMTP: 3e8e649cc8a6cebe4a1a16f6c396a273fefb2662
XMTPReactNative: 602e98fa5dfa0fe17c1bda5a94c7efbaa693c38c
Yoga: e71803b4c1fff832ccf9b92541e00f9b873119b9

PODFILE CHECKSUM: 95d6ace79946933ecf80684613842ee553dd76a2
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