fix: nostr operations cause app crashing (#20)

Reviewed-on: #20
This commit was merged in pull request #20.
This commit is contained in:
2026-06-12 08:49:14 +00:00
parent 28550f8e25
commit 00821a864b
6 changed files with 47 additions and 43 deletions

View File

@@ -33,7 +33,7 @@ kotlin {
implementation(libs.androidx.lifecycle.runtimeCompose)
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2")
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.8.0")
implementation("su.reya:nostr-sdk-kmp:0.2.6")
implementation("su.reya:nostr-sdk-kmp:0.2.7")
implementation("com.squareup.okio:okio:3.16.2")
}
androidMain.dependencies {

View File

@@ -379,27 +379,25 @@ class Nostr {
private suspend fun setCachedRumor(giftId: EventId, rumor: UnsignedEvent) {
try {
val currentUser =
signer.currentUser ?: throw IllegalStateException("User not signed in")
// Construct the room id
val roomId = rumor.roomId()
// Construct reference tags
val tags = listOf(
Tag.identifier(giftId.toHex()),
Tag.publicKey(rumor.author()),
Tag.event(rumor.id()!!),
Tag.custom("a", listOf(roomId.toString())),
Tag.custom("r", listOf(roomId.toString())),
Tag.custom("k", listOf("14"))
)
// Set event kind
val kind = Kind.fromStd(KindStandard.APPLICATION_SPECIFIC_DATA);
// Construct event
val event = EventBuilder(kind, rumor.asJson())
.tags(tags)
.finalizeUnsigned(currentUser)
.signAsync(Keys.generate())
.finalizeAsync(Keys.generate())
client?.database()?.saveEvent(event)
} catch (e: Exception) {
@@ -408,27 +406,22 @@ class Nostr {
}
private suspend fun extractRumor(event: Event): UnsignedEvent? {
// Check if the rumor is already cached
val cachedRumor = getCachedRumor(event.id())
if (cachedRumor != null) return cachedRumor
try {
// Check if the rumor is already cached
val cachedRumor = getCachedRumor(event.id())
if (cachedRumor != null) return cachedRumor
// Get all signers
val signers = listOfNotNull(signer, deviceSigner)
if (signers.isEmpty()) return null
// Unwrap the gift with current signer
val gift = UnwrappedGift.fromGiftWrapAsync(signer = signer, giftWrap = event)
val rumor = gift.rumor()
// Try to unwrap the gift with each signer
for (signer in signers) {
try {
val gift = UnwrappedGift.fromGiftWrapAsync(signer = signer, giftWrap = event)
val rumor = gift.rumor()
// Save the rumor to the database
setCachedRumor(event.id(), rumor)
// Return the rumor
return rumor
} catch (e: Exception) {
println("Failed to unwrap gift: ${e.message}")
continue
}
// Save the rumor to the database
setCachedRumor(event.id(), rumor)
// Return the rumor
return rumor
} catch (e: Exception) {
println("Failed to unwrap gift: ${e.message}")
}
return null
@@ -686,12 +679,14 @@ class Nostr {
suspend fun getChatRooms(): Set<Room>? {
try {
val userPubkey = signer.currentUser ?: throw IllegalStateException("User not signed in")
val userPubkey =
signer.getPublicKeyAsync() ?: throw IllegalStateException("User not signed in")
val kind = Kind.fromStd(KindStandard.APPLICATION_SPECIFIC_DATA)
val kTag = SingleLetterTag.lowercase(Alphabet.K)
// Get all events sent by the user
val filter = Filter().kind(kind).author(userPubkey).customTags(kTag, listOf("14", "dm"))
val filter = Filter().kind(kind).pubkey(userPubkey).customTags(kTag, listOf("14", "dm"))
val events = client?.database()?.query(filter)
// Collect rooms
@@ -707,8 +702,9 @@ class Nostr {
// Check if the room already exists
if (existingRoom == null || newRoom.createdAt.asSecs() > existingRoom.createdAt.asSecs()) {
val filter =
Filter().kind(kind).author(userPubkey).pubkeys(newRoom.members.toList())
val kind = Kind.fromStd(KindStandard.PRIVATE_DIRECT_MESSAGE)
val pubkeys = newRoom.members.toList()
val filter = Filter().kind(kind).author(userPubkey).pubkeys(pubkeys)
// Determine if it's an ongoing room
val isOngoing = client?.database()?.query(filter)?.isEmpty() == false
@@ -789,7 +785,7 @@ class Nostr {
) {
try {
val currentUser =
signer.currentUser ?: throw IllegalStateException("User not signed in")
signer.getPublicKeyAsync() ?: throw IllegalStateException("User not signed in")
val tags = mutableListOf<Tag>()
@@ -816,6 +812,7 @@ class Nostr {
val rumor = EventBuilder(Kind.fromStd(KindStandard.PRIVATE_DIRECT_MESSAGE), content)
.tags(tags)
.finalizeUnsigned(currentUser)
.ensureId()
// Emit the rumor to the chat screen
if (receiver == currentUser) {