Skip to content

fix: pubky swaps route review follow-ups - #1929

Merged
ovitrif merged 3 commits into
masterfrom
fix/pubky-swaps-route-followups-2
Nov 14, 2026
Merged

ovitrif merged 3 commits into
masterfrom
fix/pubky-swaps-route-followups-2

Conversation

@ovitrif

@ovitrif ovitrif commented Nov 14, 2026 •

Copy link
Copy Markdown
Collaborator

Closes #1925
Closes #1926
Closes #1927
Closes #1928

Follow-up to #1923: the non-blocking points from its last review, all on the Pubky Swaps route behind the debug-only PUBKY_SWAPS_ROUTES flag.

Description

Out of Scope

Design

N/A — no UI changes.

Preview

N/A

QA Notes

Setup

N/A — no device testing required: the swap route is behind the debug-only PUBKY_SWAPS_ROUTES flag, and these are failure, wipe and restore paths the unit tests drive.

Journeys

N/A — not drivable; see Manual Tests.

Manual Tests

N/A

Automated Checks

  • added AppViewModelSendFlowTest.kt — a hold failing after its sheet closed leaves no contact behind
  • added PubkySwapsRouteRepoTest.kt — a failed hold payment stops its resumed swap; a hold that failed while the app was closed, over the node or Spark, is dropped at start; a dropped swap's claim wait stops; a wipe stops a running claim wait; a restore leaves a swap dropped this session alone
  • updated AppViewModelSendFlowTest.kt — each hold is recorded before it goes out

Evidence

  • just compile, just test and just lint pass locally on this PR's head. The closed-sheet test failed before its fix.

Gaps

  • No device run: the paths are failure, wipe and restore timing that the unit tests drive.

Models used

  • Planning/scoping: claude-opus-5-5 (reasoning: Not exposed)
  • Implementation: claude-opus-5-5 (reasoning: Not exposed)
  • Review: Not performed

The session records the model but not its reasoning setting.

@ovitrif ovitrif added this to the 3.3.0 milestone Nov 14, 2026
@ovitrif ovitrif self-assigned this Nov 14, 2026
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 14, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-14T06:23:15.238929Z f26be5f PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@greptile-apps

greptile-apps Bot commented Nov 14, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 4/5

[Medium impact] The changes affect Pubky Swaps sends, recovery, and wallet-wipe cleanup.

The PR appears safe to merge, with two non-blocking cleanup gaps that can leave swap polling running.

Findings

  1. P2 Failed swaps keep polling ▶
  2. P2 Wipe misses a starting claim ▶

Summary

Adds failure and wipe cleanup for the debug-only Pubky Swaps route.

  • Failed hold payments stop their Pubky Swaps routes, even after an app restart.
  • Closing the Send sheet ends that send session.
  • Wallet wipes stop the running Pubky Swaps claim waits.
  • Restore passes skip swaps already committed or dropped this session.

Reviews (1) · Last reviewed commit: "fix: stop swaps on any hold failure, wip..." · Reviewed by Greptile

@github-actions

github-actions Bot commented Nov 14, 2026 •

Copy link
Copy Markdown
Contributor

Regtest APK

Built from 9bbb9cf (run).

Download bitkit-dev-debug universal APK (expires in 30 days).

@talosmachina talosmachina left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

1 finding (1 P1). Closes the four follow-ups from #1923 on the Pubky Swaps route: a closed Send sheet bumps sendSession, wipes cancel running claim waits, each swap's hold hash is persisted so a failed hold drops the swap live or at the next start, and a restore pass skips swaps committed or dropped this session. Reviewed f26be5f, static review (bitkit-android is not built on this side).

The live path and the wipe/restore/closed-sheet paths hold up; the gap is the restart check for a hold paid over Spark.

Merge confidence: 3/5, one P1 (the restart drop misses Spark-paid holds); build-and-test was still running when I read CI.

