m.moddie / dev
← All projects
Project / 06

Crypto Game TMA

A personal Telegram game project exploring financial accounting, Web3 and backend architecture.

Role

Backend Engineer

Period / format

2026

Status

Independent Project

My contribution

  • Designed the financial accounting system using double-entry bookkeeping to guarantee auditability and eliminate balance discrepancies.
  • Extracted EVM/TON transaction signing into an isolated microservice communicating via gRPC and RabbitMQ.

Python, FastAPI, PostgreSQL, RabbitMQ, Celery, gRPC, Web3.py, Next.js

01 / About the project

About the project

Built a personal Telegram game project to explore a white-label concept, financial-module boundaries, double-entry ledger accounting and a separate gRPC signer for EVM/TON transactions.

02 / A few decisions
01

One place owns the money

Funds handles balances, holds and ledger entries. Games use typed interfaces and never edit financial tables directly.

02

Jobs survive restarts

PostgreSQL stores the job state. RabbitMQ and Celery deliver the work, while Redis is used for temporary coordination and cache.

03

Modules talk through small interfaces

The API, game runtime and workers are separate processes. Transaction signing runs in its own gRPC service.

03 / Product screens

Mini App and admin dashboard

The player side is built for a narrow Telegram viewport. The dashboard keeps payments, games, Gifts, users and operating data in one place.

Mini App

430 x 932

Admin dashboard

26 screens · 1440 px

Captured from the local application. The admin data and live crash round use demo records.

04 / System architecture

System architecture

Original project documentation in Russian

Open interactive diagram ↗
05 / Backend details

How the backend is put together

It is one codebase, but the API, realtime games, workers and signer run separately. Here are the parts that do most of the work.

What is in the backend

01

Funds

Accounts, double-entry ledger, balances, holds, deposits, withdrawals, conversions and reconciliation.

02

Games

Case opening, slots and crash modes, wagers, liabilities, deterministic rules and realtime events.

03

Gifts

Catalog, virtual and Telegram-backed stock, user inventory, collections, procurement and delivery.

04

Referrals

Referral relations, promo codes, partner accounting, bot provisioning and payout workflows.

05

App settings

Published brand revisions and server-side capability enforcement for a white-label deployment.

06

Jobs and broadcasts

Durable background work, notification delivery, leases, retries and operational state.

A few details worth showing

01

User deposit wallets

EVM addresses are derived from an encrypted mnemonic. Index 0 is the master wallet; users receive positive derivation indices at m/44'/60'/0'/0/{index}. A user-derived key may sweep only to the master address. TON uses one Wallet V4R2 at index 0 with a per-user deposit memo.

02

Financial consistency

PostgreSQL owns balances and job state. A double-entry ledger, deferred triggers, unique operation keys, stable lock ordering and one outer ApplicationTransaction keep related changes atomic. External calls happen only after a durable checkpoint; ambiguous results remain unknown until reconciliation.

03

Gift inventory

Virtual Gifts and real Telegram-backed Gifts have separate provenance. Case opening reserves a prize before award. Missing reserved stock moves to reconciliation_required instead of being silently released. Purchases and deliveries persist an intent before Telegram is called.

04

Durable background work

Celery and RabbitMQ carry only durable PostgreSQL job IDs. Workers claim rows with leases and fencing tokens, then persist terminal state before ACK. Duplicate delivery becomes a safe no-op; unknown provider outcomes are reconciled instead of retried blindly.

05

Isolated transaction signing

The signer owns encrypted mnemonics and exposes derivation and signing over authenticated gRPC. mTLS identities receive explicit capabilities. Signing policies restrict chains, contracts, destinations, amounts, gas and fees; request results are stored for durable idempotency.

06

Auditable game and collection rules

Collection draws store the effective weight snapshot, modifiers, roll, total weight, selected item and seed hash. Wagers, maximum liabilities, results, prize awards and outbox events commit together in PostgreSQL.

Project map

A focused map of the backend and signer. Generated files and technical cache directories are omitted.

BACKEND / SIGNER
Backend / modular monolith
apps/backend/srcroot
main.pyAPI + Telegram bot composition
game_runtime.pyrealtime WebSocket process
core/database · security · tracing · metrics · UOW
modules/bounded contexts
funds/ledger · payments · custody · reconciliation
domain/money and deterministic rules
application/use cases and durable jobs
adapters/EVM · TON · Stars · Alchemy
persistence/typed repositories and models
games/game modes and realtime
api.pypublic commands · schemas · events
domain/fairness · lifecycle · liabilities
application/use cases · rules · funds ports
modes/isolated game implementations
cases/catalog · openings · prize drops
slot/grid · paylines · payouts
crash/rounds · bets · recovery
runtime/WebSocket protocol · event stream
persistence/rules · events · demo state
tests/unit · integration · recovery
gifts/catalog · inventory · delivery
referrals/partners · promo codes · payouts
app_settings/white-label revisions
jobs/ + broadcasts/durable work and delivery
presentation/HTTP and Telegram adapters
worker/Celery transport wrappers
apps/backend/testsunit · integration · architecture
Signer / isolated gRPC service
apps/signerisolated process
src/main.pygRPC server
src/service.pyauthenticated RPC methods
src/keys.pyencrypted keys and derivation
src/policy.pychain and transfer limits
src/request_store.pydurable idempotency store
tests/policy · keys · gRPC · request replay
contracts/proto/signershared versioned contract
Frontend and dashboard

I kept this part short. Backend is what I do best.