Skip to content

Remove hard 5000sats min send limit#810

Merged
praveenperera merged 17 commits into
masterfrom
remove-send-limit
Jul 3, 2026
Merged

Remove hard 5000sats min send limit#810
praveenperera merged 17 commits into
masterfrom
remove-send-limit

Conversation

@praveenperera

@praveenperera praveenperera commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Summary

Replaces Cove's 5000-sat hard send floor with finalize-time warnings for small
on-chain payments and high fee percentages.

Rust now owns the warning state, acknowledgement flow, reset behavior, and hard
validation ordering. BDK transaction construction remains authoritative for
recipient dust rejection, which is mapped to a friendly cross-platform dust
error.

iOS and Android render the new warning alerts, dispatch Send Anyway back to
Rust, use the conservative dust fallback for coin-control floors, and consume
regenerated UniFFI bindings.

Verification

  • cargo test -p cove --lib send_flow_manager
  • cargo test -p cove --lib create_tx_
  • cargo test -p cove --lib actor_manual_max_send_uses_recipient_exact_dust_floor
  • just fmt
  • just clippy
  • just build-ios
  • just build-android
  • just compile-ios
  • just compile-android
  • git diff --check

Summary by CodeRabbit

  • New Features
    • Added new send-flow warning dialogs for low amounts and high fees, including Send Anyway with warning acknowledgements.
  • Bug Fixes
    • Updated send validation to no longer block on fee-percentage checks (warnings gate the flow instead).
    • Refined dust-limit handling across amount and coin-control screens, including slider defaults and continue-button enablement.
    • Improved warning/alert dismiss and button behavior (including “Cancel” for warnings) and updated “below dust limit” messaging.
  • Tests
    • Added unit coverage for “fee too high” error classification used in custom fee UI.

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 44627080-2666-4ca9-a032-649914529bd2

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR replaces fixed minimum-send values with shared low-send warning and conservative dust-limit constants, adds warning acknowledgement state and alert variants, updates send-flow validation and finalization, and remaps dust-limit transaction errors.

Changes

Send-flow warning and dust-limit alignment

Layer / File(s) Summary
Shared threshold exports
rust/crates/cove-common/src/consts.rs, rust/src/wallet/ffi.rs, ios/Cove/Constants.swift
Common Rust constants, wallet FFI exports, and iOS constants now expose low-send warning and conservative dust-limit values.
Threshold consumers
android/app/src/main/java/org/bitcoinppl/cove/flows/SendFlow/CoinControlCustomAmountSheet.kt, ios/Cove/Flows/CoinControlFlow/UtxoListScreen.swift, ios/Cove/Flows/SendFlow/Common/SendFlowUtxoCustomAmountSheetView.swift
Coin-control and custom-amount screens use conservative dust limits for bounds and button state.
Wallet dust-limit errors
rust/src/manager/wallet_manager.rs, rust/src/manager/wallet_manager/actor/transactions.rs, rust/src/manager/wallet_manager/actor.rs
Wallet transaction creation maps dust-limit and coin-selection failures to new error variants, and max-send tests expect those variants.
Send-flow warning core
rust/src/manager/send_flow_manager/alert_state.rs, rust/src/manager/send_flow_manager/state.rs, rust/src/manager/send_flow_manager/error.rs, rust/src/manager/send_flow_manager.rs
Send-flow alert state gains warning kinds, warning acknowledgement tracking, warning validation flow, and pending-warning finalization logic.
Amount and fee flow
rust/src/manager/send_flow_manager/amount_input.rs, rust/src/manager/send_flow_manager/fee_selection.rs, rust/src/manager/send_flow_manager/finalize.rs
Amount and fee handlers clear warning acknowledgements on edits, use low-send warning sats for fee calculations, and populate missing total fees before finalization.
Address and coin-control flow
rust/src/manager/send_flow_manager/address_input.rs, rust/src/manager/send_flow_manager/coin_control.rs
Address and coin-control state changes clear warning acknowledgements, and coin-control input parsing uses the conservative dust limit.
Alert presentation and warning actions
android/app/src/main/java/org/bitcoinppl/cove/flows/SendFlow/SendFlowContainer.kt, android/app/src/main/java/org/bitcoinppl/cove/flows/SendFlow/SendFlowManager.kt, android/app/src/main/java/org/bitcoinppl/cove/flows/SendFlow/SendFlowPresenter.kt, ios/Cove/Flows/SendFlow/SendFlowManager.swift, ios/Cove/Flows/SendFlow/SendFlowPresenter.swift, ios/Cove/Flows/SendFlow/SendFlowSetAmountScreen.swift, ios/Cove/Flows/SendFlow/SendFlowCoinControlSetAmountScreen.swift
Android and iOS alert presentations branch on warning state, surface warning-specific copy and buttons, and dispatch acknowledge-and-finalize actions through the send-flow managers.
Custom fee error classification
android/app/src/main/java/org/bitcoinppl/cove/sheets/CustomFeeRateSheet.kt, android/app/src/test/java/org/bitcoinppl/cove/sheets/CustomFeeRateSheetTest.kt, ios/Cove/Flows/SendFlow/SendFlowCustomFeeRateView.swift, ios/CoveTests/CustomFeeRateErrorTests.swift, ios/Cove.xcodeproj/project.pbxproj
Custom-fee sheets classify insufficient-funds errors for fee handling, and the matching tests verify that classification.

