diff --git a/src/api-utils/newAccountHandler.ts b/src/api-utils/newAccountHandler.ts new file mode 100644 index 0000000..2cdcae7 --- /dev/null +++ b/src/api-utils/newAccountHandler.ts @@ -0,0 +1,6 @@ +const HeliusApiKey = ""; +const WebHookId = ""; + +export const newAcccountSubscriptionHandler = async (newTrg: string) => { + +}; diff --git a/src/api-utils/tradeHandler.ts b/src/api-utils/tradeHandler.ts index 4a27e41..4f4941d 100644 --- a/src/api-utils/tradeHandler.ts +++ b/src/api-utils/tradeHandler.ts @@ -8,5 +8,35 @@ export const tradeHandler = async ( CopiedTrader: undefined | Trader, AppState: Map ) => { - + if (req.method != "POST") { + return new Response( + JSON.stringify({ error: "Wrong method, this request is POST" }), + { status: 570 } + ); + } + + if (!CopiedTrader) { + return new Response( + JSON.stringify({ error: "You have not set a trader to copy" }), + { status: 590 } + ); + } + + const body = (await req.json()) as Trade; + + if ( + body.maker != CopiedTrader.traderRiskGroup.toBase58() && + body.taker != CopiedTrader.traderRiskGroup.toBase58() + ) + return new Response( + JSON.stringify({ + error: "Trade does not have CopiedTrader in it", + maker: body.maker, + taker: body.taker, + copiedTrader: CopiedTrader.traderRiskGroup.toBase58(), + }), + { status: 590 } + ); + + }; diff --git a/src/api-utils/types.ts b/src/api-utils/types.ts index b825ef8..2f9a680 100644 --- a/src/api-utils/types.ts +++ b/src/api-utils/types.ts @@ -1 +1,9 @@ -export type Trade = {}; +export type Trade = { + product: string; + taker_side: "bid" | "ask"; + quote_size: number; + base_size: number; + maker: string; + taker: string; + price: number; +}; diff --git a/src/bot.ts b/src/bot.ts index ea28c45..317fd2e 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -2,63 +2,107 @@ import TelegramBot from "node-telegram-bot-api"; import { cancelTraderSub } from "./bot-utils/cancelTraderSubHandler"; import { newTraderSubHandler } from "./bot-utils/newTraderSubHandler"; -const token = ""; -const chatId = 1000000; +const token: string = "YOUR_TELEGRAM_BOT_TOKEN"; +const chatId: number = YOUR_TELEGRAM_CHAT_ID; const bot = new TelegramBot(token, { polling: true }); console.log("Bot is live"); -bot.onText(/\/start/, (msg) => { - const welcomeMessage = `Welcome to the Trade Copy Bot! 🤖 Here's how you can get started: - - - Use /help to view all the commands. - - Use /newcopy {trg-pubkey} to subscribe to a new trader. - - Use /cancelcopy to cancel the subscription. - - Feel free to explore and let me know if you have any questions!`; - - bot.sendMessage(msg.chat.id, welcomeMessage); -}); +bot.onText(/\/newcopy (.+)/, async (msg, match) => { + if (msg.chat.id !== chatId) return; -bot.onText(/\/help/, (msg) => { - const helpMessage = `Here's how to use the bot commands: - - - Use /help to view all the commands. - - Use /newcopy {trg-pubkey} to subscribe to a new trader. - - Use /cancelcopy to cancel the subscription. - - If you have any questions or need further assistance, please reach out!`; + if (!match || !match[1]) { + return bot.sendMessage( + chatId, + "Please provide the trader's TRG pubkey in the correct format: /newcopy {trg-pubkey}" + ); + } - bot.sendMessage(msg.chat.id, helpMessage); -}); + bot.sendMessage(chatId, "Subscribing to trader..."); -bot.onText(/\/newcopy (.+)/, async (msg, match) => { - if (msg.chat.id !== chatId) return; + try { + const response = (await newTraderSubHandler(match[1])) as any; - if (!match || !match[1]) { - return bot.sendMessage( - chatId, - "Please provide the trader's TRG pubkey in the correct format: /newcopy {trg-pubkey}" - ); - } + let responseMessage = ""; - bot.sendMessage(chatId, "Subscribing to trader..."); + if (!response || !response.ok) { + responseMessage = + "Error: Unable to subscribe to the trader or to copy initial positions."; + } else { + responseMessage = `Successfully subscribed to New Trader!\n\nCopied Trader: ${response.newTrg}`; + if (response.signature) { + responseMessage += `\n\nSuccessfully copied initial positions:\nhttps://solscan.io/tx/${response.signature}?cluster=devnet`; + } + } - // handle subscribe to trader - // send response to user + bot.sendMessage(chatId, responseMessage); + } catch (error) { + console.error("Subscription Error:", error); + bot.sendMessage( + chatId, + "An error occurred while processing your request. Please try again later." + ); + } }); bot.onText(/\/cancelcopy/, async (msg, match) => { - if (msg.chat.id != chatId) return; + if (msg.chat.id != chatId) return; + + if (!match) return bot.sendMessage(chatId, "Wrong format"); + + const response = (await cancelTraderSub()) as any; + + let resp: string; - if (!match) return bot.sendMessage(chatId, "Wrong format"); + if (!response || !response.ok) { + resp = `Error: Unable to close trader subscription`; + } else { + resp = `Successfully unsubscribed from trader`; + } - // handle cancel subscription - // send response to user + bot.sendMessage(chatId, resp); }); -export const sendTradeMessageToUser = async (tradeInfo: any) => { - // parse tradeInfo into message - // send response to user +export const sendTradeMessageToUser = async (tradeInfo: { + signature: string; + productName: string; + productIndex: any; + isBid: boolean; + priceFractional: number; + sizeFractional: number; + positioningRatio: any; +}) => { + const tradeInfoMessage = `Successfully Copied Trade: + - Product Name: ${tradeInfo.productName} + - Product Index: ${tradeInfo.productIndex} + - Bid/Ask: ${tradeInfo.isBid ? "Bid" : "Ask"} + - Price: ${tradeInfo.priceFractional} + - Size: ${tradeInfo.sizeFractional} + - Positioning Ratio: ${tradeInfo.positioningRatio} + - Transaction: + https://solscan.io/tx/${tradeInfo.signature}?cluster=devnet`; + + bot.sendMessage(chatId, tradeInfoMessage); }; + +bot.onText(/\/start/, (msg) => { + const welcomeMessage = `Welcome to the Trade Copy Bot! 🤖 Here's how you can get started: + - Use /help to view all the commands. + - Use /newcopy {trg-pubkey} to subscribe to a new trader. + - Use /cancelcopy to cancel the subscription. + Feel free to explore and let me know if you have any questions!`; + + bot.sendMessage(msg.chat.id, welcomeMessage); +}); + +bot.onText(/\/help/, (msg) => { + const helpMessage = `Here's how to use the bot commands: + - Use /help to view all the commands. + - Use /newcopy {trg-pubkey} to subscribe to a new trader. + - Use /cancelcopy to cancel the subscription. + If you have any questions or need further assistance, please reach out!`; + + bot.sendMessage(msg.chat.id, helpMessage); +}); + diff --git a/src/index.ts b/src/index.ts index b256425..01a7109 100644 --- a/src/index.ts +++ b/src/index.ts @@ -10,6 +10,7 @@ import { tradeHandler } from "./api-utils/tradeHandler"; const AppState = new Map(); export const app = async () => { + const server = Bun.serve({ async fetch(req, server) { const url = new URL(req.url);