diff --git a/indexedDb/implementation.go b/indexedDb/implementation.go
index 410358d773fb486d31896dfe18fda0f8a29600b1..d9d2f7026d246f95a5e45def3863083805ae9434 100644
--- a/indexedDb/implementation.go
+++ b/indexedDb/implementation.go
@@ -39,6 +39,7 @@ const dbTimeout = time.Second
 // channel.
 type wasmModel struct {
 	db                *idb.Database
+	cipher            cryptoChannel.Cipher
 	receivedMessageCB MessageReceivedCallback
 	updateMux         sync.Mutex
 }
@@ -206,6 +207,16 @@ func (w *wasmModel) ReceiveMessage(channelID *id.ID,
 	timestamp time.Time, lease time.Duration, round rounds.Round,
 	mType channels.MessageType, status channels.SentStatus) uint64 {
 
+	// Handle encryption, if it is present
+	if w.cipher != nil {
+		cipherText, err := w.cipher.Encrypt([]byte(text))
+		if err != nil {
+			jww.ERROR.Printf("Failed to encrypt Message: %+v", err)
+			return 0
+		}
+		text = string(cipherText)
+	}
+
 	msgToInsert := buildMessage(
 		channelID.Marshal(), messageID.Bytes(), nil, nickname, text, pubKey,
 		codeset, timestamp, lease, round.ID, mType, status)
diff --git a/indexedDb/implementation_test.go b/indexedDb/implementation_test.go
index 68a8dfeb6f04a8a1e1f9c141d9e07fa14f45019f..34a1d4fc5754f106fff55ca755637850c171a6f3 100644
--- a/indexedDb/implementation_test.go
+++ b/indexedDb/implementation_test.go
@@ -12,6 +12,7 @@ package indexedDb
 import (
 	"encoding/json"
 	"fmt"
+	"gitlab.com/elixxir/xxdk-wasm/storage"
 	"gitlab.com/xx_network/primitives/netTime"
 	"os"
 	"strconv"
@@ -37,7 +38,7 @@ func dummyCallback(uint64, *id.ID, bool) {}
 func Test_wasmModel_UpdateSentStatus(t *testing.T) {
 	testString := "test"
 	testMsgId := channel.MakeMessageID([]byte(testString), &id.ID{1})
-	eventModel, err := newWASMModel(testString, dummyCallback)
+	eventModel, err := newWASMModel(testString, nil, dummyCallback)
 	if err != nil {
 		t.Fatalf("%+v", err)
 	}
@@ -90,7 +91,8 @@ func Test_wasmModel_UpdateSentStatus(t *testing.T) {
 
 // Smoke test wasmModel.JoinChannel/wasmModel.LeaveChannel happy paths.
 func Test_wasmModel_JoinChannel_LeaveChannel(t *testing.T) {
-	eventModel, err := newWASMModel("test", dummyCallback)
+	storage.GetLocalStorage().Clear()
+	eventModel, err := newWASMModel("test", nil, dummyCallback)
 	if err != nil {
 		t.Fatalf("%+v", err)
 	}
@@ -129,7 +131,7 @@ func Test_wasmModel_JoinChannel_LeaveChannel(t *testing.T) {
 // Test UUID gets returned when different messages are added.
 func Test_wasmModel_UUIDTest(t *testing.T) {
 	testString := "testHello"
-	eventModel, err := newWASMModel(testString, dummyCallback)
+	eventModel, err := newWASMModel(testString, nil, dummyCallback)
 	if err != nil {
 		t.Fatalf("%+v", err)
 	}
@@ -162,8 +164,9 @@ func Test_wasmModel_UUIDTest(t *testing.T) {
 
 // Tests if the same message ID being sent always returns the same UUID.
 func Test_wasmModel_DuplicateReceives(t *testing.T) {
+	storage.GetLocalStorage().Clear()
 	testString := "testHello"
-	eventModel, err := newWASMModel(testString, dummyCallback)
+	eventModel, err := newWASMModel(testString, nil, dummyCallback)
 	if err != nil {
 		t.Fatalf("%+v", err)
 	}
@@ -200,7 +203,7 @@ func Test_wasmModel_deleteMsgByChannel(t *testing.T) {
 	testString := "test_deleteMsgByChannel"
 	totalMessages := 10
 	expectedMessages := 5
-	eventModel, err := newWASMModel(testString, dummyCallback)
+	eventModel, err := newWASMModel(testString, nil, dummyCallback)
 	if err != nil {
 		t.Fatalf("%+v", err)
 	}
diff --git a/indexedDb/init.go b/indexedDb/init.go
index 632ad0ee736ceb95327212f8af199a5df37c112d..95ae98a0ae3ce85da85e559dd59a4a8775f1d284 100644
--- a/indexedDb/init.go
+++ b/indexedDb/init.go
@@ -10,6 +10,9 @@
 package indexedDb
 
 import (
+	"github.com/pkg/errors"
+	cryptoChannel "gitlab.com/elixxir/crypto/channel"
+	"gitlab.com/elixxir/xxdk-wasm/storage"
 	"syscall/js"
 
 	"github.com/hack-pad/go-indexeddb/idb"
@@ -37,25 +40,25 @@ type MessageReceivedCallback func(uuid uint64, channelID *id.ID, update bool)
 // NewWASMEventModelBuilder returns an EventModelBuilder which allows
 // the channel manager to define the path but the callback is the same
 // across the board.
-func NewWASMEventModelBuilder(
+func NewWASMEventModelBuilder(encryption cryptoChannel.Cipher,
 	cb MessageReceivedCallback) channels.EventModelBuilder {
 	fn := func(path string) (channels.EventModel, error) {
-		return NewWASMEventModel(path, cb)
+		return NewWASMEventModel(path, encryption, cb)
 	}
 	return fn
 }
 
 // NewWASMEventModel returns a [channels.EventModel] backed by a wasmModel.
 // The name should be a base64 encoding of the users public key.
-func NewWASMEventModel(path string, cb MessageReceivedCallback) (
-	channels.EventModel, error) {
+func NewWASMEventModel(path string, encryption cryptoChannel.Cipher,
+	cb MessageReceivedCallback) (channels.EventModel, error) {
 	databaseName := path + databaseSuffix
-	return newWASMModel(databaseName, cb)
+	return newWASMModel(databaseName, encryption, cb)
 }
 
 // newWASMModel creates the given [idb.Database] and returns a wasmModel.
-func newWASMModel(databaseName string, cb MessageReceivedCallback) (
-	*wasmModel, error) {
+func newWASMModel(databaseName string, encryption cryptoChannel.Cipher,
+	cb MessageReceivedCallback) (*wasmModel, error) {
 	// Attempt to open database object
 	ctx, cancel := newContext()
 	defer cancel()
@@ -112,7 +115,20 @@ func newWASMModel(databaseName string, cb MessageReceivedCallback) (
 		return nil, err
 	}
 
-	return &wasmModel{db: db, receivedMessageCB: cb}, err
+	encryptionStatus := encryption != nil
+	loadedEncryptionStatus, err := storage.StoreIndexedDbEncryptionStatus(
+		databaseName, encryptionStatus)
+	if err != nil {
+		return nil, err
+	}
+
+	if encryptionStatus != loadedEncryptionStatus {
+		return nil, errors.New(
+			"Cannot load database with different encryption status.")
+	} else if !encryptionStatus {
+		jww.WARN.Printf("IndexedDb encryption disabled!")
+	}
+	return &wasmModel{db: db, receivedMessageCB: cb, cipher: encryption}, err
 }
 
 // v1Upgrade performs the v0 -> v1 database upgrade.
diff --git a/main.go b/main.go
index 1214a9e82d1791ed11efabc5daf11829cf3f528f..fbec3d118fd1cff67c6a825f16c39e1f1636645b 100644
--- a/main.go
+++ b/main.go
@@ -70,6 +70,10 @@ func main() {
 		js.FuncOf(wasm.NewChannelsManagerWithIndexedDb))
 	js.Global().Set("LoadChannelsManagerWithIndexedDb",
 		js.FuncOf(wasm.LoadChannelsManagerWithIndexedDb))
+	js.Global().Set("LoadChannelsManagerWithIndexedDbUnsafe",
+		js.FuncOf(wasm.LoadChannelsManagerWithIndexedDbUnsafe))
+	js.Global().Set("NewChannelsManagerWithIndexedDbUnsafe",
+		js.FuncOf(wasm.NewChannelsManagerWithIndexedDbUnsafe))
 	js.Global().Set("GenerateChannel", js.FuncOf(wasm.GenerateChannel))
 	js.Global().Set("DecodePublicURL", js.FuncOf(wasm.DecodePublicURL))
 	js.Global().Set("DecodePrivateURL", js.FuncOf(wasm.DecodePrivateURL))
@@ -77,6 +81,8 @@ func main() {
 	js.Global().Set("GetChannelInfo", js.FuncOf(wasm.GetChannelInfo))
 	js.Global().Set("GetShareUrlType", js.FuncOf(wasm.GetShareUrlType))
 	js.Global().Set("IsNicknameValid", js.FuncOf(wasm.IsNicknameValid))
+	js.Global().Set("NewChannelsDatabaseCipher",
+		js.FuncOf(wasm.NewChannelsDatabaseCipher))
 
 	// wasm/cmix.go
 	js.Global().Set("NewCmix", js.FuncOf(wasm.NewCmix))
diff --git a/storage/indexedDbEncryptionTrack.go b/storage/indexedDbEncryptionTrack.go
new file mode 100644
index 0000000000000000000000000000000000000000..6e52a2648d3ea076578e9697fa3e9b591edf043f
--- /dev/null
+++ b/storage/indexedDbEncryptionTrack.go
@@ -0,0 +1,37 @@
+////////////////////////////////////////////////////////////////////////////////
+// Copyright © 2022 xx foundation                                             //
+//                                                                            //
+// Use of this source code is governed by a license that can be found in the  //
+// LICENSE file.                                                              //
+////////////////////////////////////////////////////////////////////////////////
+
+//go:build js && wasm
+
+package storage
+
+import (
+	"github.com/pkg/errors"
+	"os"
+)
+
+// Key to store if the database is encrypted or not
+const databaseEncryptionToggleKey = "xxdkWasmDatabaseEncryptionToggle/"
+
+// StoreIndexedDbEncryptionStatus stores the encryption status if it has not
+// been previously saved. If it has, it returns its value.
+func StoreIndexedDbEncryptionStatus(
+	databaseName string, encryption bool) (bool, error) {
+	data, err := GetLocalStorage().GetItem(
+		databaseEncryptionToggleKey + databaseName)
+	if err != nil {
+		if errors.Is(err, os.ErrNotExist) {
+			GetLocalStorage().SetItem(
+				databaseEncryptionToggleKey+databaseName, []byte{1})
+			return encryption, nil
+		} else {
+			return false, err
+		}
+	}
+
+	return data[0] == 1, nil
+}
diff --git a/storage/version.go b/storage/version.go
index 263ad6a9c4c17762d84b6229f50b5c371fea2e65..e667145c9260470e6d367ddb75f952f17b714363 100644
--- a/storage/version.go
+++ b/storage/version.go
@@ -17,7 +17,7 @@ import (
 )
 
 // SEMVER is the current semantic version of xxDK WASM.
-const SEMVER = "0.0.0"
+const SEMVER = "0.1.0"
 
 // Storage keys.
 const (
diff --git a/wasm/channels.go b/wasm/channels.go
index e84ac943a47eb8697aeaa10ea3905699fe65179e..e884ed233c4e282e23c678d1c4cc5653605d6aea 100644
--- a/wasm/channels.go
+++ b/wasm/channels.go
@@ -325,21 +325,72 @@ func LoadChannelsManager(_ js.Value, args []js.Value) interface{} {
 //    returned as an int and the channelID as a Uint8Array. The row in the
 //    database that was updated can be found using the UUID. The channel ID is
 //    provided so that the recipient can filter if they want to the processes
+//    the update now or not. An "update" bool is present which tells you if the
+//    row is new or if it is an edited old row.
+//  - args[3] - ID of [ChannelDbCipher] object in tracker (int). Create this
+//    object with [NewChannelsDatabaseCipher] and get its id with
+//    [ChannelDbCipher.GetID].
+//
+// Returns a promise:
+//  - Resolves to a Javascript representation of the [ChannelsManager] object.
+//  - Rejected with an error if loading indexedDb or the manager fails.
+//  - Throws a TypeError if the cipher ID does not correspond to a cipher.
+func NewChannelsManagerWithIndexedDb(_ js.Value, args []js.Value) interface{} {
+	cmixID := args[0].Int()
+	privateIdentity := utils.CopyBytesToGo(args[1])
+	cipherID := args[3].Int()
+
+	cipher, err := bindings.GetChannelDbCipherTrackerFromID(cipherID)
+	if err != nil {
+		utils.Throw(utils.TypeError, err)
+	}
+
+	return newChannelsManagerWithIndexedDb(cmixID, privateIdentity, args[2], cipher)
+}
+
+// NewChannelsManagerWithIndexedDbUnsafe creates a new [ChannelsManager] from a
+// new private identity ([channel.PrivateIdentity]) and using indexedDb as a
+// backend to manage the event model. However, the data is written in plain text
+// and not encrypted. It is recommended that you do not use this in production.
+//
+// This is for creating a manager for an identity for the first time. For
+// generating a new one channel identity, use [GenerateChannelIdentity]. To
+// reload this channel manager, use [LoadChannelsManagerWithIndexedDbUnsafe],
+// passing in the storage tag retrieved by [ChannelsManager.GetStorageTag].
+//
+// This function initialises an indexedDb database.
+//
+// Parameters:
+//  - args[0] - ID of [Cmix] object in tracker (int). This can be retrieved
+//    using [Cmix.GetID].
+//  - args[1] - Bytes of a private identity ([channel.PrivateIdentity]) that is
+//    generated by [GenerateChannelIdentity] (Uint8Array).
+//  - args[2] - Function that takes in the same parameters as
+//    [indexedDb.MessageReceivedCallback]. On the Javascript side, the UUID is
+//    returned as an int and the channelID as a Uint8Array. The row in the
+//    database that was updated can be found using the UUID. The channel ID is
+//    provided so that the recipient can filter if they want to the processes
 //    the update now or not. An "update" bool is present which tells you if
 //	  the row is new or if it is an edited old row
 //
 // Returns a promise:
 //  - 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{} {
+func NewChannelsManagerWithIndexedDbUnsafe(_ js.Value, args []js.Value) interface{} {
 	cmixID := args[0].Int()
 	privateIdentity := utils.CopyBytesToGo(args[1])
 
+	return newChannelsManagerWithIndexedDb(cmixID, privateIdentity, args[2], nil)
+}
+
+func newChannelsManagerWithIndexedDb(cmixID int, privateIdentity []byte,
+	cb js.Value, cipher *bindings.ChannelDbCipher) interface{} {
+
 	fn := func(uuid uint64, channelID *id.ID, update bool) {
-		args[2].Invoke(uuid, utils.CopyBytesToJS(channelID.Marshal()), update)
+		cb.Invoke(uuid, utils.CopyBytesToJS(channelID.Marshal()), update)
 	}
 
-	model := indexedDb.NewWASMEventModelBuilder(fn)
+	model := indexedDb.NewWASMEventModelBuilder(cipher, fn)
 
 	promiseFn := func(resolve, reject func(args ...interface{}) js.Value) {
 		cm, err := bindings.NewChannelsManagerGoEventModel(
@@ -372,21 +423,69 @@ func NewChannelsManagerWithIndexedDb(_ js.Value, args []js.Value) interface{} {
 //    returned as an int and the channelID as a Uint8Array. The row in the
 //    database that was updated can be found using the UUID. The channel ID is
 //    provided so that the recipient can filter if they want to the processes
+//    the update now or not. An "update" bool is present which tells you if the
+//    row is new or if it is an edited old row.
+//  - args[3] - ID of [ChannelDbCipher] object in tracker (int). Create this
+//    object with [NewChannelsDatabaseCipher] and get its id with
+//    [ChannelDbCipher.GetID].
+//
+// Returns a promise:
+//  - Resolves to a Javascript representation of the [ChannelsManager] object.
+//  - Rejected with an error if loading indexedDb or the manager fails.
+//  - Throws a TypeError if the cipher ID does not correspond to a cipher.
+func LoadChannelsManagerWithIndexedDb(_ js.Value, args []js.Value) interface{} {
+	cmixID := args[0].Int()
+	storageTag := args[1].String()
+	cipherID := args[3].Int()
+
+	cipher, err := bindings.GetChannelDbCipherTrackerFromID(cipherID)
+	if err != nil {
+		utils.Throw(utils.TypeError, err)
+	}
+
+	return loadChannelsManagerWithIndexedDb(cmixID, storageTag, args[2], cipher)
+}
+
+// LoadChannelsManagerWithIndexedDbUnsafe loads an existing [ChannelsManager]
+// using an existing indexedDb database as a backend to manage the event model.
+// This should only be used to load unsafe channel managers created by
+// [NewChannelsManagerWithIndexedDbUnsafe].
+//
+// This is for loading a manager for an identity that has already been created.
+// The channel manager should have previously been created with
+// [NewChannelsManagerWithIndexedDb] and the storage is retrievable with
+// [ChannelsManager.GetStorageTag].
+//
+// Parameters:
+//  - args[0] - ID of [Cmix] object in tracker (int). This can be retrieved
+//    using [Cmix.GetID].
+//  - args[1] - The storage tag associated with the previously created channel
+//    manager and retrieved with [ChannelsManager.GetStorageTag] (string).
+//  - args[2] - Function that takes in the same parameters as
+//    [indexedDb.MessageReceivedCallback]. On the Javascript side, the UUID is
+//    returned as an int and the channelID as a Uint8Array. The row in the
+//    database that was updated can be found using the UUID. The channel ID is
+//    provided so that the recipient can filter if they want to the processes
 //    the update now or not. An "update" bool is present which tells you if
 //	  the row is new or if it is an edited old row
 //
 // Returns a promise:
 //  - 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{} {
+func LoadChannelsManagerWithIndexedDbUnsafe(_ js.Value, args []js.Value) interface{} {
 	cmixID := args[0].Int()
 	storageTag := args[1].String()
 
+	return loadChannelsManagerWithIndexedDb(cmixID, storageTag, args[2], nil)
+}
+
+func loadChannelsManagerWithIndexedDb(cmixID int, storageTag string,
+	cb js.Value, cipher *bindings.ChannelDbCipher) interface{} {
 	fn := func(uuid uint64, channelID *id.ID, updated bool) {
-		args[2].Invoke(uuid, utils.CopyBytesToJS(channelID.Marshal()), updated)
+		cb.Invoke(uuid, utils.CopyBytesToJS(channelID.Marshal()), updated)
 	}
 
-	model := indexedDb.NewWASMEventModelBuilder(fn)
+	model := indexedDb.NewWASMEventModelBuilder(cipher, fn)
 
 	promiseFn := func(resolve, reject func(args ...interface{}) js.Value) {
 		cm, err := bindings.LoadChannelsManagerGoEventModel(
@@ -1274,3 +1373,108 @@ func (em *eventModel) UpdateSentStatus(
 	em.updateSentStatus(
 		uuid, utils.CopyBytesToJS(messageID), timestamp, roundID, status)
 }
+
+////////////////////////////////////////////////////////////////////////////////
+// Channel Cipher                                                             //
+////////////////////////////////////////////////////////////////////////////////
+
+// ChannelDbCipher wraps the [bindings.ChannelDbCipher] object so its methods
+// can be wrapped to be Javascript compatible.
+type ChannelDbCipher struct {
+	api *bindings.ChannelDbCipher
+}
+
+// newChannelDbCipherJS creates a new Javascript compatible object
+// (map[string]interface{}) that matches the [ChannelDbCipher] structure.
+func newChannelDbCipherJS(api *bindings.ChannelDbCipher) map[string]interface{} {
+	c := ChannelDbCipher{api}
+	channelDbCipherMap := map[string]interface{}{
+		"GetID":   js.FuncOf(c.GetID),
+		"Encrypt": js.FuncOf(c.Encrypt),
+		"Decrypt": js.FuncOf(c.Decrypt),
+	}
+
+	return channelDbCipherMap
+}
+
+// NewChannelsDatabaseCipher constructs a [ChannelDbCipher] object.
+//
+// Parameters:
+//  - args[0] - The tracked [Cmix] object ID (int).
+//  - args[1] - The password for storage. This should be the same password
+//    passed into [NewCmix] (Uint8Array).
+//  - args[2] - The maximum size of a payload to be encrypted. A payload passed
+//    into [ChannelDbCipher.Encrypt] that is larger than this value will result
+//    in an error (int).
+//
+// Returns:
+//   - JavaScript representation of the [ChannelDbCipher] object.
+//   - Throws a TypeError if creating the cipher fails.
+func NewChannelsDatabaseCipher(_ js.Value, args []js.Value) interface{} {
+	cmixId := args[0].Int()
+	password := utils.CopyBytesToGo(args[1])
+	plaintTextBlockSize := args[2].Int()
+
+	cipher, err := bindings.NewChannelsDatabaseCipher(
+		cmixId, password, plaintTextBlockSize)
+	if err != nil {
+		utils.Throw(utils.TypeError, err)
+		return nil
+	}
+
+	return newChannelDbCipherJS(cipher)
+}
+
+// GetID returns the ID for this [bindings.ChannelDbCipher] in the
+// channelDbCipherTracker.
+//
+// Returns:
+//  - Tracker ID (int).
+func (c *ChannelDbCipher) GetID(js.Value, []js.Value) interface{} {
+	return c.api.GetID()
+}
+
+// Encrypt will encrypt the raw data. It will return a ciphertext. Padding is
+// done on the plaintext so all encrypted data looks uniform at rest.
+//
+// Parameters:
+//  - args[0] - The data to be encrypted (Uint8Array). This must be smaller than
+//    the block size passed into [NewChannelsDatabaseCipher]. If it is larger,
+//    this will return an error.
+//
+// Returns:
+//   - The ciphertext of the plaintext passed in (Uint8Array).
+//   - Throws a TypeError if it fails to encrypt the plaintext.
+func (c *ChannelDbCipher) Encrypt(_ js.Value, args []js.Value) interface{} {
+
+	ciphertext, err := c.api.Encrypt(utils.CopyBytesToGo(args[0]))
+	if err != nil {
+		utils.Throw(utils.TypeError, err)
+		return nil
+	}
+
+	return utils.CopyBytesToJS(ciphertext)
+
+}
+
+// Decrypt will decrypt the passed in encrypted value. The plaintext will be
+// returned by this function. Any padding will be discarded within this
+// function.
+//
+// Parameters:
+//  - args[0] - the encrypted data returned by [ChannelDbCipher.Encrypt]
+//    (Uint8Array).
+//
+// Returns:
+//   - The plaintext of the ciphertext passed in (Uint8Array).
+//   - Throws a TypeError if it fails to encrypt the plaintext.
+func (c *ChannelDbCipher) Decrypt(_ js.Value, args []js.Value) interface{} {
+	plaintext, err := c.api.Decrypt(utils.CopyBytesToGo(args[0]))
+	if err != nil {
+		utils.Throw(utils.TypeError, err)
+		return nil
+	}
+
+	return utils.CopyBytesToJS(plaintext)
+
+}
diff --git a/wasm/channels_test.go b/wasm/channels_test.go
index 2e19cffdb62ef95ca5c3d2b70d726d619ba66797..127657af1507d6389bdf94e7fb920f7e1dddb2de 100644
--- a/wasm/channels_test.go
+++ b/wasm/channels_test.go
@@ -60,6 +60,47 @@ func Test_ChannelsManagerMethods(t *testing.T) {
 	}
 }
 
+// Tests that the map representing ChannelDbCipher returned by
+// newChannelDbCipherJS contains all of the methods on ChannelDbCipher.
+func Test_newChannelDbCipherJS(t *testing.T) {
+	cipherType := reflect.TypeOf(&ChannelDbCipher{})
+
+	cipher := newChannelDbCipherJS(&bindings.ChannelDbCipher{})
+	if len(cipher) != cipherType.NumMethod() {
+		t.Errorf("ChannelDbCipher JS object does not have all methods."+
+			"\nexpected: %d\nreceived: %d", cipherType.NumMethod(), len(cipher))
+	}
+
+	for i := 0; i < cipherType.NumMethod(); i++ {
+		method := cipherType.Method(i)
+
+		if _, exists := cipher[method.Name]; !exists {
+			t.Errorf("Method %s does not exist.", method.Name)
+		}
+	}
+}
+
+// Tests that ChannelDbCipher has all the methods that
+// [bindings.ChannelDbCipher] has.
+func Test_ChannelDbCipherMethods(t *testing.T) {
+	cipherType := reflect.TypeOf(&ChannelDbCipher{})
+	binCipherType := reflect.TypeOf(&bindings.ChannelDbCipher{})
+
+	if binCipherType.NumMethod() != cipherType.NumMethod() {
+		t.Errorf("WASM ChannelDbCipher object does not have all methods from "+
+			"bindings.\nexpected: %d\nreceived: %d",
+			binCipherType.NumMethod(), cipherType.NumMethod())
+	}
+
+	for i := 0; i < binCipherType.NumMethod(); i++ {
+		method := binCipherType.Method(i)
+
+		if _, exists := cipherType.MethodByName(method.Name); !exists {
+			t.Errorf("Method %s does not exist.", method.Name)
+		}
+	}
+}
+
 type jsIdentity struct {
 	pubKey  js.Value
 	codeset js.Value
diff --git a/wasm_test.go b/wasm_test.go
index 1b25d22270e75984c19ee41beeaf0e9a455df33e..38d1bdd30e9cd3efe0569afe50903b94948761af 100644
--- a/wasm_test.go
+++ b/wasm_test.go
@@ -42,6 +42,7 @@ func TestPublicFunctions(t *testing.T) {
 		"NewEventModel":                   {},
 		"NewChannelsManagerGoEventModel":  {},
 		"LoadChannelsManagerGoEventModel": {},
+		"GetChannelDbCipherTrackerFromID": {},
 
 		// Version functions were renamed to differentiate between WASM and
 		// client versions