fix(desktop): fetch account config (incl. blossom) from outbox relays

The account-config bootstrap subscription only queried the default relays,
so a user's Blossom server list (kind 10063) — published to their own write
relays, not the defaults — was never fetched, and the UI fell back to the
default server. NIP-65 relay lists hid the same gap because they're broadcast
widely and also have a local backup.

Add a subscription that re-fetches the account-config kinds (10002/10050/
10007/10006/10063) from the user's NIP-65 outbox (write + untagged relays)
once it's known, routing kind 10063 / 10002 through justConsumeMyOwnEvent
like the bootstrap does. This matches mobile's outbox model: the user's own
data comes from their write relays.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011dkzkEY6cUsRfqEb7giHi2
This commit is contained in:
Claude
2026-07-16 00:03:38 +00:00
parent f727c226c0
commit 152fc76bc0
@@ -1728,6 +1728,52 @@ fun MainContent(
onDispose { relayManager.unsubscribe(bootstrapSubId) }
}
// The bootstrap subscription above only reaches the default relays. A user's
// own account data — Blossom server list (kind 10063), DM/search/blocked
// relay lists — is published to their write relays, not the defaults, so it
// won't be found there. Re-fetch those kinds from the NIP-65 outbox
// (write + untagged relays) whenever it becomes known.
LaunchedEffect(iAccount) {
iAccount.nip65RelayList.outboxFlow.collect { outbox ->
if (outbox.isEmpty()) return@collect
relayManager.subscribe(
subId = "account-config-outbox",
filters =
listOf(
Filter(
kinds =
listOf(
AdvertisedRelayListEvent.KIND,
ChatMessageRelayListEvent.KIND,
SearchRelayListEvent.KIND,
BlockedRelayListEvent.KIND,
BlossomServersEvent.KIND,
),
authors = listOf(account.pubKeyHex),
limit = 10,
),
),
relays = outbox,
listener =
object : SubscriptionListener {
override fun onEvent(
event: com.vitorpamplona.quartz.nip01Core.core.Event,
isLive: Boolean,
relay: NormalizedRelayUrl,
forFilters: List<Filter>?,
) {
if (event is AdvertisedRelayListEvent || event is BlossomServersEvent) {
scope.launch(Dispatchers.IO) {
localCache.justConsumeMyOwnEvent(event)
}
}
accountRelays.consumeIfRelevant(event)
}
},
)
}
}
// Subscribe to incoming DMs and process into chatroomList
LaunchedEffect(account) {
relayManager.connectedRelays.first { it.isNotEmpty() }