generated from okp4/template-oss
-
Notifications
You must be signed in to change notification settings - Fork 126
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(cli): introduce "keys did" command
- Loading branch information
Showing
4 changed files
with
148 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
package keys | ||
|
||
import ( | ||
"encoding/base64" | ||
"encoding/hex" | ||
"fmt" | ||
|
||
"github.com/spf13/cobra" | ||
|
||
errorsmod "cosmossdk.io/errors" | ||
|
||
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" | ||
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" | ||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" | ||
"github.com/cosmos/cosmos-sdk/types/errors" | ||
"github.com/cosmos/cosmos-sdk/version" | ||
|
||
"github.com/okp4/okp4d/x/logic/util" | ||
) | ||
|
||
var ( | ||
flagPubKeyType = "type" | ||
) | ||
|
||
func DIDCmd() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: fmt.Sprintf("did [pubkey] -t [{%s, %s}]", util.KeyAlgEd25519, util.KeyAlgSecp256k1), | ||
Short: fmt.Sprintf("Give the did:key from a %s or %s pubkey (hex, base64)", util.KeyAlgEd25519, util.KeyAlgSecp256k1), | ||
Long: fmt.Sprintf(`Give the did:key from a %s or %s pubkey given as hex or base64 encoded string. | ||
Example: | ||
$ %s keys did "AtD+mbIUqu615Grk1loWI6ldnQzs1X1nP35MmhmsB1K8" -t %s | ||
$ %s keys did 02d0fe99b214aaeeb5e46ae4d65a1623a95d9d0cecd57d673f7e4c9a19ac0752bc -t %s | ||
`, util.KeyAlgEd25519, util.KeyAlgSecp256k1, version.AppName, util.KeyAlgSecp256k1, version.AppName, util.KeyAlgSecp256k1), | ||
Args: cobra.ExactArgs(1), | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
pubkeyType, err := cmd.Flags().GetString(flagPubKeyType) | ||
if err != nil { | ||
return err | ||
} | ||
pubkeyAlgo, err := util.ParseKeyAlg(pubkeyType) | ||
if err != nil { | ||
return errorsmod.Wrapf(errors.ErrInvalidType, | ||
"invalid pubkey type; expected oneof %+q", []util.KeyAlg{util.KeyAlgSecp256k1, util.KeyAlgEd25519}) | ||
} | ||
bs, err := getBytesFromString(args[0]) | ||
if err != nil { | ||
return err | ||
} | ||
pubKey, err := bytesToPubkey(bs, pubkeyAlgo) | ||
if err != nil { | ||
return err | ||
} | ||
did, err := util.CreateDIDKeyByPubKey(pubKey) | ||
if err != nil { | ||
return errorsmod.Wrapf(errors.ErrInvalidPubKey, "failed to make did:key from %s; %s", args[0], err) | ||
} | ||
|
||
cmd.Println(did) | ||
|
||
return nil | ||
}, | ||
} | ||
cmd.Flags().StringP(flagPubKeyType, "t", util.KeyAlgSecp256r1.String(), | ||
fmt.Sprintf("Pubkey type to decode (oneof %s, %s)", util.KeyAlgEd25519, util.KeyAlgSecp256k1)) | ||
return cmd | ||
} | ||
|
||
func getBytesFromString(pubKey string) ([]byte, error) { | ||
if bz, err := hex.DecodeString(pubKey); err == nil { | ||
return bz, nil | ||
} | ||
|
||
if bz, err := base64.StdEncoding.DecodeString(pubKey); err == nil { | ||
return bz, nil | ||
} | ||
|
||
return nil, errorsmod.Wrapf(errors.ErrInvalidPubKey, | ||
"pubkey '%s' invalid; expected hex or base64 encoding of correct size", pubKey) | ||
} | ||
|
||
func bytesToPubkey(bz []byte, keytype util.KeyAlg) (cryptotypes.PubKey, error) { | ||
switch keytype { | ||
case util.KeyAlgEd25519: | ||
if len(bz) != ed25519.PubKeySize { | ||
return nil, errorsmod.Wrapf(errors.ErrInvalidPubKey, | ||
"invalid pubkey size; expected %d, got %d", ed25519.PubKeySize, len(bz)) | ||
} | ||
return &ed25519.PubKey{Key: bz}, nil | ||
case util.KeyAlgSecp256k1: | ||
if len(bz) != secp256k1.PubKeySize { | ||
return nil, errorsmod.Wrapf(errors.ErrInvalidPubKey, | ||
"invalid pubkey size; expected %d, got %d", secp256k1.PubKeySize, len(bz)) | ||
} | ||
return &secp256k1.PubKey{Key: bz}, nil | ||
case util.KeyAlgSecp256r1: | ||
} | ||
|
||
return nil, errorsmod.Wrapf(errors.ErrInvalidType, | ||
"invalid pubkey type; expected oneof %+q", []util.KeyAlg{util.KeyAlgSecp256k1, util.KeyAlgEd25519}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package keys | ||
|
||
import "github.com/spf13/cobra" | ||
|
||
func Enhance(cmd *cobra.Command) *cobra.Command { | ||
cmd.AddCommand( | ||
DIDCmd(), | ||
) | ||
return cmd | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package util | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/hyperledger/aries-framework-go/pkg/vdr/fingerprint" | ||
|
||
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" | ||
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" | ||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" | ||
) | ||
|
||
const ( | ||
ED25519PubKeyMultiCodec = 0xed | ||
SECP256k1ubKeyMultiCodec = 0xe7 | ||
) | ||
|
||
// CreateDIDKeyByPubKey creates a did:key ID using the given public key. | ||
// The multicodec key fingerprint is determined by the key type and complies with the did:key format spec found at: | ||
// https://w3c-ccg.github.io/did-method-key/#format. | ||
func CreateDIDKeyByPubKey(pubKey cryptotypes.PubKey) (string, error) { | ||
var code uint64 | ||
switch pubKey.(type) { | ||
case *ed25519.PubKey: | ||
code = ED25519PubKeyMultiCodec | ||
case *secp256k1.PubKey: | ||
code = SECP256k1ubKeyMultiCodec | ||
default: | ||
return "", fmt.Errorf("unsupported key type: %s", pubKey.Type()) | ||
} | ||
|
||
did, _ := fingerprint.CreateDIDKeyByCode(code, pubKey.Bytes()) | ||
return did, nil | ||
} |