diff --git a/plugin/plugin.go b/plugin/plugin.go new file mode 100644 index 000000000000..ee6ad608d8b6 --- /dev/null +++ b/plugin/plugin.go @@ -0,0 +1,19 @@ +package plugin + +import "github.com/gogo/protobuf/proto" + +type Host interface { + // Expect tells the host to expect that every registered protobuf type which + // implements the protobuf interface name (cosmos_proto.implements_interface) + // is expected to register a golang interface implementation of type golangInterfaceType. + Expect(protoInterfaceName string, golangInterfaceType interface{}) + + // Register registers plugin handler constructors which are functions taking a plugin target + // and returning a handler type. Ex: func(secp256k1.PubKey) crypto.PubKey. + Register(handlerConstructors ...interface{}) + + // Resolve resolves the handler for the provided target. Ex: + // var pubKey crypto.PubKey + // host.Resolve(&secp256k1.PubKey{}, &pubKey) + Resolve(target proto.Message, handler interface{}) error +} diff --git a/plugin/plugin_test.go b/plugin/plugin_test.go new file mode 100644 index 000000000000..1bc26f64d489 --- /dev/null +++ b/plugin/plugin_test.go @@ -0,0 +1,48 @@ +package plugin_test + +import ( + "github.com/gogo/protobuf/proto" + + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + "github.com/cosmos/cosmos-sdk/crypto/types" + "github.com/cosmos/cosmos-sdk/plugin" +) + +type PubKeyModule struct{} + +type AuthModule struct{} + +type SecpHandler struct{ *secp256k1.PubKey } + +func NewSecpHandler(pubKey *secp256k1.PubKey) types.PubKey { return &SecpHandler{PubKey: pubKey} } + +type EdHandler struct{ *ed25519.PubKey } + +func NewEdHandler(pubKey *ed25519.PubKey) types.PubKey { return &EdHandler{PubKey: pubKey} } + +func (m PubKeyModule) Provide(host plugin.Host) { + host.Register( + NewSecpHandler, + NewEdHandler, + ) +} + +func (m AuthModule) Provide(host plugin.Host) AuthKeeper { + host.Expect("cosmos.crypto.PubKey", (*types.PubKey)(nil)) + return AuthKeeper{pluginHost: host} +} + +type AuthKeeper struct { + pluginHost plugin.Host +} + +func (k AuthKeeper) GetAddress(pubKeyProtoType proto.Message) types.Address { + var pubKey types.PubKey + err := k.pluginHost.Resolve(pubKeyProtoType, &pubKey) + if err != nil { + panic(err) + } + + return pubKey.Address() +}