mirror of
https://github.com/sonr-io/sonr.git
synced 2026-08-02 17:31:39 +00:00
203 lines
5.7 KiB
Go
203 lines
5.7 KiB
Go
// Package keeper implements DID integration for the DEX module
|
|
package keeper
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
|
|
"github.com/sonr-io/sonr/x/dex/types"
|
|
)
|
|
|
|
// ValidateDIDOwnership verifies that the transaction sender owns the specified DID
|
|
func (k Keeper) ValidateDIDOwnership(ctx sdk.Context, did string, sender sdk.AccAddress) error {
|
|
// Get DID document from DID keeper
|
|
didDoc, err := k.didKeeper.GetDIDDocument(ctx, did)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to get DID document: %w", err)
|
|
}
|
|
|
|
if didDoc == nil {
|
|
return fmt.Errorf("DID document not found for %s", did)
|
|
}
|
|
|
|
// Verify sender is the controller of the DID
|
|
if !k.isDIDController(didDoc, sender.String()) {
|
|
return fmt.Errorf("sender %s is not the controller of DID %s", sender, did)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// isDIDController checks if an address is a controller of the DID
|
|
func (k Keeper) isDIDController(didDoc any, address string) bool {
|
|
// This is a simplified check - actual implementation would depend on DID document structure
|
|
// For now, we'll assume the DID document has a Controller field or similar
|
|
// The actual implementation should match the x/did module's structure
|
|
|
|
// TODO: Implement proper controller verification based on actual DID document structure
|
|
// This might involve checking:
|
|
// - didDoc.Controller field
|
|
// - didDoc.Authentication keys
|
|
// - didDoc.AssertionMethod keys
|
|
|
|
return true // Placeholder - always return true for now
|
|
}
|
|
|
|
// GetDIDCapabilities retrieves the DEX-related capabilities for a DID
|
|
func (k Keeper) GetDIDCapabilities(ctx sdk.Context, did string) ([]string, error) {
|
|
// Get DID document
|
|
didDoc, err := k.didKeeper.GetDIDDocument(ctx, did)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get DID document: %w", err)
|
|
}
|
|
|
|
if didDoc == nil {
|
|
return nil, fmt.Errorf("DID document not found for %s", did)
|
|
}
|
|
|
|
// Extract DEX-related capabilities from the DID document
|
|
// This would typically be stored in service endpoints or custom fields
|
|
capabilities := []string{
|
|
"swap",
|
|
"liquidity",
|
|
"orders",
|
|
}
|
|
|
|
return capabilities, nil
|
|
}
|
|
|
|
// AuthenticateDIDOperation verifies that a DID is authorized for a specific DEX operation
|
|
func (k Keeper) AuthenticateDIDOperation(
|
|
ctx sdk.Context,
|
|
did string,
|
|
operation string,
|
|
params map[string]any,
|
|
) error {
|
|
// Get DID document to verify it exists and is active
|
|
didDoc, err := k.didKeeper.GetDIDDocument(ctx, did)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to authenticate DID: %w", err)
|
|
}
|
|
|
|
if didDoc == nil {
|
|
return fmt.Errorf("DID %s not found", did)
|
|
}
|
|
|
|
// Check if DID has the required capability for this operation
|
|
capabilities, err := k.GetDIDCapabilities(ctx, did)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to get DID capabilities: %w", err)
|
|
}
|
|
|
|
// Map operations to required capabilities
|
|
requiredCapability := k.getRequiredCapability(operation)
|
|
if !k.hasCapability(capabilities, requiredCapability) {
|
|
return fmt.Errorf("DID %s lacks capability for operation %s", did, operation)
|
|
}
|
|
|
|
// Additional authentication checks could be added here:
|
|
// - Check if DID has sufficient reputation
|
|
// - Check if DID has completed KYC/AML if required
|
|
// - Check rate limits for the DID
|
|
|
|
return nil
|
|
}
|
|
|
|
// getRequiredCapability maps DEX operations to required capabilities
|
|
func (k Keeper) getRequiredCapability(operation string) string {
|
|
switch operation {
|
|
case "swap", "execute_swap":
|
|
return "swap"
|
|
case "provide_liquidity", "remove_liquidity":
|
|
return "liquidity"
|
|
case "create_order", "cancel_order":
|
|
return "orders"
|
|
default:
|
|
return operation
|
|
}
|
|
}
|
|
|
|
// hasCapability checks if a capability exists in the list
|
|
func (k Keeper) hasCapability(capabilities []string, required string) bool {
|
|
for _, cap := range capabilities {
|
|
if cap == required {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// RecordDIDActivity records DEX activity for a DID (for analytics and compliance)
|
|
func (k Keeper) RecordDIDActivity(
|
|
ctx sdk.Context,
|
|
did string,
|
|
activity types.DEXActivity,
|
|
) error {
|
|
// Store activity record keyed by DID and timestamp
|
|
activityKey := GetDIDActivityKey(did, ctx.BlockTime().Unix())
|
|
|
|
// Store the activity
|
|
if err := k.DIDActivities.Set(ctx, activityKey, activity); err != nil {
|
|
return fmt.Errorf("failed to record DID activity: %w", err)
|
|
}
|
|
|
|
// Emit event for activity tracking
|
|
ctx.EventManager().EmitEvent(
|
|
sdk.NewEvent(
|
|
types.EventTypeDIDActivity,
|
|
sdk.NewAttribute("did", did),
|
|
sdk.NewAttribute("activity_type", activity.Type),
|
|
sdk.NewAttribute("timestamp", fmt.Sprintf("%d", ctx.BlockTime().Unix())),
|
|
),
|
|
)
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetDIDActivityHistory retrieves the activity history for a DID
|
|
func (k Keeper) GetDIDActivityHistory(
|
|
ctx sdk.Context,
|
|
did string,
|
|
limit uint32,
|
|
) ([]types.DEXActivity, error) {
|
|
activities := make([]types.DEXActivity, 0)
|
|
|
|
// Walk through activities for this DID
|
|
prefix := GetDIDActivityPrefix(did)
|
|
iterator, err := k.DIDActivities.Iterate(ctx, nil)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to iterate DID activities: %w", err)
|
|
}
|
|
defer iterator.Close()
|
|
|
|
count := uint32(0)
|
|
for ; iterator.Valid() && count < limit; iterator.Next() {
|
|
key, err := iterator.Key()
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
// Check if key starts with the DID prefix
|
|
if len(key) >= len(prefix) && string(key[:len(prefix)]) == prefix {
|
|
activity, err := iterator.Value()
|
|
if err == nil {
|
|
activities = append(activities, activity)
|
|
count++
|
|
}
|
|
}
|
|
}
|
|
|
|
return activities, nil
|
|
}
|
|
|
|
// GetDIDActivityPrefix returns the key prefix for a DID's activities
|
|
func GetDIDActivityPrefix(did string) string {
|
|
return fmt.Sprintf("did_activity_%s_", did)
|
|
}
|
|
|
|
// GetDIDActivityKey returns the key for storing a DID activity
|
|
func GetDIDActivityKey(did string, timestamp int64) string {
|
|
return fmt.Sprintf("did_activity_%s_%d", did, timestamp)
|
|
}
|