Avoid dependency of AccountSettings for NwcSignerState

This commit is contained in:
Vitor Pamplona
2026-02-08 12:04:51 -05:00
parent 913b694f78
commit 9d8c1f3ffe
3 changed files with 18 additions and 18 deletions
@@ -250,7 +250,7 @@ class Account(
val userMetadata = UserMetadataState(signer, cache, scope, settings) val userMetadata = UserMetadataState(signer, cache, scope, settings)
override val nip47SignerState = NwcSignerState(signer, nwcFilterAssembler, cache, scope, settings) override val nip47SignerState = NwcSignerState(signer, nwcFilterAssembler, cache, scope, settings.zapPaymentRequest)
val nip65RelayList = Nip65RelayListState(signer, cache, scope, settings) val nip65RelayList = Nip65RelayListState(signer, cache, scope, settings)
val localRelayList = LocalRelayListState(signer, cache, scope, settings) val localRelayList = LocalRelayListState(signer, cache, scope, settings)
@@ -122,7 +122,7 @@ class AccountSettings(
val defaultStoriesFollowList: MutableStateFlow<String> = MutableStateFlow(GLOBAL_FOLLOWS), val defaultStoriesFollowList: MutableStateFlow<String> = MutableStateFlow(GLOBAL_FOLLOWS),
val defaultNotificationFollowList: MutableStateFlow<String> = MutableStateFlow(GLOBAL_FOLLOWS), val defaultNotificationFollowList: MutableStateFlow<String> = MutableStateFlow(GLOBAL_FOLLOWS),
val defaultDiscoveryFollowList: MutableStateFlow<String> = MutableStateFlow(GLOBAL_FOLLOWS), val defaultDiscoveryFollowList: MutableStateFlow<String> = MutableStateFlow(GLOBAL_FOLLOWS),
var zapPaymentRequest: MutableStateFlow<Nip47WalletConnect.Nip47URINorm?> = MutableStateFlow(null), val zapPaymentRequest: MutableStateFlow<Nip47WalletConnect.Nip47URINorm?> = MutableStateFlow(null),
var hideDeleteRequestDialog: Boolean = false, var hideDeleteRequestDialog: Boolean = false,
var hideBlockAlertDialog: Boolean = false, var hideBlockAlertDialog: Boolean = false,
var hideNIP17WarningDialog: Boolean = false, var hideNIP17WarningDialog: Boolean = false,
@@ -144,7 +144,7 @@ class AccountSettings(
var backupEphemeralChatList: EphemeralChatListEvent? = null, var backupEphemeralChatList: EphemeralChatListEvent? = null,
var backupTrustProviderList: TrustProviderListEvent? = null, var backupTrustProviderList: TrustProviderListEvent? = null,
val lastReadPerRoute: MutableStateFlow<Map<String, MutableStateFlow<Long>>> = MutableStateFlow(mapOf()), val lastReadPerRoute: MutableStateFlow<Map<String, MutableStateFlow<Long>>> = MutableStateFlow(mapOf()),
var hasDonatedInVersion: MutableStateFlow<Set<String>> = MutableStateFlow(setOf<String>()), val hasDonatedInVersion: MutableStateFlow<Set<String>> = MutableStateFlow(setOf<String>()),
val pendingAttestations: MutableStateFlow<Map<HexKey, String>> = MutableStateFlow<Map<HexKey, String>>(mapOf()), val pendingAttestations: MutableStateFlow<Map<HexKey, String>> = MutableStateFlow<Map<HexKey, String>>(mapOf()),
var backupNipA3PaymentTargets: PaymentTargetsEvent? = null, var backupNipA3PaymentTargets: PaymentTargetsEvent? = null,
) : EphemeralChatRepository, ) : EphemeralChatRepository,
@@ -21,11 +21,11 @@
package com.vitorpamplona.amethyst.model.nip47WalletConnect package com.vitorpamplona.amethyst.model.nip47WalletConnect
import com.vitorpamplona.amethyst.commons.model.INwcSignerState import com.vitorpamplona.amethyst.commons.model.INwcSignerState
import com.vitorpamplona.amethyst.model.AccountSettings
import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.nwc.NWCPaymentFilterAssembler import com.vitorpamplona.amethyst.service.relayClient.reqCommand.nwc.NWCPaymentFilterAssembler
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.nwc.NWCPaymentQueryState import com.vitorpamplona.amethyst.service.relayClient.reqCommand.nwc.NWCPaymentQueryState
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
@@ -41,6 +41,7 @@ import com.vitorpamplona.quartz.nip47WalletConnect.Response
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
@@ -59,14 +60,14 @@ import kotlinx.coroutines.launch
* @property signer the main Nostr signer used for general Nostr operations * @property signer the main Nostr signer used for general Nostr operations
* @property cache the local cache for handling notes and events * @property cache the local cache for handling notes and events
* @property scope the coroutine scope used for async operations * @property scope the coroutine scope used for async operations
* @property settings the account settings containing NIP-47 configuration * @property nip47Setup the NIP-47 configuration
*/ */
class NwcSignerState( class NwcSignerState(
val signer: NostrSigner, val signer: NostrSigner,
val nwcFilterAssembler: NWCPaymentFilterAssembler, val nwcFilterAssembler: NWCPaymentFilterAssembler,
val cache: LocalCache, val cache: LocalCache,
val scope: CoroutineScope, val scope: CoroutineScope,
val settings: AccountSettings, val nip47Setup: MutableStateFlow<Nip47WalletConnect.Nip47URINorm?>,
) : INwcSignerState { ) : INwcSignerState {
/** /**
* Derives a NIP-47 signer from the zap payment request in settings. * Derives a NIP-47 signer from the zap payment request in settings.
@@ -74,14 +75,14 @@ class NwcSignerState(
* Flows updates whenever settings change. * Flows updates whenever settings change.
*/ */
val nip47Signer = val nip47Signer =
settings.zapPaymentRequest nip47Setup
.map { .map {
buildSigner(it) ?: signer buildSigner(it) ?: signer
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
.stateIn( .stateIn(
scope, scope,
SharingStarted.Eagerly, SharingStarted.Eagerly,
buildSigner(settings.zapPaymentRequest.value) ?: signer, buildSigner(nip47Setup.value) ?: signer,
) )
/** /**
@@ -111,30 +112,30 @@ class NwcSignerState(
NostrSignerInternal(KeyPair(it)) NostrSignerInternal(KeyPair(it))
} }
fun hasWalletConnectSetup(): Boolean = settings.zapPaymentRequest.value != null fun hasWalletConnectSetup(): Boolean = nip47Setup.value != null
override fun isNIP47Author(pubkeyHex: String?): Boolean = nip47Signer.value.pubKey == pubkeyHex override fun isNIP47Author(pubkey: HexKey?): Boolean = nip47Signer.value.pubKey == pubkey
/** /**
* Decrypts a NIP-47 payment request using the current signer. * Decrypts a NIP-47 payment request using the current signer.
* *
* @param nwcRequest the NIP-47 payment request event to decrypt * @param event the NIP-47 payment request event to decrypt
* @return the decrypted request or null if not set up or decryption fails * @return the decrypted request or null if not set up or decryption fails
*/ */
override suspend fun decryptRequest(nwcRequest: LnZapPaymentRequestEvent): Request? { override suspend fun decryptRequest(event: LnZapPaymentRequestEvent): Request? {
if (!hasWalletConnectSetup()) return null if (!hasWalletConnectSetup()) return null
return zapPaymentRequestDecryptionCache.value.decryptRequest(nwcRequest) return zapPaymentRequestDecryptionCache.value.decryptRequest(event)
} }
/** /**
* Decrypts a NIP-47 payment response using the current signer. * Decrypts a NIP-47 payment response using the current signer.
* *
* @param nwsResponse the NIP-47 payment response event to decrypt * @param event the NIP-47 payment response event to decrypt
* @return the decrypted response or null if not set up or decryption fails * @return the decrypted response or null if not set up or decryption fails
*/ */
override suspend fun decryptResponse(nwsResponse: LnZapPaymentResponseEvent): Response? { override suspend fun decryptResponse(event: LnZapPaymentResponseEvent): Response? {
if (!hasWalletConnectSetup()) return null if (!hasWalletConnectSetup()) return null
return zapPaymentResponseDecryptionCache.value.decryptResponse(nwsResponse) return zapPaymentResponseDecryptionCache.value.decryptResponse(event)
} }
/** /**
@@ -152,8 +153,7 @@ class NwcSignerState(
zappedNote: Note?, zappedNote: Note?,
onResponse: (Response?) -> Unit, onResponse: (Response?) -> Unit,
): Pair<LnZapPaymentRequestEvent, NormalizedRelayUrl> { ): Pair<LnZapPaymentRequestEvent, NormalizedRelayUrl> {
val walletService = settings.zapPaymentRequest.value val walletService = nip47Setup.value ?: throw IllegalArgumentException("No NIP47 setup")
if (walletService == null) throw IllegalArgumentException("No NIP47 setup")
val event = LnZapPaymentRequestEvent.create(bolt11, walletService.pubKeyHex, nip47Signer.value) val event = LnZapPaymentRequestEvent.create(bolt11, walletService.pubKeyHex, nip47Signer.value)