layer 0.2.0

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 222 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 222)
โ”œโ”€โ”€ 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 222 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. The architecture, design decisions, SRP math, and session handling in this project are all directly 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.


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