Skip to main content

Minimal Python framework for building crypto bots

Project description

tinybot

Minimal Python framework for building crypto bots.

Installation

pip install tinybot-eth

Environment Variables

Variable Required Description
BOT_ACCESS_TOKEN Yes Telegram bot token
GROUP_CHAT_ID Yes Telegram group for notifications
DEV_GROUP_CHAT_ID Yes Telegram group for errors and startup
PRIVATE_KEY No Private key for onchain execution

Quick Start

bot = TinyBot(rpc_url, name="my bot")

bot.listen(event="AuctionKicked", handler=on_kick, ...)
bot.every(180, check_expired)

await bot.run()
import asyncio
import os
from tinybot import TinyBot, multicall, notify_group_chat

ERC20_ABI = [...]
STRATEGY_ABI = [...]

async def on_transfer(bot, log):
    print(f"{log.args.sender} -> {log.args.receiver}: {log.args.value}")
    await notify_group_chat(f"Transfer from {log.args.sender}")

async def check_and_tend(bot):
    strategy = bot.w3.eth.contract(address="0x...", abi=STRATEGY_ABI)
    needs_tend, _ = strategy.functions.tendTrigger().call()
    if needs_tend:
        tx_hash = bot.executor.execute(
            strategy.functions.tend(),
            gas_limit=5_000_000,
        )
        await notify_group_chat(f"Tend submitted: {tx_hash}")

async def main():
    bot = TinyBot(
        rpc_url=os.environ["RPC_URL"],
        name="my bot",
        private_key=os.environ.get("PRIVATE_KEY", ""),
    )

    bot.listen(
        event="Transfer",
        addresses=["0x..."],
        abi=ERC20_ABI,
        handler=on_transfer,
        poll_interval=180,
    )

    bot.every(3600, check_and_tend)

    await bot.run()

asyncio.run(main())

API

TinyBot(rpc_url, name="tinybot", private_key="")

Creates a bot instance.

  • bot.w3web3.Web3 instance
  • bot.stateState instance (see below)
  • bot.executorExecutor instance if private_key is provided, else None
  • bot.name — used in logs and Telegram startup message

On run(), sends a startup message to DEV_GROUP_CHAT_ID and prints a polling heartbeat every tick.


bot.listen(...) -> EventListener

Register an event listener.

bot.listen(
    event="AuctionKicked",   # event name (must exist in ABI)
    addresses=["0x..."],     # contracts to monitor
    abi=[...],               # ABI containing the event
    handler=on_kick,         # async fn(bot, log)
    name="kicks",            # defaults to handler.__name__ (optional)
    poll_interval=180,       # seconds between polls (default: 180)
    block_buffer=5,          # re-scan buffer in blocks (default: 5)
    notify_errors=True,      # send errors to Telegram (default: True)
)

The event signature is derived from the ABI at registration time. Raises ValueError if:

  • Event not found in ABI
  • Duplicate listener name
  • Empty addresses

bot.every(interval, handler, name="", notify_errors=True) -> PeriodicTask

Register a periodic task.

bot.every(3600, check_expired)

Handler signature: async fn(bot)


bot.get_listener(name) -> EventListener

Get a registered listener by name. Raises ValueError if not found.


bot.replay(name, from_block, to_block)

Replay historical events through a listener's handler. Useful for testing with real chain data.

await bot.replay("kicks", from_block=21000000, to_block=21000500)

bot.run(tick=10)

Start the polling loop. tick (default: 10s) is the inner loop sleep. Each listener and task fires at its own interval.


EventListener

Returned by bot.listen().

  • listener.add_address(address) — add a contract address at runtime
  • listener.remove_address(address) — remove a contract address at runtime

Both handle checksumming and dedup.


Executor

Available via bot.executor when private_key is provided.

bot = TinyBot(rpc_url, name="my bot", private_key=os.environ["PRIVATE_KEY"])

tx_hash = bot.executor.execute(
    contract.functions.tend(strategy_addr),
    gas_limit=5_000_000,
    max_fee_gwei=100,
    max_priority_fee_gwei=3,
)
  • executor.address — signer address
  • executor.balance — signer ETH balance in wei
  • executor.execute(call, ...) — sign and broadcast a transaction, returns tx hash immediately (fire and forget)

State

In-memory state, available via bot.state.

  • state.last_blockdict[str, int] mapping names to last processed block
  • state.active_itemslist of tracked items (e.g. address pairs)
  • state.add_item(*addrs) — add an item (deduped)
  • state.remove_item(item) — remove an item
  • state.is_processed(event_id) — check if event was processed
  • state.mark_processed(event_id) — mark event as processed (handled automatically for listeners)

multicall(w3, calls) -> list

Batch contract reads via Multicall3.

symbol, decimals = multicall(bot.w3, [
    token.functions.symbol(),
    token.functions.decimals(),
])

notify_group_chat(text, parse_mode="HTML", chat_id=GROUP_CHAT_ID)

Send a Telegram message. HTML parse mode by default.


event_id(log) -> str

Unique ID from a log (txHash:logIndex). Used internally for dedup, also available for custom event processing in periodic tasks.

Handler Signatures

# Event handler
async def on_event(bot: TinyBot, log) -> None: ...

# Task handler
async def my_task(bot: TinyBot) -> None: ...

Access bot.w3, bot.state, bot.executor, and bot.get_listener() from any handler.

Error Handling

Enabled by default. Exceptions are caught and sent to DEV_GROUP_CHAT_ID as [name] error message. The bot continues running. Set notify_errors=False to disable.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tinybot_eth-0.2.0.tar.gz (9.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tinybot_eth-0.2.0-py3-none-any.whl (9.0 kB view details)

Uploaded Python 3

File details

Details for the file tinybot_eth-0.2.0.tar.gz.

File metadata

  • Download URL: tinybot_eth-0.2.0.tar.gz
  • Upload date:
  • Size: 9.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for tinybot_eth-0.2.0.tar.gz
Algorithm Hash digest
SHA256 b5fdb5210566a7628ccd663696c55f6507516c54687061fbf0c064b4c7a2c7ec
MD5 ddc615ed3c3119691f54ed5611bd9b34
BLAKE2b-256 f6f4684e794d38af8b2cce288670565d3ee5a8faf6331be9d6fa421af9f406a6

See more details on using hashes here.

File details

Details for the file tinybot_eth-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: tinybot_eth-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 9.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for tinybot_eth-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dae1452aab8802336f5eff4fecb1c2a173e577dbbec11c6a1ced649efcaf23fd
MD5 15a7da61fdcf1d1ecd09e4f15dda56b8
BLAKE2b-256 50a89edb8335ad177f1486cd6fa49745dfab6559a779bd6bba2d1c0a24aefa30

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page