Files
sonr/x/dwn/client/cli/verify.go
Prad NukalaandGitHub 13e6c3e84d Master (#1262)
* clear

* feat: Add everything

* fix: Commenht
2025-10-03 14:45:52 -04:00

155 lines
3.9 KiB
Go

package cli
import (
"context"
"encoding/hex"
"encoding/json"
"fmt"
"os"
"github.com/spf13/cobra"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/sonr-io/sonr/x/dwn/client/plugin"
)
// VerifyCmd returns a command to verify signatures using the Motor plugin
func VerifyCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "verify [signature-file]",
Short: "Verify a signature using Motor plugin",
Long: `Verify a signature against data using the Motor plugin's MPC-based verification.
Examples:
# Verify a signature file
snrd wallet verify signature.json --data "Hello World" --enclave-data @enclave.json
# Verify with data from file
snrd wallet verify signature.json --data @message.txt --enclave-data @enclave.json`,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
// Read signature file
sigFile := args[0]
sigData, err := os.ReadFile(sigFile)
if err != nil {
return fmt.Errorf("failed to read signature file: %w", err)
}
// Parse signature data
var sigInfo struct {
Signature string `json:"signature"`
Signer struct {
DID string `json:"did"`
Address string `json:"address"`
} `json:"signer"`
}
if err := json.Unmarshal(sigData, &sigInfo); err != nil {
return fmt.Errorf("failed to parse signature file: %w", err)
}
// Get data to verify against
dataInput, err := cmd.Flags().GetString("data")
if err != nil {
return err
}
if dataInput == "" {
return fmt.Errorf("--data flag is required")
}
var dataToVerify []byte
if dataInput[0] == '@' {
// Read from file
dataToVerify, err = os.ReadFile(dataInput[1:])
if err != nil {
return fmt.Errorf("failed to read data file: %w", err)
}
} else {
dataToVerify = []byte(dataInput)
}
// Get enclave data
enclaveDataStr, err := cmd.Flags().GetString("enclave-data")
if err != nil {
return err
}
if enclaveDataStr == "" {
return fmt.Errorf("--enclave-data flag is required")
}
enclaveData, err := parseEnclaveData(enclaveDataStr)
if err != nil {
return fmt.Errorf("failed to parse enclave data: %w", err)
}
// Load the plugin
chainID := clientCtx.ChainID
if chainID == "" {
chainID = DefaultTestChainID
}
config := plugin.CreateEnclaveConfig(chainID, enclaveData)
ctx := context.Background()
motorPlugin, err := plugin.LoadPluginWithManager(ctx, config)
if err != nil {
return fmt.Errorf("failed to load Motor plugin: %w", err)
}
// Decode signature
signature, err := hex.DecodeString(sigInfo.Signature)
if err != nil {
return fmt.Errorf("failed to decode signature: %w", err)
}
// Verify the signature
verifyReq := &plugin.VerifyDataRequest{
Data: dataToVerify,
Signature: signature,
}
verifyResp, err := motorPlugin.VerifyData(verifyReq)
if err != nil {
return fmt.Errorf("failed to verify signature: %w", err)
}
if verifyResp.Error != "" {
return fmt.Errorf("plugin verification error: %s", verifyResp.Error)
}
// Output verification result
result := map[string]any{
"valid": verifyResp.Valid,
"signer": map[string]any{
"did": sigInfo.Signer.DID,
"address": sigInfo.Signer.Address,
},
"signature_length": len(signature),
"data_length": len(dataToVerify),
}
if verifyResp.Valid {
fmt.Println("✓ Signature is valid")
} else {
fmt.Println("✗ Signature is invalid")
}
return clientCtx.PrintObjectLegacy(result)
},
}
flags.AddQueryFlagsToCmd(cmd)
cmd.Flags().String("data", "", "Data to verify signature against (text or @file)")
cmd.Flags().String("enclave-data", "", "Enclave data for verification (required)")
cmd.MarkFlagRequired("data")
cmd.MarkFlagRequired("enclave-data")
return cmd
}