/**
* Telegram Bot Demo Client
* Demonstrates how to use Saros MCP Server with a Telegram bot
*
* Setup:
* 1. Create a bot via @BotFather on Telegram
* 2. Set BOT_TOKEN environment variable
* 3. Run: node examples/telegram-bot.js
*/
import TelegramBot from "node-telegram-bot-api";
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
const BOT_TOKEN = process.env.BOT_TOKEN || "YOUR_BOT_TOKEN_HERE";
class SarosTelegramBot {
constructor() {
this.bot = new TelegramBot(BOT_TOKEN, { polling: true });
this.mcpClient = null;
this.userSessions = new Map();
}
async connectMCP() {
const transport = new StdioClientTransport({
command: "node",
args: ["src/index.js"],
});
this.mcpClient = new Client(
{
name: "saros-telegram-bot",
version: "1.0.0",
},
{
capabilities: {},
}
);
await this.mcpClient.connect(transport);
console.log("✅ Connected to Saros MCP Server");
}
setupHandlers() {
// Start command
this.bot.onText(/\/start/, (msg) => {
const chatId = msg.chat.id;
this.bot.sendMessage(
chatId,
`🌟 *Welcome to Saros DeFi Bot!*\n\n` +
`I can help you manage your Saros liquidity pools and farms.\n\n` +
`*Commands:*\n` +
`/wallet <address> - Set your wallet\n` +
`/positions - View your LP positions\n` +
`/rebalance <threshold> - Simulate rebalancing\n` +
`/analytics - Portfolio analytics\n` +
`/farms - View farm positions\n` +
`/quote <pool> <from> <to> <amount> - Get swap quote\n` +
`/help - Show this message`,
{ parse_mode: "Markdown" }
);
});
// Set wallet
this.bot.onText(/\/wallet (.+)/, (msg, match) => {
const chatId = msg.chat.id;
const wallet = match[1];
this.userSessions.set(chatId, { wallet });
this.bot.sendMessage(
chatId,
`✅ Wallet set to: \`${wallet}\`\n\nUse /positions to view your LP positions.`,
{ parse_mode: "Markdown" }
);
});
// Get LP positions
this.bot.onText(/\/positions/, async (msg) => {
const chatId = msg.chat.id;
const session = this.userSessions.get(chatId);
if (!session?.wallet) {
this.bot.sendMessage(chatId, "⚠️ Please set your wallet first using /wallet <address>");
return;
}
this.bot.sendMessage(chatId, "🔍 Fetching your LP positions...");
try {
const result = await this.mcpClient.callTool({
name: "get_lp_positions",
arguments: { wallet: session.wallet },
});
this.bot.sendMessage(chatId, result.content[0].text, {
parse_mode: "Markdown",
});
} catch (error) {
this.bot.sendMessage(chatId, `❌ Error: ${error.message}`);
}
});
// Simulate rebalance
this.bot.onText(/\/rebalance (\d+)/, async (msg, match) => {
const chatId = msg.chat.id;
const session = this.userSessions.get(chatId);
const threshold = parseFloat(match[1]);
if (!session?.wallet) {
this.bot.sendMessage(chatId, "⚠️ Please set your wallet first using /wallet <address>");
return;
}
this.bot.sendMessage(chatId, `⚖️ Simulating rebalance with ${threshold}% threshold...`);
try {
const result = await this.mcpClient.callTool({
name: "simulate_rebalance",
arguments: { wallet: session.wallet, threshold },
});
this.bot.sendMessage(chatId, result.content[0].text, {
parse_mode: "Markdown",
});
} catch (error) {
this.bot.sendMessage(chatId, `❌ Error: ${error.message}`);
}
});
// Portfolio analytics
this.bot.onText(/\/analytics/, async (msg) => {
const chatId = msg.chat.id;
const session = this.userSessions.get(chatId);
if (!session?.wallet) {
this.bot.sendMessage(chatId, "⚠️ Please set your wallet first using /wallet <address>");
return;
}
this.bot.sendMessage(chatId, "📊 Analyzing your portfolio...");
try {
const result = await this.mcpClient.callTool({
name: "portfolio_analytics",
arguments: { wallet: session.wallet },
});
this.bot.sendMessage(chatId, result.content[0].text, {
parse_mode: "Markdown",
});
} catch (error) {
this.bot.sendMessage(chatId, `❌ Error: ${error.message}`);
}
});
// Farm positions
this.bot.onText(/\/farms/, async (msg) => {
const chatId = msg.chat.id;
const session = this.userSessions.get(chatId);
if (!session?.wallet) {
this.bot.sendMessage(chatId, "⚠️ Please set your wallet first using /wallet <address>");
return;
}
this.bot.sendMessage(chatId, "🌾 Fetching your farm positions...");
try {
const result = await this.mcpClient.callTool({
name: "get_farm_positions",
arguments: { wallet: session.wallet },
});
this.bot.sendMessage(chatId, result.content[0].text, {
parse_mode: "Markdown",
});
} catch (error) {
this.bot.sendMessage(chatId, `❌ Error: ${error.message}`);
}
});
// Help command
this.bot.onText(/\/help/, (msg) => {
const chatId = msg.chat.id;
this.bot.sendMessage(
chatId,
`*Saros DeFi Bot Help*\n\n` +
`*Setup:*\n` +
`1. Set your wallet: /wallet <address>\n\n` +
`*Available Commands:*\n` +
`/positions - View LP positions\n` +
`/rebalance <threshold> - Simulate rebalancing\n` +
`/analytics - Portfolio analytics\n` +
`/farms - View farm positions\n\n` +
`*Example:*\n` +
`/wallet 5UrM9csUEDBeBqMZTuuZyHRNhbRW4vQ1MgKJDrKU1U2v\n` +
`/positions\n` +
`/rebalance 5`,
{ parse_mode: "Markdown" }
);
});
console.log("✅ Telegram bot handlers setup complete");
}
async start() {
try {
await this.connectMCP();
this.setupHandlers();
console.log("🤖 Telegram bot is running...");
} catch (error) {
console.error("Failed to start bot:", error);
process.exit(1);
}
}
}
// Start the bot
const bot = new SarosTelegramBot();
bot.start().catch(console.error);