Skip to content

feat: re-apply dual send for transport v2 (Phase B) without Riverpod 3.x#632

Open
AndreaDiazCorreia wants to merge 8 commits into
mainfrom
feat/transport-v2-phase-b-reapply
Open

feat: re-apply dual send for transport v2 (Phase B) without Riverpod 3.x#632
AndreaDiazCorreia wants to merge 8 commits into
mainfrom
feat/transport-v2-phase-b-reapply

Conversation

@AndreaDiazCorreia

@AndreaDiazCorreia AndreaDiazCorreia commented Jun 24, 2026

Copy link
Copy Markdown
Member

Summary

Re-applies the content of #624 (dual send for transport v2, Phase B) on top of main (post Riverpod 3.x rollback, #628), without any Riverpod 3.x changes from #613. Also includes a follow-up fix for an order-creation race surfaced while testing the restore flow.

The Phase B commit is a clean cherry-pick of the original #624 delta onto the reverted (Riverpod 2.6.1) base: byte-identical to the original and with no Riverpod 3.x API usage (only ref.read(settingsProvider), identical in 2.x/3.x).

Contents

Transport v2 (Phase B) — re-apply of #624

  • NIP-44 dual-receive/dual-send transport logic (mostro_message.dart, mostro_service.dart)
  • Restore manager decode path + tests (mostro_message_nip44_test.dart, restore_decode_test.dart)
  • Transport v2 migration docs

Fix: order-creation race with node-switch restore

A node-switch restore resets all sessions (RestoreService._clearAllsessionNotifier.reset()). Creating an order while that restore is in flight had its session wiped, leaving the order orphaned on the daemon (it consumed a trade index but never appeared in "My Trades").

  • Expose RestoreService.isOperationInProgress / awaitOperationCompletion()
  • AddOrderNotifier.submitOrder now waits for any in-flight restore to finish before creating the order session

Verification

  • flutter analyze: no issues.
  • flutter test: all tests pass (479).
  • Manual: order create + cancel round-trips end-to-end against both a v1 daemon (kind 1059 gift wrap) and a v2 daemon (kind 14 NIP-44 direct); transport is selected from the node's advertised protocol_version.

Base

Original author: Andrea Diaz (Phase B preserved via cherry-pick).

Summary by CodeRabbit

  • New Features
    • Added protocol-versioned message wrapping with automatic support for both v1 (gift-wrap) and v2 (NIP-44) across sending and restore flows.
    • Introduced session locking during restore to prevent recovery and order actions from interfering.
  • Bug Fixes
    • Improved restore decoding and temporary restore subscriptions to correctly handle both transport variants.
    • Order publishing now follows the node-advertised transport to reduce protocol mismatches.
  • Documentation
    • Updated session recovery and transport v2 migration documentation.
  • Tests
    • Added regression tests covering v2 NIP-44 wrapping and restore decoding for both transports.

AndreaDiazCorreia and others added 2 commits June 23, 2026 22:07
* feat(transport): implement protocol v2 (NIP-44 direct) send path with identity proof (Phase B)

* feat(transport): route all outbound Mostro sends through wrapForTransport (Phase B)

* feat(restore): add dual-receive support for transport v2 (NIP-44 direct) in restore flow

* test(restore): add dual-receive transport v2 regression tests for restore flow

* fix(transport): bind dispute identity proof and guard restore tuple

- DisputeRepository.createDispute now passes masterKey/keyIndex to
  wrapForTransport so reputation-mode disputes carry the v2 identity
  proof instead of being silently downgraded to full-privacy, matching
  publishOrder.
- decodeRestoreMessage guards against an empty JSON tuple before
  indexing [0] to avoid a RangeError.
- Refresh stale NIP-59-only comments in the dispute send path.

---------

Co-authored-by: grunch <fjcalderon@gmail.com>
…ion reset

- Add RestoreService.isOperationInProgress and awaitOperationCompletion() to expose restore/sync state
- AddOrderNotifier.submitOrder now waits for any in-flight restore to finish before creating an order
- Prevents session orphaning when node-switch restore's _clearAll wipes sessions mid-order-creation
@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@AndreaDiazCorreia, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 32 minutes and 22 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6849bb76-accf-4d1a-bef3-d7cdb2ee8363

📥 Commits

Reviewing files that changed from the base of the PR and between 844fda6 and db9f180.

