fix nip-17 (#305)

* NIP-59 stuff

* nip-17 ios to androing works, android to ios still wip

* fix impl

* ios compat

* default relays for DMs

* delivery ack works

* delivery ack

---------

Co-authored-by: callebtc <93376500+callebtc@users.noreply.github.com>
This commit is contained in:
shroominic
2025-08-24 19:06:29 +02:00
committed by GitHub
co-authored by callebtc
parent 23c397fe7b
commit 47c40fb9f3
11 changed files with 308 additions and 158 deletions
@@ -119,7 +119,7 @@ class NostrGeohashService(
// Subscribe to gift wraps (NIP-17 private messages)
val dmFilter = NostrFilter.giftWrapsFor(
pubkey = currentIdentity.publicKeyHex,
since = System.currentTimeMillis() - 86400000L // Last 24 hours
since = System.currentTimeMillis() - 172800000L // Last 48 hours (align with NIP-17 randomization)
)
nostrRelayManager.subscribe(
@@ -234,7 +234,7 @@ class NostrGeohashService(
// Client-side filtering: ignore messages older than 24 hours + 15 minutes buffer
val messageAge = System.currentTimeMillis() / 1000 - giftWrap.createdAt
if (messageAge > 87300) { // 24 hours + 15 minutes
if (messageAge > 173700) { // 48 hours + 15 minutes
return
}
@@ -316,7 +316,27 @@ class NostrGeohashService(
// Store Nostr key mapping
nostrKeyMapping[targetPeerID] = senderPubkey
// Process payload and update UI/state
processNoisePayload(noisePayload, targetPeerID, senderNickname, messageTimestamp)
// If this was a private message, send a delivery ACK back over Nostr
if (noisePayload.type == com.bitchat.android.model.NoisePayloadType.PRIVATE_MESSAGE) {
val pm = com.bitchat.android.model.PrivateMessagePacket.decode(noisePayload.data)
pm?.let { pmsg ->
val nostrTransport = NostrTransport.getInstance(application)
// Prefer mapped peer route; fallback to direct Nostr using sender pubkey
if (senderNoiseKey != null) {
val peerIdHex = senderNoiseKey.joinToString("") { b -> "%02x".format(b) }
nostrTransport.sendDeliveryAck(pmsg.messageID, peerIdHex)
} else {
// Fallback: direct to senders Nostr pubkey (geohash-style)
val identity = NostrIdentityBridge.getCurrentNostrIdentity(application)
if (identity != null) {
nostrTransport.sendDeliveryAckGeohash(pmsg.messageID, senderPubkey, identity)
}
}
}
}
} catch (e: Exception) {
Log.e(TAG, "Error processing Nostr message: ${e.message}")
@@ -900,18 +920,17 @@ class NostrGeohashService(
val dmFilter = NostrFilter.giftWrapsFor(
pubkey = dmIdentity.publicKeyHex,
since = System.currentTimeMillis() - 86400000L // Last 24 hours
since = System.currentTimeMillis() - 172800000L // Last 48 hours (align with NIP-17 randomization)
)
nostrRelayManager.subscribeForGeohash(
geohash = channel.channel.geohash,
// IMPORTANT: For geohash DMs, use default relays (iOS behavior)
nostrRelayManager.subscribe(
filter = dmFilter,
id = dmSubId,
handler = { giftWrap ->
handleGeohashDmEvent(giftWrap, channel.channel.geohash, dmIdentity)
},
includeDefaults = false,
nRelays = 5
targetRelayUrls = null
)
Log.i(TAG, "✅ Subscribed to geohash DMs for identity: ${dmIdentity.publicKeyHex.take(16)}...")
@@ -1177,7 +1196,7 @@ class NostrGeohashService(
)
if (decryptResult == null) {
Log.w(TAG, "Failed to decrypt geohash DM")
Log.d(TAG, "Skipping geohash DM: unwrap/open failed (non-fatal)")
return
}
@@ -1235,7 +1254,11 @@ class NostrGeohashService(
// Add to private chats
privateChatManager.handleIncomingPrivateMessage(message)
// Always send delivery ACK for geohash DMs
val nostrTransport = NostrTransport.getInstance(application)
nostrTransport.sendDeliveryAckGeohash(messageId, senderPubkey, identity)
// Send read receipt if viewing this chat
if (isViewingThisChat) {
// Send read receipt via Nostr for geohash DM