A Transparent and Verifiable Way to Sync the AT Protocol's PLC Directory
at did-resolver 120 lines 3.3 kB view raw
1package plc 2 3import ( 4 "time" 5 6 "github.com/goccy/go-json" 7) 8 9// PLCOperation represents a single operation from the PLC directory 10type PLCOperation struct { 11 DID string `json:"did"` 12 Operation json.RawMessage `json:"operation"` // Lazy 13 CID string `json:"cid"` 14 Nullified interface{} `json:"nullified,omitempty"` 15 CreatedAt time.Time `json:"createdAt"` 16 17 RawJSON []byte `json:"-"` 18 ParsedOperation map[string]interface{} `json:"-"` // Pre-parsed cache 19} 20 21// IsNullified checks if this operation has been nullified 22func (op *PLCOperation) IsNullified() bool { 23 if op.Nullified == nil { 24 return false 25 } 26 27 switch v := op.Nullified.(type) { 28 case bool: 29 return v 30 case string: 31 return v != "" 32 default: 33 return false 34 } 35} 36 37// GetNullifyingCID returns the CID that nullified this operation 38func (op *PLCOperation) GetNullifyingCID() string { 39 if s, ok := op.Nullified.(string); ok { 40 return s 41 } 42 return "" 43} 44 45// DIDDocument represents a DID document from PLC 46type DIDDocument struct { 47 Context []string `json:"@context"` 48 ID string `json:"id"` 49 AlsoKnownAs []string `json:"alsoKnownAs"` 50 VerificationMethod []VerificationMethod `json:"verificationMethod"` 51 Service []Service `json:"service"` 52} 53 54// VerificationMethod represents a verification method in a DID document 55type VerificationMethod struct { 56 ID string `json:"id"` 57 Type string `json:"type"` 58 Controller string `json:"controller"` 59 PublicKeyMultibase string `json:"publicKeyMultibase"` 60} 61 62// Service represents a service endpoint in a DID document 63type Service struct { 64 ID string `json:"id"` 65 Type string `json:"type"` 66 ServiceEndpoint string `json:"serviceEndpoint"` 67} 68 69// ExportOptions contains options for exporting PLC operations 70type ExportOptions struct { 71 Count int // Number of operations to fetch 72 After string // ISO 8601 datetime string to start after 73} 74 75// DIDHistoryEntry represents a single operation in DID history 76type DIDHistoryEntry struct { 77 Operation PLCOperation `json:"operation"` 78 PLCBundle string `json:"plc_bundle,omitempty"` 79} 80 81// DIDHistory represents the full history of a DID 82type DIDHistory struct { 83 DID string `json:"did"` 84 Current *PLCOperation `json:"current"` 85 Operations []DIDHistoryEntry `json:"operations"` 86} 87 88// EndpointInfo contains extracted endpoint information from an operation 89type EndpointInfo struct { 90 Type string // "pds", "labeler", etc. 91 Endpoint string 92} 93 94// GetOperationData parses Operation into map (with caching) 95func (op *PLCOperation) GetOperationData() (map[string]interface{}, error) { 96 // Return cached if already parsed 97 if op.ParsedOperation != nil { 98 return op.ParsedOperation, nil 99 } 100 101 // Parse on first call 102 if len(op.Operation) == 0 { 103 return nil, nil 104 } 105 106 var data map[string]interface{} 107 if err := json.UnmarshalNoEscape(op.Operation, &data); err != nil { 108 return nil, err 109 } 110 111 // Cache it 112 op.ParsedOperation = data 113 114 return data, nil 115} 116 117// GetOperationMap is an alias for compatibility 118func (op *PLCOperation) GetOperationMap() (map[string]interface{}, error) { 119 return op.GetOperationData() 120}