diff --git a/go.mod b/go.mod
index 5a684bfb4d9065c4bcf16941ad4993b61e923a73..3993a0c9fc6b19a1981472da804fc4cbf3afb831 100644
--- a/go.mod
+++ b/go.mod
@@ -11,7 +11,7 @@ require (
 	github.com/spf13/cobra v1.7.0
 	github.com/spf13/jwalterweatherman v1.1.0
 	github.com/stretchr/testify v1.8.2
-	gitlab.com/elixxir/client/v4 v4.6.4-0.20230626174341-9991c0c1c379
+	gitlab.com/elixxir/client/v4 v4.6.4-0.20230626212848-efac286b8673
 	gitlab.com/elixxir/crypto v0.0.7-0.20230614183801-387e0cb8e76f
 	gitlab.com/elixxir/primitives v0.0.3-0.20230613193928-8cf8bdd777ef
 	gitlab.com/elixxir/wasm-utils v0.0.0-20230615222914-185dd3a6fa08
diff --git a/go.sum b/go.sum
index b8f06d0dc8550462ff046a59f09aa7d2378ba5c8..1e3a483678b61da846a185a3c1ee92b26bccf0d2 100644
--- a/go.sum
+++ b/go.sum
@@ -411,8 +411,8 @@ 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.20230626174341-9991c0c1c379 h1:dv3/sCyBv439ulpN394pgN8AYNb67nvC6aP90dGOqm8=
-gitlab.com/elixxir/client/v4 v4.6.4-0.20230626174341-9991c0c1c379/go.mod h1:wSeJ9pk+qqUrKHwhd4qZW1CnNlakK75n+1fOjJ7k1Ns=
+gitlab.com/elixxir/client/v4 v4.6.4-0.20230626212848-efac286b8673 h1:HhhpEy2WJkoVqT3gmblN/V9/rnnKpuJ4Al4XNxwQrT4=
+gitlab.com/elixxir/client/v4 v4.6.4-0.20230626212848-efac286b8673/go.mod h1:wSeJ9pk+qqUrKHwhd4qZW1CnNlakK75n+1fOjJ7k1Ns=
 gitlab.com/elixxir/comms v0.0.4-0.20230613220741-7de1d2ca4a1c h1:0TpLn4AdarrqCwUMvnz4Md+9gLyk9wrQ73J3W9U5zJo=
 gitlab.com/elixxir/comms v0.0.4-0.20230613220741-7de1d2ca4a1c/go.mod h1:z+qW0D9VpY5QKTd7wRlb5SK4kBNqLYsa4DXBcUXue9Q=
 gitlab.com/elixxir/crypto v0.0.7-0.20230614183801-387e0cb8e76f h1:T0Jvhq5nCELiwkVr07Ti/Ew9ICdexviYeCkFV19kk9A=
diff --git a/storage/password.go b/storage/password.go
index bd7bbec521a32d375a7e08c57e8ca30dcedcaf28..ecacf52e5d3f77c1d1aa16847b2f778c5fd88d5e 100644
--- a/storage/password.go
+++ b/storage/password.go
@@ -97,8 +97,9 @@ const (
 //   - Internal password (Uint8Array).
 //   - Throws TypeError on failure.
 func GetOrInitPassword(_ js.Value, args []js.Value) any {
+	externalPassword := args[0].String()
 	promiseFn := func(resolve, reject func(args ...any) js.Value) {
-		internalPassword, err := getOrInit(args[0].String())
+		internalPassword, err := getOrInit(externalPassword)
 		if err != nil {
 			reject(exception.NewTrace(err))
 		} else {
diff --git a/wasm/dm.go b/wasm/dm.go
index 67d2b0a8a50e8c06115979bca0631ca972faf0eb..de38d638bea976823234b94eeec85e9b5d459697 100644
--- a/wasm/dm.go
+++ b/wasm/dm.go
@@ -76,65 +76,20 @@ func newDMClientJS(api *bindings.DMClient) map[string]any {
 	return dmClientMap
 }
 
-// newDmNotificationUpdate adds the callbacks from the Javascript object.
-func newDmNotificationUpdate(value js.Value) *dmNotificationUpdate {
-	return &dmNotificationUpdate{callback: utils.WrapCB(value, "Callback")}
+// dmCallbacks wraps Javascript callbacks to adhere to the
+// [bindings.DmCallbacks] interface.
+type dmCallbacks struct {
+	eventUpdate func(args ...any) js.Value
 }
 
-// dmNotificationUpdate wraps Javascript callbacks to adhere to the
-// [bindings.DmNotificationUpdate] interface.
-type dmNotificationUpdate struct {
-	callback func(args ...any) js.Value
+// newDmCallbacks adds the callbacks from the Javascript object.
+func newDmCallbacks(value js.Value) *dmCallbacks {
+	return &dmCallbacks{eventUpdate: utils.WrapCB(value, "EventUpdate")}
 }
 
-// Callback is called everytime there is an update to the notification filter
-// or notification status for DMs.
-//
-// Parameters:
-//   - nfJSON - JSON of [dm.NotificationFilter], which is passed into
-//     [GetDmNotificationReportsForMe] to filter DM notifications for the user.
-//   - changedStateListJSON - JSON of a slice of [dm.NotificationState]. It
-//     includes all added or changed notification states for DM conversations.
-//   - deletedListJSON - JSON of a slice of [ed25519.PublicKey]. It includes
-//     conversation that were deleted.
-//
-// Example nfJSON:
-//
-//	{
-//	  "identifier": "MWL6mvtZ9UUm7jP3ainyI4erbRl+wyVaO5MOWboP0rA=",
-//	  "myID": "AqDqg6Tcs359dBNRBCX7XHaotRDhz1ZRQNXIsGaubvID",
-//	  "tags": [
-//	    "61334HtH85DPIifvrM+JzRmLqfV5R4AMEmcPelTmFX0=",
-//	    "zc/EPwtx5OKTVdwLcI15bghjJ7suNhu59PcarXE+m9o=",
-//	    "FvArzVJ/082UEpMDCWJsopCLeLnxJV6NXINNkJTk3k8="
-//	  ],
-//	  "PublicKeys": {
-//	    "61334HtH85DPIifvrM+JzRmLqfV5R4AMEmcPelTmFX0=": "b3HygDv8gjteune9wgBm3YtVuAo2foOusRmj0m5nl6E=",
-//	    "FvArzVJ/082UEpMDCWJsopCLeLnxJV6NXINNkJTk3k8=": "uOLitBZcCh2TEW406jXHJ+Rsi6LybsH8R1u4Mxv/7hA=",
-//	    "zc/EPwtx5OKTVdwLcI15bghjJ7suNhu59PcarXE+m9o=": "lqLD1EzZBxB8PbILUJIfFq4JI0RKThpUQuNlTNgZAWk="
-//	  },
-//	  "allowedTypes": {"1": {}, "2": {}}
-//	}
-//
-// Example changedStateListJSON:
-//
-//	[
-//	  {"pubKey": "lqLD1EzZBxB8PbILUJIfFq4JI0RKThpUQuNlTNgZAWk=", "level": 40},
-//	  {"pubKey": "uOLitBZcCh2TEW406jXHJ+Rsi6LybsH8R1u4Mxv/7hA=", "level": 10},
-//	  {"pubKey": "b3HygDv8gjteune9wgBm3YtVuAo2foOusRmj0m5nl6E=", "level": 10}
-//	]
-//
-// Example deletedListJSON:
-//
-//	[
-//	  "lqLD1EzZBxB8PbILUJIfFq4JI0RKThpUQuNlTNgZAWk=",
-//	  "lqLD1EzZBxB8PbILUJIfFq4JI0RKThpUQuNlTNgZAWk="
-//	]
-func (dmNU *dmNotificationUpdate) Callback(
-	nfJSON, changedStateListJSON, deletedListJSON []byte) {
-	dmNU.callback(utils.CopyBytesToJS(nfJSON),
-		utils.CopyBytesToJS(changedStateListJSON),
-		utils.CopyBytesToJS(deletedListJSON))
+// EventUpdate implements [bindings.DmCallbacks.EventUpdate].
+func (dmCBS *dmCallbacks) EventUpdate(eventType int64, jsonData []byte) {
+	dmCBS.eventUpdate(eventType, utils.CopyBytesToJS(jsonData))
 }
 
 // NewDMClient creates a new [DMClient] from a private identity
@@ -155,9 +110,10 @@ func (dmNU *dmNotificationUpdate) Callback(
 //   - args[3] - 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 that is triggered everytime there is a change to the
-//     notification status of a DM conversation It must be a Javascript object
-//     that implements the callback in [bindings.DmNotificationUpdate].
+//   - args[4] - A Javascript object that implements the function on
+//     [bindings.DmCallbacks]. It is a callback that informs the UI about
+//     updates relating to DM conversations. The interface may be null, but if
+//     one is provided, each method must be implemented.
 //
 // Returns:
 //   - Javascript representation of the [DMClient] object.
@@ -167,10 +123,10 @@ func NewDMClient(_ js.Value, args []js.Value) any {
 	notificationsID := args[1].Int()
 	privateIdentity := utils.CopyBytesToGo(args[2])
 	em := newDMReceiverBuilder(args[3])
-	nu := newDmNotificationUpdate(args[4])
+	cbs := newDmCallbacks(args[4])
 
 	cm, err :=
-		bindings.NewDMClient(cmixID, notificationsID, privateIdentity, em, nu)
+		bindings.NewDMClient(cmixID, notificationsID, privateIdentity, em, cbs)
 	if err != nil {
 		exception.ThrowTrace(err)
 		return nil
@@ -206,9 +162,10 @@ func NewDMClient(_ js.Value, args []js.Value) any {
 //     The row in the database that was updated can be found using the UUID.
 //     messageUpdate is true if the message already exists and was edited.
 //     conversationUpdate is true if the Conversation was created or modified.
-//   - args[6] - A callback that is triggered everytime there is a change to the
-//     notification status of a DM conversation It must be a Javascript object
-//     that implements the callback in [bindings.DmNotificationUpdate].
+//   - args[6] - A Javascript object that implements the function on
+//     [bindings.DmCallbacks]. It is a callback that informs the UI about
+//     updates relating to DM conversations. The interface may be null, but if
+//     one is provided, each method must be implemented.
 //
 // Returns:
 //   - Resolves to a Javascript representation of the [DMClient] object.
@@ -221,7 +178,7 @@ func NewDMClientWithIndexedDb(_ js.Value, args []js.Value) any {
 	wasmJsPath := args[3].String()
 	privateIdentity := utils.CopyBytesToGo(args[4])
 	messageReceivedCB := args[5]
-	nu := newDmNotificationUpdate(args[6])
+	cbs := newDmCallbacks(args[6])
 
 	cipher, err := dbCipherTrackerSingleton.get(cipherID)
 	if err != nil {
@@ -229,7 +186,7 @@ func NewDMClientWithIndexedDb(_ js.Value, args []js.Value) any {
 	}
 
 	return newDMClientWithIndexedDb(cmixID, notificationsID, wasmJsPath,
-		privateIdentity, messageReceivedCB, cipher, nu)
+		privateIdentity, messageReceivedCB, cipher, cbs)
 }
 
 // NewDMClientWithIndexedDbUnsafe creates a new [DMClient] from a private
@@ -258,9 +215,10 @@ func NewDMClientWithIndexedDb(_ js.Value, args []js.Value) any {
 //     The row in the database that was updated can be found using the UUID.
 //     messageUpdate is true if the message already exists and was edited.
 //     conversationUpdate is true if the Conversation was created or modified.
-//   - args[5] - A callback that is triggered everytime there is a change to the
-//     notification status of a DM conversation It must be a Javascript object
-//     that implements the callback in [bindings.DmNotificationUpdate].
+//   - args[5] - A Javascript object that implements the function on
+//     [bindings.DmCallbacks]. It is a callback that informs the UI about
+//     updates relating to DM conversations. The interface may be null, but if
+//     one is provided, each method must be implemented.
 //
 // Returns a promise:
 //   - Resolves to a Javascript representation of the [DMClient] object.
@@ -271,14 +229,14 @@ func NewDMClientWithIndexedDbUnsafe(_ js.Value, args []js.Value) any {
 	wasmJsPath := args[2].String()
 	privateIdentity := utils.CopyBytesToGo(args[3])
 	messageReceivedCB := args[4]
-	nu := newDmNotificationUpdate(args[5])
+	cbs := newDmCallbacks(args[5])
 
 	return newDMClientWithIndexedDb(cmixID, notificationsID, wasmJsPath,
-		privateIdentity, messageReceivedCB, nil, nu)
+		privateIdentity, messageReceivedCB, nil, cbs)
 }
 
 func newDMClientWithIndexedDb(cmixID, notificationsID int, wasmJsPath string,
-	privateIdentity []byte, cb js.Value, cipher *DbCipher, nuCB bindings.DmNotificationUpdate) any {
+	privateIdentity []byte, cb js.Value, cipher *DbCipher, cbs *dmCallbacks) any {
 
 	messageReceivedCB := func(uuid uint64, pubKey ed25519.PublicKey,
 		messageUpdate, conversationUpdate bool) {
@@ -300,7 +258,7 @@ func newDMClientWithIndexedDb(cmixID, notificationsID int, wasmJsPath string,
 		}
 
 		cm, err := bindings.NewDMClientWithGoEventModel(
-			cmixID, notificationsID, privateIdentity, model, nuCB)
+			cmixID, notificationsID, privateIdentity, model, cbs)
 		if err != nil {
 			reject(exception.NewTrace(err))
 		} else {