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.
 
 
 
 
 
 

668 lines
16 KiB

syntax = "proto3";
package orlydb.v1;
option go_package = "next.orly.dev/pkg/proto/orlydb/v1;orlydbv1";
import "orlydb/v1/types.proto";
// DatabaseService provides gRPC access to the ORLY database
service DatabaseService {
// === Lifecycle Methods ===
// GetPath returns the database file path
rpc GetPath(Empty) returns (PathResponse);
// Sync flushes buffers to disk
rpc Sync(Empty) returns (Empty);
// Ready returns whether the database is ready to serve requests
rpc Ready(Empty) returns (ReadyResponse);
// SetLogLevel sets the database log level
rpc SetLogLevel(SetLogLevelRequest) returns (Empty);
// === Event Storage ===
// SaveEvent stores an event, returns whether it already existed
rpc SaveEvent(SaveEventRequest) returns (SaveEventResponse);
// GetSerialsFromFilter gets serial numbers matching a filter
rpc GetSerialsFromFilter(GetSerialsFromFilterRequest) returns (SerialList);
// WouldReplaceEvent checks if an event would replace existing ones
rpc WouldReplaceEvent(WouldReplaceEventRequest) returns (WouldReplaceEventResponse);
// === Event Queries (Streaming for large results) ===
// QueryEvents queries events matching a filter (with deletion filtering)
rpc QueryEvents(QueryEventsRequest) returns (stream EventBatch);
// QueryAllVersions queries all versions of replaceable events
rpc QueryAllVersions(QueryEventsRequest) returns (stream EventBatch);
// QueryEventsWithOptions provides full control over query behavior
rpc QueryEventsWithOptions(QueryEventsWithOptionsRequest) returns (stream EventBatch);
// QueryDeleteEventsByTargetId queries deletion events for a target
rpc QueryDeleteEventsByTargetId(QueryDeleteEventsByTargetIdRequest) returns (stream EventBatch);
// QueryForSerials queries just serial numbers matching a filter
rpc QueryForSerials(QueryEventsRequest) returns (SerialList);
// QueryForIds queries ID/Pubkey/Timestamp triplets
rpc QueryForIds(QueryEventsRequest) returns (IdPkTsList);
// CountEvents counts events matching a filter
rpc CountEvents(QueryEventsRequest) returns (CountEventsResponse);
// === Event Retrieval by Serial ===
// FetchEventBySerial fetches a single event by serial
rpc FetchEventBySerial(FetchEventBySerialRequest) returns (FetchEventBySerialResponse);
// FetchEventsBySerials fetches multiple events by serial (batch)
rpc FetchEventsBySerials(FetchEventsBySerialRequest) returns (EventMap);
// GetSerialById gets the serial for a single event ID
rpc GetSerialById(GetSerialByIdRequest) returns (GetSerialByIdResponse);
// GetSerialsByIds gets serials for multiple event IDs
rpc GetSerialsByIds(GetSerialsByIdsRequest) returns (SerialMap);
// GetSerialsByRange gets serials within an index range
rpc GetSerialsByRange(GetSerialsByRangeRequest) returns (SerialList);
// GetFullIdPubkeyBySerial gets full ID/Pubkey/Timestamp for a serial
rpc GetFullIdPubkeyBySerial(GetFullIdPubkeyBySerialRequest) returns (IdPkTs);
// GetFullIdPubkeyBySerials gets full data for multiple serials
rpc GetFullIdPubkeyBySerials(GetFullIdPubkeyBySerialsRequest) returns (IdPkTsList);
// === Event Deletion ===
// DeleteEvent deletes an event by ID
rpc DeleteEvent(DeleteEventRequest) returns (Empty);
// DeleteEventBySerial deletes an event by serial
rpc DeleteEventBySerial(DeleteEventBySerialRequest) returns (Empty);
// DeleteExpired deletes events with expired expiration tags
rpc DeleteExpired(Empty) returns (Empty);
// ProcessDelete processes a deletion event (NIP-09)
rpc ProcessDelete(ProcessDeleteRequest) returns (Empty);
// CheckForDeleted checks if an event was deleted
rpc CheckForDeleted(CheckForDeletedRequest) returns (Empty);
// === Import/Export (Streaming) ===
// Import imports events from a stream
rpc Import(stream ImportChunk) returns (ImportResponse);
// Export exports events to a stream
rpc Export(ExportRequest) returns (stream ExportChunk);
// ImportEventsFromStrings imports events from JSON strings
rpc ImportEventsFromStrings(ImportEventsFromStringsRequest) returns (ImportResponse);
// === Relay Identity ===
// GetRelayIdentitySecret gets the relay's secret key
rpc GetRelayIdentitySecret(Empty) returns (GetRelayIdentitySecretResponse);
// SetRelayIdentitySecret sets the relay's secret key
rpc SetRelayIdentitySecret(SetRelayIdentitySecretRequest) returns (Empty);
// GetOrCreateRelayIdentitySecret gets or creates the relay's secret key
rpc GetOrCreateRelayIdentitySecret(Empty) returns (GetRelayIdentitySecretResponse);
// === Markers (Key-Value Storage) ===
// SetMarker sets a metadata marker
rpc SetMarker(SetMarkerRequest) returns (Empty);
// GetMarker gets a metadata marker
rpc GetMarker(GetMarkerRequest) returns (GetMarkerResponse);
// HasMarker checks if a marker exists
rpc HasMarker(HasMarkerRequest) returns (HasMarkerResponse);
// DeleteMarker deletes a marker
rpc DeleteMarker(DeleteMarkerRequest) returns (Empty);
// === Subscriptions (Payment-Based Access) ===
// GetSubscription gets subscription info for a pubkey
rpc GetSubscription(GetSubscriptionRequest) returns (Subscription);
// IsSubscriptionActive checks if a subscription is active
rpc IsSubscriptionActive(IsSubscriptionActiveRequest) returns (IsSubscriptionActiveResponse);
// ExtendSubscription extends a subscription by days
rpc ExtendSubscription(ExtendSubscriptionRequest) returns (Empty);
// RecordPayment records a payment
rpc RecordPayment(RecordPaymentRequest) returns (Empty);
// GetPaymentHistory gets payment history for a pubkey
rpc GetPaymentHistory(GetPaymentHistoryRequest) returns (PaymentList);
// ExtendBlossomSubscription extends blossom storage subscription
rpc ExtendBlossomSubscription(ExtendBlossomSubscriptionRequest) returns (Empty);
// GetBlossomStorageQuota gets blossom storage quota
rpc GetBlossomStorageQuota(GetBlossomStorageQuotaRequest) returns (GetBlossomStorageQuotaResponse);
// IsFirstTimeUser checks if this is a first-time user
rpc IsFirstTimeUser(IsFirstTimeUserRequest) returns (IsFirstTimeUserResponse);
// === NIP-43 Invite-Based ACL ===
// AddNIP43Member adds a member via invite code
rpc AddNIP43Member(AddNIP43MemberRequest) returns (Empty);
// RemoveNIP43Member removes a member
rpc RemoveNIP43Member(RemoveNIP43MemberRequest) returns (Empty);
// IsNIP43Member checks if a pubkey is a member
rpc IsNIP43Member(IsNIP43MemberRequest) returns (IsNIP43MemberResponse);
// GetNIP43Membership gets membership details
rpc GetNIP43Membership(GetNIP43MembershipRequest) returns (NIP43Membership);
// GetAllNIP43Members gets all members
rpc GetAllNIP43Members(Empty) returns (PubkeyList);
// StoreInviteCode stores an invite code with expiration
rpc StoreInviteCode(StoreInviteCodeRequest) returns (Empty);
// ValidateInviteCode validates an invite code
rpc ValidateInviteCode(ValidateInviteCodeRequest) returns (ValidateInviteCodeResponse);
// DeleteInviteCode deletes an invite code
rpc DeleteInviteCode(DeleteInviteCodeRequest) returns (Empty);
// PublishNIP43MembershipEvent publishes a membership event
rpc PublishNIP43MembershipEvent(PublishNIP43MembershipEventRequest) returns (Empty);
// === Query Cache ===
// GetCachedJSON gets cached JSON for a filter
rpc GetCachedJSON(GetCachedJSONRequest) returns (GetCachedJSONResponse);
// CacheMarshaledJSON caches JSON for a filter
rpc CacheMarshaledJSON(CacheMarshaledJSONRequest) returns (Empty);
// GetCachedEvents gets cached events for a filter
rpc GetCachedEvents(GetCachedEventsRequest) returns (GetCachedEventsResponse);
// CacheEvents caches events for a filter
rpc CacheEvents(CacheEventsRequest) returns (Empty);
// InvalidateQueryCache invalidates the entire query cache
rpc InvalidateQueryCache(Empty) returns (Empty);
// === Access Tracking ===
// RecordEventAccess records an access to an event
rpc RecordEventAccess(RecordEventAccessRequest) returns (Empty);
// GetEventAccessInfo gets access info for an event
rpc GetEventAccessInfo(GetEventAccessInfoRequest) returns (GetEventAccessInfoResponse);
// GetLeastAccessedEvents gets least accessed events for GC
rpc GetLeastAccessedEvents(GetLeastAccessedEventsRequest) returns (SerialList);
// === Blob Storage (Blossom) ===
// SaveBlob stores a blob with its metadata
rpc SaveBlob(SaveBlobRequest) returns (Empty);
// GetBlob retrieves blob data and metadata
rpc GetBlob(GetBlobRequest) returns (GetBlobResponse);
// HasBlob checks if a blob exists
rpc HasBlob(HasBlobRequest) returns (HasBlobResponse);
// DeleteBlob deletes a blob
rpc DeleteBlob(DeleteBlobRequest) returns (Empty);
// ListBlobs lists blobs for a pubkey
rpc ListBlobs(ListBlobsRequest) returns (ListBlobsResponse);
// GetBlobMetadata gets only metadata for a blob
rpc GetBlobMetadata(GetBlobMetadataRequest) returns (BlobMetadata);
// GetTotalBlobStorageUsed gets total storage used by a pubkey in MB
rpc GetTotalBlobStorageUsed(GetTotalBlobStorageUsedRequest) returns (GetTotalBlobStorageUsedResponse);
// SaveBlobReport stores a report for a blob (BUD-09)
rpc SaveBlobReport(SaveBlobReportRequest) returns (Empty);
// ListAllBlobUserStats gets storage statistics for all users
rpc ListAllBlobUserStats(Empty) returns (ListAllBlobUserStatsResponse);
// === Utility ===
// EventIdsBySerial gets event IDs by serial range
rpc EventIdsBySerial(EventIdsBySerialRequest) returns (EventIdsBySerialResponse);
// RunMigrations runs database migrations
rpc RunMigrations(Empty) returns (Empty);
}
// === Request/Response Messages ===
// Lifecycle
message PathResponse {
string path = 1;
}
message ReadyResponse {
bool ready = 1;
}
message SetLogLevelRequest {
string level = 1;
}
// Event Storage
message SaveEventRequest {
Event event = 1;
}
message SaveEventResponse {
bool exists = 1;
}
message GetSerialsFromFilterRequest {
Filter filter = 1;
}
message WouldReplaceEventRequest {
Event event = 1;
}
message WouldReplaceEventResponse {
bool would_replace = 1;
repeated uint64 replaced_serials = 2;
}
// Event Queries
message QueryEventsRequest {
Filter filter = 1;
}
message QueryEventsWithOptionsRequest {
Filter filter = 1;
bool include_delete_events = 2;
bool show_all_versions = 3;
}
message QueryDeleteEventsByTargetIdRequest {
bytes target_event_id = 1;
}
message CountEventsResponse {
int32 count = 1;
bool approximate = 2;
}
// Event Retrieval
message FetchEventBySerialRequest {
uint64 serial = 1;
}
message FetchEventBySerialResponse {
Event event = 1;
bool found = 2;
}
message FetchEventsBySerialRequest {
repeated uint64 serials = 1;
}
message GetSerialByIdRequest {
bytes id = 1;
}
message GetSerialByIdResponse {
uint64 serial = 1;
bool found = 2;
}
message GetSerialsByIdsRequest {
repeated bytes ids = 1;
}
message GetSerialsByRangeRequest {
Range range = 1;
}
message GetFullIdPubkeyBySerialRequest {
uint64 serial = 1;
}
message GetFullIdPubkeyBySerialsRequest {
repeated uint64 serials = 1;
}
// Event Deletion
message DeleteEventRequest {
bytes event_id = 1;
}
message DeleteEventBySerialRequest {
uint64 serial = 1;
Event event = 2;
}
message ProcessDeleteRequest {
Event event = 1;
repeated bytes admins = 2;
}
message CheckForDeletedRequest {
Event event = 1;
repeated bytes admins = 2;
}
// Import/Export
message ImportChunk {
bytes data = 1;
}
message ImportResponse {
int64 events_imported = 1;
int64 events_skipped = 2;
}
message ExportRequest {
repeated bytes pubkeys = 1;
}
message ExportChunk {
bytes data = 1;
}
message ImportEventsFromStringsRequest {
repeated string event_jsons = 1;
bool check_policy = 2;
}
// Relay Identity
message GetRelayIdentitySecretResponse {
bytes secret_key = 1;
}
message SetRelayIdentitySecretRequest {
bytes secret_key = 1;
}
// Markers
message SetMarkerRequest {
string key = 1;
bytes value = 2;
}
message GetMarkerRequest {
string key = 1;
}
message GetMarkerResponse {
bytes value = 1;
bool found = 2;
}
message HasMarkerRequest {
string key = 1;
}
message HasMarkerResponse {
bool exists = 1;
}
message DeleteMarkerRequest {
string key = 1;
}
// Subscriptions
message GetSubscriptionRequest {
bytes pubkey = 1;
}
message IsSubscriptionActiveRequest {
bytes pubkey = 1;
}
message IsSubscriptionActiveResponse {
bool active = 1;
}
message ExtendSubscriptionRequest {
bytes pubkey = 1;
int32 days = 2;
}
message RecordPaymentRequest {
bytes pubkey = 1;
int64 amount = 2;
string invoice = 3;
string preimage = 4;
}
message GetPaymentHistoryRequest {
bytes pubkey = 1;
}
message ExtendBlossomSubscriptionRequest {
bytes pubkey = 1;
string tier = 2;
int64 storage_mb = 3;
int32 days_extended = 4;
}
message GetBlossomStorageQuotaRequest {
bytes pubkey = 1;
}
message GetBlossomStorageQuotaResponse {
int64 quota_mb = 1;
}
message IsFirstTimeUserRequest {
bytes pubkey = 1;
}
message IsFirstTimeUserResponse {
bool first_time = 1;
}
// NIP-43
message AddNIP43MemberRequest {
bytes pubkey = 1;
string invite_code = 2;
}
message RemoveNIP43MemberRequest {
bytes pubkey = 1;
}
message IsNIP43MemberRequest {
bytes pubkey = 1;
}
message IsNIP43MemberResponse {
bool is_member = 1;
}
message GetNIP43MembershipRequest {
bytes pubkey = 1;
}
message StoreInviteCodeRequest {
string code = 1;
int64 expires_at = 2;
}
message ValidateInviteCodeRequest {
string code = 1;
}
message ValidateInviteCodeResponse {
bool valid = 1;
}
message DeleteInviteCodeRequest {
string code = 1;
}
message PublishNIP43MembershipEventRequest {
int32 kind = 1;
bytes pubkey = 2;
}
// Query Cache
message GetCachedJSONRequest {
Filter filter = 1;
}
message GetCachedJSONResponse {
repeated bytes json_items = 1;
bool found = 2;
}
message CacheMarshaledJSONRequest {
Filter filter = 1;
repeated bytes json_items = 2;
}
message GetCachedEventsRequest {
Filter filter = 1;
}
message GetCachedEventsResponse {
repeated Event events = 1;
bool found = 2;
}
message CacheEventsRequest {
Filter filter = 1;
repeated Event events = 2;
}
// Access Tracking
message RecordEventAccessRequest {
uint64 serial = 1;
string connection_id = 2;
}
message GetEventAccessInfoRequest {
uint64 serial = 1;
}
message GetEventAccessInfoResponse {
int64 last_access = 1;
uint32 access_count = 2;
}
message GetLeastAccessedEventsRequest {
int32 limit = 1;
int64 min_age_sec = 2;
}
// Utility
message EventIdsBySerialRequest {
uint64 start = 1;
int32 count = 2;
}
message EventIdsBySerialResponse {
repeated uint64 event_ids = 1;
}
// === Blob Storage Messages ===
message BlobMetadata {
bytes pubkey = 1;
string mime_type = 2;
int64 size = 3;
int64 uploaded = 4; // Unix timestamp
string extension = 5;
}
message BlobDescriptor {
string url = 1;
string sha256 = 2;
int64 size = 3;
string type = 4; // MIME type
int64 uploaded = 5;
}
message SaveBlobRequest {
bytes sha256_hash = 1;
bytes data = 2;
bytes pubkey = 3;
string mime_type = 4;
string extension = 5;
}
message GetBlobRequest {
bytes sha256_hash = 1;
}
message GetBlobResponse {
bool found = 1;
bytes data = 2;
BlobMetadata metadata = 3;
}
message HasBlobRequest {
bytes sha256_hash = 1;
}
message HasBlobResponse {
bool exists = 1;
}
message DeleteBlobRequest {
bytes sha256_hash = 1;
bytes pubkey = 2;
}
message ListBlobsRequest {
bytes pubkey = 1;
int64 since = 2;
int64 until = 3;
}
message ListBlobsResponse {
repeated BlobDescriptor descriptors = 1;
}
message GetBlobMetadataRequest {
bytes sha256_hash = 1;
}
message GetTotalBlobStorageUsedRequest {
bytes pubkey = 1;
}
message GetTotalBlobStorageUsedResponse {
int64 total_mb = 1;
}
message SaveBlobReportRequest {
bytes sha256_hash = 1;
bytes report_data = 2;
}
message UserBlobStats {
string pubkey_hex = 1;
int64 blob_count = 2;
int64 total_size_bytes = 3;
}
message ListAllBlobUserStatsResponse {
repeated UserBlobStats stats = 1;
}