diff --git a/android/src/main/java/expo/modules/xmtpreactnativesdk/XMTPModule.kt b/android/src/main/java/expo/modules/xmtpreactnativesdk/XMTPModule.kt index d3b97ef05..f65d89480 100644 --- a/android/src/main/java/expo/modules/xmtpreactnativesdk/XMTPModule.kt +++ b/android/src/main/java/expo/modules/xmtpreactnativesdk/XMTPModule.kt @@ -170,7 +170,7 @@ class XMTPModule : Module() { // // Auth functions // - AsyncFunction("auth") { address: String, environment: String, appVersion: String?, hasCreateIdentityCallback: Boolean?, hasEnableIdentityCallback: Boolean?, enableAlphaMls: Boolean? -> + AsyncFunction("auth") { address: String, environment: String, appVersion: String?, hasCreateIdentityCallback: Boolean?, hasEnableIdentityCallback: Boolean?, enableAlphaMls: Boolean?, dbEncryptionKey: List?, dbPath: String? -> logV("auth") requireNotProductionEnvForAlphaMLS(enableAlphaMls, environment) val reactSigner = ReactNativeSigner(module = this@XMTPModule, address = address) @@ -185,13 +185,19 @@ class XMTPModule : Module() { val preEnableIdentityCallback: PreEventCallback? = preEnableIdentityCallback.takeIf { hasEnableIdentityCallback == true } val context = if (enableAlphaMls == true) context else null + val encryptionKeyBytes = + dbEncryptionKey?.foldIndexed(ByteArray(dbEncryptionKey.size)) { i, a, v -> + a.apply { set(i, v.toByte()) } + } val options = ClientOptions( api = apiEnvironments(environment, appVersion), preCreateIdentityCallback = preCreateIdentityCallback, preEnableIdentityCallback = preEnableIdentityCallback, enableAlphaMls = enableAlphaMls == true, - appContext = context + appContext = context, + dbEncryptionKey = encryptionKeyBytes, + dbPath = dbPath ) clients[address] = Client().create(account = reactSigner, options = options) ContentJson.Companion @@ -205,7 +211,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? -> + AsyncFunction("createRandom") { environment: String, appVersion: String?, hasCreateIdentityCallback: Boolean?, hasEnableIdentityCallback: Boolean?, enableAlphaMls: Boolean?, dbEncryptionKey: List?, dbPath: String? -> logV("createRandom") requireNotProductionEnvForAlphaMLS(enableAlphaMls, environment) val privateKey = PrivateKeyBuilder() @@ -219,13 +225,19 @@ class XMTPModule : Module() { val preEnableIdentityCallback: PreEventCallback? = preEnableIdentityCallback.takeIf { hasEnableIdentityCallback == true } val context = if (enableAlphaMls == true) context else null + val encryptionKeyBytes = + dbEncryptionKey?.foldIndexed(ByteArray(dbEncryptionKey.size)) { i, a, v -> + a.apply { set(i, v.toByte()) } + } val options = ClientOptions( api = apiEnvironments(environment, appVersion), preCreateIdentityCallback = preCreateIdentityCallback, preEnableIdentityCallback = preEnableIdentityCallback, enableAlphaMls = enableAlphaMls == true, - appContext = context + appContext = context, + dbEncryptionKey = encryptionKeyBytes, + dbPath = dbPath ) val randomClient = Client().create(account = privateKey, options = options) ContentJson.Companion @@ -233,15 +245,22 @@ class XMTPModule : Module() { randomClient.address } - AsyncFunction("createFromKeyBundle") { keyBundle: String, environment: String, appVersion: String?, enableAlphaMls: Boolean? -> + AsyncFunction("createFromKeyBundle") { keyBundle: String, environment: String, appVersion: String?, enableAlphaMls: Boolean?, dbEncryptionKey: List?, dbPath: String? -> logV("createFromKeyBundle") requireNotProductionEnvForAlphaMLS(enableAlphaMls, environment) + try { val context = if (enableAlphaMls == true) context else null + val encryptionKeyBytes = + dbEncryptionKey?.foldIndexed(ByteArray(dbEncryptionKey.size)) { i, a, v -> + a.apply { set(i, v.toByte()) } + } val options = ClientOptions( api = apiEnvironments(environment, appVersion), enableAlphaMls = enableAlphaMls == true, - appContext = context + appContext = context, + dbEncryptionKey = encryptionKeyBytes, + dbPath = dbPath ) val bundle = PrivateKeyOuterClass.PrivateKeyBundle.parseFrom( diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 98318b310..4b388425e 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -344,6 +344,8 @@ PODS: - RCTTypeSafety - React-Core - ReactCommon/turbomodule/core + - react-native-sqlite-storage (6.0.1): + - React-Core - React-perflogger (0.71.14) - React-RCTActionSheet (0.71.14): - React-Core/RCTActionSheetHeaders (= 0.71.14) @@ -430,6 +432,8 @@ PODS: - React-perflogger (= 0.71.14) - RNCAsyncStorage (1.21.0): - React-Core + - RNFS (2.20.0): + - React-Core - RNScreens (3.20.0): - React-Core - React-RCTImage @@ -502,6 +506,7 @@ DEPENDENCIES: - react-native-quick-crypto (from `../node_modules/react-native-quick-crypto`) - react-native-randombytes (from `../node_modules/react-native-randombytes`) - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) + - react-native-sqlite-storage (from `../node_modules/react-native-sqlite-storage`) - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`) - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) @@ -516,6 +521,7 @@ DEPENDENCIES: - React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`) - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) - "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)" + - RNFS (from `../node_modules/react-native-fs`) - RNScreens (from `../node_modules/react-native-screens`) - RNSVG (from `../node_modules/react-native-svg`) - XMTPReactNative (from `../../ios`) @@ -630,6 +636,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-randombytes" react-native-safe-area-context: :path: "../node_modules/react-native-safe-area-context" + react-native-sqlite-storage: + :path: "../node_modules/react-native-sqlite-storage" React-perflogger: :path: "../node_modules/react-native/ReactCommon/reactperflogger" React-RCTActionSheet: @@ -658,6 +666,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon" RNCAsyncStorage: :path: "../node_modules/@react-native-async-storage/async-storage" + RNFS: + :path: "../node_modules/react-native-fs" RNScreens: :path: "../node_modules/react-native-screens" RNSVG: @@ -725,6 +735,7 @@ SPEC CHECKSUMS: react-native-quick-crypto: 455c1b411db006dba1026a30681ececb19180187 react-native-randombytes: 421f1c7d48c0af8dbcd471b0324393ebf8fe7846 react-native-safe-area-context: 39c2d8be3328df5d437ac1700f4f3a4f75716acc + react-native-sqlite-storage: f6d515e1c446d1e6d026aa5352908a25d4de3261 React-perflogger: 4987ad83731c23d11813c84263963b0d3028c966 React-RCTActionSheet: 5ad952b2a9740d87a5bd77280c4bc23f6f89ea0c React-RCTAnimation: d2de22af3f536cc80bb5b3918e1a455114d1b985 @@ -739,6 +750,7 @@ SPEC CHECKSUMS: React-runtimeexecutor: ffe826b7b1cfbc32a35ed5b64d5886c0ff75f501 ReactCommon: 7f3dd5e98a9ec627c6b03d26c062bf37ea9fc888 RNCAsyncStorage: 618d03a5f52fbccb3d7010076bc54712844c18ef + RNFS: 4ac0f0ea233904cb798630b3c077808c06931688 RNScreens: 218801c16a2782546d30bd2026bb625c0302d70f RNSVG: d00c8f91c3cbf6d476451313a18f04d220d4f396 secp256k1.swift: a7e7a214f6db6ce5db32cc6b2b45e5c4dd633634 diff --git a/example/package.json b/example/package.json index f2c12fab1..43266045a 100644 --- a/example/package.json +++ b/example/package.json @@ -30,6 +30,7 @@ "react-native-config": "^1.5.1", "react-native-crypto": "^2.2.0", "react-native-encrypted-storage": "^4.0.3", + "react-native-fs": "^2.20.0", "react-native-get-random-values": "^1.10.0", "react-native-mmkv": "^2.8.0", "react-native-modal-selector": "^2.1.2", @@ -38,6 +39,7 @@ "react-native-randombytes": "^3.6.1", "react-native-safe-area-context": "4.5.0", "react-native-screens": "~3.20.0", + "react-native-sqlite-storage": "^6.0.1", "react-native-svg": "^13.9.0", "react-native-url-polyfill": "^2.0.0", "react-query": "^3.39.3", diff --git a/example/src/tests/groupTests.ts b/example/src/tests/groupTests.ts index ee6e57ec9..7a3b0b58a 100644 --- a/example/src/tests/groupTests.ts +++ b/example/src/tests/groupTests.ts @@ -1,3 +1,4 @@ +import RNFS from 'react-native-fs' import { DecodedMessage } from 'xmtp-react-native-sdk/lib/DecodedMessage' import { Test, assert, delayToPropogate, isIos } from './tests' @@ -26,6 +27,61 @@ test('can make a MLS V3 client', async () => { return true }) +test('can make a MLS V3 client with encryption key and database path', async () => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const dbDirPath = `${RNFS.DocumentDirectoryPath}/xmtp_db` + const directoryExists = await RNFS.exists(dbDirPath) + if (!directoryExists) { + await RNFS.mkdir(dbDirPath) + } + const timestamp = Date.now().toString() + const dbPath = `${dbDirPath}/myCoolApp${timestamp}.db3` + + 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, + dbPath, + }) + + const anotherClient = await Client.createRandom({ + env: 'local', + appVersion: 'Testing/0.0.0', + enableAlphaMls: true, + }) + + 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, + dbPath, + }) + + 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 make a MLS V3 client from bundle', async () => { const client = await Client.createRandom({ env: 'local', diff --git a/example/yarn.lock b/example/yarn.lock index 94a1c57ee..e2a9579bf 100644 --- a/example/yarn.lock +++ b/example/yarn.lock @@ -7325,7 +7325,7 @@ balanced-match@^1.0.0: resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base-64@0.1.0: +base-64@0.1.0, base-64@^0.1.0: version "0.1.0" resolved "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz" integrity sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA== @@ -13432,6 +13432,14 @@ react-native-encrypted-storage@^4.0.3: resolved "https://registry.npmjs.org/react-native-encrypted-storage/-/react-native-encrypted-storage-4.0.3.tgz" integrity sha512-0pJA4Aj2S1PIJEbU7pN/Qvf7JIJx3hFywx+i+bLHtgK0/6Zryf1V2xVsWcrD50dfiu3jY1eN2gesQ5osGxE7jA== +react-native-fs@^2.20.0: + version "2.20.0" + resolved "https://registry.yarnpkg.com/react-native-fs/-/react-native-fs-2.20.0.tgz#05a9362b473bfc0910772c0acbb73a78dbc810f6" + integrity sha512-VkTBzs7fIDUiy/XajOSNk0XazFE9l+QlMAce7lGuebZcag5CnjszB+u4BdqzwaQOdcYb5wsJIsqq4kxInIRpJQ== + dependencies: + base-64 "^0.1.0" + utf8 "^3.0.0" + react-native-get-random-values@^1.10.0, react-native-get-random-values@^1.4.0: version "1.10.0" resolved "https://registry.npmjs.org/react-native-get-random-values/-/react-native-get-random-values-1.10.0.tgz" @@ -13531,6 +13539,11 @@ react-native-screens@~3.20.0: react-freeze "^1.0.0" warn-once "^0.1.0" +react-native-sqlite-storage@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/react-native-sqlite-storage/-/react-native-sqlite-storage-6.0.1.tgz#ce6a6b852f07abbea68658d5363818c8bef45dfb" + integrity sha512-1tDFjrint6X6qSYKf3gDyz+XB+X79jfiL6xTugKHPRtF0WvqMtVgdLuNqZunIXjNEvNtNVEbXaeZ6MsguFu00A== + react-native-svg@^13.9.0: version "13.14.0" resolved "https://registry.npmjs.org/react-native-svg/-/react-native-svg-13.14.0.tgz" @@ -15273,7 +15286,7 @@ utf-8-validate@^5.0.2: dependencies: node-gyp-build "^4.3.0" -utf8@3.0.0: +utf8@3.0.0, utf8@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz" integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== diff --git a/ios/XMTPModule.swift b/ios/XMTPModule.swift index b89a19ac1..f2dc78c38 100644 --- a/ios/XMTPModule.swift +++ b/ios/XMTPModule.swift @@ -78,7 +78,7 @@ public class XMTPModule: Module { // // Auth functions // - AsyncFunction("auth") { (address: String, environment: String, appVersion: String?, hasCreateIdentityCallback: Bool?, hasEnableIdentityCallback: Bool?, enableAlphaMls: Bool?) in + AsyncFunction("auth") { (address: String, environment: String, appVersion: String?, hasCreateIdentityCallback: Bool?, hasEnableIdentityCallback: Bool?, enableAlphaMls: Bool?, dbEncryptionKey: [UInt8]?, dbPath: String?) in try requireNotProductionEnvForAlphaMLS(enableAlphaMls: enableAlphaMls, environment: environment) let signer = ReactNativeSigner(module: self, address: address) @@ -91,7 +91,9 @@ public class XMTPModule: Module { } 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, mlsAlpha: enableAlphaMls == true) + let encryptionKeyData = dbEncryptionKey == nil ? nil : Data(dbEncryptionKey!) + + let options = createClientConfig(env: environment, appVersion: appVersion, preEnableIdentityCallback: preEnableIdentityCallback, preCreateIdentityCallback: preCreateIdentityCallback, mlsAlpha: enableAlphaMls == true, encryptionKey: encryptionKeyData, dbPath: dbPath) try await clientsManager.updateClient(key: address, client: await XMTP.Client.create(account: signer, options: options)) self.signer = nil sendEvent("authed") @@ -102,7 +104,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?) -> String in + AsyncFunction("createRandom") { (environment: String, appVersion: String?, hasCreateIdentityCallback: Bool?, hasEnableIdentityCallback: Bool?, enableAlphaMls: Bool?, dbEncryptionKey: [UInt8]?, dbPath: String?) -> String in try requireNotProductionEnvForAlphaMLS(enableAlphaMls: enableAlphaMls, environment: environment) let privateKey = try PrivateKey.generate() @@ -114,8 +116,9 @@ public class XMTPModule: Module { } let preCreateIdentityCallback: PreEventCallback? = hasCreateIdentityCallback ?? false ? self.preCreateIdentityCallback : nil 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) + let options = createClientConfig(env: environment, appVersion: appVersion, preEnableIdentityCallback: preEnableIdentityCallback, preCreateIdentityCallback: preCreateIdentityCallback, mlsAlpha: enableAlphaMls == true, encryptionKey: encryptionKeyData, dbPath: dbPath) let client = try await Client.create(account: privateKey, options: options) await clientsManager.updateClient(key: client.address, client: client) @@ -123,7 +126,7 @@ public class XMTPModule: Module { } // Create a client using its serialized key bundle. - AsyncFunction("createFromKeyBundle") { (keyBundle: String, environment: String, appVersion: String?, enableAlphaMls: Bool?) -> String in + AsyncFunction("createFromKeyBundle") { (keyBundle: String, environment: String, appVersion: String?, enableAlphaMls: Bool?, dbEncryptionKey: [UInt8]?, dbPath: String?) -> String in try requireNotProductionEnvForAlphaMLS(enableAlphaMls: enableAlphaMls, environment: environment) do { @@ -132,8 +135,8 @@ public class XMTPModule: Module { else { throw Error.invalidKeyBundle } - - let options = createClientConfig(env: environment, appVersion: appVersion, mlsAlpha: enableAlphaMls == true) + let encryptionKeyData = dbEncryptionKey == nil ? nil : Data(dbEncryptionKey!) + let options = createClientConfig(env: environment, appVersion: appVersion, mlsAlpha: enableAlphaMls == true, encryptionKey: encryptionKeyData, dbPath: dbPath) let client = try await Client.from(bundle: bundle, options: options) await clientsManager.updateClient(key: client.address, client: client) return client.address @@ -847,7 +850,7 @@ public class XMTPModule: Module { // Helpers // - func createClientConfig(env: String, appVersion: String?, preEnableIdentityCallback: PreEventCallback? = nil, preCreateIdentityCallback: PreEventCallback? = nil, mlsAlpha: Bool = false) -> XMTP.ClientOptions { + func createClientConfig(env: String, appVersion: String?, preEnableIdentityCallback: PreEventCallback? = nil, preCreateIdentityCallback: PreEventCallback? = nil, mlsAlpha: Bool = false, encryptionKey: Data? = nil, dbPath: String? = nil) -> XMTP.ClientOptions { // Ensure that all codecs have been registered. switch env { case "local": @@ -855,19 +858,19 @@ public class XMTPModule: Module { env: XMTP.XMTPEnvironment.local, isSecure: false, appVersion: appVersion - ), preEnableIdentityCallback: preEnableIdentityCallback, preCreateIdentityCallback: preCreateIdentityCallback, mlsAlpha: mlsAlpha) + ), preEnableIdentityCallback: preEnableIdentityCallback, preCreateIdentityCallback: preCreateIdentityCallback, mlsAlpha: mlsAlpha, mlsEncryptionKey: encryptionKey, mlsDbPath: dbPath) case "production": return XMTP.ClientOptions(api: XMTP.ClientOptions.Api( env: XMTP.XMTPEnvironment.production, isSecure: true, appVersion: appVersion - ), preEnableIdentityCallback: preEnableIdentityCallback, preCreateIdentityCallback: preCreateIdentityCallback, mlsAlpha: false) + ), preEnableIdentityCallback: preEnableIdentityCallback, preCreateIdentityCallback: preCreateIdentityCallback, mlsAlpha: false, mlsEncryptionKey: encryptionKey, mlsDbPath: dbPath) default: return XMTP.ClientOptions(api: XMTP.ClientOptions.Api( env: XMTP.XMTPEnvironment.dev, isSecure: true, appVersion: appVersion - ), preEnableIdentityCallback: preEnableIdentityCallback, preCreateIdentityCallback: preCreateIdentityCallback, mlsAlpha: mlsAlpha) + ), preEnableIdentityCallback: preEnableIdentityCallback, preCreateIdentityCallback: preCreateIdentityCallback, mlsAlpha: mlsAlpha, mlsEncryptionKey: encryptionKey, mlsDbPath: dbPath) } } diff --git a/src/index.ts b/src/index.ts index e9b4721fd..2a682b8c7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -45,7 +45,9 @@ export async function auth( appVersion?: string | undefined, hasCreateIdentityCallback?: boolean | undefined, hasEnableIdentityCallback?: boolean | undefined, - enableAlphaMls?: boolean | undefined + enableAlphaMls?: boolean | undefined, + dbEncryptionKey?: Uint8Array | undefined, + dbPath?: string | undefined ) { return await XMTPModule.auth( address, @@ -53,7 +55,9 @@ export async function auth( appVersion, hasCreateIdentityCallback, hasEnableIdentityCallback, - enableAlphaMls + enableAlphaMls, + dbEncryptionKey ? Array.from(dbEncryptionKey) : undefined, + dbPath ) } @@ -66,14 +70,18 @@ export async function createRandom( appVersion?: string | undefined, hasCreateIdentityCallback?: boolean | undefined, hasEnableIdentityCallback?: boolean | undefined, - enableAlphaMls?: boolean | undefined + enableAlphaMls?: boolean | undefined, + dbEncryptionKey?: Uint8Array | undefined, + dbPath?: string | undefined ): Promise { return await XMTPModule.createRandom( environment, appVersion, hasCreateIdentityCallback, hasEnableIdentityCallback, - enableAlphaMls + enableAlphaMls, + dbEncryptionKey ? Array.from(dbEncryptionKey) : undefined, + dbPath ) } @@ -81,13 +89,17 @@ export async function createFromKeyBundle( keyBundle: string, environment: 'local' | 'dev' | 'production', appVersion?: string | undefined, - enableAlphaMls?: boolean | undefined + enableAlphaMls?: boolean | undefined, + dbEncryptionKey?: Uint8Array | undefined, + dbPath?: string | undefined ): Promise { return await XMTPModule.createFromKeyBundle( keyBundle, environment, appVersion, - enableAlphaMls + enableAlphaMls, + dbEncryptionKey ? Array.from(dbEncryptionKey) : undefined, + dbPath ) } diff --git a/src/lib/Client.ts b/src/lib/Client.ts index c3d1b9b77..048a58fd2 100644 --- a/src/lib/Client.ts +++ b/src/lib/Client.ts @@ -107,7 +107,9 @@ export class Client< options.appVersion, Boolean(createSubscription), Boolean(enableSubscription), - Boolean(options.enableAlphaMls) + Boolean(options.enableAlphaMls), + options.dbEncryptionKey, + options.dbPath ) })() }) @@ -144,7 +146,9 @@ export class Client< options.appVersion, Boolean(createSubscription), Boolean(enableSubscription), - Boolean(options.enableAlphaMls) + Boolean(options.enableAlphaMls), + options.dbEncryptionKey, + options.dbPath ) this.removeSubscription(enableSubscription) this.removeSubscription(createSubscription) @@ -173,7 +177,9 @@ export class Client< keyBundle, options.env, options.appVersion, - Boolean(options.enableAlphaMls) + Boolean(options.enableAlphaMls), + options.dbEncryptionKey, + options.dbPath ) return new Client(address, opts?.codecs || []) } @@ -427,6 +433,14 @@ export type ClientOptions = { * Specify whether to enable Alpha version of MLS (Group Chat) */ enableAlphaMls?: boolean + /** + * OPTIONAL specify the encryption key for the database + */ + dbEncryptionKey?: Uint8Array + /** + * OPTIONAL specify the XMTP managed database path + */ + dbPath?: string } export type KeyType = { @@ -443,6 +457,8 @@ export function defaultOptions(opts?: Partial): ClientOptions { const _defaultOptions: ClientOptions = { env: 'dev', enableAlphaMls: false, + dbEncryptionKey: undefined, + dbPath: undefined, } return { ..._defaultOptions, ...opts } as ClientOptions