Updated on 2026-08-14
This commit is contained in:
parent
678c1f4e88
commit
6ecbc20e26
6 changed files with 434 additions and 37 deletions
|
|
@ -24,6 +24,7 @@ import com.tangem.data.staking.converters.transaction.GasEstimateConverter
|
|||
import com.tangem.data.staking.converters.transaction.StakingTransactionConverter
|
||||
import com.tangem.data.staking.converters.transaction.StakingTransactionStatusConverter
|
||||
import com.tangem.data.staking.converters.transaction.StakingTransactionTypeConverter
|
||||
import com.tangem.data.staking.utils.StakingIdFactory.Companion.integrationIdMap
|
||||
import com.tangem.datasource.api.common.response.ApiResponse
|
||||
import com.tangem.datasource.api.common.response.getOrThrow
|
||||
import com.tangem.datasource.api.stakekit.StakeKitApi
|
||||
|
|
@ -729,45 +730,13 @@ internal class DefaultStakingRepository(
|
|||
}
|
||||
|
||||
@Suppress("unused")
|
||||
private companion object {
|
||||
const val YIELDS_STORE_KEY = "yields"
|
||||
companion object {
|
||||
private const val YIELDS_STORE_KEY = "yields"
|
||||
|
||||
const val TON_INTEGRATION_ID = "ton-ton-chorus-one-pools-staking"
|
||||
const val SOLANA_INTEGRATION_ID = "solana-sol-native-multivalidator-staking"
|
||||
const val COSMOS_INTEGRATION_ID = "cosmos-atom-native-staking"
|
||||
const val ETHEREUM_POLYGON_INTEGRATION_ID = "ethereum-matic-native-staking"
|
||||
const val BINANCE_INTEGRATION_ID = "bsc-bnb-native-staking"
|
||||
const val POLKADOT_INTEGRATION_ID = "polkadot-dot-validator-staking"
|
||||
const val AVALANCHE_INTEGRATION_ID = "avalanche-avax-native-staking"
|
||||
const val TRON_INTEGRATION_ID = "tron-trx-native-staking"
|
||||
const val CRONOS_INTEGRATION_ID = "cronos-cro-native-staking"
|
||||
const val KAVA_INTEGRATION_ID = "kava-kava-native-staking"
|
||||
const val NEAR_INTEGRATION_ID = "near-near-native-staking"
|
||||
const val TEZOS_INTEGRATION_ID = "tezos-xtz-native-staking"
|
||||
const val CARDANO_INTEGRATION_ID = "cardano-ada-native-staking"
|
||||
private const val ETHEREUM_POLYGON_APPROVE_SPENDER = "0x5e3Ef299fDDf15eAa0432E6e66473ace8c13D908"
|
||||
|
||||
const val ETHEREUM_POLYGON_APPROVE_SPENDER = "0x5e3Ef299fDDf15eAa0432E6e66473ace8c13D908"
|
||||
internal val YIELDS_WATITING_TIMEOUT = 15.seconds
|
||||
|
||||
val YIELDS_WATITING_TIMEOUT = 15.seconds
|
||||
|
||||
val INVALID_BATCHES_FOR_SOLANA = listOf("AC01", "CB79")
|
||||
|
||||
// uncomment items as implementation is ready
|
||||
val integrationIdMap = mapOf(
|
||||
Blockchain.TON.run { id + toCoinId() } to TON_INTEGRATION_ID,
|
||||
Blockchain.Solana.run { id + toCoinId() } to SOLANA_INTEGRATION_ID,
|
||||
Blockchain.Cosmos.run { id + toCoinId() } to COSMOS_INTEGRATION_ID,
|
||||
Blockchain.Tron.run { id + toCoinId() } to TRON_INTEGRATION_ID,
|
||||
Blockchain.Ethereum.id + Blockchain.Polygon.toMigratedCoinId() to ETHEREUM_POLYGON_INTEGRATION_ID,
|
||||
// Blockchain.Ethereum.id + Blockchain.Polygon.toCoinId() to ETHEREUM_POLYGON_INTEGRATION_ID,
|
||||
Blockchain.BSC.run { id + toCoinId() } to BINANCE_INTEGRATION_ID,
|
||||
// Blockchain.Polkadot.run { id + toCoinId() } to POLKADOT_INTEGRATION_ID,
|
||||
// Blockchain.Avalanche.run { id + toCoinId() } to AVALANCHE_INTEGRATION_ID,
|
||||
// Blockchain.Cronos.run { id + toCoinId() } to CRONOS_INTEGRATION_ID,
|
||||
// Blockchain.Kava.run { id + toCoinId() } to KAVA_INTEGRATION_ID,
|
||||
// Blockchain.Near.run { id + toCoinId() } to NEAR_INTEGRATION_ID,
|
||||
// Blockchain.Tezos.run { id + toCoinId() } to TEZOS_INTEGRATION_ID,
|
||||
Blockchain.Cardano.run { id + toCoinId() } to CARDANO_INTEGRATION_ID,
|
||||
)
|
||||
private val INVALID_BATCHES_FOR_SOLANA = listOf("AC01", "CB79")
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
package com.tangem.data.staking.single
|
||||
|
||||
import com.tangem.data.staking.store.YieldsBalancesStore.StakingID
|
||||
import com.tangem.data.staking.utils.StakingIdFactory
|
||||
import com.tangem.domain.staking.model.stakekit.YieldBalance
|
||||
import com.tangem.domain.staking.multi.MultiYieldBalanceProducer
|
||||
import com.tangem.domain.staking.multi.MultiYieldBalanceSupplier
|
||||
import com.tangem.domain.staking.single.SingleYieldBalanceProducer
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.mapNotNull
|
||||
|
||||
/**
|
||||
* Default implementation of [SingleYieldBalanceProducer]
|
||||
*
|
||||
* @property params params
|
||||
* @property multiYieldBalanceSupplier multi yield balance supplier
|
||||
* @property stakingIdFactory factory for creating [StakingID]
|
||||
* @property dispatchers dispatchers
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class DefaultSingleYieldBalanceProducer @AssistedInject constructor(
|
||||
@Assisted private val params: SingleYieldBalanceProducer.Params,
|
||||
private val multiYieldBalanceSupplier: MultiYieldBalanceSupplier,
|
||||
private val stakingIdFactory: StakingIdFactory,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : SingleYieldBalanceProducer {
|
||||
|
||||
override val fallback: YieldBalance by lazy {
|
||||
YieldBalance.Error(
|
||||
integrationId = stakingIdFactory.createIntegrationId(currencyId = params.currencyId),
|
||||
address = null,
|
||||
)
|
||||
}
|
||||
|
||||
override fun produce(): Flow<YieldBalance> {
|
||||
return multiYieldBalanceSupplier(
|
||||
params = MultiYieldBalanceProducer.Params(userWalletId = params.userWalletId),
|
||||
)
|
||||
.mapNotNull {
|
||||
val currentStakingIds = stakingIdFactory.create(
|
||||
userWalletId = params.userWalletId,
|
||||
currencyId = params.currencyId,
|
||||
network = params.network,
|
||||
)
|
||||
|
||||
it.firstOrNull { balance ->
|
||||
val integrationId = balance.integrationId
|
||||
val address = balance.address
|
||||
|
||||
if (integrationId == null || address == null) return@mapNotNull null
|
||||
|
||||
val balanceStakingId = StakingID(integrationId = integrationId, address = address)
|
||||
|
||||
currentStakingIds.contains(balanceStakingId)
|
||||
}
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
.flowOn(dispatchers.default)
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory : SingleYieldBalanceProducer.Factory {
|
||||
override fun create(params: SingleYieldBalanceProducer.Params): DefaultSingleYieldBalanceProducer
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
package com.tangem.data.staking.utils
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchainsdk.utils.toCoinId
|
||||
import com.tangem.blockchainsdk.utils.toMigratedCoinId
|
||||
import com.tangem.data.staking.store.YieldsBalancesStore.StakingID
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Factory of [StakingID]
|
||||
*
|
||||
* @property walletManagersFacade wallet manager facade
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class StakingIdFactory @Inject constructor(
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
) {
|
||||
|
||||
suspend fun create(userWalletId: UserWalletId, currencyId: CryptoCurrency.ID, network: Network): Set<StakingID> {
|
||||
val addresses = walletManagersFacade.getAddresses(userWalletId = userWalletId, network = network)
|
||||
|
||||
val integrationId = createIntegrationId(currencyId) ?: return emptySet()
|
||||
|
||||
return addresses.mapTo(hashSetOf()) { address ->
|
||||
StakingID(integrationId = integrationId, address = address.value)
|
||||
}
|
||||
}
|
||||
|
||||
fun createIntegrationId(currencyId: CryptoCurrency.ID): String? {
|
||||
val integrationKey = with(currencyId) { rawNetworkId.plus(rawCurrencyId) }
|
||||
return integrationIdMap[integrationKey]
|
||||
}
|
||||
|
||||
@Suppress("UnusedPrivateMember")
|
||||
companion object {
|
||||
|
||||
private const val TON_INTEGRATION_ID = "ton-ton-chorus-one-pools-staking"
|
||||
private const val SOLANA_INTEGRATION_ID = "solana-sol-native-multivalidator-staking"
|
||||
private const val COSMOS_INTEGRATION_ID = "cosmos-atom-native-staking"
|
||||
private const val ETHEREUM_POLYGON_INTEGRATION_ID = "ethereum-matic-native-staking"
|
||||
private const val BINANCE_INTEGRATION_ID = "bsc-bnb-native-staking"
|
||||
private const val POLKADOT_INTEGRATION_ID = "polkadot-dot-validator-staking"
|
||||
private const val AVALANCHE_INTEGRATION_ID = "avalanche-avax-native-staking"
|
||||
private const val TRON_INTEGRATION_ID = "tron-trx-native-staking"
|
||||
private const val CRONOS_INTEGRATION_ID = "cronos-cro-native-staking"
|
||||
private const val KAVA_INTEGRATION_ID = "kava-kava-native-staking"
|
||||
private const val NEAR_INTEGRATION_ID = "near-near-native-staking"
|
||||
private const val TEZOS_INTEGRATION_ID = "tezos-xtz-native-staking"
|
||||
private const val CARDANO_INTEGRATION_ID = "cardano-ada-native-staking"
|
||||
|
||||
// uncomment items as implementation is ready
|
||||
val integrationIdMap = mapOf(
|
||||
Blockchain.TON.toDefaultKey() to TON_INTEGRATION_ID,
|
||||
Blockchain.Solana.toDefaultKey() to SOLANA_INTEGRATION_ID,
|
||||
Blockchain.Cosmos.toDefaultKey() to COSMOS_INTEGRATION_ID,
|
||||
Blockchain.Tron.toDefaultKey() to TRON_INTEGRATION_ID,
|
||||
Blockchain.Ethereum.id + Blockchain.Polygon.toMigratedCoinId() to ETHEREUM_POLYGON_INTEGRATION_ID,
|
||||
// Blockchain.Ethereum.id + Blockchain.Polygon.toCoinId() to ETHEREUM_POLYGON_INTEGRATION_ID,
|
||||
Blockchain.BSC.toDefaultKey() to BINANCE_INTEGRATION_ID,
|
||||
// Blockchain.Polkadot.toDefaultKey() to POLKADOT_INTEGRATION_ID,
|
||||
// Blockchain.Avalanche.toDefaultKey() to AVALANCHE_INTEGRATION_ID,
|
||||
// Blockchain.Cronos.toDefaultKey() to CRONOS_INTEGRATION_ID,
|
||||
// Blockchain.Kava.toDefaultKey() to KAVA_INTEGRATION_ID,
|
||||
// Blockchain.Near.toDefaultKey() to NEAR_INTEGRATION_ID,
|
||||
// Blockchain.Tezos.toDefaultKey() to TEZOS_INTEGRATION_ID,
|
||||
Blockchain.Cardano.toDefaultKey() to CARDANO_INTEGRATION_ID,
|
||||
)
|
||||
|
||||
private fun Blockchain.toDefaultKey(): String = id + toCoinId()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,239 @@
|
|||
package com.tangem.data.staking.single
|
||||
|
||||
import com.google.common.truth.Truth
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.common.test.data.staking.MockYieldBalanceWrapperDTOFactory
|
||||
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
|
||||
import com.tangem.common.test.utils.getEmittedValues
|
||||
import com.tangem.data.staking.store.YieldsBalancesStore
|
||||
import com.tangem.data.staking.toDomain
|
||||
import com.tangem.data.staking.utils.StakingIdFactory
|
||||
import com.tangem.domain.staking.model.stakekit.YieldBalance
|
||||
import com.tangem.domain.staking.multi.MultiYieldBalanceProducer
|
||||
import com.tangem.domain.staking.multi.MultiYieldBalanceSupplier
|
||||
import com.tangem.domain.staking.single.SingleYieldBalanceProducer
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
||||
import io.mockk.*
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class DefaultSingleYieldBalanceProducerTest {
|
||||
|
||||
private val params = SingleYieldBalanceProducer.Params(
|
||||
userWalletId = UserWalletId(stringValue = "011"),
|
||||
currencyId = ton.id,
|
||||
network = ton.network,
|
||||
)
|
||||
|
||||
private val multiNetworkStatusSupplier = mockk<MultiYieldBalanceSupplier>()
|
||||
private val stakingIdFactory = mockk<StakingIdFactory>()
|
||||
private val dispatchers = TestingCoroutineDispatcherProvider()
|
||||
|
||||
private val producer = DefaultSingleYieldBalanceProducer(
|
||||
params = params,
|
||||
stakingIdFactory = stakingIdFactory,
|
||||
multiYieldBalanceSupplier = multiNetworkStatusSupplier,
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `test that flow is mapped for data from params`() = runTest {
|
||||
val balance = MockYieldBalanceWrapperDTOFactory.createWithBalance(tonId).toDomain()
|
||||
|
||||
val expected = flowOf(
|
||||
setOf(
|
||||
balance,
|
||||
MockYieldBalanceWrapperDTOFactory.createWithBalance(solanaId).toDomain(),
|
||||
),
|
||||
)
|
||||
|
||||
val multiParams = MultiYieldBalanceProducer.Params(userWalletId = params.userWalletId)
|
||||
every { multiNetworkStatusSupplier(multiParams) } returns expected
|
||||
coEvery { stakingIdFactory.create(params.userWalletId, params.currencyId, params.network) } returns stakingIds
|
||||
|
||||
val actual = producer.produce()
|
||||
|
||||
verify { multiNetworkStatusSupplier(multiParams) }
|
||||
|
||||
val values = getEmittedValues(flow = actual)
|
||||
|
||||
coVerify { stakingIdFactory.create(params.userWalletId, params.currencyId, params.network) }
|
||||
|
||||
Truth.assertThat(values.size).isEqualTo(1)
|
||||
Truth.assertThat(values).isEqualTo(listOf(balance))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test that flow is updated if yield balance is updated`() = runTest {
|
||||
val expected = MutableSharedFlow<Set<YieldBalance>>(replay = 2, extraBufferCapacity = 1)
|
||||
|
||||
val multiParams = MultiYieldBalanceProducer.Params(userWalletId = params.userWalletId)
|
||||
every { multiNetworkStatusSupplier(multiParams) } returns expected
|
||||
coEvery { stakingIdFactory.create(params.userWalletId, params.currencyId, params.network) } returns stakingIds
|
||||
|
||||
val actual = producer.produceWithFallback()
|
||||
|
||||
verify { multiNetworkStatusSupplier(multiParams) }
|
||||
|
||||
// first emit
|
||||
val balance = MockYieldBalanceWrapperDTOFactory.createWithBalance(tonId).toDomain()
|
||||
expected.emit(value = setOf(balance))
|
||||
|
||||
val values1 = getEmittedValues(flow = actual)
|
||||
|
||||
coVerify { stakingIdFactory.create(params.userWalletId, params.currencyId, params.network) }
|
||||
|
||||
Truth.assertThat(values1.size).isEqualTo(1)
|
||||
Truth.assertThat(values1).isEqualTo(listOf(balance))
|
||||
|
||||
// second emit
|
||||
val updatedStatus = YieldBalance.Error(integrationId = tonId.integrationId, address = tonId.address)
|
||||
expected.emit(value = setOf(updatedStatus))
|
||||
|
||||
val values2 = getEmittedValues(flow = actual)
|
||||
|
||||
coVerify { stakingIdFactory.create(params.userWalletId, params.currencyId, params.network) }
|
||||
|
||||
Truth.assertThat(values2.size).isEqualTo(2)
|
||||
Truth.assertThat(values2).isEqualTo(listOf(balance, updatedStatus))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test that flow is filtered the same status`() = runTest {
|
||||
val expected = MutableSharedFlow<Set<YieldBalance>>(replay = 2, extraBufferCapacity = 1)
|
||||
|
||||
val multiParams = MultiYieldBalanceProducer.Params(userWalletId = params.userWalletId)
|
||||
every { multiNetworkStatusSupplier(multiParams) } returns expected
|
||||
coEvery { stakingIdFactory.create(params.userWalletId, params.currencyId, params.network) } returns stakingIds
|
||||
|
||||
val actual = producer.produceWithFallback()
|
||||
|
||||
verify { multiNetworkStatusSupplier(multiParams) }
|
||||
|
||||
// first emit
|
||||
val balance = MockYieldBalanceWrapperDTOFactory.createWithBalance(tonId).toDomain()
|
||||
expected.emit(value = setOf(balance))
|
||||
|
||||
val values1 = getEmittedValues(flow = actual)
|
||||
|
||||
coVerify { stakingIdFactory.create(params.userWalletId, params.currencyId, params.network) }
|
||||
|
||||
Truth.assertThat(values1.size).isEqualTo(1)
|
||||
Truth.assertThat(values1).isEqualTo(listOf(balance))
|
||||
|
||||
// second emit
|
||||
expected.emit(value = setOf(balance))
|
||||
|
||||
val values2 = getEmittedValues(flow = actual)
|
||||
|
||||
coVerify { stakingIdFactory.create(params.userWalletId, params.currencyId, params.network) }
|
||||
|
||||
Truth.assertThat(values2.size).isEqualTo(1)
|
||||
Truth.assertThat(values2).isEqualTo(listOf(balance))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test if flow throws exception`() = runTest {
|
||||
val exception = IllegalStateException()
|
||||
val balance = MockYieldBalanceWrapperDTOFactory.createWithBalance(tonId).toDomain()
|
||||
|
||||
val innerFlow = MutableStateFlow(value = false)
|
||||
val expected = flow {
|
||||
if (innerFlow.value) {
|
||||
emit(setOf(balance))
|
||||
} else {
|
||||
throw exception
|
||||
}
|
||||
}
|
||||
.buffer(capacity = 5)
|
||||
|
||||
val multiParams = MultiYieldBalanceProducer.Params(userWalletId = params.userWalletId)
|
||||
every { multiNetworkStatusSupplier(multiParams) } returns expected
|
||||
every { stakingIdFactory.createIntegrationId(currencyId = params.currencyId) } returns tonId.integrationId
|
||||
|
||||
val actual = producer.produceWithFallback()
|
||||
|
||||
verify { multiNetworkStatusSupplier(multiParams) }
|
||||
|
||||
val values1 = getEmittedValues(flow = actual)
|
||||
|
||||
coVerify(inverse = true) { stakingIdFactory.create(any(), any(), any()) }
|
||||
|
||||
Truth.assertThat(values1.size).isEqualTo(1)
|
||||
val fallbackStatus = YieldBalance.Error(integrationId = tonId.integrationId, address = null)
|
||||
Truth.assertThat(values1).isEqualTo(listOf(fallbackStatus))
|
||||
|
||||
coEvery { stakingIdFactory.create(params.userWalletId, params.currencyId, params.network) } returns stakingIds
|
||||
|
||||
innerFlow.emit(value = true)
|
||||
|
||||
val values2 = getEmittedValues(flow = actual)
|
||||
|
||||
coVerify { stakingIdFactory.create(params.userWalletId, params.currencyId, params.network) }
|
||||
|
||||
Truth.assertThat(values2.size).isEqualTo(1)
|
||||
Truth.assertThat(values2).isEqualTo(listOf(balance))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test if flow doesn't contain network from params`() = runTest {
|
||||
val balance = MockYieldBalanceWrapperDTOFactory.createWithBalance(solanaId).toDomain()
|
||||
|
||||
val expected = flowOf(setOf(balance))
|
||||
|
||||
val multiParams = MultiYieldBalanceProducer.Params(userWalletId = params.userWalletId)
|
||||
every { multiNetworkStatusSupplier(multiParams) } returns expected
|
||||
coEvery { stakingIdFactory.create(params.userWalletId, params.currencyId, params.network) } returns stakingIds
|
||||
|
||||
val actual = producer.produce()
|
||||
|
||||
verify { multiNetworkStatusSupplier(multiParams) }
|
||||
|
||||
val values = getEmittedValues(flow = actual)
|
||||
|
||||
coVerify { stakingIdFactory.create(params.userWalletId, params.currencyId, params.network) }
|
||||
|
||||
Truth.assertThat(values.size).isEqualTo(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test if wallet manager facade returns empty set`() = runTest {
|
||||
val balance = MockYieldBalanceWrapperDTOFactory.createWithBalance(tonId).toDomain()
|
||||
|
||||
val expected = flowOf(setOf(balance))
|
||||
|
||||
val multiParams = MultiYieldBalanceProducer.Params(userWalletId = params.userWalletId)
|
||||
every { multiNetworkStatusSupplier(multiParams) } returns expected
|
||||
coEvery { stakingIdFactory.create(params.userWalletId, params.currencyId, params.network) } returns emptySet()
|
||||
|
||||
val actual = producer.produce()
|
||||
|
||||
verify { multiNetworkStatusSupplier(multiParams) }
|
||||
|
||||
val values = getEmittedValues(flow = actual)
|
||||
|
||||
coVerify { stakingIdFactory.create(params.userWalletId, params.currencyId, params.network) }
|
||||
|
||||
Truth.assertThat(values.size).isEqualTo(0)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
|
||||
val mocks = MockCryptoCurrencyFactory()
|
||||
|
||||
val ton = mocks.createCoin(Blockchain.TON)
|
||||
|
||||
val tonId = MockYieldBalanceWrapperDTOFactory.defaultStakingId
|
||||
val solanaId = YieldsBalancesStore.StakingID(
|
||||
integrationId = "solana-sol-native-multivalidator-staking",
|
||||
address = "0x1",
|
||||
)
|
||||
|
||||
val stakingIds = setOf(tonId)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.tangem.domain.staking.single
|
||||
|
||||
import com.tangem.domain.core.flow.FlowProducer
|
||||
import com.tangem.domain.staking.model.stakekit.YieldBalance
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
|
||||
/**
|
||||
* Producer of yield balance for selected wallet [UserWalletId]
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
interface SingleYieldBalanceProducer : FlowProducer<YieldBalance> {
|
||||
|
||||
data class Params(
|
||||
val userWalletId: UserWalletId,
|
||||
val currencyId: CryptoCurrency.ID,
|
||||
val network: Network,
|
||||
)
|
||||
|
||||
interface Factory : FlowProducer.Factory<Params, SingleYieldBalanceProducer>
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package com.tangem.domain.staking.single
|
||||
|
||||
import com.tangem.domain.core.flow.FlowCachingSupplier
|
||||
import com.tangem.domain.core.flow.FlowProducer
|
||||
import com.tangem.domain.staking.model.stakekit.YieldBalance
|
||||
|
||||
/**
|
||||
* Supplier of yield balance for selected wallet [SingleYieldBalanceProducer.Params]
|
||||
*
|
||||
* @property factory factory for creating [SingleYieldBalanceProducer]
|
||||
* @property keyCreator key creator
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
abstract class SingleYieldBalanceSupplier(
|
||||
override val factory: FlowProducer.Factory<SingleYieldBalanceProducer.Params, SingleYieldBalanceProducer>,
|
||||
override val keyCreator: (SingleYieldBalanceProducer.Params) -> String,
|
||||
) : FlowCachingSupplier<SingleYieldBalanceProducer, SingleYieldBalanceProducer.Params, YieldBalance>()
|
||||
Loading…
Add table
Add a link
Reference in a new issue