Skip to content

End-to-End Message Flow

This page shows how messages flow through Mycel from sender to recipient.

DM Delivery Flow

sequenceDiagram
    participant Sender as Sender App
    participant SDTN as Sender DTN
    participant ST as Sender Transport
    participant Relay as Nearby/Nostr
    participant RT as Recipient Transport
    participant RDTN as Recipient DTN
    participant Recipient as Recipient App

    Sender->>SDTN: Create message
    SDTN->>SDTN: Encrypt (ECIES)
    SDTN->>SDTN: Sign (Ed25519)
    SDTN->>SDTN: Store bundle (NEW)

    loop Routing attempts
        SDTN->>ST: Forward bundle
        ST->>Relay: Transmit
        Relay->>RT: Receive
        RT->>RDTN: Deliver
    end

    RDTN->>RDTN: Verify signature
    RDTN->>RDTN: Decrypt payload
    RDTN->>Recipient: Display message

    RDTN->>ST: Send DeliveryAck
    ST->>SDTN: Receive ACK
    SDTN->>Sender: Update status (DEL)

Layer Responsibilities

Layer Sender Side Recipient Side
App User types message Display in conversation
DTN Encrypt, sign, store Verify, decrypt, store
Transport Select path, transmit Receive, forward up

Detailed Steps

1. Message Creation

App Layer:
  User → ChatViewModel → DmUseCase

DTN Layer:
  BundleRepository.createDmBundle()
    1. Generate bundle ID
    2. Encrypt payload (DmCrypto)
    3. Sign header (DeviceKeys)
    4. Store with status=NEW

2. Routing Decision

flowchart TB
    START([Bundle created]) --> CHECK{Transport available?}
    CHECK -->|Nearby peer| NEARBY[Send via Nearby]
    CHECK -->|Nostr relay| NOSTR[Send via Nostr]
    CHECK -->|Neither| WAIT[Wait in queue]

    NEARBY --> SENT{Transmitted?}
    NOSTR --> SENT

    SENT -->|Yes| ACK_WAIT[Wait for ACK]
    SENT -->|No| RETRY[Retry later]

    ACK_WAIT -->|ACK received| DONE([Delivery confirmed])
    ACK_WAIT -->|Timeout| RETRY

    WAIT --> CHECK
    RETRY --> CHECK

3. Transport Selection

The routing facade evaluates all available transports:

Transport When Used Priority
Nearby Peer is connected (XFER/DRAIN state) High
Nostr Relay is connected, recipient online Medium
Store No transport available Fallback

4. Bundle Transmission

Via Nearby:

SessionRegistry → check XFER/DRAIN state
OutgoingWorker → serialize bundle
NearbyConnections → send payload
WireProtocol → frame with length prefix

Via Nostr:

RelayPool → get connected relays
GiftWrap → encrypt for relay blindness
NostrEvent → create wrapped event
RelayConnection → publish to relays

5. Bundle Reception

sequenceDiagram
    participant T as Transport
    participant P as PayloadParser
    participant R as BundleRepository
    participant N as NotificationManager

    T->>P: Raw bytes received
    P->>P: Deserialize CBOR
    P->>P: Verify signature
    P->>R: Check duplicate (by ID)

    alt New bundle
        R->>R: Store bundle
        R->>R: Check if for me
        alt Destination is me
            R->>R: Decrypt payload
            R->>N: Notify user
        else Destination is other
            R->>R: Mark FORWARDABLE
        end
    else Duplicate
        R->>R: Drop bundle
    end

6. Delivery Confirmation

sequenceDiagram
    participant R as Recipient
    participant RDTN as Recipient DTN
    participant T as Transport
    participant SDTN as Sender DTN
    participant S as Sender

    R->>RDTN: Message displayed
    RDTN->>RDTN: Create DeliveryAck
    RDTN->>T: Send ACK bundle
    T->>SDTN: ACK received
    SDTN->>SDTN: Mark original DEL
    SDTN->>SDTN: Update routing (ACK telemetry)
    SDTN->>S: Update UI (delivered)

Multi-Hop Delivery

When sender and recipient aren't directly connected:

flowchart LR
    A[Sender] -->|copy 1| B[Relay Node 1]
    A -->|copy 2| C[Relay Node 2]
    B -->|forward| D[Recipient]
    C -->|forward| D

    D -->|ACK| B
    B -->|ACK| A

Copy Budget Management:

  • Initial budget: 3 copies (configurable)
  • Each forward decrements budget
  • When budget = 1, node waits for direct delivery

Timing

Phase Typical Time Maximum
Create & encrypt < 50ms 100ms
Nearby transfer 100-500ms 2s
Nostr publish 200ms-2s 5s
ACK return Same as forward -
Total (direct) < 1s 5s
Total (multi-hop) Minutes to days TTL (7 days default)

Error Handling

Error Recovery
Transport disconnected Retry with backoff
Signature invalid Drop bundle
Duplicate received Ignore
TTL expired Remove bundle
Decryption failed Store but mark error

See Also: Bundle Lifecycle | Routing Overview