You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

206 lines
7.2 KiB

syntax = "proto3";
package orlysync.negentropy.v1;
option go_package = "next.orly.dev/pkg/proto/orlysync/negentropy/v1;negentropyv1";
import "orlysync/common/v1/types.proto";
// NegentropyService provides NIP-77 negentropy-based set reconciliation
// for both relay-to-relay sync and client-facing WebSocket operations
service NegentropyService {
// === Lifecycle Methods ===
// Ready returns whether the service is ready to serve requests
rpc Ready(orlysync.common.v1.Empty) returns (orlysync.common.v1.ReadyResponse);
// Start starts the background relay-to-relay sync
rpc Start(orlysync.common.v1.Empty) returns (orlysync.common.v1.Empty);
// Stop stops the background sync
rpc Stop(orlysync.common.v1.Empty) returns (orlysync.common.v1.Empty);
// === Client-Facing NIP-77 (WebSocket Message Handling) ===
// These handle NEG-OPEN, NEG-MSG, NEG-CLOSE from WebSocket clients
// HandleNegOpen processes a NEG-OPEN message from a client
rpc HandleNegOpen(NegOpenRequest) returns (NegOpenResponse);
// HandleNegMsg processes a NEG-MSG message from a client
rpc HandleNegMsg(NegMsgRequest) returns (NegMsgResponse);
// HandleNegClose processes a NEG-CLOSE message from a client
rpc HandleNegClose(NegCloseRequest) returns (orlysync.common.v1.Empty);
// === Relay-to-Relay Sync ===
// SyncWithPeer initiates negentropy sync with a specific peer relay
rpc SyncWithPeer(SyncPeerRequest) returns (stream SyncProgress);
// GetSyncStatus returns the current sync status
rpc GetSyncStatus(orlysync.common.v1.Empty) returns (SyncStatusResponse);
// === Peer Management ===
// GetPeers returns the list of negentropy sync peers
rpc GetPeers(orlysync.common.v1.Empty) returns (PeersResponse);
// AddPeer adds a peer for negentropy sync
rpc AddPeer(AddPeerRequest) returns (orlysync.common.v1.Empty);
// RemovePeer removes a peer from negentropy sync
rpc RemovePeer(RemovePeerRequest) returns (orlysync.common.v1.Empty);
// === Sync Control ===
// TriggerSync manually triggers sync with a specific peer or all peers
rpc TriggerSync(TriggerSyncRequest) returns (orlysync.common.v1.Empty);
// GetPeerSyncState returns sync state for a specific peer
rpc GetPeerSyncState(PeerSyncStateRequest) returns (PeerSyncStateResponse);
// === Session Management ===
// ListSessions returns active client negentropy sessions
rpc ListSessions(orlysync.common.v1.Empty) returns (ListSessionsResponse);
// CloseSession forcefully closes a client session
rpc CloseSession(CloseSessionRequest) returns (orlysync.common.v1.Empty);
}
// === Client-Facing NIP-77 Messages ===
// NegOpenRequest processes a NEG-OPEN from client
// NEG-OPEN format: ["NEG-OPEN", subscription_id, filter, initial_message?]
message NegOpenRequest {
string subscription_id = 1; // Client's subscription ID
orlysync.common.v1.Filter filter = 2; // Nostr filter for reconciliation
bytes initial_message = 3; // Optional initial negentropy message
string connection_id = 4; // Connection ID for session tracking
}
// NegOpenResponse returns the initial negentropy response
message NegOpenResponse {
bytes message = 1; // Negentropy protocol message to send back
repeated bytes have_ids = 2; // Event IDs we have that client needs (if initial reconciliation completes)
repeated bytes need_ids = 3; // Event IDs we need from client (if initial reconciliation completes)
bool complete = 4; // True if reconciliation completed in first round
string error = 5; // Error message if failed
}
// NegMsgRequest processes a NEG-MSG from client
// NEG-MSG format: ["NEG-MSG", subscription_id, message]
message NegMsgRequest {
string subscription_id = 1;
bytes message = 2; // Negentropy protocol message
string connection_id = 3;
}
// NegMsgResponse returns reconciliation results
message NegMsgResponse {
bytes message = 1; // Negentropy protocol message to send back
repeated bytes have_ids = 2; // Event IDs we have that client needs
repeated bytes need_ids = 3; // Event IDs we need from client
bool complete = 4; // True if reconciliation is complete
string error = 5; // Error message if failed
}
// NegCloseRequest processes a NEG-CLOSE from client
// NEG-CLOSE format: ["NEG-CLOSE", subscription_id]
message NegCloseRequest {
string subscription_id = 1;
string connection_id = 2;
}
// === Relay-to-Relay Sync Messages ===
// SyncPeerRequest initiates sync with a peer
message SyncPeerRequest {
string peer_url = 1; // WebSocket URL of peer relay
orlysync.common.v1.Filter filter = 2; // Optional filter to limit sync scope
int64 since = 3; // Optional: only sync events since timestamp
}
// SyncProgress streams sync progress updates
message SyncProgress {
string peer_url = 1;
int32 round = 2; // Reconciliation round number
int64 have_count = 3; // Events we have that peer needs
int64 need_count = 4; // Events we need from peer
int64 fetched_count = 5; // Events fetched so far
int64 sent_count = 6; // Events sent so far
bool complete = 7; // True when sync is complete
string error = 8; // Error message if failed
}
// SyncStatusResponse contains overall sync status
message SyncStatusResponse {
bool active = 1; // Whether background sync is running
int64 last_sync = 2; // Timestamp of last sync
int32 peer_count = 3;
repeated PeerSyncState peer_states = 4;
}
// === Peer Management Messages ===
// PeersResponse contains the list of peers
message PeersResponse {
repeated string peers = 1; // List of peer WebSocket URLs
}
// AddPeerRequest adds a peer
message AddPeerRequest {
string peer_url = 1;
}
// RemovePeerRequest removes a peer
message RemovePeerRequest {
string peer_url = 1;
}
// TriggerSyncRequest triggers manual sync
message TriggerSyncRequest {
string peer_url = 1; // Optional: specific peer (empty = all)
orlysync.common.v1.Filter filter = 2; // Optional: filter for sync scope
}
// PeerSyncStateRequest requests state for a peer
message PeerSyncStateRequest {
string peer_url = 1;
}
// PeerSyncStateResponse contains peer sync state
message PeerSyncStateResponse {
PeerSyncState state = 1;
bool found = 2;
}
// PeerSyncState represents sync state for a peer
message PeerSyncState {
string peer_url = 1;
int64 last_sync = 2; // Timestamp of last successful sync
int64 events_synced = 3; // Total events synced from this peer
string status = 4; // "idle", "syncing", "error"
string last_error = 5; // Last error message
int32 consecutive_failures = 6;
}
// === Session Management Messages ===
// ClientSession represents an active client negentropy session
message ClientSession {
string subscription_id = 1;
string connection_id = 2;
int64 created_at = 3;
int64 last_activity = 4;
int32 round_count = 5; // Number of reconciliation rounds
}
// ListSessionsResponse contains active sessions
message ListSessionsResponse {
repeated ClientSession sessions = 1;
}
// CloseSessionRequest closes a session
message CloseSessionRequest {
string subscription_id = 1;
string connection_id = 2; // Optional: if empty, close all with this sub_id
}