package main import ( "context" "fmt" "os" "strconv" "strings" "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)", 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", DisableSliceFlagSeparator: true, 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", Aliases: []string{"i"}, 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, DisableSliceFlagSeparator: true, Flags: flags, Action: func(ctx context.Context, c *cli.Command) error { relayUrls := c.StringSlice("relay") relays := connectToAllRelays(ctx, c, relayUrls, nil) 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 } logverbose("%s", evt) log("- publishing job request... ") first := true for res := range sys.Pool.PublishMany(ctx, relayUrls, evt) { cleanUrl, _ := strings.CutPrefix(res.RelayURL, "wss://") if !first { log(", ") } first = false if res.Error != nil { log("%s: %s", colors.errorf(cleanUrl), res.Error) } else { log("%s: ok", colors.successf(cleanUrl)) } } log("\n- waiting for response...\n") 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 })()...), }