Updated on 2026-08-14
This commit is contained in:
parent
c120acae62
commit
1ab4cdd170
10 changed files with 69 additions and 43 deletions
|
|
@ -4,6 +4,7 @@ import com.tangem.blockchain.common.Blockchain
|
|||
import com.tangem.blockchainsdk.utils.fromNetworkId
|
||||
import com.tangem.blockchainsdk.utils.toNetworkId
|
||||
import com.tangem.tap.domain.walletconnect2.domain.WcBlockchainHelper
|
||||
import com.tangem.tap.domain.walletconnect2.domain.models.Account
|
||||
import com.tangem.tap.domain.walletconnect2.toggles.WalletConnectFeatureToggles
|
||||
|
||||
internal class TangemWcBlockchainHelper(
|
||||
|
|
@ -35,11 +36,12 @@ internal class TangemWcBlockchainHelper(
|
|||
}
|
||||
}
|
||||
|
||||
override fun networkIdToChainIdOrNull(networkId: String): String? {
|
||||
override fun networkIdToChainIdOrNull(networkId: String): List<String> {
|
||||
val blockchain = Blockchain.fromNetworkId(networkId)
|
||||
val namespace = blockchain?.getCaip2Namespace() ?: return null
|
||||
val chainId = blockchain.getCaip2ChainId() ?: return null
|
||||
return "$namespace$CHAIN_SEPARATOR$chainId"
|
||||
val namespace = blockchain?.getCaip2Namespace() ?: return emptyList()
|
||||
return blockchain.getCaip2ChainIds().map {
|
||||
"$namespace$CHAIN_SEPARATOR$it"
|
||||
}
|
||||
}
|
||||
|
||||
override fun getNamespaceFromFullChainIdOrNull(chainId: String): String? {
|
||||
|
|
@ -52,8 +54,18 @@ internal class TangemWcBlockchainHelper(
|
|||
return Blockchain.fromNetworkId(networkId)?.fullName
|
||||
}
|
||||
|
||||
private fun Blockchain.getCaip2ChainId(): String? {
|
||||
if (this.isEvm()) return this.getChainId()?.toString()
|
||||
override fun chainIdsToAccounts(
|
||||
walletAddress: String,
|
||||
chainIds: List<String>,
|
||||
derivationPath: String?,
|
||||
): List<Account> {
|
||||
return chainIds.map { chainId ->
|
||||
Account(chainId, walletAddress, derivationPath)
|
||||
}
|
||||
}
|
||||
|
||||
private fun Blockchain.getCaip2ChainIds(): List<String> {
|
||||
if (this.isEvm()) return listOfNotNull(this.getChainId()?.toString())
|
||||
|
||||
return when (this) {
|
||||
/*
|
||||
|
|
@ -61,13 +73,12 @@ internal class TangemWcBlockchainHelper(
|
|||
* uncommented is used.
|
||||
* Docs: https://docs.walletconnect.com/advanced/multichain/chain-list
|
||||
*
|
||||
* Blockchain.Solana -> "5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"
|
||||
* */
|
||||
Blockchain.Solana -> "4sGjMW1sUnHzSxGspuhpqLDx6wiyjNtZ"
|
||||
Blockchain.SolanaTestnet -> "z4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z"
|
||||
Blockchain.Polkadot -> "91b171bb158e2d3848fa23a9f1c25182"
|
||||
Blockchain.Tron -> "0x2b6653dc"
|
||||
else -> null
|
||||
Blockchain.Solana -> listOf("5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp", "4sGjMW1sUnHzSxGspuhpqLDx6wiyjNtZ")
|
||||
Blockchain.SolanaTestnet -> listOf("z4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z")
|
||||
Blockchain.Polkadot -> listOf("91b171bb158e2d3848fa23a9f1c25182")
|
||||
Blockchain.Tron -> listOf("0x2b6653dc")
|
||||
else -> emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ class WalletConnectInteractor(
|
|||
private suspend fun setupUserChains(userWallet: UserWallet, currencies: List<CryptoCurrency>) {
|
||||
val accounts = getAccountsForWc(
|
||||
userWallet = userWallet,
|
||||
networks = currencies.map { it.network },
|
||||
networks = currencies.map { it.network }.distinct(),
|
||||
)
|
||||
setUserChains(accounts)
|
||||
handleDeeplinkStack(accounts)
|
||||
|
|
@ -403,18 +403,14 @@ class WalletConnectInteractor(
|
|||
derivationPath = it.derivationPath.value,
|
||||
)
|
||||
}
|
||||
return walletManagers.mapNotNull {
|
||||
return walletManagers.flatMap {
|
||||
val wallet = it.wallet
|
||||
val chainId = blockchainHelper.networkIdToChainIdOrNull(
|
||||
wallet.blockchain.toNetworkId(),
|
||||
val chainIds = blockchainHelper.networkIdToChainIdOrNull(wallet.blockchain.toNetworkId())
|
||||
blockchainHelper.chainIdsToAccounts(
|
||||
walletAddress = wallet.address,
|
||||
chainIds = chainIds,
|
||||
derivationPath = wallet.publicKey.derivationPath?.rawPath,
|
||||
)
|
||||
chainId?.let {
|
||||
Account(
|
||||
chainId,
|
||||
wallet.address,
|
||||
wallet.publicKey.derivationPath?.rawPath,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,17 @@
|
|||
package com.tangem.tap.domain.walletconnect2.domain
|
||||
|
||||
import com.tangem.tap.domain.walletconnect2.domain.models.Account
|
||||
|
||||
interface WcBlockchainHelper {
|
||||
fun chainIdToNetworkIdOrNull(chainId: String): String?
|
||||
|
||||
fun chainIdToMissingNetworkNameOrNull(chainId: String): String?
|
||||
|
||||
fun networkIdToChainIdOrNull(networkId: String): String?
|
||||
fun networkIdToChainIdOrNull(networkId: String): List<String>
|
||||
|
||||
fun getNamespaceFromFullChainIdOrNull(chainId: String): String?
|
||||
|
||||
fun chainIdToFullNameOrNull(chainId: String): String?
|
||||
|
||||
fun chainIdsToAccounts(walletAddress: String, chainIds: List<String>, derivationPath: String?): List<Account>
|
||||
}
|
||||
|
|
@ -223,14 +223,14 @@ internal class WcJrpcRequestsDeserializer @Inject constructor(@SdkMoshi private
|
|||
WcRequest.AddChain(data = deserializedParams)
|
||||
}
|
||||
WcJrpcMethods.SOLANA_SIGN_TX -> {
|
||||
val tx = moshi.adapter<SolanaTransactionRequest>(SolanaTransactionRequest::class.java)
|
||||
val tx = moshi.adapter(SolanaTransactionRequest::class.java)
|
||||
.fromJsonOrNull(params)
|
||||
?: return customRequest
|
||||
|
||||
WcRequest.SolanaSignRequest(data = tx)
|
||||
}
|
||||
WcJrpcMethods.SOLANA_SIGN_MESSAGE -> {
|
||||
val signMessage = moshi.adapter<SolanaSignMessage>(SolanaSignMessage::class.java)
|
||||
val signMessage = moshi.adapter(SolanaSignMessage::class.java)
|
||||
.fromJsonOrNull(params)
|
||||
?: return customRequest
|
||||
val data = WcSignMessage(
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
package com.tangem.tap.domain.walletconnect2.domain
|
||||
|
||||
import com.tangem.tap.domain.walletconnect.WalletConnectSdkHelper
|
||||
import com.tangem.tap.domain.walletconnect2.domain.mapper.mapToTransaction
|
||||
import com.tangem.tap.domain.walletconnect2.domain.models.BnbData
|
||||
import com.tangem.tap.domain.walletconnect2.domain.models.EthTransactionData
|
||||
import com.tangem.tap.domain.walletconnect2.domain.models.WalletConnectError
|
||||
import com.tangem.tap.domain.walletconnect2.domain.models.WalletConnectEvents
|
||||
import com.tangem.tap.features.details.redux.walletconnect.WcEthTransactionType
|
||||
import okio.ByteString.Companion.decodeBase64
|
||||
|
||||
internal class WcSessionRequestConverter(
|
||||
private val blockchainHelper: WcBlockchainHelper,
|
||||
|
|
@ -115,11 +115,11 @@ internal class WcSessionRequestConverter(
|
|||
)
|
||||
}
|
||||
is WcRequest.SolanaSignRequest -> {
|
||||
val data = request.data.mapToTransaction()
|
||||
val transaction = request.data.transaction
|
||||
|
||||
WcPreparedRequest.SignTransaction(
|
||||
preparedRequestData = WcGenericTransactionData(
|
||||
hashToSign = data.getSerializedMessage(),
|
||||
hashToSign = transaction.prepareSolanaTransaction(),
|
||||
dAppName = sessionRequest.metaName,
|
||||
type = TransactionType.SOLANA_TX,
|
||||
),
|
||||
|
|
@ -132,6 +132,16 @@ internal class WcSessionRequestConverter(
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Input transaction in Base64 string
|
||||
*/
|
||||
private fun String.prepareSolanaTransaction(): ByteArray {
|
||||
return this.decodeBase64()
|
||||
?.toByteArray()
|
||||
?.drop(SOLANA_SIGNATURE_PLACEHOLDER_LENGTH)
|
||||
?.toByteArray() ?: ByteArray(0)
|
||||
}
|
||||
|
||||
private fun getWalletAddress(request: WcRequest): String? {
|
||||
return when (request) {
|
||||
is WcRequest.BnbTrade -> request.data.accountNumber
|
||||
|
|
@ -156,4 +166,8 @@ internal class WcSessionRequestConverter(
|
|||
it.chainId == sessionRequest.chainId && it.walletAddress.lowercase() == walletAddress?.lowercase()
|
||||
}?.derivationPath
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val SOLANA_SIGNATURE_PLACEHOLDER_LENGTH = 65
|
||||
}
|
||||
}
|
||||
|
|
@ -14,6 +14,9 @@ data class SolanaTransactionRequest(
|
|||
|
||||
@Json(name = "instructions")
|
||||
val instructions: List<Instruction>,
|
||||
|
||||
@Json(name = "transaction")
|
||||
val transaction: String,
|
||||
) : WcRequestData {
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
|
|
@ -22,7 +25,7 @@ data class SolanaTransactionRequest(
|
|||
val programId: String,
|
||||
|
||||
@Json(name = "data")
|
||||
val data: List<Byte>,
|
||||
val data: String,
|
||||
|
||||
@Json(name = "keys")
|
||||
val keys: List<Key>,
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import com.tangem.tap.common.redux.global.GlobalAction
|
|||
import com.tangem.tap.domain.walletconnect2.domain.LegacyWalletConnectRepository
|
||||
import com.tangem.tap.domain.walletconnect2.domain.WalletConnectInteractor
|
||||
import com.tangem.tap.domain.walletconnect2.domain.WcPreparedRequest
|
||||
import com.tangem.tap.domain.walletconnect2.domain.models.Account
|
||||
import com.tangem.tap.domain.walletconnect2.domain.models.WalletConnectError
|
||||
import com.tangem.tap.features.demo.DemoHelper
|
||||
import com.tangem.tap.proxy.redux.DaggerGraphState
|
||||
|
|
@ -87,18 +86,16 @@ class WalletConnectMiddleware {
|
|||
is WalletConnectAction.ApproveProposal -> {
|
||||
scope.launch {
|
||||
val accounts = getWalletManagers()
|
||||
.mapNotNull {
|
||||
.flatMap {
|
||||
val wallet = it.wallet
|
||||
val chainId = walletConnectInteractor.blockchainHelper.networkIdToChainIdOrNull(
|
||||
val chainIds = walletConnectInteractor.blockchainHelper.networkIdToChainIdOrNull(
|
||||
wallet.blockchain.toNetworkId(),
|
||||
)
|
||||
chainId?.let {
|
||||
Account(
|
||||
chainId,
|
||||
wallet.address,
|
||||
wallet.publicKey.derivationPath?.rawPath,
|
||||
)
|
||||
}
|
||||
walletConnectInteractor.blockchainHelper.chainIdsToAccounts(
|
||||
walletAddress = wallet.address,
|
||||
chainIds = chainIds,
|
||||
derivationPath = wallet.publicKey.derivationPath?.rawPath,
|
||||
)
|
||||
}
|
||||
walletConnectInteractor.approveSessionProposal(accounts)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue