aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/nip51.ts
blob: b1b0b613ddf7e7197514c86b412845b0b8f37513 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import { SimplePool } from 'nostr-tools/pool';
import { verifyEvent } from 'nostr-tools/pure';
import { signEvent, encrypt, decrypt } from '$lib/nip07';
const pool = new SimplePool();

import { PUBLIC_DM_RELAYS } from '$env/static/public';
const DM_RELAYS_LIST = PUBLIC_DM_RELAYS.split(',');

// Mute the provided pubkey, as the provided user.
export const mute = async (user: object, pubkey: string, hide: bool) => {
    let { shown, hidden } = await getMuteLists(user);
    if (hide) {
        hidden.push(["p", pubkey]);
    } else {
        shown.push(["p", pubkey]);
    }
    await publishMuteList(user, shown, hidden);
}

const tagMatches = (tag: string[], pubkey: string): bool =>
    tag.length >= 2 && tag[0] === "p" && tag[1] === pubkey;

// Unmute the provided pubkey, as the provided user.
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);
}

// Returns a set of the provided user's muted accounts.
export const mutedAccounts = async (user: object): Set<string> => {
    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;
}

const getMuteLists = async (user: object): object => {
    const listEvents = await pool.querySync(
        DM_RELAYS_LIST, { kinds: [10000], "authors": [user.pubkey], limit: 1 }
    );
    if (listEvents.length == 0) {
        return { shown: [], hidden: [] };
    }

    return {
        shown: listEvents[0].tags,
        hidden: listEvents[0].content == "" ? [] :
            await decrypt(listEvents[0].content, user, user.pubkey)
    };
}

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: await encrypt(hidden, user, user.pubkey)
    }, user);
    return Promise.any(pool.publish(DM_RELAYS_LIST, event));
}