diff options
| author | Adrien Hopkins <[email protected]> | 2026-01-09 11:43:31 -0500 |
|---|---|---|
| committer | Adrien Hopkins <[email protected]> | 2026-01-09 11:43:48 -0500 |
| commit | d37343317689fd9b2c9716c06faab6125ddf2504 (patch) | |
| tree | fdd8cef9c8f7cbbb210459383aaa6df54d69024b | |
| parent | 33efd6bd8918d2fe0eac9ab5dd0a18f545c15879 (diff) | |
| download | coinos-ui-d37343317689fd9b2c9716c06faab6125ddf2504.tar.gz coinos-ui-d37343317689fd9b2c9716c06faab6125ddf2504.zip | |
Encrypt mute lists
| -rw-r--r-- | src/lib/nip07.ts | 30 | ||||
| -rw-r--r-- | src/lib/nip51.ts | 28 | ||||
| -rw-r--r-- | src/routes/(app)/dm/+page.svelte | 2 |
3 files changed, 52 insertions, 8 deletions
diff --git a/src/lib/nip07.ts b/src/lib/nip07.ts index b93779dc..7191da33 100644 --- a/src/lib/nip07.ts +++ b/src/lib/nip07.ts @@ -1,5 +1,9 @@ +import { bytesToHex } from '@noble/hashes/utils'; import { finalizeEvent } from 'nostr-tools/pure'; +import { unwrapEvent } from 'nostr-tools/nip17'; import { getPrivateKey } from '$lib/nostr'; +import * as libnip44 from '$lib/nip44'; +import { u } from '$lib/nip44'; export const signEvent = async (event: object, user: object): object => { if (await window.nostr.getPublicKey() === user.pubkey) { @@ -9,3 +13,29 @@ export const signEvent = async (event: object, user: object): object => { return finalizeEvent(event, sk); } } + +// Encrypts an event in NIP-44 using NIP-07 if available, otherwise getPrivateKey() +export const encrypt = async (json: object, user: object, receiverPK: string): string => { + if (await window.nostr.getPublicKey() === user.pubkey) { + return window.nostr.nip44.encrypt( + receiverPK, JSON.stringify(json)); + } else { + const senderSK = await getPrivateKey(); + const senderSKString = bytesToHex(senderSK); + const ckey = u.getConversationKey(senderSKString, receiverPK); + return libnip44.encrypt(JSON.stringify(json), ckey); + } +} + +// Decrypts an event in NIP-44 using NIP-07 if available, otherwise getPrivateKey() +export const decrypt = async (encrypted: string, user: object, receiverPK: string): object => { + if (await window.nostr.getPublicKey() === user.pubkey) { + return JSON.parse(await window.nostr.nip44.decrypt( + receiverPK, encrypted)); + } else { + const senderSK = await getPrivateKey(); + const senderSKString = bytesToHex(senderSK); + const ckey = u.getConversationKey(senderSKString, receiverPK); + return JSON.parse(libnip44.decrypt(encrypted, ckey)); + } +} diff --git a/src/lib/nip51.ts b/src/lib/nip51.ts index 81a1a9d3..8d6f76db 100644 --- a/src/lib/nip51.ts +++ b/src/lib/nip51.ts @@ -1,6 +1,6 @@ import { SimplePool } from 'nostr-tools/pool'; import { verifyEvent } from 'nostr-tools/pure'; -import { signEvent } from '$lib/nip07'; +import { signEvent, encrypt, decrypt } from '$lib/nip07'; const pool = new SimplePool(); import { PUBLIC_DM_RELAYS } from '$env/static/public'; @@ -8,7 +8,11 @@ const DM_RELAYS_LIST = PUBLIC_DM_RELAYS.split(','); export const mute = async (user: object, pubkey: string, hide: bool) => { let { shown, hidden } = await getMuteLists(user); - shown.push(["p", pubkey]); + if (hide) { + hidden.push(["p", pubkey]); + } else { + shown.push(["p", pubkey]); + } await publishMuteList(user, shown, hidden); } @@ -18,17 +22,23 @@ const tagMatches = (tag: string[], pubkey: string): bool => export const unmute = async (user: object, pubkey: string) => { let { shown, hidden } = await getMuteLists(user); shown = shown.filter(tag => !tagMatches(tag, pubkey)); + hidden = hidden.filter(tag => !tagMatches(tag, pubkey)); await publishMuteList(user, shown, hidden); } export const mutedAccounts = async (user: object): Set<string> => { - const { shown } = await getMuteLists(user); + const { shown, hidden } = await getMuteLists(user); let muted = new Set<string>(); for (const tag of shown) { if (tag.length >= 2 && tag[0] === "p") { muted.add(tag[1]); } } + for (const tag of hidden) { + if (tag.length >= 2 && tag[0] === "p") { + muted.add(tag[1]); + } + } return muted; } @@ -37,18 +47,22 @@ const getMuteLists = async (user: object): object => { DM_RELAYS_LIST, { kinds: [10000], "authors": [user.pubkey], limit: 1 } ); if (listEvents.length == 0) { - return { shown: [], hidden: "" }; + return { shown: [], hidden: [] }; } - return { shown: listEvents[0].tags, hidden: listEvents[0].content }; + return { + shown: listEvents[0].tags, + hidden: listEvents[0].content == "" ? [] : + await decrypt(listEvents[0].content, user, user.pubkey) + }; } -const publishMuteList = async (user: object, shown: Array<string>, hidden: string) => { +const publishMuteList = async (user: object, shown: string[], hidden: string[]) => { const event = await signEvent({ kind: 10000, created_at: Math.floor(Date.now() / 1000), tags: shown, - content: hidden + content: await encrypt(hidden, user, user.pubkey) }, user); return Promise.any(pool.publish(DM_RELAYS_LIST, event)); } diff --git a/src/routes/(app)/dm/+page.svelte b/src/routes/(app)/dm/+page.svelte index a8da9538..8725d9b8 100644 --- a/src/routes/(app)/dm/+page.svelte +++ b/src/routes/(app)/dm/+page.svelte @@ -265,7 +265,7 @@ if (muted && muted.has(pubkey)) { await unmute(user, pubkey); } else { - await mute(user, pubkey, false); + await mute(user, pubkey, true); } muted = await mutedAccounts(user); } |
