aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/nip51.ts
blob: 05de1947c6c79cecab75faa74cb251fdf61f520e (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
72
73
74
75
import { SimplePool } from "nostr-tools/pool";
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: any, pubkey: string, hide: boolean) => {
  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): boolean =>
  tag.length >= 2 && tag[0] === "p" && tag[1] === pubkey;

// Unmute the provided pubkey, as the provided user.
export const unmute = async (user: any, pubkey: string) => {
  let { shown, hidden } = await getMuteLists(user);
  shown = shown.filter((tag: string[]) => !tagMatches(tag, pubkey));
  hidden = hidden.filter((tag: string[]) => !tagMatches(tag, pubkey));
  await publishMuteList(user, shown, hidden);
};

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