A fork of the Cocoon PDS but being made more distributed.
11

Configure Feed

Select the types of activity you want to include in your feed.

cleanup plc operation stuff

Hailey (Mar 29, 2025, 4:20 PM -0700) b9831175 4cb0fad5

+89 -61
+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 + }