package main import ( "bytes" "context" "fmt" "io" "log" "os" "net/http" "net/http/httputil" "github.com/joho/godotenv" x402 "github.com/x402-foundation/x402/go/v2" x402http "github.com/x402-foundation/x402/go/v2/http" evm "github.com/x402-foundation/x402/go/v2/mechanisms/evm/exact/client" evmsigners "github.com/x402-foundation/x402/go/v2/signers/evm" ) type LoggingRoundTripper struct { Proxied http.RoundTripper } func (lrt *LoggingRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { var err error if req.GetBody != nil { rc, _ := req.GetBody() req.Body = rc } // Dump request reqDump, err := httputil.DumpRequestOut(req, true) if err != nil { log.Printf("Error dumping request: %v", err) } else { fmt.Printf("\n--- REQUEST ---\n%s\n----------------\n", reqDump) } // Perform request resp, err := lrt.Proxied.RoundTrip(req) if err != nil { return nil, err } // Dump response respDump, err := httputil.DumpResponse(resp, true) if err != nil { log.Printf("Error dumping response: %v", err) } else { fmt.Printf("\n--- RESPONSE ---\n%s\n----------------\n", respDump) } return resp, nil } func main() { godotenv.Load() var ( privateKey = os.Getenv("PRIVATE_KEY") serverURL = "https://api.naco.li/v1" ctx = context.Background() ) signer, err := evmsigners.NewClientSignerFromPrivateKey(privateKey) if err != nil { log.Fatal("Failed to create EVM signer:", err) } x402Client := x402.Newx402Client(). Register("eip155:*", evm.NewExactEvmScheme(signer, nil)) debugClient := &http.Client{ Transport: &LoggingRoundTripper{ Proxied: http.DefaultTransport, }, } httpClient := x402http.WrapHTTPClientWithPayment( debugClient, x402http.Newx402HTTPClient(x402Client), ) log.Println("Starting REST API tests...") log.Println("\nCalling getFeed (free tool) via HTTP client...") bodyGetFeed := []byte(`{"uri": "https://bsky.app/profile/did:plc:z72i7hdynmk6r22z27h6tvur/feed/whats-hot"}`) resp, err := httpClient.Post(fmt.Sprintf("%s/getFeed", serverURL), "application/json", bytes.NewReader(bodyGetFeed)) if err != nil { log.Println("getFeed HTTP request failed:", err) } else { defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) log.Printf("getFeed Response Status: %s\n", resp.Status) log.Printf("getFeed Response Body: %s\n", string(body)) } log.Println("\nCalling getPost (gated paid tool) via HTTP client...") bodyGetPost := []byte(`{"actor":"sharkgamiart.bsky.social","rkey":"3m47y27c67c2b"}`) req, err := http.NewRequestWithContext(ctx, "POST", fmt.Sprintf("%s/getPost", serverURL), bytes.NewReader(bodyGetPost)) if err != nil { log.Fatal("Failed to create getPost request:", err) } req.GetBody = func() (io.ReadCloser, error) { return io.NopCloser(bytes.NewReader(bodyGetPost)), nil } req.Header.Set("Content-Type", "application/json") respPost, err := httpClient.Do(req) if err != nil { log.Println("getPost HTTP request failed:", err) } else { defer respPost.Body.Close() body, _ := io.ReadAll(respPost.Body) log.Printf("getPost Response Status: %s\n", respPost.Status) log.Printf("getPost Response Body: %s\n", string(body)) } }