diff --git a/go.mod b/go.mod
index 52e77d9c6b81b92fa8ca028cf1b90dcfc21f0b39..2b702be5d45e4c52044e4cc94db377431b57d511 100644
--- a/go.mod
+++ b/go.mod
@@ -7,7 +7,7 @@ require (
 	github.com/hack-pad/go-indexeddb v0.2.0
 	github.com/pkg/errors v0.9.1
 	github.com/spf13/jwalterweatherman v1.1.0
-	gitlab.com/elixxir/client/v4 v4.6.4-0.20230522213235-dc7d3feb05b9
+	gitlab.com/elixxir/client/v4 v4.6.4-0.20230523165030-737b5db25f0d
 	gitlab.com/elixxir/crypto v0.0.7-0.20230522190154-5cbcf67f4b39
 	gitlab.com/elixxir/primitives v0.0.3-0.20230214180039-9a25e2d3969c
 	gitlab.com/xx_network/crypto v0.0.5-0.20230214003943-8a09396e95dd
diff --git a/go.sum b/go.sum
index 5fd785d49b778e55dc15bc2188a7e527f35073e0..8421df075940eae8587836e91ff57dc64db5053e 100644
--- a/go.sum
+++ b/go.sum
@@ -533,6 +533,8 @@ gitlab.com/elixxir/client/v4 v4.6.4-0.20230522204511-a198ba2e5749 h1:mFhb9/TDAtm
 gitlab.com/elixxir/client/v4 v4.6.4-0.20230522204511-a198ba2e5749/go.mod h1:rDC4sLKgj5kuuiJRp8bD1M7r0mlb0ib7q8q1Euct9/k=
 gitlab.com/elixxir/client/v4 v4.6.4-0.20230522213235-dc7d3feb05b9 h1:/g+OA8nsI0LwY1NgR7WPOAztengA2UqrY7xXZarmwgk=
 gitlab.com/elixxir/client/v4 v4.6.4-0.20230522213235-dc7d3feb05b9/go.mod h1:trGefpFqH2+kx4/uEV+yyiEWpGq3AhRMnuBQDhDQKMM=
+gitlab.com/elixxir/client/v4 v4.6.4-0.20230523165030-737b5db25f0d h1:amrJ1WHTJd9+EArwgoq4XUwHu09hFwxYNtTc3S7W7ew=
+gitlab.com/elixxir/client/v4 v4.6.4-0.20230523165030-737b5db25f0d/go.mod h1:trGefpFqH2+kx4/uEV+yyiEWpGq3AhRMnuBQDhDQKMM=
 gitlab.com/elixxir/comms v0.0.4-0.20230310205528-f06faa0d2f0b h1:8AVK93UEs/aufoqtFgyMVt9gf0oJ8F4pA60ZvEVvG+s=
 gitlab.com/elixxir/comms v0.0.4-0.20230310205528-f06faa0d2f0b/go.mod h1:z+qW0D9VpY5QKTd7wRlb5SK4kBNqLYsa4DXBcUXue9Q=
 gitlab.com/elixxir/comms v0.0.4-0.20230519211512-4a998f4b0938 h1:f27+QUFiGWrprKm+fstOg3ABkYLpWcZi3+8Lf5eDnqY=
diff --git a/indexedDb/impl/channels/callbacks.go b/indexedDb/impl/channels/callbacks.go
index 2550dbb9549ec92c82b8d00028bb5c5bd712c3bc..1d541bf5f23280bfc41d45d6b64f05e2ff4c6684 100644
--- a/indexedDb/impl/channels/callbacks.go
+++ b/indexedDb/impl/channels/callbacks.go
@@ -15,6 +15,7 @@ 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"
@@ -79,58 +80,27 @@ func (m *manager) newWASMEventModelCB(data []byte) ([]byte, error) {
 	return []byte{}, nil
 }
 
-// NotificationUpdate implements [bindings.ChannelUICallbacks.NotificationUpdate
-func (m *manager) NotificationUpdate(notificationFilterListJSON,
-	changedNotificationStatesJSON, deletedNotificationStatesJSON []byte,
-	maxState int) {
-	jww.FATAL.Panicf("unimplemented")
-}
-
-// MessageReceived implements [bindings.ChannelUICallbacks.MessageReceived].
-func (m *manager) MessageReceived(uuid int64, channelID []byte, update bool) {
-	// Package parameters for sending
-	msg := &wChannels.MessageReceivedCallbackMessage{
-		UUID:      uuid,
-		ChannelID: channelID,
-		Update:    update,
-	}
-	data, err := json.Marshal(msg)
-	if err != nil {
-		jww.ERROR.Printf("Could not JSON marshal %T: %+v", msg, err)
-		return
+// 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)
 	}
-
-	// Send it to the main thread
-	m.wtm.SendMessage(wChannels.MessageReceivedCallbackTag, data)
-}
-
-// MessageDeleted implements [bindings.ChannelUICallbacks.MessageDeleted].
-func (m *manager) MessageDeleted(messageID []byte) {
-	m.wtm.SendMessage(wChannels.DeletedMessageCallbackTag, messageID)
-}
-
-// UserMuted implements [bindings.ChannelUICallbacks.UserMuted].
-func (m *manager) UserMuted(channelID, pubKey []byte, unmute bool) {
-	// Package parameters for sending
-	msg := &wChannels.MuteUserMessage{
-		ChannelID: channelID,
-		PubKey:    pubKey,
-		Unmute:    unmute,
-	}
-	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.MutedUserCallbackTag, data)
-}
-
-// NicknameUpdate implements [bindings.ChannelUICallbacks.NicknameUpdate]
-func (m *manager) NicknameUpdate(channelIdBytes []byte, nickname string,
-	exists bool) {
-	jww.FATAL.Panicf("unimplemented")
 }
 
 // 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 04d7fb7e17dada785c95666bfc21ffff85eafc42..c017df06881eeef826d08fd54485ad498867aca9 100644