What I checked, and what I ruled out

Read: the full diff, PubkySwapsRouteRepo.kt around every changed hunk, proceedWithSwapRoutedPayment, finishSwapRoutedPayment, releaseFailedSwapHold, hideSheet, resetSendState, LightningRepo.payInvoice, WipeWalletUseCase.wipeLocal, the new tests.
CI at read time: lint, detekt, build-local green; build-and-test, compose-ui and the local e2e jobs pending.

Ruled out

  • Live hold failure no longer dropped after removing dropFailedSwap from releaseFailedSwapHold: watchHoldFailures starts from resumeUnfinishedSwaps on every successful node start, before any send can commit, and watchHold persists the hash before payInvoice, so the repo collector drops it.
  • Hold failing before payInvoice returns: the hash is in the cache store before the payment goes out, so the collector sees the event regardless of pendingPaymentRepo.track.
  • sendSession++ in hideSheet breaking the in-sheet flow: the session is read at the start of proceedWithSwapRoutedPayment, and restoreSwapContact / releaseFailedSwapHold / showCommittedSwap only compare it, so a closed sheet just stops handing the contact back, as intended.
  • Wipe racing a claim wait: claimWaits registers the job before await, and invokeOnCompletion removes it, so a cancel on wipe reaches every live wait.
  • Restore picking up a dropped swap: known.removeAll { it in committed || it in dropped } runs before track, and advanceInBackground also refuses dropped ids.

Reviewer model: claude-opus-5-5
Reasoning effort: Not exposed (the session metadata available to this reviewer does not record a reasoning setting)

@coreyphillips coreyphillips left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Two independent reviews, nothing blocking a merge.

worth doing, does not block

  • Send sheet replaced via showSheet still keeps its send session (app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt:8801-8826). The #1925 fix only bumps sendSession in hideSheet, but showSheet can close an open Send sheet without going through it. showSheet sets _currentSheet to null and then to the new sheet (AppViewModel.kt:8811 and 8826). SheetHost only calls onDismiss when the dismissed key equals the current visibility key (SheetHost.kt:171-175), so a programmatic swap never reaches hideSheet. Two callers do this while a Send sheet can be open: - handleChannelClosed shows Sheet.ConnectionClosed on a counterparty close (AppViewModel.kt:2633). - ContentView opens sheet deep links (ContentView.kt:386). A counterparty close while a swap hold HTLC is in flight is a natural way for that hold to fail later. The sequence is: 1. The Pending sheet is replaced and sendSession stays the same. 2. The hold fails. 3. releaseFailedSwapHold (AppViewModel.kt:7524) or restoreSwapContact (7462) passes the session check and sets activeContactPaymentContext with no Send sheet open, which is the #1925 symptom. I confirmed this by reading the code, not by running it. A test like the new swap route hold failing after its sheet closed leaves no contact behind, with sut.showSheet(Sheet.ConnectionClosed) in place of sut.hideSheet(), should show it. One fix is to bump the session wherever an open Sheet.Send is replaced, for example in a small helper that both hideSheet and showSheet call. The route is behind the debug-only PUBKY_SWAPS_ROUTES flag, so this is non-blocking.

@ovitrif

ovitrif commented Nov 14, 2026

Copy link
Copy Markdown
Collaborator Author

@coreyphillips thanks. Confirmed in the code: showSheet nulls _currentSheet without going through hideSheet, so a replaced Send sheet keeps its session.

Out of scope: tracked in #1930, because the route is behind the debug-only PUBKY_SWAPS_ROUTES flag and a push now would void this approval. It goes into the next follow-up PR with the helper and test you suggest.

Merging this PR now: approved, CI green, no open threads.

@ovitrif
ovitrif merged commit 7ac7214 into master Nov 14, 2026
23 checks passed
@ovitrif
ovitrif deleted the fix/pubky-swaps-route-followups-2 branch November 14, 2026 17:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants