Updated on 2026-08-14

This commit is contained in:
Tangem 2022-03-03 09:38:35 +03:00
parent 0041c0b7e5
commit b4ab6e480e
29 changed files with 669 additions and 387 deletions

View file

@ -5,7 +5,6 @@ import android.nfc.NfcAdapter
import android.nfc.Tag
import com.tangem.tap.common.redux.navigation.AppScreen
import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.domain.topup.TradeCryptoHelper
import com.tangem.tap.domain.walletconnect.WalletConnectManager
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction
import com.tangem.tap.features.home.redux.HomeAction
@ -15,6 +14,11 @@ import timber.log.Timber
class IntentHandler {
private val TRANSACTION_ID_PARAM = "transactionId"
private val CURRENCY_CODE_PARAM = "baseCurrencyCode"
private val CURRENCY_AMOUNT_PARAM = "baseCurrencyAmount"
private val DEPOSIT_WALLET_ADDRESS_PARAM = "depositWalletAddress"
fun handleIntent(intent: Intent?) {
handleBackgroundScan(intent)
handleWalletConnectLink(intent)
@ -23,8 +27,8 @@ class IntentHandler {
private fun handleBackgroundScan(intent: Intent?) {
if (intent != null && (NfcAdapter.ACTION_TECH_DISCOVERED == intent.action ||
NfcAdapter.ACTION_NDEF_DISCOVERED == intent.action
)
NfcAdapter.ACTION_NDEF_DISCOVERED == intent.action
)
) {
val tag = intent.getParcelableExtra<Tag>(NfcAdapter.EXTRA_TAG)
if (tag != null) {
@ -45,13 +49,13 @@ class IntentHandler {
private fun handleSellCurrencyCallback(intent: Intent?) {
try {
val transactionID =
intent?.data?.getQueryParameter(TradeCryptoHelper.TRANSACTION_ID_PARAM) ?: return
intent?.data?.getQueryParameter(TRANSACTION_ID_PARAM) ?: return
val currency =
intent.data?.getQueryParameter(TradeCryptoHelper.CURRENCY_CODE_PARAM) ?: return
intent.data?.getQueryParameter(CURRENCY_CODE_PARAM) ?: return
val amount =
intent.data?.getQueryParameter(TradeCryptoHelper.CURRENCY_AMOUNT_PARAM) ?: return
intent.data?.getQueryParameter(CURRENCY_AMOUNT_PARAM) ?: return
val destinationAddress =
intent.data?.getQueryParameter(TradeCryptoHelper.DEPOSIT_WALLET_ADDRESS_PARAM)
intent.data?.getQueryParameter(DEPOSIT_WALLET_ADDRESS_PARAM)
?: return
Timber.d("MoonPay Sell: $amount $currency to $destinationAddress")
@ -63,7 +67,7 @@ class IntentHandler {
transactionId = transactionID
))
} catch (exception: Exception) {
Timber.d("Not Moonpay URL")
Timber.d("Not MoonPay URL")
}
}

View file

@ -3,6 +3,7 @@ package com.tangem.tap.common.extensions
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Color
import android.net.Uri
import android.text.Spannable
import android.text.style.ForegroundColorSpan
import androidx.core.content.ContextCompat
@ -21,24 +22,24 @@ fun String?.ellipsizeBeforeSpace(allowedSize: Int): String {
val startIndex = endIndex - sizeDifference
val newString = this.removeRange(startIndex, endIndex)
return newString.substring(0 until startIndex) + "..." +
newString.substring(startIndex until newString.length)
newString.substring(startIndex until newString.length)
}
fun String.colorSegment(
context: Context,
color: Int,
startIndex: Int = 0,
endIndex: Int = this.length
context: Context,
color: Int,
startIndex: Int = 0,
endIndex: Int = this.length
): Spannable {
return this.toSpannable()
.also { spannable ->
spannable.setSpan(
ForegroundColorSpan(ContextCompat.getColor(context, color)),
startIndex,
endIndex,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
}
.also { spannable ->
spannable.setSpan(
ForegroundColorSpan(ContextCompat.getColor(context, color)),
startIndex,
endIndex,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
}
}
fun String.toQrCode(): Bitmap {
@ -59,4 +60,6 @@ fun String.toQrCode(): Bitmap {
}
}
return bmp
}
}
fun String.urlEncode(): String = Uri.encode(this)

View file

@ -7,11 +7,11 @@ import com.tangem.common.services.Result
import com.tangem.tap.domain.TapError
import com.tangem.tap.domain.extensions.amountToCreateAccount
import com.tangem.tap.domain.getFirstToken
import com.tangem.tap.domain.topup.TradeCryptoHelper
import com.tangem.tap.features.demo.isDemoWallet
import com.tangem.tap.features.wallet.redux.AddressData
import com.tangem.tap.features.wallet.redux.reducers.createAddressesData
import com.tangem.tap.network.NetworkConnectivity
import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager
import com.tangem.tap.store
import timber.log.Timber
@ -44,17 +44,17 @@ suspend fun WalletManager.safeUpdate(): Result<Wallet> = try {
}
fun WalletManager?.getToUpUrl(): String? {
val globalState = store.state.globalState
val currencyExchangeManager = globalState.currencyExchangeManager ?: return null
val wallet = this?.wallet ?: return null
val config = store.state.globalState.configManager?.config ?: return null
val defaultAddress = wallet.address
return TradeCryptoHelper.getUrl(
TradeCryptoHelper.Action.Buy,
wallet.blockchain,
wallet.blockchain.currency,
defaultAddress,
config.moonPayApiKey,
config.moonPayApiSecretKey
val defaultAddress = wallet.address
return currencyExchangeManager.getUrl(
action = CurrencyExchangeManager.Action.Buy,
blockchain = wallet.blockchain,
cryptoCurrencyName = wallet.blockchain.currency,
fiatCurrency = globalState.appCurrency,
walletAddress = defaultAddress,
)
}

View file

@ -14,7 +14,7 @@ import com.tangem.tap.domain.tasks.product.ScanResponse
import com.tangem.tap.features.details.redux.SecurityOption
import com.tangem.tap.features.feedback.EmailData
import com.tangem.tap.features.feedback.FeedbackManager
import com.tangem.tap.network.moonpay.MoonpayStatus
import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager
import org.rekotlin.Action
sealed class GlobalAction : Action {
@ -76,7 +76,7 @@ sealed class GlobalAction : Action {
data class SendFeedback(val emailData: EmailData) : GlobalAction()
data class UpdateFeedbackInfo(val walletManagers: List<WalletManager>) : GlobalAction()
object GetMoonPayStatus : GlobalAction() {
data class Success(val moonPayStatus: MoonpayStatus) : GlobalAction()
object InitCurrencyExchangeManager : GlobalAction() {
data class Success(val exchangeManager: CurrencyExchangeManager) : GlobalAction()
}
}

View file

@ -2,7 +2,7 @@ package com.tangem.tap.common.redux.global
import com.tangem.common.CompletionResult
import com.tangem.common.core.TangemSdkError
import com.tangem.common.services.Result
import com.tangem.common.extensions.ifNotNull
import com.tangem.tap.*
import com.tangem.tap.common.extensions.dispatchDialogShow
import com.tangem.tap.common.extensions.dispatchOnMain
@ -12,10 +12,11 @@ import com.tangem.tap.common.redux.AppState
import com.tangem.tap.domain.configurable.warningMessage.WarningMessagesManager
import com.tangem.tap.features.send.redux.SendAction
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.network.moonpay.MoonpayService
import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager
import com.tangem.tap.network.exchangeServices.moonpay.MoonPayService
import com.tangem.tap.network.exchangeServices.onramper.OnramperService
import kotlinx.coroutines.launch
import org.rekotlin.Middleware
import timber.log.Timber
class GlobalMiddleware {
companion object {
@ -69,19 +70,21 @@ private val globalMiddlewareHandler: Middleware<AppState> = { dispatch, appState
}
is GlobalAction.UpdateFeedbackInfo -> {
store.state.globalState.feedbackManager?.infoHolder
?.setWalletsInfo(action.walletManagers)
?.setWalletsInfo(action.walletManagers)
}
is GlobalAction.GetMoonPayStatus -> {
val apiKey = appState()?.globalState?.configManager?.config?.moonPayApiKey
if (apiKey != null) {
is GlobalAction.InitCurrencyExchangeManager -> {
val config = appState()?.globalState?.configManager?.config
ifNotNull(
config?.onramperApiKey,
config?.moonPayApiKey,
config?.moonPayApiSecretKey,
) { onramperKey, moonPayKey, moonPaySecretKey ->
scope.launch {
val result = MoonpayService().getMoonpayStatus(apiKey)
when (result) {
is Result.Success -> {
store.dispatchOnMain(GlobalAction.GetMoonPayStatus.Success(result.data))
}
is Result.Failure -> Timber.e(result.error)
}
val onramper = OnramperService(onramperKey)
val moonPay = MoonPayService(moonPayKey, moonPaySecretKey)
val exchangeManager = CurrencyExchangeManager(onramper, moonPay)
exchangeManager.getStatus()
store.dispatchOnMain(GlobalAction.InitCurrencyExchangeManager.Success(exchangeManager))
}
}
}

View file

@ -2,7 +2,6 @@ package com.tangem.tap.common.redux.global
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.features.onboarding.OnboardingManager
import com.tangem.tap.network.moonpay.MoonpayStatus
import com.tangem.tap.preferencesStorage
import org.rekotlin.Action
@ -19,7 +18,7 @@ fun globalReducer(action: Action, state: AppState): GlobalState {
is GlobalAction.Onboarding.Start -> {
val onboardingManager = if (action.scanResponse != null) {
val usedCardsPrefStorage = preferencesStorage.usedCardsPrefStorage
OnboardingManager(action.scanResponse, usedCardsPrefStorage)
OnboardingManager(action.scanResponse, usedCardsPrefStorage)
} else {
null
}
@ -67,19 +66,8 @@ fun globalReducer(action: Action, state: AppState): GlobalState {
is GlobalAction.HideDialog -> {
globalState.copy(dialog = null)
}
is GlobalAction.GetMoonPayStatus.Success -> {
val fiatExchangeIsEnabled = globalState.configManager?.config?.isTopUpEnabled ?: false
val moonpayStatus = if (fiatExchangeIsEnabled) {
action.moonPayStatus
} else {
MoonpayStatus(
isBuyAllowed = false,
isSellAllowed = false,
availableToBuy = emptyList(),
availableToSell = emptyList()
)
}
globalState.copy(moonpayStatus = moonpayStatus)
is GlobalAction.InitCurrencyExchangeManager.Success -> {
globalState.copy(currencyExchangeManager = action.exchangeManager)
}
is GlobalAction.SetIfCardVerifiedOnline ->
globalState.copy(cardVerifiedOnline = action.verified)

View file

@ -11,7 +11,7 @@ import com.tangem.tap.domain.tasks.product.ScanResponse
import com.tangem.tap.features.feedback.FeedbackManager
import com.tangem.tap.features.onboarding.OnboardingManager
import com.tangem.tap.network.coinmarketcap.CoinMarketCapService
import com.tangem.tap.network.moonpay.MoonpayStatus
import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager
import org.rekotlin.StateType
data class GlobalState(
@ -27,7 +27,7 @@ data class GlobalState(
val appCurrency: FiatCurrencyName = DEFAULT_FIAT_CURRENCY,
val scanCardFailsCounter: Int = 0,
val dialog: StateDialog? = null,
val moonpayStatus: MoonpayStatus? = null,
val currencyExchangeManager: CurrencyExchangeManager? = null,
val resources: AndroidResources = AndroidResources(),
val analyticsHandlers: AnalyticsHandler? = null,
) : StateType