Skip to content

About

Base TipBot turns any Telegram chat into an on-chain community economy: instant USDC tips, reactions, donate pages, paywalls, and prediction markets - with zero gas for users and proof of reserves on the dashboard.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

205 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Tippy - Community Economy in USDC on Base

A Telegram bot that turns any chat or community into a financial ecosystem: instant USDC tips, Polymarket-style prediction markets with live AMM odds, an AI assistant, paywalled content, and per-user wallets — all on Base. No custom contracts in the hot path: only the official USDC contract plus an optional audited-style treasury vault; everything else is instant internal accounting backed by public proof-of-reserves.

Made by @ssrjkk.

Author: @ssrjkk · @b2wmain · X / Twitter · GitHub

Links: Telegram Bot

Whitepaper: docs/WHITEPAPER.md — the full function inventory, the growth roadmap, and what the product can earn (grants, subscriptions, fees).


Screenshots

Website

Desktop Mobile
Tippy website Tippy website on mobile

Telegram Mini App

Tippy Mini App

Telegram Bot

Tippy bot menu


Features

Instant tips (zero gas)

  • /tip 5 @nick — or reply /tip 5 to any message
  • Recipient gets an immediate DM notification
  • /rain 10 [N] — scatter USDC across active group members
  • emoji reactions tip the message author (groups)

Prediction markets v2 — Polymarket analog (LMSR AMM)

  • /market create 50 Who wins? | Alice | Bob 7d — creator funds the AMM liquidity
  • Live odds that move with demand — Hanson's Logarithmic Market Scoring Rule, exact Decimal math (b = subsidy / ln(n))
  • /trade <id> <opt> <amount> — buy outcome shares at the live price
  • /sell <id> <opt> [50%] — sell back any time before resolution (exit anytime, not locked until the end like parimutuel pools)
  • /positions — your portfolio with live mark-to-market value and PnL
  • Resolution pays 1 USDC per winning share; the market creator keeps the remaining liquidity pool as their earnings
  • Guaranteed solvency by the LMSR funding theorem: the escrow can always cover the worst-case payout, verified by property tests along aggressive random trading paths
  • Deadline pings + grace-period auto-refund protection for forgotten markets

Parimutuel polls (quick group games)

  • /bet create Question | Option 1 | Option 2 [24h], /bet <id> <opt> <amount>
  • Winners split the whole pot proportionally (2% fee on net profit to the creator)
  • Inline cards, quick-amount buttons, two-tap resolution, cancel/refund paths

Cally — Polymarket on Base (/oc*)

  • /oc_create 50 Who wins? | Alice | Bob 7d — creates a market in the OutcomeMarket.sol contract: the subsidy is locked on-chain, shares are real ERC-1155 tokens, every trade is a USDC transfer anyone can verify on Basescan
  • /oc_buy <id> <opt> <amount> / /oc_sell <id> <opt> [50%] — trade at the live LMSR price with hard on-chain slippage caps (maxCost/minProceeds)
  • /oc_redeem <id> — pull resolution payouts straight from the contract
  • /oc <id> / /oc_pos — live odds and your ERC-1155 positions
  • Oracle proposes the winner, the owner can dispute within 2h (once — after a dispute only the owner finalizes), and anyone can refund an abandoned market 24h after close — refunds are hard-capped at $1/share so the creator subsidy can never be drained
  • Labels live in a bot-side registry (the contract stores numbers only); gas for first trades is auto-topped-up from the hot wallet with a per-wallet anti-drain cooldown

AI assistant

  • /ask <question> — ask about crypto, Base, market strategy, bot usage
  • Works with any OpenAI-compatible API (OpenAI, Groq, OpenRouter, local vLLM/llama.cpp) via AI_API_URL / AI_API_KEY / AI_MODEL; AI_PROVIDERS lists fallbacks, a 429 or a revoked key parks that endpoint and the next one answers
  • With no model reachable, /ask still answers from the ledger — open markets and pools with live odds, or the command list — and says that it did
  • Reply to a message with /ask to use it as context; rate-limited, typing indicator

