Skip to content

Commit 3b1fdd3

Browse files
committed
feat(mesh): add capability-gated hop-by-hop relay for DMs
1 parent dfb848d commit 3b1fdd3

26 files changed

Lines changed: 5285 additions & 435 deletions

docs/protocol/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Every frame carries a `type` field that determines the command. Commands are gro
3131
| [Delivery receipts](delivery.md) | `send_delivery_receipt`, `fetch_delivery_receipts` | Delivery and seen tracking |
3232
| [Contacts](contacts.md) | `fetch_contacts`, `fetch_trusted_contacts`, `import_contacts`, `fetch_identities`, `fetch_dm_headers` | Identity management and contact exchange |
3333
| [Peers](peers.md) | `get_peers`, `announce_peer`, `add_peer`, `fetch_peer_health`, `fetch_network_stats`, `fetch_traffic_history` | Peer discovery, health monitoring, network stats, traffic history |
34+
| [Relay](relay.md) | `relay_message`, `relay_hop_ack`, `fetch_relay_status` | Hop-by-hop message forwarding (Iteration 1, capability-gated by `mesh_relay_v1`) |
3435
| [Gazeta](gazeta.md) | `publish_notice`, `fetch_notices` | Anonymous encrypted notice board |
3536
| [Errors](errors.md) | `error` | All error codes and their meaning |
3637

@@ -69,6 +70,9 @@ Not every command is available on every connection type:
6970
| `fetch_peer_health` | yes | yes ||
7071
| `fetch_network_stats` | yes | yes ||
7172
| `fetch_traffic_history` | yes |||
73+
| `relay_message` || yes (capability-gated) | yes (capability-gated) |
74+
| `relay_hop_ack` || yes (capability-gated) | yes (capability-gated) |
75+
| `fetch_relay_status` | yes |||
7276
| `publish_notice` | yes | yes ||
7377
| `fetch_notices` | yes | yes ||
7478

@@ -175,6 +179,7 @@ Push and gossip are independent mechanisms that run in parallel. Push optimises
175179
| [Delivery receipts](delivery.md) | `send_delivery_receipt`, `fetch_delivery_receipts` | Отслеживание доставки и просмотра |
176180
| [Контакты](contacts.md) | `fetch_contacts`, `fetch_trusted_contacts`, `import_contacts`, `fetch_identities`, `fetch_dm_headers` | Управление identity и обмен контактами |
177181
| [Пиры](peers.md) | `get_peers`, `announce_peer`, `add_peer`, `fetch_peer_health`, `fetch_network_stats`, `fetch_traffic_history` | Обнаружение пиров, мониторинг, статистика, история трафика |
182+
| [Ретрансляция](relay.md) | `relay_message`, `relay_hop_ack`, `fetch_relay_status` | Пошаговая пересылка сообщений (Итерация 1, гейтинг по capability `mesh_relay_v1`) |
178183
| [Gazeta](gazeta.md) | `publish_notice`, `fetch_notices` | Анонимная зашифрованная доска объявлений |
179184
| [Ошибки](errors.md) | `error` | Все коды ошибок и их значение |
180185

@@ -213,6 +218,9 @@ Push and gossip are independent mechanisms that run in parallel. Push optimises
213218
| `fetch_peer_health` | да | да ||
214219
| `fetch_network_stats` | да | да ||
215220
| `fetch_traffic_history` | да |||
221+
| `relay_message` || да (capability-gated) | да (capability-gated) |
222+
| `relay_hop_ack` || да (capability-gated) | да (capability-gated) |
223+
| `fetch_relay_status` | да |||
216224
| `publish_notice` | да | да ||
217225
| `fetch_notices` | да | да ||
218226

docs/protocol/relay.md

Lines changed: 719 additions & 0 deletions
Large diffs are not rendered by default.

docs/roadmap.md

Lines changed: 330 additions & 28 deletions
Large diffs are not rendered by default.

docs/roadmap.ru.md

Lines changed: 336 additions & 28 deletions
Large diffs are not rendered by default.

docs/rpc.md

Lines changed: 28 additions & 308 deletions
Large diffs are not rendered by default.

