diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/TransactionExtrasReducer.kt b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/TransactionExtrasReducer.kt
index 4215143301..71000abec1 100644
--- a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/TransactionExtrasReducer.kt
+++ b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/TransactionExtrasReducer.kt
@@ -3,8 +3,19 @@ package com.tangem.tap.features.send.redux.reducers
import com.tangem.blockchain.blockchains.stellar.StellarMemo
import com.tangem.blockchain.common.Blockchain
import com.tangem.tap.features.send.redux.SendScreenAction
-import com.tangem.tap.features.send.redux.TransactionExtrasAction.*
-import com.tangem.tap.features.send.redux.states.*
+import com.tangem.tap.features.send.redux.TransactionExtrasAction.BinanceMemo
+import com.tangem.tap.features.send.redux.TransactionExtrasAction.Prepare
+import com.tangem.tap.features.send.redux.TransactionExtrasAction.Release
+import com.tangem.tap.features.send.redux.TransactionExtrasAction.XlmMemo
+import com.tangem.tap.features.send.redux.TransactionExtrasAction.XrpDestinationTag
+import com.tangem.tap.features.send.redux.states.BinanceMemoState
+import com.tangem.tap.features.send.redux.states.InputViewValue
+import com.tangem.tap.features.send.redux.states.SendState
+import com.tangem.tap.features.send.redux.states.TransactionExtraError
+import com.tangem.tap.features.send.redux.states.TransactionExtrasState
+import com.tangem.tap.features.send.redux.states.XlmMemoState
+import com.tangem.tap.features.send.redux.states.XlmMemoType
+import com.tangem.tap.features.send.redux.states.XrpDestinationTagState
/**
[REDACTED_AUTHOR]
@@ -53,42 +64,33 @@ class TransactionExtrasReducer : SendInternalReducer {
}
private fun handleXlmMemo(
- action: XlmMemo,
- sendState: SendState,
- infoState: TransactionExtrasState,
+ action: XlmMemo,
+ sendState: SendState,
+ infoState: TransactionExtrasState,
): SendState {
fun clearMemo(memo: XlmMemoState): XlmMemoState = memo.copy(text = null, id = null, error = null)
val result = when (action) {
-// is XlmMemo.ChangeSelectedMemo -> {
-// val inputViewValue = InputViewValue("", false)
-// val memo = infoState.xlmMemo?.copy(
-// viewFieldValue = inputViewValue,
-// selectedMemoType = action.memoType,
-// ) ?: XlmMemoState(inputViewValue, action.memoType)
-//
-// infoState.copy(xlmMemo = clearMemo(memo))
-// }
is XlmMemo.HandleUserInput -> {
val inputViewValue = InputViewValue(action.data, true)
var memo = infoState.xlmMemo?.copy(viewFieldValue = inputViewValue)
- ?: XlmMemoState(inputViewValue)
+ ?: XlmMemoState(inputViewValue)
memo = clearMemo(memo)
- memo = when (infoState.xlmMemo?.selectedMemoType) {
- XlmMemoType.TEXT -> memo.copy(text = StellarMemo.Text(action.data))
- XlmMemoType.ID -> {
- val id = action.data.toBigIntegerOrNull()
- if (id != null) {
- if (id > XlmMemoState.MAX_NUMBER) {
- memo.copy(error = TransactionExtraError.INVALID_XLM_MEMO)
- } else {
- memo.copy(id = StellarMemo.Id(id))
- }
+ memo = when (memo.selectedMemoType) {
+ XlmMemoType.TEXT -> {
+ if (XlmMemoState.isAssignableValue(action.data)) {
+ memo.copy(text = StellarMemo.Text(action.data))
} else {
- memo
+ memo.copy(error = TransactionExtraError.INVALID_XLM_MEMO)
+ }
+ }
+ XlmMemoType.ID -> {
+ if (XlmMemoState.isAssignableValue(action.data)) {
+ memo.copy(id = StellarMemo.Id(action.data.toBigInteger()))
+ } else {
+ memo.copy(error = TransactionExtraError.INVALID_XLM_MEMO)
}
}
- null -> memo
}
infoState.copy(xlmMemo = memo)
}
@@ -117,16 +119,16 @@ class TransactionExtrasReducer : SendInternalReducer {
}
private fun handleXrpTag(
- action: XrpDestinationTag,
- sendState: SendState,
- infoState: TransactionExtrasState,
+ action: XrpDestinationTag,
+ sendState: SendState,
+ infoState: TransactionExtrasState,
): SendState {
val result = when (action) {
is XrpDestinationTag.HandleUserInput -> {
val tag = action.data.toLongOrNull()
if (tag != null) {
val input = InputViewValue(action.data, true)
- val tagState = if (tag <= XrpDestinationTagState.MAX_NUMBER){
+ val tagState = if (tag <= XrpDestinationTagState.MAX_NUMBER) {
XrpDestinationTagState(input, tag)
} else {
XrpDestinationTagState(input, error = TransactionExtraError.INVALID_DESTINATION_TAG)
diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/states/AddressPayIdState.kt b/app/src/main/java/com/tangem/tap/features/send/redux/states/AddressPayIdState.kt
index e4f816c106..30fe37f60a 100644
--- a/app/src/main/java/com/tangem/tap/features/send/redux/states/AddressPayIdState.kt
+++ b/app/src/main/java/com/tangem/tap/features/send/redux/states/AddressPayIdState.kt
@@ -1,19 +1,20 @@
package com.tangem.tap.features.send.redux.states
+import androidx.core.text.isDigitsOnly
import com.tangem.blockchain.blockchains.stellar.StellarMemo
import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction
import java.math.BigInteger
data class AddressPayIdState(
- val viewFieldValue: InputViewValue = InputViewValue(""),
- val normalFieldValue: String? = null,
- val truncatedFieldValue: String? = null,
- val destinationWalletAddress: String? = null,
- val error: AddressPayIdVerifyAction.Error? = null,
- val truncateHandler: ((String) -> String)? = null,
- val sendingToPayIdEnabled: Boolean = false,
- val pasteIsEnabled: Boolean = false,
- val inputIsEnabled: Boolean = true
+ val viewFieldValue: InputViewValue = InputViewValue(""),
+ val normalFieldValue: String? = null,
+ val truncatedFieldValue: String? = null,
+ val destinationWalletAddress: String? = null,
+ val error: AddressPayIdVerifyAction.Error? = null,
+ val truncateHandler: ((String) -> String)? = null,
+ val sendingToPayIdEnabled: Boolean = false,
+ val pasteIsEnabled: Boolean = false,
+ val inputIsEnabled: Boolean = true,
) : SendScreenState {
override val stateId: StateId = StateId.ADDRESS_PAY_ID
@@ -26,9 +27,9 @@ data class AddressPayIdState(
}
data class TransactionExtrasState(
- val xlmMemo: XlmMemoState? = null,
- val binanceMemo: BinanceMemoState? = null,
- val xrpDestinationTag: XrpDestinationTagState? = null
+ val xlmMemo: XlmMemoState? = null,
+ val binanceMemo: BinanceMemoState? = null,
+ val xrpDestinationTag: XrpDestinationTagState? = null,
) : IdStateHolder {
override val stateId: StateId = StateId.TRANSACTION_EXTRAS
}
@@ -38,11 +39,10 @@ enum class XlmMemoType {
}
data class XlmMemoState(
- val viewFieldValue: InputViewValue = InputViewValue(""),
- val selectedMemoType: XlmMemoType = XlmMemoType.ID,
- val text: StellarMemo.Text? = null,
- val id: StellarMemo.Id? = null,
- val error: TransactionExtraError? = null,
+ val viewFieldValue: InputViewValue = InputViewValue(""),
+ val text: StellarMemo.Text? = null,
+ val id: StellarMemo.Id? = null,
+ val error: TransactionExtraError? = null,
) {
val memo: StellarMemo?
get() = when (selectedMemoType) {
@@ -50,16 +50,37 @@ data class XlmMemoState(
XlmMemoType.ID -> id
}
+ val selectedMemoType: XlmMemoType
+ get() = determineMemoType(viewFieldValue.value)
+
companion object {
- val MAX_NUMBER: BigInteger = BigInteger("FFFFFFFFFFFFFFFF", 16)
+ fun determineMemoType(value: String): XlmMemoType = when {
+ value.isNotEmpty() && value.isDigitsOnly() -> XlmMemoType.ID
+ else -> XlmMemoType.TEXT
+ }
+
+ fun isAssignableValue(value: String): Boolean = when (determineMemoType(value)) {
+ XlmMemoType.TEXT -> {
+ // from org.stellar.sdk.MemoText
+ value.toByteArray().size <= 28
+ }
+ XlmMemoType.ID -> {
+ try {
+ // from com.tangem.blockchain.blockchains.stellar.StellarMemo.toStellarSdkMemo
+ value.toBigInteger() in BigInteger.ZERO..(Long.MAX_VALUE.toBigInteger() * 2.toBigInteger())
+ } catch (ex: NumberFormatException) {
+ false
+ }
+ }
+ }
}
}
data class BinanceMemoState(
val viewFieldValue: InputViewValue = InputViewValue(""),
val memo: BigInteger? = null,
- val error: TransactionExtraError? = null
- ) {
+ val error: TransactionExtraError? = null,
+) {
companion object {
val MAX_NUMBER: BigInteger = BigInteger("FFFFFFFFFFFFFFFF", 16)
}
@@ -67,9 +88,9 @@ data class BinanceMemoState(
// tag must contains only digits
data class XrpDestinationTagState(
- val viewFieldValue: InputViewValue = InputViewValue(""),
- val tag: Long? = null,
- val error: TransactionExtraError? = null
+ val viewFieldValue: InputViewValue = InputViewValue(""),
+ val tag: Long? = null,
+ val error: TransactionExtraError? = null,
) {
companion object {
const val MAX_NUMBER: Long = 4294967295
diff --git a/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt b/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt
index 96624950c0..31fa218cfd 100644
--- a/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt
+++ b/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt
@@ -2,7 +2,6 @@ package com.tangem.tap.features.send.ui.stateSubscribers
import android.app.Dialog
import android.content.Context
-import android.text.InputType
import android.text.SpannableStringBuilder
import android.view.View
import android.view.ViewGroup
@@ -31,7 +30,6 @@ import com.tangem.tap.features.send.redux.states.SendState
import com.tangem.tap.features.send.redux.states.StateId
import com.tangem.tap.features.send.redux.states.TransactionExtraError
import com.tangem.tap.features.send.redux.states.TransactionExtrasState
-import com.tangem.tap.features.send.redux.states.XlmMemoType
import com.tangem.tap.features.send.ui.FeeUiHelper
import com.tangem.tap.features.send.ui.SendFragment
import com.tangem.tap.features.send.ui.dialogs.RequestFeeErrorDialog
@@ -80,14 +78,10 @@ class SendStateSubscriber(fragment: BaseStoreFragment) :
showView(binanceMemoContainer, infoState.binanceMemo)
infoState.xlmMemo?.let {
- etXlmMemo.inputType = when (it.selectedMemoType) {
- XlmMemoType.TEXT -> InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS
- XlmMemoType.ID -> InputType.TYPE_CLASS_NUMBER
- }
if (!it.viewFieldValue.isFromUserInput) etXlmMemo.setText(it.viewFieldValue.value)
if (it.error != null) {
if (it.error == TransactionExtraError.INVALID_XLM_MEMO) {
- tilXlmMemo.error = fg.getText(R.string.send_error_invalid_memo_id)
+ tilXlmMemo.error = fg.getText(R.string.send_error_invalid_memo)
}
} else {
tilXlmMemo.error = null
@@ -109,7 +103,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) :
infoState.binanceMemo?.let {
if (infoState.binanceMemo.error != null) {
if (infoState.binanceMemo.error == TransactionExtraError.INVALID_BINANCE_MEMO) {
- tilBinanceMemo.error = fg.getText(R.string.send_error_invalid_memo_id)
+ tilBinanceMemo.error = fg.getText(R.string.send_error_invalid_memo)
}
} else {
tilBinanceMemo.error = null
diff --git a/app/src/main/res/layout/layout_send_address_payid.xml b/app/src/main/res/layout/layout_send_address_payid.xml
index 232b778f22..b16e59b974 100644
--- a/app/src/main/res/layout/layout_send_address_payid.xml
+++ b/app/src/main/res/layout/layout_send_address_payid.xml
@@ -153,6 +153,7 @@
android:layout_height="wrap_content"
android:background="@color/backgroundLightGray"
android:ellipsize="middle"
+ android:inputType="text|textNoSuggestions"
android:paddingStart="0dp"
android:paddingEnd="0dp"
android:singleLine="true"
diff --git a/app/src/main/res/values-de/strings_final.xml b/app/src/main/res/values-de/strings_final.xml
index 4243136291..7e585b36f2 100644
--- a/app/src/main/res/values-de/strings_final.xml
+++ b/app/src/main/res/values-de/strings_final.xml
@@ -86,5 +86,9 @@
Reset to Factory Settings
Factory Reset will completely delete the wallet from the selected card. You will not be able to restore the current wallet or use the card to recover the access code.
Select network
+ Memo
+ Tag
+ Invalid Memo. It won\'t be added to the transaction
+ Invalid Tag. It won\'t be added to the transaction
%s network has a concept of Existential Deposit. If your account drops below %s %s it will be deactivated and any remaining funds will be destroyed.
\ No newline at end of file
diff --git a/app/src/main/res/values-fr/strings_final.xml b/app/src/main/res/values-fr/strings_final.xml
index 6e840c3e83..5d8b24ed0f 100644
--- a/app/src/main/res/values-fr/strings_final.xml
+++ b/app/src/main/res/values-fr/strings_final.xml
@@ -86,5 +86,9 @@
Reset to Factory Settings
Factory Reset will completely delete the wallet from the selected card. You will not be able to restore the current wallet or use the card to recover the access code.
Select network
+ Memo
+ Tag
+ Invalid Memo. It won\'t be added to the transaction
+ Invalid Tag. It won\'t be added to the transaction
%s network has a concept of Existential Deposit. If your account drops below %s %s it will be deactivated and any remaining funds will be destroyed.
\ No newline at end of file
diff --git a/app/src/main/res/values-it/strings_final.xml b/app/src/main/res/values-it/strings_final.xml
index 6e840c3e83..5d8b24ed0f 100644
--- a/app/src/main/res/values-it/strings_final.xml
+++ b/app/src/main/res/values-it/strings_final.xml
@@ -86,5 +86,9 @@
Reset to Factory Settings
Factory Reset will completely delete the wallet from the selected card. You will not be able to restore the current wallet or use the card to recover the access code.
Select network
+ Memo
+ Tag
+ Invalid Memo. It won\'t be added to the transaction
+ Invalid Tag. It won\'t be added to the transaction
%s network has a concept of Existential Deposit. If your account drops below %s %s it will be deactivated and any remaining funds will be destroyed.
\ No newline at end of file
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index c0059a0e36..9c7aef46d4 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -147,10 +147,6 @@
Добавить
Удалить
Поиск
- Памятка
- Тег назначения
- Недопустимый тег назначения. Он не будет добавлен в транзакцию.
- Недопустимый идентификатор памятки. Он не будет добавлен в транзакцию.
Приложение
Отправить отзыв
Успешно отправлено
diff --git a/app/src/main/res/values-ru/strings_final.xml b/app/src/main/res/values-ru/strings_final.xml
index 0f2737c2bb..4bc89187dc 100644
--- a/app/src/main/res/values-ru/strings_final.xml
+++ b/app/src/main/res/values-ru/strings_final.xml
@@ -97,5 +97,9 @@
Сброс к заводским настройкам
Сброс к заводским настройкам приведет к полному удалению кошелька с выбранной карты. Вы не сможете восстановить текущий кошелек или использовать эту карту для восстановления кода доступа.
Выберите сеть
+ Memo
+ Tag
+ Недопустимый Memo. Он не будет добавлен в транзакцию.
+ Недопустимый Tag. Он не будет добавлен в транзакцию.
Сеть %s использует концепцию экзистенциального депозита. Если баланс вашего счета опустится ниже %s %s, он будет деактивирован, а все оставшиеся средства будут уничтожены.
diff --git a/app/src/main/res/values/strings_final.xml b/app/src/main/res/values/strings_final.xml
index c3c6f58fe1..fa691840a2 100644
--- a/app/src/main/res/values/strings_final.xml
+++ b/app/src/main/res/values/strings_final.xml
@@ -99,5 +99,9 @@
Reset to Factory Settings
Factory Reset will completely delete the wallet from the selected card. You will not be able to restore the current wallet or use the card to recover the access code.
Select network
+ Memo
+ Tag
+ Invalid Memo. It won\'t be added to the transaction
+ Invalid Tag. It won\'t be added to the transaction
%s network has a concept of Existential Deposit. If your account drops below %s %s it will be deactivated and any remaining funds will be destroyed.
diff --git a/app/src/main/res/values/strings_untranslated.xml b/app/src/main/res/values/strings_untranslated.xml
index 55c6923133..cc9e1a3cf3 100644
--- a/app/src/main/res/values/strings_untranslated.xml
+++ b/app/src/main/res/values/strings_untranslated.xml
@@ -40,12 +40,6 @@
Remove
Search
-
- Memo
- Destination tag
- Invalid destination tag. It won\'t be added to the transaction
- Invalid Memo ID. It won\'t be added to the transaction
-
App
Send feedback
Sent successfully