diff --git a/dvm.go b/dvm.go new file mode 100644 index 0000000..659ca61 --- /dev/null +++ b/dvm.go @@ -0,0 +1,134 @@ +package main + +import ( + "context" + "fmt" + "os" + "strconv" + "strings" + + "github.com/fatih/color" + "github.com/nbd-wtf/go-nostr" + "github.com/nbd-wtf/go-nostr/nip90" + "github.com/urfave/cli/v3" +) + +var dvm = &cli.Command{ + Name: "dvm", + Usage: "deal with nip90 data-vending-machine things (experimental)", + Description: `example usage: + nak dvm 5001 --input "What is the capital of France?" --input-type text --output "text/plain" --bid 1000 wss://relay.example.com`, + DisableSliceFlagSeparator: true, + Flags: append(defaultKeyFlags, + &cli.StringSliceFlag{ + Name: "relay", + Aliases: []string{"r"}, + }, + ), + Commands: append([]*cli.Command{ + { + Name: "list", + Usage: "find DVMs that have announced themselves for a specific kind", + Action: func(ctx context.Context, c *cli.Command) error { + return fmt.Errorf("we don't know how to do this yet") + }, + }, + }, (func() []*cli.Command { + commands := make([]*cli.Command, len(nip90.Jobs)) + for i, job := range nip90.Jobs { + flags := make([]cli.Flag, 0, 2+len(job.Params)) + + if job.InputType != "" { + flags = append(flags, &cli.StringSliceFlag{ + Name: "input", + Category: "INPUT", + }) + } + + for _, param := range job.Params { + flags = append(flags, &cli.StringSliceFlag{ + Name: param, + Category: "PARAMETER", + }) + } + + commands[i] = &cli.Command{ + Name: strconv.Itoa(job.InputKind), + Usage: job.Name, + Description: job.Description, + Flags: flags, + Action: func(ctx context.Context, c *cli.Command) error { + relayUrls := c.StringSlice("relay") + relays := connectToAllRelays(ctx, relayUrls, false) + if len(relays) == 0 { + log("failed to connect to any of the given relays.\n") + os.Exit(3) + } + defer func() { + for _, relay := range relays { + relay.Close() + } + }() + + evt := nostr.Event{ + Kind: job.InputKind, + Tags: make(nostr.Tags, 0, 2+len(job.Params)), + CreatedAt: nostr.Now(), + } + + for _, input := range c.StringSlice("input") { + evt.Tags = append(evt.Tags, nostr.Tag{"i", input, job.InputType}) + } + for _, paramN := range job.Params { + for _, paramV := range c.StringSlice(paramN) { + tag := nostr.Tag{"param", paramN, "", ""}[0:2] + for _, v := range strings.Split(paramV, ";") { + tag = append(tag, v) + } + evt.Tags = append(evt.Tags, tag) + } + } + + kr, _, err := gatherKeyerFromArguments(ctx, c) + if err != nil { + return err + } + if err := kr.SignEvent(ctx, &evt); err != nil { + return err + } + + log("- publishing job request... ") + first := true + for res := range sys.Pool.PublishMany(ctx, relayUrls, evt) { + cleanUrl, ok := strings.CutPrefix(res.RelayURL, "wss://") + if !ok { + cleanUrl = res.RelayURL + } + + if !first { + log(", ") + } + first = false + + if res.Error != nil { + log("%s: %s", color.RedString(cleanUrl), res.Error) + } else { + log("%s: ok", color.GreenString(cleanUrl)) + } + } + + log("\n- waiting for response...") + for ie := range sys.Pool.SubscribeMany(ctx, relayUrls, nostr.Filter{ + Kinds: []int{7000, job.OutputKind}, + Tags: nostr.TagMap{"e": []string{evt.ID}}, + }) { + stdout(ie.Event) + } + + return nil + }, + } + } + return commands + })()...), +} diff --git a/event.go b/event.go index d30bec8..dbc2a7c 100644 --- a/event.go +++ b/event.go @@ -140,7 +140,6 @@ example: os.Exit(3) } } - defer func() { for _, relay := range relays { relay.Close() diff --git a/go.mod b/go.mod index 0866e84..b0bf039 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/mailru/easyjson v0.9.0 github.com/mark3labs/mcp-go v0.8.3 github.com/markusmobius/go-dateparser v1.2.3 - github.com/nbd-wtf/go-nostr v0.50.1 + github.com/nbd-wtf/go-nostr v0.50.2 github.com/urfave/cli/v3 v3.0.0-beta1 golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 ) @@ -70,3 +70,5 @@ require ( golang.org/x/sys v0.30.0 // indirect golang.org/x/text v0.21.0 // indirect ) + +replace github.com/nbd-wtf/go-nostr => ../go-nostr diff --git a/go.sum b/go.sum index 9f4c18c..1ef0112 100644 --- a/go.sum +++ b/go.sum @@ -133,8 +133,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/nbd-wtf/go-nostr v0.50.1 h1:l02wKcnYVyvjnj53CNB3I/C161uoH1W51sPWbrLb9C0= -github.com/nbd-wtf/go-nostr v0.50.1/go.mod h1:gOzf8mcTlMs7e+LjYDssRU4Vb/YGeeYO61aDNrxDStY= +github.com/nbd-wtf/go-nostr v0.50.2 h1:OMmxztiAPj9cjZ16C+Z13YTJBF91RKEm4HZm5ogKD/c= +github.com/nbd-wtf/go-nostr v0.50.2/go.mod h1:gOzf8mcTlMs7e+LjYDssRU4Vb/YGeeYO61aDNrxDStY= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= diff --git a/main.go b/main.go index 495f129..96c4b47 100644 --- a/main.go +++ b/main.go @@ -40,6 +40,7 @@ var app = &cli.Command{ wallet, mcpServer, curl, + dvm, }, Version: version, Flags: []cli.Flag{ diff --git a/relay.go b/relay.go index 36f5729..e464fcb 100644 --- a/relay.go +++ b/relay.go @@ -10,10 +10,10 @@ import ( "io" "net/http" - "github.com/urfave/cli/v3" "github.com/nbd-wtf/go-nostr" "github.com/nbd-wtf/go-nostr/nip11" "github.com/nbd-wtf/go-nostr/nip86" + "github.com/urfave/cli/v3" ) var relay = &cli.Command{ @@ -45,9 +45,7 @@ var relay = &cli.Command{ return nil }, Commands: (func() []*cli.Command { - commands := make([]*cli.Command, 0, 12) - - for _, def := range []struct { + methods := []struct { method string args []string }{ @@ -69,7 +67,10 @@ var relay = &cli.Command{ {"blockip", []string{"ip", "reason"}}, {"unblockip", []string{"ip", "reason"}}, {"listblockedips", nil}, - } { + } + + commands := make([]*cli.Command, 0, len(methods)) + for _, def := range methods { def := def flags := make([]cli.Flag, len(def.args), len(def.args)+4)