package main import ( "context" "encoding/base64" "fmt" "os" "os/exec" "strings" "github.com/fiatjaf/cli/v3" "github.com/nbd-wtf/go-nostr" "golang.org/x/exp/slices" ) var curlFlags []string var curl = &cli.Command{ Name: "curl", Usage: "calls curl but with a nip98 header", Description: "accepts all flags and arguments exactly as they would be passed to curl.", Flags: defaultKeyFlags, Action: func(ctx context.Context, c *cli.Command) error { kr, _, err := gatherKeyerFromArguments(ctx, c) if err != nil { return err } // cowboy parsing of curl flags to get the data we need for nip98 var url string method := "GET" nextIsMethod := false for _, f := range curlFlags { if strings.HasPrefix(f, "https://") || strings.HasPrefix(f, "http://") { url = f } else if f == "--request" || f == "-X" { nextIsMethod = true } else if nextIsMethod { method = f method, _ = strings.CutPrefix(method, `"`) method, _ = strings.CutSuffix(method, `"`) method = strings.ToUpper(method) } nextIsMethod = false } if url == "" { return fmt.Errorf("can't create nip98 event: target url is empty") } // make and sign event evt := nostr.Event{ Kind: 27235, CreatedAt: nostr.Now(), Tags: nostr.Tags{ {"u", url}, {"method", method}, }, } if err := kr.SignEvent(ctx, &evt); err != nil { return err } // the first 2 indexes of curlFlags were reserved for this curlFlags[0] = "-H" curlFlags[1] = fmt.Sprintf("Authorization: Nostr %s", base64.StdEncoding.EncodeToString([]byte(evt.String()))) // call curl cmd := exec.Command("curl", curlFlags...) cmd.Stderr = os.Stderr cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout cmd.Run() return nil }, } func realCurl() error { curlFlags = make([]string, 2, len(os.Args)-4) keyFlags := make([]string, 0, 5) for i := 0; i < len(os.Args[2:]); i++ { arg := os.Args[i+2] if slices.ContainsFunc(defaultKeyFlags, func(f cli.Flag) bool { bareArg, _ := strings.CutPrefix(arg, "-") bareArg, _ = strings.CutPrefix(bareArg, "-") return slices.Contains(f.Names(), bareArg) }) { keyFlags = append(keyFlags, arg) if arg != "--prompt-sec" { i++ val := os.Args[i+2] keyFlags = append(keyFlags, val) } } else { curlFlags = append(curlFlags, arg) } } return curl.Run(context.Background(), keyFlags) }