diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 9d646b507e9277f2c70db50363efbc0e62cc326d..5d70c54fd6b22846c042f640fda72cf7de67d6e3 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,5 +1,10 @@
 image: docker-registry.xx.network/elixxir/sysadmin/backend-ci:go1.17-wasm
 
+stages:
+  - wasm-test
+  - go-test
+  - build
+
 build:
   stage: build
   script:
@@ -10,13 +15,14 @@ build:
     paths:
       - release/
 
-#native-test:
-#    stage: test
-#    script:
-#        - go test ./...
-
 wasm-test:
-  stage: test
+  stage: wasm-test
   script:
     - export PATH=/root/go/bin:$PATH
-    - GOOS=js GOARCH=wasm go test ./...
+    - GOOS=js GOARCH=wasm go test ./... -v
+
+go-test:
+  stage: go-test
+  script:
+    - go mod vendor -v
+    - go test ./... -v
diff --git a/Makefile b/Makefile
index 14bf12e4f1a3fb11b40e949c3c5f6fcb79df1332..b6cb6de00d6a5dd5890e1aa1f61901fbe5146a5c 100644
--- a/Makefile
+++ b/Makefile
@@ -22,8 +22,19 @@ update_master:
 	GOFLAGS="" go get gitlab.com/xx_network/primitives@master
 
 binary:
-	GOOS=js GOARCH=wasm go build -ldflags '-w -s' -o xxdk.wasm main.go
+	GOOS=js GOARCH=wasm go build -ldflags '-w -s' -trimpath -o xxdk.wasm main.go
+
+wasm_tests:
+	cp utils/utils_js.s utils/utils_js.s.bak
+	> utils/utils_js.s
+	-GOOS=js GOARCH=wasm go test ./... -v
+	mv utils/utils_js.s.bak utils/utils_js.s
+
+go_tests:
+	go test ./... -v
 
 master: update_master clean build
 
 release: update_release clean build
+
+tests: wasm_tests go_tests
diff --git a/go.mod b/go.mod
index 6d626319be95ef71c0c32757bc519567bb165a24..dc9b76a86a1bde4fe4a5bed06051e52dbe6c138d 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 v1.5.1-0.20220920003304-3bce7b64b826
+	gitlab.com/elixxir/client v1.5.1-0.20220920174009-2a53a7ef68b8
 	gitlab.com/elixxir/crypto v0.0.7-0.20220920002307-5541473e9aa7
 	gitlab.com/xx_network/primitives v0.0.4-0.20220809193445-9fc0a5209548
 )
diff --git a/go.sum b/go.sum
index 7b0564e96c11e68cd7d1b827f33c8fd3db088a64..b3cee78f5efb4f5c0770b1a9edea8e2dfa104a55 100644
--- a/go.sum
+++ b/go.sum
@@ -628,26 +628,19 @@ 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-20211222005329-7d931ceead6f h1:yXGvNBqzZwAhDYlSnxPRbgor6JWoOt1Z7s3z1O9JR40=
 gitlab.com/elixxir/bloomfilter v0.0.0-20211222005329-7d931ceead6f/go.mod h1:H6jztdm0k+wEV2QGK/KYA+MY9nj9Zzatux/qIvDDv3k=