--- a/indexedDb/impl/channels/implementation.go
+++ b/indexedDb/impl/channels/implementation.go
@@ -172,7 +172,7 @@ func (w *wasmModel) ReceiveMessage(channelID *id.ID, messageID message.ID,
 		return 0
 	}
 
-	go w.cbs.MessageReceived(int64(uuid), channelIDBytes, false)
+	w.sendReceiveMessageUpdate(uuid, channelID, false)
 	return uuid
 }
 
@@ -210,7 +210,8 @@ func (w *wasmModel) ReceiveReply(channelID *id.ID, messageID,
 		jww.ERROR.Printf("Failed to receive reply: %+v", err)
 		return 0
 	}
-	go w.cbs.MessageReceived(int64(uuid), channelIDBytes, false)
+
+	w.sendReceiveMessageUpdate(uuid, channelID, false)
 	return uuid
 }
 
@@ -248,7 +249,7 @@ func (w *wasmModel) ReceiveReaction(channelID *id.ID, messageID,
 		jww.ERROR.Printf("Failed to receive reaction: %+v", err)
 		return 0
 	}
-	go w.cbs.MessageReceived(int64(uuid), channelIDBytes, false)
+	w.sendReceiveMessageUpdate(uuid, channelID, false)
 	return uuid
 }
 
@@ -395,8 +396,7 @@ func (w *wasmModel) updateMessage(currentMsg *Message, messageID *message.ID,
 	if err != nil {
 		return 0, err
 	}
-	go w.cbs.MessageReceived(int64(uuid), currentMsg.ChannelID, true)
-
+	w.sendReceiveMessageUpdate(uuid, (*id.ID)(currentMsg.ChannelID), true)
 	return uuid, nil
 }
 
@@ -493,15 +493,48 @@ func (w *wasmModel) DeleteMessage(messageID message.ID) error {
 		return err
 	}
 
