AeroNyx Chat Relay client entegrasyonu

AeroNyx19 Haziran 20264 dk okuma29 görüntüleme

Blind relay, mutual-contact presence, reciprocal read receipts, encrypted reactions, offline queue ve resumable encrypted media için client contract.

AeroNyx client geliştiren App, frontend, backend ve coding agent ekipleri için resmi frame ve media API contract. Relay yalnızca ciphertext route eder, içeriği yorumlamaz.

Değiştirilemez gizlilik ilkesi

Relay chat/reaction plaintext, voice/media, key, nonce, waveform, filename, transcript, MemChain, packet payload, DNS, destination, URL, history, wallet traffic veya private seed analiz edemez, saklayamaz, çıkaramaz. Client transport öncesi E2E şifreler.

E2E content payload_b64 ve payload_sig içindedir. Visible metadata type, IDs, receiver/group, timestamps, delivery state, blob size/expiry, access mode ve counters ile sınırlıdır.

Çevrimiçi durum gizlilik ilkesi

Online ve last seen yalnızca iki yönde aktif P2PContact varsa görünür. Backend iki tarafı kontrol ederek public key scan’i önler. Presence ve exact last seen ayrı kapatılabilir.

Hidden result online veya last_seen_ts içermez; reason=not_mutual_contact ya da reason=presence_hidden döner.

Profil gizliliği API'si

Client bağlantıda profile privacy flags okur ve UI’ı backend enforcement ile uyumlu tutar. PATCH nested privacy ve eski top-level fields kabul eder.

http
GET /api/relay/profile/
PATCH /api/relay/profile/
Authorization: Relay <pubkey>:<timestamp>:<signature>
json
{
  "privacy": {
    "presence_enabled": true,
    "last_seen_enabled": false,
    "read_receipts_enabled": false
  }
}

Çevrimiçi durum çerçeveleri

presence_subscribe yalnızca contacts için gönderilir. last_seen_enabled=false ise yaklaşık durum gösterin veya zamanı gizleyin; diğer sinyallerden exact status çıkarmayın.

json
{
  "type": "presence_subscribe",
  "pubkeys": ["contact-pubkey-a", "contact-pubkey-b"]
}
json
{
  "type": "presence_subscribe_ack",
  "updates": [{
    "pubkey": "contact-pubkey-a",
    "visible": true,
    "presence_visible": true,
    "last_seen_visible": true,
    "online": true,
    "last_seen_ts": 1780000000,
    "reason": "allowed"
  }],
  "server_ts": 1780000001
}

Karşılıklı okundu bilgisi kuralı

Read receipts reciprocal’dır: kapatan kullanıcı message_read göndermez ve peer read göstermez. Bir taraf kapalıysa veya mutual contact yoksa backend frame’i suppress eder. Yalnız metadata içerir.

json
{
  "type": "message_read",
  "msg_id": "message-id",
  "receiver_pubkey": "original-sender-pubkey",
  "timestamp": 1780000200
}
json
{
  "type": "message_read_ack",
  "msg_id": "message-id",
  "delivered": false,
  "suppressed": true,
  "reason": "receiver_read_receipts_disabled"
}

Reasons: client_disabled, not_mutual_contact, reader_read_receipts_disabled, receiver_read_receipts_disabled; offline pull aynı gate’i kullanır.

Emoji tepkileri

Reaction da E2E ciphertext’tir. Relay receiver/membership ile route eder, reaction_id ile deduplicate eder ve offline durumda store-and-forward uygular. Aggregate state client’a aittir.

json
{
  "type": "message_reaction",
  "msg_id": "target-message-id",
  "receiver_pubkey": "peer-pubkey",
  "reaction_id": "unique-reaction-event-id",
  "timestamp": 1780000300,
  "payload_b64": "e2e-ciphertext",
  "payload_sig": "ed25519-signature"
}

Discriminant 12; reaction_id idempotency/offline ACK key’idir. ACK message_reaction_ack; group group_message_reaction, group_id, key_version kullanır.

Şifreli medya nesnesi modeli

Voice, image, video ve file upload’dan önce şifrelenir. blob_id, key, nonce, duration, waveform, display filename ve preview metadata relay_send.payload_b64 içinde kalır, blob API açık alanına girmez.