-gitlab.com/elixxir/client v1.5.1-0.20220919211114-4fe61cbe3400 h1:wTpH4idYq9Xe/xYRJ+e5fRjSyj3PnpdfHH+LAfQ9K50=
-gitlab.com/elixxir/client v1.5.1-0.20220919211114-4fe61cbe3400/go.mod h1:x6QH8UsPUXpKB/B7byWwsCTBCjx+qiiE7hMvA3rK6v8=
-gitlab.com/elixxir/client v1.5.1-0.20220919221644-fed0850ccff6 h1:tVdxY5BMZ9mvIzP0ddJyoYwqKu1YIYQvCiPpKhJ9yFk=
-gitlab.com/elixxir/client v1.5.1-0.20220919221644-fed0850ccff6/go.mod h1:TrCtCQ7FAijaNfo6In2s2HDqbNJivxQV3m36ZGyNXFk=
-gitlab.com/elixxir/client v1.5.1-0.20220919223314-930e66a05c1a h1:Q8F0uZwni37B0jWbfoTBpRNsvw2yyx5dOZa6O+CGyH8=
-gitlab.com/elixxir/client v1.5.1-0.20220919223314-930e66a05c1a/go.mod h1:TrCtCQ7FAijaNfo6In2s2HDqbNJivxQV3m36ZGyNXFk=
-gitlab.com/elixxir/client v1.5.1-0.20220919230833-8d25dfcd399e h1:tVDQE+Utif6bzBhiXZuc5Je+4rPgm2WiO9uVBuJsrSk=
-gitlab.com/elixxir/client v1.5.1-0.20220919230833-8d25dfcd399e/go.mod h1:TrCtCQ7FAijaNfo6In2s2HDqbNJivxQV3m36ZGyNXFk=
-gitlab.com/elixxir/client v1.5.1-0.20220920003304-3bce7b64b826 h1:QaxYWQlCvX9KTJ5MDiNbImE7F01vitU2C2F7ITqE1ws=
-gitlab.com/elixxir/client v1.5.1-0.20220920003304-3bce7b64b826/go.mod h1:pX1uLFS8v6pNVzJEcfbMUrYPTWLPl8p71ghqW2Xm0Ns=
+gitlab.com/elixxir/client v1.5.1-0.20220920165356-70c6a360f4a4 h1:TScsikTuMTpfssqpJOG7G88icjNQVzZtTP/eJMo+WJo=
+gitlab.com/elixxir/client v1.5.1-0.20220920165356-70c6a360f4a4/go.mod h1:pX1uLFS8v6pNVzJEcfbMUrYPTWLPl8p71ghqW2Xm0Ns=
+gitlab.com/elixxir/client v1.5.1-0.20220920174009-2a53a7ef68b8 h1:4g5E4wglxzMjm1vEAtxHlpyaU2XrFV1vClIjdhdm2vo=
+gitlab.com/elixxir/client v1.5.1-0.20220920174009-2a53a7ef68b8/go.mod h1:pX1uLFS8v6pNVzJEcfbMUrYPTWLPl8p71ghqW2Xm0Ns=
+gitlab.com/elixxir/client v1.5.1-0.20220920174748-d717a6622f0e h1:AJfdLR218PR2dfgStDjlKX/F/q19Xh9uHe/g4ZbHLt0=
+gitlab.com/elixxir/client v1.5.1-0.20220920174748-d717a6622f0e/go.mod h1:pX1uLFS8v6pNVzJEcfbMUrYPTWLPl8p71ghqW2Xm0Ns=
+gitlab.com/elixxir/client v1.5.1-0.20220920180021-72075c042387 h1:nBpcixXVZhwAnbjA0DTuSaidPNFXtUM70FgusV8AwCU=
+gitlab.com/elixxir/client v1.5.1-0.20220920180021-72075c042387/go.mod h1:pX1uLFS8v6pNVzJEcfbMUrYPTWLPl8p71ghqW2Xm0Ns=
 gitlab.com/elixxir/comms v0.0.4-0.20220913220502-eed192f654bd h1:2nHE7EoptSTBFjCxMeAveKT6urbguCwgg8Jx7XYEVe4=
 gitlab.com/elixxir/comms v0.0.4-0.20220913220502-eed192f654bd/go.mod h1:AO6XkMhaHJW8eXlgL5m3UUcJqsSP8F5Wm1GX+wyq/rw=
 gitlab.com/elixxir/crypto v0.0.0-20200804182833-984246dea2c4/go.mod h1:ucm9SFKJo+K0N2GwRRpaNr+tKXMIOVWzmyUD0SbOu2c=
 gitlab.com/elixxir/crypto v0.0.3/go.mod h1:ZNgBOblhYToR4m8tj4cMvJ9UsJAUKq+p0gCp07WQmhA=
 gitlab.com/elixxir/crypto v0.0.7-0.20220913220142-ab0771bad0af/go.mod h1:QF8SzsrYh9Elip9EUYUDAhPjqO9DGrrrQxYHvn+VXok=
