diff --git a/connect/auth.go b/connect/auth.go
index c9ed33edc8c985d73958762fac452296499a2a42..10988ed56cc51fa3c7108de0c9361ad8db187404 100644
--- a/connect/auth.go
+++ b/connect/auth.go
@@ -41,17 +41,24 @@ type Auth struct {
 // no lock is taken because this is assumed to be done exclusively under the
 // send lock taken in ProtoComms.transmit()
 func (c *ProtoComms) clientHandshake(host *Host) (err error) {
-
-	// Set up the context
-	client := pb.NewGenericClient(host.connection)
 	ctx, cancel := host.GetMessagingContext()
 	defer cancel()
+	var result *pb.AssignToken
+	if host.connection.IsWeb() {
+		wc := host.connection.GetWebConn()
+		err = wc.Invoke(ctx, "/messages.Generic/RequestToken", &pb.Ping{}, result)
+		if err != nil {
+			return err
+		}
+	} else {
+		client := pb.NewGenericClient(host.connection.GetGrpcConn())
 
-	// Send the token request message
-	result, err := client.RequestToken(ctx,
-		&pb.Ping{})
-	if err != nil {
-		return errors.New(err.Error())
+		// Send the token request message
+		result, err = client.RequestToken(ctx,
+			&pb.Ping{})
+		if err != nil {
+			return errors.New(err.Error())
+		}
 	}
 
 	remoteToken, err := token.Unmarshal(result.Token)
@@ -78,12 +85,23 @@ func (c *ProtoComms) clientHandshake(host *Host) (err error) {
 	ctx, cancel = host.GetMessagingContext()
 	defer cancel()
 
-	// Send the authenticate token message
-	_, err = client.AuthenticateToken(ctx, msg)
-	if err != nil {
-		return errors.New(err.Error())
+	if host.connection.IsWeb() {
+		wc := host.connection.GetWebConn()
+		err = wc.Invoke(ctx, "/messages.Generic/AuthenticateToken", &pb.Ping{}, result)
+		if err != nil {
+			return err
+		}
+	} else {
+		client := pb.NewGenericClient(host.connection.GetGrpcConn())
+
+		// Send the authenticate token message
+		_, err = client.AuthenticateToken(ctx, msg)
+		if err != nil {
+			return errors.New(err.Error())
+		}
 	}
-	jww.TRACE.Printf("Negotiatied Remote token: %v", remoteToken)
+
+	jww.TRACE.Printf("Negotiated Remote token: %v", remoteToken)
 	// Assign the host token
 	host.transmissionToken.Set(remoteToken)
 
diff --git a/connect/comms.go b/connect/comms.go
index ec3038a1c486320c512ce84433ef254e767ef7d5..1fcf23baa0db66abb378ed9bcd47eca8f53f8571 100644
--- a/connect/comms.go
+++ b/connect/comms.go
@@ -223,11 +223,11 @@ const (
 
 // Send sets up or recovers the Host's connection,
 // then runs the given transmit function.
-func (c *ProtoComms) Send(host *Host, f func(conn *grpc.ClientConn) (*any.Any,
+func (c *ProtoComms) Send(host *Host, f func(conn Connection) (*any.Any,
 	error)) (result *any.Any, err error) {
 
 	jww.TRACE.Printf("Attempting to send to host: %s", host)
-	fSh := func(conn *grpc.ClientConn) (interface{}, error) {
+	fSh := func(conn Connection) (interface{}, error) {
 		return f(conn)
 	}
 
@@ -241,7 +241,7 @@ func (c *ProtoComms) Send(host *Host, f func(conn *grpc.ClientConn) (*any.Any,
 
 // Stream sets up or recovers the Host's connection,
 // then runs the given Stream function.
-func (c *ProtoComms) Stream(host *Host, f func(conn *grpc.ClientConn) (
+func (c *ProtoComms) Stream(host *Host, f func(conn Connection) (
 	interface{}, error)) (client interface{}, err error) {
 
 	// Ensure the connection is running
diff --git a/connect/comms_test.go b/connect/comms_test.go
index bcbd23dc065a522fe4029099a122c9deb47e5310..08a7e6c301dbcd0637cfa6849fc1ab12093b2c6f 100644
--- a/connect/comms_test.go
+++ b/connect/comms_test.go
@@ -11,7 +11,6 @@ import (
 	"github.com/golang/protobuf/ptypes/any"
 	"github.com/pkg/errors"
 	"gitlab.com/xx_network/primitives/id"
-	"google.golang.org/grpc"
 	"testing"
 )
 
@@ -24,7 +23,7 @@ func TestSendNoAddressFails(t *testing.T) {
 	host := Host{}
 
 	// Create the Send Function
-	f := func(conn *grpc.ClientConn) (*any.Any, error) {
+	f := func(conn Connection) (*any.Any, error) {
 		t.Errorf("Client send function shouldn't have run")
 		return nil, errors.New("Client send function shouldn't have run")
 	}
diff --git a/connect/connection.go b/connect/connection.go
new file mode 100644
index 0000000000000000000000000000000000000000..6aa36552e0097ee3c4ad22e34f461b0ff57d2893
--- /dev/null
+++ b/connect/connection.go
@@ -0,0 +1,42 @@
+package connect
+
+import (
+	"github.com/ktr0731/grpc-web-go-client/grpcweb"
+	"google.golang.org/grpc"
+)
+
+const (
+	tlsError = "TLS cannot be disabled in production, only for testing suites!"
+)
+
+// Connection is an interface designed to sit between hosts and connections
+// to allow use of grpcweb clients.
+type Connection interface {
+	GetWebConn() *grpcweb.ClientConn
+	GetGrpcConn() *grpc.ClientConn
+	Connect() error
+	IsWeb() bool
+
+	Close() error
+
+	clientConnHelpers
+}
+
+// clientConnHelpers holds private helper methods exposed on the connection object
+type clientConnHelpers interface {
+	isAlive() bool
+	disconnect()
+}
+
+// newConnection initializes a webConn and returns it wrapped as a Connection
+func newConnection(isWeb bool, host *Host) Connection {
+	if isWeb {
+		return &webConn{
+			h: host,
+		}
+	} else {
+		return &grpcConn{
+			h: host,
+		}
+	}
+}
diff --git a/connect/connection_test.go b/connect/connection_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..5dea349da36199283d3422a3de43db20d429812f
--- /dev/null
+++ b/connect/connection_test.go
@@ -0,0 +1,73 @@
+package connect
+
+import (
+	"context"
+	"fmt"
+	"github.com/improbable-eng/grpc-web/go/grpcweb"
+	pb "gitlab.com/xx_network/comms/messages"
+	"gitlab.com/xx_network/crypto/csprng"
+	"gitlab.com/xx_network/primitives/id"
+	"google.golang.org/grpc"
+	"net"
+	"net/http"
+	"testing"
+	"time"
+)
+
+type TestGenericServer struct {
+}
+
+func (ts *TestGenericServer) AuthenticateToken(context.Context, *pb.AuthenticatedMessage) (*pb.Ack, error) {
+	return &pb.Ack{}, nil
+}
+
+func (ts *TestGenericServer) RequestToken(context.Context, *pb.Ping) (*pb.AssignToken, error) {
+	return &pb.AssignToken{Token: []byte("testtoken")}, nil
+}
+
+func TestWebConnection(t *testing.T) {
+	addr := "0.0.0.0:11420"
+	lis, err := net.Listen("tcp", addr)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	rng := csprng.NewSystemRNG()
+	hostId, err := id.NewRandomID(rng, id.User)
+	if err != nil {
+		t.Fatal(err)
+	}
+	hostParams := GetDefaultHostParams()
+	TestingOnlyDisableTLS = true
+
+	h, err := newHost(hostId, addr, nil, hostParams, true)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	go func() {
+		s := grpc.NewServer()
+		pb.RegisterGenericServer(s, &TestGenericServer{})
+		ws := grpcweb.WrapServer(s, grpcweb.WithOriginFunc(func(origin string) bool { return true }))
+		if err := http.Serve(lis, ws); err != nil {
+			fmt.Println(err)
+			t.Errorf("failed to serve: %v", err)
+		}
+	}()
+	time.Sleep(time.Second * 5)
+
+	err = h.connect()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	ctx, cancel := h.GetMessagingContext()
+	defer cancel()
+
+	// TODO: This fails with RequestToken, seemingly because Ping has no actual contents.  Throws an EOF error when attempting to parse response.  Need to look into this in client repo.
+	resp := &pb.AssignToken{}
+	err = h.connection.GetWebConn().Invoke(ctx, "/messages.Generic/RequestToken", &pb.Ping{}, resp)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
diff --git a/connect/grpcConn.go b/connect/grpcConn.go
new file mode 100644
index 0000000000000000000000000000000000000000..fadd45df5a4d52d70b6f22782e4f43094af94311
--- /dev/null
+++ b/connect/grpcConn.go
@@ -0,0 +1,148 @@
+package connect
+
+import (
+	"errors"
+	"fmt"
+	"github.com/ktr0731/grpc-web-go-client/grpcweb"
+	jww "github.com/spf13/jwalterweatherman"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/connectivity"
+	"math"
+	"sync/atomic"
+	"time"
+)
+
+// webConn implements the Connection interface
+type grpcConn struct {
+	h        *Host
+	webConn  *grpcweb.ClientConn
+	grpcConn *grpc.ClientConn
+}
+
+// GetWebConn returns the grpcweb ClientConn object
+func (gc *grpcConn) GetWebConn() *grpcweb.ClientConn {
+	jww.FATAL.Panic("Cannot GetWebConn on a host that is configured for grpc connections")
+	return nil
+}
+
+// GetGrpcConn returns the grpc ClientConn object
+func (gc *grpcConn) GetGrpcConn() *grpc.ClientConn {
+	return gc.grpcConn
+}
+
+// Connect initializes the appropriate connection using helper functions.
+func (gc *grpcConn) Connect() error {
+	return gc.connectGrpcHelper()
+}
+
+// IsWeb returns true if the webConn is configured for web connections
+func (gc *grpcConn) IsWeb() bool {
+	return false
+}
+
+// connectGrpcHelper creates a connection while not under a write lock.
+// undefined behavior if the caller has not taken the write lock
+func (gc *grpcConn) connectGrpcHelper() (err error) {
+	// Configure TLS options
+	var securityDial grpc.DialOption
+	if gc.h.credentials != nil {
+		// Create the gRPC client with TLS
+		securityDial = grpc.WithTransportCredentials(gc.h.credentials)
+	} else if TestingOnlyDisableTLS {
+		// Create the gRPC client without TLS
+		jww.WARN.Printf("Connecting to %v without TLS!", gc.h.GetAddress())
+		securityDial = grpc.WithInsecure()
+	} else {
+		jww.FATAL.Panicf(tlsError)
+	}
+
+	jww.DEBUG.Printf("Attempting to establish connection to %s using"+
+		" credentials: %+v", gc.h.GetAddress(), securityDial)
+
+	// Attempt to establish a new connection
+	var numRetries uint32
+	//todo-remove this retry block when grpc is updated
+	for numRetries = 0; numRetries < gc.h.params.MaxRetries && !gc.isAlive(); numRetries++ {
+		gc.h.disconnect()
+
+		jww.DEBUG.Printf("Connecting to %+v Attempt number %+v of %+v",
+			gc.h.GetAddress(), numRetries, gc.h.params.MaxRetries)
+
+		// If timeout is enabled, the max wait time becomes
+		// ~14 seconds (with maxRetries=100)
+		backoffTime := 2000 * (numRetries/16 + 1)
+		if backoffTime > 15000 {
+			backoffTime = 15000
+		}
+		ctx, cancel := newContext(time.Duration(backoffTime) * time.Millisecond)
+
+		dialOpts := []grpc.DialOption{
+			grpc.WithBlock(),
+			grpc.WithKeepaliveParams(gc.h.params.KaClientOpts),
+			grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(math.MaxInt32)),
+			securityDial,
+		}
+
+		windowSize := atomic.LoadInt32(gc.h.windowSize)
+		if windowSize != 0 {
+			dialOpts = append(dialOpts, grpc.WithInitialWindowSize(windowSize))
+			dialOpts = append(dialOpts, grpc.WithInitialConnWindowSize(windowSize))
+		}
+
+		// Create the connection
+		gc.grpcConn, err = grpc.DialContext(ctx, gc.h.GetAddress(),
+			dialOpts...)
+
+		if err != nil {
+			jww.DEBUG.Printf("Attempt number %+v to connect to %s failed\n",
+				numRetries, gc.h.GetAddress())
+		}
+		cancel()
+	}
+
+	// Verify that the connection was established successfully
+	if !gc.isAlive() {
+		gc.h.disconnect()
+		return errors.New(fmt.Sprintf(
+			"Last try to connect to %s failed. Giving up",
+			gc.h.GetAddress()))
+	}
+
+	// Add the successful connection to the Manager
+	jww.INFO.Printf("Successfully connected to %v", gc.h.GetAddress())
+	return
+}
+
+func (gc *grpcConn) Close() error {
+	if gc.grpcConn == nil {
+		return nil
+	}
+	return gc.grpcConn.Close()
+}
+
+// disconnect closes the grpcConn connection while not under a write lock.
+// undefined behavior if the caller has not taken the write lock
+func (gc *grpcConn) disconnect() {
+	// it's possible to close a host which never sent so that it never made a
+	// connection. In that case, we should not close a connection which does not
+	// exist
+	if gc.grpcConn != nil {
+		jww.INFO.Printf("Disconnected from %s at %s", gc.h.GetId(), gc.h.GetAddress())
+		err := gc.grpcConn.Close()
+		if err != nil {
+			jww.ERROR.Printf("Unable to close connection to %s: %+v",
+				gc.h.GetAddress(), errors.New(err.Error()))
+		} else {
+			gc.grpcConn = nil
+		}
+	}
+}
+
+func (gc *grpcConn) isAlive() bool {
+	if gc.grpcConn == nil {
+		return false
+	}
+	state := gc.grpcConn.GetState()
+	return state == connectivity.Idle || state == connectivity.Connecting ||
+		state == connectivity.Ready
+}
diff --git a/connect/host.go b/connect/host.go
index 118ee8b13530b84358adebfe80dfec1a52bb9898..c720640751beef9b0f36cf972e2f052992b755af 100644
--- a/connect/host.go
+++ b/connect/host.go
@@ -20,8 +20,6 @@ import (
 	"gitlab.com/xx_network/primitives/exponential"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/rateLimiting"
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/connectivity"
 	"google.golang.org/grpc/credentials"
 	"math"
 	"net"
@@ -52,7 +50,7 @@ type Host struct {
 	transmissionToken *token.Live
 
 	// GRPC connection object
-	connection      *grpc.ClientConn
+	connection      Connection
 	connectionCount uint64
 	// lock which ensures only a single thread is connecting at a time and
 	// that connections do not interrupt sends
@@ -82,8 +80,18 @@ type Host struct {
 	windowSize *int32
 }
 
-// NewHost creates a new Host object
+// NewHost creates a new host object which will use GRPC.
 func NewHost(id *id.ID, address string, cert []byte, params HostParams) (host *Host, err error) {
+	return newHost(id, address, cert, params, false)
+}
+
+// NewHostWeb creates a new host object which will use the grpcweb library.
+func NewHostWeb(id *id.ID, address string, cert []byte, params HostParams) (host *Host, err error) {
+	return newHost(id, address, cert, params, true)
+}
+
+// newHost is a helper which creates a new Host object
+func newHost(id *id.ID, address string, cert []byte, params HostParams, isWeb bool) (host *Host, err error) {
 
 	windowSize := int32(0)
 
@@ -99,6 +107,8 @@ func NewHost(id *id.ID, address string, cert []byte, params HostParams) (host *H
 		windowSize:        &windowSize,
 	}
 
+	host.connection = newConnection(isWeb, host)
+
 	if params.EnableCoolOff {
 		host.coolOffBucket = rateLimiting.CreateBucket(
 			params.NumSendsBeforeCoolOff+1, params.NumSendsBeforeCoolOff+1,
@@ -149,7 +159,7 @@ func (h *Host) Connected() (bool, uint64) {
 // a connection lock. Only use if already under a connection lock. The uint is
 //the connection count, it increments every time a reconnect occurs
 func (h *Host) connectedUnsafe() (bool, uint64) {
-	return h.isAlive() && !h.authenticationRequired(), h.connectionCount
+	return h.connection != nil && h.connection.isAlive() && !h.authenticationRequired(), h.connectionCount
 }
 
 // GetMessagingContext returns a context object for message sending configured according to HostParams
@@ -203,6 +213,11 @@ func (h *Host) isExcludedMetricError(err string) bool {
 	return false
 }
 
+// IsWeb returns the connection type of the host
+func (h *Host) IsWeb() bool {
+	return h.connection.IsWeb()
+}
+
 // SetMetricsTesting sets the host metrics to an arbitrary value. Used for testing
 // purposes only
 func (h *Host) SetMetricsTesting(m *Metric, face interface{}) {
@@ -260,7 +275,7 @@ func (h *Host) IsOnline() (time.Duration, bool) {
 
 // send checks that the host has a connection and sends if it does.
 // must be called under host's connection read lock.
-func (h *Host) transmit(f func(conn *grpc.ClientConn) (interface{},
+func (h *Host) transmit(f func(conn Connection) (interface{},
 	error)) (interface{}, error) {
 
 	// Check if connection is down
@@ -303,9 +318,8 @@ func (h *Host) Connect() error {
 
 // connect attempts to connect to the host if it does not have a valid connection
 func (h *Host) connect() error {
-
 	//connect to remote
-	if err := h.connectHelper(); err != nil {
+	if err := h.connection.Connect(); err != nil {
 		return err
 	}
 
@@ -327,104 +341,16 @@ func (h *Host) isAlive() bool {
 	if h.connection == nil {
 		return false
 	}
-	state := h.connection.GetState()
-	return state == connectivity.Idle || state == connectivity.Connecting ||
-		state == connectivity.Ready
+	return h.connection.isAlive()
 }
 
 // disconnect closes the Host connection while not under a write lock.
 // undefined behavior if the caller has not taken the write lock
 func (h *Host) disconnect() {
-	// it's possible to close a host which never sent so that it never made a
-	// connection. In that case, we should not close a connection which does not
-	// exist
-	if h.connection != nil {
-		jww.INFO.Printf("Disconnected from %s at %s", h.GetId(), h.GetAddress())
-		err := h.connection.Close()
-		if err != nil {
-			jww.ERROR.Printf("Unable to close connection to %s: %+v",
-				h.GetAddress(), errors.New(err.Error()))
-		} else {
-			h.connection = nil
-		}
-	}
+	h.connection.disconnect()
 	h.transmissionToken.Clear()
 }
 
-// connectHelper creates a connection while not under a write lock.
-// undefined behavior if the caller has not taken the write lock
-func (h *Host) connectHelper() (err error) {
-
-	// Configure TLS options
-	var securityDial grpc.DialOption
-	if h.credentials != nil {
-		// Create the gRPC client with TLS
-		securityDial = grpc.WithTransportCredentials(h.credentials)
-	} else if TestingOnlyDisableTLS {
-		// Create the gRPC client without TLS
-		jww.WARN.Printf("Connecting to %v without TLS!", h.GetAddress())
-		securityDial = grpc.WithInsecure()
-	} else {
-		jww.FATAL.Panicf("TLS cannot be disabled in production, only for testing suites!")
-	}
-
-	jww.DEBUG.Printf("Attempting to establish connection to %s using"+
-		" credentials: %+v", h.GetAddress(), securityDial)
-
-	// Attempt to establish a new connection
-	var numRetries uint32
-	//todo-remove this retry block when grpc is updated
-	for numRetries = 0; numRetries < h.params.MaxRetries && !h.isAlive(); numRetries++ {
-		h.disconnect()
-
-		jww.DEBUG.Printf("Connecting to %+v Attempt number %+v of %+v",
-			h.GetAddress(), numRetries, h.params.MaxRetries)
-
-		// If timeout is enabled, the max wait time becomes
-		// ~14 seconds (with maxRetries=100)
-		backoffTime := 2000 * (numRetries/16 + 1)
-		if backoffTime > 15000 {
-			backoffTime = 15000
-		}
-		ctx, cancel := newContext(time.Duration(backoffTime) * time.Millisecond)
-
-		dialOpts := []grpc.DialOption{
-			grpc.WithBlock(),
-			grpc.WithKeepaliveParams(h.params.KaClientOpts),
-			grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(math.MaxInt32)),
-			securityDial,
-		}
-
-		windowSize := atomic.LoadInt32(h.windowSize)
-		if windowSize != 0 {
-			dialOpts = append(dialOpts, grpc.WithInitialWindowSize(windowSize))
-			dialOpts = append(dialOpts, grpc.WithInitialConnWindowSize(windowSize))
-		}
-
-		// Create the connection
-		h.connection, err = grpc.DialContext(ctx, h.GetAddress(),
-			dialOpts...)
-
-		if err != nil {
-			jww.DEBUG.Printf("Attempt number %+v to connect to %s failed\n",
-				numRetries, h.GetAddress())
-		}
-		cancel()
-	}
-
-	// Verify that the connection was established successfully
-	if !h.isAlive() {
-		h.disconnect()
-		return errors.New(fmt.Sprintf(
-			"Last try to connect to %s failed. Giving up",
-			h.GetAddress()))
-	}
-
-	// Add the successful connection to the Manager
-	jww.INFO.Printf("Successfully connected to %v", h.GetAddress())
-	return
-}
-
 // setCredentials sets TransportCredentials and RSA PublicKey objects
 // using a PEM-encoded TLS Certificate
 func (h *Host) setCredentials() error {
diff --git a/connect/host_test.go b/connect/host_test.go
index 380243e41e67c73f74724f147a313b2172d3032b..2eb8665b701f0ee0ee48a4de0d9544da5afb568c 100644
--- a/connect/host_test.go
+++ b/connect/host_test.go
@@ -12,7 +12,6 @@ import (
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/xx_network/primitives/id"
-	"google.golang.org/grpc"
 	"net"
 	"strings"
 	"testing"
@@ -214,7 +213,7 @@ func TestHost_transmit_ProxyError(t *testing.T) {
 	if err != nil {
 		t.Fatalf("Unable to create host: %+v", host)
 	}
-	host.connection = &grpc.ClientConn{}
+	host.connection = &webConn{}
 
 	originalErr := errors.New("Unable to SendToAny via " +
 		"ZT9BlnUhZZaPGB/A0BBR6tIjRrASM5GcnXrSkepElWwB: Register: Failed " +
@@ -223,7 +222,7 @@ func TestHost_transmit_ProxyError(t *testing.T) {
 		"Unknown desc = unable to connect to target host " +
 		"I3g/DVoWVGsz/JTh6DuccdgXT8o0fM+TtA21EppKPtcB..Did not replace host.")
 
-	f := func(*grpc.ClientConn) (interface{}, error) {
+	f := func(conn Connection) (interface{}, error) {
 		return nil, originalErr
 	}
 
diff --git a/connect/transmit.go b/connect/transmit.go
index 307d7ca5ea7a89f7259304f5b596fa6dc748fc8f..0d72f75213fe0384b15bc86a52a771889dde32b3 100644
--- a/connect/transmit.go
+++ b/connect/transmit.go
@@ -10,7 +10,6 @@ package connect
 import (
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	"google.golang.org/grpc"
 	"strings"
 )
 
@@ -24,7 +23,7 @@ const lastTryErr = "Last try to connect to"
 // and then do the operation, leaving the host as connected. In a system
 // like the host pool in client, this will cause untracked connections.
 // Given that connections have timeouts, this is a minor issue
-func (c *ProtoComms) transmit(host *Host, f func(conn *grpc.ClientConn) (interface{},
+func (c *ProtoComms) transmit(host *Host, f func(conn Connection) (interface{},
 	error)) (result interface{}, err error) {
 
 	if host.GetAddress() == "" {
diff --git a/connect/webConn.go b/connect/webConn.go
new file mode 100644
index 0000000000000000000000000000000000000000..2d7e7d12eefcff903971cef90806ab13dc105b1d
--- /dev/null
+++ b/connect/webConn.go
@@ -0,0 +1,139 @@
+package connect
+
+import (
+	"fmt"
+	"github.com/ktr0731/grpc-web-go-client/grpcweb"
+	"github.com/pkg/errors"
+	jww "github.com/spf13/jwalterweatherman"
+	"google.golang.org/grpc"
+)
+
+// webConn implements the Connection interface
+type webConn struct {
+	h        *Host
+	webConn  *grpcweb.ClientConn
+	grpcConn *grpc.ClientConn
+}
+
+// GetWebConn returns the grpcweb ClientConn object
+func (wc *webConn) GetWebConn() *grpcweb.ClientConn {
+	return wc.webConn
+}
+
+// GetGrpcConn returns the grpc ClientConn object
+func (wc *webConn) GetGrpcConn() *grpc.ClientConn {
+	jww.FATAL.Panicf("Cannot GetGrpcConn on a host that is configured for web connections")
+	return nil
+}
+
+// Connect initializes the appropriate connection using helper functions.
+func (wc *webConn) Connect() error {
+	return wc.connectWebHelper()
+}
+
+// IsWeb returns true if the webConn is configured for web connections
+func (wc *webConn) IsWeb() bool {
+	return true
+}
+
+// connectWebHelper initializes the grpcweb ClientConn object
+// Note that until the downstream repo is fixed, this doesn't actually
+// establish a connection past creating the http object.
+func (wc *webConn) connectWebHelper() (err error) {
+	// Configure TLS options
+	var securityDial grpcweb.DialOption
+	if wc.h.credentials != nil {
+		securityDial = grpcweb.WithTransportCredentials(wc.h.credentials)
+	} else if TestingOnlyDisableTLS {
+		jww.WARN.Printf("Connecting to %v without TLS!", wc.h.GetAddress())
+		securityDial = grpcweb.WithInsecure()
+	} else {
+		jww.FATAL.Panicf(tlsError)
+	}
+
+	jww.DEBUG.Printf("Attempting to establish connection to %s using"+
+		" credentials: %+v", wc.h.GetAddress(), securityDial)
+
+	// Attempt to establish a new connection
+	var numRetries uint32
+	for numRetries = 0; numRetries < wc.h.params.MaxRetries && !wc.isAlive(); numRetries++ {
+		wc.h.disconnect()
+
+		jww.DEBUG.Printf("Connecting to %+v Attempt number %+v of %+v",
+			wc.h.GetAddress(), numRetries, wc.h.params.MaxRetries)
+
+		// If timeout is enabled, the max wait time becomes
+		// ~14 seconds (with maxRetries=100)
+		backoffTime := 2000 * (numRetries/16 + 1)
+		if backoffTime > 15000 {
+			backoffTime = 15000
+		}
+		//ctx, cancel := newContext(time.Duration(backoffTime) * time.Millisecond)
+
+		dialOpts := []grpcweb.DialOption{
+			// grpc.WithBlock(),
+			// grpc.WithKeepaliveParams(wc.h.params.KaClientOpts),
+			grpcweb.WithDefaultCallOptions(), // grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(math.MaxInt32)),
+			securityDial,
+		}
+
+		//windowSize := atomic.LoadInt32(wc.h.windowSize)
+		//if windowSize != 0 {
+		//	dialOpts = append(dialOpts, grpc.WithInitialWindowSize(windowSize))
+		//	dialOpts = append(dialOpts, grpc.WithInitialConnWindowSize(windowSize))
+		//}
+
+		// Create the connection
+		wc.webConn, err = grpcweb.DialContext(wc.h.GetAddress(),
+			dialOpts...)
+
+		if err != nil {
+			jww.DEBUG.Printf("Attempt number %+v to connect to %s failed\n",
+				numRetries, wc.h.GetAddress())
+		}
+		//cancel()
+	}
+
+	// Verify that the connection was established successfully
+	if !wc.isAlive() {
+		wc.h.disconnect()
+		return errors.New(fmt.Sprintf(
+			"Last try to connect to %s failed. Giving up",
+			wc.h.GetAddress()))
+	}
+
+	// Add the successful connection to the Manager
+	jww.INFO.Printf("Successfully connected to %v", wc.h.GetAddress())
+	return
+}
+
+// Close handles closing the http connection.
+func (wc *webConn) Close() error {
+	// TODO this needs work on the grpc-web-go-client side
+	if wc.webConn == nil {
+		return nil
+	}
+	return nil
+
+}
+
+// disconnect closes the webConn connection while not under a write lock.
+// undefined behavior if the caller has not taken the write lock
+func (wc *webConn) disconnect() {
+	// it's possible to close a host which never sent so that it never made a
+	// connection. In that case, we should not close a connection which does not
+	// exist
+	if wc.webConn != nil {
+		// TODO webconn cannot close yet, this needs work on that side
+		wc.webConn = nil
+	}
+
+}
+
+func (wc *webConn) isAlive() bool {
+	// TODO this cannot be determined until grpcweb clients have a persistent connection
+	if wc.webConn == nil {
+		return false
+	}
+	return true
+}
diff --git a/go.mod b/go.mod
index b4d768ed238dd28d381c7224f692db2217af9374..047e8dc24311653ac7e47ce9d9c996880a8bd887 100644
--- a/go.mod
+++ b/go.mod
@@ -4,6 +4,8 @@ go 1.13
 
 require (
 	github.com/golang/protobuf v1.5.2
+	github.com/improbable-eng/grpc-web v0.12.0
+	github.com/ktr0731/grpc-web-go-client v0.2.8
 	github.com/pkg/errors v0.9.1
 	github.com/spf13/jwalterweatherman v1.1.0
 	gitlab.com/xx_network/crypto v0.0.5-0.20220606200528-3f886fe49e81
diff --git a/go.sum b/go.sum
index 9326f0b5a80f0a4ef572ffb71a5bf1a928d44c37..b7f8ae4343ed35e1b4978d38627b0bd166d07fa6 100644
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,7 @@
 cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
+github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
@@ -8,11 +10,14 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I=
+github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE=
 github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
 github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
 github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
 github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3/go.mod h1:nPpo7qLxd6XL3hWJG/O60sR8ZKfMCiIoNap5GvD12KU=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@@ -38,24 +43,51 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
+github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
+github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
+github.com/improbable-eng/grpc-web v0.12.0 h1:GlCS+lMZzIkfouf7CNqY+qqpowdKuJLSLLcKVfM1oLc=
+github.com/improbable-eng/grpc-web v0.12.0/go.mod h1:6hRR09jOEG81ADP5wCQju1z71g6OL4eEvELdran/3cs=
 github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
 github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/ktr0731/dept v0.1.3/go.mod h1:b1EtCEjbjGShAfhZue+BrFKTG7sQmK7aSD7Q6VcGvO0=
+github.com/ktr0731/go-multierror v0.0.0-20171204182908-b7773ae21874/go.mod h1:ZWayuE/hCzOD96CJizvcYnqrbmTC7RAG332yNtlKj6w=
+github.com/ktr0731/grpc-test v0.1.4/go.mod h1:v47616grayBYXQveGWxO3OwjLB3nEEnHsZuMTc73FM0=
+github.com/ktr0731/grpc-web-go-client v0.2.8 h1:nUf9p+YWirmFwmH0mwtAWhuXvzovc+/3C/eAY2Fshnk=
+github.com/ktr0731/grpc-web-go-client v0.2.8/go.mod h1:1Iac8gFJvC/DRfZoGnFZsfEbEq/wQFK+2Ve1o3pHkCQ=
+github.com/ktr0731/modfile v1.11.2/go.mod h1:LzNwnHJWHbuDh3BO17lIqzqDldXqGu1HCydWH3SinE0=
+github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
+github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
+github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
 github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
 github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
+github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
+github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/rakyll/statik v0.1.6/go.mod h1:OEi9wJV/fMUAGx1eNjq75DKDsJVuEv1U0oYdX6GX8Zs=
+github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
+github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
 github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
 github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
+github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
 github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
 github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
@@ -85,6 +117,9 @@ gitlab.com/xx_network/primitives v0.0.2/go.mod h1:cs0QlFpdMDI6lAo61lDRH2JZz+3aVk
 gitlab.com/xx_network/primitives v0.0.4-0.20220222211843-901fa4a2d72b/go.mod h1:9imZHvYwNFobxueSvVtHneZLk9wTK7HQTzxPm+zhFhE=
 gitlab.com/xx_network/primitives v0.0.4-0.20220630163313-7890038258c6 h1:3It6ILDHn/9J/Oi7MfMjkidKPe7vbFCy5JQtXx8EfYM=
 gitlab.com/xx_network/primitives v0.0.4-0.20220630163313-7890038258c6/go.mod h1:AXVVFt7dDAeIUpOGPiStCcUIKsBXLWbmV/BgZ4T+tOo=
+go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
+go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
+go.uber.org/goleak v0.10.0/go.mod h1:VCZuO8V8mFPlL0F5J5GK1rtHV3DrFcQ1R8ryq7FK0aI=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@@ -96,11 +131,14 @@ golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
 golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo=
 golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
@@ -108,6 +146,7 @@ golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAG
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -124,6 +163,7 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -131,18 +171,22 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm
 golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20200204235621-fb4a7afc5178/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
 google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
 google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
 google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
 google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
 google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
 google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
 google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
diff --git a/gossip/protocol.go b/gossip/protocol.go
index d44212c24ded4161ce0c2a3facfa57e1521d34a3..eaad11a0cd74db275f493d03bdf24e6258648cec 100644
--- a/gossip/protocol.go
+++ b/gossip/protocol.go
@@ -19,7 +19,6 @@ import (
 	"gitlab.com/xx_network/crypto/shuffle"
 	"gitlab.com/xx_network/primitives/id"
 	"golang.org/x/crypto/blake2b"
-	"google.golang.org/grpc"
 	"io"
 	"math"
 	"sync"
@@ -292,8 +291,8 @@ func (p *Protocol) Gossip(msg *GossipMsg) (int, []error) {
 		if !ok {
 			return errors.Errorf("Failed to get host with ID %s", id)
 		}
-		f := func(conn *grpc.ClientConn) (*any.Any, error) {
-			gossipClient := NewGossipClient(conn)
+		f := func(conn connect.Connection) (*any.Any, error) {
+			gossipClient := NewGossipClient(conn.GetGrpcConn())
 			ack, err := gossipClient.Endpoint(context.Background(), msg)
 			if err != nil {
 				return nil, errors.WithMessage(err, "Failed to send message")
diff --git a/interconnect/consensusClient.go b/interconnect/consensusClient.go
index d4d0efd6178b09fdce4a6fa4758688499d6e44c5..d349f60db1a9f01c7753c2406fa0b97fb886a25a 100644
--- a/interconnect/consensusClient.go
+++ b/interconnect/consensusClient.go
@@ -16,7 +16,6 @@ import (
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/xx_network/comms/connect"
 	"gitlab.com/xx_network/comms/messages"
-	"google.golang.org/grpc"
 )
 
 // CMixServer -> consensus node Send Function
@@ -24,14 +23,14 @@ func (c *CMixServer) GetNdf(host *connect.Host,
 	message *messages.Ping) (*NDF, error) {
 
 	// Create the Send Function
-	f := func(conn *grpc.ClientConn) (*any.Any, error) {
+	f := func(conn connect.Connection) (*any.Any, error) {
 		// Set up the context
 		ctx, cancel := host.GetMessagingContext()
 		defer cancel()
 		//Format to authenticated message type
 		// Send the message
 
-		resultMsg, err := NewInterconnectClient(conn).GetNDF(ctx, message)
+		resultMsg, err := NewInterconnectClient(conn.GetGrpcConn()).GetNDF(ctx, message)
 		if err != nil {
 			return nil, errors.New(err.Error())
 		}