diff --git a/auth/src/main/java/org/futo/circles/auth/view/EnterRecoveryKeyView.kt b/auth/src/main/java/org/futo/circles/auth/view/EnterRecoveryKeyView.kt
new file mode 100644
index 0000000000000000000000000000000000000000..656db7f1c1a836b6a4c8970253b9575324822915
--- /dev/null
+++ b/auth/src/main/java/org/futo/circles/auth/view/EnterRecoveryKeyView.kt
@@ -0,0 +1,60 @@
+package org.futo.circles.auth.view
+
+import android.content.Context
+import android.net.Uri
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import androidx.constraintlayout.widget.ConstraintLayout
+import org.futo.circles.auth.databinding.ViewEnterRecoveryKeyBinding
+import org.futo.circles.core.extensions.getFilename
+import org.futo.circles.core.extensions.gone
+import org.futo.circles.core.extensions.visible
+
+class EnterRecoveryKeyView(
+    context: Context,
+    attrs: AttributeSet? = null
+) : ConstraintLayout(context, attrs) {
+
+    private val binding = ViewEnterRecoveryKeyBinding.inflate(LayoutInflater.from(context), this)
+
+    private var selectedFileUri: Uri? = null
+    private var onFileUploadListener: (() -> Unit)? = null
+    private var onInputChangedListener: (() -> Unit)? = null
+
+    init {
+        binding.ivRemoveFile.setOnClickListener {
+            selectedFileUri = null
+            binding.passPhraseGroup.visible()
+            binding.fileNameGroup.gone()
+            handleOnInputChanged()
+        }
+        binding.btnUploadFile.setOnClickListener {
+            onFileUploadListener?.invoke()
+        }
+    }
+
+    fun setup(
+        onUploadFileListener: () -> Unit,
+        onInputChanged: () -> Unit
+    ) {
+        onFileUploadListener = onUploadFileListener
+        onInputChangedListener = onInputChanged
+    }
+
+    fun getRawKey(): String? = binding.tilRecoveryKey.editText?.text?.toString()
+    fun getFileUri(): Uri? = selectedFileUri
+
+    fun selectFile(uri: Uri) {
+        selectedFileUri = uri
+        binding.tvFileName.text = uri.getFilename(context) ?: uri.toString()
+        binding.passPhraseGroup.gone()
+        binding.fileNameGroup.visible()
+        handleOnInputChanged()
+    }
+
+    private fun handleOnInputChanged() {
+        onInputChangedListener?.invoke()
+    }
+
+
+}
\ No newline at end of file
diff --git a/auth/src/main/res/layout/view_enter_recovery_key.xml b/auth/src/main/res/layout/view_enter_recovery_key.xml
new file mode 100644
index 0000000000000000000000000000000000000000..39e6f38b6294002af73b6656c7ce0b2dac79ef75
--- /dev/null
+++ b/auth/src/main/res/layout/view_enter_recovery_key.xml
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merge 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="wrap_content"
+    tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
+
+    <com.google.android.material.textfield.TextInputLayout
+        android:id="@+id/tilRecoveryKey"
+        style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:hint="@string/recovery_key"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/recoveryTypeGroup">
+
+        <com.google.android.material.textfield.TextInputEditText
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:imeOptions="actionDone"
+            android:inputType="textMultiLine"
+            android:minLines="4"
+            android:padding="8dp" />
+
+    </com.google.android.material.textfield.TextInputLayout>
+
+    <TextView
+        android:id="@+id/tvOr"
+        style="@style/body"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="16dp"
+        android:text="@string/or"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tilRecoveryKey" />
+
+    <TextView
+        android:id="@+id/tvFileName"
+        style="@style/body"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="26dp"
+        android:layout_marginTop="16dp"
+        android:layout_marginEnd="8dp"
+        android:ellipsize="end"
+        android:lines="1"
+        app:layout_constrainedWidth="true"
+        app:layout_constraintEnd_toStartOf="@id/ivRemoveFile"
+        app:layout_constraintHorizontal_chainStyle="packed"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tvOr"
+        tools:text="File name.txt" />
+
+    <ImageView
+        android:id="@+id/ivRemoveFile"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="16dp"
+        android:background="?android:selectableItemBackgroundBorderless"
+        android:clickable="true"
+        android:focusable="true"
+        android:src="@drawable/ic_close"
+        app:layout_constraintBottom_toBottomOf="@id/tvFileName"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toEndOf="@id/tvFileName"
+        app:layout_constraintTop_toTopOf="@id/tvFileName"
+        app:tint="@color/blue" />
+
+    <com.google.android.material.button.MaterialButton
+        android:id="@+id/btnUploadFile"
+        style="@style/PostButtonStyle"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="16dp"
+        android:text="@string/upload_recovery_key_file"
+        app:icon="@drawable/ic_file"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tvFileName" />
+
+    <androidx.constraintlayout.widget.Group
+        android:id="@+id/passPhraseGroup"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        app:constraint_referenced_ids="tvOr,tilRecoveryKey" />
+
+    <androidx.constraintlayout.widget.Group
+        android:id="@+id/fileNameGroup"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:visibility="gone"
+        app:constraint_referenced_ids="tvFileName,ivRemoveFile"
+        tools:visibility="visible" />
+
+
+</merge>
\ No newline at end of file