fix(wallet): replace text-marker hack with proper raw event API (room.sendRaw + MsgLikeKind.Other)
- Add Timeline.sendRaw() to send custom Matrix events - Add CustomEventContent type for receiving custom events - Update TimelineEventContentMapper to handle MsgLikeKind.Other - Update TimelineItemContentFactory to intercept payment events - Rewrite DefaultPaymentEventSender to use sendRaw instead of text markers - Update TimelineItemContentPaymentFactory to parse raw JSON - Remove text-marker detection from TimelineItemContentMessageFactory - Update tests to use raw event API - Mark raw event SDK blocker as RESOLVED in BLOCKERS.md Event type: co.sulkta.payment.request (reverse-domain format) Status updates: co.sulkta.payment.status Benefits: - Proper Matrix protocol compliance - No JSON embedded in text messages - Events won't be indexed by search - Clean separation from regular messages
This commit is contained in:
parent
adee67cf0d
commit
f2b95d6b8a
10 changed files with 264 additions and 189 deletions
74
BLOCKERS.md
74
BLOCKERS.md
|
|
@ -156,55 +156,51 @@
|
|||
|
||||
---
|
||||
|
||||
## Task 8: Raw Event Handling ✅ COMPLETE
|
||||
## Task 8: Raw Event Handling ✅ COMPLETE (UPGRADED)
|
||||
|
||||
### ✅ RESOLVED: SDK Raw Event API
|
||||
**Previous blocker:** Matrix Rust SDK did not expose raw event sending or raw JSON access.
|
||||
|
||||
**Resolution:** The SDK (version 26.03.24) now provides:
|
||||
- `Timeline.sendRaw(eventType: String, content: String)` — Sends custom event types
|
||||
- `MsgLikeKind.Other` with `eventType` field — Receives custom events
|
||||
- `TimelineItemDebugInfo.originalJson` — Access to raw event JSON via debug info provider
|
||||
|
||||
**Implementation updated to use proper raw events instead of text markers.**
|
||||
|
||||
### Completed
|
||||
- ✅ **PaymentEventSender.kt** — Interface for sending payment events
|
||||
- ✅ **DefaultPaymentEventSender.kt** — Implementation
|
||||
- Sends payment as formatted text message with JSON payload
|
||||
- Format: `[cardano-payment:v1]{...json...}\n💰 Sent X ADA`
|
||||
- HTML body includes data-payment attribute for future parsing
|
||||
- Status updates use separate marker: `[cardano-payment-status:v1]`
|
||||
- ✅ **TimelineItemContentPaymentFactory.kt** — Parser for payment messages
|
||||
- `isPaymentEvent(body)` — Detects payment marker
|
||||
- `isPaymentStatusUpdate(body)` — Detects status update marker
|
||||
- `createFromBody(body, isSentByMe)` — Parses text message body
|
||||
- `createFromRaw(json, isSentByMe)` — Parses raw JSON (for future SDK extension)
|
||||
- ✅ **DefaultPaymentEventSender.kt** — Implementation using raw events
|
||||
- Uses `timeline.sendRaw(eventType, content)` to send custom events
|
||||
- Event type: `co.sulkta.payment.request` (reverse-domain format)
|
||||
- Status updates: `co.sulkta.payment.status`
|
||||
- No text marker hack — proper Matrix custom events
|
||||
- ✅ **TimelineItemContentPaymentFactory.kt** — Parser for payment events
|
||||
- `isPaymentEventType(eventType)` — Checks for payment event type
|
||||
- `isStatusUpdateEventType(eventType)` — Checks for status update type
|
||||
- `createFromRaw(json, isSentByMe)` — Parses raw JSON from custom events
|
||||
- Supports both camelCase and snake_case field names
|
||||
- Graceful error handling — returns null on malformed JSON
|
||||
- ✅ **TimelineItemContentMessageFactory.kt** — Modified to intercept payments
|
||||
- Added paymentFactory dependency
|
||||
- Added isSentByMe parameter to create()
|
||||
- TextMessageType checks for payment marker before creating text content
|
||||
- ✅ **TimelineItemContentFactory.kt** — Passes isSentByMe to message factory
|
||||
- ✅ **TimelineEventContentMapper.kt** — Maps `MsgLikeKind.Other` to `CustomEventContent`
|
||||
- ✅ **TimelineItemContentFactory.kt** — Handles `CustomEventContent` for payments
|
||||
- Gets raw JSON via `timelineItemDebugInfoProvider().originalJson`
|
||||
- Delegates to paymentFactory for payment event types
|
||||
- ✅ **CustomEventContent.kt** — New EventContent type for custom events
|
||||
- ✅ **Timeline.sendRaw()** — Added to Timeline interface and RustTimeline implementation
|
||||
- ✅ **FakePaymentEventSender.kt** — Test fake
|
||||
- ✅ **TimelineItemContentPaymentFactoryTest.kt** — Unit tests
|
||||
|
||||
### SDK Limitations & Approach
|
||||
The Matrix Rust SDK does NOT expose:
|
||||
- Raw event sending (`room.sendRawEvent()`)
|
||||
- Raw JSON access for UnknownContent
|
||||
|
||||
**Workaround implemented:**
|
||||
Instead of custom event types, we encode payment data in standard text messages:
|
||||
```
|
||||
[cardano-payment:v1]{"amount_lovelace":10000000,"to_address":"...","from_address":"...","tx_hash":"...","status":"pending","network":"testnet"}
|
||||
💰 Sent 10 ADA
|
||||
```
|
||||
|
||||
This approach:
|
||||
- Works with existing SDK (no fork needed)
|
||||
- Falls back gracefully (non-wallet clients see "💰 Sent 10 ADA")
|
||||
- Can be upgraded to proper custom events when SDK exposes raw event APIs
|
||||
- ✅ **TimelineItemContentPaymentFactoryTest.kt** — Updated unit tests
|
||||
|
||||
### m.replace Status Updates
|
||||
**Decision:** Due to SDK limitations (no direct access to m.replace relations), status updates are sent as new messages rather than event replacements.
|
||||
**Decision:** Status updates are sent as separate events of type `co.sulkta.payment.status`.
|
||||
|
||||
**Future improvement:** When SDK exposes event relations, refactor to use m.replace for cleaner status update thread.
|
||||
|
||||
### Potential Issues
|
||||
- ⚠️ Status updates create new timeline events (not ideal, but works)
|
||||
- ⚠️ Payment messages may be indexed by search (contains JSON)
|
||||
- ⚠️ Very long addresses in JSON may hit message length limits (unlikely in practice)
|
||||
### Benefits of Raw Event Approach
|
||||
- ✅ Proper Matrix protocol compliance (custom event types, not hacked text)
|
||||
- ✅ Non-wallet clients see "Unknown event" instead of JSON-in-text
|
||||
- ✅ Clean separation of payment events from regular messages
|
||||
- ✅ Events won't be indexed by message search
|
||||
- ✅ No message length limits concern
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue