this repo has no description

cleanup plc operation stuff

Hailey b9831175 4cb0fad5

Changed files
+89 -61
plc
+42 -61
plc/client.go
··· 14 14 "strings" 15 15 16 16 "github.com/bluesky-social/indigo/atproto/crypto" 17 - "github.com/bluesky-social/indigo/atproto/data" 18 17 "github.com/bluesky-social/indigo/util" 19 18 ) 20 19 21 20 type Client struct { 22 - h *http.Client 23 - 21 + h *http.Client 24 22 service string 23 + pdsHostname string 25 24 rotationKey *crypto.PrivateKeyK256 26 - recoveryKey string 27 - pdsHostname string 28 25 } 29 26 30 27 type ClientArgs struct { 31 28 Service string 32 29 RotationKey []byte 33 - RecoveryKey string 34 30 PdsHostname string 35 31 } 36 32 ··· 48 44 h: util.RobustHTTPClient(), 49 45 service: args.Service, 50 46 rotationKey: rk, 51 - recoveryKey: args.RecoveryKey, 52 47 pdsHostname: args.PdsHostname, 53 48 }, nil 54 49 } 55 50 56 - func (c *Client) CreateDID(ctx context.Context, sigkey *crypto.PrivateKeyK256, recovery string, handle string) (string, map[string]any, error) { 51 + func (c *Client) CreateDID(ctx context.Context, sigkey *crypto.PrivateKeyK256, recovery string, handle string) (string, *PlcOperation, error) { 52 + pubsigkey, err := sigkey.PublicKey() 53 + if err != nil { 54 + return "", nil, err 55 + } 56 + 57 57 pubrotkey, err := c.rotationKey.PublicKey() 58 58 if err != nil { 59 59 return "", nil, err ··· 61 61 62 62 // todo 63 63 rotationKeys := []string{pubrotkey.DIDKey()} 64 - if c.recoveryKey != "" { 65 - rotationKeys = []string{c.recoveryKey, rotationKeys[0]} 66 - } 67 64 if recovery != "" { 68 65 rotationKeys = func(recovery string) []string { 69 66 newRotationKeys := []string{recovery} ··· 74 71 }(recovery) 75 72 } 76 73 77 - op, err := c.FormatAndSignAtprotoOp(sigkey, handle, rotationKeys, nil) 74 + op := PlcOperation{ 75 + Type: "plc_operation", 76 + VerificationMethods: map[string]string{ 77 + "atproto": pubsigkey.DIDKey(), 78 + }, 79 + RotationKeys: rotationKeys, 80 + AlsoKnownAs: []string{ 81 + "at://" + handle, 82 + }, 83 + Services: map[string]PlcOperationService{ 84 + "atproto_pds": { 85 + Type: "AtprotoPersonalDataServer", 86 + Endpoint: "https://" + c.pdsHostname, 87 + }, 88 + }, 89 + Prev: nil, 90 + } 91 + 92 + signed, err := c.FormatAndSignAtprotoOp(sigkey, op) 78 93 if err != nil { 79 94 return "", nil, err 80 95 } 81 96 82 - did, err := didForCreateOp(op) 97 + did, err := didFromOp(signed) 83 98 if err != nil { 84 99 return "", nil, err 85 100 } 86 101 87 - return did, op, nil 102 + return did, &op, nil 88 103 } 89 104 90 - func (c *Client) UpdateUserHandle(ctx context.Context, didstr string, nhandle string) error { 91 - return nil 92 - } 93 - 94 - func (c *Client) FormatAndSignAtprotoOp(sigkey *crypto.PrivateKeyK256, handle string, rotationKeys []string, prev *string) (map[string]any, error) { 95 - pubsigkey, err := sigkey.PublicKey() 105 + func didFromOp(op *PlcOperation) (string, error) { 106 + b, err := op.MarshalCBOR() 96 107 if err != nil { 97 - return nil, err 108 + return "", err 98 109 } 99 - 100 - op := map[string]any{ 101 - "type": "plc_operation", 102 - "verificationMethods": map[string]string{ 103 - "atproto": pubsigkey.DIDKey(), 104 - }, 105 - "rotationKeys": rotationKeys, 106 - "alsoKnownAs": []string{"at://" + handle}, 107 - "services": map[string]any{ 108 - "atproto_pds": map[string]string{ 109 - "type": "AtprotoPersonalDataServer", 110 - "endpoint": "https://" + c.pdsHostname, 111 - }, 112 - }, 113 - "prev": prev, 114 - } 110 + s := sha256.Sum256(b) 111 + b32 := strings.ToLower(base32.StdEncoding.EncodeToString(s[:])) 112 + return "did:plc:" + b32[0:24], nil 113 + } 115 114 116 - b, err := data.MarshalCBOR(op) 115 + func (c *Client) FormatAndSignAtprotoOp(sigkey *crypto.PrivateKeyK256, op PlcOperation) (*PlcOperation, error) { 116 + b, err := op.MarshalCBOR() 117 117 if err != nil { 118 118 return nil, err 119 119 } ··· 123 123 return nil, err 124 124 } 125 125 126 - op["sig"] = base64.RawURLEncoding.EncodeToString(sig) 126 + op.Sig = base64.RawURLEncoding.EncodeToString(sig) 127 127 128 - return op, nil 128 + return &op, nil 129 129 } 130 130 131 - func didForCreateOp(op map[string]any) (string, error) { 132 - b, err := data.MarshalCBOR(op) 133 - if err != nil { 134 - return "", err 135 - } 136 - 137 - h := sha256.New() 138 - h.Write(b) 139 - bs := h.Sum(nil) 140 - 141 - b32 := strings.ToLower(base32.StdEncoding.EncodeToString(bs)) 142 - 143 - return "did:plc:" + b32[0:24], nil 144 - } 145 - 146 - func (c *Client) SendOperation(ctx context.Context, did string, op any) error { 131 + func (c *Client) SendOperation(ctx context.Context, did string, op *PlcOperation) error { 147 132 b, err := json.Marshal(op) 148 133 if err != nil { 149 134 return err ··· 162 147 } 163 148 defer resp.Body.Close() 164 149 165 - fmt.Println(resp.StatusCode) 166 - 167 150 b, err = io.ReadAll(resp.Body) 168 151 if err != nil { 169 - return err 152 + return fmt.Errorf("error sending operation. status code: %d, response: %s", resp.StatusCode, string(b)) 170 153 } 171 - 172 - fmt.Println(string(b)) 173 154 174 155 return nil 175 156 }
+47
plc/types.go
··· 1 + package plc 2 + 3 + import ( 4 + "encoding/json" 5 + 6 + "github.com/bluesky-social/indigo/atproto/data" 7 + cbg "github.com/whyrusleeping/cbor-gen" 8 + ) 9 + 10 + type PlcOperation struct { 11 + Type string `json:"type"` 12 + VerificationMethods map[string]string `json:"verificationMethods"` 13 + RotationKeys []string `json:"rotationKeys"` 14 + AlsoKnownAs []string `json:"alsoKnownAs"` 15 + Services map[string]PlcOperationService `json:"services"` 16 + Prev *string `json:"prev"` 17 + Sig string `json:"sig,omitempty"` 18 + } 19 + 20 + type PlcOperationService struct { 21 + Type string `json:"type"` 22 + Endpoint string `json:"endpoint"` 23 + } 24 + 25 + // This is kinda gross. We could just use cborgen i suppose? 26 + func (po *PlcOperation) MarshalCBOR() ([]byte, error) { 27 + if po == nil { 28 + return cbg.CborNull, nil 29 + } 30 + 31 + b, err := json.Marshal(po) 32 + if err != nil { 33 + return nil, err 34 + } 35 + 36 + var m map[string]any 37 + if err := json.Unmarshal(b, &m); err != nil { 38 + return nil, err 39 + } 40 + 41 + b, err = data.MarshalCBOR(m) 42 + if err != nil { 43 + return nil, err 44 + } 45 + 46 + return b, nil 47 + }