docs/rpc/README.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# RPC Commands
2+
3+
## English
4+
5+
Per-command-group documentation for the CORSA RPC layer. For architecture overview, configuration, CLI usage, and integration guide see the parent [rpc.md](../rpc.md).
6+
7+
### Command Index
8+
9+
| Group | Commands | File |
10+
|---|---|---|
11+
| [System](system.md) | `help`, `ping`, `hello`, `version` | [system.md](system.md) |
12+
| [Network](network.md) | `get_peers`, `fetch_peer_health`, `fetch_network_stats`, `add_peer` | [network.md](network.md) |
13+
| [Identity](identity.md) | `fetch_identities`, `fetch_contacts`, `fetch_trusted_contacts` | [identity.md](identity.md) |
14+
| [Message](message.md) | `fetch_messages`, `fetch_message_ids`, `fetch_message`, `fetch_inbox`, `fetch_pending_messages`, `fetch_delivery_receipts`, `fetch_dm_headers`, `send_dm` | [message.md](message.md) |
15+
| [Chatlog](chatlog.md) | `fetch_chatlog`, `fetch_chatlog_previews`, `fetch_conversations` | [chatlog.md](chatlog.md) |
16+
| [Notice](notice.md) | `fetch_notices` | [notice.md](notice.md) |
17+
| [Mesh](mesh.md) | `fetch_relay_status` | [mesh.md](mesh.md) |
18+
| [Metrics](metrics.md) | `fetch_traffic_history` | [metrics.md](metrics.md) |
19+
20+
### Universal Dispatch
21+
22+
**POST /rpc/v1/exec** — execute any registered command.
23+
24+
Request:
25+
```json
26+
{"command": "ping", "args": {}}
27+
```
28+
29+
Response: command-specific JSON.
30+
31+
### Raw Frame Dispatch
32+
33+
**POST /rpc/v1/frame** — accept a raw JSON protocol frame and dispatch it through `CommandTable`, falling back to `HandleLocalFrame` for unregistered frame types.
34+
35+
Request: a raw protocol frame JSON object with a `type` field:
36+
```json
37+
{"type": "fetch_chatlog", "topic": "dm", "address": "peer-addr-123"}
38+
```
39+
40+
Response: the command's response (JSON).
41+
42+
Dispatch logic:
43+
44+
1. The frame's `type` is extracted as the command name, wire field names are normalized to RPC arg names via `normalizeFrameArgs`.
45+
2. If the command is registered in `CommandTable`, it is dispatched there.
46+
3. If the command is not found in `CommandTable`, the raw frame is forwarded to `HandleLocalFrame` with all caller-supplied wire fields preserved.
47+
48+
This endpoint is only available when the server is created with a `NodeProvider`.
49+
50+
---
51+
52+
## Русский
53+
54+
Документация по группам команд RPC-слоя CORSA. Обзор архитектуры, конфигурация, CLI и интеграция — в родительском [rpc.md](../rpc.md).
55+
56+
### Индекс команд
57+
58+
| Группа | Команды | Файл |
59+
|---|---|---|
60+
| [Системные](system.md) | `help`, `ping`, `hello`, `version` | [system.md](system.md) |
61+
| [Сеть](network.md) | `get_peers`, `fetch_peer_health`, `fetch_network_stats`, `add_peer` | [network.md](network.md) |
62+
| [Идентификация](identity.md) | `fetch_identities`, `fetch_contacts`, `fetch_trusted_contacts` | [identity.md](identity.md) |
63+
| [Сообщения](message.md) | `fetch_messages`, `fetch_message_ids`, `fetch_message`, `fetch_inbox`, `fetch_pending_messages`, `fetch_delivery_receipts`, `fetch_dm_headers`, `send_dm` | [message.md](message.md) |
64+
| [История чатов](chatlog.md) | `fetch_chatlog`, `fetch_chatlog_previews`, `fetch_conversations` | [chatlog.md](chatlog.md) |
65+
| [Уведомления](notice.md) | `fetch_notices` | [notice.md](notice.md) |
66+
| [Mesh](mesh.md) | `fetch_relay_status` | [mesh.md](mesh.md) |
67+
| [Метрики](metrics.md) | `fetch_traffic_history` | [metrics.md](metrics.md) |
68+
69+
### Универсальная диспетчеризация
70+
71+
**POST /rpc/v1/exec** — выполнение любой зарегистрированной команды.
72+
73+
Запрос:
74+
```json
75+
{"command": "ping", "args": {}}
76+
```
77+
78+
Ответ: JSON, специфичный для команды.
79+
80+
### Диспетчеризация фреймов
81+
82+
**POST /rpc/v1/frame** — принимает сырой JSON-фрейм протокола и диспетчеризует его через `CommandTable`, с fallback на `HandleLocalFrame` для незарегистрированных типов фреймов.
83+
84+
Запрос: сырой JSON-объект фрейма протокола с полем `type`:
85+
```json
86+
{"type": "fetch_chatlog", "topic": "dm", "address": "peer-addr-123"}
87+
```
88+
89+
Ответ: JSON ответа команды.
90+
91+
Логика диспетчеризации:
92+
93+
1. Из фрейма извлекается `type` как имя команды, wire-имена полей нормализуются в RPC-аргументы через `normalizeFrameArgs`.
94+
2. Если команда зарегистрирована в `CommandTable`, она диспетчеризуется туда.
95+
3. Если команда не найдена в `CommandTable`, сырой фрейм пересылается в `HandleLocalFrame` с сохранением всех wire-полей отправителя.
96+
97+
Эндпоинт доступен только когда сервер создан с `NodeProvider`.

