Skip to content

Conversation

@chebizarro
Copy link
Contributor

@chebizarro chebizarro commented Jul 25, 2025

This PR adds basic support for the PaymentFailure and NextTrade payload types recently added to the mostro protocol

Users notifications and the Order Details views will now display the number of retry attempts correctly in the event of a PaymentFailure

These changes should be backwards compatible with earlier mostrod versions

Summary by CodeRabbit

  • New Features

    • Added support for displaying detailed information when a payment fails, including the number of attempts and retry intervals.
    • Introduced new message types for handling upcoming trades and failed payments.
    • Added a new "Payment Failed" status with corresponding actions for buyers and sellers.
  • Improvements

    • Payment failure messages now show actual attempt and retry values instead of placeholders, providing more accurate and informative feedback to users.
    • Updated order status indicators and transitions to reflect payment failure state.
    • Action buttons are now suppressed during payment failure state, showing only the Close button to avoid confusion.
    • Enhanced UI padding to better accommodate device safe areas across multiple screens.
    • Refined dialog button layouts and spacing for a cleaner and more consistent user interface.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 25, 2025

Walkthrough

New Dart model classes NextTrade and PaymentFailed are introduced, both implementing the Payload interface. The Payload.fromJson factory is extended to support these types. The OrderState model and related UI logic are updated to handle the PaymentFailed payload, ensuring dynamic data propagation through state, notification, and widget layers. The state machine and UI components are enhanced to reflect the new paymentFailed status and associated actions. Localization strings for the new status are added.

Changes

File(s) Change Summary
New Models
lib/data/models/next_trade.dart, lib/data/models/payment_failed.dart
Added new model classes: NextTrade and PaymentFailed, both implementing Payload with serialization logic.
Payload Factory Update
lib/data/models/payload.dart
Updated Payload.fromJson to support payment_failed and next_trade types; added necessary imports.
Order State Enhancements
lib/features/order/models/order_state.dart
Added paymentFailed field to OrderState and integrated it into constructors, state updates, equality, and status-action mappings.
Notifier Event Handling
lib/features/order/notfiers/abstract_mostro_notifier.dart
Updated event handling for paymentFailed to use dynamic values from PaymentFailed payload.
UI Updates - Message Details
lib/features/trades/widgets/mostro_message_detail_widget.dart
Updated _getActionText to display actual PaymentFailed data from provider instead of static placeholders.
UI Updates - Trade Detail Screen
lib/features/trades/screens/trade_detail_screen.dart
Modified _buildActionButtons to suppress action buttons during paymentFailed status, showing only Close button.
UI Updates - Trades List Item
lib/features/trades/widgets/trades_list_item.dart
Added UI rendering for paymentFailed status chip with appropriate colors and label.
State Machine Transitions
lib/core/mostro_fsm.dart
Added transitions for paymentFailed status and related actions for buyer and seller roles.
Status Enum Update
lib/data/models/enums/status.dart
Added new enum value paymentFailed with string 'payment-failed'.
Localization Strings
lib/l10n/intl_en.arb, lib/l10n/intl_es.arb, lib/l10n/intl_it.arb
Added new localization string key paymentFailedText with translations in English, Spanish, and Italian.
Model Exports
lib/data/models.dart
Exported the new model files payment_failed.dart and next_trade.dart.

Sequence Diagram(s)

sequenceDiagram
    participant EventSource
    participant Notifier
    participant OrderState
    participant UI

    EventSource->>Notifier: Receives event with payment_failed payload
    Notifier->>OrderState: Updates state with PaymentFailed instance
    OrderState->>UI: Provides paymentFailed data via provider
    UI->>UI: Renders details using paymentAttempts and paymentRetriesInterval
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~18 minutes

Possibly related PRs

Suggested reviewers

  • chebizarro

Poem

🐇
New models hop in, with fields so neat,
Payment failures tracked, no more defeat.
Order states updated, details now true,
Widgets display facts, not just a clue.
Code grows smarter, as rabbits cheer—
Onward we bound, with changes clear!

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 92d8b23 and b5f40df.

