76 lines
1.6 KiB
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
|
|
}
|