Updated on 2026-08-14
This commit is contained in:
parent
80d4eeaed9
commit
e2bdc12ed8
24 changed files with 696 additions and 169 deletions
|
|
@ -0,0 +1,14 @@
|
|||
package com.tangem.domain.walletconnect.model
|
||||
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
|
||||
sealed interface WcNetwork {
|
||||
|
||||
val name: String
|
||||
|
||||
data class Supported(val network: Network) : WcNetwork {
|
||||
override val name: String get() = network.name
|
||||
}
|
||||
|
||||
data class Unknown(override val name: String) : WcNetwork
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package com.tangem.domain.walletconnect.model
|
||||
|
||||
sealed class WcPairError(override val message: String) : Exception(message) {
|
||||
|
||||
data object UnsupportedDApp : WcPairError("UnsupportedDApp")
|
||||
data class UnsupportedNetworks(
|
||||
val chains: Set<WcNetwork.Unknown>,
|
||||
) : WcPairError("ApprovalErrorMissingNetworks")
|
||||
|
||||
data class ExternalApprovalError(
|
||||
override val message: String,
|
||||
) : WcPairError("ExternalApprovalError")
|
||||
|
||||
data class Unknown(override val message: String) : WcPairError(message)
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.tangem.domain.walletconnect.model
|
||||
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
|
||||
data class WcSessionApprove(
|
||||
val walletId: UserWalletId,
|
||||
val network: List<WcNetwork.Supported>,
|
||||
)
|
||||
|
|
@ -1,15 +1,19 @@
|
|||
package com.tangem.domain.walletconnect.model
|
||||
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
import com.tangem.domain.walletconnect.model.sdkcopy.WcSdkSessionProposal
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.walletconnect.model.sdkcopy.WcAppMetaData
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
|
||||
data class WcSessionProposal(
|
||||
val dAppInfo: WcSdkSessionProposal,
|
||||
val dAppMetaData: WcAppMetaData,
|
||||
val proposalNetwork: Map<UserWalletId, ProposalNetwork>,
|
||||
val securityStatus: Any,
|
||||
) {
|
||||
|
||||
// todo(wc) should map for all user wallets?
|
||||
val wallet: UserWallet,
|
||||
val missingChains: List<Network>,
|
||||
val availableChains: List<Network>,
|
||||
val notAddedChains: List<Network>,
|
||||
)
|
||||
data class ProposalNetwork(
|
||||
val walletId: UserWalletId,
|
||||
val missingRequired: Set<WcNetwork.Supported>,
|
||||
val required: Set<WcNetwork.Supported>,
|
||||
val available: Set<WcNetwork.Supported>,
|
||||
val notAdded: Set<WcNetwork.Supported>,
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package com.tangem.domain.walletconnect.model.sdkcopy
|
||||
|
||||
/**
|
||||
* copy of [com.reown.android.Core.Model.AppMetaData]
|
||||
*/
|
||||
data class WcAppMetaData(
|
||||
val name: String,
|
||||
val description: String,
|
||||
val url: String,
|
||||
val icons: List<String>,
|
||||
val redirect: String?,
|
||||
val appLink: String? = null,
|
||||
val linkMode: Boolean = false,
|
||||
val verifyUrl: String? = null,
|
||||
)
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
package com.tangem.domain.walletconnect.request
|
||||
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.adapter
|
||||
import com.tangem.domain.walletconnect.model.WcMethod
|
||||
import com.tangem.domain.walletconnect.model.WcRequest
|
||||
|
||||
interface WcRequestHandler<M : WcMethod> {
|
||||
fun canHandle(methodName: String): Boolean
|
||||
fun deserialize(methodName: String, params: String): M?
|
||||
fun handle(wcRequest: WcRequest<M>)
|
||||
|
||||
companion object {
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
inline fun <reified T> fromJson(params: String, moshi: Moshi): T? =
|
||||
runCatching { moshi.adapter<T>().fromJsonValue(params) }.getOrNull()
|
||||
}
|
||||
}
|
||||
|
|
@ -3,5 +3,5 @@ package com.tangem.domain.walletconnect.usecase
|
|||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface WcUseCasesFlowProvider {
|
||||
val flow: Flow<WcUseCase>
|
||||
val useCases: Flow<WcUseCase>
|
||||
}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
package com.tangem.domain.walletconnect.usecase.ethereum
|
||||
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.tangem.domain.walletconnect.model.WcRequest
|
||||
import com.tangem.domain.walletconnect.request.WcRequestHandler
|
||||
import com.tangem.domain.walletconnect.respond.WcRespondService
|
||||
import com.tangem.domain.walletconnect.usecase.WcUseCase
|
||||
import com.tangem.domain.walletconnect.usecase.WcUseCasesFlowProvider
|
||||
import com.tangem.domain.walletconnect.usecase.ethereum.WcEthMethod.SignMessage
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.receiveAsFlow
|
||||
|
||||
@Suppress("UnusedPrivateClass") // todo(wc) remove later
|
||||
private class WcEthChain(
|
||||
val moshi: Moshi,
|
||||
private val respondService: WcRespondService,
|
||||
) : WcRequestHandler<WcEthMethod>, WcUseCasesFlowProvider {
|
||||
|
||||
private val _flow: Channel<WcUseCase> = Channel(Channel.BUFFERED)
|
||||
override val flow = _flow.receiveAsFlow()
|
||||
|
||||
override fun canHandle(methodName: String): Boolean {
|
||||
return Name.entries.find { it.raw == methodName } != null
|
||||
}
|
||||
|
||||
override fun deserialize(methodName: String, params: String): WcEthMethod? {
|
||||
val name = Name.entries.find { it.raw == methodName } ?: return null
|
||||
return when (name) {
|
||||
Name.Sign -> TODO()
|
||||
Name.PersonalSign -> WcRequestHandler.fromJson<SignMessage>(params, moshi)
|
||||
Name.SignTypeData -> TODO()
|
||||
Name.SignTypeDataV4 -> TODO()
|
||||
Name.SignTransaction -> TODO()
|
||||
Name.SendTransaction -> TODO()
|
||||
}
|
||||
}
|
||||
|
||||
override fun handle(wcRequest: WcRequest<WcEthMethod>) {
|
||||
val useCase = when (wcRequest.method) {
|
||||
is SignMessage -> EthPersonalSignUseCase(wcRequest as WcRequest<SignMessage>, respondService)
|
||||
}
|
||||
_flow.trySend(useCase)
|
||||
}
|
||||
|
||||
enum class Name(val raw: String) {
|
||||
Sign("eth_sign"),
|
||||
PersonalSign("personal_sign"),
|
||||
SignTypeData("eth_signTypedData"),
|
||||
SignTypeDataV4("eth_signTypedData_v4"),
|
||||
SignTransaction("eth_signTransaction"),
|
||||
SendTransaction("eth_sendTransaction"),
|
||||
}
|
||||
}
|
||||
|
|
@ -1,24 +1,23 @@
|
|||
package com.tangem.domain.walletconnect.usecase.pair
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.domain.walletconnect.model.WcPairError
|
||||
import com.tangem.domain.walletconnect.model.WcSession
|
||||
import com.tangem.domain.walletconnect.model.WcSessionApprove
|
||||
import com.tangem.domain.walletconnect.model.WcSessionProposal
|
||||
|
||||
sealed interface WcPairState {
|
||||
data object Loading : WcPairState
|
||||
data class Error(val throwable: Throwable) : WcPairState
|
||||
data class Proposal(
|
||||
val dAppSession: WcSessionProposal,
|
||||
val securityStatus: Any,
|
||||
) : WcPairState
|
||||
data class Error(val error: WcPairError) : WcPairState
|
||||
data class Proposal(val dAppSession: WcSessionProposal) : WcPairState
|
||||
|
||||
sealed interface Approving : WcPairState {
|
||||
val session: WcSessionProposal
|
||||
val session: WcSessionApprove
|
||||
|
||||
data class Loading(override val session: WcSessionProposal) : Approving
|
||||
data class Loading(override val session: WcSessionApprove) : Approving
|
||||
data class Result(
|
||||
override val session: WcSessionProposal,
|
||||
val result: Either<Throwable, WcSession>,
|
||||
override val session: WcSessionApprove,
|
||||
val result: Either<WcPairError, WcSession>,
|
||||
) : Approving
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.domain.walletconnect.usecase.pair
|
||||
|
||||
import com.tangem.domain.walletconnect.model.WcSessionProposal
|
||||
import com.tangem.domain.walletconnect.model.WcSessionApprove
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
|
|
@ -8,12 +8,7 @@ interface WcPairUseCase {
|
|||
|
||||
fun pairFlow(uri: String, source: Source, selectedWallet: UserWallet): Flow<WcPairState>
|
||||
|
||||
// todo(wc) should map for all user wallets without this action in domain layer?
|
||||
fun onWalletSelect(selectedWallet: UserWallet)
|
||||
// todo(wc) accounts in future?
|
||||
fun onAccountSelect(account: Any)
|
||||
|
||||
fun approve(sessionForApprove: WcSessionProposal)
|
||||
fun approve(sessionForApprove: WcSessionApprove)
|
||||
fun reject()
|
||||
|
||||
enum class Source { QR, DEEPLINK, ETC }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue