Skip to content

Commit

Permalink
Merge pull request #405 from xmtp/np/expose-db-directory
Browse files Browse the repository at this point in the history
Add ability to specify dbDirectory
  • Loading branch information
nplasterer committed Jun 4, 2024
2 parents cdaddc0 + e43f806 commit e31f27c
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 27 deletions.
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

0 comments on commit e31f27c

Please sign in to comment.