Trade status in the UI is poll-driven: every visible My Trades row chip and
the trade detail screen run tradeStatusProvider, which calls the Rust
bridge every 2 s per subscriber (trade_state_provider.dart:34). This has
two costs:
- Latency ceiling: any status change (e.g. an order returning to pending
after a taker timeout) can take up to 2 extra seconds to paint even though
the event is already in the order book.
- Overhead: N visible rows × one FRB call every 2 s, noticeable on
phones — pure waste when nothing changed.
The push infrastructure already exists: on_trade_updated() (added for the
timeout-cleanup work) emits TradeUpdate { order_id, status }, but only the
Canceled handler and the stale-state sweep emit today. The 004 contract
already envisioned this as on_order_status_changed() — defined in
contracts/orders.md, never implemented.
Scope
- Rust: extend
emit_trade_update to every status transition — the
status-sync gift-wrap arms, PayInvoice, the peer-pubkey/active arm, and
the Kind 38383 ingest sync for own orders.
- Dart: rework
tradeStatusProvider to be push-first (initial fetch +
stream updates filtered by order_id), keeping a low-frequency poll only
as a reconnection fallback — consumers (row chips, trade detail,
pay-invoice listener, badge counter) should not need changes.
- Update
contracts/orders.md: fold on_order_status_changed into the
implemented on_trade_updated (one stream, filter client-side).
Trade status in the UI is poll-driven: every visible My Trades row chip and
the trade detail screen run
tradeStatusProvider, which calls the Rustbridge every 2 s per subscriber (
trade_state_provider.dart:34). This hastwo costs:
after a taker timeout) can take up to 2 extra seconds to paint even though
the event is already in the order book.
phones — pure waste when nothing changed.
The push infrastructure already exists:
on_trade_updated()(added for thetimeout-cleanup work) emits
TradeUpdate { order_id, status }, but only theCanceledhandler and the stale-state sweep emit today. The 004 contractalready envisioned this as
on_order_status_changed()— defined incontracts/orders.md, never implemented.Scope
emit_trade_updateto every status transition — thestatus-sync gift-wrap arms,
PayInvoice, the peer-pubkey/active arm, andthe Kind 38383 ingest sync for own orders.
tradeStatusProviderto be push-first (initial fetch +stream updates filtered by
order_id), keeping a low-frequency poll onlyas a reconnection fallback — consumers (row chips, trade detail,
pay-invoice listener, badge counter) should not need changes.
contracts/orders.md: foldon_order_status_changedinto theimplemented
on_trade_updated(one stream, filter client-side).