From fcba12d7ae3cdb361c6321519fdaf5a537a6a871 Mon Sep 17 00:00:00 2001 From: bndw Date: Fri, 13 Feb 2026 17:52:42 -0800 Subject: feat: testclient can accept JSON events from stdin Usage: - Standalone: ./bin/testclient (generates event) - With nak: nak event "hello" | ./bin/testclient Compatible with nak CLI for easy event generation --- README.md | 18 ++++++++++++++-- cmd/testclient/main.go | 57 ++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 57 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index f3d961a..142b0f1 100644 --- a/README.md +++ b/README.md @@ -31,8 +31,8 @@ The relay will start listening on `:50051` (gRPC). ### Test with Client +**Standalone mode:** ```bash -# In another terminal: ./bin/testclient # Output: @@ -40,10 +40,24 @@ The relay will start listening on `:50051` (gRPC). # Publishing event... # ✓ Event published successfully: abc123... # Querying events... -# Found 1 events +# Found 1 events from author abc123... # - abc123...: Hello from gRPC client! ``` +**With nak CLI:** +```bash +# Pipe events from nak +nak event "Hello from nak!" | ./bin/testclient + +# Or generate a signed event +nak event --sec --kind 1 "My message" | ./bin/testclient + +# Output: +# Read event from stdin: abc123... +# Publishing event... +# ✓ Event published successfully: abc123... +``` + ## gRPC API See [proto/nostr/v1/nostr.proto](proto/nostr/v1/nostr.proto) for the full API. diff --git a/cmd/testclient/main.go b/cmd/testclient/main.go index 571751e..224d9d9 100644 --- a/cmd/testclient/main.go +++ b/cmd/testclient/main.go @@ -2,8 +2,11 @@ package main import ( "context" + "encoding/json" "flag" + "io" "log" + "os" "time" "google.golang.org/grpc" @@ -26,23 +29,45 @@ func main() { client := pb.NewNostrRelayClient(conn) ctx := context.Background() - key, err := nostr.GenerateKey() - if err != nil { - log.Fatalf("failed to generate key: %v", err) - } + var event *nostr.Event + + stat, _ := os.Stdin.Stat() + if (stat.Mode() & os.ModeCharDevice) == 0 { + data, err := io.ReadAll(os.Stdin) + if err != nil { + log.Fatalf("failed to read stdin: %v", err) + } + + event = &nostr.Event{} + if err := json.Unmarshal(data, event); err != nil { + log.Fatalf("failed to parse JSON event: %v", err) + } + + log.Printf("Read event from stdin: %s", event.ID[:16]) + } else { + key, err := nostr.GenerateKey() + if err != nil { + log.Fatalf("failed to generate key: %v", err) + } + + log.Printf("Generated key: %s", key.Npub()) - log.Printf("Generated key: %s", key.Npub()) + event = &nostr.Event{ + PubKey: key.Public(), + CreatedAt: time.Now().Unix(), + Kind: 1, + Tags: nostr.Tags{}, + Content: "Hello from gRPC client!", + } - event := &nostr.Event{ - PubKey: key.Public(), - CreatedAt: time.Now().Unix(), - Kind: 1, - Tags: nostr.Tags{}, - Content: "Hello from gRPC client!", + if err := key.Sign(event); err != nil { + log.Fatalf("failed to sign event: %v", err) + } } - if err := key.Sign(event); err != nil { - log.Fatalf("failed to sign event: %v", err) + tags := make([]*pb.Tag, len(event.Tags)) + for i, tag := range event.Tags { + tags[i] = &pb.Tag{Values: tag} } pbEvent := &pb.Event{ @@ -50,7 +75,7 @@ func main() { Pubkey: event.PubKey, CreatedAt: event.CreatedAt, Kind: int32(event.Kind), - Tags: []*pb.Tag{}, + Tags: tags, Content: event.Content, Sig: event.Sig, } @@ -71,14 +96,14 @@ func main() { log.Println("Querying events...") queryResp, err := client.QueryEvents(ctx, &pb.QueryRequest{ Filters: []*pb.Filter{ - {Authors: []string{key.Public()}}, + {Authors: []string{event.PubKey}}, }, }) if err != nil { log.Fatalf("failed to query: %v", err) } - log.Printf("Found %d events", len(queryResp.Events)) + log.Printf("Found %d events from author %s", len(queryResp.Events), event.PubKey[:16]) for _, e := range queryResp.Events { log.Printf(" - %s: %s", e.Id[:16], e.Content) } -- cgit v1.2.3