diff --git a/CHANGES.md b/CHANGES.md
index 0c1d209f61..f43294ca9f 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -7,6 +7,7 @@ Features ✨:
  - Cross-Signing | Verify new session from existing session (#1134)
  - Cross-Signing | Bootstraping cross signing with 4S from mobile (#985)
  - Save media files to Gallery (#973)
+ - Account deactivation (with password only) (#35)
 
 Improvements 🙌:
  - Verification DM / Handle concurrent .start after .ready (#794)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/account/AccountService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/account/AccountService.kt
index 68643ff723..ddbaaea6ef 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/account/AccountService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/account/AccountService.kt
@@ -23,11 +23,28 @@ import im.vector.matrix.android.api.util.Cancelable
  * This interface defines methods to manage the account. It's implemented at the session level.
  */
 interface AccountService {
-
     /**
      * Ask the homeserver to change the password.
      * @param password Current password.
      * @param newPassword New password
      */
     fun changePassword(password: String, newPassword: String, callback: MatrixCallback<Unit>): Cancelable
+
+    /**
+     * Deactivate the account.
+     *
+     * This will make your account permanently unusable. You will not be able to log in, and no one will be able to re-register
+     * the same user ID. This will cause your account to leave all rooms it is participating in, and it will remove your account
+     * details from your identity server. <b>This action is irreversible</b>.\n\nDeactivating your account <b>does not by default
+     * cause us to forget messages you have sent</b>. If you would like us to forget your messages, please tick the box below.
+     *
+     * Message visibility in Matrix is similar to email. Our forgetting your messages means that messages you have sent will not
+     * be shared with any new or unregistered users, but registered users who already have access to these messages will still
+     * have access to their copy.
+     *
+     * @param password the account password
+     * @param eraseAllData set to true to forget all messages that have been sent. Warning: this will cause future users to see
+     * an incomplete view of conversations
+     */
+    fun deactivateAccount(password: String, eraseAllData: Boolean, callback: MatrixCallback<Unit>): Cancelable
 }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/AccountAPI.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/AccountAPI.kt
index 23d8210e89..e7fbd3748c 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/AccountAPI.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/AccountAPI.kt
@@ -30,4 +30,12 @@ internal interface AccountAPI {
      */
     @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "account/password")
     fun changePassword(@Body params: ChangePasswordParams): Call<Unit>
+
+    /**
+     * Deactivate the user account
+     *
+     * @param params the deactivate account params
+     */
+    @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "account/deactivate")
+    fun deactivate(@Body params: DeactivateAccountParams): Call<Unit>
 }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/AccountModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/AccountModule.kt
index 87e003b0d3..032139ce5d 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/AccountModule.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/AccountModule.kt
@@ -39,6 +39,9 @@ internal abstract class AccountModule {
     @Binds
     abstract fun bindChangePasswordTask(task: DefaultChangePasswordTask): ChangePasswordTask
 
+    @Binds
+    abstract fun bindDeactivateAccountTask(task: DefaultDeactivateAccountTask): DeactivateAccountTask
+
     @Binds
     abstract fun bindAccountService(service: DefaultAccountService): AccountService
 }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/DeactivateAccountParams.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/DeactivateAccountParams.kt
new file mode 100644
index 0000000000..7a099ca03d
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/DeactivateAccountParams.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.matrix.android.internal.session.account;
+
+import com.squareup.moshi.Json;
+import com.squareup.moshi.JsonClass;
+import im.vector.matrix.android.internal.crypto.model.rest.UserPasswordAuth
+
+@JsonClass(generateAdapter = true)
+internal data class DeactivateAccountParams(
+        @Json(name = "auth")
+        val auth: UserPasswordAuth? = null,
+
+        // Set to true to erase all data of the account
+        @Json(name = "erase")
+        val erase: Boolean
+) {
+    companion object {
+        fun create(userId: String, password: String, erase: Boolean): DeactivateAccountParams {
+            return DeactivateAccountParams(
+                    auth = UserPasswordAuth(user = userId, password = password),
+                    erase = erase
+            )
+        }
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/DeactivateAccountTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/DeactivateAccountTask.kt
new file mode 100644
index 0000000000..b8b57a24a4
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/DeactivateAccountTask.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.matrix.android.internal.session.account
+
+import im.vector.matrix.android.api.failure.Failure
+import im.vector.matrix.android.internal.auth.registration.RegistrationFlowResponse
+import im.vector.matrix.android.internal.di.MoshiProvider
+import im.vector.matrix.android.internal.di.UserId
+import im.vector.matrix.android.internal.network.executeRequest
+import im.vector.matrix.android.internal.task.Task
+import org.greenrobot.eventbus.EventBus
+import javax.inject.Inject
+
+internal interface DeactivateAccountTask : Task<DeactivateAccountTask.Params, Unit> {
+    data class Params(
+            val password: String,
+            val eraseAllData: Boolean
+    )
+}
+
+internal class DefaultDeactivateAccountTask @Inject constructor(
+        private val accountAPI: AccountAPI,
+        private val eventBus: EventBus,
+        @UserId private val userId: String
+) : DeactivateAccountTask {
+
+    override suspend fun execute(params: DeactivateAccountTask.Params) {
+        val deactivateAccountParams = DeactivateAccountParams.create(userId, params.password, params.eraseAllData)
+        try {
+            executeRequest<Unit>(eventBus) {
+                apiCall = accountAPI.deactivate(deactivateAccountParams)
+            }
+        } catch (throwable: Throwable) {
+            if (throwable is Failure.OtherServerError
+                    && throwable.httpCode == 401
+                    /* Avoid infinite loop */
+                    && deactivateAccountParams.auth?.session == null) {
+                try {
+                    MoshiProvider.providesMoshi()
+                            .adapter(RegistrationFlowResponse::class.java)
+                            .fromJson(throwable.errorBody)
+                } catch (e: Exception) {
+                    null
+                }?.let {
+                    // Retry with authentication
+                    try {
+                        executeRequest<Unit>(eventBus) {
+                            apiCall = accountAPI.deactivate(
+                                    deactivateAccountParams.copy(auth = deactivateAccountParams.auth?.copy(session = it.session))
+                            )
+                        }
+                        return
+                    } catch (failure: Throwable) {
+                        throw failure
+                    }
+                }
+            }
+            throw throwable
+        }
+
+        // TODO This task should also do the cleanup
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/DefaultAccountService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/DefaultAccountService.kt
index fce01994d3..f6db1dd3db 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/DefaultAccountService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/account/DefaultAccountService.kt
@@ -24,6 +24,7 @@ import im.vector.matrix.android.internal.task.configureWith
 import javax.inject.Inject
 
 internal class DefaultAccountService @Inject constructor(private val changePasswordTask: ChangePasswordTask,
+                                                         private val deactivateAccountTask: DeactivateAccountTask,
                                                          private val taskExecutor: TaskExecutor) : AccountService {
 
     override fun changePassword(password: String, newPassword: String, callback: MatrixCallback<Unit>): Cancelable {
@@ -33,4 +34,12 @@ internal class DefaultAccountService @Inject constructor(private val changePassw
                 }
                 .executeBy(taskExecutor)
     }
+
+    override fun deactivateAccount(password: String, eraseAllData: Boolean, callback: MatrixCallback<Unit>): Cancelable {
+        return deactivateAccountTask
+                .configureWith(DeactivateAccountTask.Params(password, eraseAllData)) {
+                    this.callback = callback
+                }
+                .executeBy(taskExecutor)
+    }
 }
diff --git a/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt
index c2f2959bd7..d22d80c4b3 100644
--- a/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt
+++ b/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt
@@ -81,6 +81,7 @@ import im.vector.riotx.features.settings.VectorSettingsNotificationPreferenceFra
 import im.vector.riotx.features.settings.VectorSettingsNotificationsTroubleshootFragment
 import im.vector.riotx.features.settings.VectorSettingsPreferencesFragment
 import im.vector.riotx.features.settings.VectorSettingsSecurityPrivacyFragment
+import im.vector.riotx.features.settings.account.deactivation.DeactivateAccountFragment
 import im.vector.riotx.features.settings.crosssigning.CrossSigningSettingsFragment
 import im.vector.riotx.features.settings.devices.VectorSettingsDevicesFragment
 import im.vector.riotx.features.settings.devtools.AccountDataFragment
@@ -445,8 +446,14 @@ interface FragmentModule {
     @IntoMap
     @FragmentKey(BootstrapAccountPasswordFragment::class)
     fun bindBootstrapAccountPasswordFragment(fragment: BootstrapAccountPasswordFragment): Fragment
+
     @Binds
     @IntoMap
     @FragmentKey(BootstrapMigrateBackupFragment::class)
     fun bindBootstrapMigrateBackupFragment(fragment: BootstrapMigrateBackupFragment): Fragment
+
+    @Binds
+    @IntoMap
+    @FragmentKey(DeactivateAccountFragment::class)
+    fun bindDeactivateAccountFragment(fragment: DeactivateAccountFragment): Fragment
 }
diff --git a/vector/src/main/java/im/vector/riotx/features/MainActivity.kt b/vector/src/main/java/im/vector/riotx/features/MainActivity.kt
index bc5a1aff95..9c5569f66d 100644
--- a/vector/src/main/java/im/vector/riotx/features/MainActivity.kt
+++ b/vector/src/main/java/im/vector/riotx/features/MainActivity.kt
@@ -49,6 +49,7 @@ data class MainActivityArgs(
         val clearCache: Boolean = false,
         val clearCredentials: Boolean = false,
         val isUserLoggedOut: Boolean = false,
+        val isAccountDeactivated: Boolean = false,
         val isSoftLogout: Boolean = false
 ) : Parcelable
 
@@ -110,6 +111,7 @@ class MainActivity : VectorBaseActivity() {
                 clearCache = argsFromIntent?.clearCache ?: false,
                 clearCredentials = argsFromIntent?.clearCredentials ?: false,
                 isUserLoggedOut = argsFromIntent?.isUserLoggedOut ?: false,
+                isAccountDeactivated = argsFromIntent?.isAccountDeactivated ?: false,
                 isSoftLogout = argsFromIntent?.isSoftLogout ?: false
         )
     }
@@ -122,7 +124,7 @@ class MainActivity : VectorBaseActivity() {
         }
         when {
             args.clearCredentials -> session.signOut(
-                    !args.isUserLoggedOut,
+                    !args.isUserLoggedOut && !args.isAccountDeactivated,
                     object : MatrixCallback<Unit> {
                         override fun onSuccess(data: Unit) {
                             Timber.w("SIGN_OUT: success, start app")
@@ -182,16 +184,16 @@ class MainActivity : VectorBaseActivity() {
     private fun startNextActivityAndFinish() {
         val intent = when {
             args.clearCredentials
-                    && !args.isUserLoggedOut ->
-                // User has explicitly asked to log out
+                    && (!args.isUserLoggedOut || args.isAccountDeactivated) ->
+                // User has explicitly asked to log out or deactivated his account
                 LoginActivity.newIntent(this, null)
-            args.isSoftLogout                ->
+            args.isSoftLogout                                               ->
                 // The homeserver has invalidated the token, with a soft logout
                 SoftLogoutActivity.newIntent(this)
-            args.isUserLoggedOut             ->
+            args.isUserLoggedOut                                            ->
                 // the homeserver has invalidated the token (password changed, device deleted, other security reasons)
                 SignedOutActivity.newIntent(this)
-            sessionHolder.hasActiveSession() ->
+            sessionHolder.hasActiveSession()                                ->
                 // We have a session.
                 // Check it can be opened
                 if (sessionHolder.getActiveSession().isOpenable) {
@@ -200,7 +202,7 @@ class MainActivity : VectorBaseActivity() {
                     // The token is still invalid
                     SoftLogoutActivity.newIntent(this)
                 }
-            else                             ->
+            else                                                            ->
                 // First start, or no active session
                 LoginActivity.newIntent(this, null)
         }
diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt
index f0a5a8ace8..e765f961dd 100755
--- a/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt
+++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt
@@ -159,7 +159,6 @@ class VectorPreferences @Inject constructor(private val context: Context) {
         private const val DID_ASK_TO_IGNORE_BATTERY_OPTIMIZATIONS_KEY = "DID_ASK_TO_IGNORE_BATTERY_OPTIMIZATIONS_KEY"
         private const val DID_MIGRATE_TO_NOTIFICATION_REWORK = "DID_MIGRATE_TO_NOTIFICATION_REWORK"
         private const val DID_ASK_TO_USE_ANALYTICS_TRACKING_KEY = "DID_ASK_TO_USE_ANALYTICS_TRACKING_KEY"
-        const val SETTINGS_DEACTIVATE_ACCOUNT_KEY = "SETTINGS_DEACTIVATE_ACCOUNT_KEY"
         private const val SETTINGS_DISPLAY_ALL_EVENTS_KEY = "SETTINGS_DISPLAY_ALL_EVENTS_KEY"
 
         private const val MEDIA_SAVING_3_DAYS = 0
diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsActivity.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsActivity.kt
index 5db14fdbd2..6d00f02c97 100755
--- a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsActivity.kt
+++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsActivity.kt
@@ -20,6 +20,7 @@ import android.content.Intent
 import androidx.fragment.app.FragmentManager
 import androidx.preference.Preference
 import androidx.preference.PreferenceFragmentCompat
+import im.vector.matrix.android.api.failure.GlobalError
 import im.vector.matrix.android.api.session.Session
 import im.vector.riotx.R
 import im.vector.riotx.core.di.ScreenComponent
@@ -43,6 +44,8 @@ class VectorSettingsActivity : VectorBaseActivity(),
 
     private var keyToHighlight: String? = null
 
+    var ignoreInvalidTokenError = false
+
     @Inject lateinit var session: Session
 
     override fun injectWith(injector: ScreenComponent) {
@@ -57,7 +60,7 @@ class VectorSettingsActivity : VectorBaseActivity(),
             when (intent.getIntExtra(EXTRA_DIRECT_ACCESS, EXTRA_DIRECT_ACCESS_ROOT)) {
                 EXTRA_DIRECT_ACCESS_ADVANCED_SETTINGS ->
                     replaceFragment(R.id.vector_settings_page, VectorSettingsAdvancedSettingsFragment::class.java, null, FRAGMENT_TAG)
-                EXTRA_DIRECT_ACCESS_SECURITY_PRIVACY ->
+                EXTRA_DIRECT_ACCESS_SECURITY_PRIVACY  ->
                     replaceFragment(R.id.vector_settings_page, VectorSettingsSecurityPrivacyFragment::class.java, null, FRAGMENT_TAG)
                 else                                  ->
                     replaceFragment(R.id.vector_settings_page, VectorSettingsRootFragment::class.java, null, FRAGMENT_TAG)
@@ -110,6 +113,14 @@ class VectorSettingsActivity : VectorBaseActivity(),
         return keyToHighlight
     }
 
+    override fun handleInvalidToken(globalError: GlobalError.InvalidToken) {
+        if (ignoreInvalidTokenError) {
+            Timber.w("Ignoring invalid token global error")
+        } else {
+            super.handleInvalidToken(globalError)
+        }
+    }
+
     companion object {
         fun getIntent(context: Context, directAccess: Int) = Intent(context, VectorSettingsActivity::class.java)
                 .apply { putExtra(EXTRA_DIRECT_ACCESS, directAccess) }
diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsGeneralFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsGeneralFragment.kt
index f754064fbc..802cf7b33f 100644
--- a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsGeneralFragment.kt
+++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsGeneralFragment.kt
@@ -234,19 +234,6 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() {
 
             false
         }
-
-        // Deactivate account section
-
-        // deactivate account
-        findPreference<VectorPreference>(VectorPreferences.SETTINGS_DEACTIVATE_ACCOUNT_KEY)!!
-                .onPreferenceClickListener = Preference.OnPreferenceClickListener {
-            activity?.let {
-                notImplemented()
-                // TODO startActivity(DeactivateAccountActivity.getIntent(it))
-            }
-
-            false
-        }
     }
 
     override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
diff --git a/vector/src/main/java/im/vector/riotx/features/settings/account/deactivation/DeactivateAccountFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/account/deactivation/DeactivateAccountFragment.kt
new file mode 100644
index 0000000000..487d913b7e
--- /dev/null
+++ b/vector/src/main/java/im/vector/riotx/features/settings/account/deactivation/DeactivateAccountFragment.kt
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.riotx.features.settings.account.deactivation
+
+import android.content.Context
+import android.os.Bundle
+import android.view.View
+import com.airbnb.mvrx.fragmentViewModel
+import com.airbnb.mvrx.withState
+import com.jakewharton.rxbinding3.widget.textChanges
+import im.vector.riotx.R
+import im.vector.riotx.core.extensions.exhaustive
+import im.vector.riotx.core.extensions.showPassword
+import im.vector.riotx.core.platform.VectorBaseActivity
+import im.vector.riotx.core.platform.VectorBaseFragment
+import im.vector.riotx.features.MainActivity
+import im.vector.riotx.features.MainActivityArgs
+import im.vector.riotx.features.settings.VectorSettingsActivity
+import kotlinx.android.synthetic.main.fragment_deactivate_account.*
+import javax.inject.Inject
+
+class DeactivateAccountFragment @Inject constructor(
+        val viewModelFactory: DeactivateAccountViewModel.Factory
+) : VectorBaseFragment() {
+
+    private val viewModel: DeactivateAccountViewModel by fragmentViewModel()
+
+    override fun getLayoutResId() = R.layout.fragment_deactivate_account
+
+    override fun onResume() {
+        super.onResume()
+        (activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.deactivate_account_title)
+    }
+
+    private var settingsActivity: VectorSettingsActivity? = null
+
+    override fun onAttach(context: Context) {
+        super.onAttach(context)
+        settingsActivity = context as? VectorSettingsActivity
+    }
+
+    override fun onDetach() {
+        super.onDetach()
+        settingsActivity = null
+    }
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+
+        setupUi()
+        setupViewListeners()
+        observeViewEvents()
+    }
+
+    private fun setupUi() {
+        deactivateAccountPassword.textChanges()
+                .subscribe {
+                    deactivateAccountPasswordTil.error = null
+                    deactivateAccountSubmit.isEnabled = it.isNotBlank()
+                }
+                .disposeOnDestroyView()
+    }
+
+    private fun setupViewListeners() {
+        deactivateAccountPasswordReveal.setOnClickListener {
+            viewModel.handle(DeactivateAccountAction.TogglePassword)
+        }
+
+        deactivateAccountCancel.setOnClickListener {
+            (activity as? VectorBaseActivity)?.onBackPressed()
+        }
+
+        deactivateAccountSubmit.setOnClickListener {
+            viewModel.handle(DeactivateAccountAction.DeactivateAccount(
+                    deactivateAccountPassword.text.toString(),
+                    deactivateAccountEraseCheckbox.isChecked))
+        }
+    }
+
+    private fun observeViewEvents() {
+        viewModel.observeViewEvents {
+            when (it) {
+                is DeactivateAccountViewEvents.Loading      -> {
+                    settingsActivity?.ignoreInvalidTokenError = true
+                    showLoadingDialog(it.message)
+                }
+                DeactivateAccountViewEvents.EmptyPassword   -> {
+                    settingsActivity?.ignoreInvalidTokenError = false
+                    deactivateAccountPasswordTil.error = getString(R.string.error_empty_field_your_password)
+                }
+                DeactivateAccountViewEvents.InvalidPassword -> {
+                    settingsActivity?.ignoreInvalidTokenError = false
+                    deactivateAccountPasswordTil.error = getString(R.string.settings_fail_to_update_password_invalid_current_password)
+                }
+                is DeactivateAccountViewEvents.OtherFailure -> {
+                    settingsActivity?.ignoreInvalidTokenError = false
+                    displayErrorDialog(it.throwable)
+                }
+                DeactivateAccountViewEvents.Done            ->
+                    MainActivity.restartApp(activity!!, MainActivityArgs(clearCredentials = true, isAccountDeactivated = true))
+
+            }.exhaustive
+        }
+    }
+
+    override fun invalidate() = withState(viewModel) { state ->
+        deactivateAccountPassword.showPassword(state.passwordShown)
+        deactivateAccountPasswordReveal.setImageResource(if (state.passwordShown) R.drawable.ic_eye_closed_black else R.drawable.ic_eye_black)
+    }
+}
diff --git a/vector/src/main/java/im/vector/riotx/features/settings/account/deactivation/DeactivateAccountViewEvents.kt b/vector/src/main/java/im/vector/riotx/features/settings/account/deactivation/DeactivateAccountViewEvents.kt
new file mode 100644
index 0000000000..4e7f7252e2
--- /dev/null
+++ b/vector/src/main/java/im/vector/riotx/features/settings/account/deactivation/DeactivateAccountViewEvents.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.riotx.features.settings.account.deactivation
+
+import im.vector.riotx.core.platform.VectorViewEvents
+
+/**
+ * Transient events for deactivate account settings screen
+ */
+sealed class DeactivateAccountViewEvents : VectorViewEvents {
+    data class Loading(val message: CharSequence? = null) : DeactivateAccountViewEvents()
+    object EmptyPassword : DeactivateAccountViewEvents()
+    object InvalidPassword : DeactivateAccountViewEvents()
+    data class OtherFailure(val throwable: Throwable) : DeactivateAccountViewEvents()
+    object Done : DeactivateAccountViewEvents()
+}
diff --git a/vector/src/main/java/im/vector/riotx/features/settings/account/deactivation/DeactivateAccountViewModel.kt b/vector/src/main/java/im/vector/riotx/features/settings/account/deactivation/DeactivateAccountViewModel.kt
new file mode 100644
index 0000000000..adfc9ff5ae
--- /dev/null
+++ b/vector/src/main/java/im/vector/riotx/features/settings/account/deactivation/DeactivateAccountViewModel.kt
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package im.vector.riotx.features.settings.account.deactivation
+
+import com.airbnb.mvrx.FragmentViewModelContext
+import com.airbnb.mvrx.MvRxState
+import com.airbnb.mvrx.MvRxViewModelFactory
+import com.airbnb.mvrx.ViewModelContext
+import com.squareup.inject.assisted.Assisted
+import com.squareup.inject.assisted.AssistedInject
+import im.vector.matrix.android.api.MatrixCallback
+import im.vector.matrix.android.api.failure.isInvalidPassword
+import im.vector.matrix.android.api.session.Session
+import im.vector.riotx.core.extensions.exhaustive
+import im.vector.riotx.core.platform.VectorViewModel
+import im.vector.riotx.core.platform.VectorViewModelAction
+
+data class DeactivateAccountViewState(
+        val passwordShown: Boolean = false
+) : MvRxState
+
+sealed class DeactivateAccountAction : VectorViewModelAction {
+    object TogglePassword : DeactivateAccountAction()
+    data class DeactivateAccount(val password: String, val eraseAllData: Boolean) : DeactivateAccountAction()
+}
+
+class DeactivateAccountViewModel @AssistedInject constructor(@Assisted private val initialState: DeactivateAccountViewState,
+                                                             private val session: Session)
+    : VectorViewModel<DeactivateAccountViewState, DeactivateAccountAction, DeactivateAccountViewEvents>(initialState) {
+
+    @AssistedInject.Factory
+    interface Factory {
+        fun create(initialState: DeactivateAccountViewState): DeactivateAccountViewModel
+    }
+
+    override fun handle(action: DeactivateAccountAction) {
+        when (action) {
+            DeactivateAccountAction.TogglePassword       -> handleTogglePassword()
+            is DeactivateAccountAction.DeactivateAccount -> handleDeactivateAccount(action)
+        }.exhaustive
+    }
+
+    private fun handleTogglePassword() = withState {
+        setState {
+            copy(passwordShown = !passwordShown)
+        }
+    }
+
+    private fun handleDeactivateAccount(action: DeactivateAccountAction.DeactivateAccount) {
+        if (action.password.isEmpty()) {
+            _viewEvents.post(DeactivateAccountViewEvents.EmptyPassword)
+            return
+        }
+
+        _viewEvents.post(DeactivateAccountViewEvents.Loading())
+
+        session.deactivateAccount(action.password, action.eraseAllData, object : MatrixCallback<Unit> {
+            override fun onSuccess(data: Unit) {
+                _viewEvents.post(DeactivateAccountViewEvents.Done)
+            }
+
+            override fun onFailure(failure: Throwable) {
+                if (failure.isInvalidPassword()) {
+                    _viewEvents.post(DeactivateAccountViewEvents.InvalidPassword)
+                } else {
+                    _viewEvents.post(DeactivateAccountViewEvents.OtherFailure(failure))
+                }
+            }
+        })
+    }
+
+    companion object : MvRxViewModelFactory<DeactivateAccountViewModel, DeactivateAccountViewState> {
+
+        @JvmStatic
+        override fun create(viewModelContext: ViewModelContext, state: DeactivateAccountViewState): DeactivateAccountViewModel? {
+            val fragment: DeactivateAccountFragment = (viewModelContext as FragmentViewModelContext).fragment()
+            return fragment.viewModelFactory.create(state)
+        }
+    }
+}
diff --git a/vector/src/main/res/layout/fragment_deactivate_account.xml b/vector/src/main/res/layout/fragment_deactivate_account.xml
new file mode 100644
index 0000000000..aca8adf12d
--- /dev/null
+++ b/vector/src/main/res/layout/fragment_deactivate_account.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:padding="16dp">
+
+        <TextView
+            android:id="@+id/deactivateAccountContent"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:text="@string/deactivate_account_content"
+            android:textColor="?riotx_text_primary"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <CheckBox
+            android:id="@+id/deactivateAccountEraseCheckbox"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="16dp"
+            android:gravity="top"
+            android:text="@string/deactivate_account_delete_checkbox"
+            android:textColor="?riotx_text_primary"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/deactivateAccountContent" />
+
+        <TextView
+            android:id="@+id/deactivateAccountPromptPassword"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="16dp"
+            android:text="@string/deactivate_account_prompt_password"
+            android:textColor="?riotx_text_primary"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/deactivateAccountEraseCheckbox" />
+
+        <FrameLayout
+            android:id="@+id/deactivateAccountPasswordContainer"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="8dp"
+            android:hint="@string/auth_password_placeholder"
+            android:inputType="textPassword"
+            android:maxLines="1"
+            android:nextFocusDown="@+id/login_password"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/deactivateAccountPromptPassword">
+
+
+            <com.google.android.material.textfield.TextInputLayout
+                android:id="@+id/deactivateAccountPasswordTil"
+                style="@style/VectorTextInputLayout"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:hint="@string/login_signup_password_hint"
+                app:errorEnabled="true"
+                app:errorIconDrawable="@null">
+
+                <com.google.android.material.textfield.TextInputEditText
+                    android:id="@+id/deactivateAccountPassword"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:ems="10"
+                    android:inputType="textPassword"
+                    android:maxLines="1"
+                    android:paddingEnd="48dp"
+                    android:paddingRight="48dp"
+                    tools:ignore="RtlSymmetry" />
+
+            </com.google.android.material.textfield.TextInputLayout>
+
+            <ImageView
+                android:id="@+id/deactivateAccountPasswordReveal"
+                android:layout_width="@dimen/layout_touch_size"
+                android:layout_height="@dimen/layout_touch_size"
+                android:layout_gravity="end"
+                android:layout_marginTop="8dp"
+                android:background="?attr/selectableItemBackground"
+                android:scaleType="center"
+                android:src="@drawable/ic_eye_black"
+                android:tint="?attr/colorAccent"
+                tools:contentDescription="@string/a11y_show_password" />
+
+        </FrameLayout>
+
+        <Button
+            android:id="@+id/deactivateAccountSubmit"
+            style="@style/VectorButtonStyleDestructive"
+            android:layout_marginTop="16dp"
+            android:layout_marginBottom="16dp"
+            android:text="@string/deactivate_account_submit"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/deactivateAccountPasswordContainer" />
+
+        <Button
+            android:id="@+id/deactivateAccountCancel"
+            style="@style/VectorButtonStyle"
+            android:layout_marginEnd="16dp"
+            android:layout_marginRight="16dp"
+            android:text="@string/cancel"
+            app:layout_constraintEnd_toStartOf="@+id/deactivateAccountSubmit"
+            app:layout_constraintTop_toTopOf="@+id/deactivateAccountSubmit" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+</androidx.core.widget.NestedScrollView>
diff --git a/vector/src/main/res/xml/vector_settings_general.xml b/vector/src/main/res/xml/vector_settings_general.xml
index ac8fb8445c..11f16655a7 100644
--- a/vector/src/main/res/xml/vector_settings_general.xml
+++ b/vector/src/main/res/xml/vector_settings_general.xml
@@ -97,14 +97,13 @@
 
     </im.vector.riotx.core.preference.VectorPreferenceCategory>
 
-    <im.vector.riotx.core.preference.VectorPreferenceCategory
-        android:key="SETTINGS_DEACTIVATE_ACCOUNT_CATEGORY_KEY"
-        android:title="@string/settings_deactivate_account_section"
-        app:isPreferenceVisible="@bool/false_not_implemented">
+    <im.vector.riotx.core.preference.VectorPreferenceCategory android:title="@string/settings_deactivate_account_section">
 
         <im.vector.riotx.core.preference.VectorPreference
             android:key="SETTINGS_DEACTIVATE_ACCOUNT_KEY"
-            android:title="@string/settings_deactivate_my_account" />
+            android:persistent="false"
+            android:title="@string/settings_deactivate_my_account"
+            app:fragment="im.vector.riotx.features.settings.account.deactivation.DeactivateAccountFragment" />
 
     </im.vector.riotx.core.preference.VectorPreferenceCategory>