diff --git a/crypto/sr25519/sr25519.go b/crypto/sr25519/sr25519.go
new file mode 100644
index 00000000..f4feae22
--- /dev/null
+++ b/crypto/sr25519/sr25519.go
@@ -0,0 +1,68 @@
+// Copyright 2020 ChainSafe Systems
+// SPDX-License-Identifier: LGPL-3.0-only
+
+package sr25519
+
+import (
+	"bytes"
+	"crypto/rand"
+
+	"github.com/centrifuge/go-substrate-rpc-client/v4/scale"
+	"github.com/centrifuge/go-substrate-rpc-client/v4/signature"
+
+	"github.com/ethereum/go-ethereum/common/hexutil"
+)
+
+type Keypair struct {
+	keyringPair *signature.KeyringPair
+}
+
+func GenerateKeypair(network uint16) (*Keypair, error) {
+	data := make([]byte, 32)
+	_, err := rand.Read(data)
+	if err != nil {
+		return nil, err
+	}
+	return NewKeypairFromSeed("//"+hexutil.Encode(data), network)
+}
+
+func NewKeypairFromSeed(seed string, network uint16) (*Keypair, error) {
+	kp, err := signature.KeyringPairFromSecret(seed, network)
+	return &Keypair{&kp}, err
+}
+
+func NewKeypairFromKRP(pair signature.KeyringPair) *Keypair {
+	return &Keypair{&pair}
+}
+
+// AsKeyringPair returns the underlying KeyringPair
+func (kp *Keypair) AsKeyringPair() *signature.KeyringPair {
+	return kp.keyringPair
+}
+
+// Encode uses scale to encode underlying KeyringPair
+func (kp *Keypair) Encode() ([]byte, error) {
+	var buffer = bytes.Buffer{}
+	err := scale.NewEncoder(&buffer).Encode(kp.keyringPair)
+	if err != nil {
+		return buffer.Bytes(), err
+	}
+	return buffer.Bytes(), nil
+}
+
+// Decode initializes keypair by decoding input as a KeyringPair
+func (kp *Keypair) Decode(in []byte) error {
+	kp.keyringPair = &signature.KeyringPair{}
+
+	return scale.NewDecoder(bytes.NewReader(in)).Decode(kp.keyringPair)
+}
+
+// Address returns the ss58 formated address
+func (kp *Keypair) Address() string {
+	return kp.keyringPair.Address
+}
+
+// PublicKey returns the publickey encoded as a string
+func (kp *Keypair) PublicKey() string {
+	return hexutil.Encode(kp.keyringPair.PublicKey)
+}
diff --git a/crypto/sr25519/sr25519_test.go b/crypto/sr25519/sr25519_test.go
new file mode 100644
index 00000000..2a14a166
--- /dev/null
+++ b/crypto/sr25519/sr25519_test.go
@@ -0,0 +1,60 @@
+// Copyright 2020 ChainSafe Systems
+// SPDX-License-Identifier: LGPL-3.0-only
+
+package sr25519
+
+import (
+	"reflect"
+	"testing"
+
+	"github.com/centrifuge/go-substrate-rpc-client/v4/signature"
+)
+
+func TestNewKeypairFromSeed(t *testing.T) {
+	kp, err := NewKeypairFromSeed("//Alice", 42)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if kp.PublicKey() == "" || kp.Address() == "" {
+		t.Fatalf("key is missing data: %#v", kp)
+	}
+}
+
+func TestKeypair_AsKeyringPair(t *testing.T) {
+
+	kp, err := NewKeypairFromSeed("//Alice", 42)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	krp := kp.AsKeyringPair()
+
+	// TODO: Add expected output from subkey
+
+	if !reflect.DeepEqual(&signature.TestKeyringPairAlice, krp) {
+		t.Fatalf("unexpected result.\n\tGot: %#v\n\texpected: %#v\n", krp, &signature.TestKeyringPairAlice)
+	}
+
+}
+
+func TestEncodeAndDecodeKeypair(t *testing.T) {
+	kp, err := NewKeypairFromSeed("//Alice", 42)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	enc, err := kp.Encode()
+	if err != nil {
+		t.Fatal(err)
+	}
+	res := new(Keypair)
+	err = res.Decode(enc)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if !reflect.DeepEqual(res, kp) {
+		t.Fatalf("Fail: got %#v expected %#v", res, kp)
+	}
+}
diff --git a/relayer/message/message.go b/relayer/message/message.go
index 32600837..4d0ffd9f 100644
--- a/relayer/message/message.go
+++ b/relayer/message/message.go
@@ -7,3 +7,12 @@ type Message struct {
 	Data        interface{} // Data associated with the message
 	Type        MessageType // Message type
 }
+
+func NewMessage(source, destination uint8, data interface{}, msgType MessageType) *Message {
+	return &Message{
+		Source:      source,
+		Destination: destination,
+		Data:        data,
+		Type:        msgType,
+	}
+}
diff --git a/relayer/proposal/proposal.go b/relayer/proposal/proposal.go
index f4f6eebc..456d5ea8 100644
--- a/relayer/proposal/proposal.go
+++ b/relayer/proposal/proposal.go
@@ -7,3 +7,12 @@ type Proposal struct {
 	Data        interface{}
 	Type        ProposalType
 }
+
+func NewProposal(source uint8, destination uint8, data interface{}, propType ProposalType) *Proposal {
+	return &Proposal{
+		Source:      source,
+		Destination: destination,
+		Data:        data,
+		Type:        propType,
+	}
+}