Updated on 2026-08-14
This commit is contained in:
commit
57b3776292
7 changed files with 94 additions and 35 deletions
|
|
@ -100,7 +100,7 @@ internal class BiometricUserWalletsListManager(
|
|||
} else {
|
||||
val isWalletSaved = state.value.userWallets
|
||||
.any {
|
||||
it.walletId == userWallet.walletId || it.cardsInWallet.contains(userWallet.cardId)
|
||||
it.walletId == userWallet.walletId
|
||||
}
|
||||
|
||||
if (isWalletSaved) {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import com.tangem.core.analytics.Analytics
|
|||
import com.tangem.tap.common.analytics.events.WalletConnect
|
||||
import com.tangem.tap.domain.walletconnect2.domain.WalletConnectRepository
|
||||
import com.tangem.tap.domain.walletconnect2.domain.WcJrpcRequestsDeserializer
|
||||
import com.tangem.tap.domain.walletconnect2.domain.WcRequest
|
||||
import com.tangem.tap.domain.walletconnect2.domain.models.*
|
||||
import com.walletconnect.android.Core
|
||||
import com.walletconnect.android.CoreClient
|
||||
|
|
@ -87,7 +88,10 @@ class WalletConnectRepositoryImpl @Inject constructor(
|
|||
|
||||
private fun defineWalletDelegate(): Web3Wallet.WalletDelegate {
|
||||
return object : Web3Wallet.WalletDelegate {
|
||||
override fun onSessionProposal(sessionProposal: Wallet.Model.SessionProposal) {
|
||||
override fun onSessionProposal(
|
||||
sessionProposal: Wallet.Model.SessionProposal,
|
||||
verifyContext: Wallet.Model.VerifyContext,
|
||||
) {
|
||||
// Triggered when wallet receives the session proposal sent by a Dapp
|
||||
Timber.d("sessionProposal: $sessionProposal")
|
||||
this@WalletConnectRepositoryImpl.sessionProposal = sessionProposal
|
||||
|
|
@ -106,7 +110,10 @@ class WalletConnectRepositoryImpl @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun onSessionRequest(sessionRequest: Wallet.Model.SessionRequest) {
|
||||
override fun onSessionRequest(
|
||||
sessionRequest: Wallet.Model.SessionRequest,
|
||||
verifyContext: Wallet.Model.VerifyContext,
|
||||
) {
|
||||
// Triggered when a Dapp sends SessionRequest to sign a transaction or a message
|
||||
Timber.d("sessionRequest: $sessionRequest")
|
||||
val request = wcRequestDeserializer.deserialize(
|
||||
|
|
@ -115,22 +122,38 @@ class WalletConnectRepositoryImpl @Inject constructor(
|
|||
)
|
||||
Timber.d("sessionRequestParsed: $request")
|
||||
|
||||
scope.launch {
|
||||
_events.emit(
|
||||
WalletConnectEvents.SessionRequest(
|
||||
request = request,
|
||||
chainId = sessionRequest.chainId,
|
||||
when (request) {
|
||||
is WcRequest.AddChain -> {
|
||||
// we can send approval automatically, because in WC 2.0 the list of chains is approved when
|
||||
// initial connection is established
|
||||
sendRequest(
|
||||
topic = sessionRequest.topic,
|
||||
id = sessionRequest.request.id,
|
||||
metaUrl = sessionRequest.peerMetaData?.url ?: "",
|
||||
metaName = sessionRequest.peerMetaData?.name ?: "",
|
||||
),
|
||||
)
|
||||
result = "",
|
||||
)
|
||||
}
|
||||
else ->
|
||||
scope.launch {
|
||||
_events.emit(
|
||||
WalletConnectEvents.SessionRequest(
|
||||
request = request,
|
||||
chainId = sessionRequest.chainId,
|
||||
topic = sessionRequest.topic,
|
||||
id = sessionRequest.request.id,
|
||||
metaUrl = sessionRequest.peerMetaData?.url ?: "",
|
||||
metaName = sessionRequest.peerMetaData?.name ?: "",
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAuthRequest(authRequest: Wallet.Model.AuthRequest) {
|
||||
override fun onAuthRequest(
|
||||
authRequest: Wallet.Model.AuthRequest,
|
||||
verifyContext: Wallet.Model.VerifyContext,
|
||||
) {
|
||||
// Triggered when Dapp / Requester makes an authorization request
|
||||
Timber.d("onAuthRequest: $authRequest")
|
||||
}
|
||||
|
||||
override fun onSessionDelete(sessionDelete: Wallet.Model.SessionDelete) {
|
||||
|
|
@ -174,6 +197,7 @@ class WalletConnectRepositoryImpl @Inject constructor(
|
|||
|
||||
override fun onError(error: Wallet.Model.Error) {
|
||||
// Triggered whenever there is an issue inside the SDK
|
||||
Timber.d("onError: $error")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
package com.tangem.tap.domain.walletconnect2.domain
|
||||
|
||||
import com.squareup.moshi.JsonAdapter
|
||||
import com.squareup.moshi.JsonClass
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.Types
|
||||
import com.squareup.moshi.*
|
||||
import com.tangem.datasource.di.SdkMoshi
|
||||
import com.tangem.tap.domain.walletconnect2.domain.models.binance.WCBinanceTxConfirmParam
|
||||
import com.tangem.tap.domain.walletconnect2.domain.models.binance.WcBinanceCancelOrder
|
||||
|
|
@ -24,6 +21,7 @@ enum class WcJrpcMethods(val code: String) {
|
|||
BNB_SIGN("bnb_sign"),
|
||||
BNB_TRANSACTION_CONFIRM("bnb_tx_confirmation"),
|
||||
SIGN_TRANSACTION("trust_signTransaction"),
|
||||
WALLET_ADD_ETHEREUM_CHAIN("wallet_addEthereumChain"),
|
||||
;
|
||||
|
||||
companion object {
|
||||
|
|
@ -33,13 +31,25 @@ enum class WcJrpcMethods(val code: String) {
|
|||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class WCSignTransaction(
|
||||
@Json(name = "network")
|
||||
val network: Int,
|
||||
|
||||
@Json(name = "transaction")
|
||||
val transaction: String,
|
||||
) : WcRequestData
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class WcAddChain(
|
||||
@Json(name = "chainId")
|
||||
val chainId: String,
|
||||
) : WcRequestData
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class WcEthereumSignMessage(
|
||||
@Json(name = "raw")
|
||||
val raw: List<String>,
|
||||
|
||||
@Json(name = "type")
|
||||
val type: WCSignType,
|
||||
) : WcRequestData {
|
||||
enum class WCSignType {
|
||||
|
|
@ -71,15 +81,34 @@ data class WcEthereumSignMessage(
|
|||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class WcEthereumTransaction(
|
||||
@Json(name = "from")
|
||||
val from: String,
|
||||
|
||||
@Json(name = "to")
|
||||
val to: String?,
|
||||
|
||||
@Json(name = "nonce")
|
||||
val nonce: String?,
|
||||
|
||||
@Json(name = "gasPrice")
|
||||
val gasPrice: String?,
|
||||
|
||||
@Json(name = "maxFeePerGas")
|
||||
val maxFeePerGas: String?,
|
||||
|
||||
@Json(name = "maxPriorityFeePerGas")
|
||||
val maxPriorityFeePerGas: String?,
|
||||
|
||||
@Json(name = "gas")
|
||||
val gas: String?,
|
||||
|
||||
@Json(name = "gasLimit")
|
||||
val gasLimit: String?,
|
||||
|
||||
@Json(name = "value")
|
||||
val value: String?,
|
||||
|
||||
@Json(name = "data")
|
||||
val data: String,
|
||||
) : WcRequestData
|
||||
|
||||
|
|
@ -96,6 +125,7 @@ sealed class WcRequest(open val data: WcRequestData) {
|
|||
data class BnbTransfer(override val data: WcBinanceTransferOrder) : WcRequest(data)
|
||||
data class BnbTxConfirm(override val data: WCBinanceTxConfirmParam) : WcRequest(data)
|
||||
data class SignTransaction(override val data: WCSignTransaction) : WcRequest(data)
|
||||
data class AddChain(override val data: WcAddChain) : WcRequest(data)
|
||||
data class CustomRequest(override val data: WcCustomRequestData) : WcRequest(data)
|
||||
}
|
||||
|
||||
|
|
@ -167,6 +197,12 @@ class WcJrpcRequestsDeserializer @Inject constructor(@SdkMoshi private val moshi
|
|||
).fromJsonFirstOrNull(params) ?: return customRequest
|
||||
WcRequest.SignTransaction(data = deserializedParams)
|
||||
}
|
||||
WcJrpcMethods.WALLET_ADD_ETHEREUM_CHAIN -> {
|
||||
val deserializedParams: WcAddChain = moshi.adapter<List<WcAddChain>>(
|
||||
Types.newParameterizedType(List::class.java, WcAddChain::class.java),
|
||||
).fromJsonFirstOrNull(params) ?: return customRequest
|
||||
WcRequest.AddChain(data = deserializedParams)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import com.tangem.common.services.Result
|
|||
import com.tangem.common.services.performRequest
|
||||
import com.tangem.datasource.api.common.createRetrofitInstance
|
||||
import com.tangem.domain.common.extensions.withIOContext
|
||||
import com.tangem.tap.common.extensions.urlEncode
|
||||
import com.tangem.tap.common.redux.global.CryptoCurrencyName
|
||||
import com.tangem.tap.features.wallet.models.Currency
|
||||
import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager
|
||||
|
|
@ -103,39 +102,37 @@ class MoonPayService(
|
|||
cryptoCurrencyName: CryptoCurrencyName,
|
||||
fatCurrency: String,
|
||||
walletAddress: String,
|
||||
): String? {
|
||||
): String {
|
||||
if (action == CurrencyExchangeManager.Action.Buy) throw UnsupportedOperationException()
|
||||
|
||||
val uri = Uri.Builder()
|
||||
.scheme(SCHEME)
|
||||
.authority(URL_SELL)
|
||||
.appendQueryParameter("apiKey", apiKey.urlEncode())
|
||||
.appendQueryParameter("baseCurrencyCode", cryptoCurrencyName.urlEncode())
|
||||
.appendQueryParameter("refundWalletAddress", walletAddress.urlEncode())
|
||||
.appendQueryParameter("redirectURL", "tangem://sell-request.tangem.com".urlEncode())
|
||||
.appendQueryParameter("apiKey", apiKey)
|
||||
.appendQueryParameter("baseCurrencyCode", cryptoCurrencyName)
|
||||
.appendQueryParameter("refundWalletAddress", walletAddress)
|
||||
.appendQueryParameter("redirectURL", "tangem://sell-request.tangem.com")
|
||||
|
||||
val originalQuery = uri.build().toString()
|
||||
val originalQuery = uri.build().encodedQuery ?: uri.build().toString()
|
||||
val signature = createSignature(originalQuery)
|
||||
uri.appendQueryParameter("signature", signature.urlEncode())
|
||||
uri.appendQueryParameter("signature", signature)
|
||||
|
||||
val url = uri.build().toString()
|
||||
return url
|
||||
return uri.build().toString()
|
||||
}
|
||||
|
||||
override fun getSellCryptoReceiptUrl(action: CurrencyExchangeManager.Action, transactionId: String): String? {
|
||||
val url = Uri.Builder()
|
||||
override fun getSellCryptoReceiptUrl(action: CurrencyExchangeManager.Action, transactionId: String): String {
|
||||
return Uri.Builder()
|
||||
.scheme(SCHEME)
|
||||
.authority(URL_SELL)
|
||||
.appendPath("transaction_receipt")
|
||||
.appendQueryParameter("transactionId", transactionId).build().toString()
|
||||
return url
|
||||
}
|
||||
|
||||
private fun createSignature(data: String): String {
|
||||
val sha256Hmac = Mac.getInstance("HmacSHA256")
|
||||
val secretKey = SecretKeySpec(secretKey.toByteArray(), "HmacSHA256")
|
||||
sha256Hmac.init(secretKey)
|
||||
val sha256encoded = sha256Hmac.doFinal(data.toByteArray())
|
||||
val sha256encoded = sha256Hmac.doFinal("?$data".toByteArray())
|
||||
return Base64.encodeToString(sha256encoded, Base64.NO_WRAP)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue