Skip to content

feat(bond): support anti-abuse bond payout claim flow#595

Open
Catrya wants to merge 2 commits into
mainfrom
AddBondInvoice
Open

feat(bond): support anti-abuse bond payout claim flow#595
Catrya wants to merge 2 commits into
mainfrom
AddBondInvoice

Conversation

@Catrya
Copy link
Copy Markdown
Member

@Catrya Catrya commented May 15, 2026

  • Parse Payload::BondPayoutRequest and new Action.addBondInvoice (mostro-core 0.11.3); Order.fromJson accepts status: null.
  • New /add_bond_invoice/:orderId screen with NWC autopay + manual bolt11 fallback; deadline computed from slashed_at
  • bond_payout_claim_window_days (kind-38385).
  • Cobra tu parte chip in My Trades and COBRAR button in Trade Detail; FSM preserves trade status so the bond flow doesn't wipe it.
  • sendBondInvoice service/notifier methods, dedicated stream provider, session navigation, and reusable info-event tag parser.
  • Localization keys across en/es/it (real) and de/fr (placeholder); unit tests for payload, dispatcher, enum decoding, and info-event parser.

Summary by CodeRabbit

  • New Features

    • Introduced bond invoice submission feature, enabling users to claim their share of slashed bonds after winning a dispute. Supports both automatic Lightning wallet integration and manual invoice entry with configurable claim deadlines.
  • Localization

    • Added complete translation support for the bond dispute resolution flow across English, German, Spanish, French, and Italian.

Review Change Stack

  - Parse Payload::BondPayoutRequest and new Action.addBondInvoice (mostro-core 0.11.3); Order.fromJson accepts
  status: null.
  - New /add_bond_invoice/:orderId screen with NWC autopay + manual bolt11 fallback; deadline computed from slashed_at
   + bond_payout_claim_window_days (kind-38385).
  - Cobra tu parte chip in My Trades and COBRAR button in Trade Detail; FSM preserves trade status so the bond flow
  doesn't wipe it.
  - sendBondInvoice service/notifier methods, dedicated stream provider, session navigation, and reusable info-event
  tag parser.
  - Localization keys across en/es/it (real) and de/fr (placeholder); unit tests for payload, dispatcher, enum
  decoding, and info-event parser.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 15, 2026

Warning

Rate limit exceeded

@Catrya has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 18 minutes and 53 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 79c73079-bf71-4adf-9634-0baa0c0ab399

📥 Commits

Reviewing files that changed from the base of the PR and between aed7457 and ee92f46.

📒 Files selected for processing (1)
  • lib/shared/providers/mostro_storage_provider.dart

Walkthrough

This PR implements end-to-end support for claiming a slashed anti-abuse bond after winning a dispute. It introduces new data models, service methods, state machine transitions, a complete bond-claim screen with NWC integration, routing infrastructure, and localized UI messaging across five languages.

Changes

Anti-Abuse Bond Claim Feature

Layer / File(s) Summary
Data Models & Action Enum
lib/data/models/bond_payout_request.dart, lib/data/models.dart, lib/data/models/enums/action.dart, lib/data/models/order.dart, lib/data/models/payload.dart
Introduces BondPayoutRequest payload model with Order and slashedAt timestamp, and JSON (de)serialization including order unwrapping and flexible slashed_at type handling. Adds Action.addBondInvoice enum constant and makes Order.status optional with Status.pending default. Extends Payload.fromJson to dispatch bond_payout_request keys to BondPayoutRequest.
MostroInstance Bond Claim Configuration
lib/features/mostro/mostro_instance.dart
Extends MostroInstance with nullable bondPayoutClaimWindowDays field read from Nostr daemon event tags via new _getOptionalTagValue helper and NostrEvent.bondPayoutClaimWindowDays extension getter using safe int.tryParse.
MostroService Bond Integration
lib/services/mostro_service.dart
Adds sendBondInvoice method that publishes Action.addBondInvoice DM with PaymentRequest payload. Also defaults MostroMessage.timestamp from decryptedEvent.createdAt when null.
Bond Payout Request Provider
lib/shared/providers/mostro_storage_provider.dart
Introduces mostroBondPayoutRequestStreamProvider to stream the latest MostroMessage containing a BondPayoutRequest for a given orderId.
Order State FSM & Event Handling
lib/features/order/models/order_state.dart, lib/features/order/notifiers/abstract_mostro_notifier.dart, lib/features/order/notifiers/order_notifier.dart
OrderState permits Action.addBondInvoice when order is Status.canceled. AbstractMostroNotifier routes BondPayoutRequest events to /add_bond_invoice/<orderId>. OrderNotifier.sendBondInvoice forwards submissions to service.
AddBondInvoiceScreen Implementation
lib/features/order/screens/add_bond_invoice_screen.dart
New ConsumerStatefulWidget watches bond payout request and NWC state, computes deadline from slashedAt plus claim-window days, and toggles between NWC-based and manual invoice entry UI. On success navigates to /, on error shows snackbar.
Route & Notification Routing
lib/core/app_routes.dart, lib/features/notifications/widgets/notification_item.dart
Registers /add_bond_invoice/:orderId route and maps notification taps for Action.addBondInvoice to the new screen.
Action UI Integration
lib/features/notifications/utils/notification_message_mapper.dart, lib/features/trades/screens/trade_detail_screen.dart, lib/features/trades/widgets/mostro_message_detail_widget.dart, lib/features/trades/widgets/trades_list_item.dart
Maps action to invoice localization keys, adds action button in trade detail screen, renders action text in message detail, and displays dedicated bond-claim chip in trades list.
Tests & Localization
integration_test/test_helpers.dart, test/data/models/bond_payout_request_test.dart, test/data/models/enums/action_test.dart, test/features/mostro/mostro_instance_test.dart, test/models/order_test.dart, lib/l10n/intl_*.arb (5 files)
Adds FakeMostroService.sendBondInvoice stub, comprehensive tests for model parsing/dispatch/round-trip and extension parsing with null-safety. Adds bond-claim UI strings across English, Spanish, German, French, and Italian with placeholders for order ID, amount, date, and error messages.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

  • MostroP2P/mobile#591: Directly implements the anti-abuse bond claim feature with all new Action/model/service/UI/storage components described in the issue scope.

Possibly related PRs

  • MostroP2P/mobile#592: Both PRs extend the same bond-action plumbing (NotificationMessageMapper, NotificationItem tap routing, OrderState action/status mapping, AbstractMostroNotifier navigation) but for different Action enum values (addBondInvoice vs payBondInvoice).
  • MostroP2P/mobile#310: Both PRs modify lib/features/order/notifiers/abstract_mostro_notifier.dart to extend Mostro action/event handling logic with new routing branches.
  • MostroP2P/mobile#116: Both PRs modify lib/features/trades/widgets/trades_list_item.dart to extend UI rendering (retrieved PR refactors role/status chip layout; main PR adds bond-claim chip via _buildBondClaimChip).

Suggested reviewers

  • AndreaDiazCorreia
  • mostronatorcoder
  • BraCR10

Poem

🐰 A bond once slashed now claims its share,
invoices sent through Lightning's air,
when disputes are won, the rabbit hops,
through screens and states until it stops!
thump thump 🌙

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(bond): support anti-abuse bond payout claim flow' accurately and concisely summarizes the main change—implementing a new bond payout claim feature with a dedicated screen, service methods, and UI support.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch AddBondInvoice

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 and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (4)
test/data/models/bond_payout_request_test.dart (1)

1-3: ⚡ Quick win

Use the aggregated models barrel import.

Switch these model imports to package:mostro_mobile/data/models.dart to match repository import conventions.

♻️ Proposed change
-import 'package:mostro_mobile/data/models/bond_payout_request.dart';
-import 'package:mostro_mobile/data/models/order.dart';
-import 'package:mostro_mobile/data/models/payload.dart';
+import 'package:mostro_mobile/data/models.dart';

