Updated on 2026-08-14
This commit is contained in:
parent
d594af91fc
commit
c3f5ea4284
10 changed files with 496 additions and 43 deletions
|
|
@ -1,7 +1,6 @@
|
|||
package com.tangem.domain.yield.supply
|
||||
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.yield.supply.models.YieldMarketToken
|
||||
import com.tangem.domain.yield.supply.models.YieldSupplyPendingStatus
|
||||
|
|
@ -84,13 +83,10 @@ interface YieldSupplyRepository {
|
|||
* Retrieve the hashes of pending (unconfirmed) transactions for the given wallet and currency.
|
||||
*
|
||||
* @param userWalletId the wallet to query
|
||||
* @param cryptoCurrencyStatus the currency status containing network information
|
||||
* @param cryptoCurrency the currency containing network information
|
||||
* @return list of transaction hashes that are still unconfirmed, or an empty list if none exist
|
||||
*/
|
||||
suspend fun getPendingTxHashes(
|
||||
userWalletId: UserWalletId,
|
||||
cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
): List<String>
|
||||
suspend fun getPendingTxHashes(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency): List<String>
|
||||
|
||||
/**
|
||||
* Get the last saved user‑initiated yield protocol action for the given wallet and currency, if any.
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ class YieldSupplyEnterStatusUseCase(
|
|||
cryptoCurrencyStatus.currency,
|
||||
)
|
||||
val pendingTxHashes = yieldSupplyRepository
|
||||
.getPendingTxHashes(userWalletId, cryptoCurrencyStatus)
|
||||
.getPendingTxHashes(userWalletId, cryptoCurrencyStatus.currency)
|
||||
.toSet()
|
||||
val hasPendingTx = status?.txIds?.any { it in pendingTxHashes } == true
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,147 @@
|
|||
package com.tangem.domain.yield.supply.usecase
|
||||
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.networks.single.SingleNetworkStatusFetcher
|
||||
import com.tangem.domain.yield.supply.YieldSupplyRepository
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import timber.log.Timber
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
/**
|
||||
* Periodically checks pending Yield Supply transaction hashes for a given set of wallet/currency pairs.
|
||||
*
|
||||
* - Call [addPending] right after sending a transaction to start tracking its hashes.
|
||||
* - The checker runs every [CHECK_INTERVAL_MS] and queries repository for the current pending tx hashes.
|
||||
* - If none of the stored hashes are pending anymore for a tracked entry, it triggers a single-network status refresh
|
||||
* via [singleNetworkStatusFetcher] and removes the entry from tracking.
|
||||
* - The periodic job stops automatically when there is nothing left to track.
|
||||
*/
|
||||
class YieldSupplyPendingTracker(
|
||||
private val yieldSupplyRepository: YieldSupplyRepository,
|
||||
private val singleNetworkStatusFetcher: SingleNetworkStatusFetcher,
|
||||
private val coroutineScope: CoroutineScope,
|
||||
) {
|
||||
|
||||
private data class TrackedKey(
|
||||
val userWalletId: UserWalletId,
|
||||
val cryptoCurrencyId: CryptoCurrency.ID,
|
||||
)
|
||||
|
||||
private data class TrackedEntry(
|
||||
val cryptoCurrency: CryptoCurrency,
|
||||
val txIds: Set<String>,
|
||||
val attempts: Int = 0,
|
||||
)
|
||||
|
||||
private val trackedEntries = ConcurrentHashMap<TrackedKey, TrackedEntry>()
|
||||
private val mutex = Mutex()
|
||||
private var checkingJob: Job? = null
|
||||
|
||||
/**
|
||||
* Add tx ids to track for a wallet/currency pair. Starts periodic checking if needed.
|
||||
*/
|
||||
suspend fun addPending(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency, txIds: List<String>) {
|
||||
val key = TrackedKey(userWalletId, cryptoCurrency.id)
|
||||
trackedEntries.compute(key) { _, existing ->
|
||||
if (existing == null) {
|
||||
TrackedEntry(
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
txIds = txIds.toSet(),
|
||||
)
|
||||
} else {
|
||||
existing.copy(txIds = existing.txIds + txIds)
|
||||
}
|
||||
}
|
||||
|
||||
startAutomaticCheckingIfNeeded()
|
||||
}
|
||||
|
||||
private suspend fun startAutomaticCheckingIfNeeded() {
|
||||
mutex.withLock {
|
||||
if (checkingJob?.isActive == true) return
|
||||
|
||||
checkingJob = coroutineScope.launch {
|
||||
while (isActive) {
|
||||
try {
|
||||
checkAllTracked()
|
||||
} catch (ex: Exception) {
|
||||
Timber.e(ex)
|
||||
}
|
||||
delay(CHECK_INTERVAL_MS)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun stopAutomaticCheckingIfEmpty() {
|
||||
if (trackedEntries.isEmpty()) {
|
||||
mutex.withLock {
|
||||
if (trackedEntries.isEmpty()) {
|
||||
checkingJob?.cancel()
|
||||
checkingJob = null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun checkAllTracked() {
|
||||
val keysSnapshot = trackedEntries.keys().toList()
|
||||
|
||||
if (keysSnapshot.isEmpty()) {
|
||||
stopAutomaticCheckingIfEmpty()
|
||||
return
|
||||
}
|
||||
|
||||
val networksToFetch = mutableSetOf<SingleNetworkStatusFetcher.Params>()
|
||||
|
||||
for (key in keysSnapshot) {
|
||||
val entry = trackedEntries[key] ?: continue
|
||||
if (entry.txIds.isEmpty()) {
|
||||
trackedEntries.remove(key)
|
||||
continue
|
||||
}
|
||||
|
||||
val pendingTxHashes =
|
||||
yieldSupplyRepository.getPendingTxHashes(
|
||||
userWalletId = key.userWalletId,
|
||||
cryptoCurrency = entry.cryptoCurrency,
|
||||
)
|
||||
.toSet()
|
||||
|
||||
val hasStillPending = entry.txIds.any { it in pendingTxHashes }
|
||||
|
||||
if (hasStillPending) {
|
||||
trackedEntries.computeIfPresent(key) { _, current ->
|
||||
val newAttempts = current.attempts + 1
|
||||
if (newAttempts >= MAX_ATTEMPTS) null else current.copy(attempts = newAttempts)
|
||||
}
|
||||
} else {
|
||||
trackedEntries.remove(key)
|
||||
}
|
||||
networksToFetch.add(
|
||||
SingleNetworkStatusFetcher.Params(
|
||||
userWalletId = key.userWalletId,
|
||||
network = entry.cryptoCurrency.network,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
for (params in networksToFetch) {
|
||||
singleNetworkStatusFetcher(params)
|
||||
}
|
||||
|
||||
stopAutomaticCheckingIfEmpty()
|
||||
}
|
||||
|
||||
private companion object {
|
||||
private const val CHECK_INTERVAL_MS = 10_000L
|
||||
private const val MAX_ATTEMPTS = 6
|
||||
}
|
||||
}
|
||||
|
|
@ -45,7 +45,7 @@ class YieldSupplyEnterStatusUseCaseTest {
|
|||
yieldSupplyRepository.getTokenProtocolPendingStatus(userWalletId, token)
|
||||
} returns status
|
||||
coEvery {
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId, cryptoStatus)
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId, cryptoStatus.currency)
|
||||
} returns listOf(pendingTxHash)
|
||||
|
||||
val result = useCase(userWalletId, cryptoStatus)
|
||||
|
|
@ -65,7 +65,7 @@ class YieldSupplyEnterStatusUseCaseTest {
|
|||
yieldSupplyRepository.getTokenProtocolPendingStatus(userWalletId, token)
|
||||
} returns status
|
||||
coEvery {
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId, cryptoStatus)
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId, cryptoStatus.currency)
|
||||
} returns listOf("0xdifferent")
|
||||
coEvery {
|
||||
yieldSupplyRepository.saveTokenProtocolPendingStatus(userWalletId, token, null)
|
||||
|
|
@ -88,7 +88,7 @@ class YieldSupplyEnterStatusUseCaseTest {
|
|||
yieldSupplyRepository.getTokenProtocolPendingStatus(userWalletId, token)
|
||||
} returns null
|
||||
coEvery {
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId, cryptoStatus)
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId, cryptoStatus.currency)
|
||||
} returns emptyList()
|
||||
coEvery {
|
||||
yieldSupplyRepository.saveTokenProtocolPendingStatus(userWalletId, token, null)
|
||||
|
|
@ -111,7 +111,7 @@ class YieldSupplyEnterStatusUseCaseTest {
|
|||
yieldSupplyRepository.getTokenProtocolPendingStatus(userWalletId, token)
|
||||
} returns status
|
||||
coEvery {
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId, cryptoStatus)
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId, cryptoStatus.currency)
|
||||
} returns emptyList()
|
||||
coEvery {
|
||||
yieldSupplyRepository.saveTokenProtocolPendingStatus(userWalletId, token, null)
|
||||
|
|
@ -153,7 +153,7 @@ class YieldSupplyEnterStatusUseCaseTest {
|
|||
yieldSupplyRepository.getTokenProtocolPendingStatus(userWalletId, token)
|
||||
} returns status
|
||||
coEvery {
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId, cryptoStatus)
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId, cryptoStatus.currency)
|
||||
} returns listOf(pendingTxHash)
|
||||
|
||||
val result = useCase(userWalletId, cryptoStatus)
|
||||
|
|
@ -174,7 +174,7 @@ class YieldSupplyEnterStatusUseCaseTest {
|
|||
yieldSupplyRepository.getTokenProtocolPendingStatus(userWalletId, token)
|
||||
} returns status
|
||||
coEvery {
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId, cryptoStatus)
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId, cryptoStatus.currency)
|
||||
} returns listOf(matchingTxHash)
|
||||
|
||||
val result = useCase(userWalletId, cryptoStatus)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,308 @@
|
|||
package com.tangem.domain.yield.supply.usecase
|
||||
|
||||
import arrow.core.Either
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.networks.single.SingleNetworkStatusFetcher
|
||||
import com.tangem.domain.yield.supply.YieldSupplyRepository
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.mockk
|
||||
import io.mockk.slot
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.advanceTimeBy
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class YieldSupplyPendingTrackerTest {
|
||||
|
||||
private val yieldSupplyRepository: YieldSupplyRepository = mockk()
|
||||
private val singleNetworkStatusFetcher: SingleNetworkStatusFetcher = mockk()
|
||||
|
||||
private lateinit var testScope: TestScope
|
||||
private lateinit var useCase: YieldSupplyPendingTracker
|
||||
|
||||
private val userWalletId = UserWalletId("00")
|
||||
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
testScope = TestScope(StandardTestDispatcher())
|
||||
useCase = YieldSupplyPendingTracker(
|
||||
yieldSupplyRepository = yieldSupplyRepository,
|
||||
singleNetworkStatusFetcher = singleNetworkStatusFetcher,
|
||||
coroutineScope = testScope,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN new tx ids WHEN addPending THEN stores entry for tracking`() = runTest {
|
||||
val token = createToken()
|
||||
val txIds = listOf("0xabc123", "0xdef456")
|
||||
|
||||
coEvery {
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId, token)
|
||||
} returns txIds
|
||||
coEvery {
|
||||
singleNetworkStatusFetcher.invoke(any())
|
||||
} returns Either.Right(Unit)
|
||||
|
||||
useCase.addPending(userWalletId, token, txIds)
|
||||
|
||||
testScope.advanceTimeBy(10_001L)
|
||||
|
||||
coVerify {
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId, token)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN existing entry WHEN addPending THEN merges tx ids`() = runTest {
|
||||
val token = createToken()
|
||||
val firstTxIds = listOf("0xfirst")
|
||||
val secondTxIds = listOf("0xsecond")
|
||||
|
||||
coEvery {
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId, token)
|
||||
} returns firstTxIds + secondTxIds
|
||||
coEvery {
|
||||
singleNetworkStatusFetcher.invoke(any())
|
||||
} returns Either.Right(Unit)
|
||||
|
||||
useCase.addPending(userWalletId, token, firstTxIds)
|
||||
useCase.addPending(userWalletId, token, secondTxIds)
|
||||
|
||||
testScope.advanceTimeBy(10_001L)
|
||||
|
||||
coVerify {
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId, token)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN tx still pending WHEN addPending THEN triggers network status refresh`() = runTest {
|
||||
val token = createToken()
|
||||
val txIds = listOf("0xpending")
|
||||
val paramsSlot = slot<SingleNetworkStatusFetcher.Params>()
|
||||
|
||||
coEvery {
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId, token)
|
||||
} returns txIds
|
||||
coEvery {
|
||||
singleNetworkStatusFetcher.invoke(capture(paramsSlot))
|
||||
} returns Either.Right(Unit)
|
||||
|
||||
useCase.addPending(userWalletId, token, txIds)
|
||||
|
||||
testScope.advanceTimeBy(10_001L)
|
||||
|
||||
coVerify {
|
||||
singleNetworkStatusFetcher.invoke(any())
|
||||
}
|
||||
assertThat(paramsSlot.captured.userWalletId).isEqualTo(userWalletId)
|
||||
assertThat(paramsSlot.captured.network).isEqualTo(token.network)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN tx no longer pending WHEN addPending THEN removes entry from tracking and refreshes network`() = runTest {
|
||||
val token = createToken()
|
||||
val txIds = listOf("0xconfirmed")
|
||||
|
||||
coEvery {
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId, token)
|
||||
} returns emptyList()
|
||||
coEvery {
|
||||
singleNetworkStatusFetcher.invoke(any())
|
||||
} returns Either.Right(Unit)
|
||||
|
||||
useCase.addPending(userWalletId, token, txIds)
|
||||
|
||||
testScope.advanceTimeBy(10_001L)
|
||||
|
||||
coVerify(exactly = 1) {
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId, token)
|
||||
}
|
||||
coVerify(exactly = 1) {
|
||||
singleNetworkStatusFetcher.invoke(any())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN max attempts reached WHEN addPending THEN stops tracking entry`() = runTest {
|
||||
val token = createToken()
|
||||
val txIds = listOf("0xstuck")
|
||||
|
||||
coEvery {
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId, token)
|
||||
} returns txIds
|
||||
coEvery {
|
||||
singleNetworkStatusFetcher.invoke(any())
|
||||
} returns Either.Right(Unit)
|
||||
|
||||
useCase.addPending(userWalletId, token, txIds)
|
||||
|
||||
testScope.advanceTimeBy(10_001L * 6)
|
||||
|
||||
coVerify(exactly = 6) {
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId, token)
|
||||
}
|
||||
|
||||
testScope.advanceTimeBy(10_001L)
|
||||
|
||||
coVerify(exactly = 6) {
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId, token)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN multiple wallets WHEN addPending THEN tracks each separately`() = runTest {
|
||||
val token = createToken()
|
||||
val userWalletId1 = UserWalletId("00")
|
||||
val userWalletId2 = UserWalletId("01")
|
||||
val txIds1 = listOf("0xtx1")
|
||||
val txIds2 = listOf("0xtx2")
|
||||
|
||||
coEvery {
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId1, token)
|
||||
} returns txIds1
|
||||
coEvery {
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId2, token)
|
||||
} returns txIds2
|
||||
coEvery {
|
||||
singleNetworkStatusFetcher.invoke(any())
|
||||
} returns Either.Right(Unit)
|
||||
|
||||
useCase.addPending(userWalletId1, token, txIds1)
|
||||
useCase.addPending(userWalletId2, token, txIds2)
|
||||
|
||||
testScope.advanceTimeBy(10_001L)
|
||||
|
||||
coVerify {
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId1, token)
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId2, token)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN multiple wallets with same network WHEN checkAllTracked THEN fetches network status once per unique pair`() = runTest {
|
||||
val token = createToken()
|
||||
val userWalletId1 = UserWalletId("00")
|
||||
val userWalletId2 = UserWalletId("01")
|
||||
val txIds1 = listOf("0xtx1")
|
||||
val txIds2 = listOf("0xtx2")
|
||||
val capturedParams = mutableListOf<SingleNetworkStatusFetcher.Params>()
|
||||
|
||||
coEvery {
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId1, token)
|
||||
} returns txIds1
|
||||
coEvery {
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId2, token)
|
||||
} returns txIds2
|
||||
coEvery {
|
||||
singleNetworkStatusFetcher.invoke(capture(capturedParams))
|
||||
} returns Either.Right(Unit)
|
||||
|
||||
useCase.addPending(userWalletId1, token, txIds1)
|
||||
useCase.addPending(userWalletId2, token, txIds2)
|
||||
|
||||
testScope.advanceTimeBy(1000)
|
||||
|
||||
assertThat(capturedParams).hasSize(2)
|
||||
assertThat(capturedParams.map { it.userWalletId }.toSet())
|
||||
.containsExactly(userWalletId1, userWalletId2)
|
||||
assertThat(capturedParams.map { it.network }.toSet())
|
||||
.containsExactly(token.network)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN same wallet with different currencies WHEN addPending THEN tracks each currency separately`() = runTest {
|
||||
val token1 = createToken(networkId = "ethereum", contractAddress = "0xToken1")
|
||||
val token2 = createToken(networkId = "polygon", contractAddress = "0xToken2")
|
||||
val txIds1 = listOf("0xtx1")
|
||||
val txIds2 = listOf("0xtx2")
|
||||
|
||||
coEvery {
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId, token1)
|
||||
} returns txIds1
|
||||
coEvery {
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId, token2)
|
||||
} returns txIds2
|
||||
coEvery {
|
||||
singleNetworkStatusFetcher.invoke(any())
|
||||
} returns Either.Right(Unit)
|
||||
|
||||
useCase.addPending(userWalletId, token1, txIds1)
|
||||
useCase.addPending(userWalletId, token2, txIds2)
|
||||
|
||||
testScope.advanceTimeBy(10_001L)
|
||||
|
||||
coVerify {
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId, token1)
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId, token2)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN partial tx match WHEN addPending THEN still triggers refresh`() = runTest {
|
||||
val token = createToken()
|
||||
val trackedTxIds = listOf("0xtracked1", "0xtracked2")
|
||||
val pendingTxIds = listOf("0xtracked1")
|
||||
val paramsSlot = slot<SingleNetworkStatusFetcher.Params>()
|
||||
|
||||
coEvery {
|
||||
yieldSupplyRepository.getPendingTxHashes(userWalletId, token)
|
||||
} returns pendingTxIds
|
||||
coEvery {
|
||||
singleNetworkStatusFetcher.invoke(capture(paramsSlot))
|
||||
} returns Either.Right(Unit)
|
||||
|
||||
useCase.addPending(userWalletId, token, trackedTxIds)
|
||||
|
||||
testScope.advanceTimeBy(10_001L)
|
||||
|
||||
coVerify {
|
||||
singleNetworkStatusFetcher.invoke(any())
|
||||
}
|
||||
assertThat(paramsSlot.captured.userWalletId).isEqualTo(userWalletId)
|
||||
}
|
||||
|
||||
private fun createToken(
|
||||
networkId: String = "ethereum",
|
||||
contractAddress: String = "0xToken",
|
||||
): CryptoCurrency.Token {
|
||||
val derivationPath = Network.DerivationPath.None
|
||||
val network = Network(
|
||||
id = Network.ID(value = networkId, derivationPath = derivationPath),
|
||||
backendId = networkId,
|
||||
name = networkId,
|
||||
currencySymbol = networkId.take(3).uppercase(),
|
||||
derivationPath = derivationPath,
|
||||
isTestnet = false,
|
||||
standardType = Network.StandardType.Unspecified("UNSPECIFIED"),
|
||||
hasFiatFeeRate = true,
|
||||
canHandleTokens = true,
|
||||
transactionExtrasType = Network.TransactionExtrasType.NONE,
|
||||
nameResolvingType = Network.NameResolvingType.NONE,
|
||||
)
|
||||
|
||||
return CryptoCurrency.Token(
|
||||
id = CryptoCurrency.ID(
|
||||
prefix = CryptoCurrency.ID.Prefix.TOKEN_PREFIX,
|
||||
body = CryptoCurrency.ID.Body.NetworkId(networkId),
|
||||
suffix = CryptoCurrency.ID.Suffix.RawID(contractAddress),
|
||||
),
|
||||
network = network,
|
||||
name = "TEST_TOKEN",
|
||||
symbol = "TTK",
|
||||
decimals = 18,
|
||||
iconUrl = null,
|
||||
isCustom = false,
|
||||
contractAddress = contractAddress,
|
||||
)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue