Skip to content

Conversation

@jvsena42
Copy link
Member

@jvsena42 jvsena42 commented Jan 5, 2026

Closes #418

Description

  1. When pasting an LNURL-withdraw with equal min/max amounts, the code updates state and immediately navigates
  2. The navigation happens before the UI has recomposed with the new state values
  3. The WithdrawConfirmScreen expects uiState.amount to be set, but may see stale data
  4. This causes the app to appear frozen or unresponsive

The fix:

  • Add a small delay before navigation (using existing TRANSITION_SCREEN_MS constant)
  • This gives the UI time to recompose with correct state

Preview

QA Notes

  • Connect to external node -> create a LNURL withdraw with minWithdrawable == maxWithdrawable -> paste in the app

@jvsena42 jvsena42 self-assigned this Jan 5, 2026
@jvsena42 jvsena42 marked this pull request as ready for review January 5, 2026 10:54
@jvsena42 jvsena42 requested a review from Copilot January 5, 2026 11:03
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a race condition in the LNURL-withdraw flow where navigation occurs before the UI has time to recompose with updated state values. When an LNURL-withdraw request has equal minimum and maximum amounts, the code was immediately navigating to the confirmation screen before the UI could reflect the new state, causing the app to appear frozen or unresponsive.

Key Changes:

  • Added a coroutine-based delay before navigation in the LNURL-withdraw handler
  • Uses the existing TRANSITION_SCREEN_MS constant to ensure UI recomposition completes

@jvsena42
Copy link
Member Author

jvsena42 commented Jan 5, 2026

@piotr-iohk Does this PR unblock some E2E flow? like lnurl_1 from the issue

@jvsena42
Copy link
Member Author

jvsena42 commented Jan 5, 2026

Couldn't decode the lnurl invoices locally, but it is passing on E2E, so I suppose it is something in my setup

2026-01-05 08:27:56.123  7761-7799  APP                     to.bitkit.dev                        E  2026-01-05 11:27:56.123 ERROR   [AppViewModel.kt:714]                Failed to decode scan data: 'lnurl1dp68gup69uhkcmmrv9kxsmmnwsarxvpsxqhhqcte9a3nyd35xa3r2enrxqcnydtzx5ckzer9xumrgvmxx5ekxcm9x5crg2wwcny' [InvalidFormat=''] - AppViewModel
                                                                                                    com.synonym.bitkitcore.DecodingException$InvalidFormat: 
                                                                                                    	at com.synonym.bitkitcore.FfiConverterTypeDecodingError.read-0Q8s1zI(bitkitcore.android.kt:6622)
                                                                                                    	at com.synonym.bitkitcore.FfiConverterTypeDecodingError.read-0Q8s1zI(bitkitcore.android.kt:6619)
                                                                                                    	at com.synonym.bitkitcore.FfiConverter$DefaultImpls.liftFromRustBuffer(bitkitcore.android.kt:231)
                                                                                                    	at com.synonym.bitkitcore.FfiConverterRustBuffer$DefaultImpls.liftFromRustBuffer(bitkitcore.android.kt:243)
                                                                                                    	at com.synonym.bitkitcore.FfiConverterTypeDecodingError.liftFromRustBuffer(bitkitcore.android.kt:6619)
                                                                                                    	at com.synonym.bitkitcore.FfiConverterTypeDecodingError.liftFromRustBuffer(bitkitcore.android.kt:6619)
                                                                                                    	at com.synonym.bitkitcore.FfiConverterRustBuffer$DefaultImpls.lift(bitkitcore.android.kt:244)
                                                                                                    	at com.synonym.bitkitcore.FfiConverterTypeDecodingError.lift(bitkitcore.android.kt:6619)
                                                                                                    	at com.synonym.bitkitcore.FfiConverterTypeDecodingError.lift(bitkitcore.android.kt:6619)
                                                                                                    	at com.synonym.bitkitcore.DecodingExceptionErrorHandler.lift(bitkitcore.android.kt:6616)
                                                                                                    	at com.synonym.bitkitcore.DecodingExceptionErrorHandler.lift(bitkitcore.android.kt:6615)
                                                                                                    	at com.synonym.bitkitcore.Bitkitcore_androidKt.uniffiCheckCallStatus(bitkitcore.android.kt:294)
                                                                                                    	at com.synonym.bitkitcore.Bitkitcore_androidKt$uniffiRustCallAsync$2$invokeSuspend$$inlined$uniffiRustCallWithError$1.invoke(bitkitcore.android.kt:284)
                                                                                                    	at com.synonym.bitkitcore.Bitkitcore_androidKt$uniffiRustCallAsync$2$invokeSuspend$$inlined$uniffiRustCallWithError$1.invoke(bitkitcore.android.kt:282)
                                                                                                    	at com.synonym.bitkitcore.UniffiRustCallStatusHelper.withReference$lib_release(bitkitcore.android.kt:382)
                                                                                                    	at com.synonym.bitkitcore.Bitkitcore_androidKt$uniffiRustCallAsync$2.invokeSuspend(bitkitcore.android.kt:11561)
                                                                                                    	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:34)
                                                                                                    	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100)
                                                                                                    	at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:124)
                                                                                                    	at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:89)
                                                                                                    	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:586)
                                                                                                    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:820)
                                                                                                    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:717)
                                                                                                    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:704)

@piotr-iohk

This comment was marked as resolved.

@jvsena42

This comment was marked as resolved.

@jvsena42 jvsena42 marked this pull request as draft January 5, 2026 13:29
@jvsena42

This comment was marked as resolved.

@jvsena42 jvsena42 marked this pull request as ready for review January 5, 2026 13:56
@jvsena42

This comment was marked as resolved.

@piotr-iohk
Copy link
Collaborator

@piotr-iohk is this code still necessary for testing? the app could read the string directly from clipboard https://github.com/synonymdev/bitkit-android/blob/c96bc1f37fb30eccbdb9b051ea12ed9f949f191f/app/src/main/java/to/bitkit/ui/screens/scanner/QrScanningScreen.kt#L337C1-L367C10

Yes, it was like that in the RN app, therefore it was ported. I guess the idea was to go through the Qr screening flow.

@jvsena42 jvsena42 enabled auto-merge January 5, 2026 16:01
Copy link
Collaborator

@ovitrif ovitrif left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small nit.

@jvsena42 jvsena42 requested a review from ovitrif January 6, 2026 10:31
Copy link
Collaborator

@ovitrif ovitrif left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utAck.

Will test later today but you can already merge.

All LGTM, if required changes are identified after testing, we can always fix later.

@jvsena42 jvsena42 merged commit 3444b07 into master Jan 6, 2026
14 checks passed
@jvsena42 jvsena42 deleted the fix/lnurl-withdraw-pasting branch January 6, 2026 10:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

LNURL-withdraw where minWithdrawable == maxWithdrawable issue when trying to read via QRCode String

4 participants