Cancel proposal flow#512
Conversation
…e interceptor to guardian
…Network/quantus-apps into beast/execute-proposal-flow
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit c9c6792. Configure here.
| return event; | ||
| } | ||
| } | ||
| return null; |
There was a problem hiding this comment.
Pending cancel ignored for signers
Medium Severity
findPendingCancellationForProposal only matches when the viewer’s account equals event.proposerId, so co-signers never see an in-flight cancellation. Approve and execute buttons still use canApprove / canExecute without checking any proposal-level pending cancel, so signers (and a proposer on a threshold-ready proposal) can submit conflicting extrinsics while cancellation is confirming.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit c9c6792. Configure here.
|
The review is complete. Here's my assessment of PR #512. Review: Cancel proposal flow (PR #512)Setup: Reviewed in worktree Verification:
OverallSolid, well-structured PR. It faithfully mirrors the existing approve/execute architecture: optimistic pending event → background submit → indexer polling with soft-timeout fallback → reconciliation into activity. Gating is correct: cancel is proposer-only, hidden on terminal proposals, and disabled for expired ones (correct, since the pallet has a separate Issue 1 — Race: approve/execute stay enabled while cancel is in flight (confirms Bugbot, medium)In final isPending = pendingApproval != null;
final canApprove = isActionable && !didApprove && !isPending && hasLocalSigner;
Note: Bugbot's "co-signers never see it" angle is largely moot — pending cancellations are device-local state, so other signers' devices can't see them regardless. The same-device race is the real defect. Issue 2 — DRY: third copy of the confirm sheet
Minor (mostly inherited from the copied pattern)
RecommendationRequest changes for Issue 1 (the in-flight cancel race) — it's a one-line-per-button fix. Issue 2 is worth doing now while all three sheets are fresh, but could be a fast-follow. The worktree is kept at |
…Network/quantus-apps into beast/execute-proposal-flow
…tus-Network/quantus-apps into beast/cancel-proposal-flow
n13
left a comment
There was a problem hiding this comment.
Review (agent-assisted, diffed against beast/execute-proposal-flow)
Verdict: GTG — no blockers found; one minor, non-blocking note.
Minor
- Logout doesn't clear pending cancellation state — the new in-memory
pendingMultisigCancellationsProvideris not cleared inmobile-app/lib/services/logout_service.dart(same pre-existing gap as the proposals/approvals/executions pending providers). After logout + re-login in the same process, stale "Cancelling…" rows could remain in activity andmemberCostcould keep being subtracted from effective balance.
Checked and fine
_executeButtonand_approveButtonboth correctly block while a cancellation is pending (pendingCancellation == nullguard), so the same device can't race conflicting cancel + execute/approve extrinsics.- Cancel-only-for-proposer gating, terminal-proposal handling (action buttons hidden), confirm sheet with fee + biometrics, optimistic pending state, polling, and reconciliation all mirror the established approve/execute patterns.
…Network/quantus-apps into beast/cancel-proposal-flow
* msig implementation 1 * linter fixes and package updates * Create multisig flow (#505) * feat: localize copy writing * Format and regrenate runtime apis * feat: finish create multisig flow * fix: code reviews * fix: code reviews * feat: finish adding in-flight tracking for multisig creation - reconcilate pending multisig creation - track multisig creation * feat: improve multisig creation - make nonce calculated on the fly - only show history for creator * feat: add checksum and not truncate checksum * fix: create multisig screen * fix: add logging on error * feat: improve UX multisig creation pending and details sheet * fix: preflight balance check * fix: DRY violation * fix: silent or masking bad data * fix: persisting pending multisig creation * chore: formatting * Discover multisig flow (#506) * feat: finish adding discover multisig * fix: code review issues * fix: another code review issues * feat: add checksum on discover list item * fix: listview item non properly ordered without key * feat: refactor repeating multisig graphql handling * feat: make json reading throw early instead of silently droping it. Also have intFromJson for supporting hasura stringify number. * fix: use variable instead of string interpolation * feat: propagate error as to not confuse user * Create proposal flow (#507) * wip: create proposal - finish create flow - create history of proposal * feat: improve UX of propose amount and review screen * feat: finish improving the lifecycle of proposal creation and event listing presentation * feat: address code review issues * feat: another code reviews fixes * chore: formatting * fix: dart rule violation * fix: redudancy * fix: graphql query for multisig * fix: circle dependency * feat: explicitly show failed fee fetch - add retry button - show message - silently refetch network fee unless failed * fix: reduce risk of double proposal creation * fix: handle last effort before timeout * chore: formatting * Sign proposal flow (#510) * feat: finish approve proposal flow from multisig account * feat: show approve event in signer account * feat: resolve DRY and simplicity issues * feat: best effort timout and balance refresh * chore: formatting * chore: revert constants * chore: remove dead code * Execute proposal flow (#511) * feat: finish approve proposal flow from multisig account * feat: show approve event in signer account * feat: resolve DRY and simplicity issues * feat: best effort timout and balance refresh * chore: formatting * wip: add execute flow * feat: regenerate polkadart metadata, clean up deposit field and rename interceptor to guardian * fix: live state resolution and update executed proposal UI * feat: improve UX executed proposals * chore: formatting * chore: revert constants * feat: show activity in executor * chore: formatting * chore: revert back chain url * fix: code reviews * fix: execute event query and data model * chore: revert constants * chore: formatting * Cancel proposal flow (#512) * feat: finish approve proposal flow from multisig account * feat: show approve event in signer account * feat: resolve DRY and simplicity issues * feat: best effort timout and balance refresh * chore: formatting * wip: add execute flow * feat: regenerate polkadart metadata, clean up deposit field and rename interceptor to guardian * fix: live state resolution and update executed proposal UI * feat: improve UX executed proposals * chore: formatting * chore: revert constants * feat: show activity in executor * chore: formatting * feat: add cancel proposal flow * feat: display cancel proposal event in proposer activity * chore: formatting * chore: revert constants * chore: revert back chain url * fix: code reviews * fix: execute event query and data model * chore: revert constants * chore: formatting * fix: code review issues * Multisig proposal polling (#513) * feat: finish approve proposal flow from multisig account * feat: show approve event in signer account * feat: resolve DRY and simplicity issues * feat: best effort timout and balance refresh * chore: formatting * wip: add execute flow * feat: regenerate polkadart metadata, clean up deposit field and rename interceptor to guardian * fix: live state resolution and update executed proposal UI * feat: improve UX executed proposals * chore: formatting * chore: revert constants * feat: show activity in executor * chore: formatting * feat: add cancel proposal flow * feat: display cancel proposal event in proposer activity * chore: formatting * chore: revert constants * feat: finish implementing polling and refresh proposals * chore: formatting * chore: revert back chain url * fix: code reviews * fix: execute event query and data model * chore: revert constants * chore: formatting * fix: code review issues * fix: code review issues * fix: broken initialization of timezone * chore: add debug on error * fix: code review issues --------- Co-authored-by: Nikolaus Heger <nheger@gmail.com>


Summary
Screenshots
Note
Medium Risk
Submits signed chain extrinsics and adjusts effective balance for pending cancel fees; behavior mirrors existing multisig execution paths with moderate surface area across SDK and wallet UI.
Overview
Adds an end-to-end multisig proposal cancel path for the proposer, aligned with existing approve/execute flows.
SDK:
multisig.cancel(fee estimate + submit),MultisigProposalCancelledEvent/PendingMultisigCancellationEvent, indexer GraphQL for cancelled proposals, and lookup by extrinsic hash.App: Proposers get a Cancel Proposal action on the detail sheet (confirm sheet with fee + biometrics) → optimistic pending state → indexer polling → reconciliation into the proposer’s activity. Pending cancellations feed activity lists, effective balance (member cost), deduplication in
combineAndDeduplicateTransactions, toasts on submit failure/timeout, and EN/ID strings.Proposal detail UI is refactored so primary actions and status notes are separate; cancelled/executed terminal proposals hide action buttons.
Reviewed by Cursor Bugbot for commit c9c6792. Configure here.