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

@ -138,8 +138,7 @@ class TapWalletManager {
loadMultiWalletData(data, blockchain, null)
}
}
val moonPayStatus = store.state.globalState.moonpayStatus
store.dispatch(WalletAction.LoadWallet(moonPayStatus))
store.dispatch(WalletAction.LoadWallet())
store.dispatch(WalletAction.LoadFiatRate())
}
}
@ -201,8 +200,7 @@ class TapWalletManager {
return@withContext
}
val moonPayStatus = store.state.globalState.moonpayStatus
store.dispatch(WalletAction.LoadWallet(moonPayStatus))
store.dispatch(WalletAction.LoadWallet())
store.dispatch(WalletAction.LoadFiatRate())
}
}

View file

@ -11,6 +11,7 @@ import com.tangem.tap.domain.configurable.Loader
data class Config(
val coinMarketCapKey: String = "f6622117-c043-47a0-8975-9d673ce484de",
val moonPayApiKey: String = "pk_test_kc90oYTANy7UQdBavDKGfL4K9l6VEPE",
val onramperApiKey: String = "pk_test_Ix2aCF3ej_5tcDKkBR7MChIvf5Nb0oPORPQ3Oal5G8I0",
val moonPayApiSecretKey: String = "sk_test_V8w4M19LbDjjYOt170s0tGuvXAgyEb1C",
val appsFlyerDevKey: String = "",
val blockchainSdkConfig: BlockchainSdkConfig = BlockchainSdkConfig(),
@ -81,6 +82,7 @@ class ConfigManager(
config = config.copy(
coinMarketCapKey = values.coinMarketCapKey,
moonPayApiKey = values.moonPayApiKey,
onramperApiKey = values.onramperApiKey,
moonPayApiSecretKey = values.moonPayApiSecretKey,
blockchainSdkConfig = BlockchainSdkConfig(
blockchairApiKey = values.blockchairApiKey,
@ -94,6 +96,7 @@ class ConfigManager(
defaultConfig = defaultConfig.copy(
coinMarketCapKey = values.coinMarketCapKey,
moonPayApiKey = values.moonPayApiKey,
onramperApiKey = values.onramperApiKey,
moonPayApiSecretKey = values.moonPayApiSecretKey,
blockchainSdkConfig = BlockchainSdkConfig(
blockchairApiKey = values.blockchairApiKey,

View file

@ -16,6 +16,7 @@ class FeatureModel(
class ConfigValueModel(
val coinMarketCapKey: String,
val moonPayApiKey: String,
val onramperApiKey: String,
val moonPayApiSecretKey: String,
val blockchairApiKey: String?,
val blockchairAuthorizationToken: String?,

View file

@ -2,13 +2,22 @@ package com.tangem.tap.domain.extensions
import com.tangem.blockchain.common.Blockchain
import com.tangem.tap.features.wallet.redux.Currency
import com.tangem.tap.network.moonpay.MoonpayStatus
import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager
import com.tangem.tap.network.exchangeServices.CurrencyExchangeStatus
import com.tangem.tap.store
/**
[REDACTED_AUTHOR]
*/
fun MoonpayStatus.buyIsAllowed(currency: Currency): Boolean {
fun CurrencyExchangeManager.buyIsAllowed(currency: Currency): Boolean {
return this.status?.buyIsAllowed(currency) ?: false
}
fun CurrencyExchangeManager.sellIsAllowed(currency: Currency): Boolean {
return this.status?.sellIsAllowed(currency) ?: false
}
fun CurrencyExchangeStatus.buyIsAllowed(currency: Currency): Boolean {
if (store.state.globalState.configManager?.config?.isTopUpEnabled == false) return false
if (!isBuyAllowed) return false
@ -25,16 +34,17 @@ fun MoonpayStatus.buyIsAllowed(currency: Currency): Boolean {
}
}
fun MoonpayStatus.sellIsAllowed(currency: Currency): Boolean {
fun CurrencyExchangeStatus.sellIsAllowed(currency: Currency): Boolean {
if (store.state.globalState.configManager?.config?.isTopUpEnabled == false) return false
if (!isSellAllowed) return false
return when (currency) {
is Currency.Blockchain -> {
if (currency.blockchain == Blockchain.Unknown || currency.blockchain == Blockchain.BSC) {
false
} else {
availableToSell.contains(currency.currencySymbol)
val blockchain = currency.blockchain
when {
blockchain.isTestnet() -> false
blockchain == Blockchain.Unknown || currency.blockchain == Blockchain.BSC -> false
else -> availableToSell.contains(currency.currencySymbol)
}
}
is Currency.Token -> false

View file

@ -1,46 +0,0 @@
package com.tangem.tap.domain.topup
import com.tangem.Message
import com.tangem.blockchain.blockchains.ethereum.EthereumWalletManager
import com.tangem.blockchain.common.Amount
import com.tangem.blockchain.common.AmountType
import com.tangem.blockchain.common.Token
import com.tangem.blockchain.extensions.Result
import com.tangem.tap.common.extensions.safeUpdate
import com.tangem.tap.common.redux.global.GlobalAction
import com.tangem.tap.domain.TangemSigner
import com.tangem.tap.store
import com.tangem.tap.tangemSdk
import java.math.BigDecimal
class TopUpManager {
suspend fun topUpTestErc20Tokens(walletManager: EthereumWalletManager, token: Token) {
walletManager.safeUpdate()
val amountToSend = Amount(walletManager.wallet.blockchain)
val destinationAddress = token.contractAddress
val feeResult = walletManager.getFee(amountToSend,
destinationAddress) as? Result.Success ?: return
val fee = feeResult.data[0]
if ((walletManager.wallet.amounts[AmountType.Coin]?.value ?: BigDecimal.ZERO) < fee.value) {
return
}
val transaction = walletManager.createTransaction(amountToSend, fee, destinationAddress)
val signer = TangemSigner(
tangemSdk = tangemSdk, Message()
) { signResponse ->
store.dispatch(
GlobalAction.UpdateWalletSignedHashes(
walletSignedHashes = signResponse.totalSignedHashes,
walletPublicKey = walletManager.wallet.publicKey.seedKey,
remainingSignatures = signResponse.remainingSignatures
)
)
}
walletManager.send(transaction, signer)
}
}

View file

@ -1,96 +0,0 @@
package com.tangem.tap.domain.topup
import android.net.Uri
import android.util.Base64
import com.tangem.blockchain.common.Blockchain
import com.tangem.tap.common.redux.global.CryptoCurrencyName
import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec
class TradeCryptoHelper {
companion object {
const val TRANSACTION_ID_PARAM = "transactionId"
const val CURRENCY_CODE_PARAM = "baseCurrencyCode"
const val CURRENCY_AMOUNT_PARAM = "baseCurrencyAmount"
const val DEPOSIT_WALLET_ADDRESS_PARAM = "depositWalletAddress"
private const val REDIRECT_URL_BUY = "tangem://success.tangem.com"
private const val REDIRECT_URL_SELL_REQUEST = "tangem://sell-request.tangem.com"
private const val BASE_URL_BUY =
"https://buy.moonpay.io"
// "https://buy-staging.moonpay.io" // TESTNET
private const val BASE_URL_SELL =
"https://sell.moonpay.com"
// "https://sell-staging.moonpay.com" // TESTNET
private const val API_KEY_PATH = "?apiKey="
private const val CURRENCY_PATH = "&currencyCode="
private const val WALLET_ADDRESS_PATH = "&walletAddress="
private const val REFUND_WALLET_ADDRESS_PATH = "&refundWalletAddress="
private const val BASE_CURRENCY_PATH = "&baseCurrencyCode="
private const val REDIRECT_URL_PATH = "&redirectURL="
private const val SIGNATURE_PATH = "&signature="
private const val TRANSACTION_RECEIPT_PATH = "transaction_receipt?transactionId="
private const val BASE_CURRENCY_USD = "USD"
fun getUrl(
action: Action,
blockchain: Blockchain?,
cryptoCurrencyName: CryptoCurrencyName,
walletAddress: String,
apiKey: String,
secretKey: String,
): String {
val originalQuery: String
val baseUrl: String
when (action) {
Action.Buy -> {
if (blockchain?.isTestnet() == true) {
return blockchain.getTestnetTopUpUrl() ?: ""
}
baseUrl = BASE_URL_BUY
originalQuery = API_KEY_PATH + apiKey.urlEncode() +
CURRENCY_PATH + cryptoCurrencyName.urlEncode() +
BASE_CURRENCY_PATH + BASE_CURRENCY_USD.urlEncode() +
WALLET_ADDRESS_PATH + walletAddress.urlEncode() +
REDIRECT_URL_PATH + REDIRECT_URL_BUY.urlEncode()
}
Action.Sell -> {
baseUrl = BASE_URL_SELL
originalQuery = API_KEY_PATH + apiKey.urlEncode() +
BASE_CURRENCY_PATH + cryptoCurrencyName.urlEncode() +
REFUND_WALLET_ADDRESS_PATH + walletAddress.urlEncode() +
REDIRECT_URL_PATH + REDIRECT_URL_SELL_REQUEST.urlEncode()
}
}
val signature = createSignature(originalQuery, secretKey)
return baseUrl + originalQuery + SIGNATURE_PATH + signature.urlEncode()
}
fun getSellCryptoReceiptUrl(transactionId: String): String {
return BASE_URL_SELL + TRANSACTION_RECEIPT_PATH + transactionId
}
private fun String.urlEncode(): String {
return Uri.encode(this)
}
private fun createSignature(data: String, key: String): String {
val sha256Hmac = Mac.getInstance("HmacSHA256")
val secretKey = SecretKeySpec(key.toByteArray(), "HmacSHA256")
sha256Hmac.init(secretKey)
val sha256encoded = sha256Hmac.doFinal(data.toByteArray())
return Base64.encodeToString(sha256encoded, Base64.NO_WRAP)
}
}
enum class Action { Buy, Sell }
}