package main import ( "context" "encoding/json" "fmt" "net/http" "net/http/httputil" "strings" "sync" "github.com/gin-gonic/gin" ) type DIDDocument struct { ID string `json:"id"` Service []struct { ID string `json:"id"` Type string `json:"type"` ServiceEndpoint string `json:"serviceEndpoint"` } `json:"service"` } func ResolveDID(did string) (*DIDDocument, error) { var url string if strings.HasPrefix(did, "did:plc:") { // Resolve via PLC Directory url = "https://plc.directory/" + did } else if strings.HasPrefix(did, "did:web:") { // Resolve via Web (simplified) domain := strings.TrimPrefix(did, "did:web:") url = "https://" + domain + "/.well-known/did.json" } else { return nil, fmt.Errorf("unsupported DID format: %s", did) } resp, err := http.Get(url) if err != nil { return nil, err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("resolver returned status: %d", resp.StatusCode) } var doc DIDDocument if err := json.NewDecoder(resp.Body).Decode(&doc); err != nil { return nil, err } return &doc, nil } type AsyncResult[T any] struct { Value T Err error } func MapConcurrent[T any, R any]( ctx context.Context, items []T, concurrencyLimit int, mapper func(context.Context, T, int) (R, error), ) []AsyncResult[R] { if len(items) == 0 { return nil } results := make([]AsyncResult[R], len(items)) var wg sync.WaitGroup sem := make(chan struct{}, concurrencyLimit) for i, item := range items { wg.Add(1) go func(idx int, input T) { defer wg.Done() sem <- struct{}{} defer func() { <-sem }() if ctx.Err() != nil { results[idx] = AsyncResult[R]{Err: ctx.Err()} return } val, err := mapper(ctx, input, idx) results[idx] = AsyncResult[R]{Value: val, Err: err} }(i, item) } wg.Wait() return results } func RunConcurrent(tasks ...func() error) []error { var wg sync.WaitGroup errs := make([]error, len(tasks)) wg.Add(len(tasks)) for i, task := range tasks { go func(i int, t func() error) { defer wg.Done() if err := t(); err != nil { errs[i] = err } }(i, task) } wg.Wait() return errs } func DebugMiddleware() gin.HandlerFunc { return func(c *gin.Context) { dump, err := httputil.DumpRequest(c.Request, true) if err == nil { fmt.Println("=== RAW REQUEST ===") fmt.Println(string(dump)) } c.Next() } }