diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/LocalPreferences.kt b/app/src/main/java/com/greenart7c3/nostrsigner/LocalPreferences.kt index fb9095f3..daf77595 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/LocalPreferences.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/LocalPreferences.kt @@ -363,6 +363,7 @@ object LocalPreferences { */ @SuppressLint("ApplySharedPref") fun updatePrefsForLogout(npub: String, context: Context): Boolean { + accountCache.get(npub)?.clearSignerCache() accountCache.remove(npub) val userPrefs = sharedPrefs(context, npub) userPrefs.edit(commit = true) { clear() } diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/models/Account.kt b/app/src/main/java/com/greenart7c3/nostrsigner/models/Account.kt index 1faa9d06..45c8836d 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/models/Account.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/models/Account.kt @@ -24,11 +24,14 @@ import com.vitorpamplona.quartz.nip49PrivKeyEnc.Nip49 import com.vitorpamplona.quartz.nip55AndroidSigner.signString import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent import com.vitorpamplona.quartz.nip57Zaps.PrivateZapRequestBuilder +import java.lang.ref.WeakReference import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock @Stable class Account( @@ -41,9 +44,30 @@ class Account( ) { val saveable: AccountLiveData = AccountLiveData(this) + @Volatile + private var signerCache: WeakReference? = null + + private val signerMutex = Mutex() + private suspend fun getSigner(): NostrSignerInternal { - val privKey = DataStoreAccess.getEncryptedKey(Amber.instance, npub, DataStoreAccess.NOSTR_PRIVKEY)!! - return NostrSignerInternal(KeyPair(privKey.hexToByteArray())) + signerCache?.get()?.let { return it } + + return signerMutex.withLock { + signerCache?.get()?.let { return it } + + val privKey = DataStoreAccess.getEncryptedKey( + Amber.instance, + npub, + DataStoreAccess.NOSTR_PRIVKEY, + ) ?: throw CancellationException("Signer unavailable") + + val signer = NostrSignerInternal( + KeyPair(privKey.hexToByteArray()), + ) + + signerCache = WeakReference(signer) + signer + } } suspend fun sign(eventTemplate: EventTemplate): T { @@ -138,6 +162,11 @@ class Account( } } } + + fun clearSignerCache() { + signerCache?.clear() + signerCache = null + } } class AccountLiveData(account: Account) : LiveData(AccountState(account))