📒 Files selected for processing (4)
  • lib/features/trades/widgets/mostro_message_detail_widget.dart (2 hunks)
  • lib/l10n/intl_en.arb (2 hunks)
  • lib/l10n/intl_es.arb (2 hunks)
  • lib/l10n/intl_it.arb (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • lib/l10n/intl_es.arb
  • lib/features/trades/widgets/mostro_message_detail_widget.dart
  • lib/l10n/intl_it.arb
  • lib/l10n/intl_en.arb
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch payment-failed

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
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: 1

🧹 Nitpick comments (1)
lib/features/order/models/order_state.dart (1)

4-4: Consider using the barrel export instead of direct import.

Since PaymentFailed should be exported through data/models.dart (line 2), you can remove this direct import if the model is properly exported in the barrel file.

-import 'package:mostro_mobile/data/models/payment_failed.dart';
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bb3cae0 and 3a635e2.

📒 Files selected for processing (6)
  • lib/data/models/next_trade.dart (1 hunks)
  • lib/data/models/payload.dart (2 hunks)
  • lib/data/models/payment_failed.dart (1 hunks)
  • lib/features/order/models/order_state.dart (9 hunks)
  • lib/features/order/notfiers/abstract_mostro_notifier.dart (2 hunks)
  • lib/features/trades/widgets/mostro_message_detail_widget.dart (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
lib/**/*.dart

📄 CodeRabbit Inference Engine (CLAUDE.md)

lib/**/*.dart: Use S.of(context).yourKey for all user-facing strings
Always check mounted before using context after async operations

Files:

  • lib/features/trades/widgets/mostro_message_detail_widget.dart
  • lib/features/order/notfiers/abstract_mostro_notifier.dart
  • lib/data/models/next_trade.dart
  • lib/data/models/payment_failed.dart
  • lib/features/order/models/order_state.dart
  • lib/data/models/payload.dart
**/*.dart

📄 CodeRabbit Inference Engine (CLAUDE.md)

**/*.dart: Remove unused imports and dependencies
Use const constructors where possible

Files:

  • lib/features/trades/widgets/mostro_message_detail_widget.dart
  • lib/features/order/notfiers/abstract_mostro_notifier.dart
  • lib/data/models/next_trade.dart
  • lib/data/models/payment_failed.dart
  • lib/features/order/models/order_state.dart
  • lib/data/models/payload.dart
🧠 Learnings (7)
📓 Common learnings
Learnt from: chebizarro
PR: MostroP2P/mobile#74
File: lib/features/trades/models/trade_state.dart:1-15
Timestamp: 2025-05-08T16:06:33.665Z
Learning: In the context of the Mostro Mobile app, the `TradeState` class is specifically constructed using the `tradeStateProvider`. While some fields are nullable (`lastAction` and `orderPayload`), they are still marked as required parameters to ensure they are explicitly considered during state construction.
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to lib/core/mostro_fsm.dart : Order state transitions are managed by `core/mostro_fsm.dart`
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to lib/data/models.dart : Models should be exported through `data/models.dart`
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to lib/features/*/notifiers/**/*.dart : Notifiers for complex state logic are placed in `features/{feature}/notifiers/`
Learnt from: chebizarro
PR: MostroP2P/mobile#110
File: test/notifiers/take_order_notifier_test.dart:72-74
Timestamp: 2025-06-04T19:35:20.209Z
Learning: MostroService methods like takeBuyOrder() and takeSellOrder() return Future<void> and trigger side effects through other mechanisms rather than direct return values. When testing these methods, focus on verifying method calls and testing state changes through the provider system rather than mocking return values.
lib/features/trades/widgets/mostro_message_detail_widget.dart (2)

Learnt from: chebizarro
PR: #127
File: lib/features/order/notfiers/abstract_mostro_notifier.dart:45-54
Timestamp: 2025-06-26T15:03:23.529Z
Learning: In AbstractMostroNotifier, state updates occur for all messages regardless of timestamp to hydrate the OrderNotifier from MostroStorage during sync, while handleEvent is only called for recent messages (within 60 seconds) to prevent re-triggering side effects like notifications and navigation for previously handled messages. This design prevents displaying stale notifications when the app is reopened or brought to the foreground.

Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to lib/core/mostro_fsm.dart : Order state transitions are managed by core/mostro_fsm.dart

lib/features/order/notfiers/abstract_mostro_notifier.dart (16)

Learnt from: Catrya
PR: #215
File: lib/features/order/notfiers/order_notifier.dart:0-0
Timestamp: 2025-07-20T23:33:17.689Z
Learning: In AbstractMostroNotifier, the handleEvent method is synchronous and returns void, not Future. Do not suggest adding await to super.handleEvent() calls as this would cause compilation errors.

Learnt from: Catrya
PR: #215
File: lib/features/order/notfiers/order_notifier.dart:0-0
Timestamp: 2025-07-20T23:33:17.689Z
Learning: In AbstractMostroNotifier, the handleEvent method is synchronous and returns void, not Future. Do not suggest adding await to super.handleEvent() calls as this would cause compilation errors.

Learnt from: Catrya
PR: #215
File: lib/features/order/notfiers/order_notifier.dart:0-0
Timestamp: 2025-07-20T23:33:17.689Z
Learning: In AbstractMostroNotifier, the handleEvent method is synchronous and returns void, not Future. Do not suggest adding await to super.handleEvent() calls as this would cause compilation errors.

Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to lib/features//notifiers/**/.dart : Notifiers for complex state logic are placed in features/{feature}/notifiers/

Learnt from: chebizarro
PR: #127
File: lib/features/order/notfiers/abstract_mostro_notifier.dart:45-54
Timestamp: 2025-06-26T15:03:23.529Z
Learning: In AbstractMostroNotifier, state updates occur for all messages regardless of timestamp to hydrate the OrderNotifier from MostroStorage during sync, while handleEvent is only called for recent messages (within 60 seconds) to prevent re-triggering side effects like notifications and navigation for previously handled messages. This design prevents displaying stale notifications when the app is reopened or brought to the foreground.

Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to lib/core/mostro_fsm.dart : Order state transitions are managed by core/mostro_fsm.dart

Learnt from: chebizarro
PR: #74
File: lib/services/mostro_service.dart:70-76
Timestamp: 2025-05-06T15:49:26.443Z
Learning: In the Mostro Mobile codebase, eventStorageProvider is exported from package:mostro_mobile/shared/providers/mostro_service_provider.dart and not from a separate event_storage_provider.dart file.

Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to test/mocks.mocks.dart : DO NOT modify test/mocks.mocks.dart - it already has file-level ignores

Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to lib/data/models/nostr_event.dart : Custom timeAgoWithLocale() method is implemented in the NostrEvent extension

Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to lib/data/models.dart : Models should be exported through data/models.dart

Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to lib/shared/providers/mostro_database_provider.dart : Database initialization is in shared/providers/mostro_database_provider.dart

Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to lib/data/repositories/**/*.dart : All data access should go through repository classes in data/repositories/

Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to lib/features//providers/**/.dart : Providers are organized by feature in features/{feature}/providers/

Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to lib/background/**/*.dart : Background services are implemented in the background/ directory

Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to lib/services/nostr_service.dart : Nostr protocol interactions go through services/nostr_service.dart

Learnt from: chebizarro
PR: #74
File: lib/services/mostro_service.dart:70-76
Timestamp: 2025-05-06T15:49:26.443Z
Learning: In the Mostro Mobile codebase, Riverpod code generation is used with @Riverpod annotations. Providers like eventStorageProvider are generated in .g.dart files from annotated functions in the main provider files. These providers are accessible by importing the main provider file (e.g., mostro_service_provider.dart), not by importing a separate provider file.

lib/data/models/next_trade.dart (3)

Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to lib/data/models.dart : Models should be exported through data/models.dart

Learnt from: chebizarro
PR: #74
File: lib/features/trades/models/trade_state.dart:1-15
Timestamp: 2025-05-08T16:06:33.665Z
Learning: In the context of the Mostro Mobile app, the TradeState class is specifically constructed using the tradeStateProvider. While some fields are nullable (lastAction and orderPayload), they are still marked as required parameters to ensure they are explicitly considered during state construction.

Learnt from: chebizarro
PR: #127
File: lib/data/models/cant_do.dart:10-27
Timestamp: 2025-07-08T05:40:47.527Z
Learning: In the CantDo model parsing in lib/data/models/cant_do.dart, the inconsistent key naming between 'cant_do' (top-level) and 'cant-do' (nested) is required by the protocol specification and should not be changed as it would break message parsing compatibility.

lib/data/models/payment_failed.dart (2)

Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to lib/data/models.dart : Models should be exported through data/models.dart

Learnt from: chebizarro
PR: #127
File: lib/data/models/cant_do.dart:10-27
Timestamp: 2025-07-08T05:40:47.527Z
Learning: In the CantDo model parsing in lib/data/models/cant_do.dart, the inconsistent key naming between 'cant_do' (top-level) and 'cant-do' (nested) is required by the protocol specification and should not be changed as it would break message parsing compatibility.

lib/features/order/models/order_state.dart (6)

Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to lib/core/mostro_fsm.dart : Order state transitions are managed by core/mostro_fsm.dart

Learnt from: chebizarro
PR: #74
File: lib/features/trades/models/trade_state.dart:1-15
Timestamp: 2025-05-08T16:06:33.665Z
Learning: In the context of the Mostro Mobile app, the TradeState class is specifically constructed using the tradeStateProvider. While some fields are nullable (lastAction and orderPayload), they are still marked as required parameters to ensure they are explicitly considered during state construction.

Learnt from: chebizarro
PR: #110
File: lib/features/trades/widgets/mostro_message_detail_widget.dart:134-141
Timestamp: 2025-06-08T23:54:09.987Z
Learning: In the OrderState refactor, public keys should be accessed via tradeState.peer?.publicKey from the OrderState instance rather than through session?.peer?.publicKey, as the OrderState encapsulates peer information directly.

Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to lib/data/models.dart : Models should be exported through data/models.dart

Learnt from: chebizarro
PR: #110
File: test/notifiers/take_order_notifier_test.dart:72-74
Timestamp: 2025-06-04T19:35:20.209Z
Learning: MostroService methods like takeBuyOrder() and takeSellOrder() return Future and trigger side effects through other mechanisms rather than direct return values. When testing these methods, focus on verifying method calls and testing state changes through the provider system rather than mocking return values.

Learnt from: chebizarro
PR: #127
File: lib/data/models/cant_do.dart:10-27
Timestamp: 2025-07-08T05:40:47.527Z
Learning: In the CantDo model parsing in lib/data/models/cant_do.dart, the inconsistent key naming between 'cant_do' (top-level) and 'cant-do' (nested) is required by the protocol specification and should not be changed as it would break message parsing compatibility.

lib/data/models/payload.dart (10)

Learnt from: chebizarro
PR: #127
File: lib/data/models/cant_do.dart:10-27
Timestamp: 2025-07-08T05:40:47.527Z
Learning: In the CantDo model parsing in lib/data/models/cant_do.dart, the inconsistent key naming between 'cant_do' (top-level) and 'cant-do' (nested) is required by the protocol specification and should not be changed as it would break message parsing compatibility.

Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to lib/data/models.dart : Models should be exported through data/models.dart

Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to lib/core/mostro_fsm.dart : Order state transitions are managed by core/mostro_fsm.dart

Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to test/mocks.mocks.dart : DO NOT modify test/mocks.mocks.dart - it already has file-level ignores

Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to lib/data/repositories/**/*.dart : All data access should go through repository classes in data/repositories/

Learnt from: chebizarro
PR: #74
File: lib/services/mostro_service.dart:70-76
Timestamp: 2025-05-06T15:49:26.443Z
Learning: In the Mostro Mobile codebase, eventStorageProvider is exported from package:mostro_mobile/shared/providers/mostro_service_provider.dart and not from a separate event_storage_provider.dart file.

Learnt from: chebizarro
PR: #110
File: test/notifiers/take_order_notifier_test.dart:72-74
Timestamp: 2025-06-04T19:35:20.209Z
Learning: MostroService methods like takeBuyOrder() and takeSellOrder() return Future and trigger side effects through other mechanisms rather than direct return values. When testing these methods, focus on verifying method calls and testing state changes through the provider system rather than mocking return values.

Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to lib/shared/providers/mostro_database_provider.dart : Database initialization is in shared/providers/mostro_database_provider.dart

Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to lib/services/nostr_service.dart : Nostr protocol interactions go through services/nostr_service.dart

Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to **/*.dart : Remove unused imports and dependencies

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (16)
lib/data/models/payment_failed.dart (1)

1-31: LGTM! Clean implementation following established patterns.

The PaymentFailed model correctly implements the Payload interface with proper JSON serialization/deserialization. The implementation follows the established pattern used by other payload models in the codebase.

Key strengths:

  • Proper field types (int for both fields)
  • Consistent JSON key naming using snake_case
  • Standard toJson structure with type as key and nested field map
  • Appropriate factory constructor for deserialization
lib/features/order/notfiers/abstract_mostro_notifier.dart (2)

5-5: Proper import added for new PaymentFailed model.

The import follows the established pattern and is necessary for the payload handling changes below.


216-222: Excellent improvement: replaced hardcoded values with dynamic payload data.

The change properly extracts paymentAttempts and paymentRetriesInterval from the PaymentFailed payload instead of using static placeholders. This follows the established pattern used for other payload types in the same method and provides accurate information to users.

The null-safe access with ?. operator is appropriate for handling cases where the payload might not be present.

lib/features/trades/widgets/mostro_message_detail_widget.dart (1)

186-191: Proper integration of dynamic PaymentFailed data.

The widget now correctly fetches the actual paymentAttempts and paymentRetriesInterval values from the paymentFailed payload via the orderNotifierProvider, replacing the previous static placeholders.

The null-safe access with appropriate fallback values (0) ensures the UI remains functional even when the payload is not available. This change aligns with the broader integration of the PaymentFailed model throughout the codebase.

lib/data/models/payload.dart (2)

3-5: Proper imports added for new payload models.

The imports for NextTrade and PaymentFailed are correctly added and necessary for the factory method extensions below.


27-30: Factory method properly extended for new payload types.

The Payload.fromJson factory correctly handles the new payment_failed and next_trade payload types, following the established pattern used for other payload types. The JSON key extraction and model instantiation are implemented consistently.

This maintains backward compatibility while enabling deserialization of the new payload types introduced in the Mostro protocol.

lib/data/models/next_trade.dart (1)

1-26: Well-implemented NextTrade model following established patterns.

The NextTrade model correctly implements the Payload interface with proper:

  • Field types (String for key, int for index)
  • Required constructor parameters
  • JSON serialization with nested structure
  • Factory constructor with safe type casting
  • Consistent naming convention

The implementation follows the same pattern as other payload models in the codebase.

lib/features/order/models/order_state.dart (9)

14-14: LGTM!

The field declaration follows the established pattern for nullable payload fields in the class.


25-25: LGTM!

The constructor parameter follows the established pattern for optional payload parameters in the OrderState class.


37-37: LGTM!

The payload extraction follows the established pattern used for other payload types in the factory method.


43-43: LGTM!

The toString method correctly includes the new paymentFailed field, maintaining consistency with the existing implementation.


55-55: LGTM!

The equality operator correctly includes the paymentFailed field in the comparison, ensuring proper equality semantics.


67-67: LGTM!

The hashCode implementation correctly includes the paymentFailed field, maintaining the equals/hashCode contract.


78-78: LGTM!

The copyWith parameter follows the established pattern for optional nullable parameters.


88-88: LGTM!

The copyWith implementation correctly uses the null-aware operator pattern to preserve or update the paymentFailed field.


146-146: LGTM!

The updateWith method correctly handles the PaymentFailed payload extraction and preservation, following the established pattern used for other payload types.

Comment on lines +1 to +26
import 'package:mostro_mobile/data/models/payload.dart';

class NextTrade implements Payload {
final String key;
final int index;

NextTrade({required this.key, required this.index});

@override
String get type => 'next_trade';

@override
Map<String, dynamic> toJson() {
return {
type: {'key': key, 'index': index},
};
}

factory NextTrade.fromJson(Map<String, dynamic> json) {
return NextTrade(
key: json['key'] as String,
index: json['index'] as int,
);
}

}
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify model export through data/models.dart.

Based on the coding guidelines, models should be exported through data/models.dart. Please ensure this new NextTrade model is added to the exports in that file.


🏁 Script executed:

#!/bin/bash
# Check if NextTrade is exported through data/models.dart
echo "Checking if NextTrade model is exported through data/models.dart..."
rg "NextTrade" lib/data/models.dart || echo "NextTrade not found in models.dart exports"

# Also check if PaymentFailed is exported
echo "Checking if PaymentFailed model is exported through data/models.dart..."
rg "PaymentFailed" lib/data/models.dart || echo "PaymentFailed not found in models.dart exports"

Length of output: 571


Export the NextTrade model in data/models.dart

Please add the new NextTrade model to your central exports so it’s discoverable throughout the app. In lib/data/models.dart, include:

 export 'models/payload.dart';
+export 'models/next_trade.dart';
 // …other exports

This aligns with our guideline to re-export all models from data/models.dart.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import 'package:mostro_mobile/data/models/payload.dart';
class NextTrade implements Payload {
final String key;
final int index;
NextTrade({required this.key, required this.index});
@override
String get type => 'next_trade';
@override
Map<String, dynamic> toJson() {
return {
type: {'key': key, 'index': index},
};
}
factory NextTrade.fromJson(Map<String, dynamic> json) {
return NextTrade(
key: json['key'] as String,
index: json['index'] as int,
);
}
}
// lib/data/models.dart
export 'models/payload.dart';
export 'models/next_trade.dart';
// …other exports
🤖 Prompt for AI Agents
In lib/data/models/next_trade.dart lines 1 to 26, the NextTrade model is defined
but not exported centrally. To fix this, open lib/data/models.dart and add an
export statement for next_trade.dart, such as "export 'models/next_trade.dart';"
to ensure the NextTrade model is discoverable and accessible throughout the app
as per project guidelines.

@grunch grunch requested review from Catrya and grunch July 26, 2025 15:34
Copy link
Member

@Catrya Catrya left a comment

Choose a reason for hiding this comment

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

Hi @chebizarro
It works, but when the payment fails, the order appears in "My Trades" screen with the status "waiting-invoice" and the same screen as when the user started the exchange, even with the 15-minute clock ticking. This shouldn't be the case. Instead, it should:

  • Order label in My Trades screen must be payment-failed (sorry, i know is a new one but we hadn't considered it before, I think it's the most descriptive possible, because it's not Success, but if we put Waiting-invoice it can confuse the user thinking it's a recently new order.)
  • In Order Details screen it must stays on the last screen (where the payment-failed message appears).
  • A button appears next to the Close button, saying "Add Invoice."
  • When the "Add Invoice" button is selected, the usual "Add Invoice" screen appears.
Captura desde 2025-07-28 10-01-19 Captura desde 2025-07-28 10-01-11

Copy link
Member

@Catrya Catrya left a comment

Choose a reason for hiding this comment

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

@chebizarro
There are two parts:
1- When the first payment fails and Mostro sends the payment-failed message (it's still trying to pay more times but isn't asking for a new invoice).
2- When all payment attempts have failed and Mostro sends the add-invoice action, but with the status settled-hold-invoice.

  1. In the first part, only the payment failure message and the close button should appear. The user must wait for Mostro to complete the payment or request a new invoice. The Dispute, Add Invoice, and Cancel buttons should not appear.
    Also, mostro sends payment_retries_interval in seconds, so it must be converted to minutes to show the user the time in minutes (in this case, payment_retries_interval=60 sec, but it shows 60 minutes because it hasn't been converted).
image
  1. In the second part, mostro sends the addinvoice message. In My Trades screen, the payment-failed status should remain. In Order details screen, the same screen should appear as above, but with only the Close and Add Invoice buttons, but not with the clock or 15 min message
image

@Catrya
Copy link
Member

Catrya commented Jul 29, 2025

Hi @chebizarro
The things I mentioned before continue to appear (except for the conversion from seconds to minutes).

  • The cancel and dispute buttons continue to appear, which aren't there.
Captura desde 2025-07-29 08-30-37
  • When the addinvoice message arrives, it still appears as if it were addinvoice waiting-buyer-invoice
Captura desde 2025-07-29 08-32-27 Captura desde 2025-07-29 08-32-19

Copy link
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: 0

🧹 Nitpick comments (2)
CHANGELOG.md (2)

8-33: Add the core feature of this PR to the changelog

The Added list omits the headline feature delivered by this PR—support for the new PaymentFailure and NextTrade payloads plus the related state/UI work—making the entry incomplete and potentially confusing for users scanning release notes.

 ### Added
 ...
 - Debug-only display mode for Current Trade Index Card (hidden in release builds)
+- Support for new Mostro protocol payloads **PaymentFailure** and **NextTrade**
+- Order/notification/UI updates that show retry attempts and new status
+- Back-compat deserialization in `Payload.fromJson` for these types

11-14: Tighten phrasing for clarity

  1. Line 12: “during relay validation and testing process” → “during the relay validation and testing process”.
  2. Line 14: “hidden in release builds” → “hidden in production builds” for consistency with other docs.

Pure wording tweaks—no functional impact.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ed23fca and d6619a4.

📒 Files selected for processing (7)
  • CHANGELOG.md (1 hunks)
  • lib/features/key_manager/key_management_screen.dart (2 hunks)
  • lib/features/relays/widgets/relay_selector.dart (2 hunks)
  • lib/features/settings/about_screen.dart (1 hunks)
  • lib/features/settings/settings_screen.dart (1 hunks)
  • lib/features/trades/screens/trade_detail_screen.dart (2 hunks)
  • pubspec.yaml (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • pubspec.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
  • lib/features/trades/screens/trade_detail_screen.dart
🧰 Additional context used
📓 Path-based instructions (2)
lib/**/*.dart

📄 CodeRabbit Inference Engine (CLAUDE.md)

lib/**/*.dart: Use S.of(context).yourKey for all user-facing strings
Always check mounted before using context after async operations

Files:

  • lib/features/relays/widgets/relay_selector.dart
  • lib/features/settings/settings_screen.dart
  • lib/features/settings/about_screen.dart
  • lib/features/key_manager/key_management_screen.dart
**/*.dart

📄 CodeRabbit Inference Engine (CLAUDE.md)

**/*.dart: Remove unused imports and dependencies
Use const constructors where possible

Files:

  • lib/features/relays/widgets/relay_selector.dart
  • lib/features/settings/settings_screen.dart
  • lib/features/settings/about_screen.dart
  • lib/features/key_manager/key_management_screen.dart
🧠 Learnings (5)
📓 Common learnings
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to lib/core/mostro_fsm.dart : Order state transitions are managed by `core/mostro_fsm.dart`
Learnt from: chebizarro
PR: MostroP2P/mobile#74
File: lib/features/trades/models/trade_state.dart:1-15
Timestamp: 2025-05-08T16:06:33.665Z
Learning: In the context of the Mostro Mobile app, the `TradeState` class is specifically constructed using the `tradeStateProvider`. While some fields are nullable (`lastAction` and `orderPayload`), they are still marked as required parameters to ensure they are explicitly considered during state construction.
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to lib/data/models.dart : Models should be exported through `data/models.dart`
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to lib/features/*/notifiers/**/*.dart : Notifiers for complex state logic are placed in `features/{feature}/notifiers/`
Learnt from: chebizarro
PR: MostroP2P/mobile#110
File: test/notifiers/take_order_notifier_test.dart:72-74
Timestamp: 2025-06-04T19:35:20.209Z
Learning: MostroService methods like takeBuyOrder() and takeSellOrder() return Future<void> and trigger side effects through other mechanisms rather than direct return values. When testing these methods, focus on verifying method calls and testing state changes through the provider system rather than mocking return values.
Learnt from: chebizarro
PR: MostroP2P/mobile#127
File: lib/data/models/cant_do.dart:10-27
Timestamp: 2025-07-08T05:40:47.527Z
Learning: In the CantDo model parsing in lib/data/models/cant_do.dart, the inconsistent key naming between 'cant_do' (top-level) and 'cant-do' (nested) is required by the protocol specification and should not be changed as it would break message parsing compatibility.
lib/features/settings/settings_screen.dart (1)

Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: All changes should pass flutter analyze before commit

lib/features/settings/about_screen.dart (1)

Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: All changes should pass flutter analyze before commit

CHANGELOG.md (1)

Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to lib/services/nostr_service.dart : Nostr protocol interactions go through services/nostr_service.dart

lib/features/key_manager/key_management_screen.dart (3)

Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: Applies to lib/**/*.dart : Use S.of(context).yourKey for all user-facing strings

Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-20T01:48:43.335Z
Learning: All changes should pass flutter analyze before commit

Learnt from: chebizarro
PR: #127
File: lib/data/models/cant_do.dart:10-27
Timestamp: 2025-07-08T05:40:47.527Z
Learning: In the CantDo model parsing in lib/data/models/cant_do.dart, the inconsistent key naming between 'cant_do' (top-level) and 'cant-do' (nested) is required by the protocol specification and should not be changed as it would break message parsing compatibility.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (6)
lib/features/settings/about_screen.dart (1)

46-51: LGTM! Safe area padding correctly implemented.

The dynamic bottom padding using MediaQuery.of(context).viewPadding.bottom ensures content is not obscured by system UI elements like gesture navigation bars. This follows Flutter best practices for responsive design across different device form factors.

lib/features/settings/settings_screen.dart (1)

46-51: LGTM! Consistent safe area handling.

The padding adjustment matches the pattern used in other screens, ensuring consistent layout behavior across the app with proper safe area handling.

lib/features/relays/widgets/relay_selector.dart (2)

104-144: LGTM! Dialog layout improvements enhance consistency.

Removing unnecessary Flexible widgets and increasing button spacing from 8 to 12 pixels improves the visual layout of the add relay dialog. The button functionality remains unchanged.


188-228: LGTM! Consistent dialog styling applied.

The edit relay dialog now matches the improved layout from the add dialog, with cleaner button structure and better spacing.

lib/features/key_manager/key_management_screen.dart (2)

142-147: LGTM! Safe area padding consistently applied.

The padding adjustment follows the same pattern used in other screens for proper safe area handling.


651-685: LGTM! Dialog layout improvements match app-wide consistency.

The dialog action buttons now follow the improved layout pattern with removed Flexible widgets and increased spacing, consistent with similar changes in other dialogs throughout the app.

@Catrya
Copy link
Member

Catrya commented Jul 31, 2025

@chebizarro Están los botones intercambiados, cuando está en payment-failed payment-failed, solo debe salir el boton de Cerrar
Captura desde 2025-07-31 11-17-52

Cuando está en payment-failed add-invoice es que deben salir Cerrar y Agregar Invoice
Captura desde 2025-07-31 11-33-56

chebizarro and others added 2 commits July 31, 2025 11:46
  - Add separate message for payment-failed add-invoice state
  - Update paymentFailed message with clearer retry information
@Catrya
Copy link
Member

Catrya commented Aug 1, 2025

Hi @chebizarro I made some changes to the texts to improve the UX. I've already tested everything and it works fine.

Copy link
Member

@grunch grunch left a comment

Choose a reason for hiding this comment

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

utACK

@grunch grunch merged commit 1739fdd into main Aug 1, 2025
2 checks passed
@grunch grunch deleted the payment-failed branch August 1, 2025 14:15
@coderabbitai coderabbitai bot mentioned this pull request Nov 10, 2025
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.

4 participants