📒 Files selected for processing (5)
  • lib/features/order/notifiers/add_order_notifier.dart
  • lib/features/order/notifiers/order_notifier.dart
  • lib/features/restore/restore_manager.dart
  • lib/shared/providers.dart
  • lib/shared/providers/session_lifecycle_lock_provider.dart

Walkthrough

This PR adds transport-aware NIP-44 sending, updates restore flows to subscribe to and decode both v1 and v2 responses, adds session locking around restore and order submission, and updates tests and architecture docs for the revised transport behavior.

Changes

NIP-44 dual-send transport v2

Layer / File(s) Summary
MostroMessage: versioned serialization and v2 wrapping
lib/data/models/mostro_message.dart
toJson/sign/serialize accept an optional version, wrapNip44 builds kind-14 encrypted tuples with transport-specific signatures, and wrapForTransport selects the send format from protocolVersion.
Outbound send sites: publishOrder and createDispute
lib/services/mostro_service.dart, lib/data/repositories/dispute_repository.dart
Order publish and dispute creation now route through wrapForTransport(...), passing node protocol version and privacy-dependent identity inputs.
RestoreService: dual-transport subscription and unified decode
lib/features/restore/restore_manager.dart
Restore adds acquireSessionLock(), subscribes to both kind 1059 and kind 14, waits for node connectivity before trade-index sync, and centralizes restore reply decoding in decodeRestoreMessage(...).
AddOrderNotifier: session lock during submit
lib/features/order/notifiers/add_order_notifier.dart
submitOrder acquires the restore session lock around session creation, timeout startup, order submission, and state updates, then releases it in finally.
Tests: NIP-44 wrapping and restore decode
test/data/mostro_message_nip44_test.dart, test/features/restore/restore_decode_test.dart
Tests cover kind-14 wrapping in reputation and full-privacy modes, plus restore decoding for gift-wrap, NIP-44 direct replies, matching decoded payloads, and unexpected-author rejection.
Architecture docs: restore and migration updates
docs/architecture/SESSION_RECOVERY_ARCHITECTURE.md, docs/architecture/TRANSPORT_V2_MIGRATION.md
Docs now describe dual-filter restore subscriptions, kind-based restore decoding, current migration phase status, and the revised Phase B dual-send contract.

Sequence Diagram(s)

sequenceDiagram
  participant AddOrderNotifier
  participant RestoreService
  participant MostroMessage
  participant NostrUtils
  participant MostroNode

  AddOrderNotifier->>RestoreService: acquireSessionLock()
  RestoreService-->>AddOrderNotifier: release callback

  AddOrderNotifier->>MostroMessage: wrapForTransport(protocolVersion, tradeKey, masterKey, ...)
  MostroMessage->>MostroMessage: resolveTransport(protocolVersion)
  alt transport == nip44
    MostroMessage->>NostrUtils: encryptNIP44([messageMap, tradeSig, identityProof])
    NostrUtils-->>MostroMessage: ciphertext
    MostroMessage-->>AddOrderNotifier: kind 14 event
  else transport == giftWrap
    MostroMessage-->>AddOrderNotifier: kind 1059 event
  end

  AddOrderNotifier->>MostroNode: publish(event)
  MostroNode-->>RestoreService: restore response (kind 14 or 1059)
  RestoreService->>NostrUtils: decrypt or unwrap response
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~55 minutes

Possibly related issues

Possibly related PRs

  • MostroP2P/mobile#624: Shares the same transport-v2 dual-send wiring across MostroMessage, restore handling, and outbound Mostro sends.
  • MostroP2P/mobile#621: Introduces the dual-receive NIP-44 restore path that this PR extends with unified decoding and dual subscriptions.
  • MostroP2P/mobile#566: Touches the same restore_manager.dart coordination path around restore execution and overlapping restore lifecycle behavior.

Suggested reviewers

  • mostronatorcoder
  • grunch
  • Catrya

Poem

🐇 I packed two messages into one neat trail,
One gift-wrapped hop, one kind-14 mail.
The restore burrow now listens both ways,
While session locks guard the order maze.
With tuple and tag, I thump in delight!

🚥 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 accurately captures the main change: reapplying Phase B dual-send support for transport v2 and notes the Riverpod 3.x constraint.
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 feat/transport-v2-phase-b-reapply

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
lib/data/models/mostro_message.dart (1)

101-134: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

De-duplicate the wrapperKey selection.

The restore/order wrapper-key logic is repeated verbatim in sign (Lines 103-106), serialize (Lines 124-127), and wrapNip44 (Lines 196-199). Since this key is load-bearing for the protocol signature, a future edit to one copy that misses the others would silently produce mismatched signatures. Consider extracting a single getter.

♻️ Suggested helper extraction
+  // Use 'restore' key for restore and last-trade-index actions, 'order' otherwise, as per protocol.
+  String get _wrapperKey =>
+      action == Action.restore || action == Action.lastTradeIndex
+      ? 'restore'
+      : 'order';
+
   String sign(NostrKeyPairs keyPair, {int? version}) {
-    //IMPORTANT : Use 'restore' key for restore and last-trade-index actions, 'order' for everything else, as per protocol
-    final wrapperKey =
-        action == Action.restore || action == Action.lastTradeIndex
-        ? 'restore'
-        : 'order';
-    final message = {wrapperKey: toJson(version: version)};
+    final message = {_wrapperKey: toJson(version: version)};
     final serializedEvent = jsonEncode(message);
     return _mostroSign(serializedEvent, keyPair);
   }

Apply the same substitution in serialize and wrapNip44.

🤖 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/data/models/mostro_message.dart` around lines 101 - 134, The wrapperKey
selection logic that checks if action is restore or lastTradeIndex is duplicated
across the sign method, serialize method, and wrapNip44 method. Extract this
logic into a single private getter method (e.g., get wrapperKey) that returns
either 'restore' or 'order' based on the action value, then replace all three
instances of the duplicated wrapperKey assignment with calls to this new getter.
This ensures the protocol-critical logic is maintained in a single location and
prevents future signature mismatches from inconsistent edits.
🤖 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/restore/restore_manager.dart`:
- Around line 66-80: The `awaitOperationCompletion()` method only waits for the
current operation to finish but does not prevent a new restore operation from
immediately starting afterward, leaving a race window where sessions created
after the await returns can still be wiped by `_clearAll()`. Instead of just
awaiting the current operation, use a proper async locking mechanism (such as a
Mutex) to serialize restore/sync operations and session-creating flows behind
the same critical section. This ensures that while a restore is in progress or
about to start, session creation is blocked, and vice versa, eliminating the
TOCTOU race condition rather than just waiting for completion.

---

Nitpick comments:
In `@lib/data/models/mostro_message.dart`:
- Around line 101-134: The wrapperKey selection logic that checks if action is
restore or lastTradeIndex is duplicated across the sign method, serialize
method, and wrapNip44 method. Extract this logic into a single private getter
method (e.g., get wrapperKey) that returns either 'restore' or 'order' based on
the action value, then replace all three instances of the duplicated wrapperKey
assignment with calls to this new getter. This ensures the protocol-critical
logic is maintained in a single location and prevents future signature
mismatches from inconsistent edits.
🪄 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: d8608883-96d3-440c-8c42-04c5e6a6c049

📥 Commits

Reviewing files that changed from the base of the PR and between 738e5f2 and 0226336.

📒 Files selected for processing (9)
  • docs/architecture/SESSION_RECOVERY_ARCHITECTURE.md
  • docs/architecture/TRANSPORT_V2_MIGRATION.md
  • lib/data/models/mostro_message.dart
  • lib/data/repositories/dispute_repository.dart
  • lib/features/order/notifiers/add_order_notifier.dart
  • lib/features/restore/restore_manager.dart
  • lib/services/mostro_service.dart
  • test/data/mostro_message_nip44_test.dart
  • test/features/restore/restore_decode_test.dart

Comment thread lib/features/restore/restore_manager.dart Outdated

@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: 0226336fd5

ℹ️ 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 thread lib/features/restore/restore_manager.dart
…rations

- Change awaitOperationCompletion from `if` to `while` to wait for any operation that starts while we're already waiting
- Prevents race where a second restore begins after the first completes but before the caller proceeds
- Update doc comment to clarify looping behavior and note that restore triggers are mutually exclusive with order submission
…event v1/v2 protocol mismatch

- Add _waitForNodeConnectivity call before _createTempSubscription to ensure mostroInstance is populated
- Prevents wrapForTransport from defaulting to v1 gift wrap when mostroInstance is null at app init
- Avoids protocol v2 nodes receiving kind 1059 requests they won't answer, which would leave local key index stale

@ermeme ermeme 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.

Review Summary

Verdict: Request changes

