diff options
| author | Adrien Hopkins <[email protected]> | 2025-11-13 17:24:48 -0500 |
|---|---|---|
| committer | Adrien Hopkins <[email protected]> | 2025-11-13 17:25:13 -0500 |
| commit | 64f200944f8016725016dfaa0e6db6a6f102b776 (patch) | |
| tree | 56225bed364712e246f8c7ca6d402cf67732ce7f | |
| parent | 3e4900606624220e6c112a5438698b03ee3c3943 (diff) | |
| download | coinos-ui-64f200944f8016725016dfaa0e6db6a6f102b776.tar.gz coinos-ui-64f200944f8016725016dfaa0e6db6a6f102b776.zip | |
Only send expiring DMs to compatible relays
| -rw-r--r-- | src/locales/en.json | 1 | ||||
| -rw-r--r-- | src/locales/fr.json | 1 | ||||
| -rw-r--r-- | src/routes/(app)/dm/[recipient]/+page.svelte | 40 |
3 files changed, 37 insertions, 5 deletions
diff --git a/src/locales/en.json b/src/locales/en.json index 427c8d96..869a6beb 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -97,6 +97,7 @@ "recipientMsg": "You are sending nostr messages to [R].", "sendMessage": "Send Message", "expiry": "Enable message expiry", + "cantSendExpiring": "None of [R]'s DM relays support message expiry. You can't send expiring messages to them.", "fadedWarning": "To avoid metadata leaks, messages expire at a random time up to 2 days after you specify; each message has its own random expiry time. Messages which appear faded are close to expiring; nearby messages may be missing.", "days": "days", "relaysNotFound": "Could not find [R]’s DM relays.", diff --git a/src/locales/fr.json b/src/locales/fr.json index 4a096420..d8533bd7 100644 --- a/src/locales/fr.json +++ b/src/locales/fr.json @@ -29,6 +29,7 @@ "recipientMsg": "Vous envoyez messages nostr à [R].", "sendMessage": "Envoyez Message", "expiry": "Expirez messages", + "cantSendExpiring": "Aucun des relais de [R] expirent les messages expirants. Vous ne pouvez pas leur envoyer des messages expirants.", "fadedWarning": "Pour protéger vos métadonées, vos messages expirent à un temps randomée au maximum 2 jours après la date que vous spécifiez; chaque message a son propre temps d’expiration randomée. Les messages qui semble faibles sont proche à expirer; les autres messages autours pouvait avoir déjà disparu.", "days": "jours", "relaysNotFound": "Ne pouvait pas trouvez les relais MD de [R].", diff --git a/src/routes/(app)/dm/[recipient]/+page.svelte b/src/routes/(app)/dm/[recipient]/+page.svelte index 443119fe..17a8ad23 100644 --- a/src/routes/(app)/dm/[recipient]/+page.svelte +++ b/src/routes/(app)/dm/[recipient]/+page.svelte @@ -2,6 +2,7 @@ import { tick } from "svelte"; import Icon from "$comp/Icon.svelte"; import { hexToBytes, bytesToHex } from '@noble/hashes/utils'; + import { fetchRelayInformation } from 'nostr-tools/nip11'; import * as toolsnip17 from 'nostr-tools/nip17'; import { SimplePool } from 'nostr-tools/pool'; import * as libnip17 from '$lib/nip17'; @@ -25,6 +26,7 @@ let expiryEnabled = $state(false); let expiryDays = $state(7); let canSend = $state(false); + let canSendExpiring = $state(false); const appendMultimap = (map: Map, key: string, value: object) => { if (map.has(key)) { @@ -66,6 +68,20 @@ return relays; } + // Accepts a list of relays, and returns a list of the relays that support all the provided NIPs. + const relaysSupporting = async (relays: string[], nips: number[]) => { + let supportingRelays = []; + + for (const relay of relays) { + const relayInfo = await fetchRelayInformation(relay); + if (nips.every(relay => relayInfo.supported_nips.includes(relay))) { + supportingRelays.push(relay); + } + } + + return supportingRelays; + } + const expired = (event: object) => { for (const tag of event.tags) { if (tag[0] == "expiration") { @@ -120,8 +136,11 @@ relayWarningShown = false; loadEvents(relays); }); - getPreferredRelays(recipient.pubkey) - .then((relays) => canSend = relays && relays.length > 0); + getPreferredRelays(recipient.pubkey).then((relays) => { + canSend = relays && relays.length > 0; + relaysSupporting(relays, [40]) + .then((supporting) => canSendExpiring = supporting.length > 0); + }); const sendMessage = async (message: string) => { const expiry = expiryEnabled ? expiryDays : null; @@ -139,10 +158,18 @@ message, sk, recipient.pubkey, user.pubkey, expiry); } - const recipientRelays = await getPreferredRelays(recipient.pubkey); + let recipientRelays = await getPreferredRelays(recipient.pubkey); + if (expiryEnabled) { + recipientRelays = relaysSupporting(recipientRelays, [40]); + } const p1 = Promise.any(pool.publish(recipientRelays, event1)); - const senderRelays = await getPreferredRelays(user.pubkey); + + let senderRelays = await getPreferredRelays(user.pubkey); + if (expiryEnabled) { + senderRelays = relaysSupporting(senderRelays, [40]); + } const p2 = Promise.any(pool.publish(senderRelays, event2)); + await Promise.all([p1, p2]); getPreferredRelays(user.pubkey).then(loadEvents); } @@ -224,8 +251,11 @@ <textarea id="message-contents" bind:value={text}></textarea> - <input type="checkbox" class="tiny" bind:checked={expiryEnabled}>{$t("dm.expiry")}: <input type="number" class="short" bind:value={expiryDays} disabled={!expiryEnabled} min="1" step="1" max="99999"> {$t("dm.days")}. + <input type="checkbox" class="tiny" bind:checked={expiryEnabled} disabled={!canSendExpiring}>{$t("dm.expiry")}: <input type="number" class="short" bind:value={expiryDays} disabled={!expiryEnabled} min="1" step="1" max="99999"> {$t("dm.days")}. <p class="expiring">{$t("dm.fadedWarning")}</p> + {#if canSend && !canSendExpiring} + <p class="warning"><em>{$t("dm.cantSendExpiring").replace("[R]", recipient.username)}</em></p> + {/if} <input id="send-message" type="button" class="btn" disabled={!canSend} value={canSend ? $t("dm.sendMessage") : $t("dm.relaysNotFound").replace("[R]", recipient.username)} on:click={async () => sendMessage(text)}> {#if relayWarningShown} |
