Bondify Flutter SDK
One-tap Telegram authentication for Flutter apps. No SMS, no passwords â your users tap a button, confirm in Telegram, and you get a verified identity.
- ð Drop-in
BondifyButtonandshowBondifyAuthSheet - ðą Built for mobile â uses the public, key-less flow (your secret key never ships in the app)
- ð Returns a signed
proof(JWT) you verify on your backend - ðĻ Themeable (Telegram / dark / light), with built-in loading & success states
- ðŠķ Tiny: only
httpandurl_launcher
Installation
Add the package to your pubspec.yaml.
From pub.dev (once published):
dependencies:
bondify_flutter: ^1.0.0
From GitHub (before it's on pub.dev):
dependencies:
bondify_flutter:
git:
url: https://github.com/bondify-dev/bondify-flutter
ref: v1.0.0
Then:
flutter pub get
Before you start: open your Bondify dashboard, copy your Project ID (
proj_âĶ), and enable Mobile SDK in the project settings. The mobile flow uses public endpoints that only work when Mobile SDK is on.
Quick start
1. The login button
import 'package:bondify_flutter/bondify_flutter.dart';
BondifyButton(
projectId: 'proj_xxxxxxxx',
label: 'Login with Telegram',
theme: BondifyTheme.telegram, // telegram | dark | light
onSuccess: (user) {
// user.proof is a signed JWT â send it to YOUR backend and verify it.
debugPrint('Welcome, ${user.name} (@${user.username})');
},
onError: (err) => debugPrint('Login failed: $err'),
)
2. Or a guided bottom sheet
final user = await showBondifyAuthSheet(context, projectId: 'proj_xxxxxxxx');
if (user != null) {
// signed in
}
3. Or drive the flow yourself
final client = BondifyClient(const BondifyConfig(projectId: 'proj_xxxxxxxx'));
try {
final user = await client.authenticate(
onStatus: (s) => debugPrint('status: $s'),
);
debugPrint('Signed in as ${user.telegramId}');
} on BondifyException catch (e) {
debugPrint('Auth error: ${e.message}');
}
You can also configure a singleton once at startup and omit projectId everywhere:
void main() {
BondifyClient.init(const BondifyConfig(projectId: 'proj_xxxxxxxx'));
runApp(const MyApp());
}
Verify the proof on your backend (required)
The SDK runs on the user's device, so never trust it alone. Always send
user.proof to your server and verify it there before creating a session.
proof is a JWT signed (HS256) with your project's webhook secret
(whsec_âĶ, found in your project settings). Verify it with any JWT library:
// Node.js (Express) example
import jwt from 'jsonwebtoken'
app.post('/auth/telegram', (req, res) => {
const { proof } = req.body
try {
const claims = jwt.verify(proof, process.env.BONDIFY_WEBHOOK_SECRET) // whsec_âĶ
// claims = { telegram_id, telegram_name, telegram_username, project_id, ... }
// â create or look up the user, issue your own session cookie/JWT
res.json({ ok: true, telegramId: claims.telegram_id })
} catch {
res.status(401).json({ error: 'Invalid proof' })
}
})
Keep
BONDIFY_WEBHOOK_SECRETon the server only. It is not the same as yoursecret_keyand must never be shipped in the app.
Platform setup
url_launcher opens the Telegram app. On Android 11+ declare the query so the
launch check works:
android/app/src/main/AndroidManifest.xml (inside <queries>):
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="https" />
</intent>
<package android:name="org.telegram.messenger" />
</queries>
iOS works out of the box; no extra configuration is required for https://t.me
links.
API reference
BondifyButton
| Property | Type | Default | Description |
|---|---|---|---|
projectId |
String? |
uses BondifyClient |
Your Project ID. Omit if you called init(). |
onSuccess |
void Function(BondifyUser) |
â | Called with the verified user. |
onError |
void Function(Object)? |
null |
Called on failure/cancel. |
label |
String |
'Login with Telegram' |
Idle button text. |
theme |
BondifyTheme |
telegram |
telegram / dark / light. |
borderRadius |
double |
14 |
Corner radius. |
expand |
bool |
false |
Full-width button. |
apiBase |
String? |
hosted API | Advanced / self-hosted. |
BondifyUser
| Field | Type | Description |
|---|---|---|
telegramId |
String |
Stable numeric Telegram ID. |
name |
String |
Display name. |
username |
String? |
@username if set (no leading @). |
phone |
String? |
Only if your project collects phone numbers. |
proof |
String |
Signed JWT â verify on your backend. |
confirmedAt |
int |
Confirmation time (ms since epoch). |
BondifyClient
Future<GenerateResponse> startSession()Future<void> openTelegram(String deeplink)Future<BondifyUser> waitForConfirmation(token, {onStatus, cancelToken})Future<BondifyUser> authenticate({onStatus, cancelToken})â full flow
Example
A complete runnable example lives in example/:
cd example
flutter run
License
MIT ÂĐ Bondify
Libraries
- bondify_flutter
- Bondify Flutter SDK One-tap Telegram authentication for Flutter apps.