aboutsummaryrefslogtreecommitdiffstats
path: root/static/punks-sm/52.webp
blob: 538949c475b17a998f5fc891cf19ea8e3b7e3dab (plain)
ofshex dumpascii
0000 52 49 46 46 52 0d 00 00 57 45 42 50 56 50 38 20 46 0d 00 00 10 3a 00 9d 01 2a 80 00 80 00 3e 79 RIFFR...WEBPVP8.F....:...*....>y
0020 34 94 46 a4 a3 22 21 2e 93 5d 40 90 0f 09 6a 00 bf 30 05 4e 9c 9b 6d 8f e7 3f 1a 73 1f 53 1e 66 4.F.."!..]@...j..0.N..m..?.s.S.f
0040 1c f9 e4 53 d6 6f 98 97 eb 97 4d 0f 30 fe 70 de 8c bf af 7a 90 7f 62 ff 63 d6 89 e8 1f e5 cd ec ...S.o....M.0.p....z..b.c.......
0060 b5 fd a3 ff 15 b3 df 22 31 a1 d0 af c9 e5 de 72 5f cc 7f 45 c6 cd 01 27 5e 2c 88 6b fe 52 35 0e ......."1......r_..E...'^,.k.R5.
0080 e9 94 32 e2 59 4a 6e 1c 6f 1a 55 a7 64 cb 62 ad 58 a3 ac 0d 7c 67 41 1f 2a d5 a6 75 2f 86 c5 a9 ..2.YJn.o.U.d.b.X...|gA.*..u/...
00a0 84 f5 95 32 c8 37 89 ec d3 85 ab ae f7 54 fb 50 e9 8d e3 e1 79 8f 03 56 73 56 4f e6 97 03 5f d7 ...2.7.......T.P....y..VsVO..._.
00c0 19 5e c6 25 5b 78 76 49 95 13 66 c3 5c 6d 41 3b b2 8b fe 46 19 8a 07 45 00 b0 0b 68 a9 bc 26 ee .^.%[xvI..f.\mA;...F...E...h..&.
00e0 d1 c5 c4 81 b2 a1 dd 65 94 e4 a0 d3 34 cf ff f3 de b5 f1 2f 77 a9 f5 7c 1b 2c 78 ce 41 60 0e 4d .......e....4....../w..|.,x.A`.M
0100 41 f8 95 11 bd a6 5e 63 53 9c 9f 55 bb 7a 1a 39 d5 9c 4e 42 dc e2 bf ec a4 24 f8 01 84 13 4c ff A.....^cS..U.z.9..NB.....$....L.
0120 1c 9a ad 87 cb 50 08 97 32 a6 a3 7a 08 d4 bb 8d 6c ba 39 f3 58 94 e3 d4 26 7b f0 5b 47 f6 ea 03 .....P..2..z....l.9.X...&{.[G...
0140 b8 59 ba 45 4f 92 0e ce 18 9b 6a ba 25 17 67 0d 7a 70 58 93 e2 d7 5b 20 2a e1 79 aa b8 f8 fc ca .Y.EO.....j.%.g.zpX...[.*.y.....
0160 20 21 f0 0a cd 49 02 54 3d 3f 63 95 9f c2 b9 a8 45 8d bb 5b 22 52 3d 0b 49 10 32 1d 6f 8f c3 84 .!...I.T=?c.....E..["R=.I.2.o...
0180 04 93 ed c8 80 55 ad c6 4e c3 9a 18 bf 18 91 d7 90 fc f8 ad 4f 0a 1d a7 8a 92 f1 86 87 e8 f5 37 .....U..N...........O..........7
01a0 25 f6 b6 cc 9c 83 a2 8d 04 16 ce 20 96 5b f5 4c 39 7f 60 7a 95 37 4c 29 ad 6c 4b 51 aa 73 cc df %............[.L9.`z.7L).lKQ.s..
01c0 4b f3 53 69 e6 2c 2c e6 85 5b 66 1a 66 9c 58 dc cd 85 4b 32 c8 5d 9e b0 af 85 54 c4 2b 02 f4 81 K.Si.,,..[f.f.X...K2.]....T.+...
01e0 72 bb 91 32 3c 9e 31 28 de ea 94 a0 40 00 fe e2 d6 e7 df e1 2b 1b e8 60 54 71 cd 93 f4 6e b4 82 r..2<.1(....@.......+..`Tq...n..
0200 7b 88 fc 73 b7 a2 06 86 0a f1 d6 48 22 fe 05 d5 ad bd 7b 96 a4 5f bb 7b d6 f5 46 87 3f 9f 82 94 {..s.......H".....{.._.{..F.?...
0220 11 97 ff f9 84 7d b6 37 94 82 65 7f bd 32 a1 4a 5a d4 cd d7 5a 29 09 75 ab b3 fd 1b b0 da 18 d6 .....}.7..e..2.JZ...Z).u........
0240 4e 0f 52 c2 3c 23 9d 01 63 02 59 a9 64 10 20 ce ea 96 62 41 39 18 99 5a 93 96 94 6e 86 4c 77 d2 N.R.<#..c.Y.d.....bA9..Z...n.Lw.
0260 3f cb ef 28 b3 47 d9 96 95 43 6a 03 6f fa 1e 59 45 88 da 72 f6 85 61 83 b3 d1 75 5b 28 52 0d 6c ?..(.G...Cj.o..YE..r..a...u[(R.l
0280 5b 2b 33 5b 0b fa 0a ae 29 db 67 41 4c 2f ee c4 4a cb 46 25 87 88 f2 dc 45 82 41 56 5e 91 f0 40 [+3[....).gAL/..J.F%....E.AV^..@
02a0 8d db 0d 7c fe bc 52 ed 59 ae c5 e6 b7 3c 1f 43 ad 05 84 ad 31 88 9b 6d da b0 47 01 25 ea 8c 6e ...|..R.Y....<.C....1..m..G.%..n
02c0 ad 45 0d 4a c0 bc 0a 2c 7d e4 52 99 d0 b5 f0 77 ef 0d 66 24 9c 14 b4 31 8f e6 c7 0b 7f bb 8b 94 .E.J...,}.R....w..f$...1........
02e0 96 1c 70 03 72 8f 54 69 4f bb 97 7c 32 a9 f0 ce 08 39 1e b7 58 20 f6 a5 fc 49 e9 c7 09 ea 46 af ..p.r.TiO..|2....9..X....I....F.
0300 ab 39 a2 db 3a da 43 e5 9e 74 c7 33 0a 81 b7 ff ef dc f9 d7 cf 9e 76 02 fe 88 05 c7 82 7e ea 2b .9..:.C..t.3..........v......~.+
0320 f8 0b e6 45 14 37 31 d3 be df 23 07 6f 34 b4 af 07 6d 6c ed 32 4d d5 93 be 18 9a cc cc fe 33 e9 ...E.71...#.o4...ml.2M........3.
0340 96 d1 2f 11 6a 91 5a 1e da 58 03 4a 5f 1e 98 21 c6 96 7a be ba 25 f5 08 0b da 73 30 f8 88 63 c5 ../.j.Z..X.J_..!..z..%....s0..c.
0360 76 b1 2e 0a 62 f7 b8 f6 51 02 01 2b c1 4c 43 3c 08 9f db 5d 49 28 26 b2 82 e0 cc e8 8b cd 6c 12 v...b...Q..+.LC<...]I(&.......l.
0380 1f b1 46 1a d7 64 cc e3 13 22 47 21 73 9c cc db 24 66 cd 27 93 8c 25 89 bd 32 c1 43 f7 1f a8 34 ..F..d..."G!s...$f.'..%..2.C...4
03a0 5d 3d 26 2e 9e 6f 21 29 e1 8d a7 ab 65 32 b2 65 e1 50 7a 8d bb ff a4 da 36 44 3b cd 0d ce c1 b9 ]=&..o!)....e2.e.Pz.....6D;.....
03c0 63 b2 5b 83 69 c5 be ca 9a 08 71 1d 48 d2 7e 62 93 b3 8c a4 b6 93 fe ca d9 ea 90 c3 a7 d7 ed 61 c.[.i.....q.H.~b...............a
03e0 1a 3f 3b c8 15 8d 6f 75 3b 80 f7 ee 11 71 69 79 bc 5c a8 84 86 24 8d c5 cb d7 d5 13 d8 94 89 4e .?;...ou;....qiy.\...$.........N
0400 60 3f e5 12 75 d9 f9 69 d3 1a 68 73 9c 0e 39 00 d1 e7 71 f0 b2 c3 8b be 01 85 e6 11 51 bc 56 2a `?..u..i..hs..9...q.........Q.V*
0420 c8 d2 e8 00 44 1a 23 23 e8 b6 cb 60 c8 8f 5f 67 4f 42 e8 5c 32 17 24 09 6e 61 f3 8f f2 d1 11 b4 ....D.##...`.._gOB.\2.$.na......
0440 52 02 bb 1d c1 0f a4 f7 26 53 a2 7f 3f 7d 00 d2 27 b8 9c da 41 61 be c4 3a 0e 8a e3 c7 0f e4 d8 R.......&S..?}..'...Aa..:.......
0460 97 43 9a 2f 74 0a 43 65 92 58 0a cb 9d 4f cc 06 28 ed bd 73 7b 0c d9 c1 11 7f ab 9e 7f b5 6a 4a .C./t.Ce
const jwt = require("jsonwebtoken");
const uuidv4 = require("uuid/v4");
const WebSocket = require("ws");