-gitlab.com/elixxir/crypto v0.0.7-0.20220919174648-8d1b7f5cacc4/go.mod h1:QF8SzsrYh9Elip9EUYUDAhPjqO9DGrrrQxYHvn+VXok=
-gitlab.com/elixxir/crypto v0.0.7-0.20220919183519-5bbca98a2c00 h1:BZ2v6dfdYOUQHbssWJyHv+jNZheORvz4O1nPT8Y2S94=
-gitlab.com/elixxir/crypto v0.0.7-0.20220919183519-5bbca98a2c00/go.mod h1:QF8SzsrYh9Elip9EUYUDAhPjqO9DGrrrQxYHvn+VXok=
-gitlab.com/elixxir/crypto v0.0.7-0.20220919221444-cb6c054c9fcd h1:uWcp0aokdBnaZhNhlbXiDYusecIP5AaFbJfBtuzEg5A=
-gitlab.com/elixxir/crypto v0.0.7-0.20220919221444-cb6c054c9fcd/go.mod h1:QF8SzsrYh9Elip9EUYUDAhPjqO9DGrrrQxYHvn+VXok=
 gitlab.com/elixxir/crypto v0.0.7-0.20220920002307-5541473e9aa7 h1:9IsBtL8zcUG86XcfNUVIKcnlL5tyKlyQt1cJ5nogr1U=
 gitlab.com/elixxir/crypto v0.0.7-0.20220920002307-5541473e9aa7/go.mod h1:QF8SzsrYh9Elip9EUYUDAhPjqO9DGrrrQxYHvn+VXok=
 gitlab.com/elixxir/ekv v0.2.1 h1:dtwbt6KmAXG2Tik5d60iDz2fLhoFBgWwST03p7T+9Is=
diff --git a/indexedDb/implementation.go b/indexedDb/implementation.go
index 6e6cc9158423b876f61bc8550688252d93c5b5f5..f8159c5156bd3796cdbe742d1e34e9bd8a8dd458 100644
--- a/indexedDb/implementation.go
+++ b/indexedDb/implementation.go
@@ -6,7 +6,6 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 //go:build js && wasm
-// +build js,wasm
 
 package indexedDb
 
diff --git a/indexedDb/implementation_test.go b/indexedDb/implementation_test.go
index 3f008359d7ff0eac2f134d8f718e0dd75f57f6cb..a4d5d0bd72b7cdb441dfbad87cfdf7d95ce4215d 100644
--- a/indexedDb/implementation_test.go
+++ b/indexedDb/implementation_test.go
@@ -5,6 +5,8 @@
 // LICENSE file.                                                              //
 ////////////////////////////////////////////////////////////////////////////////
 
