ptgc
MTProto client for Dart

Authentication Flow

Logging in as a user account is a multi-step handshake, not a single call. This page walks through every branch of it. See also the Login example for a complete, runnable version.

1. Send the code

final sent = await client.auth.sendCode('+15551234567');

Telegram delivers a login code to the phone number — as an in-app notification if that number is already signed in on another device, otherwise by SMS or call. sendCode returns a SentCode with a phoneCodeHash your next call needs.

2. Sign in with the code

final result = await client.auth.signIn(code: '12345', phoneCodeHash: sent.phoneCodeHash);

phoneCodeHash (and the phone number) default to whatever the last sendCode call used, so you can usually omit them:

final result = await client.auth.signIn(code: '12345');

signIn returns a SignInResult whose status is one of three SignInStatus values:

Status Meaning
success Logged in. result.user is set.
passwordRequired Correct code, but the account has Two-Factor Authentication enabled — go to step 3.
signUpRequired This phone number has no Telegram account yet. ptgc doesn’t wrap account creation on purpose; most automation shouldn’t be creating fresh accounts.

3. Handle Two-Factor Authentication

if (result.status == SignInStatus.passwordRequired) {
  print('Password hint: ${result.passwordHint}');
  final me = await client.auth.checkPassword('your 2FA password');
  print('Logged in as ${me.displayName}');
}

checkPassword performs Telegram’s SRP challenge locally and returns the logged-in PtgcUser directly (rather than another SignInResult) since this is always the last step.

After signing in

signIn/checkPassword call TelegramClient.rememberSignedInUser for you, which persists the session via your SessionStore. From then on, client.isSignedIn is true immediately after connect() on every subsequent run — no need to repeat any of the above.

Logging out

auth.logOut() invalidates the session on Telegram’s servers and clears your SessionStore. Use TelegramClient.disconnect() instead if you just want to stop using the connection for now without revoking it — see Logging Out.