docs/rpc/chatlog.md

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# Chat History Commands
2+
3+
## English
4+
5+
Available only in desktop mode. In standalone node mode returns 503.
6+
7+
### POST /rpc/v1/chatlog/entries
8+
9+
Fetch chat history entries for a specific peer conversation.
10+
11+
Request: `{"topic": "dm", "peer_address": "address"}`
12+
13+
| Field | Type | Required | Description |
14+
|---|---|---|---|
15+
| `topic` | string | Yes | Message topic (default: `"dm"`) |
16+
| `peer_address` | string | Yes | Transport address of the conversation peer |
17+
18+
#### CLI
19+
20+
```bash
21+
# Positional arguments (topic peer_address)
22+
corsa-cli fetch_chatlog dm 10.0.0.5:64646
23+
24+
# Named arguments
25+
corsa-cli fetch_chatlog topic=dm peer_address=10.0.0.5:64646
26+
27+
# JSON
28+
corsa-cli '{"type": "fetch_chatlog", "topic": "dm", "address": "10.0.0.5:64646"}'
29+
```
30+
31+
Note: JSON wire format uses `address`, the RPC handler expects `peer_address`. The `normalizeFrameArgs` layer maps `address``peer_address` automatically when pasting wire frames into the console.
32+
33+
#### Console
34+
35+
```
36+
fetch_chatlog dm 10.0.0.5:64646
37+
```
38+
39+
### POST /rpc/v1/chatlog/previews
40+
41+
Last message from each peer. No arguments.
42+
43+
#### CLI
44+
45+
```bash
46+
corsa-cli fetch_chatlog_previews
47+
```
48+
49+
#### Console
50+
51+
```
52+
fetch_chatlog_previews
53+
```
54+
55+
### POST /rpc/v1/chatlog/conversations
56+
57+
Metadata for all conversations. No arguments.
58+
59+
#### CLI
60+
61+
```bash
62+
corsa-cli fetch_conversations
63+
```
64+
65+
#### Console
66+
67+
```
68+
fetch_conversations
69+
```
70+
71+
---
72+
73+
## Русский
74+
75+
Доступно только в desktop-режиме. В режиме standalone-ноды возвращает 503.
76+
77+
### POST /rpc/v1/chatlog/entries
78+
79+
Получение записей истории чата для конкретного собеседника.
80+
81+
Запрос: `{"topic": "dm", "peer_address": "address"}`
82+
83+
| Поле | Тип | Обязательное | Описание |
84+
|---|---|---|---|
85+
| `topic` | string | Да | Топик сообщений (по умолчанию: `"dm"`) |
86+
| `peer_address` | string | Да | Транспортный адрес собеседника |
87+
88+
#### CLI
89+
90+
```bash
91+
# Позиционные аргументы (topic peer_address)
92+
corsa-cli fetch_chatlog dm 10.0.0.5:64646
93+
94+
# Именованные аргументы
95+
corsa-cli fetch_chatlog topic=dm peer_address=10.0.0.5:64646
96+
97+
# JSON
98+
corsa-cli '{"type": "fetch_chatlog", "topic": "dm", "address": "10.0.0.5:64646"}'
99+
```
100+
101+
Примечание: JSON wire-формат использует `address`, RPC-обработчик ожидает `peer_address`. Слой `normalizeFrameArgs` автоматически маппит `address``peer_address` при вставке wire-фреймов в консоль.
102+
103+
#### Консоль
104+
105+
```
106+
fetch_chatlog dm 10.0.0.5:64646
107+
```
108+
109+
### POST /rpc/v1/chatlog/previews
110+
111+
Последнее сообщение от каждого пира. Без аргументов.
112+
113+
#### CLI
114+
115+
```bash
116+
corsa-cli fetch_chatlog_previews
117+
```
118+
119+
#### Консоль
120+
121+
```
122+
fetch_chatlog_previews
123+
```
124+
125+
### POST /rpc/v1/chatlog/conversations
126+
127+
Метаданные всех разговоров. Без аргументов.
128+
129+
#### CLI
130+
131+
```bash
132+
corsa-cli fetch_conversations
133+
```
134+
135+
#### Консоль
136+
137+
```
138+
fetch_conversations
139+
```

