Introduction
In this tutorial, we'll create a Telegram bot that simulates a Tamagotchi-like virtual pet. This bot will allow users to interact with their virtual pet, feed it, play with it, and monitor its health.
Prerequisites
- Basic knowledge of Cairo programming, Cairo extension for vscode
- Basic knowledge of any frontend dev framework (I’ll use Svelte x Vite here), required vscode extensions
- A Telegram test account
PART 1: Smart-contracts
Step 1: Install devtools
- Be sure Rust is up-to-date, otherwise run this command:
- Install Scarb and Starknet-foundry. The easiest way, imo, is to use
asdf
- Scarb is the main package manager and build tool for Cairo. It’s like Cargo for Rust.
- Starknet-foundry is the testing framework for Cairo and Starknet smart-contracts. It is similar to Foundry for Solidity
Step 2: Setup Cairo project
Simply type snforge init project_name
, ez pz. Don’t forget to replace project_name
by a nice name for your repo. You should see a src/ folder, a test/ folder and scarb config files. Let’s write some code now !
Step 3: Code
Open src/lib.cairo and erase everything. Make your file look like this:
I won’t talk about the structure of a Cairo code here. The Cairo Book is the best place to learn the language. Cairo Agent might help too!
So, our goal is to create a basic Tamagotchi app. We would like our pet to be described by a few variables, his hunger, his happiness and his energy. Let’s add that to our contract storage. We also would like to write getters for our variables. Don’t forget, to add the functions in the interface too!
Then we need to implement user interactions. A user can play with his pet, feed him or make him rest. The characteristics of our little friend can go from 0 to 100. We can add that as constants. Let’s also configure the amount of points the pet can get or lose as constants. Of course in theory, we should bound all values to MAX or MIN (i.e not having an energy bar > 100) but we don’t really care for this tutorial. I also won’t implement the time aspect in our app. We keep it suuuuper simple. For the sake of the demo, let’s add a set_stats_to_half function so that we’ll be able to test easily our buttons on the frontend side. Let’s also fill in the constructor and set all values at 100 when deployed.
That’s basically it for the smart-contract. It obviously lacks a lot of features to turn it into a real Tamagotchi game but it’s enough for our telegram mini app demo !
Also, since we are serious devs, we need to write a test for our code. Add this to your tests/test_contract.cairo file. Then run snforge test.
Step 4: Declare contract and deploy
The next step is to deploy our contract on Sepolia. You first need to setup a wallet locally. You can either create a brand new or import an existing one. I guess you already have an Argent X testnet wallet. You can import it. In my case, this is what I did. To create an account, it is well explained here.You will need to fund it with testnet ETH or STRK, you can grab some here: https://starknet-faucet.vercel.app/.
The tool that we will use to do that is sncast
. It comes with starknet-foundry
that we installed at the beginning.
We need to call this:
- url: your rpc url. There are several API providers on Starknet. See the list.
- address: your argent x wallet address
- private-key: your Argent X wallet private key. Settings → Account → Export private key
That being said, we can now declare and deploy our contract. Smart-contracts on Starknet have classes (like in OOP). Multiple smart-contracts can be deployed using the same class. So we first need to declare our smart-contract class, then, in a second transaction, using the class, we will deploy the smart-contract.
For declaring the contract, please run this command:
It will print something like this:
Notice that I’m using env variables for RPC_URL
, PRIVATE_KEY
and ADDRESS
.
Now, to deploy, we need to run this:
and you will see your contract address and the deployment transaction hash.
PART 2: Frontend 🎨
Feel free to use your favourite framework but here I’ll use Svelte + Vite. This great guide by Manu uses React + vite if you want another example.Svelte handles how we write our components and UI logic while Vite handles how we develop and build the application. I will also use Typescript and Tailwindcss for the style.
1. Project initialization:
We have a few commands to run:
To set up tailwind we need to do a few more things:
1. Init tailwind config
2. Update tailwind.config.js
to add Svelte
3. Also, add this to app.css :
We’re almost there, don’t worry!
Create a src/app.d.ts
file and paste this:
This is used to tell Typescript how to handle Svelte files.
Update tsconfig.ts
:
Now everything should be all right ! You can run the app to see if there is no errors:
In order to verify that tailwind has been configured properly, feel free to change the color of the title and see the result.
Finally, in index.html
, add this to the <head>
2. Game implementation
Now, we will build something like this, with a cute doggo. I asked midjourney for the chara-design.
.png)
Please be nice with my design 🥲, me no designer
2.1 Pet Component
In src/lib/, create a file called Tamagotchi.svelte. Add this:
For the demo, our doggo will only have 3 moods, happy, sad and neutral. You need 3 pics to illustrate that. Place them in src/assets/
. you might need to change the imports.
2.2 Buttons
In src/lib/, create another file called Buttons.svelte
.
2.3 Game logic
Create a lib/contracts.ts
file. It’s a helper file for us that will contain smart-contracts and wallet interactions.
We implement the Argent telegram wallet SDK here. Don’t worry about the two environment variables VITE_TELEGRAM_APP_NAME
and VITE_TELEGRAM_APP_URL
. We will configure them later.
If you’d like to pay the transaction fees in STRK, you’d need to implement this in a slightly more complex way, see Starknet.js doc:
An important thing to notice here is this:
The goal of the SDK it to allow devs to create mini apps with a smooth blockchain integration. We think that a good UX for a game has to abstract away the entire concept of blockchain. The user shouldn’t even notice he is interacting with one. Our SDK uses “Session keys”.
You can configure which functions the backend will be able to execute on behalf of the user.
Now comes the most important file. Create a src/lib/Game.svelte
file. We will implement the game logic there. It will look like this:
2.4 Last touch
Now, if you copy paste this. You will still have a few errors in the code. To solve the first one, run this command:
pnpm add svelte-french-toast
I’m using toasts to send actions notifications to the user.Add this to App.svelte
To solve another one, you need to go back to your smart-contract repo. Go to target/
. this folder contains the build files from scarb. Now copy a file called tamago_Tamagotchi.contract_class.json
, projectName_smartcontractName.contract_class.json.
In your frontend repo, create a folder src/utils/abi
and paste the file there. you don’t really need to understand what’s in that file. We’re only interested in the abi
attribute. The ABI contains every function signatures of your smart-contracts. It describes how to interact with your smart-contract. Modify your import accordingly import artifact from '../utils/abi/tamago_Tamagotchi.contract_class.json';
in Game.svelte
Finally, create a .env file at the root of you project. Create the variable VITE_TAMAGOTCHI_CONTRACT_ADDRESS=0xyour_contract_address
. The contract address was given to you when you deployed your smart-contract here.
Now, you shouldn’t see any errors in the code.
Run pnpm dev
and see what it does. Feel fry to modify the frontend as you wish !
PART 3: Telegram bot
Last chapter of the tutorial. Now that we have our app ready, let’s integrate it with Telegram.
The first step will be to create a Telegram test account if you don’t already have one. Mano explains it here.
🚨 DON’T FORGET TO SETUP A USERNAME FOR YOUR TEST ACCOUNT. 🚨
1. Talk to @BotFather to create a bot
A bot to create them all: https://telegram.me/BotFather
Interact with Botfather.
Run /newbot
and follow what he says to create a new bot.
2. Talk to Botfather again to create a new app
Run /newapp
and follow the instructions.
At some point, Botfather will ask for an app URL. You need to make your webapp host available somewhere. There are several ways to do that. You could deploy it on Vercel and share the vercel link but that wouldn’t be super efficient and convenient for a development phase. With Vite you can expose your local app to the network by running pnpm run dev --host
. This exposes your IP address so use only that for dev purposes.
Other tools like ngrok
exist to expose a local project to the network. It’s also fine to use that and even safer.
Give Botfather the URL from the Vite server or ngrok.
He’ll then ask you for an app name.
At the end of the process, Botfather will give you an app url.
3. Configure the SDK with your Telegram app params
Go back to your frontend Game.svelte
file. Find this:
Replace appName
and appTelegramUrl
with the values from Botfather.
4. Configure the bot
We created the app and now we need to configure the bot to launch our app.
Talk to Botfather, prompt /mybots
. Select yours. Then go to Bot settings. Click on Menu Button then “Configure Menu Button”. He will ask for a URL, give him your Telegram app url http://t.me/TestBotTutoBot/titleForApp.
He will then ask for the button title. You can put something like “Open mini app”.
Now, if you open your bot chat, you’ll see the blue button “Open mini app”. If you click on it, it will open your mini app !
You could also customize your bot commands (/start, /help etc) if you wished to.
Written by Antoine Mecker, Dev Rel @ Argent.
For any questions, ping me on Telegram @Flexouille.