Donations & wallets

  • /donate — personal donation page with QR (t.me/<bot>?start=donate_<id>)
  • Deposits auto-credit with push notifications (Basescan tx link included)
  • /link <address> + signature → automatic deposit crediting (ecrecover-verified; a deposit can only be claimed by the wallet's owner — never by tx-hash sniping)
  • /wallet — built-in custodial wallet, export/import by seed phrase
  • /withdraw <address> <amount> — on-chain payout (1% fee, min 1 USDC, ≤5/day), staged behind an explicit Confirm tap before anything is debited, full auto-refund for stuck/reverted transactions
  • /tx <hash> — look up any Base transaction and decode its USDC transfer

Basenames (on-chain identity on Base)

  • /basename — your on-chain name (ENSIP-19 reverse resolution of your deposit address against the Base L2 resolver); shows in /wallet and the public donate page automatically
  • /basename <name>.base.eth — on-chain availability check: free (with a registration hint), taken (owner address), or confirmed yours when it resolves to your linked/custodial wallet
  • Tips by name: /tip <name>.base.eth resolves the basename to its on-chain owner — the chain is the source of truth, nothing is stored bot-side

Paid content & channels

  • /paywall create 5 Title → sell posts for USDC (buyers read instantly)
  • /paywall channel 5 → paid Telegram channel access, 5 USDC / 30 days, one-time invite links, expired subscribers auto-kicked
  • x402 HTTP payments: POST /api/x402/tip and POST /api/x402/paywall — AI agents pay on-chain via the 402 handshake (invoice → pay → replay-proof credit)

Autonomous agent (fail-closed)

  • Perceives crypto news → LLM filters noise → creates markets, bets, sells analysis as paywall posts — every action EAS-attested on Base
  • News sources: CryptoPanic (with CRYPTOPANIC_TOKEN) plus free RSS fallbacks (CoinDesk, CoinTelegraph); deduplication and relevance scoring built in
  • Runs inside the main process (deploy/run.py) when AGENT_TG_ID > 0 and the cap set validates — no separate service needed; a silent agent death stops the process like any other watcher (fail-fast)
  • State (caps counters, seen-news, audit trail) lives in AGENT_STATE_DIR (default: the agent/ package dir) so a restart never resets the daily cap
  • Spend is capped in code (never in the prompt): daily + per-tx caps, actions per hour, circuit breaker with cooldown; caps are validated at startup and the agent refuses to run on a misconfigured set
  • LLM failure = no action (fail-closed); the agent can never trade on its own markets (DB-level guard)
  • /agent (admin-only) — live caps state, circuit-breaker status and the agent's recent actions straight in Telegram, no web dashboard needed

Web dashboard (public transparency)

  • Live stats, volume chart, markets with odds/backers, leaderboards, user profiles
  • Proof of Reserves /api/solvency: bot liabilities vs on-chain USDC (read from the TipBotVault contract when deployed, else the hot wallet)
  • Base design system UI — light (default) + dark theme with a toggle, on the tokens measured on base.org: brand #0000ff / #224bff, canvases #ffffff / #111111, Schibsted Grotesk with Golos Text behind it for Cyrillic, Geist Mono for every number
  • Public JSON API: /api/stats, /api/markets, /api/predictions, /api/prediction/{id}, /api/leaderboard, /api/user/{id}, /api/info, /api/health, /qr, rate-limited per IP

Smart Wallet (ERC-4337) — gasless, operator-custodied

  • Per-user Smart Accounts via CREATE2 (SmartAccountFactory) — deterministic counterfactual addresses; no ETH needed from the user
  • VerifyingPaymaster sponsors gas — users tip/trade without ever holding ETH (Base Sepolia proven: direct handleOps and gasless paymaster UserOps, status=1)
  • The operator holds the keys, not the user — SmartAccount.owner is the relayer address (bot/smart_wallet.py::_owner, derived from HOT_WALLET_KEY), and that key signs every UserOperation. Gasless is what the user pays with custody; the same rule is stated in docs/SECURITY.md («The hot wallet is custodial by design»).
  • bot/smart_wallet.py builds + signs UserOperations (EIP-191) and drives approveAndTrade from the wallet's own USDC
  • Details: docs/ARCHITECTURE.md (Smart Wallet section)

Breakthrough Base L2 Features

4 killer functions leveraging unique Base L2 capabilities:

1. Gasless Onboarding

New users get 10 FREE transactions — zero barrier to entry.

  • /gasless — check your free transaction balance
  • Uses Base Paymaster API (Pimlico) to sponsor UserOperations
  • New wallets automatically qualify; gas paid by the protocol
  • After 10 free txs — standard Base fees (still just fractions of a cent)
/gasless -> You have 10 of 10 free transactions left!
           Gas is sponsored by Base — you pay nothing.

Why it's a breakthrough: Traditional bots require users to hold ETH for gas. Base Paymaster eliminates this entirely — users onboard with USDC only and transact for free until they're hooked.

2. Recurring Payments (Subscriptions)

Automated scheduled transfers — daily, weekly, biweekly, monthly.

  • /subscribe @user <amount> <interval> — create a subscription
  • /subscriptions — view all active subscriptions
  • /cancelsub <id> — cancel a subscription
  • Background executor runs hourly and auto-processes due payments
  • Supports: daily (24h), weekly (7d), biweekly (14d), monthly (30d)
/subscribe @creator 10 monthly -> Subscription created!
                                  @creator: $10.00 every monthly

Why it matters: the schedule lives in the bot's own Postgres and an hourly watcher debits the internal USDC balance — no external billing service, nothing to renew by hand. Creators use it for patronage, communities for paid memberships.

3. Creator Tokens with Revenue Sharing

Issue tokens that automatically distribute your earnings to holders.

  • /createtoken <name> <SYMBOL> <supply> <price> — launch a creator token
  • /buytoken <token_id> <amount> — buy a creator's tokens
  • /claim <token_id> — claim your share of their revenue
  • When creators earn (tips, market winnings), revenue automatically splits:
    • Proportional to holder balance
    • No manual distribution needed
    • Dividends accrue per second
/createtoken "My Token" MTK 1000000 0.10
-> Token created! ID: ct_123456_1790013544
   Holders receive dividends from your earnings automatically.

/buytoken ct_123456_1790013544 1000
-> Bought 1000 tokens for $100.00!

[Creator earns $50 in tips]
-> Dividend auto-distributed: $0.05 per token

/claim ct_123456_1790013544
-> Claimed $50.00 in dividends!

Why it's a breakthrough: This is the creator economy natively on-chain. Fans invest in creators, creators share revenue automatically — all powered by Base's smart accounts. No traditional equity needed; the token IS the revenue share.

On-chain treasury (TipBotVault)

  • Users deposit USDC into the vault contract — visible to anyone on Base
  • Relayer distributes under a daily limit; owner (multisig) keeps full control
  • Distributed events make every payout publicly auditable

Operations

Tippy runs as a private production deployment operated by its maintainers. The source is published for transparency and audit; there is no public run-it-yourself guide, and contract deployment stays with the team (vault/market owners are multisigs, never the hot wallet).

Commands

A plain-language walkthrough for Telegram users lives in docs/USER_GUIDE.md — the table below is the short form.

Command What it does
/menu · /help Menu with all sections, command list
/tip 5 @nick Instant USDC tip (or reply to a message)
/market create 50 Q | A | B [24h] Create an AMM prediction market
/markets · /trade · /sell · /positions Trade shares at live odds
/oc · /oc_create · /oc_buy · /oc_sell · /oc_redeem · /oc_pos On-chain markets (OutcomeMarket.sol, ERC-1155)
/bet create Q | A | B [24h] · /bets · /mybets · /resolve · /cancel Parimutuel polls
/ask <question> AI assistant
/deposit / /claim <tx> / /link / /confirm Fund your account (private chat only)
/withdraw <addr> <amt> On-chain payout — 1% fee, min 1 USDC, ≤5/day (atomic DB cap), needs a Confirm tap, private chat only
/wallet · /import · /export Per-user key pair, generated in chat
/tx <hash> Decode a Base transaction
/rain 10 [N] Group giveaway
/donate Your donation page, linkable from anywhere
/paywall ... Paid posts and channels
/balance / /stats / /top / /history Analytics
/gasless Check free gasless transactions
/subscribe @user <amt> <interval> · /subscriptions · /cancelsub Recurring payments
/createtoken <name> <SYM> <supply> <price> Launch a creator token
/buytoken <id> <amount> · /claim <id> Buy tokens / claim dividends
/basename Claim a Basename (on-chain identity)
/settings · /language · /about · /app Notifications, ru/en/zh, what this is, Mini App
/admin Owner-only panel: users, volume, fees, treasury against liabilities, deposit-scanner lag, AI chain and its daily budget — read-only, private chat only

Architecture

bot/
├─ main.py              entrypoint, background watchers (deposits, withdrawals, deadlines)
├─ handlers/            aiogram handlers by domain
│  ├─ _common.py        shared helpers, router, menu KB
│  ├─ menu.py           /start, /menu, settings, language, broadcast
│  ├─ wallet.py         /deposit, /withdraw, /balance, /link, /claim
│  ├─ tips.py           /tip, /rain, reaction tips
│  ├─ bets.py           parimutuel /bet, /bets, /resolve, /cancel
│  ├─ markets.py        LMSR AMM /market, /trade, /sell, /positions
│  ├─ onchain.py        /oc_* on-chain OutcomeMarket commands
│  ├─ paywall.py        /paywall, paid posts/channels
│  ├─ stats.py          /stats, /top, /history
│  ├─ ai.py             /ask AI assistant
│  ├─ basename.py       /basename on-chain identity
│  ├─ agent.py          /agent admin dashboard
│  ├─ admin.py          /admin — the owner's read-only panel
│  └─ breakthrough.py   /gasless, /subscribe, /createtoken
├─ ledger/              PostgreSQL accounting + LMSR AMM engine (Decimal-exact)
│  ├─ __init__.py       Ledger facade + singletons + lmsr_* re-exports
│  ├─ _core.py          connect/schema/ping
│  ├─ _schema.py        DDL
│  ├─ _conn.py          ReconnectingConn
│  ├─ _users.py         accounts, wallet links, create2
│  ├─ _pay.py / _paywall.py / _transfer.py   x402, paywalls, transfers
│  ├─ _withdraw.py      AML, batches, refunds
│  ├─ _audit.py         audit_log rows: who did what to whose money
│  ├─ _ai.py            the shared AI budget and provider health, as DB rows
│  ├─ _bets.py / _markets.py   parimutuel + LMSR AMM (buy/sell/resolve)
│  ├─ _onchain.py       on-chain outcome markets registry
│  ├─ _recurring.py     subscription executor
│  ├─ _paymaster.py     gasless onboarding
│  ├─ _creator.py       creator tokens + dividends
│  ├─ _messages.py / _notify.py / _admin.py / _views.py
│  └─ _base.py          audit_log, MICRO, LMSR math
├─ base.py              web3 layer: USDC transfers, deposit scanning, tx decoding
├─ chain/               on-chain helpers
│  ├─ core.py           RPC, chain head, block polling
│  ├─ transactions.py   tx status, receipts
│  ├─ transfers.py      USDC transfer helpers
│  ├─ tokens.py         token metadata, decimals
│  ├─ dex.py            price feeds
│  ├─ prices.py         quote helpers
│  ├─ basenames.py      ENSIP-19 reverse resolution
│  └─ network.py        chain labels, explorer URLs
├─ ai.py                provider chain: failover, parks, shared daily budget
├─ ai_data.py           /ask without a model, answered from the ledger
├─ qr.py                local QR generation
├─ smart_wallet.py      ERC-4337: UserOp build/sign, paymaster data, approve+trade sync
├─ paymaster.py         Base Paymaster integration: gasless onboarding (10 free txs)
├─ recurring.py         Recurring payments: subscriptions executor (hourly watcher)
├─ creator_tokens.py    Revenue sharing: creator tokens + dividend distribution
├─ create2.py           CREATE2 deterministic address computation
├─ solvency.py          Proof-of-reserves: liabilities vs on-chain USDC
├─ wallets.py           Custodial wallet: seed export/import, balance
├─ tip_targets.py       Username/name resolution for tip recipients
├─ commands_catalog.py  Command registry for /help
├─ telegram_transport.py  Telegram API wrapper (send/edit/delete)
├─ x402_sweep.py        x402 invoice settlement sweeper
├─ onchain_market.py    OutcomeMarket contract ABI + helpers
├─ i18n.py              RU/EN/ZH message tables
├─ fees.py              the one money notation: USDC labels, fee rates, percentages
├─ tx_view.py           one tx_log row → one label (kind decides sign and counterparty)
└─ config.py            env-driven configuration
agent/                  autonomous market-maker: news → LLM → markets, EAS attestations
web/
├─ server.py            FastAPI: public API, proof-of-reserves, x402 endpoints
├─ auth.py              Telegram OAuth, session cookies, rate limiting
├─ mini.py              Mini App: balance, tip, deposit, withdraw, markets
├─ refusals.py          Refusal sentences, in the language the caller reads
├─ x402.py              x402 handshake: invoice → verify → replay-proof credit
├─ x402_spec.py         x402 protocol spec + types
├─ metrics.py           Prometheus metrics endpoint
├─ frame.py             Farcaster Frame endpoints
├─ hook.py              Telegram webhook handler
└─ static/              Base-design dashboard + Mini App (CSP nonce, no inline JS)
contracts/
├─ TipBotVault.sol      on-chain treasury (proof of reserves)
├─ OutcomeMarket.sol    on-chain markets (ERC-1155 shares, LMSR on-chain)
├─ SmartAccount.sol     ERC-4337 account (CREATE2)
├─ SmartAccountFactory.sol  deterministic account factory
├─ VerifyingPaymaster.sol   gas-sponsoring paymaster
├─ Create2Factory.sol   generic CREATE2 factory
├─ LMSR.sol             on-chain LMSR market maker
├─ MiniUSDC.sol         minimal USDC mock for testing
└─ USDCForwarder.sol    USDC transfer helper
scripts/                deploy, smoke, backup, restore and the i18n check
deploy/                 container entrypoint, launch supervisor, tunnel, oracle bootstrap
functions/              the Cloudflare Pages edge: bundle assets, proxy the rest to the origin
tests/                  real Postgres, real dispatcher, real crypto, local EVM

Testing

python -m ruff check bot web tests deploy agent scripts alembic
python -m pytest -q -m "not production"   # 1336 passed

Tests need a PostgreSQL 16 on localhost:5432 with a tipbot role (password tipbot): tests/conftest.py drops and recreates tipbot_test once per session, so the dev database is never touched. Point TEST_DATABASE_URL and TEST_ADMIN_DATABASE_URL elsewhere if your server listens somewhere else. The 171 production-marked tests are excluded from this run — they check the deployed site and belong to the Prod Health Check workflow.

What is tested for real (not mocked): money conservation across every flow (tips, fees, refunds, parimutuel payouts, rain, AMM buy/sell/resolve/cancel — balances + escrows always sum to deposits), deposit-security (claiming someone else's tx is rejected), fee math, real signature recovery, the full aiogram dispatcher with real Update objects, USDC ABI decoding, the FastAPI dashboard against a real ledger, background watchers, 15 end-to-end scenarios, and 13 TipBotVault tests on a local EVM (eth-tester + py-evm, real compiled bytecode). Only external networks are mocked (Telegram transport, RPC) — tests/conftest.py pins the chain endpoint to a refused port, because a test that reads a live node answers whatever that node holds: on Base mainnet one of the suite's test addresses carries EIP-7702 delegation code, so /withdraw there refuses it as a smart contract while the same test passes against a Sepolia endpoint.

The LMSR engine additionally has a property test proving the funding theorem: along randomized aggressive trading paths the escrow never drops below the worst-case payout.

Security

  • HOT_WALLET_KEY is money — never commit .env
  • Official USDC only: 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
  • Prediction markets rely on the creator resolving honestly; deadline + grace auto-refund bounds the damage of abandoned markets
  • Anti-spam cooldowns, per-day withdrawal limits, gas-griefing protection
  • Sensitive commands (/withdraw, /deposit, /claim, /link, /confirm, /export, /import, /paywall subscribe) answer only in private chats; the daily withdrawal cap is enforced atomically in the database
  • /withdraw is two-step: it only stages a payout, and the debit happens on an explicit Confirm tap. The staged request is single-use (DELETE ... RETURNING), expires in WITHDRAW_CONFIRM_TTL_SECONDS (default 10 min), is bound to the requesting tg_id, and the fee is frozen at staging time — so the number you confirm is the number that is charged
  • First-party destinations (zero address, hot wallet, vault, x402 pool) are blocked by one shared blocked_destination() helper used by both the handler and the ledger, so the refusal reason shown can never drift from the one enforced — and each reason gets its own message
  • All bot output is HTML-escaped (no Markdown injection from user titles); the dashboard serves a strict CSP (nonce-based scripts) with zero inline event handlers; web login nonces are single-use with a TTL and pruned
  • Multi-relayer withdrawals keep per-relayer daily caps in a persisted state file (a restart cannot reset the budget); relayer keys and caps are validated by python scripts/validate_env.py
  • The autonomous agent is fail-closed: LLM errors mean no action, caps are validated at startup, and the DB blocks trading on its own markets

Roadmap

  • Per-user deposit addresses (CREATE2 vaults)
  • Smart Wallet (ERC-4337) + gasless paymaster core shipped + Sepolia-proven (P2)
  • Withdrawal batching for gas savings shipped (queued payouts flushed as one vault batch, direct-send fallback)
  • Order-book style CLOB on top of the AMM
  • On-chain market escrow (resolution via a UMA-style oracle) shipped as Cally (OutcomeMarket ERC-1155): an oracle proposes, the owner has 2h to dispute. Not trustless — with no ORACLE_PRIVATE_KEY configured the bot resolves through the owner key, so one signature holds both roles.

Contributing

PRs welcome — see docs/CONTRIBUTING.md for setup, style rules, and the money-conservation requirement for any fund-touching change. Security issues: docs/SECURITY.md (no public issues). Community rules: docs/CODE_OF_CONDUCT.md. Licensed under MIT.


Author: @ssrjkk · @b2wmain · X / Twitter · GitHub

Built on Base · Powered by USDC

Installation

git clone https://github.com/ssrjkk/tippy-on-base.git
cd tippy-on-base
python -m pip install -r requirements.txt -r requirements-dev.txt
cp .env.example .env        # then fill in BOT_TOKEN and the wallet keys

Usage

python deploy/run.py                      # bot + dashboard in one process
python -m bot.main                        # bot only (long polling)
python -m uvicorn web.server:app          # dashboard only, on WEB_HOST:WEB_PORT

The dashboard listens on WEB_HOST:WEB_PORT (0.0.0.0:8000 by default) and the bot answers in Telegram; docs/DEPLOY.md covers the server, docs/CLOUDFLARE.md the Pages front.


SSRJKK — GitHub · Telegram · Projects hub · Bot catalogue

About

Base TipBot turns any Telegram chat into an on-chain community economy: instant USDC tips, reactions, donate pages, paywalls, and prediction markets - with zero gas for users and proof of reserves on the dashboard.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages