diff --git a/specs/004-mostro-p2p-client/tasks.md b/specs/004-mostro-p2p-client/tasks.md index 9dada5ee..c26dc917 100644 --- a/specs/004-mostro-p2p-client/tasks.md +++ b/specs/004-mostro-p2p-client/tasks.md @@ -19,6 +19,21 @@ - `[~]` — Partial: code exists but blocked on missing infrastructure (noted in description) - `[ ]` — Not started +## Open work at a glance + +Almost everything below (T001–T145) is `[x]` — the phases read as a +completed build log, not a live backlog. What's actually still open lives +in two clusters of `[~]` partial tasks (code exists, UI wiring doesn't): + +- **File attachments** (Phase 10 — P2P Chat): T079, T080, T081 — Blossom + upload/download (T070) has no Dart caller yet. +- **Dispute admin chat** (Phase 12 — Dispute System): T088, T090, T091, + T092, T093 — the Rust side (T085/T086) is ready; the screens are stubs + with no bridge subscription. + +Plus one task with no entry at all: **restore from mnemonic** — see T148 +below. + --- ## Phase 1: Setup (Project Initialization) @@ -47,7 +62,7 @@ - [x] T009 Implement storage trait in `rust/src/db/mod.rs` defining async CRUD interface for all entities (Identity, Order, Trade, Message, Relay, Dispute, Settings, MessageQueue, NwcWallet, FileAttachment, Rating). Implement SQLite backend in `rust/src/db/sqlite.rs` using `sqlx` with full schema migrations for all 11 entities per `data-model.md`. - [x] T010 [P] Implement IndexedDB storage backend in `rust/src/db/indexeddb.rs` using `indexed_db_futures`, feature-gated with `#[cfg(target_arch = "wasm32")]`. Must implement the same trait as `sqlite.rs` and support all 11 entities. -> **Transport v2 note**: T011/T012/T039/T040/T049/T066/T085/T137 below describe the original NIP-59 gift-wrap (Kind 1059) transport implemented in 004. Messages to the Mostro daemon were later migrated to transport v2 (NIP-44, signed Kind 14); peer chat (NIP-17) stays on NIP-59 gift wrap (Kind 1059). These task records are kept as-is for history. +> **Transport v2 note**: T011/T012/T039/T040/T049/T066/T085/T137 below describe the original NIP-59 gift-wrap (Kind 1059) transport implemented in 004. Messages to the Mostro daemon were migrated to transport v2 (NIP-44, signed Kind 14) in spec 005. Peer and dispute chat later moved off gift wrap too (#246/#254) — this client now speaks a custom Kind-14 chat envelope in both directions and neither reads nor writes Kind 1059 anywhere. These task records are kept as-is for history; do not read them as a description of the current transport. - [x] T011 [P] Implement NIP-59 Gift Wrap encode/decode in `rust/src/nostr/gift_wrap.rs` using `nostr-sdk`: create unsigned rumor event, encrypt into Seal (Kind 13, NIP-44), wrap into Gift Wrap (Kind 1059, ephemeral key). Export `wrap_message(content, recipient_pubkey, sender_key)` and `unwrap_message(gift_wrap_event, recipient_key)`. - [x] T012 [P] Implement relay pool with Kind 1059 + Kind 38383 subscriptions in `rust/src/nostr/relay_pool.rs` using `nostr-sdk`. Multi-relay connection manager: connect, disconnect, add/remove relays, subscribe to order events (Kind 38383) and gift-wrap DMs (Kind 1059 targeting user's trade keys), emit events via channels. @@ -458,6 +473,26 @@ configuration. --- +## Phase 21: Restore Sessions & Trades from Mnemonic + +**Purpose**: Track the recovery flow contract that already exists in +`contracts/identity.md` (`import_from_mnemonic(recover: true)`) but has no +implementation task in this file. Currently, reinstalling the app with an +existing mnemonic loses all trades, sessions, and disputes — see epic #142 +and its sub-issues (#216, #218, #219, #220, #221, #222) for the current, +actively maintained breakdown of this work. + +- [ ] T148 Implement the recovery flow per `contracts/identity.md` + `import_from_mnemonic(words, recover: true)`: send `Action.restore` + to the Mostro daemon via NIP-44 (Kind 14), receive order/dispute IDs, + request details for each, sync the trade key index, and reconstruct + the local DB from daemon responses. Recovery only applies outside + privacy mode. **This task is a pointer, not a plan** — see epic #142 + for the up-to-date task breakdown; do not duplicate work already + scoped there. + +--- + ## Dependencies & Execution Order ### Phase Dependencies diff --git a/specs/005-transport-v2-migration/tasks.md b/specs/005-transport-v2-migration/tasks.md index eecae289..34d14fa5 100644 --- a/specs/005-transport-v2-migration/tasks.md +++ b/specs/005-transport-v2-migration/tasks.md @@ -7,28 +7,38 @@ **Organization**: Two phases = two PRs. Phase 2 depends on Phase 1. +**Status: done.** Merged in #111 and verified end-to-end on a v2 node. The +plan below is kept as a historical record — do not use it as a map of the +current code. It has since been superseded by further refactors: `mostro-core` +is now `0.14.1` (past the `0.13.1` this plan targeted), `gift_wrap.rs` no +longer exists (`wrap_mostro_message`/`unwrap_mostro_message` now live in +`rust/src/nostr/transport.rs`), and T011's "leave gift wrap on peer/dispute +chat untouched" no longer holds — that chat also moved off gift wrap +entirely (kind-14 chat envelope) in #246/#254. + ## Phase 1 — mostro-core bump (PR #1: `chore/mostro-core-0.13`) -- [ ] T001 Set `mostro-core = "0.13.1"` in `rust/Cargo.toml`; update `Cargo.lock`. -- [ ] T002 Fix `map_core_status` in `rust/src/api/orders.rs`: add explicit arm +- [x] T001 Set `mostro-core = "0.13.1"` in `rust/Cargo.toml`; update `Cargo.lock`. +- [x] T002 Fix `map_core_status` in `rust/src/api/orders.rs`: add explicit arm `S::WaitingTakerBond | S::WaitingMakerBond => return None` (no wildcard). -- [ ] T003 Run `cargo build && cargo test && cargo clippy`; resolve any residual +- [x] T003 Run `cargo build && cargo test && cargo clippy`; resolve any residual fallout surfaced by the compiler. **Checkpoint**: green, app still on gift wrap. ## Phase 2 — transport switch (PR #2: `feat/transport-v2`) -- [ ] T004 `gift_wrap.rs::wrap_mostro_message` → `wrap_message_with(Transport::Nip44Direct, +- [x] T004 `gift_wrap.rs::wrap_mostro_message` → `wrap_message_with(Transport::Nip44Direct, …, WrapOptions { pow, expiration: None, signed: true })`. -- [ ] T005 `gift_wrap.rs::unwrap_mostro_message` → `unwrap_incoming(event, trade_keys)`. -- [ ] T006 [P] `relay_pool.rs::subscribe_order_and_dm_feeds` dm_filter → kind 14 + +- [x] T005 `gift_wrap.rs::unwrap_mostro_message` → `unwrap_incoming(event, trade_keys)`. +- [x] T006 [P] `relay_pool.rs::subscribe_order_and_dm_feeds` dm_filter → kind 14 + `.author(mostro_pubkey)`. -- [ ] T007 [P] `orders.rs::subscribe_gift_wraps` filter → kind 14 + `.author(...)` +- [x] T007 [P] `orders.rs::subscribe_gift_wraps` filter → kind 14 + `.author(...)` (resolve `mostro_pubkey` via `config::active_mostro_pubkey()`). -- [ ] T008 [P] `orders.rs` global bulk `gw_filter` → kind 14 + `.author(...)`. -- [ ] T009 Update the three receive handlers in `orders.rs` (per-trade, global, +- [x] T008 [P] `orders.rs` global bulk `gw_filter` → kind 14 + `.author(...)`. +- [x] T009 Update the three receive handlers in `orders.rs` (per-trade, global, event loop): kind-14 check + reject `event.pubkey != mostro_pubkey`. -- [ ] T010 Update `gift_wrap.rs` tests: assert kind 14 + author = trade key. -- [ ] T011 Leave local `wrap`/`unwrap` (peer/dispute chat, kind 1059) untouched — - regression-verify peer chat still works. -- [ ] T012 `cargo test && cargo clippy` green; manual E2E order lifecycle vs the v2 +- [x] T010 Update `gift_wrap.rs` tests: assert kind 14 + author = trade key. +- [x] T011 Leave local `wrap`/`unwrap` (peer/dispute chat, kind 1059) untouched — + regression-verify peer chat still works. _(Superseded: this chat later + moved off gift wrap too, see status note above.)_ +- [x] T012 `cargo test && cargo clippy` green; manual E2E order lifecycle vs the v2 node. **Checkpoint**: full trade flow works on protocol v2.