Build an automated workflow that sends Telegram alerts when a wallet balance falls below a specified threshold using Kwala
Manually tracking wallet balances in decentralized apps can mean missed alerts and failed transactions. In this guide, we’ll build a low-balance notifier that automatically sends a Telegram alert when a wallet’s native token balance falls below a chosen threshold using Kwala’s low-code automation platform.With Kwala, you can create event-driven workflows using simple YAML scripts, no backend servers required.
Step 1: Build and deploy the Solidity smart contract
This Solidity contract checks user balances and emits an event when the balance drops below 0.1 POL.Solidity smart contract:
Copy
// SPDX-License-Identifier: MITpragma solidity ^0.8.20;/// @title Native POL balance checker (Polygon)/// @notice Emits an event if a user's native POL balance is below 0.1 POL.contract PolNativeBalanceChecker { // 1 POL == 1 ether in EVM units; 0.1 POL is 0.1 ether. uint256 public constant THRESHOLD = 0.1 ether; event LowPolBalance(address indexed user, uint256 balanceWei); /// @notice Read-only helper to get any address's native POL balance. function polBalanceOf(address user) public view returns (uint256) { return user.balance; // Wei } /// @notice Checks `user` balance and emits LowPolBalance if below 0.1 POL. /// @return balanceWei The user's current balance in wei. function checkAndWarn(address user) public returns (uint256 balanceWei) { balanceWei = user.balance; if (balanceWei < THRESHOLD) { emit LowPolBalance(user, balanceWei); } } /// @notice Convenience for the caller; checks your own balance and may emit. function checkMe() external returns (uint256) { return checkAndWarn(msg.sender); }}
How it worksThe contract compares a user’s balance with the defined threshold. If the balance is below the threshold, it emits a LowPolBalance event: this event becomes the trigger for your Kwala workflow.
Deploy the contract using Remix and connect your MetaMask wallet to Polygon Amoy Testnet. You must have POL Faucet to deploy the smart contract.
After deployment, copy your deployed smart contract address from the Amoy Polygon explorer (https://amoy.polygonscan.com/) to inspect the contract and its transactions.
Bot token to access the HTTP API, for example, 7754368882:AAHS4KbbOkl5rEHoBBIR8eljgwq2PARYLyY
Chat ID, for example, 968602918
Use these credentials inside the workflow to send notifications later.
Test your bot token using an API tool like ReqBin or Postman with a POST request. If the token works, the test request will deliver a Telegram notification.
TriggersThis is the event that activates your workflow.
Execute After: Set to event: executes the action after the event is emitted.
Repeat Every:event triggered by the event.
Expires: Add an expiration timestamp. For example, 17-09-2025 16:00 in IST.
ParameterValue: RecurringSource Contract:0x1C5a23Fd1F7fEd9A5d020858BD4b93e5c93C92a8 the deployed smart contract address, available on Amoy Polygonscan.
Below is the YAML script to use for your Kwala workflow. Save and compile this code in the Kwala dashboard.
Copy
Name: LowBalanceNotification15Trigger: TriggerSourceContract: 0x1C5a23Fd1F7fEd9A5d020858BD4b93e5c93C92a8 TriggerChainID: 80002 TriggerEventName: LowPolBalance(address,uint256) TriggerEventFilter: NA TriggerSourceContractABI: WwogIHsKICAgICJhbm9ueW1vdXMiOiBmYWxzZSwKICAgICJpbnB1dHMiOiBbCiAgICAgIHsKICAgICAgICAiaW5kZXhlZCI6IHRydWUsCiAgICAgICAgImludGVybmFsVHlwZSI6ICJhZGRyZXNzIiwKICAgICAgICAibmFtZSI6ICJ1c2VyIiwKICAgICAgICAidHlwZSI6ICJhZGRyZXNzIgogICAgICB9LAogICAgICB7CiAgICAgICAgImluZGV4ZWQiOiBmYWxzZSwKICAgICAgICAiaW50ZXJuYWxUeXBlIjogInVpbnQyNTYiLAogICAgICAgICJuYW1lIjogImJhbGFuY2VXZWkiLAogICAgICAgICJ0eXBlIjogInVpbnQyNTYiCiAgICAgIH0KICAgIF0sCiAgICAibmFtZSI6ICJMb3dQb2xCYWxhbmNlIiwKICAgICJ0eXBlIjogImV2ZW50IgogIH0sCiAgewogICAgImlucHV0cyI6IFtdLAogICAgIm5hbWUiOiAiVEhSRVNIT0xEIiwKICAgICJvdXRwdXRzIjogWwogICAgICB7CiAgICAgICAgImludGVybmFsVHlwZSI6ICJ1aW50MjU2IiwKICAgICAgICAibmFtZSI6ICIiLAogICAgICAgICJ0eXBlIjogInVpbnQyNTYiCiAgICAgIH0KICAgIF0sCiAgICAic3RhdGVNdXRhYmlsaXR5IjogInZpZXciLAogICAgInR5cGUiOiAiZnVuY3Rpb24iCiAgfSwKICB7CiAgICAiaW5wdXRzIjogWwogICAgICB7CiAgICAgICAgImludGVybmFsVHlwZSI6ICJhZGRyZXNzIiwKICAgICAgICAibmFtZSI6ICJ1c2VyIiwKICAgICAgICAidHlwZSI6ICJhZGRyZXNzIgogICAgICB9CiAgICBdLAogICAgIm5hbWUiOiAiY2hlY2tBbmRXYXJuIiwKICAgICJvdXRwdXRzIjogWwogICAgICB7CiAgICAgICAgImludGVybmFsVHlwZSI6ICJ1aW50MjU2IiwKICAgICAgICAibmFtZSI6ICJiYWxhbmNlV2VpIiwKICAgICAgICAidHlwZSI6ICJ1aW50MjU2IgogICAgICB9CiAgICBdLAogICAgInN0YXRlTXV0YWJpbGl0eSI6ICJub25wYXlhYmxlIiwKICAgICJ0eXBlIjogImZ1bmN0aW9uIgogIH0sCiAgewogICAgImlucHV0cyI6IFtdLAogICAgIm5hbWUiOiAiY2hlY2tNZSIsCiAgICAib3V0cHV0cyI6IFsKICAgICAgewogICAgICAgICJpbnRlcm5hbFR5cGUiOiAidWludDI1NiIsCiAgICAgICAgIm5hbWUiOiAiIiwKICAgICAgICAidHlwZSI6ICJ1aW50MjU2IgogICAgICB9CiAgICBdLAogICAgInN0YXRlTXV0YWJpbGl0eSI6ICJub25wYXlhYmxlIiwKICAgICJ0eXBlIjogImZ1bmN0aW9uIgogIH0sCiAgewogICAgImlucHV0cyI6IFsKICAgICAgewogICAgICAgICJpbnRlcm5hbFR5cGUiOiAiYWRkcmVzcyIsCiAgICAgICAgIm5hbWUiOiAidXNlciIsCiAgICAgICAgInR5cGUiOiAiYWRkcmVzcyIKICAgICAgfQogICAgXSwKICAgICJuYW1lIjogInBvbEJhbGFuY2VPZiIsCiAgICAib3V0cHV0cyI6IFsKICAgICAgewogICAgICAgICJpbnRlcm5hbFR5cGUiOiAidWludDI1NiIsCiAgICAgICAgIm5hbWUiOiAiIiwKICAgICAgICAidHlwZSI6ICJ1aW50MjU2IgogICAgICB9CiAgICBdLAogICAgInN0YXRlTXV0YWJpbGl0eSI6ICJ2aWV3IiwKICAgICJ0eXBlIjogImZ1bmN0aW9uIgogIH0KXQ== TriggerPrice: NA RecurringSourceContract: 0x1C5a23Fd1F7fEd9A5d020858BD4b93e5c93C92a8 RecurringChainID: 80002 RecurringEventName: LowPolBalance(address,uint256) RecurringEventFilter: NA RecurringSourceContractABI: WwogIHsKICAgICJhbm9ueW1vdXMiOiBmYWxzZSwKICAgICJpbnB1dHMiOiBbCiAgICAgIHsKICAgICAgICAiaW5kZXhlZCI6IHRydWUsCiAgICAgICAgImludGVybmFsVHlwZSI6ICJhZGRyZXNzIiwKICAgICAgICAibmFtZSI6ICJ1c2VyIiwKICAgICAgICAidHlwZSI6ICJhZGRyZXNzIgogICAgICB9LAogICAgICB7CiAgICAgICAgImluZGV4ZWQiOiBmYWxzZSwKICAgICAgICAiaW50ZXJuYWxUeXBlIjogInVpbnQyNTYiLAogICAgICAgICJuYW1lIjogImJhbGFuY2VXZWkiLAogICAgICAgICJ0eXBlIjogInVpbnQyNTYiCiAgICAgIH0KICAgIF0sCiAgICAibmFtZSI6ICJMb3dQb2xCYWxhbmNlIiwKICAgICJ0eXBlIjogImV2ZW50IgogIH0sCiAgewogICAgImlucHV0cyI6IFtdLAogICAgIm5hbWUiOiAiVEhSRVNIT0xEIiwKICAgICJvdXRwdXRzIjogWwogICAgICB7CiAgICAgICAgImludGVybmFsVHlwZSI6ICJ1aW50MjU2IiwKICAgICAgICAibmFtZSI6ICIiLAogICAgICAgICJ0eXBlIjogInVpbnQyNTYiCiAgICAgIH0KICAgIF0sCiAgICAic3RhdGVNdXRhYmlsaXR5IjogInZpZXciLAogICAgInR5cGUiOiAiZnVuY3Rpb24iCiAgfSwKICB7CiAgICAiaW5wdXRzIjogWwogICAgICB7CiAgICAgICAgImludGVybmFsVHlwZSI6ICJhZGRyZXNzIiwKICAgICAgICAibmFtZSI6ICJ1c2VyIiwKICAgICAgICAidHlwZSI6ICJhZGRyZXNzIgogICAgICB9CiAgICBdLAogICAgIm5hbWUiOiAiY2hlY2tBbmRXYXJuIiwKICAgICJvdXRwdXRzIjogWwogICAgICB7CiAgICAgICAgImludGVybmFsVHlwZSI6ICJ1aW50MjU2IiwKICAgICAgICAibmFtZSI6ICJiYWxhbmNlV2VpIiwKICAgICAgICAidHlwZSI6ICJ1aW50MjU2IgogICAgICB9CiAgICBdLAogICAgInN0YXRlTXV0YWJpbGl0eSI6ICJub25wYXlhYmxlIiwKICAgICJ0eXBlIjogImZ1bmN0aW9uIgogIH0sCiAgewogICAgImlucHV0cyI6IFtdLAogICAgIm5hbWUiOiAiY2hlY2tNZSIsCiAgICAib3V0cHV0cyI6IFsKICAgICAgewogICAgICAgICJpbnRlcm5hbFR5cGUiOiAidWludDI1NiIsCiAgICAgICAgIm5hbWUiOiAiIiwKICAgICAgICAidHlwZSI6ICJ1aW50MjU2IgogICAgICB9CiAgICBdLAogICAgInN0YXRlTXV0YWJpbGl0eSI6ICJub25wYXlhYmxlIiwKICAgICJ0eXBlIjogImZ1bmN0aW9uIgogIH0sCiAgewogICAgImlucHV0cyI6IFsKICAgICAgewogICAgICAgICJpbnRlcm5hbFR5cGUiOiAiYWRkcmVzcyIsCiAgICAgICAgIm5hbWUiOiAidXNlciIsCiAgICAgICAgInR5cGUiOiAiYWRkcmVzcyIKICAgICAgfQogICAgXSwKICAgICJuYW1lIjogInBvbEJhbGFuY2VPZiIsCiAgICAib3V0cHV0cyI6IFsKICAgICAgewogICAgICAgICJpbnRlcm5hbFR5cGUiOiAidWludDI1NiIsCiAgICAgICAgIm5hbWUiOiAiIiwKICAgICAgICAidHlwZSI6ICJ1aW50MjU2IgogICAgICB9CiAgICBdLAogICAgInN0YXRlTXV0YWJpbGl0eSI6ICJ2aWV3IiwKICAgICJ0eXBlIjogImZ1bmN0aW9uIgogIH0KXQ== RecurringPrice: NA RepeatEvery: event ExecuteAfter: event ExpiresIn: 1789749000 Meta: NA ActionStatusNotificationPOSTURL: ActionStatusNotificationAPIKey: NAActions: - Name: telegram_notifier Type: post APIEndpoint: https://api.telegram.org/bot7754368882:AAHS4KbbOkl5rEHoBBIR8eljgwq2PARYLyY/sendMessage APIPayload: chat_id: '968602918' text: LOW BALANCE! Recharge your wallet. Add 5 POL TargetContract: NA TargetFunction: NA TargetParams: ChainID: NA EncodedABI: NA Bytecode: NA EncodedGoContract: NA Metadata: NA RetriesUntilSuccess: 5Execution: Mode: sequential
After successful compilation, deploy the workflow. Activate it in Kwala and wait for the workflow status to show claimed.
Make sure you are in the Kwala network (not Polygon Amoy testnet) in MetaMask when creating/deploying this workflow.
Name: Polling1Trigger: TriggerSourceContract: NA TriggerChainID: NA TriggerEventName: NA TriggerEventFilter: NA TriggerSourceContractABI: NA TriggerPrice: NA RecurringSourceContract: NA RecurringChainID: NA RecurringEventName: NA RecurringEventFilter: NA RecurringSourceContractABI: NA RecurringPrice: NA RepeatEvery: 1m ExecuteAfter: immediate ExpiresIn: 1789732800 Meta: NA ActionStatusNotificationPOSTURL: ActionStatusNotificationAPIKey: NAActions: - Name: Polling1 Type: call APIEndpoint: NA APIPayload: Message: NA TargetContract: 0x0F0C0b9683180DF0a13Fc176aFFd92E1F7f380f0 TargetFunction: function checkAndWarn(address user) TargetParams: - 0x0F0C0b9683180DF0a13Fc176aFFd92E1F7f380f0 ChainID: 80002 EncodedABI: NA Bytecode: NA EncodedGoContract: NA Metadata: NA RetriesUntilSuccess: 5Execution: Mode: parallel
Save, compile, and deploy this workflow. Activate it and wait for the workflow status to show claimed.
The trigger monitors the LowPolBalance event, and when the event fires, the workflow sends a POST request to your Telegram bot API endpoint with a custom message. Within seconds, you’ll receive a Telegram message automatically.The second automated Kwala workflow (polling) runs every minute after checkAndWarn is called in Remix; it will trigger a notification each minute. Your Telegram will display: “LOW BALANCE! Recharge your wallet. Add 5 POL” repeatedly, every minute. The process runs automatically with no manual checks required.
In this guide, you built a real-time wallet balance notifier using Kwala’s low-code workflow automation. The notifier has no backend servers or infrastructure overhead; just a smart contract and a YAML configuration. Kwala empowers developers to create, automate, and scale on-chain logic effortlessly.