From 5be1bd21cb8e50f24895548e3447b40cd04156d5 Mon Sep 17 00:00:00 2001 From: Matt Jones <885417+jonesmac@users.noreply.github.com> Date: Mon, 18 Nov 2024 16:03:11 -0500 Subject: [PATCH 01/20] change PrefsDataStore to AccountPrefsDataStore --- .../xyo/client/datastore/AccountDataStore.kt | 8 +++---- .../AccountPrefsDataStoreSerializer.kt | 21 +++++++++++++++++++ .../datastore/AccountPrefsRepository.kt | 21 +++++++++---------- .../datastore/PrefsDataStoreSerializer.kt | 21 ------------------- ...tore.proto => AccountPrefsDataStore.proto} | 3 ++- 5 files changed, 37 insertions(+), 37 deletions(-) create mode 100644 sdk/src/main/java/network/xyo/client/datastore/AccountPrefsDataStoreSerializer.kt delete mode 100644 sdk/src/main/java/network/xyo/client/datastore/PrefsDataStoreSerializer.kt rename sdk/src/main/java/network/xyo/client/proto/{PrefsDataStore.proto => AccountPrefsDataStore.proto} (84%) diff --git a/sdk/src/main/java/network/xyo/client/datastore/AccountDataStore.kt b/sdk/src/main/java/network/xyo/client/datastore/AccountDataStore.kt index c9620ce..9048da1 100644 --- a/sdk/src/main/java/network/xyo/client/datastore/AccountDataStore.kt +++ b/sdk/src/main/java/network/xyo/client/datastore/AccountDataStore.kt @@ -7,22 +7,22 @@ import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import network.xyo.client.settings.DefaultXyoSdkSettings -import network.xyo.data.PrefsDataStoreProtos.PrefsDataStore +import network.xyo.data.PrefsDataStoreProtos.AccountPrefsDataStore import java.io.File val defaults = DefaultXyoSdkSettings() -fun Context.xyoAccountDataStore(name: String?, path: String?): DataStore { +fun Context.xyoAccountDataStore(name: String?, path: String?): DataStore { val resolvedName = name ?: defaults.accountPreferences.fileName val resolvedPath = path ?: defaults.accountPreferences.storagePath val dataStoreFile = File(filesDir, "$resolvedPath/$resolvedName") return MultiProcessDataStoreFactory.create( - serializer = PrefsDataStoreSerializer, + serializer = AccountPrefsDataStoreSerializer, produceFile = { dataStoreFile }, corruptionHandler = ReplaceFileCorruptionHandler( - produceNewData = { PrefsDataStore.getDefaultInstance() } + produceNewData = { AccountPrefsDataStore.getDefaultInstance() } ), scope = CoroutineScope(Dispatchers.IO) ) diff --git a/sdk/src/main/java/network/xyo/client/datastore/AccountPrefsDataStoreSerializer.kt b/sdk/src/main/java/network/xyo/client/datastore/AccountPrefsDataStoreSerializer.kt new file mode 100644 index 0000000..c666e4c --- /dev/null +++ b/sdk/src/main/java/network/xyo/client/datastore/AccountPrefsDataStoreSerializer.kt @@ -0,0 +1,21 @@ +package network.xyo.client.datastore + +import androidx.datastore.core.CorruptionException +import androidx.datastore.core.Serializer +import com.google.protobuf.InvalidProtocolBufferException +import network.xyo.data.PrefsDataStoreProtos.AccountPrefsDataStore +import java.io.InputStream +import java.io.OutputStream + +object AccountPrefsDataStoreSerializer : Serializer { + override val defaultValue: AccountPrefsDataStore = AccountPrefsDataStore.getDefaultInstance() + override suspend fun readFrom(input: InputStream): AccountPrefsDataStore { + try { + return AccountPrefsDataStore.parseFrom(input) + } catch (exception: InvalidProtocolBufferException) { + throw CorruptionException("Cannot read proto.", exception) + } + } + + override suspend fun writeTo(t: AccountPrefsDataStore, output: OutputStream) = t.writeTo(output) +} \ No newline at end of file diff --git a/sdk/src/main/java/network/xyo/client/datastore/AccountPrefsRepository.kt b/sdk/src/main/java/network/xyo/client/datastore/AccountPrefsRepository.kt index 9d1e2db..1cfe0b9 100644 --- a/sdk/src/main/java/network/xyo/client/datastore/AccountPrefsRepository.kt +++ b/sdk/src/main/java/network/xyo/client/datastore/AccountPrefsRepository.kt @@ -5,7 +5,7 @@ import android.os.Build import android.util.Log import androidx.annotation.RequiresApi import androidx.datastore.core.DataStore -import network.xyo.data.PrefsDataStoreProtos.PrefsDataStore +import network.xyo.data.PrefsDataStoreProtos.AccountPrefsDataStore import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch import network.xyo.client.account.Account @@ -19,7 +19,7 @@ class AccountPrefsRepository(context: Context, private val _accountPreferences: // This should set the proper paths for the prefs datastore each time the the class is instantiated @Volatile - private var prefsDataStore: DataStore = appContext.xyoAccountDataStore( + private var accountPrefsDataStore: DataStore = appContext.xyoAccountDataStore( accountPreferences.fileName, accountPreferences.storagePath ) @@ -38,7 +38,7 @@ class AccountPrefsRepository(context: Context, private val _accountPreferences: suspend fun initializeAccount(account: AccountInstance): AccountInstance? { var updatedKey: String? = null val job = xyoScope.launch { - val savedKey = prefsDataStore.data.first().accountKey + val savedKey = accountPrefsDataStore.data.first().accountKey if (savedKey.isNullOrEmpty()) { // no saved key so save the passed in one updatedKey = null @@ -59,7 +59,7 @@ class AccountPrefsRepository(context: Context, private val _accountPreferences: @OptIn(ExperimentalStdlibApi::class) @RequiresApi(Build.VERSION_CODES.M) private suspend fun getAccountKey(): String { - val savedKey = prefsDataStore.data.first().accountKey + val savedKey = accountPrefsDataStore.data.first().accountKey return if (savedKey.isEmpty()) { val newAccount: AccountInstance = Account.random() setAccountKey(newAccount.privateKey.toHexString()) @@ -69,31 +69,30 @@ class AccountPrefsRepository(context: Context, private val _accountPreferences: } } - private suspend fun setAccountKey(accountKey: String): DataStore { + private suspend fun setAccountKey(accountKey: String): DataStore { val job = xyoScope.launch { - this@AccountPrefsRepository.prefsDataStore.updateData { currentPrefs -> + this@AccountPrefsRepository.accountPrefsDataStore.updateData { currentPrefs -> currentPrefs.toBuilder() .setAccountKey(accountKey) .build() } } job.join() - return prefsDataStore + return accountPrefsDataStore } - suspend fun clearSavedAccountKey(): DataStore { + suspend fun clearSavedAccountKey(): DataStore { val job = xyoScope.launch { - this@AccountPrefsRepository.prefsDataStore.updateData { currentPrefs -> + this@AccountPrefsRepository.accountPrefsDataStore.updateData { currentPrefs -> currentPrefs.toBuilder() .setAccountKey("") .build() } } job.join() - return prefsDataStore + return accountPrefsDataStore } - // Define the singleton instance within a companion object companion object { @Volatile private var INSTANCE: AccountPrefsRepository? = null diff --git a/sdk/src/main/java/network/xyo/client/datastore/PrefsDataStoreSerializer.kt b/sdk/src/main/java/network/xyo/client/datastore/PrefsDataStoreSerializer.kt deleted file mode 100644 index 674b248..0000000 --- a/sdk/src/main/java/network/xyo/client/datastore/PrefsDataStoreSerializer.kt +++ /dev/null @@ -1,21 +0,0 @@ -package network.xyo.client.datastore - -import androidx.datastore.core.CorruptionException -import androidx.datastore.core.Serializer -import com.google.protobuf.InvalidProtocolBufferException -import network.xyo.data.PrefsDataStoreProtos.PrefsDataStore -import java.io.InputStream -import java.io.OutputStream - -object PrefsDataStoreSerializer : Serializer { - override val defaultValue: PrefsDataStore = PrefsDataStore.getDefaultInstance() - override suspend fun readFrom(input: InputStream): PrefsDataStore { - try { - return PrefsDataStore.parseFrom(input) - } catch (exception: InvalidProtocolBufferException) { - throw CorruptionException("Cannot read proto.", exception) - } - } - - override suspend fun writeTo(t: PrefsDataStore, output: OutputStream) = t.writeTo(output) -} \ No newline at end of file diff --git a/sdk/src/main/java/network/xyo/client/proto/PrefsDataStore.proto b/sdk/src/main/java/network/xyo/client/proto/AccountPrefsDataStore.proto similarity index 84% rename from sdk/src/main/java/network/xyo/client/proto/PrefsDataStore.proto rename to sdk/src/main/java/network/xyo/client/proto/AccountPrefsDataStore.proto index d1fa4ed..823cb47 100644 --- a/sdk/src/main/java/network/xyo/client/proto/PrefsDataStore.proto +++ b/sdk/src/main/java/network/xyo/client/proto/AccountPrefsDataStore.proto @@ -5,6 +5,7 @@ package network.xyo.proto; option java_package = "network.xyo.data"; option java_outer_classname = "PrefsDataStoreProtos"; -message PrefsDataStore { +message AccountPrefsDataStore { optional string account_key = 1; + } \ No newline at end of file From 48434f52d6834281d3308d9dcf240f6f588df168 Mon Sep 17 00:00:00 2001 From: Matt Jones <885417+jonesmac@users.noreply.github.com> Date: Mon, 18 Nov 2024 16:05:42 -0500 Subject: [PATCH 02/20] Assume Previous Hash Store methods will use Coroutines --- .../network/xyo/client/account/model/PreviousHashStore.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/src/main/java/network/xyo/client/account/model/PreviousHashStore.kt b/sdk/src/main/java/network/xyo/client/account/model/PreviousHashStore.kt index 3c39d6b..5b0b628 100644 --- a/sdk/src/main/java/network/xyo/client/account/model/PreviousHashStore.kt +++ b/sdk/src/main/java/network/xyo/client/account/model/PreviousHashStore.kt @@ -1,7 +1,7 @@ package network.xyo.client.account.model interface PreviousHashStore { - fun getItem(address: ByteArray): ByteArray? - fun removeItem(address: ByteArray) - fun setItem(address: ByteArray, previousHash: ByteArray) + suspend fun getItem(address: ByteArray): ByteArray? + suspend fun removeItem(address: ByteArray) + suspend fun setItem(address: ByteArray, previousHash: ByteArray) } \ No newline at end of file From dd2c2938888cde2bf477455e21b27ff802575e60 Mon Sep 17 00:00:00 2001 From: Matt Jones <885417+jonesmac@users.noreply.github.com> Date: Mon, 18 Nov 2024 16:17:46 -0500 Subject: [PATCH 03/20] Update Generated AccountPrefs protobuf file --- .../main/java/network/xyo/client/datastore/AccountDataStore.kt | 2 +- .../xyo/client/datastore/AccountPrefsDataStoreSerializer.kt | 2 +- .../java/network/xyo/client/datastore/AccountPrefsRepository.kt | 2 +- .../java/network/xyo/client/proto/AccountPrefsDataStore.proto | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sdk/src/main/java/network/xyo/client/datastore/AccountDataStore.kt b/sdk/src/main/java/network/xyo/client/datastore/AccountDataStore.kt index 9048da1..37551e2 100644 --- a/sdk/src/main/java/network/xyo/client/datastore/AccountDataStore.kt +++ b/sdk/src/main/java/network/xyo/client/datastore/AccountDataStore.kt @@ -7,7 +7,7 @@ import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import network.xyo.client.settings.DefaultXyoSdkSettings -import network.xyo.data.PrefsDataStoreProtos.AccountPrefsDataStore +import network.xyo.data.AccountPrefsDataStoreProtos.AccountPrefsDataStore import java.io.File val defaults = DefaultXyoSdkSettings() diff --git a/sdk/src/main/java/network/xyo/client/datastore/AccountPrefsDataStoreSerializer.kt b/sdk/src/main/java/network/xyo/client/datastore/AccountPrefsDataStoreSerializer.kt index c666e4c..d4fbc92 100644 --- a/sdk/src/main/java/network/xyo/client/datastore/AccountPrefsDataStoreSerializer.kt +++ b/sdk/src/main/java/network/xyo/client/datastore/AccountPrefsDataStoreSerializer.kt @@ -3,7 +3,7 @@ package network.xyo.client.datastore import androidx.datastore.core.CorruptionException import androidx.datastore.core.Serializer import com.google.protobuf.InvalidProtocolBufferException -import network.xyo.data.PrefsDataStoreProtos.AccountPrefsDataStore +import network.xyo.data.AccountPrefsDataStoreProtos.AccountPrefsDataStore import java.io.InputStream import java.io.OutputStream diff --git a/sdk/src/main/java/network/xyo/client/datastore/AccountPrefsRepository.kt b/sdk/src/main/java/network/xyo/client/datastore/AccountPrefsRepository.kt index 1cfe0b9..185fe54 100644 --- a/sdk/src/main/java/network/xyo/client/datastore/AccountPrefsRepository.kt +++ b/sdk/src/main/java/network/xyo/client/datastore/AccountPrefsRepository.kt @@ -5,7 +5,7 @@ import android.os.Build import android.util.Log import androidx.annotation.RequiresApi import androidx.datastore.core.DataStore -import network.xyo.data.PrefsDataStoreProtos.AccountPrefsDataStore +import network.xyo.data.AccountPrefsDataStoreProtos.AccountPrefsDataStore import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch import network.xyo.client.account.Account diff --git a/sdk/src/main/java/network/xyo/client/proto/AccountPrefsDataStore.proto b/sdk/src/main/java/network/xyo/client/proto/AccountPrefsDataStore.proto index 823cb47..835a491 100644 --- a/sdk/src/main/java/network/xyo/client/proto/AccountPrefsDataStore.proto +++ b/sdk/src/main/java/network/xyo/client/proto/AccountPrefsDataStore.proto @@ -3,7 +3,7 @@ syntax = "proto2"; package network.xyo.proto; option java_package = "network.xyo.data"; -option java_outer_classname = "PrefsDataStoreProtos"; +option java_outer_classname = "AccountPrefsDataStoreProtos"; message AccountPrefsDataStore { optional string account_key = 1; From 51a5691a5df36a64ea3d25e255603b956cad907b Mon Sep 17 00:00:00 2001 From: Matt Jones <885417+jonesmac@users.noreply.github.com> Date: Mon, 18 Nov 2024 16:18:18 -0500 Subject: [PATCH 04/20] add Previous Hash Protobuf --- .../xyo/client/proto/PreviousHashPrefsDataStore.proto | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 sdk/src/main/java/network/xyo/client/proto/PreviousHashPrefsDataStore.proto diff --git a/sdk/src/main/java/network/xyo/client/proto/PreviousHashPrefsDataStore.proto b/sdk/src/main/java/network/xyo/client/proto/PreviousHashPrefsDataStore.proto new file mode 100644 index 0000000..4253a81 --- /dev/null +++ b/sdk/src/main/java/network/xyo/client/proto/PreviousHashPrefsDataStore.proto @@ -0,0 +1,10 @@ +syntax = "proto2"; + +package network.xyo.proto; + +option java_package = "network.xyo.data"; +option java_outer_classname = "PreviousHashPrefsDataStoreProtos"; + +message PreviousHashPrefsDataStore { + map address_to_hash = 1; +} \ No newline at end of file From d1510a24d16e3b49ec4a4033c31af89cf40d9e5a Mon Sep 17 00:00:00 2001 From: Matt Jones <885417+jonesmac@users.noreply.github.com> Date: Mon, 18 Nov 2024 16:28:17 -0500 Subject: [PATCH 05/20] use new defaults import --- .../xyo/client/datastore/AccountDataStore.kt | 8 +++---- .../network/xyo/client/settings/Defaults.kt | 21 +++++++++++++++---- .../xyo/client/settings/SettingsInterface.kt | 9 ++++++-- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/sdk/src/main/java/network/xyo/client/datastore/AccountDataStore.kt b/sdk/src/main/java/network/xyo/client/datastore/AccountDataStore.kt index 37551e2..2fe96db 100644 --- a/sdk/src/main/java/network/xyo/client/datastore/AccountDataStore.kt +++ b/sdk/src/main/java/network/xyo/client/datastore/AccountDataStore.kt @@ -6,15 +6,13 @@ import androidx.datastore.core.MultiProcessDataStoreFactory import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers -import network.xyo.client.settings.DefaultXyoSdkSettings +import network.xyo.client.settings.defaultXyoSdkSettings import network.xyo.data.AccountPrefsDataStoreProtos.AccountPrefsDataStore import java.io.File -val defaults = DefaultXyoSdkSettings() - fun Context.xyoAccountDataStore(name: String?, path: String?): DataStore { - val resolvedName = name ?: defaults.accountPreferences.fileName - val resolvedPath = path ?: defaults.accountPreferences.storagePath + val resolvedName = name ?: defaultXyoSdkSettings.accountPreferences.fileName + val resolvedPath = path ?: defaultXyoSdkSettings.accountPreferences.storagePath val dataStoreFile = File(filesDir, "$resolvedPath/$resolvedName") diff --git a/sdk/src/main/java/network/xyo/client/settings/Defaults.kt b/sdk/src/main/java/network/xyo/client/settings/Defaults.kt index 9b0560c..392b873 100644 --- a/sdk/src/main/java/network/xyo/client/settings/Defaults.kt +++ b/sdk/src/main/java/network/xyo/client/settings/Defaults.kt @@ -1,10 +1,23 @@ package network.xyo.client.settings +const val DefaultStoragePath = "__xyo-client-sdk__" +const val DefaultFileName = "network-xyo-sdk-prefs" + open class DefaultXyoSdkSettings(): SettingsInterface { override val accountPreferences: AccountPreferences = DefaultAccountPreferences() + override val previousHashStorePreferences: PreviousHashStorePreferences = DefaultPreviousHashStorePreferences() +} + +open class DefaultStorageLocationPreferences: StorageLocationPreference { + override val storagePath = DefaultStoragePath + override val fileName = DefaultFileName +} + +open class DefaultAccountPreferences: DefaultStorageLocationPreferences(), AccountPreferences { + override val fileName = "network-xyo-sdk-account-prefs" +} +open class DefaultPreviousHashStorePreferences: DefaultStorageLocationPreferences(), PreviousHashStorePreferences { + override val fileName = "network-xyo-sdk-previous-hash-store-prefs" } -open class DefaultAccountPreferences: AccountPreferences { - override val fileName = "network-xyo-sdk-prefs" - override val storagePath = "__xyo-client-sdk__" -} \ No newline at end of file +val defaultXyoSdkSettings = DefaultXyoSdkSettings() \ No newline at end of file diff --git a/sdk/src/main/java/network/xyo/client/settings/SettingsInterface.kt b/sdk/src/main/java/network/xyo/client/settings/SettingsInterface.kt index 85b62ee..60361b6 100644 --- a/sdk/src/main/java/network/xyo/client/settings/SettingsInterface.kt +++ b/sdk/src/main/java/network/xyo/client/settings/SettingsInterface.kt @@ -2,9 +2,14 @@ package network.xyo.client.settings interface SettingsInterface { val accountPreferences: AccountPreferences + val previousHashStorePreferences: PreviousHashStorePreferences } -interface AccountPreferences { +interface StorageLocationPreference { val fileName: String? val storagePath: String? -} \ No newline at end of file +} + +interface AccountPreferences: StorageLocationPreference {} + +interface PreviousHashStorePreferences: StorageLocationPreference {} \ No newline at end of file From 302a5a1ab53390cfcee60b80db8a645c33190d85 Mon Sep 17 00:00:00 2001 From: Matt Jones <885417+jonesmac@users.noreply.github.com> Date: Mon, 18 Nov 2024 16:29:50 -0500 Subject: [PATCH 06/20] nest accounts DataStore files in new package --- .../java/network/xyo/client/AccountPrefsRepositoryTest.kt | 2 +- .../xyo/client/datastore/{ => accounts}/AccountDataStore.kt | 2 +- .../datastore/{ => accounts}/AccountPrefsDataStoreSerializer.kt | 2 +- .../client/datastore/{ => accounts}/AccountPrefsRepository.kt | 2 +- sdk/src/main/java/network/xyo/client/settings/XyoSdk.kt | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) rename sdk/src/main/java/network/xyo/client/datastore/{ => accounts}/AccountDataStore.kt (96%) rename sdk/src/main/java/network/xyo/client/datastore/{ => accounts}/AccountPrefsDataStoreSerializer.kt (94%) rename sdk/src/main/java/network/xyo/client/datastore/{ => accounts}/AccountPrefsRepository.kt (98%) diff --git a/sdk/src/androidTest/java/network/xyo/client/AccountPrefsRepositoryTest.kt b/sdk/src/androidTest/java/network/xyo/client/AccountPrefsRepositoryTest.kt index 8641834..c686451 100644 --- a/sdk/src/androidTest/java/network/xyo/client/AccountPrefsRepositoryTest.kt +++ b/sdk/src/androidTest/java/network/xyo/client/AccountPrefsRepositoryTest.kt @@ -5,7 +5,7 @@ import androidx.test.platform.app.InstrumentationRegistry import kotlinx.coroutines.runBlocking import network.xyo.client.account.Account import network.xyo.client.boundwitness.XyoBoundWitnessBuilder -import network.xyo.client.datastore.AccountPrefsRepository +import network.xyo.client.datastore.accounts.AccountPrefsRepository import network.xyo.client.settings.AccountPreferences import network.xyo.client.witness.system.info.XyoSystemInfoWitness import org.junit.Before diff --git a/sdk/src/main/java/network/xyo/client/datastore/AccountDataStore.kt b/sdk/src/main/java/network/xyo/client/datastore/accounts/AccountDataStore.kt similarity index 96% rename from sdk/src/main/java/network/xyo/client/datastore/AccountDataStore.kt rename to sdk/src/main/java/network/xyo/client/datastore/accounts/AccountDataStore.kt index 2fe96db..9dc42ec 100644 --- a/sdk/src/main/java/network/xyo/client/datastore/AccountDataStore.kt +++ b/sdk/src/main/java/network/xyo/client/datastore/accounts/AccountDataStore.kt @@ -1,4 +1,4 @@ -package network.xyo.client.datastore +package network.xyo.client.datastore.accounts import android.content.Context import androidx.datastore.core.DataStore diff --git a/sdk/src/main/java/network/xyo/client/datastore/AccountPrefsDataStoreSerializer.kt b/sdk/src/main/java/network/xyo/client/datastore/accounts/AccountPrefsDataStoreSerializer.kt similarity index 94% rename from sdk/src/main/java/network/xyo/client/datastore/AccountPrefsDataStoreSerializer.kt rename to sdk/src/main/java/network/xyo/client/datastore/accounts/AccountPrefsDataStoreSerializer.kt index d4fbc92..a9f4b80 100644 --- a/sdk/src/main/java/network/xyo/client/datastore/AccountPrefsDataStoreSerializer.kt +++ b/sdk/src/main/java/network/xyo/client/datastore/accounts/AccountPrefsDataStoreSerializer.kt @@ -1,4 +1,4 @@ -package network.xyo.client.datastore +package network.xyo.client.datastore.accounts import androidx.datastore.core.CorruptionException import androidx.datastore.core.Serializer diff --git a/sdk/src/main/java/network/xyo/client/datastore/AccountPrefsRepository.kt b/sdk/src/main/java/network/xyo/client/datastore/accounts/AccountPrefsRepository.kt similarity index 98% rename from sdk/src/main/java/network/xyo/client/datastore/AccountPrefsRepository.kt rename to sdk/src/main/java/network/xyo/client/datastore/accounts/AccountPrefsRepository.kt index 185fe54..3a257a5 100644 --- a/sdk/src/main/java/network/xyo/client/datastore/AccountPrefsRepository.kt +++ b/sdk/src/main/java/network/xyo/client/datastore/accounts/AccountPrefsRepository.kt @@ -1,4 +1,4 @@ -package network.xyo.client.datastore +package network.xyo.client.datastore.accounts import android.content.Context import android.os.Build diff --git a/sdk/src/main/java/network/xyo/client/settings/XyoSdk.kt b/sdk/src/main/java/network/xyo/client/settings/XyoSdk.kt index 3407655..ef8afd8 100644 --- a/sdk/src/main/java/network/xyo/client/settings/XyoSdk.kt +++ b/sdk/src/main/java/network/xyo/client/settings/XyoSdk.kt @@ -4,7 +4,7 @@ import android.content.Context import android.os.Build import androidx.annotation.RequiresApi import network.xyo.client.account.model.AccountInstance -import network.xyo.client.datastore.AccountPrefsRepository +import network.xyo.client.datastore.accounts.AccountPrefsRepository class XyoSdk private constructor(context: Context, val settings: SettingsInterface) { private val appContext = context.applicationContext From 8a69580f561dd829d2cfd8aef1c4660d9de3bab7 Mon Sep 17 00:00:00 2001 From: Matt Jones <885417+jonesmac@users.noreply.github.com> Date: Mon, 18 Nov 2024 16:32:58 -0500 Subject: [PATCH 07/20] fix import --- .../xyo/client/datastore/accounts/AccountPrefsRepository.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sdk/src/main/java/network/xyo/client/datastore/accounts/AccountPrefsRepository.kt b/sdk/src/main/java/network/xyo/client/datastore/accounts/AccountPrefsRepository.kt index 3a257a5..d17835f 100644 --- a/sdk/src/main/java/network/xyo/client/datastore/accounts/AccountPrefsRepository.kt +++ b/sdk/src/main/java/network/xyo/client/datastore/accounts/AccountPrefsRepository.kt @@ -11,10 +11,11 @@ import kotlinx.coroutines.launch import network.xyo.client.account.Account import network.xyo.client.account.model.AccountInstance import network.xyo.client.settings.AccountPreferences +import network.xyo.client.settings.defaultXyoSdkSettings import network.xyo.client.xyoScope -class AccountPrefsRepository(context: Context, private val _accountPreferences: AccountPreferences = defaults.accountPreferences) { +class AccountPrefsRepository(context: Context, private val _accountPreferences: AccountPreferences = defaultXyoSdkSettings.accountPreferences) { private val appContext = context.applicationContext // This should set the proper paths for the prefs datastore each time the the class is instantiated @@ -98,7 +99,7 @@ class AccountPrefsRepository(context: Context, private val _accountPreferences: private var INSTANCE: AccountPrefsRepository? = null // Method to retrieve the singleton instance - fun getInstance(context: Context, accountPreferences: AccountPreferences = defaults.accountPreferences): AccountPrefsRepository { + fun getInstance(context: Context, accountPreferences: AccountPreferences = defaultXyoSdkSettings.accountPreferences): AccountPrefsRepository { val newInstance = INSTANCE ?: synchronized(this) { INSTANCE ?: AccountPrefsRepository(context.applicationContext, accountPreferences).also { INSTANCE = it } } From 0646c4ee114b11954b777a3b2dbdea639625ba5c Mon Sep 17 00:00:00 2001 From: Matt Jones <885417+jonesmac@users.noreply.github.com> Date: Mon, 18 Nov 2024 16:33:10 -0500 Subject: [PATCH 08/20] add new datastore and serializer --- .../PreviousHashDataStore.kt | 30 +++++++++++++++++++ ...eviousHashStorePrefsDataStoreSerializer.kt | 22 ++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 sdk/src/main/java/network/xyo/client/datastore/previous_hash_store/PreviousHashDataStore.kt create mode 100644 sdk/src/main/java/network/xyo/client/datastore/previous_hash_store/PreviousHashStorePrefsDataStoreSerializer.kt diff --git a/sdk/src/main/java/network/xyo/client/datastore/previous_hash_store/PreviousHashDataStore.kt b/sdk/src/main/java/network/xyo/client/datastore/previous_hash_store/PreviousHashDataStore.kt new file mode 100644 index 0000000..615eff2 --- /dev/null +++ b/sdk/src/main/java/network/xyo/client/datastore/previous_hash_store/PreviousHashDataStore.kt @@ -0,0 +1,30 @@ +package network.xyo.client.datastore.previous_hash_store + +import android.content.Context +import androidx.datastore.core.DataStore +import androidx.datastore.core.MultiProcessDataStoreFactory +import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import network.xyo.client.datastore.accounts.AccountPrefsDataStoreSerializer +import network.xyo.client.settings.defaultXyoSdkSettings +import network.xyo.data.AccountPrefsDataStoreProtos.AccountPrefsDataStore +import network.xyo.data.PreviousHashPrefsDataStoreProtos +import network.xyo.data.PreviousHashPrefsDataStoreProtos.PreviousHashPrefsDataStore +import java.io.File + +fun Context.xyoPreviousHashDataStore(name: String?, path: String?): DataStore { + val resolvedName = name ?: defaultXyoSdkSettings.previousHashStorePreferences.fileName + val resolvedPath = path ?: defaultXyoSdkSettings.previousHashStorePreferences.storagePath + + val dataStoreFile = File(filesDir, "$resolvedPath/$resolvedName") + + return MultiProcessDataStoreFactory.create( + serializer = PreviousHashStorePrefsDataStoreSerializer, + produceFile = { dataStoreFile }, + corruptionHandler = ReplaceFileCorruptionHandler( + produceNewData = { PreviousHashPrefsDataStore.getDefaultInstance() } + ), + scope = CoroutineScope(Dispatchers.IO) + ) +} \ No newline at end of file diff --git a/sdk/src/main/java/network/xyo/client/datastore/previous_hash_store/PreviousHashStorePrefsDataStoreSerializer.kt b/sdk/src/main/java/network/xyo/client/datastore/previous_hash_store/PreviousHashStorePrefsDataStoreSerializer.kt new file mode 100644 index 0000000..aeb8826 --- /dev/null +++ b/sdk/src/main/java/network/xyo/client/datastore/previous_hash_store/PreviousHashStorePrefsDataStoreSerializer.kt @@ -0,0 +1,22 @@ +package network.xyo.client.datastore.previous_hash_store + +import androidx.datastore.core.CorruptionException +import androidx.datastore.core.Serializer +import com.google.protobuf.InvalidProtocolBufferException +import network.xyo.data.AccountPrefsDataStoreProtos.AccountPrefsDataStore +import network.xyo.data.PreviousHashPrefsDataStoreProtos.PreviousHashPrefsDataStore +import java.io.InputStream +import java.io.OutputStream + +object PreviousHashStorePrefsDataStoreSerializer : Serializer { + override val defaultValue: PreviousHashPrefsDataStore = PreviousHashPrefsDataStore.getDefaultInstance() + override suspend fun readFrom(input: InputStream): PreviousHashPrefsDataStore { + try { + return PreviousHashPrefsDataStore.parseFrom(input) + } catch (exception: InvalidProtocolBufferException) { + throw CorruptionException("Cannot read proto.", exception) + } + } + + override suspend fun writeTo(t: PreviousHashPrefsDataStore, output: OutputStream) = t.writeTo(output) +} \ No newline at end of file From f8a9d80e25f977f6c3b86ac78d9bfdaff10f69e6 Mon Sep 17 00:00:00 2001 From: Matt Jones <885417+jonesmac@users.noreply.github.com> Date: Mon, 18 Nov 2024 16:33:23 -0500 Subject: [PATCH 09/20] add new datastore and serializer --- .../PreviousHashStorePrefsDataStoreSerializer.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/sdk/src/main/java/network/xyo/client/datastore/previous_hash_store/PreviousHashStorePrefsDataStoreSerializer.kt b/sdk/src/main/java/network/xyo/client/datastore/previous_hash_store/PreviousHashStorePrefsDataStoreSerializer.kt index aeb8826..72972df 100644 --- a/sdk/src/main/java/network/xyo/client/datastore/previous_hash_store/PreviousHashStorePrefsDataStoreSerializer.kt +++ b/sdk/src/main/java/network/xyo/client/datastore/previous_hash_store/PreviousHashStorePrefsDataStoreSerializer.kt @@ -3,7 +3,6 @@ package network.xyo.client.datastore.previous_hash_store import androidx.datastore.core.CorruptionException import androidx.datastore.core.Serializer import com.google.protobuf.InvalidProtocolBufferException -import network.xyo.data.AccountPrefsDataStoreProtos.AccountPrefsDataStore import network.xyo.data.PreviousHashPrefsDataStoreProtos.PreviousHashPrefsDataStore import java.io.InputStream import java.io.OutputStream From 2b75cf478bd7796eaea0bd4f194a1c84fad29c55 Mon Sep 17 00:00:00 2001 From: Matt Jones <885417+jonesmac@users.noreply.github.com> Date: Mon, 18 Nov 2024 16:37:24 -0500 Subject: [PATCH 10/20] WIP - PreviousHashStorePrefsRepository --- .../PreviousHashStorePrefsRepository.kt | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 sdk/src/main/java/network/xyo/client/datastore/previous_hash_store/PreviousHashStorePrefsRepository.kt diff --git a/sdk/src/main/java/network/xyo/client/datastore/previous_hash_store/PreviousHashStorePrefsRepository.kt b/sdk/src/main/java/network/xyo/client/datastore/previous_hash_store/PreviousHashStorePrefsRepository.kt new file mode 100644 index 0000000..b66a5f0 --- /dev/null +++ b/sdk/src/main/java/network/xyo/client/datastore/previous_hash_store/PreviousHashStorePrefsRepository.kt @@ -0,0 +1,117 @@ +package network.xyo.client.datastore.previous_hash_store + +import android.content.Context +import androidx.datastore.core.DataStore +import network.xyo.client.settings.PreviousHashStorePreferences +import network.xyo.client.settings.defaultXyoSdkSettings +import network.xyo.data.PreviousHashPrefsDataStoreProtos.PreviousHashPrefsDataStore + + +class PreviousHashStorePrefsRepository( + context: Context, + private val _previousHashStorePreferences: PreviousHashStorePreferences = defaultXyoSdkSettings.previousHashStorePreferences +) { + private val appContext = context.applicationContext + + // This should set the proper paths for the prefs datastore each time the the class is instantiated + @Volatile + private var previousHashStorePrefsDataStore: DataStore = appContext.xyoPreviousHashDataStore( + previousHashStorePreferences.fileName, previousHashStorePreferences.storagePath + ) + + // Exposing as a getter so path/filename preferences can be fetched from a separate location if needed. + val previousHashStorePreferences: PreviousHashStorePreferences + get() = _previousHashStorePreferences + +// @RequiresApi(Build.VERSION_CODES.M) +// suspend fun getPreviousHashes(): PreviousHashStore { +// val saveKeyHex = getPreviousHashStore() +// return +// } + +// @OptIn(ExperimentalStdlibApi::class) +// @RequiresApi(Build.VERSION_CODES.M) +// suspend fun initializeAccount(account: AccountInstance): AccountInstance? { +// var updatedKey: String? = null +// val job = xyoScope.launch { +// val savedKey = accountPrefsDataStore.data.first().accountKey +// if (savedKey.isNullOrEmpty()) { +// // no saved key so save the passed in one +// updatedKey = null +// setAccountKey(account.privateKey.toHexString()) +// } else { +// updatedKey = null +// Log.w("xyoClient", "Key already exists. Clear it first before initializing prefs with new account") +// } +// } +// job.join() +// return if (updatedKey !== null) { +// account +// } else { +// null +// } +// } + +// @OptIn(ExperimentalStdlibApi::class) +// @RequiresApi(Build.VERSION_CODES.M) +// private suspend fun getAccountKey(): String { +// val savedKey = accountPrefsDataStore.data.first().accountKey +// return if (savedKey.isEmpty()) { +// val newAccount: AccountInstance = Account.random() +// setAccountKey(newAccount.privateKey.toHexString()) +// newAccount.privateKey.toHexString() +// } else { +// return savedKey +// } +// } + +// private suspend fun setAccountKey(accountKey: String): DataStore { +// val job = xyoScope.launch { +// this@PreviousHashStorePrefsRepository.accountPrefsDataStore.updateData { currentPrefs -> +// currentPrefs.toBuilder() +// .setAccountKey(accountKey) +// .build() +// } +// } +// job.join() +// return accountPrefsDataStore +// } +// +// suspend fun clearSavedAccountKey(): DataStore { +// val job = xyoScope.launch { +// this@PreviousHashStorePrefsRepository.accountPrefsDataStore.updateData { currentPrefs -> +// currentPrefs.toBuilder() +// .setAccountKey("") +// .build() +// } +// } +// job.join() +// return accountPrefsDataStore +// } + + companion object { + @Volatile + private var INSTANCE: PreviousHashStorePrefsRepository? = null + + // Method to retrieve the singleton instance + fun getInstance(context: Context, previousHashStorePreferences: PreviousHashStorePreferences = defaultXyoSdkSettings.previousHashStorePreferences): PreviousHashStorePrefsRepository { + val newInstance = INSTANCE ?: synchronized(this) { + INSTANCE ?: PreviousHashStorePrefsRepository(context.applicationContext, previousHashStorePreferences).also { INSTANCE = it } + } + return newInstance + } + + fun refresh(context: Context, previousHashStorePreferences: PreviousHashStorePreferences): PreviousHashStorePrefsRepository { + synchronized(this) { + INSTANCE = PreviousHashStorePrefsRepository(context.applicationContext, previousHashStorePreferences) + return INSTANCE!! + } + } + + fun resetInstance() { + synchronized(this) { + INSTANCE = null + } + } + } +} \ No newline at end of file From f8873b953f045bb1fa6bee45f232b3167daf19eb Mon Sep 17 00:00:00 2001 From: Matt Jones <885417+jonesmac@users.noreply.github.com> Date: Mon, 18 Nov 2024 16:49:30 -0500 Subject: [PATCH 11/20] getItem method --- .../PreviousHashStorePrefsRepository.kt | 36 +++++++++++++++---- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/sdk/src/main/java/network/xyo/client/datastore/previous_hash_store/PreviousHashStorePrefsRepository.kt b/sdk/src/main/java/network/xyo/client/datastore/previous_hash_store/PreviousHashStorePrefsRepository.kt index b66a5f0..0607c01 100644 --- a/sdk/src/main/java/network/xyo/client/datastore/previous_hash_store/PreviousHashStorePrefsRepository.kt +++ b/sdk/src/main/java/network/xyo/client/datastore/previous_hash_store/PreviousHashStorePrefsRepository.kt @@ -2,15 +2,20 @@ package network.xyo.client.datastore.previous_hash_store import android.content.Context import androidx.datastore.core.DataStore +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.launch +import network.xyo.client.account.hexStringToByteArray +import network.xyo.client.account.model.PreviousHashStore import network.xyo.client.settings.PreviousHashStorePreferences import network.xyo.client.settings.defaultXyoSdkSettings +import network.xyo.client.xyoScope import network.xyo.data.PreviousHashPrefsDataStoreProtos.PreviousHashPrefsDataStore class PreviousHashStorePrefsRepository( context: Context, private val _previousHashStorePreferences: PreviousHashStorePreferences = defaultXyoSdkSettings.previousHashStorePreferences -) { +): PreviousHashStore { private val appContext = context.applicationContext // This should set the proper paths for the prefs datastore each time the the class is instantiated @@ -23,11 +28,30 @@ class PreviousHashStorePrefsRepository( val previousHashStorePreferences: PreviousHashStorePreferences get() = _previousHashStorePreferences -// @RequiresApi(Build.VERSION_CODES.M) -// suspend fun getPreviousHashes(): PreviousHashStore { -// val saveKeyHex = getPreviousHashStore() -// return -// } + @OptIn(ExperimentalStdlibApi::class) + override suspend fun getItem(address: ByteArray): ByteArray? { + var savedPreviousHash: String? = null + val job = xyoScope.launch { + val savedPreviousHashStore = previousHashStorePrefsDataStore.data.first().addressToHashMap + val searchKey = address.toHexString() + savedPreviousHash = savedPreviousHashStore[searchKey] + } + job.join() + return if (savedPreviousHash != null) { + hexStringToByteArray(savedPreviousHash!!) + } else { + null + } + } + + suspend override fun setItem(address: ByteArray, previousHash: ByteArray) { + TODO("Not yet implemented") + } + + suspend override fun removeItem(address: ByteArray) { + TODO("Not yet implemented") + } + // @OptIn(ExperimentalStdlibApi::class) // @RequiresApi(Build.VERSION_CODES.M) From d3ef34857c95226476254f51c10e15ca9d6e48b6 Mon Sep 17 00:00:00 2001 From: Matt Jones <885417+jonesmac@users.noreply.github.com> Date: Mon, 18 Nov 2024 17:03:37 -0500 Subject: [PATCH 12/20] upgrade to proto3 --- .../java/network/xyo/client/proto/AccountPrefsDataStore.proto | 2 +- .../network/xyo/client/proto/PreviousHashPrefsDataStore.proto | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/src/main/java/network/xyo/client/proto/AccountPrefsDataStore.proto b/sdk/src/main/java/network/xyo/client/proto/AccountPrefsDataStore.proto index 835a491..9bee6db 100644 --- a/sdk/src/main/java/network/xyo/client/proto/AccountPrefsDataStore.proto +++ b/sdk/src/main/java/network/xyo/client/proto/AccountPrefsDataStore.proto @@ -1,4 +1,4 @@ -syntax = "proto2"; +syntax = "proto3"; package network.xyo.proto; diff --git a/sdk/src/main/java/network/xyo/client/proto/PreviousHashPrefsDataStore.proto b/sdk/src/main/java/network/xyo/client/proto/PreviousHashPrefsDataStore.proto index 4253a81..a94af75 100644 --- a/sdk/src/main/java/network/xyo/client/proto/PreviousHashPrefsDataStore.proto +++ b/sdk/src/main/java/network/xyo/client/proto/PreviousHashPrefsDataStore.proto @@ -1,4 +1,4 @@ -syntax = "proto2"; +syntax = "proto3"; package network.xyo.proto; From 111d62047c968180908d57e1b48983304cb46bae Mon Sep 17 00:00:00 2001 From: Matt Jones <885417+jonesmac@users.noreply.github.com> Date: Mon, 18 Nov 2024 17:03:58 -0500 Subject: [PATCH 13/20] finish PreviousHashStore repository implementation --- .../PreviousHashStorePrefsRepository.kt | 95 +++++++------------ 1 file changed, 33 insertions(+), 62 deletions(-) diff --git a/sdk/src/main/java/network/xyo/client/datastore/previous_hash_store/PreviousHashStorePrefsRepository.kt b/sdk/src/main/java/network/xyo/client/datastore/previous_hash_store/PreviousHashStorePrefsRepository.kt index 0607c01..05c9605 100644 --- a/sdk/src/main/java/network/xyo/client/datastore/previous_hash_store/PreviousHashStorePrefsRepository.kt +++ b/sdk/src/main/java/network/xyo/client/datastore/previous_hash_store/PreviousHashStorePrefsRepository.kt @@ -44,74 +44,45 @@ class PreviousHashStorePrefsRepository( } } - suspend override fun setItem(address: ByteArray, previousHash: ByteArray) { - TODO("Not yet implemented") + @OptIn(ExperimentalStdlibApi::class) + override suspend fun setItem(address: ByteArray, previousHash: ByteArray) { + val addressString = address.toHexString() + val previousHashString = previousHash.toHexString() + val job = xyoScope.launch { + this@PreviousHashStorePrefsRepository.previousHashStorePrefsDataStore.updateData { currentPrefs -> + currentPrefs.toBuilder() + .putAddressToHash(addressString, previousHashString) + .build() + } + } + job.join() } - suspend override fun removeItem(address: ByteArray) { - TODO("Not yet implemented") + @OptIn(ExperimentalStdlibApi::class) + override suspend fun removeItem(address: ByteArray) { + val addressString = address.toHexString() + val job = xyoScope.launch { + this@PreviousHashStorePrefsRepository.previousHashStorePrefsDataStore.updateData { currentPrefs -> + currentPrefs.toBuilder() + .removeAddressToHash(addressString) + .build() + } + } + job.join() } + suspend fun clearStore() { + val job = xyoScope.launch { + this@PreviousHashStorePrefsRepository.previousHashStorePrefsDataStore.updateData { currentPrefs -> + currentPrefs.toBuilder() + .clearAddressToHash() + .build() + } + } + job.join() + } -// @OptIn(ExperimentalStdlibApi::class) -// @RequiresApi(Build.VERSION_CODES.M) -// suspend fun initializeAccount(account: AccountInstance): AccountInstance? { -// var updatedKey: String? = null -// val job = xyoScope.launch { -// val savedKey = accountPrefsDataStore.data.first().accountKey -// if (savedKey.isNullOrEmpty()) { -// // no saved key so save the passed in one -// updatedKey = null -// setAccountKey(account.privateKey.toHexString()) -// } else { -// updatedKey = null -// Log.w("xyoClient", "Key already exists. Clear it first before initializing prefs with new account") -// } -// } -// job.join() -// return if (updatedKey !== null) { -// account -// } else { -// null -// } -// } - -// @OptIn(ExperimentalStdlibApi::class) -// @RequiresApi(Build.VERSION_CODES.M) -// private suspend fun getAccountKey(): String { -// val savedKey = accountPrefsDataStore.data.first().accountKey -// return if (savedKey.isEmpty()) { -// val newAccount: AccountInstance = Account.random() -// setAccountKey(newAccount.privateKey.toHexString()) -// newAccount.privateKey.toHexString() -// } else { -// return savedKey -// } -// } -// private suspend fun setAccountKey(accountKey: String): DataStore { -// val job = xyoScope.launch { -// this@PreviousHashStorePrefsRepository.accountPrefsDataStore.updateData { currentPrefs -> -// currentPrefs.toBuilder() -// .setAccountKey(accountKey) -// .build() -// } -// } -// job.join() -// return accountPrefsDataStore -// } -// -// suspend fun clearSavedAccountKey(): DataStore { -// val job = xyoScope.launch { -// this@PreviousHashStorePrefsRepository.accountPrefsDataStore.updateData { currentPrefs -> -// currentPrefs.toBuilder() -// .setAccountKey("") -// .build() -// } -// } -// job.join() -// return accountPrefsDataStore -// } companion object { @Volatile From 925f20554f772d7825c252148029d68b99a7ae6c Mon Sep 17 00:00:00 2001 From: Matt Jones <885417+jonesmac@users.noreply.github.com> Date: Mon, 18 Nov 2024 17:15:19 -0500 Subject: [PATCH 14/20] passing tests for AccountPrefsRepository --- .../{ => prefs}/AccountPrefsRepositoryTest.kt | 12 +++-- .../PreviousHashStorePrefsRepositoryTest.kt | 44 +++++++++++++++++++ 2 files changed, 53 insertions(+), 3 deletions(-) rename sdk/src/androidTest/java/network/xyo/client/{ => prefs}/AccountPrefsRepositoryTest.kt (94%) create mode 100644 sdk/src/androidTest/java/network/xyo/client/prefs/PreviousHashStorePrefsRepositoryTest.kt diff --git a/sdk/src/androidTest/java/network/xyo/client/AccountPrefsRepositoryTest.kt b/sdk/src/androidTest/java/network/xyo/client/prefs/AccountPrefsRepositoryTest.kt similarity index 94% rename from sdk/src/androidTest/java/network/xyo/client/AccountPrefsRepositoryTest.kt rename to sdk/src/androidTest/java/network/xyo/client/prefs/AccountPrefsRepositoryTest.kt index c686451..62b9a7d 100644 --- a/sdk/src/androidTest/java/network/xyo/client/AccountPrefsRepositoryTest.kt +++ b/sdk/src/androidTest/java/network/xyo/client/prefs/AccountPrefsRepositoryTest.kt @@ -1,8 +1,10 @@ -package network.xyo.client +package network.xyo.client.prefs import android.content.Context import androidx.test.platform.app.InstrumentationRegistry import kotlinx.coroutines.runBlocking +import network.xyo.client.TestConstants +import network.xyo.client.XyoPanel import network.xyo.client.account.Account import network.xyo.client.boundwitness.XyoBoundWitnessBuilder import network.xyo.client.datastore.accounts.AccountPrefsRepository @@ -117,7 +119,9 @@ class AccountPrefsRepositoryTest { assertEquals(firstAccount.privateKey.toHexString(), testAccount.privateKey.toHexString()) // Sign with the test account - val firstBw = XyoBoundWitnessBuilder().witness(firstAccount, null).payloads(listOf(TestConstants.debugPayload)).build() + val firstBw = XyoBoundWitnessBuilder().witness(firstAccount, null).payloads(listOf( + TestConstants.debugPayload + )).build() val firstAddress = firstBw.addresses.first() // Deserialize the test account (Ideally we would refresh the singleton but in tests this seems to cause errors with multiple instances of the prefs DataStore) @@ -125,7 +129,9 @@ class AccountPrefsRepositoryTest { val secondAccount = secondInstance.getAccount() // Sign with the test account - val secondBw = XyoBoundWitnessBuilder().witness(secondAccount, null).payloads(listOf(TestConstants.debugPayload)).build() + val secondBw = XyoBoundWitnessBuilder().witness(secondAccount, null).payloads(listOf( + TestConstants.debugPayload + )).build() val secondAddress = secondBw.addresses.first() // check that addresses have not changed and no errors occurred during signing diff --git a/sdk/src/androidTest/java/network/xyo/client/prefs/PreviousHashStorePrefsRepositoryTest.kt b/sdk/src/androidTest/java/network/xyo/client/prefs/PreviousHashStorePrefsRepositoryTest.kt new file mode 100644 index 0000000..48c0f5d --- /dev/null +++ b/sdk/src/androidTest/java/network/xyo/client/prefs/PreviousHashStorePrefsRepositoryTest.kt @@ -0,0 +1,44 @@ +package network.xyo.client.prefs + +import android.content.Context +import androidx.test.platform.app.InstrumentationRegistry +import kotlinx.coroutines.runBlocking +import network.xyo.client.TestConstants +import network.xyo.client.account.Account +import network.xyo.client.account.hexStringToByteArray +import network.xyo.client.datastore.previous_hash_store.PreviousHashStorePrefsRepository +import org.junit.Before +import org.junit.Test +import org.junit.jupiter.api.Assertions.assertNotNull + +class PreviousHashStorePrefsRepositoryTest { + private lateinit var appContext: Context + + @Before + fun useAppContext() { + // Context of the app under test. + this.appContext = InstrumentationRegistry.getInstrumentation().targetContext + } + + @OptIn(ExperimentalStdlibApi::class) + @Test + fun testPreviousHashStorePersistence() { + runBlocking { + val prefsRepository = + PreviousHashStorePrefsRepository.getInstance(appContext) + prefsRepository.clearStore() + + val testAccountAddress = Account.random().address + val testPreviousHash = hexStringToByteArray(TestConstants.debugPayloadHash) + prefsRepository.setItem(testAccountAddress, testPreviousHash) + + val savedItem = prefsRepository.getItem(testAccountAddress) + assertNotNull(savedItem) + assert(savedItem!!.contentEquals(testPreviousHash)) + + prefsRepository.removeItem(testAccountAddress) + val removedItem = prefsRepository.getItem(testAccountAddress) + assert(removedItem == null) + } + } +} \ No newline at end of file From c5bf52a57162637aa87e587b17cdd34626205067 Mon Sep 17 00:00:00 2001 From: Matt Jones <885417+jonesmac@users.noreply.github.com> Date: Mon, 18 Nov 2024 20:09:21 -0500 Subject: [PATCH 15/20] let AccountPrefsRepository take generic settings object --- .../prefs/AccountPrefsRepositoryTest.kt | 20 +++++++++++++++---- .../accounts/AccountPrefsRepository.kt | 12 ++++++----- .../network/xyo/client/settings/XyoSdk.kt | 4 ++-- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/sdk/src/androidTest/java/network/xyo/client/prefs/AccountPrefsRepositoryTest.kt b/sdk/src/androidTest/java/network/xyo/client/prefs/AccountPrefsRepositoryTest.kt index 62b9a7d..119c87f 100644 --- a/sdk/src/androidTest/java/network/xyo/client/prefs/AccountPrefsRepositoryTest.kt +++ b/sdk/src/androidTest/java/network/xyo/client/prefs/AccountPrefsRepositoryTest.kt @@ -9,6 +9,8 @@ import network.xyo.client.account.Account import network.xyo.client.boundwitness.XyoBoundWitnessBuilder import network.xyo.client.datastore.accounts.AccountPrefsRepository import network.xyo.client.settings.AccountPreferences +import network.xyo.client.settings.PreviousHashStorePreferences +import network.xyo.client.settings.SettingsInterface import network.xyo.client.witness.system.info.XyoSystemInfoWitness import org.junit.Before import org.junit.Test @@ -82,19 +84,29 @@ class AccountPrefsRepositoryTest { override val storagePath = "__xyo-client-sdk-1__" } - val updatedAccountPrefs = UpdatedAccountPreferences() + class UpdatedPreviousHashShorePreferences : PreviousHashStorePreferences { + override val fileName = "network-xyo-sdk-prefs-2" + override val storagePath = "__xyo-client-sdk-1__" + } + + class Settings: SettingsInterface { + override val accountPreferences = UpdatedAccountPreferences() + override val previousHashStorePreferences = UpdatedPreviousHashShorePreferences() + } + + val updatedSettings = Settings() val refreshedInstance = - AccountPrefsRepository.refresh(appContext, updatedAccountPrefs) + AccountPrefsRepository.refresh(appContext, updatedSettings) // Test that accountPreferences are updated assertEquals( refreshedInstance.accountPreferences.fileName, - updatedAccountPrefs.fileName + updatedSettings.accountPreferences.fileName ) assertEquals( refreshedInstance.accountPreferences.storagePath, - updatedAccountPrefs.storagePath + updatedSettings.accountPreferences.storagePath ) val refreshedAddress = refreshedInstance.getAccount().privateKey.toHexString() diff --git a/sdk/src/main/java/network/xyo/client/datastore/accounts/AccountPrefsRepository.kt b/sdk/src/main/java/network/xyo/client/datastore/accounts/AccountPrefsRepository.kt index d17835f..9edc3c8 100644 --- a/sdk/src/main/java/network/xyo/client/datastore/accounts/AccountPrefsRepository.kt +++ b/sdk/src/main/java/network/xyo/client/datastore/accounts/AccountPrefsRepository.kt @@ -11,12 +11,14 @@ import kotlinx.coroutines.launch import network.xyo.client.account.Account import network.xyo.client.account.model.AccountInstance import network.xyo.client.settings.AccountPreferences +import network.xyo.client.settings.SettingsInterface import network.xyo.client.settings.defaultXyoSdkSettings import network.xyo.client.xyoScope -class AccountPrefsRepository(context: Context, private val _accountPreferences: AccountPreferences = defaultXyoSdkSettings.accountPreferences) { +class AccountPrefsRepository(context: Context, settings: SettingsInterface = defaultXyoSdkSettings) { private val appContext = context.applicationContext + private val _accountPreferences: AccountPreferences = settings.accountPreferences // This should set the proper paths for the prefs datastore each time the the class is instantiated @Volatile @@ -99,16 +101,16 @@ class AccountPrefsRepository(context: Context, private val _accountPreferences: private var INSTANCE: AccountPrefsRepository? = null // Method to retrieve the singleton instance - fun getInstance(context: Context, accountPreferences: AccountPreferences = defaultXyoSdkSettings.accountPreferences): AccountPrefsRepository { + fun getInstance(context: Context, settings: SettingsInterface = defaultXyoSdkSettings): AccountPrefsRepository { val newInstance = INSTANCE ?: synchronized(this) { - INSTANCE ?: AccountPrefsRepository(context.applicationContext, accountPreferences).also { INSTANCE = it } + INSTANCE ?: AccountPrefsRepository(context.applicationContext, settings).also { INSTANCE = it } } return newInstance } - fun refresh(context: Context, accountPreferences: AccountPreferences): AccountPrefsRepository { + fun refresh(context: Context, settings: SettingsInterface = defaultXyoSdkSettings): AccountPrefsRepository { synchronized(this) { - INSTANCE = AccountPrefsRepository(context.applicationContext, accountPreferences) + INSTANCE = AccountPrefsRepository(context.applicationContext, settings) return INSTANCE!! } } diff --git a/sdk/src/main/java/network/xyo/client/settings/XyoSdk.kt b/sdk/src/main/java/network/xyo/client/settings/XyoSdk.kt index ef8afd8..b90ef7e 100644 --- a/sdk/src/main/java/network/xyo/client/settings/XyoSdk.kt +++ b/sdk/src/main/java/network/xyo/client/settings/XyoSdk.kt @@ -32,7 +32,7 @@ class XyoSdk private constructor(context: Context, val settings: SettingsInterfa fun getInstance(context: Context, settings: SettingsInterface = DefaultXyoSdkSettings()): XyoSdk { // Initialize the singleton with the users accountPreferences - AccountPrefsRepository.getInstance(context.applicationContext, settings.accountPreferences) + AccountPrefsRepository.getInstance(context.applicationContext, settings) val newInstance = INSTANCE ?: synchronized(this) { INSTANCE ?: XyoSdk(context.applicationContext, settings).also { INSTANCE = it } @@ -43,7 +43,7 @@ class XyoSdk private constructor(context: Context, val settings: SettingsInterfa fun refresh(context: Context, settings: SettingsInterface = DefaultXyoSdkSettings()): XyoSdk { synchronized(this) { // Initialize the singleton with the users accountPreferences - AccountPrefsRepository.getInstance(context.applicationContext, settings.accountPreferences) + AccountPrefsRepository.getInstance(context.applicationContext, settings) INSTANCE = XyoSdk(context.applicationContext, settings) } return INSTANCE!! From 9c1a9c3cbc9d0b9d23966044eb67073b785ea62a Mon Sep 17 00:00:00 2001 From: Matt Jones <885417+jonesmac@users.noreply.github.com> Date: Mon, 18 Nov 2024 20:14:34 -0500 Subject: [PATCH 16/20] force all signing to take place inside a Coroutine --- .../network/xyo/client/account/AccountTest.kt | 19 +++++++++++-------- .../network/xyo/client/account/Account.kt | 3 ++- .../account/model/PrivateKeyInstance.kt | 2 +- .../boundwitness/QueryBoundWitnessBuilder.kt | 2 +- .../boundwitness/XyoBoundWitnessBuilder.kt | 8 ++++---- .../accounts/AccountPrefsRepository.kt | 1 - .../xyo/client/node/client/NodeClient.kt | 4 ++-- 7 files changed, 21 insertions(+), 18 deletions(-) diff --git a/sdk/src/androidTest/java/network/xyo/client/account/AccountTest.kt b/sdk/src/androidTest/java/network/xyo/client/account/AccountTest.kt index 1f14ef6..0fa920a 100644 --- a/sdk/src/androidTest/java/network/xyo/client/account/AccountTest.kt +++ b/sdk/src/androidTest/java/network/xyo/client/account/AccountTest.kt @@ -1,5 +1,6 @@ package network.xyo.client.account +import kotlinx.coroutines.runBlocking import org.junit.Test class AccountTest { @@ -22,13 +23,15 @@ class AccountTest { @OptIn(ExperimentalStdlibApi::class) @Test fun testKnownPrivateKeyAccount() { - val account = Account.fromPrivateKey(hexStringToByteArray(testVectorPrivateKey)) - assert(account.privateKey.count() == 32) - assert(account.publicKey.count() == 64) - assert(account.publicKey.toHexString() == testVectorPublicKey) - assert(account.address.toHexString() == testVectorAddress) - val signature = account.sign(hexStringToByteArray(testVectorHash)) - assert(signature.toHexString() == testVectorSignature) - assert(account.verify(hexStringToByteArray(testVectorHash), signature)) + runBlocking { + val account = Account.fromPrivateKey(hexStringToByteArray(testVectorPrivateKey)) + assert(account.privateKey.count() == 32) + assert(account.publicKey.count() == 64) + assert(account.publicKey.toHexString() == testVectorPublicKey) + assert(account.address.toHexString() == testVectorAddress) + val signature = account.sign(hexStringToByteArray(testVectorHash)) + assert(signature.toHexString() == testVectorSignature) + assert(account.verify(hexStringToByteArray(testVectorHash), signature)) + } } } \ No newline at end of file diff --git a/sdk/src/main/java/network/xyo/client/account/Account.kt b/sdk/src/main/java/network/xyo/client/account/Account.kt index 7219d96..f235809 100644 --- a/sdk/src/main/java/network/xyo/client/account/Account.kt +++ b/sdk/src/main/java/network/xyo/client/account/Account.kt @@ -29,9 +29,10 @@ open class Account private constructor (private val _privateKey: PrivateKey, pri final override val publicKey: ByteArray get() = _privateKey.toPublicKey().key.toBytesPadded(64) - override fun sign(hash: ByteArray): ByteArray { + override suspend fun sign(hash: ByteArray): ByteArray { val result = BCECSigner().sign(_privateKey, hash) _previousHash = hash + previousHashStore?.setItem(address, hash) return result.encodeAsBTC().toByteArray() } diff --git a/sdk/src/main/java/network/xyo/client/account/model/PrivateKeyInstance.kt b/sdk/src/main/java/network/xyo/client/account/model/PrivateKeyInstance.kt index f69ee3b..d8f1a10 100644 --- a/sdk/src/main/java/network/xyo/client/account/model/PrivateKeyInstance.kt +++ b/sdk/src/main/java/network/xyo/client/account/model/PrivateKeyInstance.kt @@ -1,5 +1,5 @@ package network.xyo.client.account.model interface PrivateKeyInstance: PublicKeyInstance { - fun sign(hash: ByteArray): ByteArray + suspend fun sign(hash: ByteArray): ByteArray } \ No newline at end of file diff --git a/sdk/src/main/java/network/xyo/client/boundwitness/QueryBoundWitnessBuilder.kt b/sdk/src/main/java/network/xyo/client/boundwitness/QueryBoundWitnessBuilder.kt index 42ad43a..7a91160 100644 --- a/sdk/src/main/java/network/xyo/client/boundwitness/QueryBoundWitnessBuilder.kt +++ b/sdk/src/main/java/network/xyo/client/boundwitness/QueryBoundWitnessBuilder.kt @@ -28,7 +28,7 @@ class QueryBoundWitnessBuilder : XyoBoundWitnessBuilder() { return this } - override fun build(previousHash: String?): QueryBoundWitnessJson { + override suspend fun build(previousHash: String?): QueryBoundWitnessJson { bw = QueryBoundWitnessJson() // override to support additional properties for query bound witnesses return bw.let { diff --git a/sdk/src/main/java/network/xyo/client/boundwitness/XyoBoundWitnessBuilder.kt b/sdk/src/main/java/network/xyo/client/boundwitness/XyoBoundWitnessBuilder.kt index 11e8c18..c2422da 100644 --- a/sdk/src/main/java/network/xyo/client/boundwitness/XyoBoundWitnessBuilder.kt +++ b/sdk/src/main/java/network/xyo/client/boundwitness/XyoBoundWitnessBuilder.kt @@ -61,14 +61,14 @@ open class XyoBoundWitnessBuilder { return this } - private fun sign(hash: String): List { + private suspend fun sign(hash: String): List { return _witnesses.map { val sig = XyoSerializable.bytesToHex(it.sign(hexStringToByteArray(hash))) sig } } - protected fun constructFields() { + protected suspend fun constructFields() { // update json class properties bw.payload_hashes = _payload_hashes bw.payload_schemas = _payload_schemas @@ -82,7 +82,7 @@ open class XyoBoundWitnessBuilder { constructHashableFieldsFields() } - private fun constructHashableFieldsFields() { + private suspend fun constructHashableFieldsFields() { // Note: Once fields are hashed, do not update class properties that are expected // in the serialized version of the bw because they will invalidate the hash val hashable = hashableFields() @@ -91,7 +91,7 @@ open class XyoBoundWitnessBuilder { bw._hash = hash } - open fun build(previousHash: String? = null): XyoBoundWitnessJson { + open suspend fun build(previousHash: String? = null): XyoBoundWitnessJson { return bw.let{ // store the previous hash on the class it._previous_hash = previousHash diff --git a/sdk/src/main/java/network/xyo/client/datastore/accounts/AccountPrefsRepository.kt b/sdk/src/main/java/network/xyo/client/datastore/accounts/AccountPrefsRepository.kt index 9edc3c8..f023c4c 100644 --- a/sdk/src/main/java/network/xyo/client/datastore/accounts/AccountPrefsRepository.kt +++ b/sdk/src/main/java/network/xyo/client/datastore/accounts/AccountPrefsRepository.kt @@ -100,7 +100,6 @@ class AccountPrefsRepository(context: Context, settings: SettingsInterface = def @Volatile private var INSTANCE: AccountPrefsRepository? = null - // Method to retrieve the singleton instance fun getInstance(context: Context, settings: SettingsInterface = defaultXyoSdkSettings): AccountPrefsRepository { val newInstance = INSTANCE ?: synchronized(this) { INSTANCE ?: AccountPrefsRepository(context.applicationContext, settings).also { INSTANCE = it } diff --git a/sdk/src/main/java/network/xyo/client/node/client/NodeClient.kt b/sdk/src/main/java/network/xyo/client/node/client/NodeClient.kt index 004041e..b7b6778 100644 --- a/sdk/src/main/java/network/xyo/client/node/client/NodeClient.kt +++ b/sdk/src/main/java/network/xyo/client/node/client/NodeClient.kt @@ -81,7 +81,7 @@ class NodeClient(private val url: String, private val accountToUse: AccountInsta } @RequiresApi(Build.VERSION_CODES.M) - private fun buildQuery(query: XyoPayload, payloads: List?, previousHash: String?): String { + private suspend fun buildQuery(query: XyoPayload, payloads: List?, previousHash: String?): String { val builtQuery = queryBuilder(query, payloads, previousHash) val queryPayloads = buildQueryPayloads(query, payloads) val queryPayloadsJsonArray = queryPayloadsJsonArray(queryPayloads) @@ -89,7 +89,7 @@ class NodeClient(private val url: String, private val accountToUse: AccountInsta return builtQueryTuple.joinToString(",", "[", "]") } - private fun queryBuilder(query: XyoPayload, payloads: List?, previousHash: String?): QueryBoundWitnessJson { + private suspend fun queryBuilder(query: XyoPayload, payloads: List?, previousHash: String?): QueryBoundWitnessJson { return QueryBoundWitnessBuilder().let { payloads?.let { payload -> it.payloads(payload) From 1d5d63c209198a161f075a87c7b87f58069352d6 Mon Sep 17 00:00:00 2001 From: Matt Jones <885417+jonesmac@users.noreply.github.com> Date: Mon, 18 Nov 2024 20:14:58 -0500 Subject: [PATCH 17/20] add PreviousHashStore to global Account instance when sdk is initialized --- sdk/src/main/java/network/xyo/client/settings/XyoSdk.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sdk/src/main/java/network/xyo/client/settings/XyoSdk.kt b/sdk/src/main/java/network/xyo/client/settings/XyoSdk.kt index b90ef7e..c6500c1 100644 --- a/sdk/src/main/java/network/xyo/client/settings/XyoSdk.kt +++ b/sdk/src/main/java/network/xyo/client/settings/XyoSdk.kt @@ -3,8 +3,10 @@ package network.xyo.client.settings import android.content.Context import android.os.Build import androidx.annotation.RequiresApi +import network.xyo.client.account.Account import network.xyo.client.account.model.AccountInstance import network.xyo.client.datastore.accounts.AccountPrefsRepository +import network.xyo.client.datastore.previous_hash_store.PreviousHashStorePrefsRepository class XyoSdk private constructor(context: Context, val settings: SettingsInterface) { private val appContext = context.applicationContext @@ -31,8 +33,10 @@ class XyoSdk private constructor(context: Context, val settings: SettingsInterfa private var INSTANCE: XyoSdk? = null fun getInstance(context: Context, settings: SettingsInterface = DefaultXyoSdkSettings()): XyoSdk { - // Initialize the singleton with the users accountPreferences + // Initialize the global AccountPrefs DataStore AccountPrefsRepository.getInstance(context.applicationContext, settings) + // Initialize the global Account object with the previous hash store DataStore + Account.previousHashStore = PreviousHashStorePrefsRepository.getInstance(context.applicationContext) val newInstance = INSTANCE ?: synchronized(this) { INSTANCE ?: XyoSdk(context.applicationContext, settings).also { INSTANCE = it } From 1007c1677f93f892bdd7b6086306b6f2d564870d Mon Sep 17 00:00:00 2001 From: Matt Jones <885417+jonesmac@users.noreply.github.com> Date: Mon, 18 Nov 2024 20:53:13 -0500 Subject: [PATCH 18/20] test for using previousHashStore in account --- .../network/xyo/client/account/AccountTest.kt | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/sdk/src/androidTest/java/network/xyo/client/account/AccountTest.kt b/sdk/src/androidTest/java/network/xyo/client/account/AccountTest.kt index 0fa920a..998db91 100644 --- a/sdk/src/androidTest/java/network/xyo/client/account/AccountTest.kt +++ b/sdk/src/androidTest/java/network/xyo/client/account/AccountTest.kt @@ -1,6 +1,9 @@ package network.xyo.client.account +import androidx.test.platform.app.InstrumentationRegistry import kotlinx.coroutines.runBlocking +import network.xyo.client.datastore.previous_hash_store.PreviousHashStorePrefsRepository +import org.junit.Before import org.junit.Test class AccountTest { @@ -13,6 +16,11 @@ class AccountTest { val testVectorSignature = "b61dad551e910e2793b4f9f880125b5799086510ce102fad0222c1b093c60a6b38aa35ef56f97f86537269e8be95832aaa37d3b64d86b67f0cda467ac7cb5b3e" + @Before + fun setupAccount() { + Account.previousHashStore = PreviousHashStorePrefsRepository.getInstance(InstrumentationRegistry.getInstrumentation().targetContext) + } + @Test fun testRandomAccount() { val account = Account.random() @@ -34,4 +42,18 @@ class AccountTest { assert(account.verify(hexStringToByteArray(testVectorHash), signature)) } } + + @OptIn(ExperimentalStdlibApi::class) + @Test + fun testPreviousHash() { + runBlocking { + val address = hexStringToByteArray(testVectorPrivateKey) + val account = Account.fromPrivateKey(address) + account.sign(hexStringToByteArray(testVectorHash)) + + val savedAddressInStore = Account.addressFromPublicKey(account.publicKey) + val previousHashInStore = Account.previousHashStore?.getItem(savedAddressInStore)?.toHexString() + assert(previousHashInStore == testVectorHash) + } + } } \ No newline at end of file From 272f14935e7ffd6f29f28b4a31a631c1fbd98da3 Mon Sep 17 00:00:00 2001 From: Matt Jones <885417+jonesmac@users.noreply.github.com> Date: Mon, 18 Nov 2024 20:57:34 -0500 Subject: [PATCH 19/20] let PreviousHashStorePrefsRepository take full settings interface --- .../PreviousHashStorePrefsRepository.kt | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/sdk/src/main/java/network/xyo/client/datastore/previous_hash_store/PreviousHashStorePrefsRepository.kt b/sdk/src/main/java/network/xyo/client/datastore/previous_hash_store/PreviousHashStorePrefsRepository.kt index 05c9605..c02082c 100644 --- a/sdk/src/main/java/network/xyo/client/datastore/previous_hash_store/PreviousHashStorePrefsRepository.kt +++ b/sdk/src/main/java/network/xyo/client/datastore/previous_hash_store/PreviousHashStorePrefsRepository.kt @@ -7,6 +7,7 @@ import kotlinx.coroutines.launch import network.xyo.client.account.hexStringToByteArray import network.xyo.client.account.model.PreviousHashStore import network.xyo.client.settings.PreviousHashStorePreferences +import network.xyo.client.settings.SettingsInterface import network.xyo.client.settings.defaultXyoSdkSettings import network.xyo.client.xyoScope import network.xyo.data.PreviousHashPrefsDataStoreProtos.PreviousHashPrefsDataStore @@ -14,9 +15,10 @@ import network.xyo.data.PreviousHashPrefsDataStoreProtos.PreviousHashPrefsDataSt class PreviousHashStorePrefsRepository( context: Context, - private val _previousHashStorePreferences: PreviousHashStorePreferences = defaultXyoSdkSettings.previousHashStorePreferences + settings: SettingsInterface = defaultXyoSdkSettings ): PreviousHashStore { private val appContext = context.applicationContext + private val previousHashStorePreferences: PreviousHashStorePreferences = settings.previousHashStorePreferences // This should set the proper paths for the prefs datastore each time the the class is instantiated @Volatile @@ -24,10 +26,6 @@ class PreviousHashStorePrefsRepository( previousHashStorePreferences.fileName, previousHashStorePreferences.storagePath ) - // Exposing as a getter so path/filename preferences can be fetched from a separate location if needed. - val previousHashStorePreferences: PreviousHashStorePreferences - get() = _previousHashStorePreferences - @OptIn(ExperimentalStdlibApi::class) override suspend fun getItem(address: ByteArray): ByteArray? { var savedPreviousHash: String? = null @@ -89,16 +87,16 @@ class PreviousHashStorePrefsRepository( private var INSTANCE: PreviousHashStorePrefsRepository? = null // Method to retrieve the singleton instance - fun getInstance(context: Context, previousHashStorePreferences: PreviousHashStorePreferences = defaultXyoSdkSettings.previousHashStorePreferences): PreviousHashStorePrefsRepository { + fun getInstance(context: Context, settings: SettingsInterface): PreviousHashStorePrefsRepository { val newInstance = INSTANCE ?: synchronized(this) { - INSTANCE ?: PreviousHashStorePrefsRepository(context.applicationContext, previousHashStorePreferences).also { INSTANCE = it } + INSTANCE ?: PreviousHashStorePrefsRepository(context.applicationContext, settings).also { INSTANCE = it } } return newInstance } - fun refresh(context: Context, previousHashStorePreferences: PreviousHashStorePreferences): PreviousHashStorePrefsRepository { + fun refresh(context: Context, settings: SettingsInterface): PreviousHashStorePrefsRepository { synchronized(this) { - INSTANCE = PreviousHashStorePrefsRepository(context.applicationContext, previousHashStorePreferences) + INSTANCE = PreviousHashStorePrefsRepository(context.applicationContext, settings) return INSTANCE!! } } From 0ad7ba2d55b9b726e3c0d6f29fc79af2b5dfd311 Mon Sep 17 00:00:00 2001 From: Matt Jones <885417+jonesmac@users.noreply.github.com> Date: Mon, 18 Nov 2024 20:57:45 -0500 Subject: [PATCH 20/20] simplify instance properties --- .../xyo/client/datastore/accounts/AccountPrefsRepository.kt | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/sdk/src/main/java/network/xyo/client/datastore/accounts/AccountPrefsRepository.kt b/sdk/src/main/java/network/xyo/client/datastore/accounts/AccountPrefsRepository.kt index f023c4c..994f7dd 100644 --- a/sdk/src/main/java/network/xyo/client/datastore/accounts/AccountPrefsRepository.kt +++ b/sdk/src/main/java/network/xyo/client/datastore/accounts/AccountPrefsRepository.kt @@ -18,7 +18,7 @@ import network.xyo.client.xyoScope class AccountPrefsRepository(context: Context, settings: SettingsInterface = defaultXyoSdkSettings) { private val appContext = context.applicationContext - private val _accountPreferences: AccountPreferences = settings.accountPreferences + private val accountPreferences: AccountPreferences = settings.accountPreferences // This should set the proper paths for the prefs datastore each time the the class is instantiated @Volatile @@ -26,10 +26,6 @@ class AccountPrefsRepository(context: Context, settings: SettingsInterface = def accountPreferences.fileName, accountPreferences.storagePath ) - // Exposing as a getter so path/filename preferences can be fetched from a separate location if needed. - val accountPreferences: AccountPreferences - get() = _accountPreferences - @RequiresApi(Build.VERSION_CODES.M) suspend fun getAccount(): AccountInstance { val saveKeyHex = getAccountKey()