As per coding guidelines: "Import models through data/models.dart instead of importing individual model files".

🤖 Prompt for 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.

In `@test/data/models/bond_payout_request_test.dart` around lines 1 - 3, Replace
the three individual model imports in bond_payout_request_test.dart (imports of
bond_payout_request, order, payload) with the aggregated models barrel import by
importing package:mostro_mobile/data/models.dart; update any references to
BondPayoutRequest, Order, Payload remain unchanged since they are re-exported
from the barrel so no other code changes are needed.
test/data/models/enums/action_test.dart (1)

1-1: ⚡ Quick win

Use data/models.dart instead of importing enum files directly.

Please replace the direct Action import with the shared models barrel import for consistency with project conventions.

♻️ Proposed change
-import 'package:mostro_mobile/data/models/enums/action.dart';
+import 'package:mostro_mobile/data/models.dart';

As per coding guidelines: "Import models through data/models.dart instead of importing individual model files".

🤖 Prompt for 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.

In `@test/data/models/enums/action_test.dart` at line 1, Replace the direct enum
import of Action with the project's models barrel: in
test/data/models/enums/action_test.dart remove the import
'package:mostro_mobile/data/models/enums/action.dart' and import the shared
barrel 'package:mostro_mobile/data/models.dart' instead so the test uses Action
via the consolidated models export; update any references to Action remain
unchanged.
lib/features/order/screens/add_bond_invoice_screen.dart (1)

5-5: ⚡ Quick win

Use the models barrel import for BondPayoutRequest.

This import bypasses the project’s model import convention.

♻️ Proposed fix
-import 'package:mostro_mobile/data/models/bond_payout_request.dart';
+import 'package:mostro_mobile/data/models.dart';

As per coding guidelines: "Import models through data/models.dart instead of importing individual model files".

🤖 Prompt for 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.

In `@lib/features/order/screens/add_bond_invoice_screen.dart` at line 5, Replace
the direct model import of BondPayoutRequest with the project's models barrel
import: remove the import
'package:mostro_mobile/data/models/bond_payout_request.dart' in
add_bond_invoice_screen.dart and add the barrel import
'package:mostro_mobile/data/models.dart' so references to BondPayoutRequest
continue to resolve via the models.dart export; ensure no other individual model
imports remain in that file.
lib/features/trades/widgets/trades_list_item.dart (1)

6-6: ⚡ Quick win

Switch this enum import to the data/models.dart barrel.

This new import bypasses the repository model import convention.

♻️ Proposed fix
-import 'package:mostro_mobile/data/models/enums/action.dart' as mostro_action;
+import 'package:mostro_mobile/data/models.dart' as mostro_models;
-                        orderState.action == mostro_action.Action.addBondInvoice
+                        orderState.action == mostro_models.Action.addBondInvoice

As per coding guidelines: "Import models through data/models.dart instead of importing individual model files".

🤖 Prompt for 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.

In `@lib/features/trades/widgets/trades_list_item.dart` at line 6, The file
imports the enum directly from action.dart (import
'package:mostro_mobile/data/models/enums/action.dart' as mostro_action;); change
this to import the models barrel instead by replacing that direct enum import
with a single import from 'package:mostro_mobile/data/models.dart' and update
any usages that reference mostro_action to use the same symbol from the barrel
(e.g., Action or mostro_action if you keep the alias) so the code follows the
repository convention of importing models from data/models.dart.
🤖 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 `@lib/features/order/screens/add_bond_invoice_screen.dart`:
- Line 109: Replace the hardcoded error text in the error builder (currently
"Center(child: Text('Error: \$e'))" in add_bond_invoice_screen.dart) with a
localized string: import package:mostro_mobile/generated/l10n.dart, use
S.of(context)! with an appropriate key (e.g. errorWithDetails or genericError)
and pass the error message (e.toString()) to that localized formatter; update or
add the localization key in your ARB/intl resources if it doesn't exist, then
use that S.of(context)!.key in the error branch so the UI is fully localized.

