npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mtproto2/client

v0.1.0

Published

High-level Telegram client API for MTProto 2.0

Readme

@mtproto2/client

High-level Telegram client API built on top of @mtproto2/mtproto.

Provides TelegramClient with authentication, messaging, channel management, contacts, file transfer, session storage, entity caching, and typed events.

Installation

npm install @mtproto2/client

Quick Start

import { TelegramClient, MemorySession } from '@mtproto2/client';

const client = new TelegramClient({
  apiId: 12345,
  apiHash: 'your_api_hash',
  session: new MemorySession(),
});

await client.connect();
const me = await client.getMe();
await client.disconnect();

API

TelegramClient

The main entry point. Wraps MTProtoConnection with session management, entity caching, file management, and typed events.

import { TelegramClient } from '@mtproto2/client';
import type { TelegramClientOptions, TelegramClientEvents } from '@mtproto2/client';

const client = new TelegramClient({
  apiId: 12345,                // Your Telegram API ID
  apiHash: 'abcdef...',       // Your Telegram API hash
  session: new MemorySession(), // Session storage backend
  dcId: 2,                    // Data center ID (default: 2)
  testMode: false,            // Use test servers (default: false)
  autoReconnect: true,        // Auto-reconnect on disconnect (default: true)
});

await client.connect();
await client.invoke(serializedMethod); // Send raw TL method
const me = await client.getMe();       // Get current user
client.isConnected();                   // Connection status check
await client.disconnect();

Events:

client.on('connected', () => { /* ... */ });
client.on('disconnected', () => { /* ... */ });
client.on('error', (err: Error) => { /* ... */ });
client.on('update', (data: Buffer) => { /* TL-serialized update */ });

Authentication

import { sendCode, signIn, signUp, logOut, checkPassword } from '@mtproto2/client';

// Step 1: Send verification code
const sentCode = await sendCode(client, '+1234567890');

// Step 2: Sign in with the received code
const auth = await signIn(client, '+1234567890', phoneCodeHash, '12345');

// Step 2 (alt): Sign up if the phone is unregistered
const auth = await signUp(client, '+1234567890', phoneCodeHash, 'First', 'Last');

// 2FA: Check password (when signIn returns SESSION_PASSWORD_NEEDED)
const auth = await checkPassword(client, srpData);

// Log out
await logOut(client);

Messages

import {
  sendMessage,
  getMessages,
  getHistory,
  deleteMessages,
  editMessage,
  searchMessages,
} from '@mtproto2/client';

// Send a text message
await sendMessage(client, inputPeer, 'Hello!', { silent: false, noWebpage: true });

// Get messages by ID
const msgs = await getMessages(client, [msgId1, msgId2]);

// Get chat history
const history = await getHistory(client, inputPeer, { limit: 50, offsetId: 0 });

// Delete messages
await deleteMessages(client, [msgId1, msgId2], { revoke: true });

// Edit a message
await editMessage(client, inputPeer, msgId, 'Updated text');

// Search messages
const results = await searchMessages(client, inputPeer, 'query', { limit: 20 });

Channels

import {
  joinChannel,
  leaveChannel,
  getParticipants,
  getFullChannel,
  createChannelHelper,
  editAdminHelper,
} from '@mtproto2/client';

await joinChannel(client, channelPeer);
await leaveChannel(client, channelPeer);
const participants = await getParticipants(client, channelPeer, { limit: 100 });
const fullInfo = await getFullChannel(client, channelPeer);

Contacts

import {
  importContacts,
  resolveUsername,
  searchContacts,
  getContacts,
} from '@mtproto2/client';
import type { PhoneContact } from '@mtproto2/client';

// Resolve a username to an entity
const resolved = await resolveUsername(client, 'username');

// Search contacts
const results = await searchContacts(client, 'query', 20);

// Import phone contacts
await importContacts(client, [{ phone: '+1234567890', firstName: 'John', lastName: 'Doe' }]);

// Get all contacts
const contacts = await getContacts(client);

Users

import { getUsers, getFullUser } from '@mtproto2/client';

const users = await getUsers(client, userIds);
const fullUser = await getFullUser(client, userId);

Dialogs

import { getDialogs, getPeerDialogs } from '@mtproto2/client';

const dialogs = await getDialogs(client, { limit: 100 });
const peerDialogs = await getPeerDialogs(client, [peer1, peer2]);

Search

import { searchGlobal } from '@mtproto2/client';

const results = await searchGlobal(client, 'query', { limit: 50 });

Admin

import { adminCreateChannel, deleteChannel, adminEditAdmin } from '@mtproto2/client';

const channel = await adminCreateChannel(client, 'Channel Title', 'Description');
await adminEditAdmin(client, channelPeer, userId, adminRights);
await deleteChannel(client, channelPeer);

Session Storage

Two session storage backends are included:

MemorySession

In-memory storage. Session data is lost when the process exits. Useful for testing and short-lived scripts.

import { MemorySession } from '@mtproto2/client';

const session = new MemorySession();

StringSession

Base64-encoded session string for portable persistence. Compatible with common session string formats.

import { StringSession } from '@mtproto2/client';

// Create a new session
const session = new StringSession();

// Or load from an existing session string
const session = new StringSession('AQ...');

// After connecting, retrieve the session string for storage
const str = session.getSessionString();

Security warning: The session string contains the raw 256-byte auth key in plaintext (base64-encoded). Anyone with this string can impersonate the authenticated user. Treat session strings with the same care as passwords -- never log them, commit them to version control, or expose them in client-side code.

Custom Storage

Implement the SessionStorage interface for custom backends (database, file, encrypted storage):

import type { SessionStorage, SessionData } from '@mtproto2/client';

class MySessionStorage implements SessionStorage {
  async load(): Promise<SessionData | null> { /* ... */ }
  async save(data: SessionData): Promise<void> { /* ... */ }
  async delete(): Promise<void> { /* ... */ }
}

Entity Cache

Caches user, chat, and channel entities for InputPeer resolution.

import { EntityCache } from '@mtproto2/client';
import type { EntityType, CachedEntity } from '@mtproto2/client';

const cache = new EntityCache();

// Store an entity
cache.set(userId, accessHash, 'user');
cache.set(channelId, accessHash, 'channel');

// Retrieve a cached entity
const entity = cache.get(userId);

// Serialize as InputPeer (for use in API calls)
const inputPeer: Buffer = cache.getInputPeer(userId);
// Returns TL-serialized inputPeerUser, inputPeerChat, or inputPeerChannel

cache.has(userId);  // Check existence
cache.size;         // Number of cached entities
cache.clear();      // Remove all

File Transfer

The FileManager handles file uploads and downloads with progress tracking.

import { FileManager } from '@mtproto2/client';
import type { UploadProgress, DownloadProgress, FileManagerOptions } from '@mtproto2/client';

// FileManager is available as client.fileManager
client.fileManager.on('upload-progress', (progress: UploadProgress) => {
  console.log(`Upload: ${progress.uploaded}/${progress.total} (${progress.speed} B/s)`);
});

client.fileManager.on('download-progress', (progress: DownloadProgress) => {
  console.log(`Download: ${progress.offset}/${progress.total}`);
});

Low-level file helpers are also available:

import {
  serializeSaveFilePart,
  serializeSaveBigFilePart,
  serializeGetFile,
  parseGetFileResponse,
  splitFile,
  computePartSize,
  generateFileId,
} from '@mtproto2/client';

Files larger than 10 MB automatically use saveBigFilePart instead of saveFilePart.

TypedEventEmitter

A type-safe wrapper around Node.js EventEmitter:

import { TypedEventEmitter } from '@mtproto2/client';

interface MyEvents {
  'data': (payload: Buffer) => void;
  'error': (err: Error) => void;
  'close': () => void;
}

class MyClass extends TypedEventEmitter<MyEvents> {
  // on(), off(), once(), emit() are all type-checked
}

License

MIT