From 95263c02a13a825a8d02dbe760f2a74de8f93f77 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Sun, 2 Aug 2026 13:40:54 -0700 Subject: Chat v2: DMs, invites, and multi-community — coinos is the default, not the only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - NIP-17 private DMs (src/dm.js): kind-14 rumors in sender-signed seals under ephemeral wraps; interops with other nostr DM clients. Login signers gained encryptTo/decryptFrom so extensions and bunkers can seal to a peer; the inbox listens for both the login npub and the wallet key and publishes a kind-10050 DM-relay list for the wallet key when none exists. - Concord invites (CORD-05): mint shareable links (33301 bundle on relays, keys only in the URL fragment), join by pasting a link or opening v3.coinos.io/invite/…, and direct invites giftwrapped to an npub with the k-tag index hint. Bundles self-certify the founder before anything joins. - Multi-community: home view lists DM threads and communities; found your own community in-app (owner-signed genesis). coinos stays baked in as default. - Welcome DM: the names registrar DMs every first-time registrant from Adam's npub on claim (config: welcome{sk,message}; deduped in registrar state). Every new wallet auto-claims a payment address, so every new user gets one. - relay.coinos.io write policy now allows 33301/13302/13303. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi --- src/nostr-login.js | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/nostr-login.js') diff --git a/src/nostr-login.js b/src/nostr-login.js index 7addfc5..077d9a6 100644 --- a/src/nostr-login.js +++ b/src/nostr-login.js @@ -84,6 +84,9 @@ export async function extensionSigner() { signEvent: (e) => nostr.signEvent(e), encryptSelf: (txt) => nostr.nip44.encrypt(pubkey, txt), decryptSelf: (ct) => nostr.nip44.decrypt(pubkey, ct), + // peer variants: NIP-17 DMs seal to the recipient, not to self + encryptTo: (peer, txt) => nostr.nip44.encrypt(peer, txt), + decryptFrom: (peer, ct) => nostr.nip44.decrypt(peer, ct), }; } @@ -104,6 +107,8 @@ export async function bunkerSigner(uri, { onAuth } = {}) { signEvent: (e) => signer.signEvent(e), encryptSelf: (txt) => signer.nip44Encrypt(pubkey, txt), decryptSelf: (ct) => signer.nip44Decrypt(pubkey, ct), + encryptTo: (peer, txt) => signer.nip44Encrypt(peer, txt), + decryptFrom: (peer, ct) => signer.nip44Decrypt(peer, ct), close: () => { try { signer.close(); } catch {} }, }; } @@ -117,6 +122,8 @@ export function keySigner(sk) { signEvent: async (e) => finalizeEvent(e, sk), encryptSelf: async (txt) => nip44.encrypt(txt, conv), decryptSelf: async (ct) => nip44.decrypt(ct, conv), + encryptTo: async (peer, txt) => nip44.encrypt(txt, nip44.getConversationKey(sk, peer)), + decryptFrom: async (peer, ct) => nip44.decrypt(ct, nip44.getConversationKey(sk, peer)), }; } -- cgit v1.2.3