Sequence Diagram(s)

sequenceDiagram
  participant SendFlowSetAmountScreen
  participant SendFlowPresenter
  participant SendFlowManager
  SendFlowSetAmountScreen->>SendFlowPresenter: alertButtons(alert)
  SendFlowPresenter->>SendFlowManager: dispatch(.AcknowledgeWarningAndFinalize(kind))
  SendFlowManager->>SendFlowManager: finalize_and_go_to_next_screen()
  SendFlowManager->>SendFlowPresenter: clearAlert()
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested labels

android

Poem

🐇 I sniffed a dust limit in the clover,
and hopped where warning bells rang over.
“Send anyway” twinkled bright,
then fee totals clicked just right —
a moonlit hop, and the path rolled over.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The summary and testing notes are solid, but the required Platform Coverage and Checklist sections are missing. Add the Platform Coverage checkboxes and the Checklist items for CONTRIBUTING.md and ARCHITECTURE.md to match the template.
Docstring Coverage ⚠️ Warning Docstring coverage is 47.06% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title matches the main change: replacing the hard 5000-sat send floor with warning-based flow.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch remove-send-limit

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@praveenperera praveenperera changed the title Warn before small on-chain sends Remove hard 5000sats min send limit Jun 25, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 027a2ea8f0

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +38 to +42
if me.selected_fee_rate().and_then(|fee| fee.total_fee).is_none() {
return me
.send_alert_async(SendFlowError::UnableToGetFeeDetails(
"selected fee total unavailable".to_string(),
))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Return the dust error when fee totals are unavailable

When the selected fee option has no total_fee (common on a fresh flow before totals are calculated), a below-dust amount makes get_or_update_fee_rate_options() fail to populate totals because BDK rejects the candidate output. This branch then surfaces UnableToGetFeeDetails("selected fee total unavailable") and returns before confirm_txn can map BDK's OutputBelowDustLimit into the new friendly dust error, so users sending e.g. 1 sat see a misleading fee-details failure instead of the intended dust-limit guidance.

Useful? React with 👍 / 👎.

@greptile-apps

greptile-apps Bot commented Jun 25, 2026

Copy link
Copy Markdown

Greptile Summary

This PR moves small on-chain sends from hard limits to warning and dust-validation flows. The main changes are:

  • Rust-owned small-send and high-fee warning state.
  • Address-specific dust rejection mapped into send-flow errors.
  • Android and iOS warning dialogs with Send Anyway actions.
  • Updated coin-control amount handling and regenerated bindings.

Confidence Score: 4/5

This is close, but the iOS coin-control gate should be fixed before merging.

  • Rust now preserves low coin-control amounts and relies on address-specific dust validation.
  • Android warning sequencing has a delay path for follow-up alerts after dismissal.
  • iOS still blocks sub-546-sat coin-control selections before the send flow can validate them with the recipient address.

ios/Cove/Flows/CoinControlFlow/UtxoListScreen.swift

Important Files Changed

Filename Overview
rust/src/manager/send_flow_manager/coin_control.rs Removes the Rust-side hard minimum clamp and preserves low manual coin-control amounts unless fee changes exceed the available maximum.
rust/src/manager/send_flow_manager/finalize.rs Adds finalize-time warning checks and maps transaction-build dust failures into send-flow alerts.
android/app/src/main/java/org/bitcoinppl/cove/flows/SendFlow/SendFlowContainer.kt Adds Send Anyway and Cancel handling for warning alerts.
ios/Cove/Flows/CoinControlFlow/UtxoListScreen.swift Updates the coin-control Continue button to use the conservative dust fallback, but still hard-blocks lower valid selections.

Reviews (5): Last reviewed commit: "Recheck send snapshot before PSBT result" | Re-trigger Greptile

Comment thread rust/src/manager/send_flow_manager/coin_control.rs Outdated
@praveenperera

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@praveenperera

Copy link
Copy Markdown
Contributor Author

@greptileai

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Comment thread rust/src/manager/send_flow_manager/coin_control.rs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@android/app/src/main/java/org/bitcoinppl/cove/flows/SendFlow/CoinControlCustomAmountSheet.kt`:
- Around line 76-81: The max send calculation in CoinControlCustomAmountSheet
can collapse the slider range to a single point when maxSendMinusFees() returns
a value at or below minSend. Update the maxSend logic so it is clamped to a real
upper bound like conservativeDustLimitSatsU + 1_000uL (matching the iOS
behavior) rather than only coerceAtLeast(minSend), and keep the Slider
valueRange in sync with that safer bound.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 255cf688-e98a-4434-be4a-f99966a14472

📥 Commits

Reviewing files that changed from the base of the PR and between f120549 and 95b68ab.

⛔ Files ignored due to path filters (2)
  • android/app/src/main/java/org/bitcoinppl/cove_core/cove.kt is excluded by !android/app/src/main/java/org/bitcoinppl/cove_core/**
  • ios/CoveCore/Sources/CoveCore/generated/cove.swift is excluded by !**/generated/**, !ios/CoveCore/Sources/CoveCore/generated/**
📒 Files selected for processing (25)
  • android/app/src/main/java/org/bitcoinppl/cove/flows/SendFlow/CoinControlCustomAmountSheet.kt
  • android/app/src/main/java/org/bitcoinppl/cove/flows/SendFlow/SendFlowContainer.kt
  • android/app/src/main/java/org/bitcoinppl/cove/flows/SendFlow/SendFlowManager.kt
  • android/app/src/main/java/org/bitcoinppl/cove/flows/SendFlow/SendFlowPresenter.kt
  • ios/Cove/Constants.swift
  • ios/Cove/Flows/CoinControlFlow/UtxoListScreen.swift
  • ios/Cove/Flows/SendFlow/Common/SendFlowUtxoCustomAmountSheetView.swift
  • ios/Cove/Flows/SendFlow/SendFlowCoinControlSetAmountScreen.swift
  • ios/Cove/Flows/SendFlow/SendFlowManager.swift
  • ios/Cove/Flows/SendFlow/SendFlowPresenter.swift
  • ios/Cove/Flows/SendFlow/SendFlowSetAmountScreen.swift
  • rust/crates/cove-common/src/consts.rs
  • rust/src/manager/send_flow_manager.rs
  • rust/src/manager/send_flow_manager/address_input.rs
  • rust/src/manager/send_flow_manager/alert_state.rs
  • rust/src/manager/send_flow_manager/amount_input.rs
  • rust/src/manager/send_flow_manager/coin_control.rs
  • rust/src/manager/send_flow_manager/error.rs
  • rust/src/manager/send_flow_manager/fee_selection.rs
  • rust/src/manager/send_flow_manager/finalize.rs
  • rust/src/manager/send_flow_manager/state.rs
  • rust/src/manager/wallet_manager.rs
  • rust/src/manager/wallet_manager/actor.rs
  • rust/src/manager/wallet_manager/actor/transactions.rs
  • rust/src/wallet/ffi.rs

@praveenperera

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@praveenperera

Copy link
Copy Markdown
Contributor Author

@greptileai

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Comment thread rust/src/manager/send_flow_manager/coin_control.rs Outdated
@praveenperera

praveenperera commented Jun 30, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the remaining review findings through 2b2e701d.

Changes:

  • Fixed Android alert re-presentation while a previous alert is dismissing.
  • Fixed exact-dust coin-control slider bounds on Android and iOS.
  • Verified the conservative dust UniFFI symbols are present in generated bindings and native artifacts.
  • Removed the conservative 546-sat clamp from coin-control amount entry so 294-545 sat values remain available for recipient-specific dust validation.
  • Preserved low coin-control entries when the small-UTXO snap threshold is unavailable.
  • Kept above-max selected-coin entries in max mode while validating against the fee-adjusted recipient amount.
  • Avoided zero-amount snaps while fee totals are still loading.
  • Capped preserved coin-control edits once real fee totals arrive.
  • Preserved positive manual amounts when the fee-adjusted selected-coin cap is zero so the send flow uses the fee-too-high path.
  • Blocked coin-control sends when selected fees exhaust the selected coins.
  • Guarded async fallback finalization against stale amount, address, mode, or fee-choice snapshots before handling fallback PSBT success or error results.

Verification passed:

  • just build-ios
  • just build-android
  • just fmt
  • just clippy
  • just compile-ios
  • just compile-android
  • git diff --check
  • cargo test
  • cargo test -p cove coin_control
  • cargo test -p cove finalize_snapshot
  • Android dev debug Kotlin compile and unit tests
  • GitHub PR checks for 2b2e701d

Final review passes:

  • Codex xhigh: no actionable findings
  • Claude: no actionable findings
  • CodeRabbit CLI: current-head retry was blocked by the free OSS rate limit; the latest completed CodeRabbit CLI pass on cfb7dd7f had zero findings, and GitHub reports the CodeRabbit check passing/skipped on 2b2e701d.

@praveenperera praveenperera added the review-complete Review complete, ready to merge label Jun 30, 2026
Comment thread rust/src/manager/send_flow_manager/coin_control.rs Outdated
@praveenperera praveenperera force-pushed the remove-send-limit branch 3 times, most recently from 1c8f9bb to 9d4a15b Compare July 3, 2026 19:45
Replace the 5000-sat hard floor with Rust-owned finalize warnings, keep BDK dust rejection as the hard policy, and update generated iOS and Android bindings plus platform alert handling.
Surface BDK dust failures when fee totals cannot be refreshed.
Update locked-output tests for the new insufficient-funds mapping.
Delay chained iOS alerts during dismissal.
Handle exact-dust max-send slider bounds on both mobile platforms and delay Android alert re-presentation while an existing alert is dismissing.
Let coin-control amount entry keep values below the conservative dust fallback so recipient-specific dust validation can decide whether the send is valid.
Let coin-control amount updates continue when the max-send snap threshold cannot be computed, so small selected coin sets still preserve the user's entered amount for later dust validation.
Keep coin-control entries above the fee-adjusted selected-coin max in max mode when the small-UTXO snap threshold is unavailable.
Abort the async fee fallback when the amount, address, mode, or fee choice changed while fee totals were loading.

Also block coin-control sends when the selected fee exhausts the selected coins.
Comment on lines +244 to +257
@@ -254,7 +254,7 @@ struct UtxoListScreen: View {
.frame(maxWidth: .infinity)
.padding(.horizontal)
.padding(.bottom, 4)
.disabled(manager.totalSelectedSats < minSendSats)
.disabled(manager.totalSelectedSats < conservativeDustLimitSats)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Static Floor Blocks Sends This still disables the iOS coin-control Continue button for any selected total below conservativeDustLimitSats. A user with a 300-sat selection cannot enter the send flow, even though that amount can be valid for lower-dust recipient scripts once the address is entered and BDK applies the script-specific dust check. This leaves a hard 546-sat platform gate in front of the new finalize-time validation path.

Updated `UtxoListScreen` to use a new `canContinue` computed property for the Continue button state and styling. The button is now enabled when there is at least one selected UTXO and the selected total is greater than zero, instead of being blocked by the conservative dust-limit threshold.
@praveenperera praveenperera enabled auto-merge (squash) July 3, 2026 20:40
@praveenperera praveenperera merged commit 0cabe57 into master Jul 3, 2026
9 checks passed
@praveenperera praveenperera deleted the remove-send-limit branch July 3, 2026 20:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review-complete Review complete, ready to merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant