Browse Source

fix inbox/outbox selection

master
silberengel 7 months ago
parent
commit
e8ce9bb8eb
  1. 72
      src/lib/components/Notifications.svelte
  2. 54
      src/lib/utils/kind24_utils.ts

72
src/lib/components/Notifications.svelte

@ -460,8 +460,22 @@
try { try {
isComposingMessage = true; isComposingMessage = true;
// Create p-tags for all recipients // Create p-tags for all recipients (ensure hex format)
const pTags = selectedRecipients.map(recipient => ["p", recipient.pubkey!]); const pTags = selectedRecipients.map(recipient => {
let pubkey = recipient.pubkey!;
// Convert npub to hex if needed
if (pubkey.startsWith('npub')) {
try {
const decoded = nip19.decode(pubkey);
if (decoded.type === 'npub') {
pubkey = decoded.data;
}
} catch (e) {
console.warn("[Send Message] Failed to decode npub:", pubkey, e);
}
}
return ["p", pubkey];
});
// Add q tag if replying to a message (for jump-to functionality) // Add q tag if replying to a message (for jump-to functionality)
if (replyToMessage) { if (replyToMessage) {
@ -470,8 +484,22 @@
pTags.push(["q", replyToMessage.id, relayUrl, replyToMessage.pubkey]); pTags.push(["q", replyToMessage.id, relayUrl, replyToMessage.pubkey]);
} }
// Get all recipient pubkeys for relay calculation // Get all recipient pubkeys for relay calculation (ensure hex format)
const recipientPubkeys = selectedRecipients.map(r => r.pubkey!); const recipientPubkeys = selectedRecipients.map(r => {
let pubkey = r.pubkey!;
// Convert npub to hex if needed
if (pubkey.startsWith('npub')) {
try {
const decoded = nip19.decode(pubkey);
if (decoded.type === 'npub') {
pubkey = decoded.data;
}
} catch (e) {
console.warn("[Send Message Relay Calc] Failed to decode npub:", pubkey, e);
}
}
return pubkey;
});
// Calculate relay set using the same logic as kind24_utils // Calculate relay set using the same logic as kind24_utils
const senderPubkey = $userStore.pubkey; const senderPubkey = $userStore.pubkey;
@ -786,8 +814,25 @@
// Calculate relay set when recipients change // Calculate relay set when recipients change
$effect(() => { $effect(() => {
const senderPubkey = $userStore.pubkey; const senderPubkey = $userStore.pubkey;
console.log("[Relay Effect] Recipients changed:", selectedRecipients.length, "Sender:", senderPubkey?.slice(0, 8));
if (selectedRecipients.length > 0 && senderPubkey) { if (selectedRecipients.length > 0 && senderPubkey) {
const recipientPubkeys = selectedRecipients.map(r => r.pubkey!); const recipientPubkeys = selectedRecipients.map(r => {
const pubkey = r.pubkey!;
// Convert npub to hex if needed
if (pubkey.startsWith('npub')) {
try {
const decoded = nip19.decode(pubkey);
if (decoded.type === 'npub') {
return decoded.data;
}
} catch (e) {
console.warn("[Relay Effect] Failed to decode npub:", pubkey, e);
}
}
return pubkey;
});
console.log("[Relay Effect] Getting relay sets for recipients (hex):", recipientPubkeys.map(p => p.slice(0, 8)));
// Get relay sets for all recipients and combine them // Get relay sets for all recipients and combine them
const relaySetPromises = recipientPubkeys.map(recipientPubkey => const relaySetPromises = recipientPubkeys.map(recipientPubkey =>
@ -795,15 +840,28 @@
); );
Promise.all(relaySetPromises).then(relaySets => { Promise.all(relaySetPromises).then(relaySets => {
console.log("[Relay Effect] Received relay sets:", relaySets);
// Combine and deduplicate all relay sets // Combine and deduplicate all relay sets
const allRelays = relaySets.flat(); const allRelays = relaySets.flat();
const uniqueRelays = [...new Set(allRelays)]; const uniqueRelays = [...new Set(allRelays)];
console.log("[Relay Effect] Final relay list:", uniqueRelays);
// If no relays found from NIP-65, use fallback relays
if (uniqueRelays.length === 0) {
console.log("[Relay Effect] No NIP-65 relays found, using fallback");
const fallbackRelays = getAvailableRelays();
newMessageRelays = fallbackRelays.slice(0, 5); // Limit to first 5 for performance
} else {
newMessageRelays = uniqueRelays; newMessageRelays = uniqueRelays;
}
}).catch(error => { }).catch(error => {
console.error("Error getting relay set:", error); console.error("[Relay Effect] Error getting relay set:", error);
newMessageRelays = []; console.log("[Relay Effect] Using fallback relays due to error");
const fallbackRelays = getAvailableRelays();
newMessageRelays = fallbackRelays.slice(0, 5);
}); });
} else { } else {
console.log("[Relay Effect] Clearing relays - no recipients or sender");
newMessageRelays = []; newMessageRelays = [];
} }
}); });

54
src/lib/utils/kind24_utils.ts

@ -31,12 +31,11 @@ async function getUseroutboxRelays(ndk: NDK, user: NDKUser): Promise<string[]> {
if (tag[0] === 'r' && tag[1]) { if (tag[0] === 'r' && tag[1]) {
// NIP-65: r tags with optional inbox/outbox markers // NIP-65: r tags with optional inbox/outbox markers
const marker = tag[2]; const marker = tag[2];
if (!marker || marker === 'outbox' || marker === 'inbox') { if (!marker || marker === 'outbox' || marker === 'both') {
// If no marker or marker is 'outbox', it's a outbox relay // If no marker, marker is 'outbox', or marker is 'both', it's an outbox relay
// If marker is 'inbox', it's also a outbox relay (NIP-65 allows both)
outboxRelays.push(tag[1]); outboxRelays.push(tag[1]);
} }
// Note: inbox-only relays are NOT included in outbox relays
} }
}); });
@ -56,6 +55,7 @@ async function getUseroutboxRelays(ndk: NDK, user: NDKUser): Promise<string[]> {
*/ */
async function getUserinboxRelays(ndk: NDK, user: NDKUser): Promise<string[]> { async function getUserinboxRelays(ndk: NDK, user: NDKUser): Promise<string[]> {
try { try {
console.log(`[getUserinboxRelays] Fetching kind 10002 for user: ${user.pubkey.slice(0, 8)}`);
const relayList = await ndk.fetchEvent( const relayList = await ndk.fetchEvent(
{ {
@ -65,27 +65,31 @@ async function getUserinboxRelays(ndk: NDK, user: NDKUser): Promise<string[]> {
); );
if (!relayList) { if (!relayList) {
console.log(`[getUserinboxRelays] No kind 10002 relay list found for user: ${user.pubkey.slice(0, 8)}`);
return []; return [];
} }
console.log(`[getUserinboxRelays] Found relay list for user: ${user.pubkey.slice(0, 8)}, tags:`, relayList.tags);
const inboxRelays: string[] = []; const inboxRelays: string[] = [];
relayList.tags.forEach((tag) => { relayList.tags.forEach((tag) => {
if (tag[0] === 'r' && tag[1]) { if (tag[0] === 'r' && tag[1]) {
// NIP-65: r tags with optional inbox/outbox markers // NIP-65: r tags with optional inbox/outbox markers
const marker = tag[2]; const marker = tag[2];
if (!marker || marker === 'inbox' || marker === 'outbox') { console.log(`[getUserinboxRelays] Processing relay tag:`, tag, `marker: ${marker}`);
// If no marker or marker is 'inbox', it's a inbox relay if (!marker || marker === 'inbox' || marker === 'both') {
// If marker is 'outbox', it's also a inbox relay (NIP-65 allows both) // If no marker, marker is 'inbox', or marker is 'both', it's an inbox relay
inboxRelays.push(tag[1]); inboxRelays.push(tag[1]);
console.log(`[getUserinboxRelays] Added inbox relay: ${tag[1]} (marker: ${marker || 'none'})`);
} }
// Note: outbox-only relays are NOT included in inbox relays
} }
}); });
console.log(`[getUserinboxRelays] Final inbox relays for user ${user.pubkey.slice(0, 8)}:`, inboxRelays);
return inboxRelays; return inboxRelays;
} catch (error) { } catch (error) {
console.error(`[getUserinboxRelays] Error fetching inbox relays for user ${user.pubkey.slice(0, 8)}:`, error);
return []; return [];
} }
} }
@ -117,7 +121,13 @@ export async function createKind24Reply(
// Get recipient's inbox relays (NIP-65) // Get recipient's inbox relays (NIP-65)
const recipientUser = ndk.getUser({ pubkey: recipientPubkey }); const recipientUser = ndk.getUser({ pubkey: recipientPubkey });
const recipientinboxRelays = await getUserinboxRelays(ndk, recipientUser); let recipientinboxRelays = await getUserinboxRelays(ndk, recipientUser);
// Fallback: if no inbox relays found, use recipient's outbox relays
if (recipientinboxRelays.length === 0) {
console.log(`[createKind24Reply] No inbox relays found for recipient, falling back to outbox relays`);
recipientinboxRelays = await getUseroutboxRelays(ndk, recipientUser);
}
// According to NIP-A4: Messages MUST be sent to the NIP-65 inbox relays of each receiver // According to NIP-A4: Messages MUST be sent to the NIP-65 inbox relays of each receiver
// and the outbox relay of the sender // and the outbox relay of the sender
@ -212,17 +222,29 @@ export async function getKind24RelaySet(
throw new Error("NDK not available"); throw new Error("NDK not available");
} }
console.log(`[getKind24RelaySet] Getting relays for sender: ${senderPubkey.slice(0, 8)} -> recipient: ${recipientPubkey.slice(0, 8)}`);
// Get sender's outbox relays (NIP-65) // Get sender's outbox relays (NIP-65)
const senderUser = ndk.getUser({ pubkey: senderPubkey }); const senderUser = ndk.getUser({ pubkey: senderPubkey });
const senderoutboxRelays = await getUseroutboxRelays(ndk, senderUser); const senderoutboxRelays = await getUseroutboxRelays(ndk, senderUser);
console.log(`[getKind24RelaySet] Sender outbox relays:`, senderoutboxRelays);
// Get recipient's inbox relays (NIP-65) // Get recipient's inbox relays (NIP-65)
const recipientUser = ndk.getUser({ pubkey: recipientPubkey }); const recipientUser = ndk.getUser({ pubkey: recipientPubkey });
const recipientinboxRelays = await getUserinboxRelays(ndk, recipientUser); let recipientinboxRelays = await getUserinboxRelays(ndk, recipientUser);
console.log(`[getKind24RelaySet] Recipient inbox relays:`, recipientinboxRelays);
// Fallback: if no inbox relays found, use recipient's outbox relays
if (recipientinboxRelays.length === 0) {
console.log(`[getKind24RelaySet] No inbox relays found for recipient, falling back to outbox relays`);
recipientinboxRelays = await getUseroutboxRelays(ndk, recipientUser);
console.log(`[getKind24RelaySet] Recipient outbox relays (used as fallback):`, recipientinboxRelays);
}
// According to NIP-A4: Messages MUST be sent to the NIP-65 inbox relays of each receiver // According to NIP-A4: Messages MUST be sent to the NIP-65 inbox relays of each receiver
// and the outbox relay of the sender // and the outbox relay of the sender
const targetRelays = [...new Set([...senderoutboxRelays, ...recipientinboxRelays])]; const targetRelays = [...new Set([...senderoutboxRelays, ...recipientinboxRelays])];
console.log(`[getKind24RelaySet] Combined target relays:`, targetRelays);
// Prioritize common relays between sender and recipient for better privacy // Prioritize common relays between sender and recipient for better privacy
const commonRelays = senderoutboxRelays.filter((relay: string) => const commonRelays = senderoutboxRelays.filter((relay: string) =>
@ -235,6 +257,12 @@ export async function getKind24RelaySet(
!senderoutboxRelays.includes(relay) !senderoutboxRelays.includes(relay)
); );
console.log(`[getKind24RelaySet] Common relays:`, commonRelays);
console.log(`[getKind24RelaySet] Sender-only relays:`, senderOnlyRelays);
console.log(`[getKind24RelaySet] Recipient-only relays:`, recipientOnlyRelays);
// Prioritize: common relays first, then sender outbox, then recipient inbox // Prioritize: common relays first, then sender outbox, then recipient inbox
return [...commonRelays, ...senderOnlyRelays, ...recipientOnlyRelays]; const finalRelays = [...commonRelays, ...senderOnlyRelays, ...recipientOnlyRelays];
console.log(`[getKind24RelaySet] Final relay list:`, finalRelays);
return finalRelays;
} }

Loading…
Cancel
Save