package main import ( "bytes" "encoding/json" "fmt" "io" "net/http" "os" "time" "github.com/golang-jwt/jwt/v5" "github.com/google/uuid" ) type Claims struct { SessionID string `json:"session_id"` PartyID string `json:"party_id"` TokenType string `json:"token_type"` jwt.RegisteredClaims } func generateAccessToken(secretKey, userID, username string) (string, error) { now := time.Now() claims := Claims{ PartyID: username, TokenType: "access", RegisteredClaims: jwt.RegisteredClaims{ ID: uuid.New().String(), Issuer: "mpc-system", Subject: userID, IssuedAt: jwt.NewNumericDate(now), NotBefore: jwt.NewNumericDate(now), ExpiresAt: jwt.NewNumericDate(now.Add(24 * time.Hour)), }, } token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) return token.SignedString([]byte(secretKey)) } func makeRequest(method, url string, body interface{}, token, apiKey string) (int, []byte, error) { var reqBody io.Reader if body != nil { jsonData, err := json.Marshal(body) if err != nil { return 0, nil, err } reqBody = bytes.NewBuffer(jsonData) } req, err := http.NewRequest(method, url, reqBody) if err != nil { return 0, nil, err } req.Header.Set("Content-Type", "application/json") req.Header.Set("X-API-Key", apiKey) req.Header.Set("Authorization", "Bearer "+token) client := &http.Client{Timeout: 10 * time.Second} resp, err := client.Do(req) if err != nil { return 0, nil, err } defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return 0, nil, err } return resp.StatusCode, respBody, nil } func main() { // Get JWT secret from environment or use test value jwtSecret := os.Getenv("JWT_SECRET_KEY") if jwtSecret == "" { jwtSecret = "change_this_jwt_secret_key_to_random_value_min_32_chars" } // Generate access token token, err := generateAccessToken(jwtSecret, "admin", "admin") if err != nil { fmt.Printf("Failed to generate token: %v\n", err) os.Exit(1) } // Get API key from environment or use test value apiKey := os.Getenv("MPC_API_KEY") if apiKey == "" { apiKey = "test-api-key" } // Use the wallet created from keygen test username := "wallet-f13135f7" baseURL := "http://localhost:4000/api/v1/accounts/by-username/" + username + "/signing-config" fmt.Println("===========================================") fmt.Println("Testing Signing Parties Configuration APIs") fmt.Println("===========================================") fmt.Printf("Username: %s\n\n", username) // Test 1: GET - Query current signing parties configuration fmt.Println("--------------------------------------------") fmt.Println("Test 1: GET signing-config (Query)") fmt.Println("--------------------------------------------") status, body, err := makeRequest("GET", baseURL, nil, token, apiKey) if err != nil { fmt.Printf("Error: %v\n", err) } else { fmt.Printf("Status: %d\n", status) var result map[string]interface{} json.Unmarshal(body, &result) prettyJSON, _ := json.MarshalIndent(result, "", " ") fmt.Printf("Response:\n%s\n", prettyJSON) } // Extract active parties from the response for later tests var activeParties []string var result map[string]interface{} json.Unmarshal(body, &result) if parties, ok := result["active_parties"].([]interface{}); ok { for _, p := range parties { if s, ok := p.(string); ok { activeParties = append(activeParties, s) } } } fmt.Printf("\nActive parties found: %v\n", activeParties) if len(activeParties) < 2 { fmt.Println("\nError: Need at least 2 active parties for testing") os.Exit(1) } // Test 2: POST - Set signing parties (select first 2 parties) fmt.Println("\n--------------------------------------------") fmt.Println("Test 2: POST signing-config (Set)") fmt.Println("--------------------------------------------") signingParties := activeParties[:2] // Select first 2 parties setData := map[string]interface{}{ "party_ids": signingParties, } fmt.Printf("Setting signing parties to: %v\n", signingParties) status, body, err = makeRequest("POST", baseURL, setData, token, apiKey) if err != nil { fmt.Printf("Error: %v\n", err) } else { fmt.Printf("Status: %d\n", status) var result map[string]interface{} json.Unmarshal(body, &result) prettyJSON, _ := json.MarshalIndent(result, "", " ") fmt.Printf("Response:\n%s\n", prettyJSON) } // Test 3: GET - Query again to verify it was set fmt.Println("\n--------------------------------------------") fmt.Println("Test 3: GET signing-config (Verify Set)") fmt.Println("--------------------------------------------") status, body, err = makeRequest("GET", baseURL, nil, token, apiKey) if err != nil { fmt.Printf("Error: %v\n", err) } else { fmt.Printf("Status: %d\n", status) var result map[string]interface{} json.Unmarshal(body, &result) prettyJSON, _ := json.MarshalIndent(result, "", " ") fmt.Printf("Response:\n%s\n", prettyJSON) } // Test 4: POST again - Should fail (already configured) fmt.Println("\n--------------------------------------------") fmt.Println("Test 4: POST signing-config (Should Fail - Already Set)") fmt.Println("--------------------------------------------") status, body, err = makeRequest("POST", baseURL, setData, token, apiKey) if err != nil { fmt.Printf("Error: %v\n", err) } else { fmt.Printf("Status: %d (expected 409 Conflict)\n", status) var result map[string]interface{} json.Unmarshal(body, &result) prettyJSON, _ := json.MarshalIndent(result, "", " ") fmt.Printf("Response:\n%s\n", prettyJSON) } // Test 5: PUT - Update signing parties (use different combination if possible) fmt.Println("\n--------------------------------------------") fmt.Println("Test 5: PUT signing-config (Update)") fmt.Println("--------------------------------------------") var updateParties []string if len(activeParties) >= 3 { // If we have 3 parties, use parties 2 and 3 (different combination) updateParties = []string{activeParties[1], activeParties[2]} } else { // Otherwise, reverse the order updateParties = []string{signingParties[1], signingParties[0]} } updateData := map[string]interface{}{ "party_ids": updateParties, } fmt.Printf("Updating signing parties to: %v\n", updateParties) status, body, err = makeRequest("PUT", baseURL, updateData, token, apiKey) if err != nil { fmt.Printf("Error: %v\n", err) } else { fmt.Printf("Status: %d\n", status) var result map[string]interface{} json.Unmarshal(body, &result) prettyJSON, _ := json.MarshalIndent(result, "", " ") fmt.Printf("Response:\n%s\n", prettyJSON) } // Test 6: GET - Query to verify update fmt.Println("\n--------------------------------------------") fmt.Println("Test 6: GET signing-config (Verify Update)") fmt.Println("--------------------------------------------") status, body, err = makeRequest("GET", baseURL, nil, token, apiKey) if err != nil { fmt.Printf("Error: %v\n", err) } else { fmt.Printf("Status: %d\n", status) var result map[string]interface{} json.Unmarshal(body, &result) prettyJSON, _ := json.MarshalIndent(result, "", " ") fmt.Printf("Response:\n%s\n", prettyJSON) } // Test 7: DELETE - Clear signing parties configuration fmt.Println("\n--------------------------------------------") fmt.Println("Test 7: DELETE signing-config (Clear)") fmt.Println("--------------------------------------------") status, body, err = makeRequest("DELETE", baseURL, nil, token, apiKey) if err != nil { fmt.Printf("Error: %v\n", err) } else { fmt.Printf("Status: %d\n", status) var result map[string]interface{} json.Unmarshal(body, &result) prettyJSON, _ := json.MarshalIndent(result, "", " ") fmt.Printf("Response:\n%s\n", prettyJSON) } // Test 8: GET - Query to verify cleared fmt.Println("\n--------------------------------------------") fmt.Println("Test 8: GET signing-config (Verify Cleared)") fmt.Println("--------------------------------------------") status, body, err = makeRequest("GET", baseURL, nil, token, apiKey) if err != nil { fmt.Printf("Error: %v\n", err) } else { fmt.Printf("Status: %d\n", status) var result map[string]interface{} json.Unmarshal(body, &result) prettyJSON, _ := json.MarshalIndent(result, "", " ") fmt.Printf("Response:\n%s\n", prettyJSON) } // Test 9: DELETE again - Should fail (not configured) fmt.Println("\n--------------------------------------------") fmt.Println("Test 9: DELETE signing-config (Should Fail - Not Configured)") fmt.Println("--------------------------------------------") status, body, err = makeRequest("DELETE", baseURL, nil, token, apiKey) if err != nil { fmt.Printf("Error: %v\n", err) } else { fmt.Printf("Status: %d (expected 404 Not Found)\n", status) var result map[string]interface{} json.Unmarshal(body, &result) prettyJSON, _ := json.MarshalIndent(result, "", " ") fmt.Printf("Response:\n%s\n", prettyJSON) } // Test 10: PUT when not configured - Should fail fmt.Println("\n--------------------------------------------") fmt.Println("Test 10: PUT signing-config (Should Fail - Not Configured)") fmt.Println("--------------------------------------------") status, body, err = makeRequest("PUT", baseURL, setData, token, apiKey) if err != nil { fmt.Printf("Error: %v\n", err) } else { fmt.Printf("Status: %d (expected 404 Not Found)\n", status) var result map[string]interface{} json.Unmarshal(body, &result) prettyJSON, _ := json.MarshalIndent(result, "", " ") fmt.Printf("Response:\n%s\n", prettyJSON) } fmt.Println("\n===========================================") fmt.Println("All tests completed!") fmt.Println("===========================================") }