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.

use new plc client

Hailey (Mar 29, 2025, 4:27 PM -0700) 536b10bd b9831175

+51 -32
+8 -7
identity/identity.go
··· 10 10 "strings" 11 11 12 12 "github.com/bluesky-social/indigo/atproto/syntax" 13 + "github.com/haileyok/cocoon/plc" 13 14 ) 14 15 15 16 func ResolveHandle(ctx context.Context, handle string) (string, error) { ··· 108 109 type DidLog []DidLogEntry 109 110 110 111 type DidLogEntry struct { 111 - Sig string `json:"sig"` 112 - Prev *string `json:"prev"` 113 - Type string `json:"string"` 114 - Services map[string]DidDataService `json:"services"` 115 - AlsoKnownAs []string `json:"alsoKnownAs"` 116 - RotationKeys []string `json:"rotationKeys"` 117 - VerificationMethods map[string]string `json:"verificationMethods"` 112 + Sig string `json:"sig"` 113 + Prev *string `json:"prev"` 114 + Type string `json:"string"` 115 + Services map[string]plc.OperationService `json:"services"` 116 + AlsoKnownAs []string `json:"alsoKnownAs"` 117 + RotationKeys []string `json:"rotationKeys"` 118 + VerificationMethods map[string]string `json:"verificationMethods"` 118 119 } 119 120 120 121 type DidAuditEntry struct {
+11 -12
plc/client.go
··· 48 48 }, nil 49 49 } 50 50 51 - func (c *Client) CreateDID(ctx context.Context, sigkey *crypto.PrivateKeyK256, recovery string, handle string) (string, *PlcOperation, error) { 51 + func (c *Client) CreateDID(ctx context.Context, sigkey *crypto.PrivateKeyK256, recovery string, handle string) (string, *Operation, error) { 52 52 pubsigkey, err := sigkey.PublicKey() 53 53 if err != nil { 54 54 return "", nil, err ··· 71 71 }(recovery) 72 72 } 73 73 74 - op := PlcOperation{ 74 + op := Operation{ 75 75 Type: "plc_operation", 76 76 VerificationMethods: map[string]string{ 77 77 "atproto": pubsigkey.DIDKey(), ··· 80 80 AlsoKnownAs: []string{ 81 81 "at://" + handle, 82 82 }, 83 - Services: map[string]PlcOperationService{ 83 + Services: map[string]OperationService{ 84 84 "atproto_pds": { 85 85 Type: "AtprotoPersonalDataServer", 86 86 Endpoint: "https://" + c.pdsHostname, ··· 89 89 Prev: nil, 90 90 } 91 91 92 - signed, err := c.FormatAndSignAtprotoOp(sigkey, op) 93 - if err != nil { 92 + if err := c.SignOp(sigkey, &op); err != nil { 94 93 return "", nil, err 95 94 } 96 95 97 - did, err := didFromOp(signed) 96 + did, err := didFromOp(&op) 98 97 if err != nil { 99 98 return "", nil, err 100 99 } ··· 102 101 return did, &op, nil 103 102 } 104 103 105 - func didFromOp(op *PlcOperation) (string, error) { 104 + func didFromOp(op *Operation) (string, error) { 106 105 b, err := op.MarshalCBOR() 107 106 if err != nil { 108 107 return "", err ··· 112 111 return "did:plc:" + b32[0:24], nil 113 112 } 114 113 115 - func (c *Client) FormatAndSignAtprotoOp(sigkey *crypto.PrivateKeyK256, op PlcOperation) (*PlcOperation, error) { 114 + func (c *Client) SignOp(sigkey *crypto.PrivateKeyK256, op *Operation) error { 116 115 b, err := op.MarshalCBOR() 117 116 if err != nil { 118 - return nil, err 117 + return err 119 118 } 120 119 121 120 sig, err := c.rotationKey.HashAndSign(b) 122 121 if err != nil { 123 - return nil, err 122 + return err 124 123 } 125 124 126 125 op.Sig = base64.RawURLEncoding.EncodeToString(sig) 127 126 128 - return &op, nil 127 + return nil 129 128 } 130 129 131 - func (c *Client) SendOperation(ctx context.Context, did string, op *PlcOperation) error { 130 + func (c *Client) SendOperation(ctx context.Context, did string, op *Operation) error { 132 131 b, err := json.Marshal(op) 133 132 if err != nil { 134 133 return err
+10 -10
plc/types.go
··· 7 7 cbg "github.com/whyrusleeping/cbor-gen" 8 8 ) 9 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"` 10 + type Operation 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]OperationService `json:"services"` 16 + Prev *string `json:"prev"` 17 + Sig string `json:"sig,omitempty"` 18 18 } 19 19 20 - type PlcOperationService struct { 20 + type OperationService struct { 21 21 Type string `json:"type"` 22 22 Endpoint string `json:"endpoint"` 23 23 } 24 24 25 25 // This is kinda gross. We could just use cborgen i suppose? 26 - func (po *PlcOperation) MarshalCBOR() ([]byte, error) { 26 + func (po *Operation) MarshalCBOR() ([]byte, error) { 27 27 if po == nil { 28 28 return cbg.CborNull, nil 29 29 }
+22 -3
server/handle_identity_update_handle.go
··· 13 13 "github.com/haileyok/cocoon/identity" 14 14 "github.com/haileyok/cocoon/internal/helpers" 15 15 "github.com/haileyok/cocoon/models" 16 + "github.com/haileyok/cocoon/plc" 16 17 "github.com/labstack/echo/v4" 17 18 ) 18 19 ··· 46 47 47 48 latest := log[len(log)-1] 48 49 50 + var newAka []string 51 + for _, aka := range latest.Operation.AlsoKnownAs { 52 + if aka == "at://"+repo.Handle { 53 + continue 54 + } 55 + newAka = append(newAka, aka) 56 + } 57 + 58 + newAka = append(newAka, "at://"+req.Handle) 59 + 60 + op := plc.Operation{ 61 + Type: "plc_operation", 62 + VerificationMethods: latest.Operation.VerificationMethods, 63 + RotationKeys: latest.Operation.RotationKeys, 64 + AlsoKnownAs: newAka, 65 + Services: latest.Operation.Services, 66 + Prev: &latest.Cid, 67 + } 68 + 49 69 k, err := crypto.ParsePrivateBytesK256(repo.SigningKey) 50 70 if err != nil { 51 71 s.logger.Error("error parsing signing key", "error", err) 52 72 return helpers.ServerError(e, nil) 53 73 } 54 74 55 - op, err := s.plcClient.FormatAndSignAtprotoOp(k, req.Handle, latest.Operation.RotationKeys, &latest.Cid) 56 - if err != nil { 75 + if err := s.plcClient.SignOp(k, &op); err != nil { 57 76 return err 58 77 } 59 78 60 - if err := s.plcClient.SendOperation(context.TODO(), repo.Repo.Did, op); err != nil { 79 + if err := s.plcClient.SendOperation(e.Request().Context(), repo.Repo.Did, &op); err != nil { 61 80 return err 62 81 } 63 82 }