Blocking issue:

  • awaitOperationCompletion() only waits for the current restore to finish. A restore can start again immediately after the await returns but before newSession() runs, and _clearAll() will still wipe the newly created session. This needs real serialization/mutex protection around restore and session creation, not a wait-only check.

Comment thread lib/features/order/notifiers/add_order_notifier.dart Outdated
…ce in order creation

- Replace awaitOperationCompletion with acquireSessionLock in AddOrderNotifier.submitOrder
- Wrap session creation in try/finally with lock release to serialize with restore's _clearAll
- Add _sessionLockTail future chain to RestoreService to implement critical-section lock
- Hold session lock for entire restore process in initRestoreProcess
- Prevents race where restore's session reset interleaves with order creation even after wait compl

@ermeme ermeme 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.

Review Summary

Verdict: Request changes

The new lock is only taken by AddOrderNotifier, but the restore path never acquires the same lock. That means _clearAll() can still interleave with newSession(), and you also release the lock before submitOrder(), so the newly created session can still be wiped before the order is published.

Please move the same lock into the restore/reset side (or hold it across the full session-creation + publish critical section) so both flows synchronize on the same primitive.

Comment thread lib/features/order/notifiers/add_order_notifier.dart Outdated
@MostroP2P MostroP2P deleted a comment from ermeme Bot Jun 24, 2026
…rphaning

- Move mostroService.submitOrder and state update inside try/finally lock block
- Prevents race where restore's _clearAll can wipe session after creation but before publish
- Ensures entire create critical section (session + publish) is atomic with respect to restore

@ermeme ermeme 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.

Review Summary

Verdict: Request changes

844fda6 fixes the original AddOrder path: submitOrder() is now inside the lock, and restore holds the same lock around _clearAll(). That closes the specific TOCTOU you asked about.

However, the invariant is still not true globally: there are other session-creating flows (lib/features/order/notifiers/order_notifier.darttakeSellOrder() / takeBuyOrder()) that still call sessionNotifier.newSession() without acquiring the same session lock. If restore can overlap with those flows, the same session-orphaning race remains.

So this commit resolves the AddOrder race, but not all session-creation paths yet. The shared lock needs to cover every path that creates a session before I can approve.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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/notifiers/add_order_notifier.dart`:
- Around line 116-133: The create-order critical section in
add_order_notifier.dart is released too early in the flow around submitOrder and
newSession, which lets restore cleanup clear a pending create before the first
terminal response arrives. Update the logic in the notifier path that acquires
acquireSessionLock so the lock stays held until the create request reaches its
first terminal outcome via _confirmOrder or equivalent, or otherwise ensure
pending create sessions survive _clearAll during restore. Keep the
session/sessionNotifier/newSession and mostroService.submitOrder sequence
protected until that terminal response is processed.

In `@lib/features/restore/restore_manager.dart`:
- Around line 1089-1094: `syncTradeIndex()` needs to be serialized with order
session creation so it cannot update the trade index while
`submitOrder()`/`newSession()` is running with stale state. In
`restore_manager.dart`, around `syncTradeIndex()` and `setCurrentKeyIndex(...)`,
acquire the same `acquireSessionLock()` used by `submitOrder()` (or otherwise
block order submission until this sync finishes) and hold it across the
connectivity wait and index update so `newSession()` cannot publish with an
outdated index.
🪄 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: 9e129d10-2363-424d-adbe-6708c384a46e

📥 Commits

Reviewing files that changed from the base of the PR and between 0226336 and 844fda6.

📒 Files selected for processing (2)
  • lib/features/order/notifiers/add_order_notifier.dart
  • lib/features/restore/restore_manager.dart

Comment thread lib/features/order/notifiers/add_order_notifier.dart Outdated
Comment thread lib/features/restore/restore_manager.dart
ermeme[bot]
ermeme Bot previously approved these changes Jun 24, 2026

@ermeme ermeme 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.

Review Summary

Verdict: Approve

The shared SessionLifecycleLock now covers all session-creating paths I called out:

  • AddOrderNotifier.submitOrder()
  • OrderNotifier.takeSellOrder() / takeBuyOrder()
  • RestoreService.initRestoreProcess() around _clearAll() and the restore rebuild

That closes the TOCTOU/session-orphaning race across the current code paths. The lock is centralized, used consistently, and the critical section now includes the dependent publish step.

…e index reads

- Acquire sessionLifecycleLock before updating trade index in syncTradeIndex
- Prevents order/take flows from creating sessions with stale keyIndex while sync is in progress
- Release lock in finally block after index update completes

@ermeme ermeme 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.

Review Summary

Verdict: Approve

The latest commit is correct: syncTradeIndex() now acquires the same shared SessionLifecycleLock, so the stale-index path is serialized with restore and the session-creating flows (add order, take buy/sell). That keeps a session from being created/published while the trade index is mid-update.

I don't see a remaining blocking issue in this head.

@grunch grunch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It doesn't create a new order when I try to create a new order on a mostro node with transport = nip44 and in main head:

======== Exception caught by gesture ===============================================================
The following _Exception was thrown while handling a gesture:
Exception: Nostr is not initialized. Call init() first.

When the exception was thrown, this was the stack: 
#1      ProviderContainer.read (package:riverpod/src/framework/container.dart:241:21)
#2      ConsumerStatefulElement.read (package:flutter_riverpod/src/consumer.dart:620:59)
#3      _AddOrderScreenState._submitOrder (package:mostro_mobile/features/order/screens/add_order_screen.dart:504:34)
#4      _MostroReactiveButtonState._startOperation (package:mostro_mobile/shared/widgets/mostro_reactive_button.dart:96:22)
#5      _InkResponseState.handleTap (package:flutter/src/material/ink_well.dart:1224:21)
#6      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:345:24)
#7      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:758:11)
#8      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:383:5)
#9      BaseTapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:353:7)
#10     GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:173:27)
#11     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:532:20)
#12     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:498:22)
#13     RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:473:11)
#14     GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:437:7)
#15     GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:394:5)
#16     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:341:7)
#17     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:308:9)
#18     _invoke1 (dart:ui/hooks.dart:372:13)
#19     PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:467:7)
#20     _dispatchPointerDataPacket (dart:ui/hooks.dart:307:31)
#21     NostrService.subscribeToEvents (package:mostro_mobile/services/nostr_service.dart:202:7)
#22     OpenOrdersRepository._subscribeToOrders (package:mostro_mobile/data/repositories/open_orders_repository.dart:61:35)
#23     new OpenOrdersRepository (package:mostro_mobile/data/repositories/open_orders_repository.dart:39:5)
#24     orderRepositoryProvider.<anonymous closure> (package:mostro_mobile/shared/providers/order_repository_provider.dart:13:21)
#25     ProviderElementBase.read (package:riverpod/src/framework/element.dart:691:12)
#26     SubscriptionManager._initMostroInstanceListener (package:mostro_mobile/features/subscriptions/subscription_manager.dart:63:15)
#27     new SubscriptionManager (package:mostro_mobile/features/subscriptions/subscription_manager.dart:51:5)
#28     RelaysNotifier._initMostroRelaySync (package:mostro_mobile/features/relays/relays_notifier.dart:416:30)
#29     new RelaysNotifier (package:mostro_mobile/features/relays/relays_notifier.dart:44:5)
#30     relaysProvider.<anonymous closure> (package:mostro_mobile/features/relays/relays_provider.dart:10:10)
#31     ProviderContainer.read (package:riverpod/src/framework/container.dart:241:21)
#32     _initializeRelaySynchronization (package:mostro_mobile/main.dart:89:15)
#33     main (package:mostro_mobile/main.dart:69:3)
Handler: "onTap"
Recognizer: TapGestureRecognizer#f4369
  debugOwner: GestureDetector
  state: ready
  won arena
  finalPosition: Offset(295.6, 492.2)
  finalLocalPosition: Offset(83.9, 12.2)
  button: 1
  sent tap down
====================================================================================================
[Nostr] data entity with content: ["EOSE","e9a8731714e672ada2cb747d3c578491f3188ba90b09c35efa499aa96fd4b741"] is already registered, skipping...
[Nostr] Registered data entity: ["EVENT","e9a8731714e672ada2cb747d3c578491f3188ba90b09c35efa499aa96fd4b741",{"content":"","created_at":1782162321,"id":"743e357e8a229cb15f90e0587413fa651b9ad21c1b0d02d936cff64c4fc71b05","kind":10002,"pubkey":"dbe0b1be7aafd3cfba92d7463edbd4e33b2969f61bd554d37ac56f032e13355a","sig":"80f05f44cf6852b490ae8f79525b8d10ee8f5ed883976be45925ecd7aba8a0e3e2a89321f3938b3e0ee469e9add8381f0325fd52a7edf196bc2ba0dea8af9844","tags":[["r","wss://relay.mostro.network"]]}]

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.

2 participants