In `@lib/shared/providers/mostro_storage_provider.dart`:
- Around line 2-4: Replace the three individual model imports in
mostro_storage_provider.dart (the imports for bond_payout_request.dart,
mostro_message.dart, and order.dart) with the single barrel import
package:mostro_mobile/data/models.dart; update the import section in the file so
the provider uses the consolidated models.dart export instead of per-model
imports (no code changes needed elsewhere).

---

Nitpick comments:
In `@lib/features/order/screens/add_bond_invoice_screen.dart`:
- Line 5: Replace the direct model import of BondPayoutRequest with the
project's models barrel import: remove the import
'package:mostro_mobile/data/models/bond_payout_request.dart' in
add_bond_invoice_screen.dart and add the barrel import
'package:mostro_mobile/data/models.dart' so references to BondPayoutRequest
continue to resolve via the models.dart export; ensure no other individual model
imports remain in that file.

In `@lib/features/trades/widgets/trades_list_item.dart`:
- Line 6: The file imports the enum directly from action.dart (import
'package:mostro_mobile/data/models/enums/action.dart' as mostro_action;); change
this to import the models barrel instead by replacing that direct enum import
with a single import from 'package:mostro_mobile/data/models.dart' and update
any usages that reference mostro_action to use the same symbol from the barrel
(e.g., Action or mostro_action if you keep the alias) so the code follows the
repository convention of importing models from data/models.dart.

In `@test/data/models/bond_payout_request_test.dart`:
- Around line 1-3: Replace the three individual model imports in
bond_payout_request_test.dart (imports of bond_payout_request, order, payload)
with the aggregated models barrel import by importing
package:mostro_mobile/data/models.dart; update any references to
BondPayoutRequest, Order, Payload remain unchanged since they are re-exported
from the barrel so no other code changes are needed.

In `@test/data/models/enums/action_test.dart`:
- Line 1: Replace the direct enum import of Action with the project's models
barrel: in test/data/models/enums/action_test.dart remove the import
'package:mostro_mobile/data/models/enums/action.dart' and import the shared
barrel 'package:mostro_mobile/data/models.dart' instead so the test uses Action
via the consolidated models export; update any references to Action remain
unchanged.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6ed9d43c-641a-46dd-a0ce-7be12c66062e

📥 Commits

Reviewing files that changed from the base of the PR and between 48d4bb5 and aed7457.

📒 Files selected for processing (28)
  • integration_test/test_helpers.dart
  • lib/core/app_routes.dart
  • lib/data/models.dart
  • lib/data/models/bond_payout_request.dart
  • lib/data/models/enums/action.dart
  • lib/data/models/order.dart
  • lib/data/models/payload.dart
  • lib/features/mostro/mostro_instance.dart
  • lib/features/notifications/utils/notification_message_mapper.dart
  • lib/features/notifications/widgets/notification_item.dart
  • lib/features/order/models/order_state.dart
  • lib/features/order/notifiers/abstract_mostro_notifier.dart
  • lib/features/order/notifiers/order_notifier.dart
  • lib/features/order/screens/add_bond_invoice_screen.dart
  • lib/features/trades/screens/trade_detail_screen.dart
  • lib/features/trades/widgets/mostro_message_detail_widget.dart
  • lib/features/trades/widgets/trades_list_item.dart
  • lib/l10n/intl_de.arb
  • lib/l10n/intl_en.arb
  • lib/l10n/intl_es.arb
  • lib/l10n/intl_fr.arb
  • lib/l10n/intl_it.arb
  • lib/services/mostro_service.dart
  • lib/shared/providers/mostro_storage_provider.dart
  • test/data/models/bond_payout_request_test.dart
  • test/data/models/enums/action_test.dart
  • test/features/mostro/mostro_instance_test.dart
  • test/models/order_test.dart

Comment thread lib/features/order/screens/add_bond_invoice_screen.dart
Comment thread lib/shared/providers/mostro_storage_provider.dart Outdated
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.

1 participant