this repo has no description
1package main 2 3import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 "io" 8 "net" 9 "net/http" 10 "strings" 11 12 "github.com/bluesky-social/indigo/atproto/syntax" 13) 14 15func resolveHandle(ctx context.Context, handle string) (string, error) { 16 var did string 17 18 _, err := syntax.ParseHandle(handle) 19 if err != nil { 20 return "", err 21 } 22 23 recs, err := net.LookupTXT(fmt.Sprintf("_atproto.%s", handle)) 24 if err == nil { 25 for _, rec := range recs { 26 if strings.HasPrefix(rec, "did=") { 27 did = strings.Split(rec, "did=")[1] 28 break 29 } 30 } 31 } 32 33 if did == "" { 34 req, err := http.NewRequestWithContext( 35 ctx, 36 "GET", 37 fmt.Sprintf("https://%s/.well-known/atproto-did", handle), 38 nil, 39 ) 40 if err != nil { 41 return "", err 42 } 43 44 resp, err := http.DefaultClient.Do(req) 45 if err != nil { 46 return "", err 47 } 48 defer resp.Body.Close() 49 50 if resp.StatusCode != http.StatusOK { 51 io.Copy(io.Discard, resp.Body) 52 return "", fmt.Errorf("unable to resolve handle") 53 } 54 55 b, err := io.ReadAll(resp.Body) 56 if err != nil { 57 return "", err 58 } 59 60 maybeDid := string(b) 61 62 if _, err := syntax.ParseDID(maybeDid); err != nil { 63 return "", fmt.Errorf("unable to resolve handle") 64 } 65 66 did = maybeDid 67 } 68 69 return did, nil 70} 71 72func resolveService(ctx context.Context, did string) (string, error) { 73 type Identity struct { 74 Service []struct { 75 ID string `json:"id"` 76 Type string `json:"type"` 77 ServiceEndpoint string `json:"serviceEndpoint"` 78 } `json:"service"` 79 } 80 81 var ustr string 82 if strings.HasPrefix(did, "did:plc:") { 83 ustr = fmt.Sprintf("https://plc.directory/%s", did) 84 } else if strings.HasPrefix(did, "did:web:") { 85 ustr = fmt.Sprintf("https://%s/.well-known/did.json", strings.TrimPrefix(did, "did:web:")) 86 } else { 87 return "", fmt.Errorf("did was not a supported did type") 88 } 89 90 req, err := http.NewRequestWithContext(ctx, "GET", ustr, nil) 91 if err != nil { 92 return "", err 93 } 94 95 resp, err := http.DefaultClient.Do(req) 96 if err != nil { 97 return "", err 98 } 99 defer resp.Body.Close() 100 101 if resp.StatusCode != 200 { 102 io.Copy(io.Discard, resp.Body) 103 return "", fmt.Errorf("could not find identity in plc registry") 104 } 105 106 var identity Identity 107 if err := json.NewDecoder(resp.Body).Decode(&identity); err != nil { 108 return "", err 109 } 110 111 var service string 112 for _, svc := range identity.Service { 113 if svc.ID == "#atproto_pds" { 114 service = svc.ServiceEndpoint 115 } 116 } 117 118 if service == "" { 119 return "", fmt.Errorf("could not find atproto_pds service in identity services") 120 } 121 122 return service, nil 123}