@@ -66,6 +66,8 @@ data class ClientOptions(
66
66
val preEnableIdentityCallback : PreEventCallback ? = null ,
67
67
val appContext : Context ? = null ,
68
68
val enableAlphaMls : Boolean = false ,
69
+ val dbPath : String? = null ,
70
+ val dbEncryptionKey : ByteArray? = null ,
69
71
) {
70
72
data class Api (
71
73
val env : XMTPEnvironment = XMTPEnvironment .DEV ,
@@ -81,8 +83,8 @@ class Client() {
81
83
lateinit var contacts: Contacts
82
84
lateinit var conversations: Conversations
83
85
var logger: XMTPLogger = XMTPLogger ()
84
- var libXMTPClient: FfiXmtpClient ? = null
85
86
val libXMTPVersion: String = getVersionInfo()
87
+ private var libXMTPClient: FfiXmtpClient ? = null
86
88
87
89
companion object {
88
90
private const val TAG = " Client"
@@ -296,40 +298,52 @@ class Client() {
296
298
if (isAlphaMlsEnabled(options)) {
297
299
val alias = " xmtp-${options!! .api.env} -${accountAddress.lowercase()} "
298
300
299
- val dbDir = File (appContext?.filesDir?.absolutePath, " xmtp_db" )
300
- dbDir.mkdir()
301
- val dbPath: String = dbDir.absolutePath + " /$alias .db3"
302
-
303
- val keyStore = KeyStore .getInstance(" AndroidKeyStore" )
304
- withContext(Dispatchers .IO ) {
305
- keyStore.load(null )
301
+ val dbPath = if (options.dbPath == null ) {
302
+ val dbDir = File (appContext?.filesDir?.absolutePath, " xmtp_db" )
303
+ dbDir.mkdir()
304
+ dbDir.absolutePath + " /$alias .db3"
305
+ } else {
306
+ options.dbPath
306
307
}
307
308
308
- val entry = keyStore.getEntry(alias, null )
309
-
310
- val retrievedKey: SecretKey = if (entry is KeyStore .SecretKeyEntry ) {
311
- entry.secretKey
309
+ val encryptionKey = if (options.dbEncryptionKey == null ) {
310
+ val keyStore = KeyStore .getInstance(" AndroidKeyStore" )
311
+ withContext(Dispatchers .IO ) {
312
+ keyStore.load(null )
313
+ }
314
+
315
+ val entry = keyStore.getEntry(alias, null )
316
+
317
+ val retrievedKey: SecretKey = if (entry is KeyStore .SecretKeyEntry ) {
318
+ entry.secretKey
319
+ } else {
320
+ val keyGenerator =
321
+ KeyGenerator .getInstance(
322
+ KeyProperties .KEY_ALGORITHM_AES ,
323
+ " AndroidKeyStore"
324
+ )
325
+ val keyGenParameterSpec = KeyGenParameterSpec .Builder (
326
+ alias,
327
+ KeyProperties .PURPOSE_ENCRYPT or KeyProperties .PURPOSE_DECRYPT
328
+ ).setBlockModes(KeyProperties .BLOCK_MODE_GCM )
329
+ .setEncryptionPaddings(KeyProperties .ENCRYPTION_PADDING_NONE )
330
+ .setKeySize(256 )
331
+ .build()
332
+
333
+ keyGenerator.init (keyGenParameterSpec)
334
+ keyGenerator.generateKey()
335
+ }
336
+ retrievedKey.encoded
312
337
} else {
313
- val keyGenerator =
314
- KeyGenerator .getInstance(KeyProperties .KEY_ALGORITHM_AES , " AndroidKeyStore" )
315
- val keyGenParameterSpec = KeyGenParameterSpec .Builder (
316
- alias,
317
- KeyProperties .PURPOSE_ENCRYPT or KeyProperties .PURPOSE_DECRYPT
318
- ).setBlockModes(KeyProperties .BLOCK_MODE_GCM )
319
- .setEncryptionPaddings(KeyProperties .ENCRYPTION_PADDING_NONE )
320
- .setKeySize(256 )
321
- .build()
322
-
323
- keyGenerator.init (keyGenParameterSpec)
324
- keyGenerator.generateKey()
338
+ options.dbEncryptionKey
325
339
}
326
340
327
341
createClient(
328
342
logger = logger,
329
343
host = if (options.api.env == XMTPEnvironment .LOCAL ) " http://${options.api.env.getValue()} :5556" else " https://${options.api.env.getValue()} :443" ,
330
344
isSecure = options.api.isSecure,
331
345
db = dbPath,
332
- encryptionKey = retrievedKey.encoded ,
346
+ encryptionKey = encryptionKey ,
333
347
accountAddress = accountAddress,
334
348
legacyIdentitySource = legacyIdentitySource,
335
349
legacySignedPrivateKeyProto = privateKeyBundleV1.toV2().identityKey.toByteArray()
@@ -564,10 +578,12 @@ class Client() {
564
578
return runBlocking { query(Topic .contact(peerAddress)).envelopesList.size > 0 }
565
579
}
566
580
567
- fun canMessage (addresses : List <String >): Boolean {
568
- return runBlocking {
569
- libXMTPClient != null && ! libXMTPClient!! .canMessage(addresses).contains(false )
581
+ fun canMessageV3 (addresses : List <String >): Boolean {
582
+ if (libXMTPClient == null ) return false
583
+ val statuses = runBlocking {
584
+ libXMTPClient!! .canMessage(addresses)
570
585
}
586
+ return ! statuses.contains(false )
571
587
}
572
588
573
589
val privateKeyBundle: PrivateKeyBundle
0 commit comments