diff --git a/app/src/main/java/com/futo/circles/feature/validate_email/ValidateEmailFragment.kt b/app/src/main/java/com/futo/circles/feature/validate_email/ValidateEmailFragment.kt
index 1fafd6d3e42a1f563bb64d9e1493b8b03f5cabc4..0fc91ea0b13db975171de8180405de3f6a942780 100644
--- a/app/src/main/java/com/futo/circles/feature/validate_email/ValidateEmailFragment.kt
+++ b/app/src/main/java/com/futo/circles/feature/validate_email/ValidateEmailFragment.kt
@@ -8,7 +8,10 @@ import by.kirich1409.viewbindingdelegate.viewBinding
 import com.futo.circles.R
 import com.futo.circles.core.HasLoadingState
 import com.futo.circles.databinding.ValidateEmailFragmentBinding
+import com.futo.circles.extensions.observeResponse
 import com.futo.circles.extensions.showDialog
+import com.futo.circles.extensions.showSuccess
+import com.futo.circles.extensions.visible
 import org.koin.androidx.viewmodel.ext.android.viewModel
 
 class ValidateEmailFragment : Fragment(R.layout.validate_email_fragment), HasLoadingState {
@@ -26,7 +29,10 @@ class ValidateEmailFragment : Fragment(R.layout.validate_email_fragment), HasLoa
     private fun setupViews() {
         with(binding) {
             tilEmail.editText?.doAfterTextChanged {
-                it?.let { btnSendCode.setButtonEnabled(it.isNotEmpty()) }
+                it?.let { btnSendCode.isEnabled = it.isNotEmpty() }
+            }
+            tilValidationCode.editText?.doAfterTextChanged {
+                it?.let { btnValidate.isEnabled = it.isNotEmpty() }
             }
             tilEmail.setEndIconOnClickListener {
                 showDialog(
@@ -42,7 +48,7 @@ class ValidateEmailFragment : Fragment(R.layout.validate_email_fragment), HasLoa
             }
             btnSendCode.setOnClickListener {
                 startLoading(btnSendCode)
-                viewModel.sendCode(tilEmail.editText?.text?.toString()?.trim() ?: "")
+                viewModel.sendCode(getEmailInput())
             }
             btnValidate.setOnClickListener {
                 startLoading(btnValidate)
@@ -52,6 +58,15 @@ class ValidateEmailFragment : Fragment(R.layout.validate_email_fragment), HasLoa
     }
 
     private fun setupObservers() {
+        viewModel.sendCodeLiveData.observeResponse(this,
+            success = {
+                showSuccess(getString(R.string.validation_code_sent_to_format, getEmailInput()))
+                binding.tilValidationCode.visible()
+            }
+        )
+        viewModel.validateEmailLiveData.observeResponse(this)
     }
 
+    private fun getEmailInput(): String = binding.tilEmail.editText?.text?.toString()?.trim() ?: ""
+
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/futo/circles/feature/validate_email/ValidateEmailViewModel.kt b/app/src/main/java/com/futo/circles/feature/validate_email/ValidateEmailViewModel.kt
index e0f61b8e3221128fc4ebc04de8226046d4b66742..a8875c9ba5e7c4ed6f01394ff05eca867da1004e 100644
--- a/app/src/main/java/com/futo/circles/feature/validate_email/ValidateEmailViewModel.kt
+++ b/app/src/main/java/com/futo/circles/feature/validate_email/ValidateEmailViewModel.kt
@@ -1,18 +1,31 @@
 package com.futo.circles.feature.validate_email
 
+import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.ViewModel
+import com.futo.circles.core.SingleEventLiveData
+import com.futo.circles.extensions.Response
+import com.futo.circles.extensions.launchBg
 import com.futo.circles.feature.validate_email.data_source.ValidateEmailDataSource
+import org.matrix.android.sdk.api.auth.registration.RegistrationResult
 
 class ValidateEmailViewModel(
     private val dataSource: ValidateEmailDataSource
 ) : ViewModel() {
 
-    fun sendCode(email: String) {
+    val sendCodeLiveData = MutableLiveData<Response<RegistrationResult>>()
+    val validateEmailLiveData = SingleEventLiveData<Response<RegistrationResult>>()
+
 
+    fun sendCode(email: String) {
+        launchBg {
+            sendCodeLiveData.postValue(dataSource.sendValidationCode(email))
+        }
     }
 
     fun validateEmail(code: String) {
-
+        launchBg {
+            validateEmailLiveData.postValue(dataSource.validateEmail(code))
+        }
     }
 
 
diff --git a/app/src/main/java/com/futo/circles/feature/validate_email/data_source/ValidateEmailDataSource.kt b/app/src/main/java/com/futo/circles/feature/validate_email/data_source/ValidateEmailDataSource.kt
index d7dd035547e98ff5033e17dac6625bc6b85f4b2a..8df473074e61207bb8e6a2e869bf90604d9385de 100644
--- a/app/src/main/java/com/futo/circles/feature/validate_email/data_source/ValidateEmailDataSource.kt
+++ b/app/src/main/java/com/futo/circles/feature/validate_email/data_source/ValidateEmailDataSource.kt
@@ -1,7 +1,11 @@
 package com.futo.circles.feature.validate_email.data_source
 
+import com.futo.circles.extensions.Response
+import com.futo.circles.extensions.createResult
 import com.futo.circles.feature.sign_up.data_source.SignUpDataSource
 import com.futo.circles.provider.MatrixInstanceProvider
+import org.matrix.android.sdk.api.auth.registration.RegisterThreePid
+import org.matrix.android.sdk.api.auth.registration.RegistrationResult
 
 class ValidateEmailDataSource(
     private val signUpDataSource: SignUpDataSource
@@ -11,8 +15,13 @@ class ValidateEmailDataSource(
         MatrixInstanceProvider.matrix.authenticationService().getRegistrationWizard()
     }
 
-    suspend fun sendValidationCode(email: String) {}
+    suspend fun sendValidationCode(email: String): Response<RegistrationResult> =
+        createResult { wizard.addThreePid(RegisterThreePid.Email(email)) }
 
-    suspend fun validateEmail(code:String){}
 
+    suspend fun validateEmail(code: String): Response<RegistrationResult> {
+        val result = createResult { wizard.handleValidateThreePid(code) }
+        (result as? Response.Success)?.let { signUpDataSource.stageCompleted(result.data) }
+        return result
+    }
 }
\ No newline at end of file