-	go w.cbs.MessageDeleted(messageID.Bytes())
-
+	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.cbs.EventUpdate(bindings.MessageDeleted, eventData)
+	}
 	return nil
 }
 
 // MuteUser is called whenever a user is muted or unmuted.
 func (w *wasmModel) MuteUser(
 	channelID *id.ID, pubKey ed25519.PublicKey, unmute bool) {
-	go w.cbs.UserMuted(channelID.Marshal(), pubKey, unmute)
+	eventData, err := json.Marshal(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.cbs.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.cbs.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 7de828ef6235425dcb7b40f4efc5fa47ac717eb4..1a8c87f0792a71ab6274e4e82f7ef075bd17e5f7 100644
--- a/indexedDb/impl/channels/implementation_test.go
+++ b/indexedDb/impl/channels/implementation_test.go
@@ -44,16 +44,7 @@ func TestMain(m *testing.M) {
 
 type dummyCbs struct{}
 
-func (c *dummyCbs) MessageReceived(uuid int64, channelID []byte, update bool) {}
-func (c *dummyCbs) UserMuted(channelID []byte, pubKey []byte, unmute bool)    {}
-func (c *dummyCbs) MessageDeleted(messageId []byte)                           {}
-func (c *dummyCbs) NicknameUpdate(channelIdBytes []byte, nickname string,
-	exists bool) {
-}
-func (c *dummyCbs) NotificationUpdate(notificationFilterListJSON,
-	changedNotificationStatesJSON, deletedNotificationStatesJSON []byte,
-	maxState int) {
-}
+func (c *dummyCbs) EventUpdate(eventType int64, dataJson []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 34dd3f0d2548042a3778267e9b5e46172c384dd6..cf7b83f5fcb4a72d8e6ea22561f78790c950d727 100644
--- a/indexedDb/worker/channels/init.go
+++ b/indexedDb/worker/channels/init.go
@@ -20,7 +20,6 @@ import (
 	"gitlab.com/elixxir/client/v4/channels"
 
 	cryptoChannel "gitlab.com/elixxir/crypto/channel"
-	"gitlab.com/elixxir/crypto/message"
 	"gitlab.com/elixxir/xxdk-wasm/storage"
 	"gitlab.com/elixxir/xxdk-wasm/worker"
 )
@@ -28,17 +27,10 @@ import (
 // databaseSuffix is the suffix to be appended to the name of the database.
 const databaseSuffix = "_speakeasy"
 
-// MessageReceivedCallback is called any time a message is received or updated.
-//
-// update is true if the row is old and was edited.
-type MessageReceivedCallback func(uuid int64, channelID []byte, update bool)
-
-// DeletedMessageCallback is called any time a message is deleted.
-type DeletedMessageCallback func(messageID []byte)
-
-// MutedUserCallback is called any time a user is muted or unmuted. unmute is
-// true if the user has been unmuted and false if they have been muted.
-type MutedUserCallback func(channelID, pubKey []byte, unmute bool)
+// eventUpdateCallback is the [bindings.ChannelUICallback] callback function
+// it has a type ([bindings.NickNameUpdate] to [bindings.MessageDeleted]
+// and json data that is the callback information.
+type eventUpdateCallback func(eventType int64, jsonData []byte)
 
 // NewWASMEventModelBuilder returns an EventModelBuilder which allows
 // the channel manager to define the path but the callback is the same
@@ -74,15 +66,15 @@ func NewWASMEventModel(path, wasmJsPath string, encryption cryptoChannel.Cipher,
 
 	// Register handler to manage messages for the MessageReceivedCallback
 	wm.RegisterCallback(MessageReceivedCallbackTag,
-		messageReceivedCallbackHandler(channelCbs.MessageReceived))
+		messageReceivedCallbackHandler(channelCbs.EventUpdate))
 
 	// Register handler to manage messages for the DeletedMessageCallback
 	wm.RegisterCallback(DeletedMessageCallbackTag,
-		deletedMessageCallbackHandler(channelCbs.MessageDeleted))
+		deletedMessageCallbackHandler(channelCbs.EventUpdate))
 
 	// Register handler to manage messages for the MutedUserCallback
 	wm.RegisterCallback(MutedUserCallbackTag,
-		mutedUserCallbackHandler(channelCbs.UserMuted))
+		mutedUserCallbackHandler(channelCbs.EventUpdate))
 
 	// Store the database name
 	err = storage.StoreIndexedDb(databaseName)
@@ -139,47 +131,25 @@ type MessageReceivedCallbackMessage struct {
 
 // messageReceivedCallbackHandler returns a handler to manage messages for the
 // MessageReceivedCallback.
-func messageReceivedCallbackHandler(cb MessageReceivedCallback) func(data []byte) {
+func messageReceivedCallbackHandler(cb eventUpdateCallback) func(data []byte) {
 	return func(data []byte) {
-		var msg MessageReceivedCallbackMessage
-		err := json.Unmarshal(data, &msg)
-		if err != nil {
-			jww.ERROR.Printf(
-				"Failed to JSON unmarshal %T from worker: %+v", msg, err)
-			return
-		}
-
-		cb(msg.UUID, msg.ChannelID, msg.Update)
+		cb(bindings.MessageReceived, data)
 	}
 }
 
 // deletedMessageCallbackHandler returns a handler to manage messages for the
 // DeletedMessageCallback.
-func deletedMessageCallbackHandler(cb DeletedMessageCallback) func(data []byte) {
+func deletedMessageCallbackHandler(cb eventUpdateCallback) func(data []byte) {
 	return func(data []byte) {
-		messageID, err := message.UnmarshalID(data)
-		if err != nil {
-			jww.ERROR.Printf(
-				"Failed to JSON unmarshal message ID from worker: %+v", err)
-		}
-
-		cb(messageID.Bytes())
+		cb(bindings.MessageDeleted, data)
 	}
 }
 
 // mutedUserCallbackHandler returns a handler to manage messages for the
 // MutedUserCallback.
-func mutedUserCallbackHandler(cb MutedUserCallback) func(data []byte) {
+func mutedUserCallbackHandler(cb eventUpdateCallback) func(data []byte) {
 	return func(data []byte) {
-		var msg MuteUserMessage
-		err := json.Unmarshal(data, &msg)
-		if err != nil {
-			jww.ERROR.Printf(
-				"Failed to JSON unmarshal %T from worker: %+v", msg, err)
-			return
-		}
-
-		cb(msg.ChannelID, msg.PubKey, msg.Unmute)
+		cb(bindings.UserMuted, data)
 	}
 }
 
diff --git a/wasm/channels.go b/wasm/channels.go
index e7f3449f712908d26e6e49aaa6f650118f91593c..6795bd0e2f1d6376368d13206109bba6cad20960 100644
--- a/wasm/channels.go
+++ b/wasm/channels.go
@@ -2342,53 +2342,18 @@ func (c *ChannelDbCipher) UnmarshalJSON(_ js.Value, args []js.Value) any {
 // channelUI callbacks implementation struct.
 func newChannelUI(cbImpl js.Value) *channelUI {
 	return &channelUI{
-		notificationUpdate: utils.WrapCB(cbImpl, "NotificationUpdate"),
-		messageReceived:    utils.WrapCB(cbImpl, "MessageReceived"),
-		userMuted:          utils.WrapCB(cbImpl, "UserMuted"),
-		messageDeleted:     utils.WrapCB(cbImpl, "MessageDeleted"),
-		nicknameUpdate:     utils.WrapCB(cbImpl, "NicknameUpdate"),
+		eventUpdate: utils.WrapCB(cbImpl, "eventUpdate"),
 	}
 }
 
 // eventModel wraps Javascript callbacks to adhere to the
 // [bindings.ChannelUICallbacks] interface.
 type channelUI struct {
-	notificationUpdate func(args ...any) js.Value
-	messageReceived    func(args ...any) js.Value
-	userMuted          func(args ...any) js.Value
-	messageDeleted     func(args ...any) js.Value
-	nicknameUpdate     func(args ...any) js.Value
+	eventUpdate func(args ...any) js.Value
 }
 
-// NotificationUpdate implements
-// [bindings.ChannelUICallbacks.NotificationUpdate].
-func (c *channelUI) NotificationUpdate(notificationFilterListJSON,
-	changedNotificationStatesJSON, deletedNotificationStatesJSON []byte,
-	maxState int) {
-	c.notificationUpdate(notificationFilterListJSON,
-		changedNotificationStatesJSON,
-		deletedNotificationStatesJSON,
-		maxState)
-}
-
-// MessageReceived implements [bindings.ChannelUICallbacks.MessageReceived].
-func (c *channelUI) MessageReceived(uuid int64, channelID []byte, update bool) {
-	c.messageReceived(uuid, utils.CopyBytesToJS(channelID), update)
-}
-
-// UserMuted implements [bindings.ChannelUICallbacks.UserMuted].
-func (c *channelUI) UserMuted(channelID []byte, pubKey []byte, unmute bool) {
-	c.userMuted(utils.CopyBytesToJS(channelID), utils.CopyBytesToJS(pubKey),
-		unmute)
-}
-
-// MessageDeleted implements [bindings.ChannelUICallbacks.MessageDeleted].
-func (c *channelUI) MessageDeleted(messageId []byte) {
-	c.messageDeleted(utils.CopyBytesToJS(messageId))
-}
-
-// NicknameUpdate implements [bindings.ChannelUICallbacks.NicknameUpdate]
-func (c *channelUI) NicknameUpdate(channelIdBytes []byte, nickname string,
-	exists bool) {
-	c.nicknameUpdate(utils.CopyBytesToJS(channelIdBytes), nickname, exists)
+// EventUpdate implements
+// [bindings.ChannelUICallbacks.EventUpdate].
+func (c *channelUI) EventUpdate(eventType int64, dataJson []byte) {
+	c.eventUpdate(eventType, utils.CopyBytesToJS(dataJson))
 }