chore: merge the develop branch into master #1

Merged
reya merged 43 commits from develop into master 2026-05-23 00:50:13 +00:00
2 changed files with 44 additions and 1 deletions
Showing only changes of commit 77f4ea71b1 - Show all commits

View File

@@ -26,7 +26,7 @@ kotlin {
commonMain.dependencies { commonMain.dependencies {
implementation("org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose:2.10.0") implementation("org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose:2.10.0")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2")
implementation("su.reya:nostr-sdk-kmp:0.1") implementation("su.reya:nostr-sdk-kmp:0.1.1")
} }
commonTest.dependencies { commonTest.dependencies {
implementation(libs.kotlin.test) implementation(libs.kotlin.test)

View File

@@ -30,6 +30,7 @@ import rust.nostr.sdk.Tag
import rust.nostr.sdk.Timestamp import rust.nostr.sdk.Timestamp
import rust.nostr.sdk.UnsignedEvent import rust.nostr.sdk.UnsignedEvent
import rust.nostr.sdk.UnwrappedGift import rust.nostr.sdk.UnwrappedGift
import rust.nostr.sdk.extractMessagingRelayList
class Nostr { class Nostr {
var client: Client? = null var client: Client? = null
@@ -88,6 +89,14 @@ class Nostr {
getUserMetadata() getUserMetadata()
} }
suspend fun isSignedByUser(event: Event): Boolean {
return try {
signer?.getPublicKey()?.toBech32() == event.author().toBech32()
} catch (e: Exception) {
false
}
}
suspend fun getUserMetadata() { suspend fun getUserMetadata() {
val userPubkey = signer?.getPublicKey() ?: return val userPubkey = signer?.getPublicKey() ?: return
@@ -110,9 +119,34 @@ class Nostr {
client?.subscribe(target = target, id = "user-metadata", closeOn = opts) client?.subscribe(target = target, id = "user-metadata", closeOn = opts)
} }
suspend fun getUserMessages(msgRelayList: Event) {
val userPubkey = signer?.getPublicKey() ?: return
val relays = extractMessagingRelayList(msgRelayList)
// Ensure relay connections
relays.forEach { relay ->
client?.addRelay(relay, RelayCapabilities.none())
client?.connectRelay(relay)
}
// Construct a filter for gift wrap events
val filter = Filter().kind(Kind.fromStd(KindStandard.GIFT_WRAP)).pubkey(userPubkey)
val target = mutableMapOf<RelayUrl, List<Filter>>()
relays.forEach { relay ->
target[relay] = listOf(filter)
}
client?.subscribe(
target = ReqTarget.manual(target),
id = "user-messages",
closeOn = null
)
}
suspend fun handleNotifications(onMetadataUpdate: (PublicKey, Metadata) -> Unit) { suspend fun handleNotifications(onMetadataUpdate: (PublicKey, Metadata) -> Unit) {
val now = Timestamp.now() val now = Timestamp.now()
val notifications = client?.notifications() val notifications = client?.notifications()
val processedEvent = mutableSetOf<EventId>()
while (true) { while (true) {
val notification = notifications?.next() ?: break val notification = notifications?.next() ?: break
@@ -126,6 +160,9 @@ class Nostr {
is RelayMessageEnum.EventMsg -> { is RelayMessageEnum.EventMsg -> {
val event = message.event val event = message.event
// Prevent processing duplicate events
if (processedEvent.contains(event.id())) continue
processedEvent.add(event.id())
if (event.kind().asStd() == KindStandard.METADATA) { if (event.kind().asStd() == KindStandard.METADATA) {
try { try {
@@ -136,6 +173,12 @@ class Nostr {
} }
} }
if (event.kind().asStd() == KindStandard.INBOX_RELAYS) {
if (isSignedByUser(event = event)) {
getUserMessages(msgRelayList = event)
}
}
if (event.kind().asStd() == KindStandard.GIFT_WRAP) { if (event.kind().asStd() == KindStandard.GIFT_WRAP) {
try { try {
val rumor = extractRumor(event) val rumor = extractRumor(event)