fix(onchain-zaps): UserProfileZapsViewModel crashed casting kind 8333 as LnZapEvent

observeEvents<LnZapEvent>(filterAcceptingBothKinds) is generic-erased
at runtime, so an OnchainZapEvent landing in the cache (e.g. right
after sending an onchain zap from the wallet) flowed through and
crashed in sumAmountsByUser's forEach checkcast.

Observe as <Event> and dispatch on type: LnZapEvent keeps its
private-zap decryption path; OnchainZapEvent attributes the
claimedAmountInSats to event.pubKey (no zap-request envelope).
This commit is contained in:
Claude
2026-05-16 19:56:22 +00:00
parent 6361fb1c9d
commit 1d5ce994a6
@@ -28,6 +28,7 @@ import androidx.lifecycle.viewModelScope
import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
import com.vitorpamplona.quartz.nipBCOnchainZaps.zap.OnchainZapEvent
@@ -96,11 +97,24 @@ class UserProfileZapsViewModel(
}
}
suspend fun List<LnZapEvent>.sumAmountsByUser(): List<ZapAmount> {
private fun mapOnchainZap(event: OnchainZapEvent): ZapAmount {
val amountSats = event.claimedAmountInSats() ?: 0L
return ZapAmount(
LocalCache.getOrCreateUser(event.pubKey),
BigDecimal(amountSats),
)
}
suspend fun List<Event>.sumAmountsByUser(): List<ZapAmount> {
val results = mutableMapOf<User, BigDecimal>()
this.forEach { zapEvent ->
val zapAmount = mapRequest(zapEvent)
val zapAmount =
when (zapEvent) {
is LnZapEvent -> mapRequest(zapEvent)
is OnchainZapEvent -> mapOnchainZap(zapEvent)
else -> null
}
if (zapAmount != null) {
val existingAmount = results[zapAmount.user] ?: BigDecimal.ZERO
results[zapAmount.user] = existingAmount + zapAmount.amount
@@ -113,7 +127,7 @@ class UserProfileZapsViewModel(
@OptIn(kotlinx.coroutines.FlowPreview::class)
val receivedZapAmountsByUser: StateFlow<List<ZapAmount>> =
account.cache
.observeEvents<LnZapEvent>(zapsToUser)
.observeEvents<Event>(zapsToUser)
.sample(500)
.map { zapEvents ->
zapEvents.sumAmountsByUser()