---
title: "Sign in on a phone"
description: "Add QR sign-in from desktop to phone, push approval with number matching, trusted devices, recovery and native passkeys."
section: "guides"
status: "Planned for 1.1"
spec: "mobile-auth"
canonical: "https://mainsdk.dev/docs/guides/sign-in-on-a-phone"
updated: "2026-10-28"
---

# Sign in on a phone

> Add QR sign-in from desktop to phone, push approval with number matching, trusted devices, recovery and native passkeys.

Status: Planned for 1.1 · Canonical: https://mainsdk.dev/docs/guides/sign-in-on-a-phone · Updated: 2026-10-28

You will add the phone-side sign-in flows to an app that already has passkeys. It takes about 30 minutes.

## You need

- The mobile target from [Build a mobile app with Expo](https://mainsdk.dev/docs/guides/build-a-mobile-app-with-expo), with `auth.passkeys.rpId` set.

## 1. Sign in a desktop from a phone with a QR code

`QrSignIn` starts a one-time code that lives 60 seconds. The desktop shows it as a QR code; the signed-in phone scans it, `describe` shows what is being approved, `approve` binds it to the person, and the desktop `redeem`s it once. A malformed, expired or reused code fails with `MAIN-AUTH-0102`.

## 2. Ask the phone to approve a sign-in

`PushApproval` sends a prompt with a two-digit number. The person must pick the same number on the sign-in page; a wrong number or a deny raises an `mfa-fatigue` event in OCSF form, and too many prompts in the window fail with `MAIN-AUTH-0103`.

## 3. Trust devices and recover accounts

`TrustedDevices` lists devices, ties sessions to them and revokes them; a revoked device fails with `MAIN-AUTH-0105`. `Recovery` accepts a recovery code, a second passkey or a verified email or WhatsApp, then waits before it finishes so the owner can cancel (`MAIN-AUTH-0104`).

## 4. Use the passkey from the app

`signInNative` asks the platform for an assertion and accepts the web origin and the Android app's `android:apk-key-hash` origin for the same credential. `mainsdk sync` writes `assetlinks.json` and `apple-app-site-association` from `targets.mobile.signing`; `mainsdk check` fails with `MAIN-AUTH-0101` when they disagree.

## Check that it works

- Scan a code twice: the second scan fails.
- Answer a push prompt with the wrong number: the sign-in fails and an event is logged.
