<div align="center">
# β‘ layer
**A modular, production-grade async Rust implementation of the Telegram MTProto protocol.**
[](https://crates.io/crates/layer-client)
[](#license)
[](https://www.rust-lang.org/)
[](https://core.telegram.org/schema)
[](#)
[](https://github.ankitchaubey.in/layer/)
[](https://t.me/layer_rs)
[](https://t.me/layer_chat)
*Written from the ground up to understand Telegram's internals at the lowest level.*
</div>
---
## π§© What is layer?
**layer** is a hand-crafted, bottom-up async Rust implementation of the
[Telegram MTProto](https://core.telegram.org/mtproto) protocol - built not to
reinvent the wheel, but to *understand* it.
The core protocol pieces - the `.tl` schema parser, the AES-IGE cipher, the
Diffie-Hellman key exchange, the MTProto session, the async update stream - are
all written from scratch. The async runtime and a handful of well-known utilities
(`tokio`, `flate2`, `getrandom`) are borrowed from the ecosystem, because that's
just good engineering. The architecture draws inspiration from the excellent
[grammers](https://codeberg.org/Lonami/grammers) library.
The goal was never "yet another Telegram SDK." It was: *what happens if you sit
down and build every piece yourself, and actually understand why it works?*
> **π Personal use & learning project** - layer was built as a personal exploration:
> *learning by building*. The goal is to deeply understand Telegram's protocol by
> implementing every layer from scratch, not to ship a polished production SDK.
> Feel free to explore, learn from it, or hack on it!
> **β οΈ Pre-production (0.x.x)** - This library is still in early development.
> APIs **will** change without notice. **Not production-ready - use at your own risk!**
---
## π¬ Community
| π’ **Channel** (updates & releases) | [@layer_rs](https://t.me/layer_rs) |
| π¬ **Chat** (questions & discussion) | [@layer_chat](https://t.me/layer_chat) |
---
## ποΈ Crate Overview
| [`layer-tl-parser`](./layer-tl-parser) | Parses `.tl` schema text into an AST |
| [`layer-tl-gen`](./layer-tl-gen) | Generates Rust code from the AST at build time |
| [`layer-tl-types`](./layer-tl-types) | All Layer 223 constructors, functions and enums |
| [`layer-crypto`](./layer-crypto) | AES-IGE, RSA, SHA, DH key derivation |
| [`layer-mtproto`](./layer-mtproto) | MTProto session, DH exchange, message framing |
| [`layer-client`](./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`:
```toml
[dependencies]
layer-client = "0.2.2"
tokio = { version = "1", features = ["full"] }
```
### π€ User Account
```rust
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
```rust
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`)
| `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
```bash
# 1. Replace the schema
cp new-api.tl layer-tl-types/tl/api.tl
# 2. Build - types regenerate automatically
cargo build
```
---
## π§ͺ Tests
```bash
cargo test --workspace
```
---
## π License
Licensed under either of, at your option:
- **MIT License** - see [LICENSE-MIT](LICENSE-MIT)
- **Apache License, Version 2.0** - see [LICENSE-APACHE](LICENSE-APACHE)
---
## π€ Author
<div align="center">
### Ankit Chaubey
*Built with curiosity, caffeine, and a lot of Rust compiler errors. π¦*
| π **GitHub** | [github.com/ankit-chaubey](https://github.com/ankit-chaubey) |
| π **Website** | [ankitchaubey.in](https://ankitchaubey.in) |
| π¬ **Email** | [ankitchaubey.dev@gmail.com](mailto:ankitchaubey.dev@gmail.com) |
| π¦ **Project** | [github.com/ankit-chaubey/layer](https://github.com/ankit-chaubey/layer) |
| π’ **Channel** | [@layer_rs](https://t.me/layer_rs) |
| π¬ **Chat** | [@layer_chat](https://t.me/layer_chat) |
</div>
---
## π Acknowledgements
- [**Lonami**](https://codeberg.org/Lonami) for
[**grammers**](https://codeberg.org/Lonami/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**](https://core.telegram.org/mtproto) 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](https://core.telegram.org/api/terms).
Misuse or abuse of the Telegram API may result in temporary limitations or
permanent bans of Telegram accounts.
---
<div align="center">
*layer.. because sometimes you have to build it yourself to truly understand it.*
</div>