cosmos-sdk/x/accounts/defaults/base/pubkey.go

76 lines
1.6 KiB
Go

package base
import (
"fmt"
"strings"
gogoproto "github.com/cosmos/gogoproto/proto"
dcrd_secp256k1 "github.com/decred/dcrd/dcrec/secp256k1/v4"
"cosmossdk.io/core/transaction"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
)
// this file implements a general mechanism to plugin public keys to a baseaccount
// PubKey defines a generic pubkey.
type PubKey interface {
transaction.Msg
VerifySignature(msg, sig []byte) bool
}
type PubKeyG[T any] interface {
*T
PubKey
}
type pubKeyImpl struct {
decode func(b []byte) (PubKey, error)
validate func(key PubKey) error
}
func WithSecp256K1PubKey() Option {
return WithPubKeyWithValidationFunc(func(pt *secp256k1.PubKey) error {
_, err := dcrd_secp256k1.ParsePubKey(pt.Key)
return err
})
}
func WithPubKey[T any, PT PubKeyG[T]]() Option {
return WithPubKeyWithValidationFunc[T, PT](func(_ PT) error {
return nil
})
}
func WithPubKeyWithValidationFunc[T any, PT PubKeyG[T]](validateFn func(PT) error) Option {
pkImpl := pubKeyImpl{
decode: func(b []byte) (PubKey, error) {
key := PT(new(T))
err := gogoproto.Unmarshal(b, key)
if err != nil {
return nil, err
}
return key, nil
},
validate: func(k PubKey) error {
concrete, ok := k.(PT)
if !ok {
return fmt.Errorf("invalid pubkey type passed for validation, wanted: %T, got: %T", concrete, k)
}
return validateFn(concrete)
},
}
return func(a *Account) {
a.supportedPubKeys[gogoproto.MessageName(PT(new(T)))] = pkImpl
}
}
func nameFromTypeURL(url string) string {
name := url
if i := strings.LastIndexByte(url, '/'); i >= 0 {
name = name[i+len("/"):]
}
return name
}