From 90bdddb5e8792f7dcb4694557e1c2c43983b1b41 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 4 Sep 2020 20:14:19 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../main/java/com/tangem/tap/MainActivity.kt | 3 + .../com/tangem/tap/domain/PayIdManager.kt | 10 +- .../tap/features/send/redux/SendMiddleware.kt | 109 +++++++++++------- .../tap/features/send/redux/SendReducer.kt | 48 +++++--- .../features/send/redux/SendScreenAction.kt | 29 ++++- .../tap/features/send/redux/SendState.kt | 26 ++++- .../tap/features/send/ui/SendFragment.kt | 23 +++- .../stateSubscribers/SendStateSubscriber.kt | 27 ++++- .../tap/network/payid/PayIdVerifyApi.kt | 44 +++++++ .../tap/network/payid/PayIdVerifyService.kt | 21 ++++ .../res/layout/layout_send_address_payid.xml | 2 +- app/src/main/res/values/strings.xml | 7 ++ 12 files changed, 278 insertions(+), 71 deletions(-) create mode 100644 app/src/main/java/com/tangem/tap/network/payid/PayIdVerifyApi.kt create mode 100644 app/src/main/java/com/tangem/tap/network/payid/PayIdVerifyService.kt diff --git a/app/src/main/java/com/tangem/tap/MainActivity.kt b/app/src/main/java/com/tangem/tap/MainActivity.kt index b2947e0c13..9b24821ade 100644 --- a/app/src/main/java/com/tangem/tap/MainActivity.kt +++ b/app/src/main/java/com/tangem/tap/MainActivity.kt @@ -36,6 +36,9 @@ private val coroutineContext: CoroutineContext get() = Job() + Dispatchers.IO + initCoroutineExceptionHandler() val scope = CoroutineScope(coroutineContext) +private val mainCoroutineContext: CoroutineContext + get() = Job() + Dispatchers.Main +val mainScope = CoroutineScope(mainCoroutineContext) private fun initCoroutineExceptionHandler(): CoroutineExceptionHandler { return CoroutineExceptionHandler { _, throwable -> diff --git a/app/src/main/java/com/tangem/tap/domain/PayIdManager.kt b/app/src/main/java/com/tangem/tap/domain/PayIdManager.kt index 235f0ea37a..ddf6c99669 100644 --- a/app/src/main/java/com/tangem/tap/domain/PayIdManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/PayIdManager.kt @@ -3,7 +3,9 @@ package com.tangem.tap.domain import com.tangem.blockchain.common.Blockchain import com.tangem.commands.common.network.Result import com.tangem.tap.network.payid.PayIdService +import com.tangem.tap.network.payid.PayIdVerifyService import com.tangem.tap.network.payid.SetPayIdResponse +import com.tangem.tap.network.payid.VerifyPayIdResponse import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import retrofit2.HttpException @@ -41,13 +43,19 @@ class PayIdManager { } } + suspend fun verifyPayId(payId: String, blockchain: Blockchain): Result = withContext(Dispatchers.IO) { + val splitPayId = payId.split("\$") + val user = splitPayId[0] + val baseUrl = "https://${splitPayId[1]}/" + return@withContext PayIdVerifyService(baseUrl).verifyAddress(user, blockchain.getPayIdNetwork()) + } private fun Blockchain.getPayIdNetwork(): String { return when (this) { Blockchain.XRP -> "XRPL" Blockchain.RSK -> "RSK" else -> this.currency - } + }.toLowerCase() } companion object { diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/SendMiddleware.kt b/app/src/main/java/com/tangem/tap/features/send/redux/SendMiddleware.kt index f734d0816c..604d7c7a22 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/SendMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/SendMiddleware.kt @@ -1,13 +1,19 @@ package com.tangem.tap.features.send.redux +import com.tangem.blockchain.common.Wallet import com.tangem.blockchain.common.WalletManager +import com.tangem.commands.common.network.Result import com.tangem.tap.common.redux.AppState import com.tangem.tap.domain.PayIdManager +import com.tangem.tap.domain.PayIdManager.Companion.isPayId import com.tangem.tap.domain.isPayIdSupported import com.tangem.tap.features.send.redux.AddressPayIdActionUI.SetAddressOrPayId +import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction.* import com.tangem.tap.scope import com.tangem.tap.store +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import org.rekotlin.Action import org.rekotlin.Middleware @@ -29,59 +35,84 @@ private fun handleSendAction(action: Action) { when (sendAction) { is AddressPayIdActionUI -> { when (sendAction) { - is SetAddressOrPayId -> AddressPayIdHandler().handle(sendAction.data?.toString()) + is SetAddressOrPayId -> AddressPayIdHandler().handle(sendAction.data) } } } } internal class AddressPayIdHandler { - fun handle(data: String?) { + fun handle(data: String) { val walletManager = store.state.globalState.walletManager ?: return - val clipboardData = data ?: return - if (PayIdManager.isPayId(clipboardData)) { - if (walletManager.wallet.blockchain.isPayIdSupported()) { - store.dispatch(AddressPayIdAction.Verification.PayIdNotSupportedByBlockchain) - } else { - scope.launch { - val response = verifyPayID(walletManager, clipboardData) - if (response == null) { - store.dispatch(AddressPayIdAction.Verification.Failed) - } else { - val address = "some address D:" // extract from response - store.dispatch(AddressPayIdAction.Verification.Success(address)) - } - } - } + if (isPayId(data)) { + verifyPayId(data, walletManager) + store.dispatch(ProcessedButNotVerifiedAddressPayId(data)) } else { - + val supposedAddress = extractAddressFromShareUri(data) + store.dispatch(PayIdVerification.Failed(supposedAddress, FailReason.IS_NOT_PAY_ID)) + store.dispatch(ProcessedButNotVerifiedAddressPayId(supposedAddress)) + verifyAddress(walletManager, supposedAddress) } } - private suspend fun verifyPayID(walletManager: WalletManager, payID: String?): String? { - val cardId = walletManager.cardId - val publicKey = store.state.globalState.card?.cardPublicKey + private fun verifyPayId(payId: String, walletManager: WalletManager) { + val blockchain = walletManager.wallet.blockchain + if (!blockchain.isPayIdSupported()) { + store.dispatch(PayIdVerification.Failed(payId, FailReason.PAY_ID_UNSUPPORTED_BY_BLOCKCHAIN)) + return + } -// val result = PayIdManager().getPayId(cardId, publicKey.toHexString()) -// withContext(Dispatchers.Main) { -// when (result) { -// is Result.Success -> { -// val payId = result.data -// if (payId == null) { -// store.dispatch(WalletAction.LoadPayId.NotCreated) -// } else { -// store.dispatch(WalletAction.LoadPayId.Success(payId)) -// } -// } -// is Result.Failure -> store.dispatch(WalletAction.LoadPayId.Failure) -// } -// } - return null + scope.launch { + val result = PayIdManager().verifyPayId(payId, blockchain) + withContext(Dispatchers.Main) { + when (result) { + is Result.Success -> { + val address = result.data.getAddress() + if (address == null) { + store.dispatch(PayIdVerification.Failed(payId, FailReason.PAY_ID_NOT_REGISTERED)) + return@withContext + } + val failReason = isValidBlockchainAddressAndNotTheSameAsWallet(walletManager.wallet, address) + + val actionToSend = if (failReason == FailReason.NONE) PayIdVerification.Success(payId, address) + else AddressVerification.Failed(payId, failReason) + store.dispatch(actionToSend) + } + is Result.Failure -> { + store.dispatch(PayIdVerification.Failed(payId, FailReason.PAY_ID_REQUEST_FAILED)) + } + } + + } + } } - private suspend fun verifyWalletAddress(payID: String?): Boolean { - val isRealAddress = true - return isRealAddress + private fun verifyAddress(walletManager: WalletManager, supposedAddress: String) { + val failReason = isValidBlockchainAddressAndNotTheSameAsWallet(walletManager.wallet, supposedAddress) + val actionToSend = if (failReason == FailReason.NONE) AddressVerification.Success(supposedAddress) + else AddressVerification.Failed(supposedAddress, failReason) + + store.dispatch(actionToSend) + } + + private fun isValidBlockchainAddressAndNotTheSameAsWallet(wallet: Wallet, address: String): FailReason { + return if (wallet.blockchain.validateAddress(address)) { + if (wallet.address != address) { + FailReason.NONE + } else { + FailReason.ADDRESS_SAME_AS_WALLET + } + } else { + FailReason.ADDRESS_INVALID_OR_UNSUPPORTED_BY_BLOCKCHAIN + } + } + + //TODO: move to the blockchainSDK + private fun extractAddressFromShareUri(shareUri: String): String { + val sharePrefix = listOf("bitcoin:", "ethereum:", "ripple:") + val prefixes = sharePrefix.filter { shareUri.contains(it) } + return if (prefixes.isEmpty()) shareUri + else shareUri.replace(prefixes[0], "") } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/SendReducer.kt b/app/src/main/java/com/tangem/tap/features/send/redux/SendReducer.kt index 67a2f55308..27f36ed995 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/SendReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/SendReducer.kt @@ -1,7 +1,6 @@ package com.tangem.tap.features.send.redux import android.view.View -import com.tangem.tap.features.send.redux.AddressPayIdActionUI.SetAddressOrPayId import com.tangem.tap.features.send.redux.FeeActionUI.* import org.rekotlin.Action import org.rekotlin.StateType @@ -16,32 +15,47 @@ class SendReducer { } } -private fun internalReduce(action: Action, sendState: SendState): SendState { - if (action is ReleaseSendState) return SendState() - val sendAction = action as? SendScreenAction ?: return sendState +private fun internalReduce(incomingAction: Action, sendState: SendState): SendState { + if (incomingAction is ReleaseSendState) return SendState() + val action = incomingAction as? SendScreenAction ?: return sendState - return when (sendAction) { - is AddressPayIdActionUI -> handleAddressPayIdAction(sendAction, sendState, sendState.addressPayIDState) - is FeeActionUI -> handleFeeLayoutAction(sendAction, sendState, sendState.feeLayoutState) + return when (action) { + is FeeActionUI -> handleFeeLayoutAction(action, sendState, sendState.feeLayoutState) +// is SetAddressOrPayId -> handleAddressPayIdUIAction(action, sendState, sendState.addressPayIDState) + is AddressPayIdVerifyAction -> handleAddressPayIdAction(action, sendState, sendState.addressPayIDState) else -> sendState } } private fun handleAddressPayIdAction( - action: AddressPayIdActionUI, + action: AddressPayIdVerifyAction, sendState: SendState, state: AddressPayIDState ): SendState { - var state = state - - when (action) { - is SetAddressOrPayId -> { - state = state.copy(value = action.data?.toString()) - return updateLastState(sendState.copy(addressPayIDState = state), state) + val result: AddressPayIDState? = when (action) { + is AddressPayIdVerifyAction.PayIdVerification.Success -> { + state.copyPayIdWalletAddress(action.payId, action.payIdWalletAddress) + } + is AddressPayIdVerifyAction.PayIdVerification.Failed -> { + state.copyPaiIdError(action.payId, action.reason) + } + is AddressPayIdVerifyAction.AddressVerification.Success -> { + state.copyWalletAddress(action.address) + } + is AddressPayIdVerifyAction.AddressVerification.Failed -> { + state.copyError(action.address, action.reason) + } + is AddressPayIdVerifyAction.ProcessedButNotVerifiedAddressPayId -> { + state.copy(etFieldValue = action.data) } } + return if (result == null) { + Timber.e("AddressPayIDState didn't modified.") + sendState + } else { + updateLastState(sendState.copy(addressPayIDState = result), result) + } - return sendState } private fun handleFeeLayoutAction(action: FeeActionUI, sendState: SendState, state: FeeLayoutState): SendState { @@ -64,8 +78,8 @@ private fun handleFeeLayoutAction(action: FeeActionUI, sendState: SendState, sta } } -private fun updateLastState(sendState: SendState, state: StateType): SendState { - val sendState = sendState.copy(lastChangedStateType = state) +private fun updateLastState(sendState: SendState, lastChangedState: StateType): SendState { + val sendState = sendState.copy(lastChangedStateType = lastChangedState) Timber.d("$sendState") return sendState } diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt b/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt index 6e0075913b..e37b243aa2 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt @@ -16,14 +16,31 @@ sealed class FeeActionUI : SendScreenActionUI { class ChangeIncludeFee(val isChecked: Boolean) : FeeActionUI() } +// shortness AddressOrPayId = APid sealed class AddressPayIdActionUI : SendScreenActionUI { - data class SetAddressOrPayId(val data: CharSequence?) : AddressPayIdActionUI() + data class SetAddressOrPayId(val data: String) : AddressPayIdActionUI() } -sealed class AddressPayIdAction : SendScreenAction { - object Verification : AddressPayIdAction() { - object PayIdNotSupportedByBlockchain : AddressPayIdAction() - object Failed : AddressPayIdAction() - data class Success(val payIdWalletAddress: String) : AddressPayIdAction() +sealed class AddressPayIdVerifyAction : SendScreenAction { + enum class FailReason { + NONE, + IS_NOT_PAY_ID, + PAY_ID_UNSUPPORTED_BY_BLOCKCHAIN, + PAY_ID_NOT_REGISTERED, + PAY_ID_REQUEST_FAILED, + ADDRESS_INVALID_OR_UNSUPPORTED_BY_BLOCKCHAIN, + ADDRESS_SAME_AS_WALLET + } + + data class ProcessedButNotVerifiedAddressPayId(val data: String) : AddressPayIdVerifyAction() + + sealed class PayIdVerification : AddressPayIdVerifyAction() { + data class Failed(val payId: String, val reason: FailReason) : PayIdVerification() + data class Success(val payId: String, val payIdWalletAddress: String) : PayIdVerification() + } + + sealed class AddressVerification : AddressPayIdVerifyAction() { + data class Failed(val address: String, val reason: FailReason) : AddressVerification() + data class Success(val address: String) : AddressVerification() } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/SendState.kt b/app/src/main/java/com/tangem/tap/features/send/redux/SendState.kt index 70036db005..221290b937 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/SendState.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/SendState.kt @@ -18,10 +18,28 @@ data class SendState( class NoneState : StateType data class AddressPayIDState( - val value: String? = null, - val payIDWalletAddress: String? = null, - val error: String? = null, -) : StateType + val etFieldValue: String? = null, + val walletAddress: String? = null, + val error: AddressPayIdVerifyAction.FailReason? = null, +) : StateType { + + fun isPayIdState():Boolean = walletAddress != null && walletAddress != etFieldValue + + fun copyWalletAddress(address: String): AddressPayIDState { + return this.copy(etFieldValue = address, walletAddress = address, error = null) + } + fun copyError(address: String, error: AddressPayIdVerifyAction.FailReason): AddressPayIDState { + return this.copy(etFieldValue = address, error = error, walletAddress = null) + } + + fun copyPayIdWalletAddress(payId: String, address: String): AddressPayIDState { + return this.copy(etFieldValue = payId, walletAddress = address, error = null) + } + + fun copyPaiIdError(payId: String, error: AddressPayIdVerifyAction.FailReason): AddressPayIDState { + return this.copy(etFieldValue = payId, error = error, walletAddress = null) + } +} data class FeeLayoutState( val visibility: Int = View.GONE, diff --git a/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt b/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt index 1879d895a8..94e0c1bc34 100644 --- a/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt @@ -3,6 +3,8 @@ package com.tangem.tap.features.send.ui import android.content.Intent import android.os.Bundle import android.view.View +import android.widget.EditText +import androidx.core.widget.addTextChangedListener import com.tangem.tap.common.extensions.getFromClipboard import com.tangem.tap.common.qrCodeScan.ScanQrCodeActivity import com.tangem.tap.features.send.BaseStoreFragment @@ -11,11 +13,17 @@ import com.tangem.tap.features.send.redux.FeeActionUI.* import com.tangem.tap.features.send.redux.ReleaseSendState import com.tangem.tap.features.send.ui.stateSubscribers.SendStateSubscriber import com.tangem.tap.features.send.ui.stateSubscribers.WalletStateSubscriber +import com.tangem.tap.mainScope import com.tangem.tap.store import com.tangem.wallet.R import kotlinx.android.synthetic.main.btn_paste.* import kotlinx.android.synthetic.main.btn_qr_code.* +import kotlinx.android.synthetic.main.layout_send_address_payid.* import kotlinx.android.synthetic.main.layout_send_network_fee.* +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.* + /** [REDACTED_AUTHOR] @@ -27,7 +35,6 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - flExpandCollapse.setOnClickListener { store.dispatch(ToggleFeeLayoutVisibility) } @@ -38,8 +45,14 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) { store.dispatch(ChangeIncludeFee(isChecked)) } + etAddressOrPayId.inputedTextAsFlow() + .debounce(400) + .filter { store.state.sendState.addressPayIDState.etFieldValue != it } + .onEach { store.dispatch(SetAddressOrPayId(it)) } + .launchIn(mainScope) + imvPaste.setOnClickListener { - store.dispatch(SetAddressOrPayId(requireContext().getFromClipboard())) + store.dispatch(SetAddressOrPayId(requireContext().getFromClipboard()?.toString() ?: "")) } imvQrCode.setOnClickListener { requireActivity().startActivity(Intent(requireContext(), ScanQrCodeActivity::class.java)) @@ -64,5 +77,11 @@ class SendFragment : BaseStoreFragment(R.layout.fragment_send) { } } +@ExperimentalCoroutinesApi +fun EditText.inputedTextAsFlow(): Flow = callbackFlow { + val watcher = addTextChangedListener { editable -> offer(editable?.toString() ?: "") } + awaitClose { removeTextChangedListener(watcher) } +} + 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 d86fe32991..12e4deee26 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 @@ -1,11 +1,14 @@ package com.tangem.tap.features.send.ui.stateSubscribers +import android.content.Context import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.transition.TransitionManager import com.tangem.tap.features.send.redux.AddressPayIDState +import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction.FailReason import com.tangem.tap.features.send.redux.FeeLayoutState import com.tangem.tap.features.send.redux.SendState +import com.tangem.wallet.R import kotlinx.android.synthetic.main.btn_expand_collapse.* import kotlinx.android.synthetic.main.layout_send_address_payid.* import kotlinx.android.synthetic.main.layout_send_network_fee.* @@ -23,7 +26,29 @@ class SendStateSubscriber(fragment: Fragment) : FragmentStateSubscriber R.string.error_payid_verification_failed + FailReason.PAY_ID_UNSUPPORTED_BY_BLOCKCHAIN -> R.string.error_payid_unsupported_by_blockchain + FailReason.PAY_ID_NOT_REGISTERED -> R.string.error_payid_not_registere + FailReason.PAY_ID_REQUEST_FAILED -> R.string.error_payid_request_failed + FailReason.ADDRESS_INVALID_OR_UNSUPPORTED_BY_BLOCKCHAIN -> R.string.error_address_invalid_or_unsupported + FailReason.ADDRESS_SAME_AS_WALLET -> R.string.error_address_same_as_wallet + else -> null + } + return if (resId == null) null + else context.getString(resId) + } + + val parsedError = parseError(fg.tilAddressOrPayId.context, state.error) + fg.tilAddressOrPayId.error = parsedError + fg.tilAddressOrPayId.isErrorEnabled = parsedError != null + fg.tilAddressOrPayId.helperText = state.walletAddress + fg.tilAddressOrPayId.isHelperTextEnabled = state.isPayIdState() && parsedError == null + if (fg.etAddressOrPayId.text?.toString() != state.etFieldValue) { + fg.etAddressOrPayId.setText(state.etFieldValue) + if (fg.etAddressOrPayId.isFocused) fg.etAddressOrPayId.setSelection(state.etFieldValue?.length ?: 0) + } } private fun handleFeeLayoutState(fg: Fragment, layoutState: FeeLayoutState) { diff --git a/app/src/main/java/com/tangem/tap/network/payid/PayIdVerifyApi.kt b/app/src/main/java/com/tangem/tap/network/payid/PayIdVerifyApi.kt new file mode 100644 index 0000000000..e026dd8b11 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/network/payid/PayIdVerifyApi.kt @@ -0,0 +1,44 @@ +package com.tangem.tap.network.payid + +import com.squareup.moshi.JsonClass +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Path + +/** +[REDACTED_AUTHOR] + */ +interface PayIdVerifyApi { + @GET("{user}") + suspend fun verifyAddress( + @Path("user") user: String, + @Header("Accept") acceptNetworkHeader: String, + @Header("PayID-Version") payIdVersion: String = "1.0" + ): VerifyPayIdResponse +} + + +@JsonClass(generateAdapter = true) +data class VerifyPayIdResponse( + val addresses: List = mutableListOf(), + val payId: String? = null, +) { + fun getAddress(): String? { + return if (addresses.isEmpty()) null + else addresses[0].addressDetails.address + } +} + +@JsonClass(generateAdapter = true) +data class PayIdAddress( + var paymentNetwork: String, + var environment: String, + var addressDetailsType: String, + var addressDetails: PayIdAddressDetails +) + +@JsonClass(generateAdapter = true) +data class PayIdAddressDetails( + var address: String, + var tag: String? = null +) \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/network/payid/PayIdVerifyService.kt b/app/src/main/java/com/tangem/tap/network/payid/PayIdVerifyService.kt new file mode 100644 index 0000000000..109dc5e97f --- /dev/null +++ b/app/src/main/java/com/tangem/tap/network/payid/PayIdVerifyService.kt @@ -0,0 +1,21 @@ +package com.tangem.tap.network.payid + +import com.tangem.commands.common.network.Result +import com.tangem.commands.common.network.performRequest +import com.tangem.tap.network.createRetrofitInstance + +/** +[REDACTED_AUTHOR] + */ +class PayIdVerifyService( + private val baseUrl: String +) { + + private val api = createRetrofitInstance(baseUrl).create(PayIdVerifyApi::class.java) + + suspend fun verifyAddress(user: String, network: String): Result { + return performRequest { api.verifyAddress(user, createNetworkHeader(network)) } + } + + private fun createNetworkHeader(network: String): String = "application/$network-mainnet+json" +} \ No newline at end of file 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 3f48a6131d..a399a74119 100644 --- a/app/src/main/res/layout/layout_send_address_payid.xml +++ b/app/src/main/res/layout/layout_send_address_payid.xml @@ -45,7 +45,7 @@ layout="@layout/btn_qr_code" android:layout_width="wrap_content" android:layout_height="wrap_content" - app:layout_constraintBottom_toBottomOf="@+id/tilAddressOrPayId" + android:layout_marginTop="16dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="@+id/tilAddressOrPayId" /> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9f30e32ccb..283438efc0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -33,6 +33,13 @@ This PayID already exists. Try a different one. Error response while creating PayID. + PayID verification failed + PayID unsupported by blockchain + PayID not registered + PayID request failed + Address is invalid or unsupported by blockchain + Address is invalid or unsupported by blockchain + Send Address or PayID