diff --git a/Makefile b/Makefile
index ef9bc2a690b2397ea8342e79aa5d5217fff7d4c7..c899add28240bd6c3c47544c55a47d4e9c47c8aa 100644
--- a/Makefile
+++ b/Makefile
@@ -20,6 +20,7 @@ update_release:
 update_master:
 	GOFLAGS="" go get -d gitlab.com/elixxir/client@master
 	GOFLAGS="" go get gitlab.com/elixxir/crypto@master
+	GOFLAGS="" go get gitlab.com/elixxir/primitives@master
 	GOFLAGS="" go get gitlab.com/xx_network/primitives@master
 
 binary:
diff --git a/wasm/authenticatedConnection.go b/wasm/authenticatedConnection.go
index 8b2d03f263b1d60277ee5709d7437c6d5c4b5583..c18f48d062b918b682a77188b951e3fa16d77d08 100644
--- a/wasm/authenticatedConnection.go
+++ b/wasm/authenticatedConnection.go
@@ -68,10 +68,11 @@ func (ac *AuthenticatedConnection) GetId(js.Value, []js.Value) interface{} {
 //    [Cmix.WaitForRoundResult] to see if the send succeeded (Uint8Array).
 //  - Rejected with an error if sending fails.
 func (ac *AuthenticatedConnection) SendE2E(_ js.Value, args []js.Value) interface{} {
-	payload := utils.CopyBytesToGo(args[2])
+	mt := args[0].Int()
+	payload := utils.CopyBytesToGo(args[1])
 
 	promiseFn := func(resolve, reject func(args ...interface{}) js.Value) {
-		sendReport, err := ac.api.SendE2E(args[0].Int(), payload)
+		sendReport, err := ac.api.SendE2E(mt, payload)
 		if err != nil {
 			reject(utils.JsTrace(err))
 		} else {
@@ -135,12 +136,13 @@ func (ac *AuthenticatedConnection) RegisterListener(
 //  - Resolves to a Javascript representation of the [Connection] object.
 //  - Rejected with an error if loading the parameters or connecting fails.
 func (c *Cmix) ConnectWithAuthentication(_ js.Value, args []js.Value) interface{} {
+	e2eID := args[0].Int()
 	recipientContact := utils.CopyBytesToGo(args[1])
 	e2eParamsJSON := utils.CopyBytesToGo(args[2])
 
 	promiseFn := func(resolve, reject func(args ...interface{}) js.Value) {
 		ac, err := c.api.ConnectWithAuthentication(
-			args[0].Int(), recipientContact, e2eParamsJSON)
+			e2eID, recipientContact, e2eParamsJSON)
 		if err != nil {
 			reject(utils.JsTrace(err))
 		} else {
diff --git a/wasm/channels.go b/wasm/channels.go
index f93a95c5498f107000b7dcfd8c6f17d9d969a60e..024d31c0d627b64bacf8287347236ae5fe280323 100644
--- a/wasm/channels.go
+++ b/wasm/channels.go
@@ -10,7 +10,6 @@
 package wasm
 
 import (
-	"gitlab.com/elixxir/client/channels"
 	"syscall/js"
 
 	"gitlab.com/elixxir/client/bindings"
@@ -135,7 +134,9 @@ type eventModelBuilder struct {
 	build func(args ...interface{}) js.Value
 }
 
-// Build initializes and returns the event model.
+// Build initializes and returns the event model.  It wraps a Javascript object
+// that has all the methods in [bindings.EventModel] to make it adhere to the Go
+// interface [bindings.EventModel].
 func (emb *eventModelBuilder) Build(path string) bindings.EventModel {
 	emJs := emb.build(path)
 	return &eventModel{
@@ -233,21 +234,12 @@ func LoadChannelsManager(_ js.Value, args []js.Value) interface{} {
 //  - Resolves to a Javascript representation of the [ChannelsManager] object.
 //  - Rejected with an error if loading indexedDb or the manager fails.
 func NewChannelsManagerWithIndexedDb(_ js.Value, args []js.Value) interface{} {
+	cmixID := args[0].Int()
 	privateIdentity := utils.CopyBytesToGo(args[1])
 
 	promiseFn := func(resolve, reject func(args ...interface{}) js.Value) {
-		emBuilder := func(path string) channels.EventModel {
-			em, err := indexedDb.NewWasmEventModel(path)
-			if err != nil {
-				reject(utils.JsTrace(err))
-				return nil
-			}
-
-			return em
-		}
-
 		cm, err := bindings.NewChannelsManagerGoEventModel(
-			args[0].Int(), privateIdentity, emBuilder)
+			cmixID, privateIdentity, indexedDb.NewWasmEventModel)
 		if err != nil {
 			reject(utils.JsTrace(err))
 		} else {
@@ -276,19 +268,12 @@ func NewChannelsManagerWithIndexedDb(_ js.Value, args []js.Value) interface{} {
 //  - Resolves to a Javascript representation of the [ChannelsManager] object.
 //  - Rejected with an error if loading indexedDb or the manager fails.
 func LoadChannelsManagerWithIndexedDb(_ js.Value, args []js.Value) interface{} {
-	promiseFn := func(resolve, reject func(args ...interface{}) js.Value) {
-		emBuilder := func(path string) channels.EventModel {
-			em, err := indexedDb.NewWasmEventModel(path)
-			if err != nil {
-				reject(utils.JsTrace(err))
-				return nil
-			}
-
-			return em
-		}
+	cmixID := args[0].Int()
+	storageTag := args[1].String()
 
+	promiseFn := func(resolve, reject func(args ...interface{}) js.Value) {
 		cm, err := bindings.LoadChannelsManagerGoEventModel(
-			args[0].Int(), args[1].String(), emBuilder)
+			cmixID, storageTag, indexedDb.NewWasmEventModel)
 		if err != nil {
 			reject(utils.JsTrace(err))
 		} else {
@@ -569,15 +554,15 @@ func (ch *ChannelsManager) SendMessage(_ js.Value, args []js.Value) interface{}
 	return utils.CreatePromise(promiseFn)
 }
 
-// SendReply is used to send a formatted message over a channel.
-// Due to the underlying encoding using compression, it isn't possible to define
-// the largest payload that can be sent, but it will always be possible to send
-// a payload of 766 bytes at minimum.
+// SendReply is used to send a formatted message over a channel. Due to the
+// underlying encoding using compression, it isn't possible to define the
+// largest payload that can be sent, but it will always be possible to send a
+// payload of 766 bytes at minimum.
 //
-// If the message ID the reply is sent to does not exist, then the other side
-// will post the message as a normal message and not a reply.
-// The message will auto delete validUntil after the round it is sent in,
-// lasting forever if ValidForever is used.
+// If the message ID the reply is sent to is nonexistent, the other side will
+// post the message as a normal message and not a reply. The message will auto
+// delete validUntil after the round it is sent in, lasting forever if
+// [channels.ValidForever] is used.
 //
 // Parameters:
 //  - args[0] - Marshalled bytes of the channel [id.ID] (Uint8Array).
diff --git a/wasm/connect.go b/wasm/connect.go
index e3bc13313df46d53856c2cb0f1468f4369cec013..cd3cce95d47094d7fb6edb093e093ad9129b9cad 100644
--- a/wasm/connect.go
+++ b/wasm/connect.go
@@ -61,11 +61,12 @@ func (c *Connection) GetId(js.Value, []js.Value) interface{} {
 //  - Resolves to a Javascript representation of the [Connection] object.
 //  - Rejected with an error if loading the parameters or connecting fails.
 func (c *Cmix) Connect(_ js.Value, args []js.Value) interface{} {
+	e2eID := args[0].Int()
 	recipientContact := utils.CopyBytesToGo(args[1])
 	e2eParamsJSON := utils.CopyBytesToGo(args[2])
 
 	promiseFn := func(resolve, reject func(args ...interface{}) js.Value) {
-		api, err := c.api.Connect(args[0].Int(), recipientContact, e2eParamsJSON)
+		api, err := c.api.Connect(e2eID, recipientContact, e2eParamsJSON)
 		if err != nil {
 			reject(utils.JsTrace(err))
 		} else {
@@ -92,10 +93,11 @@ func (c *Cmix) Connect(_ js.Value, args []js.Value) interface{} {
 //    into [Cmix.WaitForRoundResult] to see if the send succeeded (Uint8Array).
 //  - Rejected with an error if sending fails.
 func (c *Connection) SendE2E(_ js.Value, args []js.Value) interface{} {
+	e2eID := args[0].Int()
 	payload := utils.CopyBytesToGo(args[1])
 
 	promiseFn := func(resolve, reject func(args ...interface{}) js.Value) {
-		sendReport, err := c.api.SendE2E(args[0].Int(), payload)
+		sendReport, err := c.api.SendE2E(e2eID, payload)
 		if err != nil {
 			reject(utils.JsTrace(err))
 		} else {
diff --git a/wasm/e2eHandler.go b/wasm/e2eHandler.go
index 1929b3539ba721e1b0157a194cecf4964a238c83..556f9699da670662d1a5294c7d7407d02e79304c 100644
--- a/wasm/e2eHandler.go
+++ b/wasm/e2eHandler.go
@@ -170,13 +170,13 @@ func (e *E2e) RemoveService(_ js.Value, args []js.Value) interface{} {
 //    into [Cmix.WaitForRoundResult] to see if the send succeeded (Uint8Array).
 //  - Rejected with an error if sending fails.
 func (e *E2e) SendE2E(_ js.Value, args []js.Value) interface{} {
+	mt := args[0].Int()
 	recipientId := utils.CopyBytesToGo(args[1])
 	payload := utils.CopyBytesToGo(args[2])
 	e2eParams := utils.CopyBytesToGo(args[3])
 
 	promiseFn := func(resolve, reject func(args ...interface{}) js.Value) {
-		sendReport, err := e.api.SendE2E(
-			args[0].Int(), recipientId, payload, e2eParams)
+		sendReport, err := e.api.SendE2E(mt, recipientId, payload, e2eParams)
 		if err != nil {
 			reject(utils.JsTrace(err))
 		} else {
diff --git a/wasm/follow.go b/wasm/follow.go
index f794aa606d8396ced9ce570958c989c01aec75e8..627250636d990de545a9ed0b2b98e1afad752116 100644
--- a/wasm/follow.go
+++ b/wasm/follow.go
@@ -91,8 +91,9 @@ func (c *Cmix) StopNetworkFollower(js.Value, []js.Value) interface{} {
 //  - A promise that resolves if the network is healthy and rejects if the
 //    network is not healthy.
 func (c *Cmix) WaitForNetwork(_ js.Value, args []js.Value) interface{} {
+	timeoutMS := args[0].Int()
 	promiseFn := func(resolve, reject func(args ...interface{}) js.Value) {
-		if c.api.WaitForNetwork(args[0].Int()) {
+		if c.api.WaitForNetwork(timeoutMS) {
 			resolve()
 		} else {
 			reject()
diff --git a/wasm/group.go b/wasm/group.go
index 31c031af2f42160e03f8cd4f9349d9f10b12a430..ebe3b6aa38ad719407a1f3aaaefee687a9488b7d 100644
--- a/wasm/group.go
+++ b/wasm/group.go
@@ -113,8 +113,9 @@ func (g *GroupChat) MakeGroup(_ js.Value, args []js.Value) interface{} {
 //    into [Cmix.WaitForRoundResult] to see if the send succeeded (Uint8Array).
 //  - Rejected with an error if resending the request fails.
 func (g *GroupChat) ResendRequest(_ js.Value, args []js.Value) interface{} {
+	groupId := utils.CopyBytesToGo(args[0])
 	promiseFn := func(resolve, reject func(args ...interface{}) js.Value) {
-		sendReport, err := g.api.ResendRequest(utils.CopyBytesToGo(args[0]))
+		sendReport, err := g.api.ResendRequest(groupId)
 		if err != nil {
 			reject(utils.JsTrace(err))
 		} else {
@@ -181,9 +182,10 @@ func (g *GroupChat) LeaveGroup(_ js.Value, args []js.Value) interface{} {
 func (g *GroupChat) Send(_ js.Value, args []js.Value) interface{} {
 	groupId := utils.CopyBytesToGo(args[0])
 	message := utils.CopyBytesToGo(args[1])
+	tag := args[2].String()
 
 	promiseFn := func(resolve, reject func(args ...interface{}) js.Value) {
-		sendReport, err := g.api.Send(groupId, message, args[2].String())
+		sendReport, err := g.api.Send(groupId, message, tag)
 		if err != nil {
 			reject(utils.JsTrace(err))
 		} else {
diff --git a/wasm/ndf.go b/wasm/ndf.go
index 0d99bc9e58f4680a232d86d29956c51d5be5a85c..8e84254b3c0b017bb37d14fa1e6993a724d3adcc 100644
--- a/wasm/ndf.go
+++ b/wasm/ndf.go
@@ -28,9 +28,11 @@ import (
 //  - Resolves to the JSON of the NDF ([ndf.NetworkDefinition]) (Uint8Array).
 //  - Rejected with an error if downloading fails.
 func DownloadAndVerifySignedNdfWithUrl(_ js.Value, args []js.Value) interface{} {
+	url := args[0].String()
+	cert := args[1].String()
+
 	promiseFn := func(resolve, reject func(args ...interface{}) js.Value) {
-		ndf, err := bindings.DownloadAndVerifySignedNdfWithUrl(
-			args[0].String(), args[1].String())
+		ndf, err := bindings.DownloadAndVerifySignedNdfWithUrl(url, cert)
 		if err != nil {
 			reject(utils.JsTrace(err))
 		} else {