+//go:build js && wasm
+
 package indexedDb
 
 import (
diff --git a/indexedDb/init.go b/indexedDb/init.go
index fa82a6e29e76db0310e7db6b69049aca14e5d272..515505c7bad04b0f81fbe2e621f66b4801280014 100644
--- a/indexedDb/init.go
+++ b/indexedDb/init.go
@@ -6,7 +6,6 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 //go:build js && wasm
-// +build js,wasm
 
 package indexedDb
 
diff --git a/indexedDb/model.go b/indexedDb/model.go
index e8050d52fed2d4e4ab3762e812dd2b0375839cc6..c46bad409ca43a8fb8276c249c3dcb3876dd1457 100644
--- a/indexedDb/model.go
+++ b/indexedDb/model.go
@@ -6,7 +6,6 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 //go:build js && wasm
-// +build js,wasm
 
 package indexedDb
 
diff --git a/utils/array.go b/utils/array.go
index 9a1266960e689210f5a32de95800aa9f85e070fd..3b7032377f252bc75d9da16fe8ce5b942b1615f3 100644
--- a/utils/array.go
+++ b/utils/array.go
@@ -5,6 +5,8 @@
 // LICENSE file.                                                              //
 ////////////////////////////////////////////////////////////////////////////////
 
+//go:build js && wasm
+
 package utils
 
 import (
diff --git a/utils/array_test.go b/utils/array_test.go
index a420dc844bd3acb13031ecfd6cb0da29814dafa2..fa52ee9e3fc256450d8805bd77be8818c315fbea 100644
--- a/utils/array_test.go
+++ b/utils/array_test.go
@@ -5,6 +5,8 @@
 // LICENSE file.                                                              //
 ////////////////////////////////////////////////////////////////////////////////
 
+//go:build js && wasm
+
 package utils
 
 import (
@@ -28,6 +30,7 @@ var testBytes = [][]byte{
 // Tests that a series of Uint8Array Javascript objects are correctly converted
 // to base 64 strings with Uint8ArrayToBase64.
 func TestUint8ArrayToBase64(t *testing.T) {
+	t.Errorf("ERROR")
 	for i, val := range testBytes {
 		// Create Uint8Array and set each element individually
 		jsBytes := Uint8Array.New(len(val))
diff --git a/utils/convert.go b/utils/convert.go
index 589979abb11553523cbde7df89b0d9691f03721c..6f4be8fd876b64da85895064a95eb4ae69d991d5 100644
--- a/utils/convert.go
+++ b/utils/convert.go
@@ -5,6 +5,8 @@
 // LICENSE file.                                                              //
 ////////////////////////////////////////////////////////////////////////////////
 
+//go:build js && wasm
+
 package utils
 
 import (
diff --git a/utils/convert_test.go b/utils/convert_test.go
index 7a9e1fb6e3ab2f3b8dec72ce4b6e964d936a03a0..9193aa93f91a2a8871de431c4ed2a760eb86531d 100644
--- a/utils/convert_test.go
+++ b/utils/convert_test.go
@@ -5,6 +5,8 @@
 // LICENSE file.                                                              //
 ////////////////////////////////////////////////////////////////////////////////
 
+//go:build js && wasm
+
 package utils
 
 import (
diff --git a/utils/errors.go b/utils/errors.go
index 2b3f15723462b21c3f7bccf549960f71f0d0046e..d8de2b0a1fd8c7c67def0ce17773c4e4ba11cca1 100644
--- a/utils/errors.go
+++ b/utils/errors.go
@@ -5,6 +5,8 @@
 // LICENSE file.                                                              //
 ////////////////////////////////////////////////////////////////////////////////
 
+//go:build js && wasm
+
 package utils
 
 import (
diff --git a/utils/errors_test.go b/utils/errors_test.go
index 94b507d7c90d8a3d3a45465cec0437a1b3011c3e..f9965e34878f0cd507e2839482e1f38201a99055 100644
--- a/utils/errors_test.go
+++ b/utils/errors_test.go
@@ -5,6 +5,8 @@
 // LICENSE file.                                                              //
 ////////////////////////////////////////////////////////////////////////////////
 
+//go:build js && wasm
+
 package utils
 
 import (
diff --git a/wasm/backup_test.go b/wasm/backup_test.go
index 8946fc6aefaf2fe15a7fc452e1559194ee41502c..8ac779ae36922566705a53374a0a213f2af03f62 100644
--- a/wasm/backup_test.go
+++ b/wasm/backup_test.go
@@ -5,6 +5,8 @@
 // LICENSE file.                                                              //
 ////////////////////////////////////////////////////////////////////////////////
 
+//go:build js && wasm
+
 package wasm
 
 import (
diff --git a/wasm/channels.go b/wasm/channels.go
index d3c497d32007023d2384a85999b387e88b8db6d3..4706c03893438e9d58ee59e5275b4ab190641f27 100644
--- a/wasm/channels.go
+++ b/wasm/channels.go
@@ -5,6 +5,8 @@
 // LICENSE file.                                                              //
 ////////////////////////////////////////////////////////////////////////////////
 
+//go:build js && wasm
+
 package wasm
 
 import (
@@ -116,8 +118,8 @@ func NewChannelsManagerWithIndexedDb(_ js.Value, args []js.Value) interface{} {
 // using an indexedDb backend and a dummy name server instead of UD.
 //
 // Parameters:
-//  - args[0] - ID of E2e object in tracker (int). This can be retrieved using
-//    [E2e.GetID].
+//  - args[0] - ID of Cmix object in tracker (int). This can be retrieved using
+//    [Cmix.GetID].
 //  - args[1] - username (string).
 //
 // Returns:
@@ -145,8 +147,8 @@ func NewChannelsManagerWithIndexedDbDummyNameService(_ js.Value, args []js.Value
 // using a Javascript event model backend and a dummy name server instead of UD.
 //
 // Parameters:
-//  - args[0] - ID of E2e object in tracker (int). This can be retrieved using
-//    [E2e.GetID].
+//  - args[0] -  ID of Cmix object in tracker (int). This can be retrieved using
+//    [Cmix.GetID].
 //  - args[1] - Username (string).
 //  - args[2] - Javascript object that matches the [bindings.EventModel]
 //    interface.
@@ -592,6 +594,8 @@ func (ch *ChannelsManager) RegisterReceiveHandler(_ js.Value, args []js.Value) i
 // Event Model Logic                                                          //
 ////////////////////////////////////////////////////////////////////////////////
 
+// TODO: add comments
+
 type eventModel struct {
 	joinChannel      func(args ...interface{}) js.Value
 	leaveChannel     func(args ...interface{}) js.Value
diff --git a/wasm/channels_test.go b/wasm/channels_test.go
index 7f952295a8a911a4cbc5fc0f7c94255f8f1d5c22..c9ec47fb0e6dd6f5a38f7f7b9d3e84002c5d2fdf 100644
--- a/wasm/channels_test.go
+++ b/wasm/channels_test.go
@@ -5,6 +5,8 @@
 // LICENSE file.                                                              //
 ////////////////////////////////////////////////////////////////////////////////
 
+//go:build js && wasm
+
 package wasm
 
 import (
diff --git a/wasm/cmix_test.go b/wasm/cmix_test.go
index 703440b4bfa2a0183583407c9fa052a6d47bc09c..2455ff06ec50be4808563a494268fcc7ffaba188 100644
--- a/wasm/cmix_test.go
+++ b/wasm/cmix_test.go
@@ -6,7 +6,6 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 //go:build js && wasm
-// +build js,wasm
 
 package wasm
 
diff --git a/wasm/connect_test.go b/wasm/connect_test.go
index c2acb98aa8b4c11ee216759ff2227a6b79db5816..5c9739914c91d25331052f7e0ffc49f432b101bc 100644
--- a/wasm/connect_test.go
+++ b/wasm/connect_test.go
@@ -5,6 +5,8 @@
 // LICENSE file.                                                              //
 ////////////////////////////////////////////////////////////////////////////////
 
+//go:build js && wasm
+
 package wasm
 
 import (
diff --git a/wasm/fileTransfer_test.go b/wasm/fileTransfer_test.go
index b339903f19465f9bc8a5f27f68d589884bb3f812..ead8b566ff405c4b86ac9cc731b05f6d305aeaf2 100644
--- a/wasm/fileTransfer_test.go
+++ b/wasm/fileTransfer_test.go
@@ -5,6 +5,8 @@
 // LICENSE file.                                                              //
 ////////////////////////////////////////////////////////////////////////////////
 
+//go:build js && wasm
+
 package wasm
 
 import (
diff --git a/wasm_test.go b/wasm_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..f8a02021bad6200b2ee839b34bc87adeebb8c348
--- /dev/null
+++ b/wasm_test.go
@@ -0,0 +1,83 @@
+////////////////////////////////////////////////////////////////////////////////
+// Copyright © 2022 xx foundation                                             //
+//                                                                            //
+// Use of this source code is governed by a license that can be found in the  //
+// LICENSE file.                                                              //
+////////////////////////////////////////////////////////////////////////////////
+
+// This file is compiled for all architectures except WebAssembly.
+//go:build !js || !wasm
+
+package xxdk_wasm
+
+import (
+	"go/ast"
+	"go/parser"
+	"go/token"
+	"testing"
+	"unicode"
+)
+
+// Tests that all public functions in client/bindings are implemented here in
+// the WASM bindings.
+func TestPublicFunctions(t *testing.T) {
+	// Exclude these functions from the check. These functions are intentionally
+	// not implemented.
+	excludeList := map[string]struct{}{
+		// Notifications are not available in the browser
+		"GetNotificationsReport":     {},
+		"RegisterForNotifications":   {},
+		"UnregisterForNotifications": {},
+
+		// UD not available in the browser
+		"IsRegisteredWithUD":     {},
+		"NewOrLoadUd":            {},
+		"NewUdManagerFromBackup": {},
+		"LookupUD":               {},
+		"MultiLookupUD":          {},
+		"SearchUD":               {},
+
+		// These functions are used internally by the WASM bindings but are not
+		// exposed
+		"NewEventModel":                                  {},
+		"NewChannelsManagerGoEventModel":                 {},
+		"NewChannelsManagerGoEventModelDummyNameService": {},
+	}
+	wasmFuncs := getPublicFunctions("wasm", t)
+	bindingsFuncs := getPublicFunctions(
+		"vendor/gitlab.com/elixxir/client/bindings", t)
+
+	for fnName := range bindingsFuncs {
+		if _, exists := wasmFuncs[fnName]; !exists {
+			if _, exists = excludeList[fnName]; !exists {
+				t.Errorf("Function %q does not exist in WASM bindings.", fnName)
+			} else {
+				delete(wasmFuncs, fnName)
+			}
+		}
+	}
+}
+
+func getPublicFunctions(pkg string, t testing.TB) map[string]*ast.FuncDecl {
+	set := token.NewFileSet()
+	packs, err := parser.ParseDir(set, pkg, nil, 0)
+	if err != nil {
+		t.Fatalf("Failed to parse package: %+v", err)
+	}
+
+	funcs := make(map[string]*ast.FuncDecl)
+	for _, pack := range packs {
+		for _, f := range pack.Files {
+			for _, d := range f.Decls {
+				if fn, isFn := d.(*ast.FuncDecl); isFn {
+					// Exclude type methods and private functions
+					if fn.Recv == nil && unicode.IsUpper(rune(fn.Name.Name[0])) {
+						funcs[fn.Name.Name] = fn
+					}
+				}
+			}
+		}
+	}
+
+	return funcs
+}