wss = new WebSocket.Server({ clientTracking: false, noServer: true });

/* eslint-disable-next-line */
const pick = (O, ...K) => K.reduce((o, k) => ((o[k] = O[k]), o), {});
const all = {};
const subscriptions = [];

emit = (username, type, data) => {
  if (data.username !== undefined) data = pick(data, ...whitelist);

  if (type === "payment" && data.amount > 0) {
    for (let i = subscriptions.length - 1; i >= 0; i--) {
      let s = subscriptions[i];
      if (
        s.invoice.amount === data.amount ||
        s.invoice.address === data.address ||
        s.invoice.unconfidential === data.address
      ) {
        s.ws.send(JSON.stringify({ type, data }));
        subscriptions.splice(i, 1);
      }
    }
  }

  if (!sockets[username]) return;
  for (id in sockets[username]) {
    const ws = sockets[username][id];
    ws.send(JSON.stringify({ type, data }));
  }
};

broadcast = (type, data) => {
  const sent = [];
  for (const username in sockets) {
    for (const id in sockets[username]) {
      const ws = sockets[username][id];
      ws.send(JSON.stringify({ type, data }));
      sent.push(ws.id);
    }
  }

  Object.values(all).map(ws => {
    if (!sent.includes(ws.id)) ws.send(JSON.stringify({ type, data }));
  });
};