docs/rpc/identity.md

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# Identity Commands
2+
3+
## English
4+
5+
All identity commands require no arguments.
6+
7+
### POST /rpc/v1/identity/identities
8+
9+
All known identities (ed25519 fingerprints observed on the network).
10+
11+
#### CLI
12+
13+
```bash
14+
corsa-cli fetch_identities
15+
```
16+
17+
#### Console
18+
19+
```
20+
fetch_identities
21+
```
22+
23+
### POST /rpc/v1/identity/contacts
24+
25+
All contacts (identities with associated metadata such as display name).
26+
27+
#### CLI
28+
29+
```bash
30+
corsa-cli fetch_contacts
31+
```
32+
33+
#### Console
34+
35+
```
36+
fetch_contacts
37+
```
38+
39+
### POST /rpc/v1/identity/trusted_contacts
40+
41+
Trusted contacts (TOFU pinned — identity verified on first contact and locked).
42+
43+
#### CLI
44+
45+
```bash
46+
corsa-cli fetch_trusted_contacts
47+
```
48+
49+
#### Console
50+
51+
```
52+
fetch_trusted_contacts
53+
```
54+
55+
---
56+
57+
## Русский
58+
59+
Все команды идентификации не требуют аргументов.
60+
61+
### POST /rpc/v1/identity/identities
62+
63+
Все известные идентификаторы (ed25519-отпечатки, обнаруженные в сети).
64+
65+
#### CLI
66+
67+
```bash
68+
corsa-cli fetch_identities
69+
```
70+
71+
#### Консоль
72+
73+
```
74+
fetch_identities
75+
```
76+
77+
### POST /rpc/v1/identity/contacts
78+
79+
Все контакты (идентификаторы с ассоциированными метаданными, например отображаемое имя).
80+
81+
#### CLI
82+
83+
```bash
84+
corsa-cli fetch_contacts
85+
```
86+
87+
#### Консоль
88+
89+
```
90+
fetch_contacts
91+
```
92+
93+
### POST /rpc/v1/identity/trusted_contacts
94+
95+
Доверенные контакты (закреплённые по TOFU — идентификатор подтверждён при первом контакте и зафиксирован).
96+
97+
#### CLI
98+
99+
```bash
100+
corsa-cli fetch_trusted_contacts
101+
```
102+
103+
#### Консоль
104+
105+
```
106+
fetch_trusted_contacts
107+
```

0 commit comments

Comments
 (0)