telegram-fragment-api
v0.3.3
Published
Unofficial TypeScript client for Fragment.com — Telegram Stars, Premium, usernames and TON wallet operations, fully typed.
Maintainers
Readme
🧩 telegram-fragment-api
Неофициальный полностью типизированный TypeScript-клиент для Fragment.com
Покупка Telegram Stars, цены Premium, поиск пользователей и переводы TON — на классах, безопасно через Result, без исключений.
English · Русский
⭐ Нравится библиотека?
Пожалуйста, поставьте звезду репозиторию на GitHub — это один клик, вам ничего не стоит, а проекту реально помогает развиваться и поддерживаться. Спасибо! 🙏
✨ Возможности
- 🏛️ Классовый namespace-API —
client.stars.getPrice({ quantity }),client.ton.wallet.v4r2.send({ … }) - 🧯 Без исключений — каждый метод возвращает
Result({ ok: true, data } | { ok: false, error }) - 🧩 Типизированные ошибки — структурный
FragmentErrorсcode(VALIDATION,AUTH,NETWORK,API, …) - 🔭 Поиск по нику, ⭐ Stars (цены + покупка), 👑 Premium (цены)
- 💎 Блокчейн TON — lite-серверы, баланс кошелька и переводы v4r2
- 🔑 Авто-hash — парсинг hash сессии через
client.auth.fetchHash() - 🧾 Декодер payload, 👤 профиль и сессии
- 🟦 100% TypeScript + 🧪 полностью покрыт мок-тестами (Vitest), ESM и CommonJS, на axios
📦 Установка
# npm
npm install telegram-fragment-api
# yarn
yarn add telegram-fragment-api
# pnpm
pnpm add telegram-fragment-api
# bun
bun add telegram-fragment-apiРаботает на Node.js ≥ 18, Bun и любом рантайме с глобальным
fetch. Поставляется в двух форматах — ESM + CommonJS, поэтомуimportиrequireоба работают.
🚀 Быстрый старт
import { Fragment } from "telegram-fragment-api";
// Создаём клиент со своими данными (см. «Где взять данные» ниже)
const client = new Fragment({
hash: "ваш_hash",
stelSsid: "ваш_stel_ssid",
stelToken: "ваш_stel_token",
stelTonToken: "ваш_stel_ton_token",
toncenterApiKey: "ваш_toncenter_api_key",
walletSeed: "слово1 слово2 ... слово24",
});
const res = await client.stars.getPrice({ quantity: 5050 });
if (res.ok) {
console.log(res.data.curPrice); // { TON: "...", USDT: "..." }
} else {
console.error(res.error.code, res.error.message);
}CommonJS?
const { Fragment } = require("telegram-fragment-api");тоже работает — сборки ESM/CJS.
🧯 Обработка ошибок — паттерн Result
Методы не бросают исключений. Каждый возвращает размеченное объединение, которое сужается по res.ok:
const res = await client.users.nickToHash({ nickname: "durov" });
if (res.ok) {
// res.data полностью типизирован здесь
console.log(res.data.found?.recipient);
} else {
// res.error — это FragmentError
switch (res.error.code) {
case "AUTH": /* неверные cookie / hash */ break;
case "NOT_FOUND": /* у ника нет recipient */ break;
case "NETWORK": /* таймаут / соединение */ break;
default: console.error(res.error.message);
}
}Коды ошибок: VALIDATION · AUTH · NETWORK · API · PARSE · NOT_FOUND · INSUFFICIENT_FUNDS · UNKNOWN.
🔑 Где взять данные
| Поле | Где взять |
|---|---|
| hash | Параметр hash в любом XHR к fragment.com/api — или вызовите client.auth.fetchHash() |
| stelSsid, stelToken, stelTonToken | Cookie на fragment.com (DevTools → Application → Cookies) |
| stelDt | Cookie stel_dt (смещение таймзоны, обычно "-180") |
| toncenterApiKey | Бесплатный ключ от @tonapibot / toncenter.com |
| tonconsoleApiKey | Альтернативный источник баланса — tonconsole.com (tonapi.io) |
| walletSeed | 24-словная мнемоника кошелька — нужна только для отправки TON |
🔒 Безопасность: относитесь к этим данным как к паролям. Храните в переменных окружения, не хардкодьте и не коммитьте. Любой, у кого есть ваш
walletSeed, может вывести все средства.
Данные можно обновлять и после создания клиента:
client.configure({ hash: "новый_hash" });
await client.auth.fetchHash(); // спарсит и сохранит hash автоматически📚 Справочник API
Каждый сетевой вызов возвращает Promise<Result<T>>.
client.users / client.utils
await client.users.nickToHash({ nickname: "durov" }); // → recipient-хеш
client.utils.decodePayload({ payload: "te6ccg..." }); // → { decoded } (синхронно)
client.utils.fromNano("456100000"); // → "0.4561" (нано → TON)
client.utils.toNano("0.4561"); // → 456100000n (TON → нано)client.stars
await client.stars.getPrice({ quantity: 5050 }); // → { curPrice: { TON, USDT } }
await client.stars.purchase({ recipient, quantity: 50 }); // → весь сценарий: init → getBuyStarsLink(account) → send → ждём on-chain
await client.stars.initPayment({ recipient, quantity: 50 }); // → { req_id, amount } (payment_method: "ton" по умолчанию)
await client.stars.getPaymentInfo({ requestId, account }); // → { transaction, … } (передай `account` — привязывает заказ к кошельку)
await client.ton.wallet.waitForConfirmation({ boc, address }); // ← ждём подтверждения TON-перевода в блокчейне⚠️ Stars зачисляются только после confirm-запроса. Сайт Fragment не останавливается на подписи TonConnect-перевода — после бродкаста он отдельно постит
confirm_method(из ответаgetBuyStarsLink) с{account, device, boc, …confirm_params}. Без этого вызова Fragment никогда не сопоставит ончейн-TON с твоимreq_id, и кошелёк спишет TON, но получатель не увидит звёзды. Используй высокоуровневыйclient.stars.purchase({ recipient, quantity })— он делает всё сам. Или собери три шага вручную (см. полный сценарий ниже).💡 Что ещё нужно для покупки звёзд.
initPaymentшлётpayment_method(по умолчанию"ton") — Fragment требует его; без него будетAccess denied. К аккаунту Fragment должен быть подключён TON-кошелёк (иначеinitPaymentвернёт ошибкуAUTHсneed_ton).
client.premium
const res = await client.premium.getPrice({ months: 12 });
if (res.ok) console.log(res.data.tonRate, res.data.options);client.ton
await client.ton.getRandomLiteServer(); // → { ip_readable, port }
await client.ton.wallet.getAddress(); // → { friendly, raw } (из walletSeed, без сети)
await client.ton.wallet.getAccount(); // → { address, publicKey, chain, walletStateInit } (TonConnect-JSON, без сети)
await client.ton.wallet.getBalance({ address: "UQ..." }); // → { nano, ton, source }
// сумму можно в TON …
await client.ton.wallet.v4r2.send({ destinationAddress: "UQ...", amount: 0.21 });
// … или точный платёж Fragment — amount + payload прямо из getPaymentInfo:
await client.ton.wallet.v4r2.send({
destinationAddress: msg.address,
amountNano: msg.amount, // точные нанотоны, без округлений
payloadCell: msg.payload, // точная BoC-ячейка (байт-в-байт как сайт)
}); // → { sender, amount, amountNano, boc, balanceBefore }💡 Для платежей Stars/Fragment используй
amountNano+payloadCell(оба прямо изgetPaymentInfo).amountNanoубирает float-баг с/1e9;payloadCellшлёт точную ячейку Fragment — пере-кодированный текст-комментарий (payload) может не совпасть байт-в-байт. Полеbocв ответе — это BoC внешнего сообщения, отправленного в сеть; передай его как есть вstars.confirmPayment(...), чтобы Fragment зачислил Stars.
client.account
await client.account.getProfile(); // → { username, verified, wallet, ... }
await client.account.getSessions(); // → { account, sessions: [...] }client.auth
await client.auth.fetchHash(); // парсит hash со страницы fragment.com/
await client.auth.fetchHash({ url: ".../stars" }); // с конкретной страницы🔗 Полный сценарий: покупка Stars от и до
В один вызов (рекомендуется)
import { Fragment } from "telegram-fragment-api";
const client = new Fragment({
hash: process.env.FRAGMENT_HASH!,
stelSsid: process.env.FRAGMENT_STEL_SSID!,
stelToken: process.env.FRAGMENT_STEL_TOKEN!,
stelTonToken: process.env.FRAGMENT_STEL_TON_TOKEN!,
toncenterApiKey: process.env.TONCENTER_API_KEY!,
walletSeed: process.env.WALLET_SEED!,
});
const user = await client.users.nickToHash({ nickname: "maksim_dremin" });
if (!user.ok) throw new Error(user.error.message);
const res = await client.stars.purchase({
recipient: user.data.found!.recipient,
quantity: 50,
});
console.log(res.ok ? `Отправлено ✅ req=${res.data.reqId}` : res.error.message);purchase() делает все четыре реальных шага: initBuyStarsRequest →
getBuyStarsLink → wallet.v4r2.send → POST confirm_method. Именно
последний шаг чаще всего упускают — без него TON списывается, а звёзды не
приходят.
Вручную, по шагам
Бери этот вариант, если нужны промежуточные результаты (логировать ончейн-хеш, ждать подтверждения пользователя или ретраить только confirm):
const init = await client.stars.initPayment({ recipient, quantity: 50 });
if (!init.ok) throw new Error(init.error.message);
// Получаем кошелёк-плательщик и передаём `account` в getBuyStarsLink — Fragment
// привязывает к нему заказ и зачисляет пришедший от него on-chain платёж.
// Кошелёк должен быть тем, что подключён к твоей сессии Fragment.
const account = await client.ton.wallet.getAccount();
if (!account.ok) throw new Error(account.error.message);
const info = await client.stars.getPaymentInfo({
requestId: init.data.req_id,
account: account.data,
});
if (!info.ok) throw new Error(info.error.message);
const msg = info.data.transaction!.messages[0]!;
const tx = await client.ton.wallet.v4r2.send({
destinationAddress: msg.address,
amountNano: msg.amount, // точные нанотоны
payloadCell: msg.payload, // точная BoC-ячейка — байт-в-байт как сайт
});
if (!tx.ok) throw new Error(tx.error.message);
// Ждём подтверждения перевода в блокчейне — Fragment зачислит звёзды по
// подтверждённому платежу. Никакого confirm POST и TON Connect proof не нужно.
const confirmed = await client.ton.wallet.waitForConfirmation({
boc: tx.data.boc,
address: tx.data.sender,
});
console.log(confirmed.ok ? `Звёзды зачислены ✅ tx ${confirmed.data.txHash}` : confirmed.error.message);
initPaymentсам синхронизирует курс TON и ретраит приPrice was changed, так что вручную это делать не нужно. К аккаунту Fragment должен быть подключён TON-кошелёк, а для подписи нужны настоящийtoncenterApiKey+walletSeed.
🧰 Несколько аккаунтов
Каждый экземпляр Fragment полностью изолирован — просто создайте ещё:
const a = new Fragment({ hash: "..." });
const b = new Fragment({ hash: "..." });🧪 Тестирование
Вся библиотека покрыта мок-тестами (Vitest + axios-mock-adapter, @ton/ton замокан):
npm test # запустить тесты
npm run test:coverage🎯 Принципы дизайна
- На классах —
new Fragment({ … }), один изолированный клиент на аккаунт. - Объект-параметры —
getPrice({ quantity })читается ясно и легко расширяется. Resultвместо исключений — проверяемres.okвместоtry/catch.- Везде
asyncи camelCase, строгие типы.
⚠️ Дисклеймер
Это неофициальная библиотека, не связанная с Telegram или Fragment. Она работает с недокументированными эндпоинтами, которые могут измениться в любой момент. Используйте на свой страх и риск и в соответствии с правилами Fragment. Вы несёте полную ответственность за свои данные и средства.
🤝 Контрибьютинг
Issues и pull requests приветствуются! Создайте issue.
⭐ Поддержать проект
Если библиотека сэкономила вам время — лучшее «спасибо» это звезда на GitHub ⭐. Это помогает другим находить проект и поддерживает разработку.
📄 Лицензия
MIT © Maksim Dremin