server.on("upgrade", function(req, socket, head) {
  wss.handleUpgrade(req, socket, head, function(ws) {
    wss.emit("connection", ws, req);
  });
});

const names = {};

setInterval(() => {
  for (const username in sockets) {
    for (const id in sockets[username]) {
      let ws = sockets[username][id];
      ws.beats++;
      if (ws.beats > 10) ws.close();
    }
  }
}, 2000);

wss.on("connection", function(ws, req) {
  const id = uuidv4();
  ws.id = id;
  ws.beats = 0;
  ws.send(JSON.stringify({ type: "connected", data: id }));
  all[id] = ws;

  ws.on("message", async message => {
    let type, data;
    try {
      ({ type, data } = JSON.parse(message));
    } catch (e) {
      l.error("coudn't parse socket message");
    }

    switch (type) {
      case "heartbeat":
        ws.beats = 0;
        break;

      case "login":
        let token = data;
        try {
          if (!token || token === "null") return ws.close();
          const username = jwt.decode(token).username;
          if (!username) throw new Error("Invalid JWT token");

          if (!sockets[username]) sockets[username] = {};
          const existing = Object.keys(sockets[username]);
          if (existing.length > 4) {
            const p = existing.find(sid => sid !== id);
            sockets[username][p].send(JSON.stringify({ type: "logout" }));
            setTimeout(() => {
              if (sockets[username][p]) sockets[username][p].close();
            }, 5000);
          }
          sockets[username][id] = ws;
          names[id] = username;

          let user = await getUser(username);
          let payments = await user.getPayments({
            where: {
              account_id: user.account_id
            },
            order: [["id", "DESC"]],
            limit: 12,
            include: {
              model: db.Account,
              as: "account"
            }
          });
          let accounts = await user.getAccounts();
          let keys = await user.getKeys();
          user = user.get({ plain: true });
          user.accounts = accounts;
          user.keys = keys;
          user.payments = payments;

          ws.user = user;
          ws.send(JSON.stringify({ type: "login", data: user }));
          ws.send(
            JSON.stringify({ type: "version", data: config.clientVersion })
          );
        } catch (e) {
          l.error("caught socket error", e.message);
          if (e.message.includes("not found"))
            ws.send(JSON.stringify({ type: "logout" }));
          setTimeout(ws.close, 1000);
        }
        break;
      case "token":
        if (!ws.user) return;
        ws.token = data;
        break;
      case "lnurl":
        sessions[data] = ws;
        break;
      case "updateMemo":
        const payment = await db.Payment.findOne({
          where: {
            user_id: ws.user.id,
            id: data.id
          },
          include: {
            model: db.Account,
            as: "account"
          }
        });
        if (payment) {
          payment.memo = data.memo;
          await payment.save();
          emit(ws.user.username, "payment", payment);
        }
        break;
      case "subscribe":
        subscriptions.push({ invoice: data, ws });
        break;
      default:
        l.warn("received socket message of unknown type", type, data);
    }
  });

  ws.on("close", function() {
    try {
      const username = names[id];
      if (sockets[username] && sockets[username][id]) {
        delete sockets[username][id];
      }

      if (all[id]) delete all[id];
    } catch (e) {
      l.error("problem closing socket", e.message);
    }
  });
});