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 @@ @@ -460,8 +460,22 @@
try {
isComposingMessage = true;
// Create p-tags for all recipients
const pTags = selectedRecipients.map(recipient => ["p", recipient.pubkey!]);
// Create p-tags for all recipients (ensure hex format)
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)
if (replyToMessage) {
@ -470,8 +484,22 @@ @@ -470,8 +484,22 @@
pTags.push(["q", replyToMessage.id, relayUrl, replyToMessage.pubkey]);
}
// Get all recipient pubkeys for relay calculation
const recipientPubkeys = selectedRecipients.map(r => r.pubkey!);
// Get all recipient pubkeys for relay calculation (ensure hex format)
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
const senderPubkey = $userStore.pubkey;
@ -786,8 +814,25 @@ @@ -786,8 +814,25 @@
// Calculate relay set when recipients change
$effect(() => {
const senderPubkey = $userStore.pubkey;
console.log("[Relay Effect] Recipients changed:", selectedRecipients.length, "Sender:", senderPubkey?.slice(0, 8));
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
const relaySetPromises = recipientPubkeys.map(recipientPubkey =>
@ -795,15 +840,28 @@ @@ -795,15 +840,28 @@
);
Promise.all(relaySetPromises).then(relaySets => {
console.log("[Relay Effect] Received relay sets:", relaySets);
// Combine and deduplicate all relay sets
const allRelays = relaySets.flat();
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;
}
}).catch(error => {
console.error("Error getting relay set:", error);
newMessageRelays = [];
console.error("[Relay Effect] Error getting relay set:", error);
console.log("[Relay Effect] Using fallback relays due to error");
const fallbackRelays = getAvailableRelays();
newMessageRelays = fallbackRelays.slice(0, 5);
});
} else {
console.log("[Relay Effect] Clearing relays - no recipients or sender");
newMessageRelays = [];
}
});

54
src/lib/utils/kind24_utils.ts

@ -31,12 +31,11 @@ async function getUseroutboxRelays(ndk: NDK, user: NDKUser): Promise<string[]> { @@ -31,12 +31,11 @@ async function getUseroutboxRelays(ndk: NDK, user: NDKUser): Promise<string[]> {
if (tag[0] === 'r' && tag[1]) {
// NIP-65: r tags with optional inbox/outbox markers
const marker = tag[2];
if (!marker || marker === 'outbox' || marker === 'inbox') {
// If no marker or marker is 'outbox', it's a outbox relay
// If marker is 'inbox', it's also a outbox relay (NIP-65 allows both)
if (!marker || marker === 'outbox' || marker === 'both') {
// If no marker, marker is 'outbox', or marker is 'both', it's an outbox relay
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[]> { @@ -56,6 +55,7 @@ async function getUseroutboxRelays(ndk: NDK, user: NDKUser): Promise<string[]> {
*/
async function getUserinboxRelays(ndk: NDK, user: NDKUser): Promise<string[]> {
try {
console.log(`[getUserinboxRelays] Fetching kind 10002 for user: ${user.pubkey.slice(0, 8)}`);
const relayList = await ndk.fetchEvent(
{
@ -65,27 +65,31 @@ async function getUserinboxRelays(ndk: NDK, user: NDKUser): Promise<string[]> { @@ -65,27 +65,31 @@ async function getUserinboxRelays(ndk: NDK, user: NDKUser): Promise<string[]> {
);
if (!relayList) {
console.log(`[getUserinboxRelays] No kind 10002 relay list found for user: ${user.pubkey.slice(0, 8)}`);
return [];
}
console.log(`[getUserinboxRelays] Found relay list for user: ${user.pubkey.slice(0, 8)}, tags:`, relayList.tags);
const inboxRelays: string[] = [];
relayList.tags.forEach((tag) => {
if (tag[0] === 'r' && tag[1]) {
// NIP-65: r tags with optional inbox/outbox markers
const marker = tag[2];
if (!marker || marker === 'inbox' || marker === 'outbox') {
// If no marker or marker is 'inbox', it's a inbox relay
// If marker is 'outbox', it's also a inbox relay (NIP-65 allows both)
console.log(`[getUserinboxRelays] Processing relay tag:`, tag, `marker: ${marker}`);
if (!marker || marker === 'inbox' || marker === 'both') {
// If no marker, marker is 'inbox', or marker is 'both', it's an inbox relay
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;
} catch (error) {
console.error(`[getUserinboxRelays] Error fetching inbox relays for user ${user.pubkey.slice(0, 8)}:`, error);
return [];
}
}
@ -117,7 +121,13 @@ export async function createKind24Reply( @@ -117,7 +121,13 @@ export async function createKind24Reply(
// Get recipient's inbox relays (NIP-65)
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
// and the outbox relay of the sender
@ -212,17 +222,29 @@ export async function getKind24RelaySet( @@ -212,17 +222,29 @@ export async function getKind24RelaySet(
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)
const senderUser = ndk.getUser({ pubkey: senderPubkey });
const senderoutboxRelays = await getUseroutboxRelays(ndk, senderUser);
console.log(`[getKind24RelaySet] Sender outbox relays:`, senderoutboxRelays);
// Get recipient's inbox relays (NIP-65)
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
// and the outbox relay of the sender
const targetRelays = [...new Set([...senderoutboxRelays, ...recipientinboxRelays])];
console.log(`[getKind24RelaySet] Combined target relays:`, targetRelays);
// Prioritize common relays between sender and recipient for better privacy
const commonRelays = senderoutboxRelays.filter((relay: string) =>
@ -235,6 +257,12 @@ export async function getKind24RelaySet( @@ -235,6 +257,12 @@ export async function getKind24RelaySet(
!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
return [...commonRelays, ...senderOnlyRelays, ...recipientOnlyRelays];
const finalRelays = [...commonRelays, ...senderOnlyRelays, ...recipientOnlyRelays];
console.log(`[getKind24RelaySet] Final relay list:`, finalRelays);
return finalRelays;
}

Loading…
Cancel
Save