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
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; |
|
}
|
|
|