diff options
| author | Adam Soltys <[email protected]> | 2026-10-18 23:32:31 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-10-18 23:32:31 -0700 |
| commit | a99d37ca24e6484d8c2edd2ec7ac7dcaf4f29809 (patch) | |
| tree | e984d45a06a73fecfa2e70f5a6329e51e8ac94be /src/features/messages.js | |
| parent | 7367343cb45d08bcc0f5e3246c8c5462ea204281 (diff) | |
| download | coinosv3-a99d37ca24e6484d8c2edd2ec7ac7dcaf4f29809.tar.gz coinosv3-a99d37ca24e6484d8c2edd2ec7ac7dcaf4f29809.zip | |
DMs and calls go to relay.coinos.io and relay.primal.net (both take gift wraps and pass call messages on live), not nos.lol, which refused or ignored the household IP's publishes. A relay that turns a call message away is left out of the next ones on this device: a day for one that won't take the kind (nip17.com: only kind 1059), ten minutes for a rate limit or ban. publishOn tells its caller which relay refused and why (onrefused).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013ZDf1cyCQLkfjftYhymZAg
Diffstat (limited to 'src/features/messages.js')
| -rw-r--r-- | src/features/messages.js | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/src/features/messages.js b/src/features/messages.js index bfdabd1..695cba2 100644 --- a/src/features/messages.js +++ b/src/features/messages.js @@ -63,7 +63,10 @@ import { COMMUNITY, EPOCH } from '../community.js'; import COMMUNITY_DIRECTORY from '../community-directory.json'; import { assetUrl } from '../asset-url.js'; import { mergeFeeds } from '../feed-sync.js'; -const DM_RELAYS = ['wss://relay.coinos.io', 'wss://nos.lol']; +// coinos's own relay and primal: both take DM gift wraps and pass call +// messages (ephemeral 21059) on live. nos.lol was here until 2026-10-19 — it +// refused or ignored the household IP's publishes, call answers among them. +const DM_RELAYS = ['wss://relay.coinos.io', 'wss://relay.primal.net']; const NOTIFIER = 'https://nwcpush.coinos.io'; const APP_BASE = 'https://v3.coinos.io'; const CACHE_MAX = 50; // messages kept per channel / per DM thread in feature state @@ -9257,6 +9260,21 @@ export function messagesFeature(ctx) { }; let calls = null; const callInbox = new Map(); // peer -> their inbox relays, for this session + // Relays that turned a call message away are left out of the next ones: a + // relay that won't take the kind (nip17.com: "only kind 1059") for a day, + // one rate-limiting or banning us for ten minutes. Kept on this device. + const CALL_SHUN_KEY = 'coinos-call-shun'; + let callShun = (() => { try { return JSON.parse(localStorage.getItem(CALL_SHUN_KEY) || '{}'); } catch { return {}; } })(); // relay -> until + function callRefused(url, msg) { + const kindRule = /only kind|not (accepted|allowed)|blocked|unsupported|restricted|kind \d+/i.test(msg) && !/rate|too many|banned|slow down/i.test(msg); + callShun[url] = Date.now() + (kindRule ? 86400_000 : 600_000); + try { localStorage.setItem(CALL_SHUN_KEY, JSON.stringify(callShun)); } catch {} + } + function callRelaysOf(relays) { + const now = Date.now(); + const ok = relays.filter((r) => !(callShun[r] > now)); + return ok.length ? ok : relays; // all of them shunned: try them anyway + } async function inboxFor(pk) { if (callInbox.has(pk)) return callInbox.get(pk); const p = (isMe(pk) ? Promise.resolve(ownInbox) : fetchInboxRelays(pk).catch(() => [])) @@ -9313,7 +9331,8 @@ export function messagesFeature(ctx) { const tries = signed.kind === CALL.ICE ? 1 : 4; for (let i = 0; i < tries; i++) { if (i) await new Promise((r) => setTimeout(r, 1500 * 2 ** (i - 1))); - if (await publishOn(await inboxFor(pk), wrapCall(signed, pk), { onauth: relayAuth })) return; + const relays = callRelaysOf(await inboxFor(pk)); + if (await publishOn(relays, wrapCall(signed, pk), { onauth: relayAuth, onrefused: callRefused })) return; } throw new Error('not delivered'); }, |
