diff --git a/Makefile b/Makefile
index 7712c6a1784f114afb04be79d17b0ef647872e0b..657afc891a3ecac25d132c699a30cc3f0e459940 100644
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,7 @@ update_release:
 	GOFLAGS="" go get gitlab.com/elixxir/primitives@release
 	GOFLAGS="" go get gitlab.com/xx_network/crypto@release
 	GOFLAGS="" go get gitlab.com/elixxir/crypto@release
-	GOFLAGS="" go get -d gitlab.com/elixxir/client/v4@release
+	GOFLAGS="" go get -d gitlab.com/elixxir/client/v4@project/HavenBeta
 
 update_master:
 	GOFLAGS="" go get gitlab.com/elixxir/wasm-utils@master
diff --git a/go.mod b/go.mod
index a2f047722be1535744ff3cf78ab51a8cc08f4ced..529ef417e1e05705d52fcbd7d0c91b4666a0e811 100644
--- a/go.mod
+++ b/go.mod
@@ -8,8 +8,9 @@ require (
 	github.com/pkg/errors v0.9.1
 	github.com/spf13/cobra v1.7.0
 	github.com/spf13/jwalterweatherman v1.1.0
-	gitlab.com/elixxir/client/v4 v4.6.4-0.20230523181720-70dea644d559
-	gitlab.com/elixxir/crypto v0.0.7-0.20230522190154-5cbcf67f4b39
+	github.com/stretchr/testify v1.8.2
+	gitlab.com/elixxir/client/v4 v4.6.4-0.20230524163547-0691d7515af0
+	gitlab.com/elixxir/crypto v0.0.7-0.20230522162218-45433d877235
 	gitlab.com/elixxir/primitives v0.0.3-0.20230214180039-9a25e2d3969c
 	gitlab.com/elixxir/wasm-utils v0.0.0-20230522231408-a43b2c1481b2
 	gitlab.com/xx_network/crypto v0.0.5-0.20230214003943-8a09396e95dd
@@ -51,7 +52,6 @@ require (
 	github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect
 	github.com/soheilhy/cmux v0.1.5 // indirect
 	github.com/spf13/pflag v1.0.5 // indirect
-	github.com/stretchr/testify v1.8.2 // indirect
 	github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2 // indirect
 	github.com/ttacon/libphonenumber v1.2.1 // indirect
 	github.com/tyler-smith/go-bip39 v1.1.0 // indirect
diff --git a/go.sum b/go.sum
index c341fcefd3bfdc8377ebd1d1c15473db69be455a..97116d345e70e017bbd8b705a74512de2639efd2 100644
--- a/go.sum
+++ b/go.sum
@@ -405,12 +405,12 @@ github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo=
 github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
 gitlab.com/elixxir/bloomfilter v0.0.0-20230322223210-fa84f6842de8 h1:uAFCyBkXprQoPkcDDfxXtaMyL5x+xSGrAWzR907xROQ=
 gitlab.com/elixxir/bloomfilter v0.0.0-20230322223210-fa84f6842de8/go.mod h1:1X8gRIAPDisS3W6Vtr/ymiUmZMJUIwDV1o5DEOo/pzw=
-gitlab.com/elixxir/client/v4 v4.6.4-0.20230523181720-70dea644d559 h1:F1/+kAVnCqsxHeAiX7S0wYDGF0VhfNMEGoZZayyvt2w=
-gitlab.com/elixxir/client/v4 v4.6.4-0.20230523181720-70dea644d559/go.mod h1:trGefpFqH2+kx4/uEV+yyiEWpGq3AhRMnuBQDhDQKMM=
+gitlab.com/elixxir/client/v4 v4.6.4-0.20230524163547-0691d7515af0 h1:0aond5d8bNT2acvagMLGkygBty0AcWjYzjh4P99cl+k=
+gitlab.com/elixxir/client/v4 v4.6.4-0.20230524163547-0691d7515af0/go.mod h1:HgAbm91+FJ5NZ+tO9J1YoAcOOeH3n6ctu0AARQPHr5I=
 gitlab.com/elixxir/comms v0.0.4-0.20230519211512-4a998f4b0938 h1:f27+QUFiGWrprKm+fstOg3ABkYLpWcZi3+8Lf5eDnqY=
 gitlab.com/elixxir/comms v0.0.4-0.20230519211512-4a998f4b0938/go.mod h1:z+qW0D9VpY5QKTd7wRlb5SK4kBNqLYsa4DXBcUXue9Q=
-gitlab.com/elixxir/crypto v0.0.7-0.20230522190154-5cbcf67f4b39 h1:cU8066kdJRH88GUetdoYfT4ATg+uzSyquhHbVcbxw7Q=
-gitlab.com/elixxir/crypto v0.0.7-0.20230522190154-5cbcf67f4b39/go.mod h1:IYInxKr5Q7EH3oNhg1QX1/sTTRNi7L0JkcyfdRegoio=
+gitlab.com/elixxir/crypto v0.0.7-0.20230522162218-45433d877235 h1:0BySdXTzRWxzH8k5RiNNMmmn2lpuQWLVcDDA/7ehyqc=
+gitlab.com/elixxir/crypto v0.0.7-0.20230522162218-45433d877235/go.mod h1:IYInxKr5Q7EH3oNhg1QX1/sTTRNi7L0JkcyfdRegoio=
 gitlab.com/elixxir/ekv v0.3.1-0.20230504190918-f5e96603c2e0 h1:4d2vg4Sh3N5mR1ta152cg6ybPWHYqsPtkEyJKaDYGnw=
 gitlab.com/elixxir/ekv v0.3.1-0.20230504190918-f5e96603c2e0/go.mod h1:EMaUQrsOxvEPQ0/8V/PSkGqFmEC2axBG/uqY0oW2uJM=
 gitlab.com/elixxir/primitives v0.0.3-0.20230214180039-9a25e2d3969c h1:muG8ff95woeVVwQoJHCEclxBFB22lc7EixPylEkYDRU=
diff --git a/indexedDb/impl/channels/callbacks.go b/indexedDb/impl/channels/callbacks.go
index 1d541bf5f23280bfc41d45d6b64f05e2ff4c6684..2a901597117fac367e360ee2f80a2567fcab036f 100644
--- a/indexedDb/impl/channels/callbacks.go
+++ b/indexedDb/impl/channels/callbacks.go
@@ -15,7 +15,6 @@ import (
 
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/bindings"
 	"gitlab.com/elixxir/client/v4/channels"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
 	cryptoBroadcast "gitlab.com/elixxir/crypto/broadcast"
@@ -82,25 +81,19 @@ func (m *manager) newWASMEventModelCB(data []byte) ([]byte, error) {
 
 // EventUpdate implements [bindings.ChannelUICallbacks.EventUpdate].
 func (m *manager) EventUpdate(eventType int64, jsonData []byte) {
-	var callbackTag worker.Tag
-	isValid := false
-	switch eventType {
-	case bindings.MessageReceived:
-		callbackTag = wChannels.MessageReceivedCallbackTag
-		isValid = true
-	case bindings.MessageDeleted:
-		callbackTag = wChannels.DeletedMessageCallbackTag
-		isValid = true
-	case bindings.UserMuted:
-		callbackTag = wChannels.MutedUserCallbackTag
-		isValid = true
-	default:
-		jww.ERROR.Printf("invalid indexedDB EventUpdate type %d: %+v)",
-			eventType, jsonData)
-	}
-	if isValid {
-		m.wtm.SendMessage(callbackTag, jsonData)
+	// Package parameters for sending
+	msg := &wChannels.EventUpdateCallbackMessage{
+		EventType: eventType,
+		JsonData:  jsonData,
 	}
+	data, err := json.Marshal(msg)
+	if err != nil {
+		jww.ERROR.Printf("Could not JSON marshal %T: %+v", msg, err)
+		return
+	}
+
+	// Send it to the main thread
+	m.wtm.SendMessage(wChannels.EventUpdateCallbackTag, data)
 }
 
 // joinChannelCB is the callback for wasmModel.JoinChannel. Always returns nil;
diff --git a/indexedDb/impl/channels/implementation.go b/indexedDb/impl/channels/implementation.go
index d55033349a60c424e946d6e79f352afc78be7e8d..f043c60be8b1c2b91931a466c1153ee2680ce07c 100644
--- a/indexedDb/impl/channels/implementation.go
+++ b/indexedDb/impl/channels/implementation.go
@@ -172,7 +172,11 @@ func (w *wasmModel) ReceiveMessage(channelID *id.ID, messageID message.ID,
 		return 0
 	}
 
-	w.sendReceiveMessageUpdate(uuid, channelID, false)
+	go w.eventUpdate(bindings.MessageReceived, bindings.MessageReceivedJson{
+		Uuid:      int64(uuid),
+		ChannelID: channelID,
+		Update:    false,
+	})
 	return uuid
 }
 
@@ -211,7 +215,11 @@ func (w *wasmModel) ReceiveReply(channelID *id.ID, messageID,
 		return 0
 	}
 
-	w.sendReceiveMessageUpdate(uuid, channelID, false)
+	go w.eventUpdate(bindings.MessageReceived, bindings.MessageReceivedJson{
+		Uuid:      int64(uuid),
+		ChannelID: channelID,
+		Update:    false,
+	})
 	return uuid
 }
 
@@ -249,7 +257,12 @@ func (w *wasmModel) ReceiveReaction(channelID *id.ID, messageID,
 		jww.ERROR.Printf("Failed to receive reaction: %+v", err)
 		return 0
 	}
-	w.sendReceiveMessageUpdate(uuid, channelID, false)
+
+	go w.eventUpdate(bindings.MessageReceived, bindings.MessageReceivedJson{
+		Uuid:      int64(uuid),
+		ChannelID: channelID,
+		Update:    false,
+	})
 	return uuid
 }
 
@@ -396,7 +409,18 @@ func (w *wasmModel) updateMessage(currentMsg *Message, messageID *message.ID,
 	if err != nil {
 		return 0, err
 	}
-	w.sendReceiveMessageUpdate(uuid, (*id.ID)(currentMsg.ChannelID), true)
+
+	channelID, err := id.Unmarshal(currentMsg.ChannelID)
+	if err != nil {
+		return 0, err
+	}
+
+	go w.eventUpdate(bindings.MessageReceived, bindings.MessageReceivedJson{
+		Uuid:      int64(uuid),
+		ChannelID: channelID,
+		Update:    true,
+	})
+
 	return uuid, nil
 }
 
@@ -493,48 +517,21 @@ func (w *wasmModel) DeleteMessage(messageID message.ID) error {
 		return err
 	}
 
-	eventData, err := json.Marshal(bindings.MessageDeletedJson{
-		MessageID: messageID,
-	})
-	if err != nil {
-		jww.WARN.Printf("couldn't marshal MessageDeleted: %s, %+v",
-			messageID, err)
-	} else {
-		go w.eventUpdate(bindings.MessageDeleted, eventData)
-	}
+	go w.eventUpdate(bindings.MessageDeleted,
+		bindings.MessageDeletedJson{MessageID: messageID})
+
 	return nil
 }
 
 // MuteUser is called whenever a user is muted or unmuted.
 func (w *wasmModel) MuteUser(
 	channelID *id.ID, pubKey ed25519.PublicKey, unmute bool) {
-	eventData, err := json.Marshal(bindings.UserMutedJson{
+
+	go w.eventUpdate(bindings.UserMuted, bindings.UserMutedJson{
 		ChannelID: channelID,
 		PubKey:    pubKey,
 		Unmute:    unmute,
 	})
-	if err != nil {
-		jww.WARN.Printf("couldn't marshal UserMuted: %s, %+v",
-			pubKey, err)
-	} else {
-		go w.eventUpdate(bindings.UserMuted, eventData)
-	}
-}
-
-func (w *wasmModel) sendReceiveMessageUpdate(uuid uint64, channelID *id.ID,
-	update bool) {
-	eventMsg := bindings.MessageReceivedJson{
-		Uuid:      int64(uuid),
-		ChannelID: channelID,
-		Update:    update,
-	}
-	eventData, err := json.Marshal(eventMsg)
-	if err != nil {
-		jww.WARN.Printf("couldn't marshal MessageReceive: %v, %+v",
-			eventMsg, err)
-	} else {
-		go w.eventUpdate(bindings.MessageReceived, eventData)
-	}
 }
 
 // valueToMessage is a helper for converting js.Value to Message.
diff --git a/indexedDb/impl/channels/implementation_test.go b/indexedDb/impl/channels/implementation_test.go
index 9688c6714c6da34a5395e328865745b311580a30..f596065dcc47aa39e3b5aeda7b97a1f389071977 100644
--- a/indexedDb/impl/channels/implementation_test.go
+++ b/indexedDb/impl/channels/implementation_test.go
@@ -19,17 +19,16 @@ import (
 	"testing"
 	"time"
 
-	cft "gitlab.com/elixxir/client/v4/channelsFileTransfer"
-	"gitlab.com/elixxir/crypto/fileTransfer"
-
 	"github.com/hack-pad/go-indexeddb/idb"
 	jww "github.com/spf13/jwalterweatherman"
 	"github.com/stretchr/testify/require"
 
 	"gitlab.com/elixxir/client/v4/channels"
+	cft "gitlab.com/elixxir/client/v4/channelsFileTransfer"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
 	cryptoBroadcast "gitlab.com/elixxir/crypto/broadcast"
 	cryptoChannel "gitlab.com/elixxir/crypto/channel"
+	"gitlab.com/elixxir/crypto/fileTransfer"
 	"gitlab.com/elixxir/crypto/message"
 	"gitlab.com/elixxir/wasm-utils/storage"
 	"gitlab.com/elixxir/xxdk-wasm/indexedDb/impl"
@@ -45,7 +44,7 @@ func TestMain(m *testing.M) {
 
 type dummyCbs struct{}
 
-func (c *dummyCbs) EventUpdate(eventType int64, dataJson []byte) {}
+func (c *dummyCbs) EventUpdate(int64, []byte) {}
 
 // Happy path test for receiving, updating, getting, and deleting a File.
 func TestWasmModel_ReceiveFile(t *testing.T) {
diff --git a/indexedDb/worker/channels/init.go b/indexedDb/worker/channels/init.go
index dd0dd99d474299327a12aff8712ced83f9ba46e5..d24120aa445d6c161bf148a242439f4a6bf05eb1 100644
--- a/indexedDb/worker/channels/init.go
+++ b/indexedDb/worker/channels/init.go
@@ -64,18 +64,10 @@ func NewWASMEventModel(path, wasmJsPath string, encryption cryptoChannel.Cipher,
 		return nil, err
 	}
 
-	// Register handler to manage messages for the MessageReceivedCallback
-	wm.RegisterCallback(MessageReceivedCallbackTag,
+	// Register handler to manage messages for the EventUpdate
+	wm.RegisterCallback(EventUpdateCallbackTag,
 		messageReceivedCallbackHandler(channelCbs.EventUpdate))
 
-	// Register handler to manage messages for the DeletedMessageCallback
-	wm.RegisterCallback(DeletedMessageCallbackTag,
-		deletedMessageCallbackHandler(channelCbs.EventUpdate))
-
-	// Register handler to manage messages for the MutedUserCallback
-	wm.RegisterCallback(MutedUserCallbackTag,
-		mutedUserCallbackHandler(channelCbs.EventUpdate))
-
 	// Store the database name
 	err = storage.StoreIndexedDb(databaseName)
 	if err != nil {
@@ -132,23 +124,15 @@ type EventUpdateCallbackMessage struct {
 // MessageReceivedCallback.
 func messageReceivedCallbackHandler(cb eventUpdateCallback) func(data []byte) {
 	return func(data []byte) {
-		cb(bindings.MessageReceived, data)
-	}
-}
-
-// deletedMessageCallbackHandler returns a handler to manage messages for the
-// DeletedMessageCallback.
-func deletedMessageCallbackHandler(cb eventUpdateCallback) func(data []byte) {
-	return func(data []byte) {
-		cb(bindings.MessageDeleted, data)
-	}
-}
+		var msg EventUpdateCallbackMessage
+		err := json.Unmarshal(data, &msg)
+		if err != nil {
+			jww.ERROR.Printf(
+				"Failed to JSON unmarshal %T from worker: %+v", msg, err)
+			return
+		}
 
-// mutedUserCallbackHandler returns a handler to manage messages for the
-// MutedUserCallback.
-func mutedUserCallbackHandler(cb eventUpdateCallback) func(data []byte) {
-	return func(data []byte) {
-		cb(bindings.UserMuted, data)
+		cb(msg.EventType, msg.JsonData)
 	}
 }
 
diff --git a/indexedDb/worker/channels/tags.go b/indexedDb/worker/channels/tags.go
index 019911288e4cdc2c78ad352d7813094e31aeee99..f21c91653547cfe37158d514ef482c468084d800 100644
--- a/indexedDb/worker/channels/tags.go
+++ b/indexedDb/worker/channels/tags.go
@@ -14,11 +14,8 @@ import "gitlab.com/elixxir/xxdk-wasm/worker"
 // List of tags that can be used when sending a message or registering a handler
 // to receive a message.
 const (
-	NewWASMEventModelTag          worker.Tag = "NewWASMEventModel"
-	NotificationUpdateCallbackTag worker.Tag = "NotificationUpdateCallback"
-	MessageReceivedCallbackTag    worker.Tag = "MessageReceivedCallback"
-	DeletedMessageCallbackTag     worker.Tag = "DeletedMessageCallback"
-	MutedUserCallbackTag          worker.Tag = "MutedUserCallback"
+	NewWASMEventModelTag   worker.Tag = "NewWASMEventModel"
+	EventUpdateCallbackTag worker.Tag = "EventUpdateCallback"
 
 	JoinChannelTag         worker.Tag = "JoinChannel"
 	LeaveChannelTag        worker.Tag = "LeaveChannel"
diff --git a/wasm/channels.go b/wasm/channels.go
index a551d637a4e38512a54be92cddfc039e58fcbd4b..eb5c571d3ff98c60fd2f3e6140ea94d0cdb4dc8b 100644
--- a/wasm/channels.go
+++ b/wasm/channels.go
@@ -258,34 +258,35 @@ func GetPublicChannelIdentityFromPrivate(_ js.Value, args []js.Value) any {
 // Parameters:
 //   - args[0] - ID of [Cmix] object in tracker (int). This can be retrieved
 //     using [Cmix.GetID].
-//   - args[1] - ID of [bindings.Notifications] object in tracker (int). Can be
-//     retrieved using [Notifications.GetID].
-//   - args[2] - Bytes of a private identity ([channel.PrivateIdentity]) that is
+//   - args[1] - Bytes of a private identity ([channel.PrivateIdentity]) that is
 //     generated by [GenerateChannelIdentity] (Uint8Array).
+//   - args[2] - A function that initialises and returns a Javascript object
+//     that matches the [bindings.EventModel] interface. The function must match
+//     the Build function in [bindings.EventModelBuilder].
 //   - args[3] - JSON of an array of integers of [channels.ExtensionBuilder]
 //     IDs. The ID can be retrieved from an object with an extension builder
 //     (e.g., [ChannelsFileTransfer.GetExtensionBuilderID]). Leave empty if not
 //     using extension builders. Example: `[2,11,5]` (Uint8Array).
-//   - args[4] - A function that initialises and returns a Javascript object
-//     that matches the [bindings.EventModel] interface. The function must match
-//     the Build function in [bindings.EventModelBuilder].
-//   - args[4] - A callback object which implements the
-//     [bindings.ChannelUICallbacks] javascript functions.
+//   - args[4] - ID of [Notifications] object in tracker. This can be retrieved
+//     using [Notifications.GetID] (int).
+//   - args[5] - A Javascript object that implements the function on
+//     [bindings.ChannelUICallbacks]. It is a callback that informs the UI about
+//     various events. The entire interface can be nil, but if defined, each
+//     method must be implemented.
 //
 // Returns:
 //   - Javascript representation of the [ChannelsManager] object.
 //   - Throws an error if creating the manager fails.
 func NewChannelsManager(_ js.Value, args []js.Value) any {
 	cmixId := args[0].Int()
-	notificationsId := args[1].Int()
-	privateIdentity := utils.CopyBytesToGo(args[2])
+	privateIdentity := utils.CopyBytesToGo(args[1])
+	em := newEventModelBuilder(args[2])
 	extensionBuilderIDsJSON := utils.CopyBytesToGo(args[3])
-	em := newEventModelBuilder(args[4])
-	channelCbs := newChannelUI(args[5])
+	notificationsID := args[4].Int()
+	cUI := newChannelUI(args[5])
 
 	cm, err := bindings.NewChannelsManager(
-		cmixId, privateIdentity, extensionBuilderIDsJSON, em,
-		notificationsId, channelCbs)
+		cmixId, privateIdentity, em, extensionBuilderIDsJSON, notificationsID, cUI)
 	if err != nil {
 		exception.ThrowTrace(err)
 		return nil
@@ -305,27 +306,34 @@ func NewChannelsManager(_ js.Value, args []js.Value) any {
 // Parameters:
 //   - args[0] - ID of [Cmix] object in tracker (int). This can be retrieved
 //     using [Cmix.GetID].
-//   - args[1] - ID of [bindings.Notifications] object in tracker (int). Can be
-//     retrieved using [Notifications.GetID].
-//   - args[2] - The storage tag associated with the previously created channel
+//   - args[1] - The storage tag associated with the previously created channel
 //     manager and retrieved with [ChannelsManager.GetStorageTag] (string).
-//   - args[3] - A function that initialises and returns a Javascript object
+//   - args[2] - A function that initializes and returns a Javascript object
 //     that matches the [bindings.EventModel] interface. The function must match
 //     the Build function in [bindings.EventModelBuilder].
-//   - args[4] - A callback object which implements the
-//     [bindings.ChannelUICallbacks] javascript functions.
+//   - args[3] - JSON of an array of integers of [channels.ExtensionBuilder]
+//     IDs. The ID can be retrieved from an object with an extension builder
+//     (e.g., [ChannelsFileTransfer.GetExtensionBuilderID]). Leave empty if not
+//     using extension builders. Example: `[2,11,5]`.
+//   - args[4] - ID of [Notifications] object in tracker. This can be retrieved
+//     using [Notifications.GetID] (int).
+//   - args[5] - A Javascript object that implements the function on
+//     [bindings.ChannelUICallbacks]. It is a callback that informs the UI about
+//     various events. The entire interface can be nil, but if defined, each
+//     method must be implemented.
 //
 // Returns:
 //   - Javascript representation of the [ChannelsManager] object.
 //   - Throws an error if loading the manager fails.
 func LoadChannelsManager(_ js.Value, args []js.Value) any {
-	cMixID := args[0].Int()
-	notificationsID := args[1].Int()
-	storageTag := args[2].String()
-	em := newEventModelBuilder(args[3])
-	cUI := newChannelUI(args[4])
-	cm, err := bindings.LoadChannelsManager(cMixID, storageTag, em,
-		notificationsID, cUI)
+	cmixID := args[0].Int()
+	storageTag := args[1].String()
+	em := newEventModelBuilder(args[2])
+	extensionBuilderIDsJSON := utils.CopyBytesToGo(args[3])
+	notificationsID := args[4].Int()
+	cUI := newChannelUI(args[5])
+	cm, err := bindings.LoadChannelsManager(
+		cmixID, storageTag, em, extensionBuilderIDsJSON, notificationsID, cUI)
 	if err != nil {
 		exception.ThrowTrace(err)
 		return nil
@@ -348,17 +356,19 @@ func LoadChannelsManager(_ js.Value, args []js.Value) any {
 // Parameters:
 //   - args[0] - ID of [Cmix] object in tracker (int). This can be retrieved
 //     using [Cmix.GetID].
-//   - args[1] - ID of [bindings.Notifications] object in tracker (int). Can be
-//     retrieved using [Notifications.GetID].
-//   - args[2] - Path to Javascript file that starts the worker (string).
-//   - args[3] - Bytes of a private identity ([channel.PrivateIdentity]) that is
+//   - args[1] - Path to Javascript file that starts the worker (string).
+//   - args[2] - Bytes of a private identity ([channel.PrivateIdentity]) that is
 //     generated by [GenerateChannelIdentity] (Uint8Array).
-//   - args[4] - JSON of an array of integers of [channels.ExtensionBuilder]
+//   - args[3] - JSON of an array of integers of [channels.ExtensionBuilder]
 //     IDs. The ID can be retrieved from an object with an extension builder
 //     (e.g., [ChannelsFileTransfer.GetExtensionBuilderID]). Leave empty if not
 //     using extension builders. Example: `[2,11,5]` (Uint8Array).
-//   - args[5] - A callback object which implements the
-//     [bindings.ChannelUICallbacks] javascript functions.
+//   - args[4] - ID of [Notifications] object in tracker. This can be retrieved
+//     using [Notifications.GetID] (int).
+//   - args[5] - A Javascript object that implements the function on
+//     [bindings.ChannelUICallbacks]. It is a callback that informs the UI about
+//     various events. The entire interface can be nil, but if defined, each
+//     method must be implemented.
 //   - args[6] - ID of [ChannelDbCipher] object in tracker (int). Create this
 //     object with [NewChannelsDatabaseCipher] and get its id with
 //     [ChannelDbCipher.GetID].
@@ -369,11 +379,11 @@ func LoadChannelsManager(_ js.Value, args []js.Value) any {
 //   - Throws an error if the cipher ID does not correspond to a cipher.
 func NewChannelsManagerWithIndexedDb(_ js.Value, args []js.Value) any {
 	cmixID := args[0].Int()
-	notificationsID := args[1].Int()
-	wasmJsPath := args[2].String()
-	privateIdentity := utils.CopyBytesToGo(args[3])
-	extensionBuilderIDsJSON := utils.CopyBytesToGo(args[4])
-	channelCbs := newChannelUI(args[5])
+	wasmJsPath := args[1].String()
+	privateIdentity := utils.CopyBytesToGo(args[2])
+	extensionBuilderIDsJSON := utils.CopyBytesToGo(args[3])
+	notificationsID := args[4].Int()
+	cUI := newChannelUI(args[5])
 	cipherID := args[6].Int()
 
 	cipher, err := bindings.GetChannelDbCipherTrackerFromID(cipherID)
@@ -381,9 +391,8 @@ func NewChannelsManagerWithIndexedDb(_ js.Value, args []js.Value) any {
 		exception.ThrowTrace(err)
 	}
 
-	return newChannelsManagerWithIndexedDb(cmixID, notificationsID,
-		wasmJsPath, privateIdentity,
-		extensionBuilderIDsJSON, channelCbs, cipher)
+	return newChannelsManagerWithIndexedDb(cmixID, wasmJsPath, privateIdentity,
+		extensionBuilderIDsJSON, notificationsID, cUI, cipher)
 }
 
 // NewChannelsManagerWithIndexedDbUnsafe creates a new [ChannelsManager] from a
@@ -401,17 +410,19 @@ func NewChannelsManagerWithIndexedDb(_ js.Value, args []js.Value) any {
 // Parameters:
 //   - args[0] - ID of [Cmix] object in tracker (int). This can be retrieved
 //     using [Cmix.GetID].
-//   - args[1] - ID of [bindings.Notifications] object in tracker (int). Can be
-//     retrieved using [Notifications.GetID].
-//   - args[2] - Path to Javascript file that starts the worker (string).
-//   - args[3] - Bytes of a private identity ([channel.PrivateIdentity]) that is
+//   - args[1] - Path to Javascript file that starts the worker (string).
+//   - args[2] - Bytes of a private identity ([channel.PrivateIdentity]) that is
 //     generated by [GenerateChannelIdentity] (Uint8Array).
-//   - args[4] - JSON of an array of integers of [channels.ExtensionBuilder]
+//   - args[3] - JSON of an array of integers of [channels.ExtensionBuilder]
 //     IDs. The ID can be retrieved from an object with an extension builder
 //     (e.g., [ChannelsFileTransfer.GetExtensionBuilderID]). Leave empty if not
 //     using extension builders. Example: `[2,11,5]` (Uint8Array).
-//   - args[5] - A callback object which implements the
-//     [bindings.ChannelUICallbacks] javascript functions.
+//   - args[4] - ID of [Notifications] object in tracker. This can be retrieved
+//     using [Notifications.GetID] (int).
+//   - args[5] - A Javascript object that implements the function on
+//     [bindings.ChannelUICallbacks]. It is a callback that informs the UI about
+//     various events. The entire interface can be nil, but if defined, each
+//     method must be implemented.
 //
 // Returns a promise:
 //   - Resolves to a Javascript representation of the [ChannelsManager] object.
@@ -420,19 +431,18 @@ func NewChannelsManagerWithIndexedDb(_ js.Value, args []js.Value) any {
 // FIXME: package names in comments for indexedDb
 func NewChannelsManagerWithIndexedDbUnsafe(_ js.Value, args []js.Value) any {
 	cmixID := args[0].Int()
-	notificationsID := args[1].Int()
-	wasmJsPath := args[2].String()
-	privateIdentity := utils.CopyBytesToGo(args[3])
-	extensionBuilderIDsJSON := utils.CopyBytesToGo(args[4])
-	channelsCbs := newChannelUI(args[5])
+	wasmJsPath := args[1].String()
+	privateIdentity := utils.CopyBytesToGo(args[2])
+	extensionBuilderIDsJSON := utils.CopyBytesToGo(args[3])
+	notificationsID := args[4].Int()
+	cUI := newChannelUI(args[5])
 
-	return newChannelsManagerWithIndexedDb(cmixID, notificationsID,
-		wasmJsPath, privateIdentity,
-		extensionBuilderIDsJSON, channelsCbs, nil)
+	return newChannelsManagerWithIndexedDb(cmixID, wasmJsPath, privateIdentity,
+		extensionBuilderIDsJSON, notificationsID, cUI, nil)
 }
 
-func newChannelsManagerWithIndexedDb(cmixID, notificationsID int,
-	wasmJsPath string, privateIdentity, extensionBuilderIDsJSON []byte,
+func newChannelsManagerWithIndexedDb(cmixID int, wasmJsPath string,
+	privateIdentity, extensionBuilderIDsJSON []byte, notificationsID int,
 	channelsCbs bindings.ChannelUICallbacks,
 	cipher *bindings.ChannelDbCipher) any {
 
@@ -440,9 +450,9 @@ func newChannelsManagerWithIndexedDb(cmixID, notificationsID int,
 		wasmJsPath, cipher, channelsCbs)
 
 	promiseFn := func(resolve, reject func(args ...any) js.Value) {
-		cm, err := bindings.NewChannelsManagerGoEventModel(
-			cmixID, privateIdentity, extensionBuilderIDsJSON, model,
-			notificationsID, channelsCbs)
+		cm, err := bindings.NewChannelsManagerGoEventModel(cmixID,
+			privateIdentity, extensionBuilderIDsJSON, model, notificationsID,
+			channelsCbs)
 		if err != nil {
 			reject(exception.NewTrace(err))
 		} else {
@@ -464,14 +474,20 @@ func newChannelsManagerWithIndexedDb(cmixID, notificationsID int,
 // Parameters:
 //   - args[0] - ID of [Cmix] object in tracker (int). This can be retrieved
 //     using [Cmix.GetID].
-//   - args[1] - ID of [bindings.Notifications] object in tracker (int). Can be
-//     retrieved using [Notifications.GetID].
-//   - args[2] - Path to Javascript file that starts the worker (string).
-//   - args[3] - The storage tag associated with the previously created channel
+//   - args[1] - Path to Javascript file that starts the worker (string).
+//   - args[2] - The storage tag associated with the previously created channel
 //     manager and retrieved with [ChannelsManager.GetStorageTag] (string).
-//   - args[4] - A callback object which implements the
-//     [bindings.ChannelUICallbacks] javascript functions.
-//   - args[5] - ID of [ChannelDbCipher] object in tracker (int). Create this
+//   - args[3] - JSON of an array of integers of [channels.ExtensionBuilder]
+//     IDs. The ID can be retrieved from an object with an extension builder
+//     (e.g., [ChannelsFileTransfer.GetExtensionBuilderID]). Leave empty if not
+//     using extension builders. Example: `[2,11,5]` (Uint8Array).
+//   - args[4] - ID of [Notifications] object in tracker. This can be retrieved
+//     using [Notifications.GetID] (int).
+//   - args[5] - A Javascript object that implements the function on
+//     [bindings.ChannelUICallbacks]. It is a callback that informs the UI about
+//     various events. The entire interface can be nil, but if defined, each
+//     method must be implemented.
+//   - args[6] - ID of [ChannelDbCipher] object in tracker (int). Create this
 //     object with [NewChannelsDatabaseCipher] and get its id with
 //     [ChannelDbCipher.GetID].
 //
@@ -481,20 +497,20 @@ func newChannelsManagerWithIndexedDb(cmixID, notificationsID int,
 //   - Throws an error if the cipher ID does not correspond to a cipher.
 func LoadChannelsManagerWithIndexedDb(_ js.Value, args []js.Value) any {
 	cmixID := args[0].Int()
-	notificationsID := args[1].Int()
-	wasmJsPath := args[2].String()
-	storageTag := args[3].String()
-	channelsCbs := newChannelUI(args[4])
-	cipherID := args[5].Int()
+	wasmJsPath := args[1].String()
+	storageTag := args[2].String()
+	extensionBuilderIDsJSON := utils.CopyBytesToGo(args[3])
+	notificationsID := args[4].Int()
+	channelsCbs := newChannelUI(args[5])
+	cipherID := args[6].Int()
 
 	cipher, err := bindings.GetChannelDbCipherTrackerFromID(cipherID)
 	if err != nil {
 		exception.ThrowTrace(err)
 	}
 
-	return loadChannelsManagerWithIndexedDb(cmixID, notificationsID,
-		wasmJsPath, storageTag,
-		channelsCbs, cipher)
+	return loadChannelsManagerWithIndexedDb(cmixID, wasmJsPath, storageTag,
+		extensionBuilderIDsJSON, notificationsID, channelsCbs, cipher)
 }
 
 // LoadChannelsManagerWithIndexedDbUnsafe loads an existing [ChannelsManager]
@@ -510,32 +526,37 @@ func LoadChannelsManagerWithIndexedDb(_ js.Value, args []js.Value) any {
 // Parameters:
 //   - args[0] - ID of [Cmix] object in tracker (int). This can be retrieved
 //     using [Cmix.GetID].
-//   - args[1] - ID of [bindings.Notifications] object in tracker (int). Can be
-//     retrieved using [Notifications.GetID].
-//   - args[2] - Path to Javascript file that starts the worker (string).
-//   - args[3] - The storage tag associated with the previously created channel
+//   - args[1] - Path to Javascript file that starts the worker (string).
+//   - args[2] - The storage tag associated with the previously created channel
 //     manager and retrieved with [ChannelsManager.GetStorageTag] (string).
-//   - args[4] - A callback object which implements the
-//     [bindings.ChannelUICallbacks] javascript functions.
+//   - args[3] - JSON of an array of integers of [channels.ExtensionBuilder]
+//     IDs. The ID can be retrieved from an object with an extension builder
+//     (e.g., [ChannelsFileTransfer.GetExtensionBuilderID]). Leave empty if not
+//     using extension builders. Example: `[2,11,5]` (Uint8Array).
+//   - args[4] - ID of [Notifications] object in tracker. This can be retrieved
+//     using [Notifications.GetID] (int).
+//   - args[5] - A Javascript object that implements the function on
+//     [bindings.ChannelUICallbacks]. It is a callback that informs the UI about
+//     various events. The entire interface can be nil, but if defined, each
+//     method must be implemented.
 //
 // Returns a promise:
 //   - Resolves to a Javascript representation of the [ChannelsManager] object.
 //   - Rejected with an error if loading indexedDb or the manager fails.
 func LoadChannelsManagerWithIndexedDbUnsafe(_ js.Value, args []js.Value) any {
 	cmixID := args[0].Int()
-	notificationsID := args[1].Int()
-	wasmJsPath := args[2].String()
-	storageTag := args[3].String()
-	cUI := newChannelUI(args[4])
+	wasmJsPath := args[1].String()
+	storageTag := args[2].String()
+	extensionBuilderIDsJSON := utils.CopyBytesToGo(args[3])
+	notificationsID := args[4].Int()
+	cUI := newChannelUI(args[5])
 
-	return loadChannelsManagerWithIndexedDb(cmixID, notificationsID,
-		wasmJsPath, storageTag,
-		cUI, nil)
+	return loadChannelsManagerWithIndexedDb(cmixID, wasmJsPath, storageTag,
+		extensionBuilderIDsJSON, notificationsID, cUI, nil)
 }
 
-func loadChannelsManagerWithIndexedDb(cmixID, notificationsID int,
-	wasmJsPath, storageTag string,
-	channelsCbs bindings.ChannelUICallbacks,
+func loadChannelsManagerWithIndexedDb(cmixID int, wasmJsPath, storageTag string,
+	extensionBuilderIDsJSON []byte, notificationsID int, channelsCbs bindings.ChannelUICallbacks,
 	cipher *bindings.ChannelDbCipher) any {
 
 	model := channelsDb.NewWASMEventModelBuilder(
@@ -543,7 +564,7 @@ func loadChannelsManagerWithIndexedDb(cmixID, notificationsID int,
 
 	promiseFn := func(resolve, reject func(args ...any) js.Value) {
 		cm, err := bindings.LoadChannelsManagerGoEventModel(
-			cmixID, storageTag, model, nil, notificationsID,
+			cmixID, storageTag, model, extensionBuilderIDsJSON, notificationsID,
 			channelsCbs)
 		if err != nil {
 			reject(exception.NewTrace(err))
@@ -974,9 +995,16 @@ func ValidForever(js.Value, []js.Value) any {
 //     to the user should be tracked while all actions should not be (boolean).
 //   - args[5] - JSON of [xxdk.CMIXParams]. If left empty
 //     [bindings.GetDefaultCMixParams] will be used internally (Uint8Array).
-//   - args[6] - pingBytes - An array of public keys of users that
-//     should receive mobile notifications for the message (JSON of
-//     []Uint8Array list).
+//   - args[6] - JSON of a slice of public keys of users that should receive
+//     mobile notifications for the message.
+//
+// Example slice of public keys:
+//
+//	[
+//	  "FgJMvgSsY4rrKkS/jSe+vFOJOs5qSSyOUSW7UtF9/KU=",
+//	  "fPqcHtrJ398PAC35QyWXEU9PHzz8Z4BKQTCxSvpSygw=",
+//	  "JnjCgh7g/+hNiI9VPKW01aRSxGOFmNulNCymy3ImXAo="
+//	]
 //
 // Returns a promise:
 //   - Resolves to the JSON of [bindings.ChannelSendReport] (Uint8Array).
@@ -988,16 +1016,11 @@ func (cm *ChannelsManager) SendGeneric(_ js.Value, args []js.Value) any {
 	leaseTimeMS := int64(args[3].Int())
 	tracked := args[4].Bool()
 	cmixParamsJSON := utils.CopyBytesToGo(args[5])
-	var pingBytes [][]byte
+	pingsJSON := utils.CopyBytesToGo(args[6])
 
 	promiseFn := func(resolve, reject func(args ...any) js.Value) {
-		err := json.Unmarshal(utils.CopyBytesToGo(args[6]), pingBytes)
-		if err != nil {
-			reject(exception.NewTrace(err))
-		}
-		sendReport, err := cm.api.SendGeneric(marshalledChanId,
-			messageType, msg, leaseTimeMS, tracked,
-			cmixParamsJSON, pingBytes)
+		sendReport, err := cm.api.SendGeneric(marshalledChanId, messageType,
+			msg, leaseTimeMS, tracked, cmixParamsJSON, pingsJSON)
 		if err != nil {
 			reject(exception.NewTrace(err))
 		} else {
@@ -1027,9 +1050,16 @@ func (cm *ChannelsManager) SendGeneric(_ js.Value, args []js.Value) any {
 //     be enumerated here. Use [ValidForever] to last the max message life.
 //   - args[3] - JSON of [xxdk.CMIXParams]. If left empty
 //     [bindings.GetDefaultCMixParams] will be used internally (Uint8Array).
-//   - args[4] - pingBytes - An array of public keys of users that
-//     should receive mobile notifications for the message (JSON of
-//     []Uint8Array list).
+//   - args[4] - JSON of a slice of public keys of users that should receive
+//     mobile notifications for the message.
+//
+// Example slice of public keys:
+//
+//	[
+//	  "FgJMvgSsY4rrKkS/jSe+vFOJOs5qSSyOUSW7UtF9/KU=",
+//	  "fPqcHtrJ398PAC35QyWXEU9PHzz8Z4BKQTCxSvpSygw=",
+//	  "JnjCgh7g/+hNiI9VPKW01aRSxGOFmNulNCymy3ImXAo="
+//	]
 //
 // Returns a promise:
 //   - Resolves to the JSON of [bindings.ChannelSendReport] (Uint8Array).
@@ -1039,16 +1069,11 @@ func (cm *ChannelsManager) SendMessage(_ js.Value, args []js.Value) any {
 	msg := args[1].String()
 	leaseTimeMS := int64(args[2].Int())
 	cmixParamsJSON := utils.CopyBytesToGo(args[3])
-	var pingBytes [][]byte
+	pingsJSON := utils.CopyBytesToGo(args[4])
 
 	promiseFn := func(resolve, reject func(args ...any) js.Value) {
-		err := json.Unmarshal(utils.CopyBytesToGo(args[6]), pingBytes)
-		if err != nil {
-			reject(exception.NewTrace(err))
-		}
 		sendReport, err := cm.api.SendMessage(
-			marshalledChanId, msg, leaseTimeMS, cmixParamsJSON,
-			pingBytes)
+			marshalledChanId, msg, leaseTimeMS, cmixParamsJSON, pingsJSON)
 		if err != nil {
 			reject(exception.NewTrace(err))
 		} else {
@@ -1085,9 +1110,16 @@ func (cm *ChannelsManager) SendMessage(_ js.Value, args []js.Value) any {
 //     be enumerated here. Use [ValidForever] to last the max message life.
 //   - args[4] - JSON of [xxdk.CMIXParams]. If left empty
 //     [bindings.GetDefaultCMixParams] will be used internally (Uint8Array).
-//   - args[6] - pingBytes - An array of public keys of users that
-//     should receive mobile notifications for the message (JSON of
-//     []Uint8Array list).
+//   - args[5] - JSON of a slice of public keys of users that should receive
+//     mobile notifications for the message.
+//
+// Example slice of public keys:
+//
+//	[
+//	  "FgJMvgSsY4rrKkS/jSe+vFOJOs5qSSyOUSW7UtF9/KU=",
+//	  "fPqcHtrJ398PAC35QyWXEU9PHzz8Z4BKQTCxSvpSygw=",
+//	  "JnjCgh7g/+hNiI9VPKW01aRSxGOFmNulNCymy3ImXAo="
+//	]
 //
 // Returns a promise:
 //   - Resolves to the JSON of [bindings.ChannelSendReport] (Uint8Array).
@@ -1098,16 +1130,11 @@ func (cm *ChannelsManager) SendReply(_ js.Value, args []js.Value) any {
 	messageToReactTo := utils.CopyBytesToGo(args[2])
 	leaseTimeMS := int64(args[3].Int())
 	cmixParamsJSON := utils.CopyBytesToGo(args[4])
-	var pingBytes [][]byte
+	pingsJSON := utils.CopyBytesToGo(args[5])
 
 	promiseFn := func(resolve, reject func(args ...any) js.Value) {
-		err := json.Unmarshal(utils.CopyBytesToGo(args[6]), pingBytes)
-		if err != nil {
-			reject(exception.NewTrace(err))
-		}
 		sendReport, err := cm.api.SendReply(marshalledChanId, msg,
-			messageToReactTo, leaseTimeMS, cmixParamsJSON,
-			pingBytes)
+			messageToReactTo, leaseTimeMS, cmixParamsJSON, pingsJSON)
 		if err != nil {
 			reject(exception.NewTrace(err))
 		} else {
@@ -1140,26 +1167,20 @@ func (cm *ChannelsManager) SendReply(_ js.Value, args []js.Value) any {
 //     be enumerated here. Use [ValidForever] to last the max message life.
 //   - args[4] - JSON of [xxdk.CMIXParams]. If left empty
 //     [bindings.GetDefaultCMixParams] will be used internally (Uint8Array).
-//   - args[5] - pingBytes - An array of public keys of users that
-//     should receive mobile notifications for the message (JSON of
-//     []Uint8Array list).
 //
 // Returns a promise:
 //   - Resolves to the JSON of [bindings.ChannelSendReport] (Uint8Array).
 //   - Rejected with an error if sending fails.
 func (cm *ChannelsManager) SendReaction(_ js.Value, args []js.Value) any {
-	marshalledChanId := utils.CopyBytesToGo(args[0])
-	reaction := args[1].String()
-	messageToReactTo := utils.CopyBytesToGo(args[2])
-	leaseTimeMS := int64(args[3].Int())
-	cmixParamsJSON := utils.CopyBytesToGo(args[4])
-	var pingBytes [][]byte
+	var (
+		marshalledChanId = utils.CopyBytesToGo(args[0])
+		reaction         = args[1].String()
+		messageToReactTo = utils.CopyBytesToGo(args[2])
+		leaseTimeMS      = int64(args[3].Int())
+		cmixParamsJSON   = utils.CopyBytesToGo(args[4])
+	)
 
 	promiseFn := func(resolve, reject func(args ...any) js.Value) {
-		err := json.Unmarshal(utils.CopyBytesToGo(args[6]), pingBytes)
-		if err != nil {
-			reject(exception.NewTrace(err))
-		}
 		sendReport, err := cm.api.SendReaction(marshalledChanId, reaction,
 			messageToReactTo, leaseTimeMS, cmixParamsJSON)
 		if err != nil {
@@ -1567,18 +1588,17 @@ func (cm *ChannelsManager) GetMutedUsers(_ js.Value, args []js.Value) any {
 // Notifications                                                              //
 ////////////////////////////////////////////////////////////////////////////////
 
-// GetNotificationLevel implements
-// [bindings.ChannelsManager.GetNotificationLevel]
+// GetNotificationLevel returns the [channels.NotificationLevel] for the given
+// channel.
 //
 // Parameters:
-//   - args[0] - channelIDBytes - The marshalled bytes of the
-//     channel's [id.ID] (Uint8Array)
+//   - args[0] - The marshalled bytes of the channel's [id.ID] (Uint8Array).
 //
 // Returns:
-//   - int - The [channels.NotificationLevel] for the channel.
-//     throws an error if there is an issue
-func (cm *ChannelsManager) GetNotificationLevel(_ js.Value,
-	args []js.Value) any {
+//   - The [channels.NotificationLevel] for the channel (int).
+//   - Throws an error if the channel ID cannot be unmarshalled or the channel
+//     cannot be found.
+func (cm *ChannelsManager) GetNotificationLevel(_ js.Value, args []js.Value) any {
 	channelIDBytes := utils.CopyBytesToGo(args[0])
 
 	level, err := cm.api.GetNotificationLevel(channelIDBytes)
@@ -1590,59 +1610,116 @@ func (cm *ChannelsManager) GetNotificationLevel(_ js.Value,
 	return level
 }
 
-// SetMobileNotificationsLevel implements
-// [bindings.ChannelsManager.SetMobileNotificationsLevel]
+// SetMobileNotificationsLevel sets the notification level for the given
+// channel. The [channels.NotificationLevel] dictates the type of notifications
+// received and the status controls weather the notification is push or in-app.
+// If muted, both the level and status must be set to mute.
+//
+// To use push notifications, a token must be registered with the notification
+// manager. Note, when enabling push notifications, information may be shared
+// with third parties (i.e., Firebase and Google's Palantir) and may represent a
+// security risk to the user.
 //
 // Parameters:
-//   - args[0] - channelIDBytes - The marshaled bytes of the channel's [id.ID]
-//     (Uint8Array).
-//   - args[1] - level - The [channels.NotificationLevel] to set for
-//     the channel.
-//   - args[2] - status - The [notifications.NotificationState] to set
-//     for the channel.
-//   - args[3] - push - True to enable push notifications and false to
-//     only have in-app notifications.
-//
-// Returns nothing or throws an error
-func (cm *ChannelsManager) SetMobileNotificationsLevel(_ js.Value,
-	args []js.Value) any {
+//   - args[0] - The marshalled bytes of the channel's [id.ID] (Uint8Array).
+//   - args[1] - The [channels.NotificationLevel] to set for the channel (int).
+//   - args[2] - The [notifications.NotificationState] to set for the channel
+//     (int).
+//
+// Returns:
+//   - Throws an error if setting the notification level fails.
+func (cm *ChannelsManager) SetMobileNotificationsLevel(_ js.Value, args []js.Value) any {
 	channelIDBytes := utils.CopyBytesToGo(args[0])
 	level := args[1].Int()
 	status := args[2].Int()
-	push := args[3].Bool()
 
-	err := cm.api.SetMobileNotificationsLevel(channelIDBytes, level,
-		status, push)
+	err := cm.api.SetMobileNotificationsLevel(channelIDBytes, level, status)
 	if err != nil {
 		exception.ThrowTrace(err)
+		return nil
 	}
+
 	return nil
 }
 
-// GetNotificationReportsForMe implements
-// [bindings.GetNotificationsReportsForMe]
+// GetNotificationReportsForMe checks the notification data against the filter
+// list to determine which notifications belong to the user. A list of
+// notification reports is returned detailing all notifications for the user.
 //
 // Parameters:
-//   - args[0] - notificationFilterJSON - JSON of a slice of
-//     [channels.NotificationFilter] (Uint8Array).
-//   - args[1] - notificationDataJSON - JSON of a slice of
-//     [notifications.Data] (Uint8Array).
+//   - notificationFilterJSON - JSON of a slice of [channels.NotificationFilter].
+//   - notificationDataJSON - JSON of a slice of [notifications.Data].
+//
+// Example JSON of a slice of [channels.NotificationFilter]:
+// [
+//
+//	  {
+//	    "identifier": "O8NUg0KaDo18ybTKajXM/sgqEYS37+lewPhGV/2sMAUDYXN5bUlkZW50aWZpZXI=",
+//	    "channelID": "O8NUg0KaDo18ybTKajXM/sgqEYS37+lewPhGV/2sMAUD",
+//	    "tags": ["6de69009a93d53793ee344e8fb48fae194eaf51861d3cc51c7348c337d13aedf-usrping"],
+//	    "allowLists": {
+//	      "allowWithTags": {},
+//	      "allowWithoutTags": {"102":{}, "2":{}}
+//	    }
+//	  },
+//	  {
+//	    "identifier": "O8NUg0KaDo18ybTKajXM/sgqEYS37+lewPhGV/2sMAUDc3ltSWRlbnRpZmllcg==",
+//	    "channelID": "O8NUg0KaDo18ybTKajXM/sgqEYS37+lewPhGV/2sMAUD",
+//	    "tags": ["6de69009a93d53793ee344e8fb48fae194eaf51861d3cc51c7348c337d13aedf-usrping"],
+//	    "allowLists": {
+//	      "allowWithTags": {},
+//	      "allowWithoutTags": {"1":{}, "40000":{}}
+//	    }
+//	  },
+//	  {
+//	    "identifier": "jCRgFRQvzzKOb8DJ0fqCRLgr9kiHN9LpqHXVhyHhhlQDYXN5bUlkZW50aWZpZXI=",
+//	    "channelID": "jCRgFRQvzzKOb8DJ0fqCRLgr9kiHN9LpqHXVhyHhhlQD",
+//	    "tags": ["6de69009a93d53793ee344e8fb48fae194eaf51861d3cc51c7348c337d13aedf-usrping"],
+//	    "allowLists": {
+//	      "allowWithTags": {},
+//	      "allowWithoutTags": {"102":{}, "2":{}}
+//	    }
+//	  }
+//	]
+//
+// Example JSON of a slice of [notifications.Data]:
+//
+//	[
+//	  {
+//	    "EphemeralID": -6475,
+//	    "RoundID": 875,
+//	    "IdentityFP": "jWG/UuxRjD80HEo0WX3KYIag5LCfgaWKAg==",
+//	    "MessageHash": "hDGE46QWa3d70y5nJTLbEaVmrFJHOyp2"
+//	  },
+//	  {
+//	    "EphemeralID": -2563,
+//	    "RoundID": 875,
+//	    "IdentityFP": "gL4nhCGKPNBm6YZ7KC0v4JThw65N9bRLTQ==",
+//	    "MessageHash": "WcS4vGrSWDK8Kj7JYOkMo8kSh1Xti94V"
+//	  },
+//	  {
+//	    "EphemeralID": -13247,
+//	    "RoundID": 875,
+//	    "IdentityFP": "qV3uD++VWPhD2rRMmvrP9j8hp+jpFSsUHg==",
+//	    "MessageHash": "VX6Tw7N48j7U2rRXYle20mFZi0If4CB1"
+//	  }
+//	]
 //
 // Returns:
-//   - []byte - JSON of a slice of [channels.NotificationReport].
-//     Throws an error if one occurs
+//   - The JSON of a slice of [channels.NotificationReport] (Uint8Array).
+//   - Throws an error if getting the report fails.
 func GetNotificationReportsForMe(_ js.Value, args []js.Value) any {
 	notificationFilterJSON := utils.CopyBytesToGo(args[0])
 	notificationDataJSON := utils.CopyBytesToGo(args[1])
 
-	nrs, err := bindings.GetNotificationReportsForMe(notificationFilterJSON,
-		notificationDataJSON)
+	report, err := bindings.GetNotificationReportsForMe(
+		notificationFilterJSON, notificationDataJSON)
 	if err != nil {
 		exception.ThrowTrace(err)
 		return nil
 	}
 
-	return utils.CopyBytesToJS(nrs)
+	return utils.CopyBytesToJS(report)
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -2393,6 +2470,6 @@ type channelUI struct {
 
 // EventUpdate implements
 // [bindings.ChannelUICallbacks.EventUpdate].
-func (c *channelUI) EventUpdate(eventType int64, dataJson []byte) {
-	c.eventUpdate(eventType, utils.CopyBytesToJS(dataJson))
+func (c *channelUI) EventUpdate(eventType int64, jsonData []byte) {
+	c.eventUpdate(int(eventType), utils.CopyBytesToJS(jsonData))
 }
diff --git a/wasm/collective.go b/wasm/collective.go
index 77a8fdd35f3c5d45b57881b4cf895209aaab1a1d..3ce0c1250059b6a91f27c7867d5775fe519e5930 100644
--- a/wasm/collective.go
+++ b/wasm/collective.go
@@ -12,9 +12,8 @@ package wasm
 import (
 	"syscall/js"
 
-	"gitlab.com/elixxir/wasm-utils/exception"
-
 	"gitlab.com/elixxir/client/v4/bindings"
+	"gitlab.com/elixxir/wasm-utils/exception"
 	"gitlab.com/elixxir/wasm-utils/utils"
 )
 
diff --git a/wasm/e2eHandler.go b/wasm/e2eHandler.go
index fd107b0b1390a9ec759e0cdfaf0a6544ee97d3e6..e483fc7e46cf9e0624881aefaf80a9c5ffcae2af 100644
--- a/wasm/e2eHandler.go
+++ b/wasm/e2eHandler.go
@@ -201,15 +201,14 @@ type processor struct {
 //
 // Parameters:
 //   - message - Returns the message contents (Uint8Array).
-//   - tags - a byte array representing the tags on the message (Uint8Array)
-//   - metadata - other arbitrary metadata (Uint8Array)
+//   - tags - The tags on the message (Uint8Array).
+//   - metadata - Other arbitrary metadata (Uint8Array).
 //   - receptionId - Returns the marshalled bytes of the sender's [id.ID]
 //     (Uint8Array).
 //   - ephemeralId - Returns the ephemeral ID of the sender (int).
 //   - roundId - Returns the ID of the round sent on (int).
 func (p *processor) Process(message, tags, metadata, receptionId []byte,
-	ephemeralId int64, roundId int64) {
-
+	ephemeralId, roundId int64) {
 	p.process(utils.CopyBytesToJS(message),
 		utils.CopyBytesToJS(tags),
 		utils.CopyBytesToJS(metadata),
diff --git a/wasm/follow.go b/wasm/follow.go
index cfc49d4241bb0b87eb184685b4f521daa7105f03..a0fdeb73b4db5926ddba8f604bf7583fe07c7ac8 100644
--- a/wasm/follow.go
+++ b/wasm/follow.go
@@ -382,22 +382,21 @@ func (tsc *trackServicesCallback) Callback(marshalData []byte, err error) {
 	tsc.callback(utils.CopyBytesToJS(marshalData), exception.NewTrace(err))
 }
 
-// trackServicesCallback adheres to the [bindings.TrackServicesCallback]
-// interface.
+// trackCompressedServicesCallback adheres to the
+// [bindings.TrackCompressedServicesCallback] interface.
 type trackCompressedServicesCallback struct {
 	callback func(args ...any) js.Value
 }
 
-// Callback is the callback for [Cmix.TrackCompressedServices]. This
-// will pass to the user a JSON-marshalled list of backend
-// services. If there was an error retrieving or marshalling the
-// service list, there is an error for the second parameter, which
-// will be non-null.
+// Callback is the callback for [Cmix.TrackServices] that passes a
+// JSON-marshalled list of compressed backend services. If an error occurs while
+// retrieving or marshalling the service list, then err will be non-null.
 //
 // Parameters:
-//   - marshalData - Returns the JSON of
-//     [message.CompressedServiceList] (Uint8Array).
-//   - err - Returns an error on failure (Error).
+//   - marshalData - JSON of [message.CompressedServiceList] (Uint8Array),
+//     which is a map of [id.ID] to an array of [message.CompressedService].
+//   - err - Error that occurs during retrieval or marshalling. Null otherwise
+//     (Error).
 //
 // Example JSON:
 //
@@ -424,9 +423,8 @@ type trackCompressedServicesCallback struct {
 //	     }
 //	   ]
 //	 }
-func (tcsc *trackCompressedServicesCallback) Callback(marshalData []byte,
-	err error) {
-	tcsc.callback(utils.CopyBytesToJS(marshalData), exception.NewTrace(err))
+func (tsc *trackCompressedServicesCallback) Callback(marshalData []byte, err error) {
+	tsc.callback(utils.CopyBytesToJS(marshalData), exception.NewTrace(err))
 }
 
 // TrackServicesWithIdentity will return via a callback the list of services the
@@ -437,20 +435,17 @@ func (tcsc *trackCompressedServicesCallback) Callback(marshalData []byte,
 // Parameters:
 //   - args[0] - ID of [E2e] object in tracker (int).
 //   - args[1] - Javascript object that has functions that implement the
-//     [bindings.TrackServicesCallback] interface.
-//   - args[1] - Javascript object that has functions that implement the
-//     [bindings.TrackCompressedServicesCallback] interface.
+//     [bindings.ClientError] interface.
+//   - args[2] - Javascript object that has functions that implement the
+//     [bindings.TrackCompressedServicesCallback], which will be passed the JSON
+//     of [message.CompressedServiceList].
 //
 // Returns:
 //   - Throws TypeError if the [E2e] ID is invalid.
 func (c *Cmix) TrackServicesWithIdentity(_ js.Value, args []js.Value) any {
 	err := c.api.TrackServicesWithIdentity(args[0].Int(),
-		&trackServicesCallback{
-			utils.WrapCB(args[0], "Callback"),
-		},
-		&trackCompressedServicesCallback{
-			utils.WrapCB(args[0], "Callback"),
-		})
+		&trackServicesCallback{utils.WrapCB(args[0], "Callback")},
+		&trackCompressedServicesCallback{utils.WrapCB(args[0], "Callback")})
 	if err != nil {
 		exception.ThrowTrace(err)
 		return nil