layer 0.2.2

Ergonomic Telegram MTProto library β€” auto-generated TL types, raw API access, session management
Documentation

⚑ layer

A modular, production-grade async Rust implementation of the Telegram MTProto protocol.

Crates.io License: MIT OR Apache-2.0 Rust TL Layer Build

Written from the ground up to understand Telegram's internals at the lowest level.


🧩 What is layer?

layer is a hand-written, bottom-up async Rust implementation of the Telegram MTProto protocol. Every component β€” from the .tl schema parser, to the AES-IGE cipher, to the Diffie-Hellman key exchange, to the async update stream β€” is written and owned by this project.

No black boxes. No magic. Just Rust, all the way down.


πŸ—οΈ Crate Overview

Crate Description
layer-tl-parser Parses .tl schema text into an AST
layer-tl-gen Generates Rust code from the AST at build time
layer-tl-types All Layer 223 constructors, functions and enums
layer-crypto AES-IGE, RSA, SHA, DH key derivation
layer-mtproto MTProto session, DH exchange, message framing
layer-client High-level async client β€” auth, bots, updates, 2FA
layer-app Interactive demo binary (not published)
layer-connect Raw DH connection demo (not published)
layer/
β”œβ”€β”€ layer-tl-parser/   ── Parses .tl schema text β†’ AST
β”œβ”€β”€ layer-tl-gen/      ── AST β†’ Rust source (build-time)
β”œβ”€β”€ layer-tl-types/    ── Auto-generated types, functions & enums (Layer 223)
β”œβ”€β”€ layer-crypto/      ── AES-IGE, RSA, SHA, auth key derivation
β”œβ”€β”€ layer-mtproto/     ── MTProto session, DH, framing, transport
β”œβ”€β”€ layer-client/      ── High-level async Client API
β”œβ”€β”€ layer-connect/     ── Demo: raw DH + getConfig
└── layer-app/         ── Demo: interactive login + update stream

πŸš€ Quick Start

Add to your Cargo.toml:

[dependencies]
layer-client = "0.1.2"
tokio = { version = "1", features = ["full"] }

πŸ‘€ User Account

use layer_client::{Client, Config, SignInError};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::connect(Config {
        session_path: "my.session".into(),
        api_id:       12345,          // https://my.telegram.org
        api_hash:     "abc123".into(),
        ..Default::default()
    }).await?;

    if !client.is_authorized().await? {
        let token = client.request_login_code("+1234567890").await?;
        let code  = "12345"; // read from stdin

        match client.sign_in(&token, code).await {
            Ok(name) => println!("Welcome, {name}!"),
            Err(SignInError::PasswordRequired(t)) => {
                client.check_password(t, "my_2fa_password").await?;
            }
            Err(e) => return Err(e.into()),
        }
        client.save_session().await?;
    }

    client.send_message("me", "Hello from layer! πŸ‘‹").await?;
    Ok(())
}

πŸ€– Bot

use layer_client::{Client, Config, update::Update};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::connect(Config {
        session_path: "bot.session".into(),
        api_id:       12345,
        api_hash:     "abc123".into(),
        ..Default::default()
    }).await?;

    client.bot_sign_in("1234567890:ABCdef...").await?;
    client.save_session().await?;

    let mut updates = client.stream_updates();
    while let Some(update) = updates.next().await {
        match update {
            Update::NewMessage(msg) if !msg.outgoing() => {
                if let Some(peer) = msg.peer_id() {
                    client.send_message_to_peer(
                        peer.clone(),
                        &format!("Echo: {}", msg.text().unwrap_or("")),
                    ).await?;
                }
            }
            Update::CallbackQuery(cb) => {
                client.answer_callback_query(cb.query_id, Some("Done!"), false).await?;
            }
            _ => {}
        }
    }
    Ok(())
}

βœ… Features

πŸ” Cryptography

  • AES-IGE encryption / decryption (MTProto 2.0)
  • RSA encryption with Telegram's public keys
  • SHA-1 and SHA-256 hashing
  • Auth key derivation from DH nonce material
  • PQ factorization (Pollard's rho)
  • Diffie-Hellman shared secret computation

πŸ“‘ MTProto

  • Full 3-step DH key exchange handshake
  • MTProto 2.0 encrypted sessions
  • Proper message framing (salt, session_id, msg_id, seq_no)
  • Abridged TCP transport
  • msg_container (multi-message) unpacking
  • gzip-packed response decompression
  • Server salt tracking, pong, bad_server_salt handling

πŸ“¦ TL Type System

  • Full .tl schema parser
  • Build-time Rust code generation
  • All Layer 223 constructors β€” 2,295 definitions
  • Serializable / Deserializable traits for all types
  • RemoteCall trait for all RPC functions
  • Optional: Debug, serde, name_for_id(u32)

πŸ‘€ Client

  • Client::connect() β€” async TCP + DH + initConnection
  • Session persistence across restarts
  • Phone code login + 2FA SRP
  • Bot token login
  • DC migration (PHONE_MIGRATE, USER_MIGRATE)
  • FLOOD_WAIT auto-retry with configurable policy
  • Async update stream with typed events
  • Send / delete / fetch messages
  • Dialogs list
  • Username / peer resolution
  • Raw RemoteCall escape hatch for any API method

πŸ”§ Feature Flags (layer-tl-types)

Feature Default Description
tl-api βœ… High-level Telegram API schema
tl-mtproto ❌ Low-level MTProto schema
impl-debug βœ… #[derive(Debug)] on generated types
impl-from-type βœ… From<types::T> for enums::E
impl-from-enum βœ… TryFrom<enums::E> for types::T
name-for-id ❌ name_for_id(u32) -> Option<&'static str>
impl-serde ❌ serde::Serialize / Deserialize

πŸ“ Updating to a New TL Layer

# 1. Replace the schema
cp new-api.tl layer-tl-types/tl/api.tl

# 2. Build β€” types regenerate automatically
cargo build

πŸ§ͺ Tests

cargo test --workspace

πŸ“„ License

Licensed under either of, at your option:


πŸ‘€ Author

πŸ“¦ Project: github.com/ankit-chaubey/layer


πŸ™ Acknowledgements

  • Lonami for grammers. Portions of this project include code derived from the grammers project, which is dual-licensed under the MIT or Apache-2.0 licenses. The architecture, design decisions, SRP math, and session handling are deeply inspired by grammers. It's a fantastic library and an even better learning resource. Thank you for making it open source! πŸŽ‰

  • Telegram for the detailed MTProto specification.

  • The Rust async ecosystem tokio, getrandom, flate2, and friends.

  • πŸ€– AI tools used for clearer documentation and better comments across the repo (2026 is a good year to use AI).
    Even regrets 😁 after making these docs through AI. iykyk. Too lazy to revert and type again, so it stays as is!


⚠️ Telegram Terms of Service

As with any third-party Telegram library, please ensure that your usage complies with Telegram’s Terms of Service. Misuse or abuse of the Telegram API may result in temporary limitations or permanent bans of Telegram accounts.


layer.. because sometimes you have to build it yourself to truly understand it.