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