开发自己的TG钱包机器人
这是一篇关于实际工作的 TG 钱包机器人的博客,详解介绍了如何使用node.js开发一个完整的TG钱包机器人。
一键发币: SOL | BNB | ETH | BASE | Blast | ARB | OP | POLYGON | AVAX | FTM | OK
大家好👋,我是 Himanshu。在过去的 1.7 年里,我一直在 Cosmos 生态系统的加密钱包扩展中担任前端工程师。工作之余,我通过一个共同的朋友完成了许多自由职业项目。在自由职业中,我主要从事 web3 项目,涉及制作 TG 购买机器人追踪器、DEX网络应用游戏和以太坊生态系统中的 TG 钱包机器人。
在从事这些项目时,我总是发现很难找到一些好的资源,大多数时候我都会参考 Chat GPT、一些随机博客和 YouTube 视频。这就是为什么我认为我应该写一篇关于实际工作的 TG 钱包机器人的博客,这就是这个博客的原因。
让我们开始吧。
1、初始化项目
我将使用 NodeJS 环境来创建此项目。因此,首先,创建一个新文件夹 tg-wallet-bot,并在其中运行 npm init -y。
运行此命令后,你的 tg-wallet-bot 文件夹中必须有一个 package.json 文件。现在,让我们添加一些依赖项,它们将帮助我们快速测试我们的机器人。创建依赖项,在 package.json 文件对象中创建一个新字段,并使用上述版本添加以下依赖项。
"express": "4.18.2",
"telegraf": "4.12.2",
"dotenv": "16.3.1"
为什么要固定依赖项而不是 semver 范围?原因与安全性有关。只是为了确保当攻击者试图在更高版本中做一些可疑的事情时,我们的项目不会受到损害。
为什么只有这些版本?我已经有一个使用此配置运行的项目,所以我仅出于本博客的学习目的而提及它。这就是原因。
到目前为止,您的 package.json 文件必须看起来像这样
{
"name": "tg-wallet-bot",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"dotenv": "16.3.1",
"express": "4.18.2",
"telegraf": "4.12.2"
}
}
现在,我们在根目录创建一个 index.js 文件,并添加以下代码
require("dotenv").config();
const { Telegraf } = require("telegraf");
const bot = new Telegraf(process.env.TG_WALLET_BOT_TOKEN);
bot.command("start", (ctx) => {
const message = `Welcome to the TG Wallet Bot!`;
ctx.reply(message);
});
bot.launch();
在上面的代码片段中,我们创建了一个 Telegram 机器人实例并处理该机器人的 /start 命令。您一定在机器人中见过这个命令,当您第一次开始与机器人交互时单击“开始”按钮时,这个命令也会运行。然后,我们启动机器人。
此外,现在是时候在 TG 上创建一个机器人并将其链接到我们的代码了。要在 TG 上创建机器人,您必须在 Telegram 上搜索 BotFather。搜索后,单击“开始”按钮,之后您必须获得支持的命令列表。要创建新的机器人,您必须单击 /newbot 并回答一些问题,例如 TG 机器人名称和用户名,完成后您将获得一个需要保护的令牌,因为此令牌允许任何人访问您的机器人。
现在在项目目录的根级别创建一个新的 .env 文件,并将以下代码添加到该文件中
TG_WALLET_BOT_TOKEN=<Bot Token that you got in BotFather>
我们几乎准备好测试我们的机器人了。
但在测试之前,请在你的终端中运行 npm install 命令。
进入你刚刚在 BotFather 中创建的 TG 机器人(您必须在 BotFather 上看到带有令牌的 TG 机器人链接)。
现在,在你的终端中运行 node index.js 命令。
单击你在 TG 机器人中看到的“开始”按钮。
哇哦!它正在运行
你可以在消息框中输入 /start 命令,这样也可以正常工作。
到目前为止,我们还没有添加任何与加密相关的代码。这只是一个简单的 TG 机器人。
我想向你展示如何在您的机器人中导入钱包,将其存储在 Telegram 会话中,并向用户显示导入的钱包信息(公共地址)。
我不会在本博客中显示任何交易或其他任何内容,否则,博客会变得很长,并且仅通过导入钱包,您就会了解如何从用户那里获取输入,如何处理单击任何按钮的用户操作,以及如何显示按钮。
2、导入钱包
现在,为了让用户导入钱包,我们需要显示一个按钮,让用户可以选择执行此操作。所以,让我们在启动命令上快速添加一个按钮。要创建一个按钮,我将创建一个实用函数,它将返回一个我们可以使用的按钮。
在项目目录的根级别创建一个 utils 文件夹,并在其中创建 misc.js 和 index.js 文件。
在 utils/misc.js 文件中,添加以下代码
const { Markup } = require("telegraf");
function createCallBackBtn(btnLabel, cbActionCommand) {
return Markup.button.callback(btnLabel, cbActionCommand);
}
module.exports = {
createCallBackBtn,
};
上面的代码片段创建了一个回调按钮,我们可以使用它向用户显示一个按钮。
在 utils/index.js 文件中,添加以下代码
const misc = require("./misc");
module.exports = {
...misc,
};
在上面的代码片段中,我们只是重新导出函数。这将有助于我们保持代码井然有序。
现在,在 index.js 文件中,使用以下内容更改启动命令处理程序代码
const { Telegraf } = require("telegraf");
const { createCallBackBtn } = require("./utils");
...
bot.command("start", (ctx) => {
const message = `Welcome to the TG Wallet Bot!`;
const importWalletButton = createCallBackBtn(
"Import Wallet",
"import-wallet"
);
ctx.reply(message, {
reply_markup: {
inline_keyboard: [[importWalletButton]],
},
});
});
因此,我们创建一个带有标签“导入钱包”的按钮,该按钮附带一个回调操作(很快你就会看到它的用途)。
现在,当你在终端中运行 node index.js 命令时(如果任何命令仍在运行,请停止前面的命令),将看到“导入钱包”出现在启动命令消息中。
尝试点击按钮,什么都不会发生。
让我们为导入钱包按钮添加一个处理程序。
在你的 index.js 文件中添加以下代码
...
bot.action("import-wallet", (ctx) => {
ctx.reply("Import wallet clicked");
});
bot.launch();
现在,当你在终端中运行 node index.js 命令并单击导入钱包按钮时,将看到“单击导入钱包”消息。
因此,我们可以显示一个按钮并监听该按钮上的单击事件,现在我们要获取用户输入,在我们的例子中,该输入将是钱包的种子短语或私钥。
要在 Telegram 中获取用户输入,我们需要创建一个名为“场景”的东西,所以基本上当我们想要来回获取用户的输入时(如果用户输入了错误的值),我们会维护一个场景,而当我们想要停止这样做时,我们会离开该场景。
让我们为导入钱包创建一个场景。
让我们遵循与实用程序函数相同的文件夹结构,首先,在项目的根级别创建一个文件夹 scenes,并在其中创建文件 importWalletScene.js index.js。
在 scenes/importWalletScene.js 文件中,添加以下代码
const { Scenes } = require("telegraf");
const importWalletScene = "importWalletScene";
const importWalletStep = new Scenes.BaseScene(importWalletScene);
importWalletStep.enter((ctx) =>
ctx.reply(
"Please provide either the private key of the wallet you wish to import or a 12-word mnemonic phrase."
)
);
importWalletStep.on("text", (ctx) => {
const phrase = ctx.message.text;
ctx.reply("You entered" + phrase);
ctx.scene.leave();
});
module.exports = {
importWalletScene,
importWalletStep,
};
在上面的代码中,我们只是监听文本事件,然后使用用户输入的文本进行回复。
在 scenes/index.js 文件中,添加以下代码
const importWalletScene = require("./importWalletScene");
module.exports = {
...importWalletScene,
};
再次,我们只是重新导出场景变量。
现在,在 index.js 文件中,你需要添加以下代码
const { Telegraf, Scenes, session } = require("telegraf");
const { createCallBackBtn } = require("./utils");
const { importWalletScene, importWalletStep } = require("./scenes");
const bot = new Telegraf(process.env.TG_WALLET_BOT_TOKEN);
const stage = new Scenes.Stage([importWalletStep]);
bot.use(session());
bot.use(stage.middleware());
...
bot.action("import-wallet", (ctx) => {
ctx.scene.enter(importWalletScene);
});
在上面的代码片段中,我们只是导入了必要的变量,并为机器人放置了一些中间件,然后当用户点击“导入钱包”时,我们就会进入场景。
现在,如果你再次在终端中运行命令 node index.js,你必须能够得到以下内容
现在我们可以获取用户输入了。
现在,我们应该根据用户输入的短语生成帐户。
为此,我们需要创建一个新的实用函数来为我们执行此操作。
但是,在此之前,我们需要添加一些依赖项,因此让我们将 package.json 中的依赖项更新为以下内容
{
...,
"dependencies": {
"crypto-js": "4.1.1",
"dotenv": "16.3.1",
"ethers": "5.7.2",
"express": "4.18.2",
"telegraf": "4.12.2"
}
}
现在,在 utils 文件夹中,创建一个encryption.js文件并添加以下代码
const crypto = require("crypto-js");
function encrypt(text) {
return crypto.AES.encrypt(text, process.env.TG_WALLET_BOT_TOKEN).toString();
}
function decrypt(cipherText) {
const bytes = crypto.AES.decrypt(cipherText, process.env.TG_WALLET_BOT_TOKEN);
return bytes.toString(crypto.enc.Utf8);
}
module.exports = {
encrypt,
decrypt,
};
我们只是创建了一些辅助函数来加密和解密我们的信息,因为我们不能以纯文本形式存储敏感信息。
为什么是高级加密系统 (AES) 而不是 RSA 加密?您也可以在这里使用 RSA 加密,因为我们这里不处理大量数据。我使用了 AES 加密,因此我不必维护两个密钥。
现在,使用以下代码更新 utils/index.js 文件
const misc = require("./misc");
const encryption = require("./encryption");
module.exports = {
...misc,
...encryption,
};
并且,在 utils/misc.js 文件中,让我们添加辅助函数来生成帐户。
const { encrypt } = require("./encryption");
const { Wallet } = require("ethers");
...
function generateAccount(phrase, index = 0) {
/**
* If the phrase does not contain spaces, it is likely a private key
*/
const wallet = phrase.includes(" ")
? Wallet.fromMnemonic(phrase, `m/44'/60'/0'/0/${index}`)
: new Wallet(phrase);
return {
address: wallet.address,
privateKey: encrypt(wallet.privateKey),
mnemonic: encrypt(phrase),
};
}
module.exports = {
...,
generateAccount,
};
在上面的代码片段中,我们检查传递的短语是否是种子短语,然后使用派生路径获取给定索引处的钱包。我们还会在返回敏感信息之前对其进行加密。
现在,我们必须使用以下代码更新 scenes/importWalletScene.js 文件中的文本处理程序
importWalletStep.on("text", (ctx) => {
const phrase = ctx.message.text;
try {
const wallet = generateAccount(phrase);
ctx.reply("Address: " + wallet.address);
} catch (error) {
ctx.reply(
"😔 This does not appear to be a valid private key / mnemonic phrase. Please try again."
);
}
ctx.scene.leave();
});
我认为这里的代码是不言自明的。
现在,我们只需要检查一下这段代码。
首先,让我们再次运行 npm install。
之后,你可以运行 node index.js
如果输入了错误的种子短语/私钥,你将看到以下屏幕
但是,如果您输入正确的种子短语/私钥,您将在回复中收到地址。我不会在本博客中这样做,但如果您在执行此操作时遇到任何问题,您可以对该问题发表评论,我可以尝试进行调试。
啊!最后,钱包准备好了。
3、显示钱包
如果我们想让用户稍后也可以查看导入的钱包,该怎么办?
好吧,要做到这一点,您需要将导入的钱包存储在某个地方,稍后当用户单击“显示钱包”按钮(我们将为此提供一个按钮)时,我们将显示导入钱包的公共地址。
我们将存储从generateAccount函数返回的完整对象,因此如果您以后想使用私钥或助记词进行某些操作,您可以这样做。
我们不会在这里使用任何像DB这样的持久存储,所以我们会有一个类似非托管钱包的东西。
Telegram 有一种称为会话存储的功能,基本上,它会将信息保留在会话中,并且每当您重新启动服务器时,会话都会被清除。
让我们快速添加此功能。
首先,在 /start 命令消息中添加一个新按钮。为此,请在 index.js 文件中添加以下代码
bot.command("start", (ctx) => {
...
const showWalletButton = createCallBackBtn("Show Wallet", "show-wallet");
ctx.reply(message, {
reply_markup: {
inline_keyboard: [[importWalletButton], [showWalletButton]],
},
});
});
...
bot.action("show-wallet", (ctx) => {
if (ctx.session.wallet) {
ctx.reply(`Your wallet address is ${ctx.session.wallet.address}`);
} else {
ctx.reply("You have not imported any wallet yet.");
}
});
现在,在 scenes/importWalletScene.js 文件中,我们必须在会话中添加新生成的钱包,为此添加以下代码
importWalletStep.on("text", (ctx) => {
try {
const wallet = generateAccount(phrase);
ctx.session.wallet = wallet;
ctx.reply(
`🎉 Your wallet has been successfully imported. Your wallet address is ${wallet.address}.`
);
} catch (error) {
...
}
});
如果你现在在终端中运行 node index.js 命令,导入钱包,然后单击显示钱包按钮(你可以输入 /start 命令并检查),你将看到类似以下内容
终于完成了🥱。您可以在这里找到完整的代码。
原文链接:Write your own Telegram Wallet bot
DefiPlot翻译整理,转载请标明出处