Updated on 2026-08-14
This commit is contained in:
parent
2322038300
commit
35c41329bf
5 changed files with 86 additions and 34 deletions
|
|
@ -1,23 +1,18 @@
|
|||
package com.tangem.tap.di.hot
|
||||
|
||||
import android.content.Context
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.tangem.hot.sdk.TangemHotSdk
|
||||
import com.tangem.hot.sdk.android.create
|
||||
import com.tangem.tap.features.hot.TangemHotSDKProxy
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.components.ActivityComponent
|
||||
import dagger.hilt.android.qualifiers.ActivityContext
|
||||
import dagger.hilt.android.scopes.ActivityScoped
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(ActivityComponent::class)
|
||||
internal object TangemHotSdkModule {
|
||||
@InstallIn(SingletonComponent::class)
|
||||
internal interface TangemHotSdkModule {
|
||||
|
||||
@Provides
|
||||
@ActivityScoped
|
||||
fun provideRootAppComponentContext(@ActivityContext context: Context): TangemHotSdk {
|
||||
return TangemHotSdk.create(context as AppCompatActivity)
|
||||
}
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindTangemHotSdk(proxy: TangemHotSDKProxy): TangemHotSdk
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package com.tangem.tap.features.hot
|
||||
|
||||
import com.tangem.crypto.bip39.Mnemonic
|
||||
import com.tangem.hot.sdk.TangemHotSdk
|
||||
import com.tangem.hot.sdk.model.*
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.filterNotNull
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.withTimeout
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
* Proxy for [TangemHotSdk] to allow lazy initialization and provide a way to access the SDK state from domain layer.
|
||||
* SDK is initialized in the [com.tangem.tap.routing.component.RoutingComponent] and can be accessed through this proxy.
|
||||
* Be aware that the SDK is initialized on activity creation, so it may not be available immediately.
|
||||
*/
|
||||
@Singleton
|
||||
class TangemHotSDKProxy @Inject constructor() : TangemHotSdk {
|
||||
|
||||
val sdkState = MutableStateFlow<TangemHotSdk?>(null)
|
||||
|
||||
override suspend fun importWallet(mnemonic: Mnemonic, passphrase: CharArray?, auth: HotAuth): HotWalletId =
|
||||
callSdk { importWallet(mnemonic, passphrase, auth) }
|
||||
|
||||
override suspend fun generateWallet(auth: HotAuth, mnemonicType: MnemonicType): HotWalletId =
|
||||
callSdk { generateWallet(auth, mnemonicType) }
|
||||
|
||||
override suspend fun exportMnemonic(unlockHotWallet: UnlockHotWallet): SeedPhrasePrivateInfo =
|
||||
callSdk { exportMnemonic(unlockHotWallet) }
|
||||
|
||||
override suspend fun exportBackup(unlockHotWallet: UnlockHotWallet): ByteArray =
|
||||
callSdk { exportBackup(unlockHotWallet) }
|
||||
|
||||
override suspend fun delete(id: HotWalletId) = callSdk { delete(id) }
|
||||
|
||||
override suspend fun changeAuth(unlockHotWallet: UnlockHotWallet, auth: HotAuth): HotWalletId =
|
||||
callSdk { changeAuth(unlockHotWallet, auth) }
|
||||
|
||||
override suspend fun derivePublicKey(
|
||||
unlockHotWallet: UnlockHotWallet,
|
||||
request: DeriveWalletRequest,
|
||||
): DerivedPublicKeyResponse = callSdk { derivePublicKey(unlockHotWallet, request) }
|
||||
|
||||
override suspend fun signHashes(unlockHotWallet: UnlockHotWallet, dataToSign: List<DataToSign>): List<SignedData> =
|
||||
callSdk { signHashes(unlockHotWallet, dataToSign) }
|
||||
|
||||
private suspend fun <T> callSdk(block: suspend TangemHotSdk.() -> T): T {
|
||||
return withTimeout(timeMillis = 1000) {
|
||||
sdkState.filterNotNull().first()
|
||||
}.block()
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import com.arkivanov.decompose.router.stack.ChildStack
|
|||
import com.arkivanov.decompose.router.stack.childStack
|
||||
import com.arkivanov.decompose.value.Value
|
||||
import com.arkivanov.decompose.value.subscribe
|
||||
import com.arkivanov.essenty.lifecycle.subscribe
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
|
|
@ -16,7 +17,10 @@ import com.tangem.core.ui.extensions.TextReference
|
|||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.message.SnackbarMessage
|
||||
import com.tangem.features.walletconnect.components.WcRoutingComponent
|
||||
import com.tangem.hot.sdk.TangemHotSdk
|
||||
import com.tangem.hot.sdk.android.create
|
||||
import com.tangem.tap.common.SnackbarHandler
|
||||
import com.tangem.tap.features.hot.TangemHotSDKProxy
|
||||
import com.tangem.tap.routing.RootContent
|
||||
import com.tangem.tap.routing.component.RoutingComponent
|
||||
import com.tangem.tap.routing.component.RoutingComponent.Child
|
||||
|
|
@ -36,6 +40,7 @@ internal class DefaultRoutingComponent @AssistedInject constructor(
|
|||
private val uiDependencies: UiDependencies,
|
||||
private val wcRoutingComponentFactory: WcRoutingComponent.Factory,
|
||||
private val deeplinkFactory: DeepLinkFactory,
|
||||
private val tangemHotSDKProxy: TangemHotSDKProxy,
|
||||
) : RoutingComponent,
|
||||
AppComponentContext by context,
|
||||
SnackbarHandler {
|
||||
|
|
@ -70,6 +75,8 @@ internal class DefaultRoutingComponent @AssistedInject constructor(
|
|||
appRouterConfig.stack = stackItems
|
||||
}
|
||||
}
|
||||
|
||||
configureHotSdk()
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
|
@ -120,6 +127,17 @@ internal class DefaultRoutingComponent @AssistedInject constructor(
|
|||
initialStack
|
||||
}
|
||||
|
||||
private fun configureHotSdk() {
|
||||
lifecycle.subscribe(
|
||||
onCreate = {
|
||||
tangemHotSDKProxy.sdkState.value = TangemHotSdk.create(activity)
|
||||
},
|
||||
onDestroy = {
|
||||
tangemHotSDKProxy.sdkState.value = null
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory : RoutingComponent.Factory {
|
||||
override fun create(context: AppComponentContext, initialStack: List<AppRoute>?): DefaultRoutingComponent
|
||||
|
|
|
|||
|
|
@ -2,9 +2,11 @@ package com.tangem.features.hotwallet.createmobilewallet
|
|||
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.core.decompose.navigation.Router
|
||||
import com.tangem.features.hotwallet.createmobilewallet.entity.CreateMobileWalletUM
|
||||
import com.tangem.hot.sdk.TangemHotSdk
|
||||
import com.tangem.hot.sdk.model.HotAuth
|
||||
import com.tangem.hot.sdk.model.MnemonicType
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
|
@ -15,11 +17,9 @@ import javax.inject.Inject
|
|||
internal class CreateMobileWalletModel @Inject constructor(
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val router: Router,
|
||||
private val paramsContainer: ParamsContainer,
|
||||
private val tangemHotSdk: TangemHotSdk,
|
||||
) : Model() {
|
||||
|
||||
private val params = paramsContainer.require<DefaultCreateMobileWalletComponent.Params>()
|
||||
|
||||
internal val uiState: StateFlow<CreateMobileWalletUM>
|
||||
field = MutableStateFlow(
|
||||
CreateMobileWalletUM(
|
||||
|
|
@ -30,9 +30,8 @@ internal class CreateMobileWalletModel @Inject constructor(
|
|||
|
||||
private fun onCreateClick() {
|
||||
modelScope.launch {
|
||||
val tangemHotSdk = params.tangemHotSdk.instanceAccess.get() ?: return@launch
|
||||
tangemHotSdk.generateWallet(HotAuth.NoAuth, mnemonicType = MnemonicType.Words12)
|
||||
// TODO
|
||||
// val hotWalletId = tangemHotSdk.generateWallet(HotAuth.NoAuth, mnemonicType = MnemonicType.Words12)
|
||||
// val hotUserWalletBuilder = hotUserWalletBuilderFactory.create(hotWalletId, tangemHotSdk)
|
||||
// saveUserWalletUseCase(
|
||||
// hotUserWalletBuilder.build(),
|
||||
|
|
|
|||
|
|
@ -6,11 +6,8 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.decompose.utils.ActivityInstanceHolder
|
||||
import com.tangem.core.decompose.utils.getOrCreateActivityInstanceHolder
|
||||
import com.tangem.features.hotwallet.CreateMobileWalletComponent
|
||||
import com.tangem.features.hotwallet.createmobilewallet.ui.CreateMobileWalletContent
|
||||
import com.tangem.hot.sdk.TangemHotSdk
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
|
|
@ -19,15 +16,9 @@ import dagger.assisted.AssistedInject
|
|||
internal class DefaultCreateMobileWalletComponent @AssistedInject constructor(
|
||||
@Assisted private val context: AppComponentContext,
|
||||
@Assisted private val params: Unit,
|
||||
private val tangemHotSdk: TangemHotSdk,
|
||||
) : CreateMobileWalletComponent, AppComponentContext by context {
|
||||
|
||||
private val modelParams: Params =
|
||||
Params(
|
||||
tangemHotSdk = getOrCreateActivityInstanceHolder { tangemHotSdk },
|
||||
)
|
||||
|
||||
private val model: CreateMobileWalletModel = getOrCreateModel(modelParams)
|
||||
private val model: CreateMobileWalletModel = getOrCreateModel(params)
|
||||
|
||||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
|
|
@ -38,10 +29,6 @@ internal class DefaultCreateMobileWalletComponent @AssistedInject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
class Params(
|
||||
val tangemHotSdk: ActivityInstanceHolder<TangemHotSdk>,
|
||||
)
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory : CreateMobileWalletComponent.Factory {
|
||||
override fun create(context: AppComponentContext, params: Unit): DefaultCreateMobileWalletComponent
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue