Recently, Telegram has officially opened up Mini App capabilities to developers, meaning you can build native app-like interactive experiences within Telegram. Today, we'll guide you step-by-step in building a simple yet complete Web3 mini-game. Users can create a wallet with just their email, play Rock Paper Scissors, and claim token rewards – all without the user paying any Gas fees.
This tutorial will not only teach you how to create and deploy a Telegram Mini App but also demonstrate how to leverage the free features of the thirdweb SDK to implement core Web3 capabilities like Account Abstraction, wallet creation, and token airdrops.
Telegram boasts over 800 million monthly active users and supports global developers in deploying applications for free. For Web3 projects, the advantages of Telegram Mini Apps are:
Combined with Account Abstraction technology, you can enable users to have an on-chain wallet using only their email, without needing to download wallet plugins – this is crucial for lowering the barrier to entry for Web3 projects.
The core workflow of this game is:
Throughout this process, users don't need to pay any Gas fees or encounter complex signature confirmation prompts – this is the true seamless Web3 experience brought by Account Abstraction + Gas Sponsorship.
In the Telegram search bar, type @BotFather and find the official bot. Click "Start."
Enter the command to create a new bot:
/newbotFollow the prompts to enter a name and username (must end with bot), for example:
Name: thirdweb YouTube Demo
Username: thirdwebYouTubeBotUpon successful creation, BotFather will return a Token – keep it safe, as it's your credential for managing the bot.
Continue in BotFather by entering:
/newappSelect the bot you just created, then fill in the following information sequentially:
thirdweb Rock Paper Scissors DemoWeb3 Rock Paper Scissors Mini GameAt this point, Telegram will prompt you to provide the access link for your Mini App. Let's develop the application first, then fill in this field.
Open your terminal and run:
bun create viteSelect:
thirdweb-telegram-miniappReactTypeScript + SWCNavigate into the project directory:
cd thirdweb-telegram-miniappInstall the Telegram Web App adapter library:
bun add @vov/react-telegram-web-appInstall the thirdweb SDK:
bun add thirdwebOpen index.html and add the following within the <head> tag:
<script src="https://telegram.org/js/telegram-web-app.js"></script>This code tells Telegram that your webpage needs to run in a Mini App environment.
npm run devThis will typically start the service at http://localhost:5174.
Since Telegram requires a public URL to access your Mini App, we'll use the ngrok tool to temporarily expose your local service to the internet.
Run:
ngrok http 5174ngrok will return a public URL, for example:
https://abc123.ngrok.ioCopy this link, go back to BotFather, and paste it into the Web App URL field.
Now, if you click the Mini App link in Telegram, you should see your default Vite page!
Go to the thirdweb Dashboard, navigate to Settings > API Keys, and create a new Client ID.
Copy the Client ID into a .env.local file in your project's root directory:
VITE_CLIENT_ID=your_client_id_hereWrap your application in src/main.tsx:
import { ThirdwebProvider } from "thirdweb/react";
import { createThirdwebClient } from "thirdweb";
const client = createThirdwebClient({
clientId: import.meta.env.VITE_CLIENT_ID,
});
root.render(
<ThirdwebProvider>
<App />
</ThirdwebProvider>
);Use the ConnectButton component provided by thirdweb:
import { ConnectButton } from "thirdweb/react";
import { inAppWallet } from "thirdweb/wallets";
<ConnectButton
client={client}
wallets={[
inAppWallet({
auth: {
options: ["email"],
},
}),
]}
/>The user enters their email → receives a verification code → after successful verification, a wallet is automatically generated → complete!
Implement the core logic in src/components/RockPaperScissors.tsx:
type Choice = "rock" | "paper" | "scissors";
type Result = "win" | "lose" | "tie";
const choices: Choice[] = ["rock", "paper", "scissors"];
const getComputerChoice = (): Choice => {
return choices[Math.floor(Math.random() * 3)];
};
const determineWinner = (player: Choice, computer: Choice): Result => {
if (player === computer) return "tie";
if (
(player === "rock" && computer === "scissors") ||
(player === "paper" && computer === "rock") ||
(player === "scissors" && computer === "paper")
) {
return "win";
}
return "lose";
};The user clicks a button → the computer's choice is randomly generated → the win/loss is determined → the result is displayed.
Go back to the thirdweb Dashboard, click Contracts > Deploy, and select Token Drop.
Configure:
Rock Paper Scissors TokenRPSBase SepoliaAfter successful deployment, set the Claim Conditions to "Public claim, no restrictions."
Copy the contract address and add it to your code:
import { getContract } from "thirdweb";
import { baseSepolia } from "thirdweb/chains";
const contract = getContract({
client,
chain: baseSepolia,
address: "0xYourContractAddress",
});Add the following to your ConnectButton:
<ConnectButton
client={client}
wallets={[inAppWallet({ auth: { options: ["email"] } })]}
accountAbstraction={{
chain: baseSepolia,
sponsorGas: true,
}}
/>This ensures that the wallet generated for the user is a Smart Account wallet, and we can sponsor their Gas fees.
import { TransactionButton } from "thirdweb/react";
import { claimTo } from "thirdweb/extensions/erc20";
<TransactionButton
transaction={() =>
claimTo({
contract,
to: account.address,
quantity: "10",
})
}
onTransactionConfirmed={() => alert("Token claimed!")}
>
Claim 10 RPS
</TransactionButton>The user clicks the button → thirdweb automatically handles the transaction → tokens arrive → the user pays nothing!
import { useReadContract } from "thirdweb/react";
import { getBalance } from "thirdweb/extensions/erc20";
const { data: tokenBalance } = useReadContract(getBalance, {
contract,
address: account.address,
});
<div>Balance: {tokenBalance?.displayValue} RPS</div>import { useDisconnect, useActiveWallet } from "thirdweb/react";
const wallet = useActiveWallet();
const { disconnect } = useDisconnect();
<button onClick={() => disconnect(wallet)}>Log Out</button>Open Telegram on your phone, search for your bot, and click the Mini App link:
All thirdweb features used in this tutorial fall under the free plan, including wallet creation, contract interaction, and account abstraction. If you need direct login using a Telegram account (without email verification), you'll need to upgrade to a paid plan.
You can add logic within your smart contract to limit the number of claims per address or use thirdweb's Claim Conditions feature to set rules like whitelists or time windows.
Absolutely. Simply replace the chain in your getContract and accountAbstraction configurations with your desired chain (e.g., Polygon, Arbitrum, etc.). thirdweb supports over 900 EVM-compatible chains.
Deploy your code to platforms like Vercel or Netlify. Once you have a formal domain, replace the Web App URL in BotFather.
thirdweb's free plan provides a certain amount of sponsored Gas per month, which is sufficient for small projects or testing. If you have high traffic, you can upgrade based on your actual needs.
Through this tutorial, you've learned how to build a complete Web3 application within Telegram – from wallet creation and game logic to token distribution, all seamlessly integrated. This tech stack is not only suitable for mini-games but can also be extended to DeFi, NFTs, social applications, and more.
Outline
_00000.png)

