mirror of
https://github.com/sonr-io/sonr.git
synced 2026-08-02 17:31:39 +00:00
@@ -0,0 +1,606 @@
|
||||
// Package did provides a client interface for interacting with the Sonr DID module.
|
||||
package did
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/types/tx"
|
||||
|
||||
"github.com/sonr-io/sonr/client/config"
|
||||
"github.com/sonr-io/sonr/client/errors"
|
||||
didtypes "github.com/sonr-io/sonr/x/did/types"
|
||||
)
|
||||
|
||||
// Client provides an interface for interacting with the DID module.
|
||||
type Client interface {
|
||||
// DID Operations
|
||||
CreateDID(ctx context.Context, opts *CreateDIDOptions) (*DIDDocument, error)
|
||||
ResolveDID(ctx context.Context, did string) (*DIDDocument, error)
|
||||
UpdateDID(ctx context.Context, did string, opts *UpdateDIDOptions) (*DIDDocument, error)
|
||||
DeactivateDID(ctx context.Context, did string) error
|
||||
|
||||
// DID Document Operations
|
||||
AddVerificationMethod(ctx context.Context, did string, method *VerificationMethod) error
|
||||
RemoveVerificationMethod(ctx context.Context, did string, methodID string) error
|
||||
AddService(ctx context.Context, did string, service *Service) error
|
||||
RemoveService(ctx context.Context, did string, serviceID string) error
|
||||
|
||||
// WebAuthn Operations
|
||||
RegisterWebAuthn(ctx context.Context, opts *WebAuthnRegistrationOptions) (*WebAuthnCredential, error)
|
||||
AuthenticateWebAuthn(ctx context.Context, opts *WebAuthnAuthenticationOptions) (*WebAuthnAssertion, error)
|
||||
|
||||
// Query Operations
|
||||
ListDIDs(ctx context.Context, options *ListDIDsOptions) (*DIDListResponse, error)
|
||||
GetDIDsByOwner(ctx context.Context, owner string) ([]*DIDDocument, error)
|
||||
}
|
||||
|
||||
// DIDDocument represents a W3C DID Document.
|
||||
type DIDDocument struct {
|
||||
ID string `json:"id"`
|
||||
Controller []string `json:"controller,omitempty"`
|
||||
VerificationMethod []*VerificationMethod `json:"verificationMethod,omitempty"`
|
||||
Authentication []string `json:"authentication,omitempty"`
|
||||
AssertionMethod []string `json:"assertionMethod,omitempty"`
|
||||
KeyAgreement []string `json:"keyAgreement,omitempty"`
|
||||
CapabilityInvocation []string `json:"capabilityInvocation,omitempty"`
|
||||
CapabilityDelegation []string `json:"capabilityDelegation,omitempty"`
|
||||
Service []*Service `json:"service,omitempty"`
|
||||
AlsoKnownAs []string `json:"alsoKnownAs,omitempty"`
|
||||
Metadata *DIDMetadata `json:"metadata,omitempty"`
|
||||
}
|
||||
|
||||
// VerificationMethod represents a verification method in a DID document.
|
||||
type VerificationMethod struct {
|
||||
ID string `json:"id"`
|
||||
Type string `json:"type"`
|
||||
Controller string `json:"controller"`
|
||||
PublicKeyJwk map[string]any `json:"publicKeyJwk,omitempty"`
|
||||
PublicKeyMultibase string `json:"publicKeyMultibase,omitempty"`
|
||||
}
|
||||
|
||||
// Service represents a service endpoint in a DID document.
|
||||
type Service struct {
|
||||
ID string `json:"id"`
|
||||
Type string `json:"type"`
|
||||
ServiceEndpoint any `json:"serviceEndpoint"`
|
||||
}
|
||||
|
||||
// DIDMetadata contains metadata about a DID.
|
||||
type DIDMetadata struct {
|
||||
Created string `json:"created"`
|
||||
Updated string `json:"updated,omitempty"`
|
||||
Deactivated bool `json:"deactivated,omitempty"`
|
||||
VersionID string `json:"versionId,omitempty"`
|
||||
NextUpdate string `json:"nextUpdate,omitempty"`
|
||||
NextVersionID string `json:"nextVersionId,omitempty"`
|
||||
}
|
||||
|
||||
// CreateDIDOptions configures DID creation.
|
||||
type CreateDIDOptions struct {
|
||||
Controller []string `json:"controller,omitempty"`
|
||||
VerificationMethods []*VerificationMethod `json:"verificationMethods,omitempty"`
|
||||
Services []*Service `json:"services,omitempty"`
|
||||
AlsoKnownAs []string `json:"alsoKnownAs,omitempty"`
|
||||
UseWebAuthn bool `json:"useWebAuthn,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateDIDOptions configures DID updates.
|
||||
type UpdateDIDOptions struct {
|
||||
AddVerificationMethods []*VerificationMethod `json:"addVerificationMethods,omitempty"`
|
||||
RemoveVerificationMethods []string `json:"removeVerificationMethods,omitempty"`
|
||||
AddServices []*Service `json:"addServices,omitempty"`
|
||||
RemoveServices []string `json:"removeServices,omitempty"`
|
||||
AddController []string `json:"addController,omitempty"`
|
||||
RemoveController []string `json:"removeController,omitempty"`
|
||||
}
|
||||
|
||||
// WebAuthnRegistrationOptions configures WebAuthn registration.
|
||||
type WebAuthnRegistrationOptions struct {
|
||||
Username string `json:"username"`
|
||||
DisplayName string `json:"displayName"`
|
||||
Challenge []byte `json:"challenge"`
|
||||
Timeout int `json:"timeout,omitempty"`
|
||||
Extensions map[string]any `json:"extensions,omitempty"`
|
||||
}
|
||||
|
||||
// WebAuthnCredential represents a WebAuthn credential.
|
||||
type WebAuthnCredential struct {
|
||||
ID string `json:"id"`
|
||||
RawID []byte `json:"rawId"`
|
||||
Type string `json:"type"`
|
||||
Response *AuthenticatorResponse `json:"response"`
|
||||
ClientExtensions map[string]any `json:"clientExtensions,omitempty"`
|
||||
}
|
||||
|
||||
// AuthenticatorResponse represents the authenticator response.
|
||||
type AuthenticatorResponse struct {
|
||||
ClientDataJSON []byte `json:"clientDataJSON"`
|
||||
AttestationObject []byte `json:"attestationObject"`
|
||||
}
|
||||
|
||||
// WebAuthnAuthenticationOptions configures WebAuthn authentication.
|
||||
type WebAuthnAuthenticationOptions struct {
|
||||
Challenge []byte `json:"challenge"`
|
||||
Timeout int `json:"timeout,omitempty"`
|
||||
AllowedCredentials []string `json:"allowedCredentials,omitempty"`
|
||||
}
|
||||
|
||||
// WebAuthnAssertion represents a WebAuthn assertion.
|
||||
type WebAuthnAssertion struct {
|
||||
ID string `json:"id"`
|
||||
RawID []byte `json:"rawId"`
|
||||
Type string `json:"type"`
|
||||
Response *AuthenticatorAssertionResponse `json:"response"`
|
||||
}
|
||||
|
||||
// AuthenticatorAssertionResponse represents the assertion response.
|
||||
type AuthenticatorAssertionResponse struct {
|
||||
ClientDataJSON []byte `json:"clientDataJSON"`
|
||||
AuthenticatorData []byte `json:"authenticatorData"`
|
||||
Signature []byte `json:"signature"`
|
||||
UserHandle []byte `json:"userHandle,omitempty"`
|
||||
}
|
||||
|
||||
// ListDIDsOptions configures DID listing.
|
||||
type ListDIDsOptions struct {
|
||||
Limit uint64 `json:"limit,omitempty"`
|
||||
Offset uint64 `json:"offset,omitempty"`
|
||||
Owner string `json:"owner,omitempty"`
|
||||
}
|
||||
|
||||
// DIDListResponse contains a list of DIDs with pagination.
|
||||
type DIDListResponse struct {
|
||||
DIDs []*DIDDocument `json:"dids"`
|
||||
TotalCount uint64 `json:"totalCount"`
|
||||
Limit uint64 `json:"limit"`
|
||||
Offset uint64 `json:"offset"`
|
||||
}
|
||||
|
||||
// client implements the DID Client interface.
|
||||
type client struct {
|
||||
grpcConn *grpc.ClientConn
|
||||
config *config.NetworkConfig
|
||||
|
||||
// Service clients for DID module
|
||||
queryClient didtypes.QueryClient
|
||||
msgClient didtypes.MsgClient
|
||||
txClient tx.ServiceClient
|
||||
}
|
||||
|
||||
// NewClient creates a new DID module client.
|
||||
func NewClient(grpcConn *grpc.ClientConn, cfg *config.NetworkConfig) Client {
|
||||
return &client{
|
||||
grpcConn: grpcConn,
|
||||
config: cfg,
|
||||
queryClient: didtypes.NewQueryClient(grpcConn),
|
||||
msgClient: didtypes.NewMsgClient(grpcConn),
|
||||
txClient: tx.NewServiceClient(grpcConn),
|
||||
}
|
||||
}
|
||||
|
||||
// CreateDID creates a new DID document on the Sonr blockchain.
|
||||
func (c *client) CreateDID(ctx context.Context, opts *CreateDIDOptions) (*DIDDocument, error) {
|
||||
if opts == nil {
|
||||
return nil, errors.NewModuleError("did", "CreateDID",
|
||||
fmt.Errorf("options cannot be nil"))
|
||||
}
|
||||
|
||||
// Generate DID ID
|
||||
// Note: In a real implementation, this would use proper key derivation
|
||||
didID := GenerateDID(fmt.Sprintf("user_%d", len(opts.Controller)))
|
||||
|
||||
// Convert verification methods to protobuf format
|
||||
var verificationMethods []*didtypes.VerificationMethod
|
||||
for _, vm := range opts.VerificationMethods {
|
||||
verificationMethods = append(verificationMethods, &didtypes.VerificationMethod{
|
||||
Id: vm.ID,
|
||||
VerificationMethodKind: vm.Type,
|
||||
Controller: vm.Controller,
|
||||
PublicKeyMultibase: vm.PublicKeyMultibase,
|
||||
})
|
||||
}
|
||||
|
||||
// Convert services to protobuf format
|
||||
var services []*didtypes.Service
|
||||
for _, svc := range opts.Services {
|
||||
services = append(services, &didtypes.Service{
|
||||
Id: svc.ID,
|
||||
ServiceKind: svc.Type,
|
||||
SingleEndpoint: fmt.Sprintf("%v", svc.ServiceEndpoint),
|
||||
})
|
||||
}
|
||||
|
||||
// Get primary controller (first one if multiple)
|
||||
primaryController := ""
|
||||
if len(opts.Controller) > 0 {
|
||||
primaryController = opts.Controller[0]
|
||||
}
|
||||
|
||||
// Create DID Document
|
||||
didDocument := didtypes.DIDDocument{
|
||||
Id: didID,
|
||||
PrimaryController: primaryController,
|
||||
AlsoKnownAs: opts.AlsoKnownAs,
|
||||
VerificationMethod: verificationMethods,
|
||||
Service: services,
|
||||
}
|
||||
|
||||
// Create the MsgCreateDID message
|
||||
msg := &didtypes.MsgCreateDID{
|
||||
Controller: primaryController, // Will be set by the transaction builder
|
||||
DidDocument: didDocument,
|
||||
}
|
||||
|
||||
// In a real implementation, this would submit the transaction
|
||||
// For now, store the message for later use
|
||||
_ = msg
|
||||
|
||||
// Return a mock DID document
|
||||
return &DIDDocument{
|
||||
ID: didID,
|
||||
Controller: opts.Controller,
|
||||
VerificationMethod: opts.VerificationMethods,
|
||||
Service: opts.Services,
|
||||
AlsoKnownAs: opts.AlsoKnownAs,
|
||||
Metadata: &DIDMetadata{
|
||||
Created: "2024-01-01T00:00:00Z",
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ResolveDID resolves a DID to its document.
|
||||
func (c *client) ResolveDID(ctx context.Context, did string) (*DIDDocument, error) {
|
||||
// TODO: Implement DID resolution using DID module query client
|
||||
// Should validate DID format before querying chain
|
||||
// Query chain state for DID document by ID
|
||||
// Convert protobuf DIDDocument to client type
|
||||
// Handle DID not found and deactivated DID cases
|
||||
|
||||
return nil, errors.NewModuleError("did", "ResolveDID",
|
||||
fmt.Errorf("DID resolution not yet implemented"))
|
||||
}
|
||||
|
||||
// UpdateDID updates an existing DID document.
|
||||
func (c *client) UpdateDID(ctx context.Context, did string, opts *UpdateDIDOptions) (*DIDDocument, error) {
|
||||
// TODO: Implement DID updates using DID module
|
||||
// Should validate DID ownership and update permissions
|
||||
// Build MsgUpdateDID with incremental changes
|
||||
// Handle verification method and service updates
|
||||
// Return updated DID document with new version
|
||||
|
||||
return nil, errors.NewModuleError("did", "UpdateDID",
|
||||
fmt.Errorf("DID updates not yet implemented"))
|
||||
}
|
||||
|
||||
// DeactivateDID deactivates a DID document.
|
||||
func (c *client) DeactivateDID(ctx context.Context, did string) error {
|
||||
// TODO: Implement DID deactivation using DID module
|
||||
// Should validate DID ownership before deactivation
|
||||
// Build MsgDeactivateDID and submit to chain
|
||||
// Mark DID as deactivated in chain state
|
||||
// Handle cascading effects on dependent services
|
||||
|
||||
return errors.NewModuleError("did", "DeactivateDID",
|
||||
fmt.Errorf("DID deactivation not yet implemented"))
|
||||
}
|
||||
|
||||
// AddVerificationMethod adds a verification method to a DID document.
|
||||
func (c *client) AddVerificationMethod(ctx context.Context, did string, method *VerificationMethod) error {
|
||||
// TODO: Implement verification method addition using DID module
|
||||
// Should validate DID ownership and method format
|
||||
// Build MsgAddVerificationMethod and submit to chain
|
||||
// Validate public key format and cryptographic validity
|
||||
// Update DID document with new verification method
|
||||
|
||||
return errors.NewModuleError("did", "AddVerificationMethod",
|
||||
fmt.Errorf("verification method addition not yet implemented"))
|
||||
}
|
||||
|
||||
// RemoveVerificationMethod removes a verification method from a DID document.
|
||||
func (c *client) RemoveVerificationMethod(ctx context.Context, did string, methodID string) error {
|
||||
// TODO: Implement verification method removal using DID module
|
||||
// Should validate DID ownership and method existence
|
||||
// Build MsgRemoveVerificationMethod and submit to chain
|
||||
// Check if method is used in other DID relationships
|
||||
// Prevent removal of last verification method
|
||||
|
||||
return errors.NewModuleError("did", "RemoveVerificationMethod",
|
||||
fmt.Errorf("verification method removal not yet implemented"))
|
||||
}
|
||||
|
||||
// AddService adds a service to a DID document.
|
||||
func (c *client) AddService(ctx context.Context, did string, service *Service) error {
|
||||
// TODO: Implement service addition using DID module
|
||||
// Should validate DID ownership and service format
|
||||
// Build MsgAddService and submit to chain
|
||||
// Validate service endpoint URLs and accessibility
|
||||
// Update DID document with new service entry
|
||||
|
||||
return errors.NewModuleError("did", "AddService",
|
||||
fmt.Errorf("service addition not yet implemented"))
|
||||
}
|
||||
|
||||
// RemoveService removes a service from a DID document.
|
||||
func (c *client) RemoveService(ctx context.Context, did string, serviceID string) error {
|
||||
// TODO: Implement service removal using DID module
|
||||
// Should validate DID ownership and service existence
|
||||
// Build MsgRemoveService and submit to chain
|
||||
// Check for dependent systems using this service
|
||||
// Update DID document removing service entry
|
||||
|
||||
return errors.NewModuleError("did", "RemoveService",
|
||||
fmt.Errorf("service removal not yet implemented"))
|
||||
}
|
||||
|
||||
// RegisterWebAuthn registers a WebAuthn credential with a DID.
|
||||
func (c *client) RegisterWebAuthn(ctx context.Context, opts *WebAuthnRegistrationOptions) (*WebAuthnCredential, error) {
|
||||
// TODO: Implement WebAuthn registration using DID module
|
||||
// Should validate registration options and challenge
|
||||
// Build MsgRegisterWebAuthnCredential and submit to chain
|
||||
// Process authenticator attestation and public key
|
||||
// Store credential ID and public key in DID document
|
||||
// Support auto-vault creation if enabled
|
||||
|
||||
return nil, errors.NewModuleError("did", "RegisterWebAuthn",
|
||||
fmt.Errorf("WebAuthn registration not yet implemented"))
|
||||
}
|
||||
|
||||
// AuthenticateWebAuthn performs WebAuthn authentication.
|
||||
func (c *client) AuthenticateWebAuthn(ctx context.Context, opts *WebAuthnAuthenticationOptions) (*WebAuthnAssertion, error) {
|
||||
// TODO: Implement WebAuthn authentication using DID module
|
||||
// Should validate authentication challenge and credentials
|
||||
// Verify authenticator assertion against stored public key
|
||||
// Check credential ID against allowed credentials list
|
||||
// Return verified assertion with user handle and signature
|
||||
|
||||
return nil, errors.NewModuleError("did", "AuthenticateWebAuthn",
|
||||
fmt.Errorf("WebAuthn authentication not yet implemented"))
|
||||
}
|
||||
|
||||
// ListDIDs lists DIDs with optional filtering and pagination.
|
||||
func (c *client) ListDIDs(ctx context.Context, options *ListDIDsOptions) (*DIDListResponse, error) {
|
||||
// TODO: Implement DID listing using DID module query client
|
||||
// Should support pagination with limit/offset
|
||||
// Filter by owner address if specified
|
||||
// Return DIDs with basic metadata and status
|
||||
// Handle empty result sets gracefully
|
||||
|
||||
return nil, errors.NewModuleError("did", "ListDIDs",
|
||||
fmt.Errorf("DID listing not yet implemented"))
|
||||
}
|
||||
|
||||
// GetDIDsByOwner retrieves all DIDs owned by a specific address.
|
||||
func (c *client) GetDIDsByOwner(ctx context.Context, owner string) ([]*DIDDocument, error) {
|
||||
// TODO: Implement owner-based DID lookup using DID module
|
||||
// Should validate owner address format
|
||||
// Query chain state for DIDs controlled by owner
|
||||
// Return complete DID documents for all owned DIDs
|
||||
// Include active and deactivated DIDs with status
|
||||
|
||||
return nil, errors.NewModuleError("did", "GetDIDsByOwner",
|
||||
fmt.Errorf("owner-based DID lookup not yet implemented"))
|
||||
}
|
||||
|
||||
// Utility functions
|
||||
|
||||
// GenerateDID generates a new DID identifier for the Sonr network.
|
||||
func GenerateDID(identifier string) string {
|
||||
return fmt.Sprintf("did:sonr:%s", identifier)
|
||||
}
|
||||
|
||||
// ValidateDID validates a DID format.
|
||||
func ValidateDID(did string) error {
|
||||
// Basic DID format validation
|
||||
if len(did) == 0 {
|
||||
return fmt.Errorf("DID cannot be empty")
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(did, "did:sonr:") {
|
||||
return fmt.Errorf("DID must start with 'did:sonr:'")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateDefaultVerificationMethod creates a default verification method.
|
||||
func CreateDefaultVerificationMethod(did string, publicKey []byte) *VerificationMethod {
|
||||
return &VerificationMethod{
|
||||
ID: fmt.Sprintf("%s#key-1", did),
|
||||
Type: "Ed25519VerificationKey2020",
|
||||
Controller: did,
|
||||
PublicKeyMultibase: fmt.Sprintf("z%x", publicKey), // Simplified multibase encoding
|
||||
}
|
||||
}
|
||||
|
||||
// CreateWebAuthnService creates a service entry for WebAuthn.
|
||||
func CreateWebAuthnService(did string, endpoint string) *Service {
|
||||
return &Service{
|
||||
ID: fmt.Sprintf("%s#webauthn", did),
|
||||
Type: "WebAuthnService",
|
||||
ServiceEndpoint: endpoint,
|
||||
}
|
||||
}
|
||||
|
||||
// Message Builders - These create the actual transaction messages
|
||||
|
||||
// BuildMsgCreateDID builds a MsgCreateDID message.
|
||||
func BuildMsgCreateDID(controller string, opts *CreateDIDOptions) (*didtypes.MsgCreateDID, error) {
|
||||
if opts == nil {
|
||||
return nil, fmt.Errorf("options cannot be nil")
|
||||
}
|
||||
|
||||
// Generate DID ID
|
||||
didID := GenerateDID(fmt.Sprintf("user_%s", controller[:8]))
|
||||
|
||||
// Convert verification methods
|
||||
var verificationMethods []*didtypes.VerificationMethod
|
||||
for _, vm := range opts.VerificationMethods {
|
||||
verificationMethods = append(verificationMethods, &didtypes.VerificationMethod{
|
||||
Id: vm.ID,
|
||||
VerificationMethodKind: vm.Type,
|
||||
Controller: vm.Controller,
|
||||
PublicKeyMultibase: vm.PublicKeyMultibase,
|
||||
})
|
||||
}
|
||||
|
||||
// Convert services
|
||||
var services []*didtypes.Service
|
||||
for _, svc := range opts.Services {
|
||||
services = append(services, &didtypes.Service{
|
||||
Id: svc.ID,
|
||||
ServiceKind: svc.Type,
|
||||
SingleEndpoint: fmt.Sprintf("%v", svc.ServiceEndpoint),
|
||||
})
|
||||
}
|
||||
|
||||
// Create DID Document
|
||||
didDocument := didtypes.DIDDocument{
|
||||
Id: didID,
|
||||
PrimaryController: controller,
|
||||
AlsoKnownAs: opts.AlsoKnownAs,
|
||||
VerificationMethod: verificationMethods,
|
||||
Service: services,
|
||||
}
|
||||
|
||||
return &didtypes.MsgCreateDID{
|
||||
Controller: controller,
|
||||
DidDocument: didDocument,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// BuildMsgUpdateDID builds a MsgUpdateDID message.
|
||||
func BuildMsgUpdateDID(controller, did string, opts *UpdateDIDOptions) (*didtypes.MsgUpdateDID, error) {
|
||||
if opts == nil {
|
||||
return nil, fmt.Errorf("options cannot be nil")
|
||||
}
|
||||
|
||||
// Note: In a real implementation, we would need to query the existing DID document
|
||||
// and apply the updates. For now, we create a minimal DID document with updates.
|
||||
|
||||
// Convert new verification methods
|
||||
var verificationMethods []*didtypes.VerificationMethod
|
||||
for _, vm := range opts.AddVerificationMethods {
|
||||
verificationMethods = append(verificationMethods, &didtypes.VerificationMethod{
|
||||
Id: vm.ID,
|
||||
VerificationMethodKind: vm.Type,
|
||||
Controller: vm.Controller,
|
||||
PublicKeyMultibase: vm.PublicKeyMultibase,
|
||||
})
|
||||
}
|
||||
|
||||
// Convert new services
|
||||
var services []*didtypes.Service
|
||||
for _, svc := range opts.AddServices {
|
||||
services = append(services, &didtypes.Service{
|
||||
Id: svc.ID,
|
||||
ServiceKind: svc.Type,
|
||||
SingleEndpoint: fmt.Sprintf("%v", svc.ServiceEndpoint),
|
||||
})
|
||||
}
|
||||
|
||||
// Create updated DID Document
|
||||
didDocument := didtypes.DIDDocument{
|
||||
Id: did,
|
||||
PrimaryController: controller,
|
||||
VerificationMethod: verificationMethods,
|
||||
Service: services,
|
||||
}
|
||||
|
||||
return &didtypes.MsgUpdateDID{
|
||||
Controller: controller,
|
||||
Did: did,
|
||||
DidDocument: didDocument,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// BuildMsgDeactivateDID builds a MsgDeactivateDID message.
|
||||
func BuildMsgDeactivateDID(controller, did string) *didtypes.MsgDeactivateDID {
|
||||
return &didtypes.MsgDeactivateDID{
|
||||
Controller: controller,
|
||||
Did: did,
|
||||
}
|
||||
}
|
||||
|
||||
// BuildMsgAddVerificationMethod builds a MsgAddVerificationMethod message.
|
||||
func BuildMsgAddVerificationMethod(controller, did string, method *VerificationMethod) (*didtypes.MsgAddVerificationMethod, error) {
|
||||
if method == nil {
|
||||
return nil, fmt.Errorf("verification method cannot be nil")
|
||||
}
|
||||
|
||||
return &didtypes.MsgAddVerificationMethod{
|
||||
Controller: controller,
|
||||
Did: did,
|
||||
VerificationMethod: didtypes.VerificationMethod{
|
||||
Id: method.ID,
|
||||
VerificationMethodKind: method.Type,
|
||||
Controller: method.Controller,
|
||||
PublicKeyMultibase: method.PublicKeyMultibase,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// BuildMsgRemoveVerificationMethod builds a MsgRemoveVerificationMethod message.
|
||||
func BuildMsgRemoveVerificationMethod(controller, did, methodID string) *didtypes.MsgRemoveVerificationMethod {
|
||||
return &didtypes.MsgRemoveVerificationMethod{
|
||||
Controller: controller,
|
||||
Did: did,
|
||||
VerificationMethodId: methodID,
|
||||
}
|
||||
}
|
||||
|
||||
// BuildMsgAddService builds a MsgAddService message.
|
||||
func BuildMsgAddService(controller, did string, service *Service) (*didtypes.MsgAddService, error) {
|
||||
if service == nil {
|
||||
return nil, fmt.Errorf("service cannot be nil")
|
||||
}
|
||||
|
||||
return &didtypes.MsgAddService{
|
||||
Controller: controller,
|
||||
Did: did,
|
||||
Service: didtypes.Service{
|
||||
Id: service.ID,
|
||||
ServiceKind: service.Type,
|
||||
SingleEndpoint: fmt.Sprintf("%v", service.ServiceEndpoint),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// BuildMsgRemoveService builds a MsgRemoveService message.
|
||||
func BuildMsgRemoveService(controller, did, serviceID string) *didtypes.MsgRemoveService {
|
||||
return &didtypes.MsgRemoveService{
|
||||
Controller: controller,
|
||||
Did: did,
|
||||
ServiceId: serviceID,
|
||||
}
|
||||
}
|
||||
|
||||
// BuildMsgRegisterWebAuthnCredential builds a MsgRegisterWebAuthnCredential message.
|
||||
func BuildMsgRegisterWebAuthnCredential(controller, username string, credential *WebAuthnCredential, autoCreateVault bool) (*didtypes.MsgRegisterWebAuthnCredential, error) {
|
||||
if credential == nil {
|
||||
return nil, fmt.Errorf("credential cannot be nil")
|
||||
}
|
||||
|
||||
// Convert our WebAuthnCredential to the protobuf type
|
||||
webAuthnCred := didtypes.WebAuthnCredential{
|
||||
CredentialId: credential.ID,
|
||||
PublicKey: credential.RawID, // Using RawID as the public key bytes
|
||||
// Algorithm would need to be determined from the credential
|
||||
// AttestationType would need to be extracted from the attestation object
|
||||
// Origin would need to be extracted from the client data
|
||||
}
|
||||
|
||||
// Generate a verification method ID based on the username
|
||||
verificationMethodID := fmt.Sprintf("did:sonr:%s#webauthn-1", username)
|
||||
|
||||
return &didtypes.MsgRegisterWebAuthnCredential{
|
||||
Controller: controller,
|
||||
Username: username,
|
||||
WebauthnCredential: webAuthnCred,
|
||||
VerificationMethodId: verificationMethodID,
|
||||
AutoCreateVault: autoCreateVault,
|
||||
}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user