add first draft graph query implementation
Some checks failed
Go / build-and-release (push) Has been cancelled
Some checks failed
Go / build-and-release (push) Has been cancelled
This commit is contained in:
@@ -25,6 +25,7 @@ import (
|
||||
"git.mleku.dev/mleku/nostr/encoders/reason"
|
||||
"git.mleku.dev/mleku/nostr/encoders/tag"
|
||||
"next.orly.dev/pkg/policy"
|
||||
"next.orly.dev/pkg/protocol/graph"
|
||||
"next.orly.dev/pkg/protocol/nip43"
|
||||
"git.mleku.dev/mleku/nostr/utils/normalize"
|
||||
"git.mleku.dev/mleku/nostr/utils/pointers"
|
||||
@@ -142,6 +143,71 @@ func (l *Listener) HandleReq(msg []byte) (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Check for NIP-XX graph queries in filters
|
||||
// Graph queries use the _graph filter extension to traverse the social graph
|
||||
for _, f := range *env.Filters {
|
||||
if f != nil && graph.IsGraphQuery(f) {
|
||||
graphQuery, graphErr := graph.ExtractFromFilter(f)
|
||||
if graphErr != nil {
|
||||
log.W.F("invalid _graph query from %s: %v", l.remote, graphErr)
|
||||
if err = closedenvelope.NewFrom(
|
||||
env.Subscription,
|
||||
reason.Error.F("invalid _graph query: %s", graphErr.Error()),
|
||||
).Write(l); chk.E(err) {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
if graphQuery != nil {
|
||||
log.I.F("graph query from %s: method=%s seed=%s depth=%d",
|
||||
l.remote, graphQuery.Method, graphQuery.Seed, graphQuery.Depth)
|
||||
|
||||
// Check if graph executor is available
|
||||
if l.graphExecutor == nil {
|
||||
log.W.F("graph query received but executor not initialized")
|
||||
if err = closedenvelope.NewFrom(
|
||||
env.Subscription,
|
||||
reason.Error.F("graph queries not supported on this relay"),
|
||||
).Write(l); chk.E(err) {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Execute the graph query
|
||||
resultEvent, execErr := l.graphExecutor.Execute(graphQuery)
|
||||
if execErr != nil {
|
||||
log.W.F("graph query execution failed from %s: %v", l.remote, execErr)
|
||||
if err = closedenvelope.NewFrom(
|
||||
env.Subscription,
|
||||
reason.Error.F("graph query failed: %s", execErr.Error()),
|
||||
).Write(l); chk.E(err) {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Send the result event
|
||||
var res *eventenvelope.Result
|
||||
if res, err = eventenvelope.NewResultWith(env.Subscription, resultEvent); chk.E(err) {
|
||||
return
|
||||
}
|
||||
if err = res.Write(l); chk.E(err) {
|
||||
return
|
||||
}
|
||||
|
||||
// Send EOSE to signal completion
|
||||
if err = eoseenvelope.NewFrom(env.Subscription).Write(l); chk.E(err) {
|
||||
return
|
||||
}
|
||||
|
||||
log.I.F("graph query completed for %s: method=%s, returned event kind %d",
|
||||
l.remote, graphQuery.Method, resultEvent.Kind)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter out policy config events (kind 12345) for non-policy-admin users
|
||||
// Policy config events should only be visible to policy administrators
|
||||
if l.policyManager != nil && l.policyManager.IsEnabled() {
|
||||
|
||||
18
app/main.go
18
app/main.go
@@ -18,6 +18,7 @@ import (
|
||||
"next.orly.dev/pkg/database"
|
||||
"git.mleku.dev/mleku/nostr/encoders/bech32encoding"
|
||||
"next.orly.dev/pkg/policy"
|
||||
"next.orly.dev/pkg/protocol/graph"
|
||||
"next.orly.dev/pkg/protocol/nip43"
|
||||
"next.orly.dev/pkg/protocol/publish"
|
||||
"next.orly.dev/pkg/spider"
|
||||
@@ -120,6 +121,23 @@ func Run(
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize graph query executor (only for Badger backend)
|
||||
if badgerDB, ok := db.(*database.D); ok {
|
||||
// Get relay identity key for signing graph query responses
|
||||
relaySecretKey, err := badgerDB.GetOrCreateRelayIdentitySecret()
|
||||
if err != nil {
|
||||
log.E.F("failed to get relay identity key for graph executor: %v", err)
|
||||
} else {
|
||||
// Create the graph adapter and executor
|
||||
graphAdapter := database.NewGraphAdapter(badgerDB)
|
||||
if l.graphExecutor, err = graph.NewExecutor(graphAdapter, relaySecretKey); err != nil {
|
||||
log.E.F("failed to create graph executor: %v", err)
|
||||
} else {
|
||||
log.I.F("graph query executor initialized")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize spider manager based on mode (only for Badger backend)
|
||||
if badgerDB, ok := db.(*database.D); ok && cfg.SpiderMode != "none" {
|
||||
if l.spiderManager, err = spider.New(ctx, badgerDB, l.publishers, cfg.SpiderMode); chk.E(err) {
|
||||
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
"next.orly.dev/pkg/policy"
|
||||
"git.mleku.dev/mleku/nostr/protocol/auth"
|
||||
"git.mleku.dev/mleku/nostr/httpauth"
|
||||
"next.orly.dev/pkg/protocol/graph"
|
||||
"next.orly.dev/pkg/protocol/nip43"
|
||||
"next.orly.dev/pkg/protocol/publish"
|
||||
"next.orly.dev/pkg/spider"
|
||||
@@ -62,6 +63,7 @@ type Server struct {
|
||||
clusterManager *dsync.ClusterManager
|
||||
blossomServer *blossom.Server
|
||||
InviteManager *nip43.InviteManager
|
||||
graphExecutor *graph.Executor
|
||||
cfg *config.C
|
||||
db database.Database // Changed from *database.D to interface
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user