json
{
  "kind": "voice",
  "blob_id": "blob-uuid",
  "key_b64": "inside-e2e-envelope",
  "nonce_b64": "inside-e2e-envelope",
  "duration_ms": 43000,
  "waveform": [0, 3, 8, 6, 2],
  "media_type": "audio/ogg; codecs=opus",
  "file_size": 7340032
}

Basit şifreli nesne yükleme

Short voice ve small image için multipart kullanın. Server sadece encrypted bytes alır; TTL default 7 gün, policy 1–30. Download unguessable capability veya authenticated P2P key ile yapılır.

http
POST /api/relay/blob/
Authorization: Relay <pubkey>:<timestamp>:<signature>
Content-Type: multipart/form-data
fieldrequiredvalue
filetrueciphertext
media_kindfalsevoice, image, video, file, avatar, other
media_typefalseMIME
ttl_daysfalse1..30
access_modefalsecapability, authenticated
allowed_downloadersfalseJSON P2P pubkey array

Simple limit 10 MB; aşım HTTP 413, error_code=blob_too_large, chunked_max_bytes=104857600 döndürür.

Devam ettirilebilir şifreli nesne yükleme

Simple limit üstünde chunk session kullanın. Ciphertext total en fazla 100 MB; aynı chunk index güvenle retry edilir. upload_id, chunk_size, completed indexes local saklanır.

1. Yükleme oturumu oluşturma

http
POST /api/relay/blob/session/
Authorization: Relay <pubkey>:<timestamp>:<signature>
Content-Type: application/json
json
{
  "total_size": 7340032,
  "chunk_size": 1048576,
  "media_type": "audio/ogg",
  "media_kind": "voice",
  "ttl_days": 7,
  "access_mode": "authenticated",
  "allowed_downloaders": ["receiver-pubkey"]
}

2. Parçaları yükleme

http
PUT /api/relay/blob/session/{upload_id}/chunk/{chunk_index}/
Authorization: Relay <pubkey>:<timestamp>:<signature>
Content-Type: application/octet-stream

Default chunk 1 MB, maximum 4 MB; aynı index retry eski chunk’ı değiştirir ve idempotent’tir.

3. Ağ kesintisinden sonra devam etme

http
GET /api/relay/blob/session/{upload_id}/
Authorization: Relay <pubkey>:<timestamp>:<signature>

missing_chunks okuyup yalnız eksik index’leri gönderin. Session 24 saat geçerlidir.

4. Yüklemeyi tamamlama

http
POST /api/relay/blob/session/{upload_id}/complete/
Authorization: Relay <pubkey>:<timestamp>:<signature>

Complete chunks ve total bytes doğrular; safe retry mevcut final blob döndürür, duplicate yaratmaz.

5. Yüklemeyi iptal etme

http
DELETE /api/relay/blob/session/{upload_id}/
Authorization: Relay <pubkey>:<timestamp>:<signature>

Şifreli nesneyi indirme

Capability UUID bearer capability olduğundan RelayAuth istemez. Authenticated imza ister ve uploader veya allowed_downloaders erişir. Expired blob access sırasında silinir.

http
GET /api/relay/blob/{blob_id}/
HTTPerror_code
400blob_id_invalid
401auth_required
403download_forbidden
404blob_not_found
410blob_expired
413blob_too_large, blob_total_size_too_large, chunk_too_large
409upload_incomplete

İstemci UX rehberi

Small file için simple upload, max_bytes sonrası chunks kullanın. App restart sonrası missing_chunks okuyun. Secrets E2E’de kalsın; 410 blob_expired resend action olsun.

AI aracısı entegrasyon sırası

Agent sırasıyla RelayAuth, profile privacy, presence UI, reciprocal reads, reaction idempotency, simple blob, chunk resume ve relay_send reference uygular. Server-side chat search eklemez.

Doğrulanmış iki atlamalı teslimat

Eligible ChatRelay network-diverse two-hop path seçebilir. Source expected terminal signed receipt doğrulandıktan sonra delivery sayar; middle node ciphertext route eder.

Node discovery ve doğrulanabilir encrypted delivery