Skip to content

bug: pubky sign-in from a link fails on the first try when bitkit cold-starts #1513

Closed

Description

@ovitrif

What happened?

Signing in to a Pubky app (Pubky App or the Pubky Shop) with Bitkit on Android consistently fails on the first attempt when Bitkit is not already running. The sign-in link opens Bitkit from a cold start, but the authorization does not complete; a second attempt, with Bitkit now running, works.

Reported by @catch-21 in the Shop launch thread on staging.

Expected behavior

The first sign-in attempt completes even when the link cold-starts Bitkit: Bitkit keeps the incoming authorization request through startup and shows the approval once it is ready.

Steps to Reproduce

  1. Force-stop Bitkit on Android.
  2. On staging.pubky.app (or the Shop), choose sign-in with Bitkit so the link opens Bitkit.
  3. Bitkit starts, but the sign-in does not complete.
  4. Try again with Bitkit running: it works.

Logs / Screenshots / Recordings

N/A

Bitkit Version

3.0.0 RC2 (current master)

Device / OS

Android

Reproducibility

Always on a cold start

Activity

  1. added this to the 3.0.5 milestone on Oct 16, 2026
  2. ovitrif commented on Oct 16, 2026

    @ovitrif
    CollaboratorAuthor

    Reproduced on an Android 16 emulator against staging, with 2.6.0 (192) and master 0801188, using a wallet whose pubky was created in Bitkit.

    Results

    Case 2.6.0 (192) master 0801188
    Cold start, stay in Bitkit 3 of 3 signed in 3 of 3 signed in
    Cold start, leave Bitkit during the wait, tap again (the reported flow) not run second tap signed in
    Cold start, Pubky session restore fails (network cut for 25 s once the link arrives) 0 of 1, Bitkit closes itself 0 of 1, Bitkit closes itself
    Warm, Bitkit running 1 of 2 signed in 1 of 1 signed in

    The link is never dropped on a plain cold start. Every run logs the deeplink as received, queued and started, and no run showed the timeout toast. The Authorize sheet appears late: 12 to 19 s after the wallet home screen shows, 19 to 40 s after the tap, with nothing on screen in between. Bitkit waits there for Paykit to restore the Pubky session before it shows the sheet (AppViewModel.kt#L3103-L3120). The report's video matches this path: the user sees wallet home, returns to the browser and taps again. By then the session is restored, so the second tap shows the sheet at once.

    A worse path appears when that restore fails. It happened on its own in 1 of 4 cold starts on 2.6.0 (192), a transport_error fetching the Paykit App Registry, and every time the network was cut:

    1. PubkyRepo treats the error as a deferred restoration and clears the public key (PubkyRepo.kt#L481-L490).
    2. PubkyAuthHandlerRegistrar sees no public key and disables the .ui.MainActivityPubkyAuth alias (PubkyAuthHandlerRegistrar.kt#L52-L69, L83).
    3. That alias is the component the sign-in link launched Bitkit through (AndroidManifest.xml#L172). In both runs Bitkit's task closed about 1 s after the alias was disabled and the browser came back, with no sheet and no toast.
    4. The alias stays disabled until a later restore succeeds, so further taps in the browser open nothing. On master it was still disabled 3 minutes later. Opening Bitkit by hand restores the session within about 30 s, and sign-in works after that. The saved session is kept, so no reinstall is needed.
    09:52:52.806 I ActivityTaskManager: START u0 {act=android.intent.action.VIEW cat=[android.intent.category.BROWSABLE] dat=pubkyauth://signin_grant/... cmp=to.bitkit.dev/to.bitkit.ui.MainActivityPubkyAuth
    09:53:02.932 D APP: [AppViewModel.kt:7449] Received deeplink 'pubkyauth://signin_grant'
    09:53:05.606 W APP: [PubkyRepo.kt:531] Deferred session restoration, keeping saved session [Transport='code=transport_error, context=get_paykit_app_registry: fetch Paykit App Registry]
    09:53:05.712 I APP: [PubkyAuthHandlerRegistrar.kt:89] Updated Pubky handler 'to.bitkit.ui.MainActivityPubkyAuth' to 'disabled'
    09:53:06.728 V WindowManagerShell: TransitionRequestInfo { type = CLOSE, triggerTask = TaskInfo{taskId=22 (to.bitkit.dev)} }
    

    The failed warm attempt on 2.6.0 (192) is a separate finding. Bitkit approved and posted the grant to the relay, but the App stayed on the sign-in page. It did not repeat.

    Recordings (2x speed)

    Cold start, sheet appears lateReported flow: leave, tap againRestore fails, Bitkit closes itself
    rc1-cold1.2x.mp4
    m-retap.2x.mp4
    m-netcut.2x.mp4
  3. modified the milestones: 3.0.5, 3.0.0 on Oct 16, 2026
  4. ovitrif commented on Oct 16, 2026

    @ovitrif
    CollaboratorAuthor

    Moved to 3.0.0 after the repro above. When the Pubky session restore fails on a cold start, Bitkit disables its own sign-in handler, closes and drops the request, and every later sign-in link does nothing until the user opens Bitkit by hand. That breaks the launch's Shop sign-in flow on Android in about 1 of 4 cold starts on RC1 (every time with no network). The plain cold-start delay (the approval sheet appearing 12-19 s after the wallet home with no feedback) can follow in 3.0.5 if the fix doesn't cover it.

  5. ovitrif commented on Oct 16, 2026

    @ovitrif
    CollaboratorAuthor

    Suggestions from @catch-21 for the slow path: show a general profile loading indicator in the app status area while the Pubky session restores, so the 12-19 s wait before the Authorize sheet isn't silent; a toast could help too, shown long enough to read (toasts often disappear before he can read them).

  6. ovitrif commented on Oct 16, 2026

    @ovitrif
    CollaboratorAuthor

    Fix in #1514: a failed Pubky session restore no longer disables the sign-in handler or closes Bitkit, the waiting link retries the restore, and a loading toast stays until the Authorize sheet opens. Recordings of the cold start and the network-cut case are in the PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions