-
Notifications
You must be signed in to change notification settings - Fork 129
/
server.ts
147 lines (133 loc) · 4.5 KB
/
server.ts
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import express from "express";
import { initClient as initDiscordClient } from "lib/discord";
import initWorkers from "workers/initWorkers";
import {
maxSupportedTransactionVersion,
newConnection,
} from "lib/solana/connection";
import dotenv from "dotenv";
import notifyDiscordSale, { getStatus } from "lib/discord/notifyDiscordSale";
import { Env, loadConfig } from "config";
import { Worker } from "workers/types";
import notifyNFTSalesWorker from "workers/notifyNFTSalesWorker";
import notifyMagicEdenNFTSalesWorker from "workers/notifyMagicEdenNFTSalesWorker";
import { parseNFTSale } from "lib/marketplaces";
import { ParsedTransactionWithMeta } from "@solana/web3.js";
import notifyTwitter from "lib/twitter/notifyTwitter";
import logger from "lib/logger";
import { newNotifierFactory } from "lib/notifier";
import initTwitterClient from "lib/twitter";
import queue from "queue";
(async () => {
try {
const result = dotenv.config();
if (result.error) {
throw result.error;
}
const config = loadConfig(process.env as Env);
const { subscriptions } = config;
const port = process.env.PORT || 4000;
const web3Conn = newConnection();
const nQueue = queue({
concurrency: config.queueConcurrency,
autostart: true,
});
const notifierFactory = await newNotifierFactory(config, nQueue);
const server = express();
server.get("/", (req, res) => {
const { totalNotified, lastNotified } = getStatus();
res.send(`
${subscriptions.map(
(s) =>
`Watching the address ${s.mintAddress} at discord channel #${s.discordChannelId} for NFT sales.<br/>`
)}
Total notifications sent: ${totalNotified}<br/>
${
lastNotified
? `Last notified at: ${lastNotified.toISOString()}<br/>`
: ""
}
${`Current UTC time: ${new Date().toISOString()}`}
`);
});
server.get("/test-sale-tx", async (req, res) => {
const signature = (req.query["signature"] as string) || "";
if (!signature) {
res.send(`no signature in query param`);
return;
}
let tx: ParsedTransactionWithMeta | null = null;
try {
tx = await web3Conn.getParsedTransaction(signature, {
commitment: "finalized",
maxSupportedTransactionVersion,
});
} catch (e) {
logger.log(e);
res.send(`Get transaction failed, check logs for error.`);
return;
}
if (!tx) {
res.send(`No transaction found for ${signature}`);
return;
}
const nftSale = await parseNFTSale(web3Conn, tx);
if (!nftSale) {
res.send(
`No NFT Sale detected for tx: ${signature}\n${JSON.stringify(tx)}`
);
return;
}
if (config.discordBotToken) {
const discordClient = await initDiscordClient(config.discordBotToken);
if (discordClient) {
const channelId = (req.query["channelId"] as string) || "";
await notifyDiscordSale(discordClient, channelId, nftSale);
}
}
const twitterClient = await initTwitterClient(config.twitter);
const sendTweet = (req.query["tweet"] as string) || "";
if (sendTweet && twitterClient) {
await notifyTwitter(twitterClient, nftSale).catch((err) => {
logger.error("Error occurred when notifying twitter", err);
});
}
res.send(`NFT Sales parsed: \n${JSON.stringify(nftSale)}`);
});
server.listen(port, (err?: any) => {
if (err) throw err;
logger.log(`Ready on http://localhost:${port}`);
});
let workers: Worker[] = [];
if (subscriptions.length) {
workers = subscriptions.map((s) => {
const project = {
discordChannelId: s.discordChannelId,
mintAddress: s.mintAddress,
};
const notifier = notifierFactory.create(project);
return notifyNFTSalesWorker(notifier, web3Conn, project);
});
}
if (config.magicEdenConfig.collection) {
const notifier = notifierFactory.create({
discordChannelId: config.magicEdenConfig?.discordChannelId,
mintAddress: "",
});
workers.push(
notifyMagicEdenNFTSalesWorker(
notifier,
web3Conn,
config.magicEdenConfig
)
);
}
const _ = initWorkers(workers, () => {
// Add randomness between worker executions so the requests are not made all at once
return Math.random() * 5000; // 0-5s
});
} catch (e) {
logger.error(e);
process.exit(1);
}
})();