Updated on 2026-08-14
This commit is contained in:
parent
40f24bd65b
commit
724a1fe19b
19 changed files with 550 additions and 587 deletions
|
|
@ -1,6 +1,9 @@
|
||||||
package com.tangem.tap.di.domain
|
package com.tangem.tap.di.domain
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import com.squareup.moshi.Moshi
|
||||||
import com.tangem.datasource.config.ConfigManager
|
import com.tangem.datasource.config.ConfigManager
|
||||||
|
import com.tangem.datasource.di.SdkMoshi
|
||||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||||
import com.tangem.datasource.local.walletmanager.WalletManagersStore
|
import com.tangem.datasource.local.walletmanager.WalletManagersStore
|
||||||
import com.tangem.domain.walletmanager.DefaultWalletManagersFacade
|
import com.tangem.domain.walletmanager.DefaultWalletManagersFacade
|
||||||
|
|
@ -8,6 +11,7 @@ import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import dagger.hilt.components.SingletonComponent
|
import dagger.hilt.components.SingletonComponent
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
|
@ -21,7 +25,15 @@ internal object WalletManagersFacadeModule {
|
||||||
walletManagersStore: WalletManagersStore,
|
walletManagersStore: WalletManagersStore,
|
||||||
userWalletsStore: UserWalletsStore,
|
userWalletsStore: UserWalletsStore,
|
||||||
configManager: ConfigManager,
|
configManager: ConfigManager,
|
||||||
|
@ApplicationContext appContext: Context,
|
||||||
|
@SdkMoshi moshi: Moshi,
|
||||||
): WalletManagersFacade {
|
): WalletManagersFacade {
|
||||||
return DefaultWalletManagersFacade(walletManagersStore, userWalletsStore, configManager)
|
return DefaultWalletManagersFacade(
|
||||||
|
walletManagersStore = walletManagersStore,
|
||||||
|
userWalletsStore = userWalletsStore,
|
||||||
|
configManager = configManager,
|
||||||
|
assetManager = appContext.assets,
|
||||||
|
moshi = moshi,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -453,6 +453,7 @@
|
||||||
<string name="transaction_history_error_failed_to_load">Не удалось загрузить историю транзакций.\nНажмите на кнопку перезагрузки, чтобы обновить информацию.</string>
|
<string name="transaction_history_error_failed_to_load">Не удалось загрузить историю транзакций.\nНажмите на кнопку перезагрузки, чтобы обновить информацию.</string>
|
||||||
<string name="transaction_history_multiple_addresses">Несколько адресов</string>
|
<string name="transaction_history_multiple_addresses">Несколько адресов</string>
|
||||||
<string name="transaction_history_not_supported_description">История транзакций в настоящее время не поддерживается для этого блокчейна. Но не волнуйтесь, мы работаем над этим! А пока вы можете проверить ее в обозревателе.</string>
|
<string name="transaction_history_not_supported_description">История транзакций в настоящее время не поддерживается для этого блокчейна. Но не волнуйтесь, мы работаем над этим! А пока вы можете проверить ее в обозревателе.</string>
|
||||||
|
<string name="transaction_history_operation">Операция</string>
|
||||||
<string name="transaction_history_transaction_from_address">от: %s</string>
|
<string name="transaction_history_transaction_from_address">от: %s</string>
|
||||||
<string name="transaction_history_transaction_to_address">на: %s</string>
|
<string name="transaction_history_transaction_to_address">на: %s</string>
|
||||||
<string name="transaction_history_tx_in_progress">В процессе…</string>
|
<string name="transaction_history_tx_in_progress">В процессе…</string>
|
||||||
|
|
|
||||||
|
|
@ -469,6 +469,7 @@
|
||||||
<string name="transaction_history_error_failed_to_load">Failed to load transaction history.\nClick on reload button to update the information.</string>
|
<string name="transaction_history_error_failed_to_load">Failed to load transaction history.\nClick on reload button to update the information.</string>
|
||||||
<string name="transaction_history_multiple_addresses">Multiple addresses</string>
|
<string name="transaction_history_multiple_addresses">Multiple addresses</string>
|
||||||
<string name="transaction_history_not_supported_description">Transaction history is currently not supported for this blockchain. But don\'t worry, we\'re working on it! In the meantime you can check it in the explorer.</string>
|
<string name="transaction_history_not_supported_description">Transaction history is currently not supported for this blockchain. But don\'t worry, we\'re working on it! In the meantime you can check it in the explorer.</string>
|
||||||
|
<string name="transaction_history_operation">Operation</string>
|
||||||
<string name="transaction_history_transaction_from_address">from: %s</string>
|
<string name="transaction_history_transaction_from_address">from: %s</string>
|
||||||
<string name="transaction_history_transaction_to_address">to: %s</string>
|
<string name="transaction_history_transaction_to_address">to: %s</string>
|
||||||
<string name="transaction_history_tx_in_progress">In progress…</string>
|
<string name="transaction_history_tx_in_progress">In progress…</string>
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ import com.tangem.core.ui.components.transactions.state.TransactionState.Content
|
||||||
import com.tangem.core.ui.components.transactions.state.TransactionState.Content.Status
|
import com.tangem.core.ui.components.transactions.state.TransactionState.Content.Status
|
||||||
import com.tangem.core.ui.extensions.TextReference
|
import com.tangem.core.ui.extensions.TextReference
|
||||||
import com.tangem.core.ui.extensions.resolveReference
|
import com.tangem.core.ui.extensions.resolveReference
|
||||||
|
import com.tangem.core.ui.extensions.resourceReference
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
|
|
@ -137,22 +138,7 @@ private fun Icon(state: TransactionState, modifier: Modifier = Modifier) {
|
||||||
),
|
),
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
painter = painterResource(
|
painter = painterResource(id = state.iconRes),
|
||||||
id = when (state.status) {
|
|
||||||
is Status.Failed -> R.drawable.ic_close_24
|
|
||||||
else -> when (state) {
|
|
||||||
is TransactionState.Transfer -> {
|
|
||||||
when (state.direction) {
|
|
||||||
Direction.OUTGOING -> R.drawable.ic_arrow_up_24
|
|
||||||
Direction.INCOMING -> R.drawable.ic_arrow_down_24
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is TransactionState.Approve -> R.drawable.ic_doc_24
|
|
||||||
is TransactionState.Swap -> R.drawable.ic_exchange_vertical_24
|
|
||||||
is TransactionState.Custom -> R.drawable.ic_exchange_vertical_24
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(TangemTheme.dimens.size20)
|
.size(TangemTheme.dimens.size20)
|
||||||
|
|
@ -189,12 +175,7 @@ private fun Title(state: TransactionState, modifier: Modifier = Modifier) {
|
||||||
is TransactionState.Content -> {
|
is TransactionState.Content -> {
|
||||||
Row(modifier = modifier, horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing6)) {
|
Row(modifier = modifier, horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing6)) {
|
||||||
Text(
|
Text(
|
||||||
text = when (state) {
|
text = state.title.resolveReference(),
|
||||||
is TransactionState.Approve -> stringResource(R.string.common_approval)
|
|
||||||
is TransactionState.Transfer -> stringResource(R.string.common_transfer)
|
|
||||||
is TransactionState.Swap -> stringResource(R.string.common_swap)
|
|
||||||
is TransactionState.Custom -> state.title.resolveReference()
|
|
||||||
},
|
|
||||||
color = TangemTheme.colors.text.primary1,
|
color = TangemTheme.colors.text.primary1,
|
||||||
style = TangemTheme.typography.subtitle2,
|
style = TangemTheme.typography.subtitle2,
|
||||||
)
|
)
|
||||||
|
|
@ -228,35 +209,7 @@ private fun Subtitle(state: TransactionState, modifier: Modifier = Modifier) {
|
||||||
Text(
|
Text(
|
||||||
text = when (state.status) {
|
text = when (state.status) {
|
||||||
is Status.Failed -> stringResource(id = R.string.common_transaction_failed)
|
is Status.Failed -> stringResource(id = R.string.common_transaction_failed)
|
||||||
else -> when (state) {
|
else -> state.subtitle.resolveReference()
|
||||||
is TransactionState.Transfer -> {
|
|
||||||
when (state.direction) {
|
|
||||||
Direction.OUTGOING -> stringResource(
|
|
||||||
id = R.string.transaction_history_transaction_to_address,
|
|
||||||
state.address.resolveReference(),
|
|
||||||
)
|
|
||||||
Direction.INCOMING -> stringResource(
|
|
||||||
id = R.string.transaction_history_transaction_from_address,
|
|
||||||
state.address.resolveReference(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is TransactionState.Approve -> stringResource(
|
|
||||||
id = R.string.transaction_history_transaction_from_address,
|
|
||||||
state.address.resolveReference(),
|
|
||||||
)
|
|
||||||
is TransactionState.Swap -> stringResource(
|
|
||||||
id = R.string.transaction_history_contract_address,
|
|
||||||
state.address.resolveReference(),
|
|
||||||
)
|
|
||||||
is TransactionState.Custom -> stringResource(
|
|
||||||
id = when (state.direction) {
|
|
||||||
Direction.OUTGOING -> R.string.transaction_history_transaction_to_address
|
|
||||||
Direction.INCOMING -> R.string.transaction_history_transaction_from_address
|
|
||||||
},
|
|
||||||
state.subtitle.resolveReference(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
textAlign = TextAlign.Start,
|
textAlign = TextAlign.Start,
|
||||||
|
|
@ -362,78 +315,98 @@ private fun Preview_TransactionItem_DarkTheme(
|
||||||
|
|
||||||
private class TransactionItemStateProvider : CollectionPreviewParameterProvider<TransactionState>(
|
private class TransactionItemStateProvider : CollectionPreviewParameterProvider<TransactionState>(
|
||||||
collection = listOf(
|
collection = listOf(
|
||||||
TransactionState.Transfer(
|
TransactionState.Content(
|
||||||
txHash = UUID.randomUUID().toString(),
|
txHash = UUID.randomUUID().toString(),
|
||||||
address = TextReference.Str("33BddS...ga2B"),
|
address = TextReference.Str("33BddS...ga2B"),
|
||||||
amount = "-0.500913 BTC",
|
amount = "-0.500913 BTC",
|
||||||
timestamp = "8:41",
|
timestamp = "8:41",
|
||||||
status = Status.Confirmed,
|
status = Status.Confirmed,
|
||||||
direction = Direction.OUTGOING,
|
direction = Direction.OUTGOING,
|
||||||
|
iconRes = R.drawable.ic_arrow_up_24,
|
||||||
|
title = resourceReference(R.string.common_transfer),
|
||||||
|
subtitle = TextReference.Str("33BddS...ga2B"),
|
||||||
onClick = {},
|
onClick = {},
|
||||||
),
|
),
|
||||||
TransactionState.Transfer(
|
TransactionState.Content(
|
||||||
txHash = UUID.randomUUID().toString(),
|
txHash = UUID.randomUUID().toString(),
|
||||||
address = TextReference.Str("33BddS...ga2B"),
|
address = TextReference.Str("33BddS...ga2B"),
|
||||||
amount = "+0.500913 BTC",
|
amount = "+0.500913 BTC",
|
||||||
timestamp = "8:41",
|
timestamp = "8:41",
|
||||||
status = Status.Unconfirmed,
|
status = Status.Unconfirmed,
|
||||||
direction = Direction.INCOMING,
|
direction = Direction.INCOMING,
|
||||||
|
iconRes = R.drawable.ic_arrow_down_24,
|
||||||
|
title = resourceReference(R.string.common_transfer),
|
||||||
|
subtitle = TextReference.Str("33BddS...ga2B"),
|
||||||
onClick = {},
|
onClick = {},
|
||||||
),
|
),
|
||||||
TransactionState.Approve(
|
TransactionState.Content(
|
||||||
txHash = UUID.randomUUID().toString(),
|
txHash = UUID.randomUUID().toString(),
|
||||||
address = TextReference.Str("33BddS...ga2B"),
|
address = TextReference.Str("33BddS...ga2B"),
|
||||||
amount = "+0.500913 BTC",
|
amount = "+0.500913 BTC",
|
||||||
timestamp = "8:41",
|
timestamp = "8:41",
|
||||||
status = Status.Unconfirmed,
|
status = Status.Unconfirmed,
|
||||||
direction = Direction.OUTGOING,
|
direction = Direction.OUTGOING,
|
||||||
|
iconRes = R.drawable.ic_doc_24,
|
||||||
|
title = resourceReference(R.string.common_approval),
|
||||||
|
subtitle = TextReference.Str("33BddS...ga2B"),
|
||||||
onClick = {},
|
onClick = {},
|
||||||
),
|
),
|
||||||
TransactionState.Approve(
|
TransactionState.Content(
|
||||||
txHash = UUID.randomUUID().toString(),
|
txHash = UUID.randomUUID().toString(),
|
||||||
address = TextReference.Str("33BddS...ga2B"),
|
address = TextReference.Str("33BddS...ga2B"),
|
||||||
amount = "+0.500913 BTC",
|
amount = "+0.500913 BTC",
|
||||||
timestamp = "8:41",
|
timestamp = "8:41",
|
||||||
status = Status.Failed,
|
status = Status.Failed,
|
||||||
direction = Direction.OUTGOING,
|
direction = Direction.OUTGOING,
|
||||||
|
iconRes = R.drawable.ic_doc_24,
|
||||||
|
title = resourceReference(R.string.common_approval),
|
||||||
|
subtitle = TextReference.Str("33BddS...ga2B"),
|
||||||
onClick = {},
|
onClick = {},
|
||||||
),
|
),
|
||||||
TransactionState.Approve(
|
TransactionState.Content(
|
||||||
txHash = UUID.randomUUID().toString(),
|
txHash = UUID.randomUUID().toString(),
|
||||||
address = TextReference.Str("33BddS...ga2B"),
|
address = TextReference.Str("33BddS...ga2B"),
|
||||||
amount = "+0.500913 BTC",
|
amount = "+0.500913 BTC",
|
||||||
timestamp = "8:41",
|
timestamp = "8:41",
|
||||||
status = Status.Confirmed,
|
status = Status.Confirmed,
|
||||||
direction = Direction.OUTGOING,
|
direction = Direction.OUTGOING,
|
||||||
|
iconRes = R.drawable.ic_doc_24,
|
||||||
|
title = resourceReference(R.string.common_approval),
|
||||||
|
subtitle = TextReference.Str("33BddS...ga2B"),
|
||||||
onClick = {},
|
onClick = {},
|
||||||
),
|
),
|
||||||
TransactionState.Swap(
|
TransactionState.Content(
|
||||||
txHash = UUID.randomUUID().toString(),
|
txHash = UUID.randomUUID().toString(),
|
||||||
address = TextReference.Str("33BddS...ga2B"),
|
address = TextReference.Str("33BddS...ga2B"),
|
||||||
amount = "+0.500913 BTC",
|
amount = "+0.500913 BTC",
|
||||||
timestamp = "8:41",
|
timestamp = "8:41",
|
||||||
status = Status.Unconfirmed,
|
status = Status.Unconfirmed,
|
||||||
direction = Direction.INCOMING,
|
direction = Direction.INCOMING,
|
||||||
|
iconRes = R.drawable.ic_arrow_down_24,
|
||||||
|
title = resourceReference(R.string.common_swap),
|
||||||
|
subtitle = TextReference.Str("33BddS...ga2B"),
|
||||||
onClick = {},
|
onClick = {},
|
||||||
),
|
),
|
||||||
TransactionState.Custom(
|
TransactionState.Content(
|
||||||
txHash = UUID.randomUUID().toString(),
|
txHash = UUID.randomUUID().toString(),
|
||||||
address = TextReference.Str("33BddS...ga2B"),
|
address = TextReference.Str("33BddS...ga2B"),
|
||||||
amount = "+0.500913 BTC",
|
amount = "+0.500913 BTC",
|
||||||
timestamp = "8:41",
|
timestamp = "8:41",
|
||||||
status = Status.Confirmed,
|
status = Status.Confirmed,
|
||||||
direction = Direction.INCOMING,
|
direction = Direction.INCOMING,
|
||||||
|
iconRes = R.drawable.ic_doc_24,
|
||||||
title = TextReference.Str("Submit"),
|
title = TextReference.Str("Submit"),
|
||||||
subtitle = TextReference.Str("33BddS...ga2B"),
|
subtitle = TextReference.Str("33BddS...ga2B"),
|
||||||
onClick = {},
|
onClick = {},
|
||||||
),
|
),
|
||||||
TransactionState.Custom(
|
TransactionState.Content(
|
||||||
txHash = UUID.randomUUID().toString(),
|
txHash = UUID.randomUUID().toString(),
|
||||||
address = TextReference.Str("33BddS...ga2B"),
|
address = TextReference.Str("33BddS...ga2B"),
|
||||||
amount = "+0.500913 BTC",
|
amount = "+0.500913 BTC",
|
||||||
timestamp = "8:41",
|
timestamp = "8:41",
|
||||||
status = Status.Confirmed,
|
status = Status.Confirmed,
|
||||||
direction = Direction.OUTGOING,
|
direction = Direction.OUTGOING,
|
||||||
|
iconRes = R.drawable.ic_arrow_up_24,
|
||||||
title = TextReference.Str("Submit"),
|
title = TextReference.Str("Submit"),
|
||||||
subtitle = TextReference.Str("33BddS...ga2B"),
|
subtitle = TextReference.Str("33BddS...ga2B"),
|
||||||
onClick = {},
|
onClick = {},
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.tangem.core.ui.components.transactions.state
|
package com.tangem.core.ui.components.transactions.state
|
||||||
|
|
||||||
|
import androidx.annotation.DrawableRes
|
||||||
import com.tangem.core.ui.extensions.TextReference
|
import com.tangem.core.ui.extensions.TextReference
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -22,30 +23,18 @@ sealed interface TransactionState {
|
||||||
* @property direction transaction direction
|
* @property direction transaction direction
|
||||||
* @property onClick Lambda be invoked when manage button is clicked
|
* @property onClick Lambda be invoked when manage button is clicked
|
||||||
*/
|
*/
|
||||||
sealed class Content : TransactionState {
|
data class Content(
|
||||||
|
override val txHash: String,
|
||||||
abstract val address: TextReference
|
val address: TextReference,
|
||||||
abstract val amount: String
|
val amount: String,
|
||||||
abstract val timestamp: String
|
val timestamp: String,
|
||||||
abstract val status: Status
|
val status: Status,
|
||||||
abstract val direction: Direction
|
val direction: Direction,
|
||||||
abstract val onClick: () -> Unit
|
val onClick: () -> Unit,
|
||||||
|
@DrawableRes val iconRes: Int,
|
||||||
fun copySealed(
|
val title: TextReference,
|
||||||
txHash: String = this.txHash,
|
val subtitle: TextReference,
|
||||||
address: TextReference = this.address,
|
) : TransactionState {
|
||||||
amount: String = this.amount,
|
|
||||||
timestamp: String = this.timestamp,
|
|
||||||
status: Status = this.status,
|
|
||||||
direction: Direction = this.direction,
|
|
||||||
): Content {
|
|
||||||
return when (this) {
|
|
||||||
is Approve -> copy(txHash, address, amount, timestamp, status, direction)
|
|
||||||
is Transfer -> copy(txHash, address, amount, timestamp, status, direction)
|
|
||||||
is Swap -> copy(txHash, address, amount, timestamp, status, direction)
|
|
||||||
is Custom -> copy(txHash, address, amount, timestamp, status, direction)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sealed class Status {
|
sealed class Status {
|
||||||
object Failed : Status()
|
object Failed : Status()
|
||||||
|
|
@ -59,75 +48,6 @@ sealed interface TransactionState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Completed sending transaction state
|
|
||||||
*
|
|
||||||
* @property txHash transaction hash
|
|
||||||
* @property address address
|
|
||||||
* @property amount amount
|
|
||||||
* @property timestamp timestamp
|
|
||||||
* @property direction transaction direction
|
|
||||||
*/
|
|
||||||
data class Transfer(
|
|
||||||
override val txHash: String,
|
|
||||||
override val address: TextReference,
|
|
||||||
override val amount: String,
|
|
||||||
override val timestamp: String,
|
|
||||||
override val status: Status,
|
|
||||||
override val direction: Direction,
|
|
||||||
override val onClick: () -> Unit,
|
|
||||||
) : Content()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Completed approving transaction state
|
|
||||||
*
|
|
||||||
* @property txHash transaction hash
|
|
||||||
* @property address address
|
|
||||||
* @property amount amount
|
|
||||||
* @property timestamp timestamp
|
|
||||||
* @property direction transaction direction
|
|
||||||
*/
|
|
||||||
data class Approve(
|
|
||||||
override val txHash: String,
|
|
||||||
override val address: TextReference,
|
|
||||||
override val amount: String,
|
|
||||||
override val timestamp: String,
|
|
||||||
override val status: Status,
|
|
||||||
override val direction: Direction,
|
|
||||||
override val onClick: () -> Unit,
|
|
||||||
) : Content()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Completed swapping transaction state
|
|
||||||
*
|
|
||||||
* @property txHash transaction hash
|
|
||||||
* @property address address
|
|
||||||
* @property amount amount
|
|
||||||
* @property timestamp timestamp
|
|
||||||
* @property direction transaction direction
|
|
||||||
*/
|
|
||||||
data class Swap(
|
|
||||||
override val txHash: String,
|
|
||||||
override val address: TextReference,
|
|
||||||
override val amount: String,
|
|
||||||
override val timestamp: String,
|
|
||||||
override val status: Status,
|
|
||||||
override val direction: Direction,
|
|
||||||
override val onClick: () -> Unit,
|
|
||||||
) : Content()
|
|
||||||
|
|
||||||
data class Custom(
|
|
||||||
override val txHash: String,
|
|
||||||
override val address: TextReference,
|
|
||||||
override val amount: String,
|
|
||||||
override val timestamp: String,
|
|
||||||
override val status: Status,
|
|
||||||
override val direction: Direction,
|
|
||||||
override val onClick: () -> Unit,
|
|
||||||
val title: TextReference,
|
|
||||||
val subtitle: TextReference,
|
|
||||||
) : Content()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loading state
|
* Loading state
|
||||||
*
|
*
|
||||||
|
|
|
||||||
125
domain/legacy/src/main/assets/contract_methods.json
Normal file
125
domain/legacy/src/main/assets/contract_methods.json
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
{
|
||||||
|
"0xa9059cbb":{
|
||||||
|
"info":"ERC20",
|
||||||
|
"source":"https://eips.ethereum.org/EIPS/eip-20",
|
||||||
|
"name":"transfer"
|
||||||
|
},
|
||||||
|
"0x095ea7b3":{
|
||||||
|
"info":"ERC20",
|
||||||
|
"source":"https://eips.ethereum.org/EIPS/eip-20",
|
||||||
|
"name":"approve"
|
||||||
|
},
|
||||||
|
"0x357a150b":{
|
||||||
|
"info":"ERC721",
|
||||||
|
"source":"https://eips.ethereum.org/EIPS/eip-721",
|
||||||
|
"name":"run"
|
||||||
|
},
|
||||||
|
"0x23b872dd":{
|
||||||
|
"info":"ERC721",
|
||||||
|
"source":"https://eips.ethereum.org/EIPS/eip-721",
|
||||||
|
"name":"transferFrom"
|
||||||
|
},
|
||||||
|
"0x87201b41":{
|
||||||
|
"info":"ERC721",
|
||||||
|
"source":"https://eips.ethereum.org/EIPS/eip-721",
|
||||||
|
"name":"fulfillAvailableAdvancedOrders"
|
||||||
|
},
|
||||||
|
"0xe449f341":{
|
||||||
|
"info":"ERC721",
|
||||||
|
"source":"https://eips.ethereum.org/EIPS/eip-721",
|
||||||
|
"name":"unstake"
|
||||||
|
},
|
||||||
|
"0x84bb1e42":{
|
||||||
|
"info":"ERC721",
|
||||||
|
"source":"https://eips.ethereum.org/EIPS/eip-721",
|
||||||
|
"name":"claim"
|
||||||
|
},
|
||||||
|
"0xd48c03e5":{
|
||||||
|
"info":"ERC1155",
|
||||||
|
"source":"https://eips.ethereum.org/EIPS/eip-1155",
|
||||||
|
"name":"mint"
|
||||||
|
},
|
||||||
|
"0xe3afe0a3":{
|
||||||
|
"info":"Lido",
|
||||||
|
"source":"https://github.com/LedgerHQ/app-plugin-lido#smart-contracts",
|
||||||
|
"name":"withdrawal"
|
||||||
|
},
|
||||||
|
"0xd6681042":{
|
||||||
|
"info":"Lido",
|
||||||
|
"source":"https://github.com/LedgerHQ/app-plugin-lido#smart-contracts",
|
||||||
|
"name":"withdrawal"
|
||||||
|
},
|
||||||
|
"0x19aa6257":{
|
||||||
|
"info":"Lido",
|
||||||
|
"source":"https://github.com/LedgerHQ/app-plugin-lido#smart-contracts",
|
||||||
|
"name":"withdrawal"
|
||||||
|
},
|
||||||
|
"0xacf41e4d":{
|
||||||
|
"info":"Lido",
|
||||||
|
"source":"https://github.com/LedgerHQ/app-plugin-lido#smart-contracts",
|
||||||
|
"name":"withdrawal"
|
||||||
|
},
|
||||||
|
"0x7951b76f":{
|
||||||
|
"info":"Lido",
|
||||||
|
"source":"https://github.com/LedgerHQ/app-plugin-lido#smart-contracts",
|
||||||
|
"name":"withdrawal"
|
||||||
|
},
|
||||||
|
"0xa1903eab":{
|
||||||
|
"info":"Lido",
|
||||||
|
"source":"https://github.com/LedgerHQ/app-plugin-lido#smart-contracts",
|
||||||
|
"name":"submit"
|
||||||
|
},
|
||||||
|
"0x617ba037":{
|
||||||
|
"info":"AAVE",
|
||||||
|
"source":"https://etherscan.io/address/0x87870bca3f3fd6335c3f4ce8392d69350b4fa4e2",
|
||||||
|
"name":"supply"
|
||||||
|
},
|
||||||
|
"0x69328dec":{
|
||||||
|
"info":"AAVE",
|
||||||
|
"source":"https://etherscan.io/address/0x87870bca3f3fd6335c3f4ce8392d69350b4fa4e2",
|
||||||
|
"name":"withdraw"
|
||||||
|
},
|
||||||
|
"0x3ccfd60b":{
|
||||||
|
"info":"AAVE",
|
||||||
|
"source":"https://etherscan.io/address/0x87870bca3f3fd6335c3f4ce8392d69350b4fa4e2",
|
||||||
|
"name":"withdraw"
|
||||||
|
},
|
||||||
|
"0x573ade81":{
|
||||||
|
"info":"AAVE",
|
||||||
|
"source":"https://etherscan.io/address/0x87870bca3f3fd6335c3f4ce8392d69350b4fa4e2",
|
||||||
|
"name":"repay"
|
||||||
|
},
|
||||||
|
"0xa415bcad":{
|
||||||
|
"info":"AAVE",
|
||||||
|
"source":"https://etherscan.io/address/0x87870bca3f3fd6335c3f4ce8392d69350b4fa4e2",
|
||||||
|
"name":"borrow"
|
||||||
|
},
|
||||||
|
"0x12aa3caf":{
|
||||||
|
"info":"1inch v5",
|
||||||
|
"source":"https://github.com/LedgerHQ/app-plugin-1inch#functions-implemented",
|
||||||
|
"name":"swap"
|
||||||
|
},
|
||||||
|
"0x7c025200":{
|
||||||
|
"info":"1inch",
|
||||||
|
"source":"https://github.com/LedgerHQ/app-plugin-1inch#functions-implemented",
|
||||||
|
"name":"swap"
|
||||||
|
},
|
||||||
|
"0x2e95b6c8":{
|
||||||
|
"info":"1inch",
|
||||||
|
"source":"https://github.com/LedgerHQ/app-plugin-1inch#functions-implemented",
|
||||||
|
"name":"unoswap"
|
||||||
|
},
|
||||||
|
"0x0502b1c5":{
|
||||||
|
"info":"1inch",
|
||||||
|
"source":"https://github.com/LedgerHQ/app-plugin-1inch#functions-implemented",
|
||||||
|
"name":"unoswap"
|
||||||
|
},
|
||||||
|
"0x3593564c": {
|
||||||
|
"info":"unoswap",
|
||||||
|
"source":"https://etherscan.io/address/0x3fc91a3afd70395cd496c647d5a6cc9d4b2b7fad",
|
||||||
|
"name":"execute"
|
||||||
|
},
|
||||||
|
"0xd0e30db0": {
|
||||||
|
"name":"deposit"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,8 @@ import arrow.core.Either
|
||||||
import arrow.core.raise.either
|
import arrow.core.raise.either
|
||||||
import arrow.core.raise.ensureNotNull
|
import arrow.core.raise.ensureNotNull
|
||||||
import arrow.core.right
|
import arrow.core.right
|
||||||
|
import android.content.res.AssetManager
|
||||||
|
import com.squareup.moshi.Moshi
|
||||||
import com.tangem.blockchain.blockchains.polkadot.ExistentialDepositProvider
|
import com.tangem.blockchain.blockchains.polkadot.ExistentialDepositProvider
|
||||||
import com.tangem.blockchain.blockchains.solana.RentProvider
|
import com.tangem.blockchain.blockchains.solana.RentProvider
|
||||||
import com.tangem.blockchain.common.*
|
import com.tangem.blockchain.common.*
|
||||||
|
|
@ -41,6 +43,8 @@ class DefaultWalletManagersFacade(
|
||||||
private val walletManagersStore: WalletManagersStore,
|
private val walletManagersStore: WalletManagersStore,
|
||||||
private val userWalletsStore: UserWalletsStore,
|
private val userWalletsStore: UserWalletsStore,
|
||||||
configManager: ConfigManager,
|
configManager: ConfigManager,
|
||||||
|
assetManager: AssetManager,
|
||||||
|
moshi: Moshi,
|
||||||
) : WalletManagersFacade {
|
) : WalletManagersFacade {
|
||||||
|
|
||||||
private val demoConfig by lazy { DemoConfig() }
|
private val demoConfig by lazy { DemoConfig() }
|
||||||
|
|
@ -48,7 +52,7 @@ class DefaultWalletManagersFacade(
|
||||||
private val walletManagerFactory by lazy { WalletManagerFactory(configManager) }
|
private val walletManagerFactory by lazy { WalletManagerFactory(configManager) }
|
||||||
private val sdkTokenConverter by lazy { SdkTokenConverter() }
|
private val sdkTokenConverter by lazy { SdkTokenConverter() }
|
||||||
private val txHistoryStateConverter by lazy { SdkTransactionHistoryStateConverter() }
|
private val txHistoryStateConverter by lazy { SdkTransactionHistoryStateConverter() }
|
||||||
private val txHistoryItemConverter by lazy { SdkTransactionHistoryItemConverter() }
|
private val txHistoryItemConverter by lazy { SdkTransactionHistoryItemConverter(assetManager, moshi) }
|
||||||
|
|
||||||
override suspend fun update(
|
override suspend fun update(
|
||||||
userWalletId: UserWalletId,
|
userWalletId: UserWalletId,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.tangem.domain.walletmanager.model
|
||||||
|
|
||||||
|
import com.squareup.moshi.Json
|
||||||
|
import com.squareup.moshi.JsonClass
|
||||||
|
|
||||||
|
@JsonClass(generateAdapter = true)
|
||||||
|
data class SmartContractMethod(
|
||||||
|
@Json(name = "info") val info: String?,
|
||||||
|
@Json(name = "source") val source: String?,
|
||||||
|
@Json(name = "name") val name: String,
|
||||||
|
)
|
||||||
|
|
@ -1,44 +1,93 @@
|
||||||
package com.tangem.domain.walletmanager.utils
|
package com.tangem.domain.walletmanager.utils
|
||||||
|
|
||||||
|
import android.content.res.AssetManager
|
||||||
|
import com.squareup.moshi.Moshi
|
||||||
import com.tangem.blockchain.common.txhistory.TransactionHistoryItem
|
import com.tangem.blockchain.common.txhistory.TransactionHistoryItem
|
||||||
import com.tangem.domain.txhistory.models.TxHistoryItem
|
import com.tangem.domain.txhistory.models.TxHistoryItem
|
||||||
import com.tangem.utils.converter.Converter
|
import com.tangem.utils.converter.Converter
|
||||||
import com.tangem.blockchain.common.txhistory.TransactionHistoryItem as SdkTransactionHistoryItem
|
import com.tangem.blockchain.common.txhistory.TransactionHistoryItem as SdkTransactionHistoryItem
|
||||||
|
|
||||||
internal class SdkTransactionHistoryItemConverter : Converter<SdkTransactionHistoryItem, TxHistoryItem> {
|
internal class SdkTransactionHistoryItemConverter(
|
||||||
|
assetManager: AssetManager,
|
||||||
|
moshi: Moshi,
|
||||||
|
) : Converter<SdkTransactionHistoryItem, TxHistoryItem> {
|
||||||
|
|
||||||
|
private val typeConverter by lazy {
|
||||||
|
SdkTransactionTypeConverter(assetManager, moshi)
|
||||||
|
}
|
||||||
|
|
||||||
override fun convert(value: SdkTransactionHistoryItem): TxHistoryItem = TxHistoryItem(
|
override fun convert(value: SdkTransactionHistoryItem): TxHistoryItem = TxHistoryItem(
|
||||||
txHash = value.txHash,
|
txHash = value.txHash,
|
||||||
timestampInMillis = value.timestamp,
|
timestampInMillis = value.timestamp,
|
||||||
direction = value.direction.toDomain(),
|
isOutgoing = value.isOutgoing,
|
||||||
|
destinationType = value.destinationType.toDomain(),
|
||||||
|
sourceType = value.sourceType.toDomain(),
|
||||||
|
interactionAddressType = value.extractInteractionAddressType(),
|
||||||
status = when (value.status) {
|
status = when (value.status) {
|
||||||
TransactionHistoryItem.TransactionStatus.Confirmed -> TxHistoryItem.TransactionStatus.Confirmed
|
SdkTransactionHistoryItem.TransactionStatus.Confirmed -> TxHistoryItem.TransactionStatus.Confirmed
|
||||||
TransactionHistoryItem.TransactionStatus.Failed -> TxHistoryItem.TransactionStatus.Failed
|
SdkTransactionHistoryItem.TransactionStatus.Failed -> TxHistoryItem.TransactionStatus.Failed
|
||||||
TransactionHistoryItem.TransactionStatus.Unconfirmed -> TxHistoryItem.TransactionStatus.Unconfirmed
|
SdkTransactionHistoryItem.TransactionStatus.Unconfirmed -> TxHistoryItem.TransactionStatus.Unconfirmed
|
||||||
},
|
|
||||||
type = when (val type = value.type) {
|
|
||||||
TransactionHistoryItem.TransactionType.Transfer -> TxHistoryItem.TransactionType.Transfer
|
|
||||||
TransactionHistoryItem.TransactionType.Approve -> TxHistoryItem.TransactionType.Approve
|
|
||||||
is TransactionHistoryItem.TransactionType.Custom -> TxHistoryItem.TransactionType.Custom(type.id)
|
|
||||||
TransactionHistoryItem.TransactionType.Deposit -> TxHistoryItem.TransactionType.Deposit
|
|
||||||
TransactionHistoryItem.TransactionType.Submit -> TxHistoryItem.TransactionType.Submit
|
|
||||||
TransactionHistoryItem.TransactionType.Supply -> TxHistoryItem.TransactionType.Supply
|
|
||||||
TransactionHistoryItem.TransactionType.Swap -> TxHistoryItem.TransactionType.Swap
|
|
||||||
TransactionHistoryItem.TransactionType.Unoswap -> TxHistoryItem.TransactionType.Unoswap
|
|
||||||
TransactionHistoryItem.TransactionType.Withdraw -> TxHistoryItem.TransactionType.Withdraw
|
|
||||||
},
|
},
|
||||||
|
type = typeConverter.convert(value.type),
|
||||||
amount = requireNotNull(value.amount.value) { "Transaction amount value must not be null" },
|
amount = requireNotNull(value.amount.value) { "Transaction amount value must not be null" },
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun TransactionHistoryItem.TransactionDirection.toDomain() = when (this) {
|
private fun SdkTransactionHistoryItem.SourceType.toDomain(): TxHistoryItem.SourceType = when (this) {
|
||||||
is TransactionHistoryItem.TransactionDirection.Incoming ->
|
is TransactionHistoryItem.SourceType.Single -> TxHistoryItem.SourceType.Single(address)
|
||||||
TxHistoryItem.TransactionDirection.Incoming(address.toDomain())
|
is TransactionHistoryItem.SourceType.Multiple -> TxHistoryItem.SourceType.Multiple(addresses)
|
||||||
is TransactionHistoryItem.TransactionDirection.Outgoing ->
|
|
||||||
TxHistoryItem.TransactionDirection.Outgoing(address.toDomain())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun TransactionHistoryItem.Address.toDomain(): TxHistoryItem.Address = when (this) {
|
private fun SdkTransactionHistoryItem.DestinationType.toDomain(): TxHistoryItem.DestinationType = when (this) {
|
||||||
TransactionHistoryItem.Address.Multiple -> TxHistoryItem.Address.Multiple
|
is SdkTransactionHistoryItem.DestinationType.Single -> TxHistoryItem.DestinationType.Single(
|
||||||
is TransactionHistoryItem.Address.Single -> TxHistoryItem.Address.Single(rawAddress = rawAddress)
|
addressType.toDomain(),
|
||||||
|
)
|
||||||
|
is SdkTransactionHistoryItem.DestinationType.Multiple -> TxHistoryItem.DestinationType.Multiple(
|
||||||
|
addressTypes.map { it.toDomain() },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun SdkTransactionHistoryItem.AddressType.toDomain(): TxHistoryItem.AddressType = when (this) {
|
||||||
|
is SdkTransactionHistoryItem.AddressType.Contract -> TxHistoryItem.AddressType.Contract(address)
|
||||||
|
is SdkTransactionHistoryItem.AddressType.User -> TxHistoryItem.AddressType.User(address)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun SdkTransactionHistoryItem.extractInteractionAddressType(): TxHistoryItem.InteractionAddressType {
|
||||||
|
return when (type) {
|
||||||
|
SdkTransactionHistoryItem.TransactionType.Transfer -> if (isOutgoing) {
|
||||||
|
mapToInteractionAddressType(destinationType = destinationType)
|
||||||
|
} else {
|
||||||
|
mapToInteractionAddressType(sourceType = sourceType)
|
||||||
|
}
|
||||||
|
is SdkTransactionHistoryItem.TransactionType.ContractMethod -> mapToInteractionAddressType(destinationType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun mapToInteractionAddressType(
|
||||||
|
destinationType: SdkTransactionHistoryItem.DestinationType,
|
||||||
|
): TxHistoryItem.InteractionAddressType {
|
||||||
|
return when (destinationType) {
|
||||||
|
is TransactionHistoryItem.DestinationType.Multiple -> TxHistoryItem.InteractionAddressType.Multiple(
|
||||||
|
destinationType.addressTypes.map { it.address },
|
||||||
|
)
|
||||||
|
is TransactionHistoryItem.DestinationType.Single -> when (destinationType.addressType) {
|
||||||
|
is TransactionHistoryItem.AddressType.Contract -> TxHistoryItem.InteractionAddressType.Contract(
|
||||||
|
destinationType.addressType.address,
|
||||||
|
)
|
||||||
|
is TransactionHistoryItem.AddressType.User -> TxHistoryItem.InteractionAddressType.User(
|
||||||
|
destinationType.addressType.address,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun mapToInteractionAddressType(
|
||||||
|
sourceType: SdkTransactionHistoryItem.SourceType,
|
||||||
|
): TxHistoryItem.InteractionAddressType {
|
||||||
|
return when (sourceType) {
|
||||||
|
is TransactionHistoryItem.SourceType.Multiple -> TxHistoryItem.InteractionAddressType.Multiple(
|
||||||
|
sourceType.addresses,
|
||||||
|
)
|
||||||
|
is TransactionHistoryItem.SourceType.Single -> TxHistoryItem.InteractionAddressType.User(sourceType.address)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
package com.tangem.domain.walletmanager.utils
|
||||||
|
|
||||||
|
import android.content.res.AssetManager
|
||||||
|
import com.squareup.moshi.JsonAdapter
|
||||||
|
import com.squareup.moshi.Moshi
|
||||||
|
import com.squareup.moshi.Types
|
||||||
|
import com.tangem.blockchain.common.txhistory.TransactionHistoryItem
|
||||||
|
import com.tangem.domain.txhistory.models.TxHistoryItem
|
||||||
|
import com.tangem.domain.walletmanager.model.SmartContractMethod
|
||||||
|
import com.tangem.utils.converter.Converter
|
||||||
|
import okio.buffer
|
||||||
|
import okio.source
|
||||||
|
|
||||||
|
class SdkTransactionTypeConverter(
|
||||||
|
private val assetManager: AssetManager,
|
||||||
|
private val moshi: Moshi,
|
||||||
|
) : Converter<TransactionHistoryItem.TransactionType, TxHistoryItem.TransactionType> {
|
||||||
|
|
||||||
|
private val adapter: JsonAdapter<Map<String, SmartContractMethod>> by lazy {
|
||||||
|
moshi.adapter(
|
||||||
|
Types.newParameterizedType(
|
||||||
|
Map::class.java,
|
||||||
|
String::class.java,
|
||||||
|
SmartContractMethod::class.java,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
private val smartContractMethods by lazy { readSmartContractMethods() }
|
||||||
|
|
||||||
|
override fun convert(value: TransactionHistoryItem.TransactionType): TxHistoryItem.TransactionType {
|
||||||
|
return when (value) {
|
||||||
|
TransactionHistoryItem.TransactionType.Transfer -> TxHistoryItem.TransactionType.Transfer
|
||||||
|
is TransactionHistoryItem.TransactionType.ContractMethod -> {
|
||||||
|
return when (val name = smartContractMethods[value.id]?.name) {
|
||||||
|
"transfer" -> TxHistoryItem.TransactionType.Transfer
|
||||||
|
"approve" -> TxHistoryItem.TransactionType.Approve
|
||||||
|
"swap" -> TxHistoryItem.TransactionType.Swap
|
||||||
|
null -> TxHistoryItem.TransactionType.UnknownOperation
|
||||||
|
else -> TxHistoryItem.TransactionType.Operation(name = name.replaceFirstChar { it.titlecase() })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun readSmartContractMethods(): Map<String, SmartContractMethod> {
|
||||||
|
return assetManager.open("contract_methods.json").use { stream ->
|
||||||
|
adapter.fromJson(stream.source().buffer())
|
||||||
|
} ?: emptyMap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -118,18 +118,22 @@ internal class UpdateWalletManagerResultFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createTxHistoryItem(walletAddresses: Set<String>, data: TransactionData): TxHistoryItem? {
|
private fun createTxHistoryItem(walletAddresses: Set<String>, data: TransactionData): TxHistoryItem? {
|
||||||
val direction = extractDirection(walletAddresses, data) ?: run {
|
|
||||||
Timber.w("Can not determine address for $data")
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
val hash = data.hash ?: return null
|
val hash = data.hash ?: return null
|
||||||
val millis = data.date?.timeInMillis ?: return null
|
val millis = data.date?.timeInMillis ?: return null
|
||||||
val amount = getTransactionAmountValue(data.amount) ?: return null
|
val amount = getTransactionAmountValue(data.amount) ?: return null
|
||||||
|
val isOutgoing = data.sourceAddress in walletAddresses
|
||||||
|
|
||||||
return TxHistoryItem(
|
return TxHistoryItem(
|
||||||
txHash = hash,
|
txHash = hash,
|
||||||
timestampInMillis = TimeUnit.SECONDS.toMillis(millis),
|
timestampInMillis = TimeUnit.SECONDS.toMillis(millis),
|
||||||
direction = direction,
|
isOutgoing = isOutgoing,
|
||||||
|
destinationType = TxHistoryItem.DestinationType.Single(
|
||||||
|
TxHistoryItem.AddressType.User(data.destinationAddress),
|
||||||
|
),
|
||||||
|
sourceType = TxHistoryItem.SourceType.Single(data.sourceAddress),
|
||||||
|
interactionAddressType = TxHistoryItem.InteractionAddressType.User(
|
||||||
|
if (isOutgoing) data.destinationAddress else data.sourceAddress,
|
||||||
|
),
|
||||||
status = when (data.status) {
|
status = when (data.status) {
|
||||||
TransactionStatus.Confirmed -> TxHistoryItem.TransactionStatus.Confirmed
|
TransactionStatus.Confirmed -> TxHistoryItem.TransactionStatus.Confirmed
|
||||||
TransactionStatus.Unconfirmed -> TxHistoryItem.TransactionStatus.Unconfirmed
|
TransactionStatus.Unconfirmed -> TxHistoryItem.TransactionStatus.Unconfirmed
|
||||||
|
|
@ -139,35 +143,6 @@ internal class UpdateWalletManagerResultFactory {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun extractDirection(
|
|
||||||
walletAddresses: Set<String>,
|
|
||||||
data: TransactionData,
|
|
||||||
): TxHistoryItem.TransactionDirection? {
|
|
||||||
val fromAddress = data.sourceAddress
|
|
||||||
val toAddress = data.destinationAddress
|
|
||||||
|
|
||||||
return when {
|
|
||||||
toAddress in walletAddresses -> {
|
|
||||||
TxHistoryItem.TransactionDirection.Incoming(TxHistoryItem.Address.Single(fromAddress))
|
|
||||||
}
|
|
||||||
fromAddress in walletAddresses -> {
|
|
||||||
TxHistoryItem.TransactionDirection.Outgoing(TxHistoryItem.Address.Single(toAddress))
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
Timber.w(
|
|
||||||
"""
|
|
||||||
Unable to find transaction direction
|
|
||||||
|- To address: ${data.destinationAddress}
|
|
||||||
|- From address: ${data.sourceAddress}
|
|
||||||
|- Network addresses: $walletAddresses
|
|
||||||
""".trimIndent(),
|
|
||||||
)
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getAvailableAddresses(addresses: Set<Address>): Set<String> {
|
private fun getAvailableAddresses(addresses: Set<Address>): Set<String> {
|
||||||
return addresses.mapTo(hashSetOf()) { it.value }
|
return addresses.mapTo(hashSetOf()) { it.value }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,29 +5,39 @@ import java.math.BigDecimal
|
||||||
data class TxHistoryItem(
|
data class TxHistoryItem(
|
||||||
val txHash: String,
|
val txHash: String,
|
||||||
val timestampInMillis: Long,
|
val timestampInMillis: Long,
|
||||||
val direction: TransactionDirection,
|
val isOutgoing: Boolean,
|
||||||
|
val destinationType: DestinationType,
|
||||||
|
val sourceType: SourceType,
|
||||||
|
val interactionAddressType: InteractionAddressType,
|
||||||
val status: TransactionStatus,
|
val status: TransactionStatus,
|
||||||
val type: TransactionType,
|
val type: TransactionType,
|
||||||
val amount: BigDecimal,
|
val amount: BigDecimal,
|
||||||
) {
|
) {
|
||||||
sealed interface TransactionDirection {
|
|
||||||
|
|
||||||
val address: Address
|
sealed class DestinationType {
|
||||||
|
data class Single(val addressType: AddressType) : DestinationType()
|
||||||
|
data class Multiple(val addressTypes: List<AddressType>) : DestinationType()
|
||||||
|
}
|
||||||
|
|
||||||
data class Incoming(override val address: Address) : TransactionDirection
|
sealed class SourceType {
|
||||||
data class Outgoing(override val address: Address) : TransactionDirection
|
|
||||||
|
data class Single(val address: String) : SourceType()
|
||||||
|
data class Multiple(val addresses: List<String>) : SourceType()
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class AddressType {
|
||||||
|
abstract val address: String
|
||||||
|
|
||||||
|
data class User(override val address: String) : AddressType()
|
||||||
|
data class Contract(override val address: String) : AddressType()
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed interface TransactionType {
|
sealed interface TransactionType {
|
||||||
object Transfer : TransactionType
|
object Transfer : TransactionType
|
||||||
object Submit : TransactionType
|
|
||||||
object Approve : TransactionType
|
object Approve : TransactionType
|
||||||
object Supply : TransactionType
|
|
||||||
object Withdraw : TransactionType
|
|
||||||
object Deposit : TransactionType
|
|
||||||
object Swap : TransactionType
|
object Swap : TransactionType
|
||||||
object Unoswap : TransactionType
|
object UnknownOperation : TransactionType
|
||||||
data class Custom(val id: String) : TransactionType
|
data class Operation(val name: String) : TransactionType
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class TransactionStatus {
|
sealed class TransactionStatus {
|
||||||
|
|
@ -36,8 +46,9 @@ data class TxHistoryItem(
|
||||||
object Confirmed : TransactionStatus()
|
object Confirmed : TransactionStatus()
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class Address {
|
sealed class InteractionAddressType {
|
||||||
data class Single(val rawAddress: String) : Address()
|
data class User(val address: String) : InteractionAddressType()
|
||||||
object Multiple : Address()
|
data class Contract(val address: String) : InteractionAddressType()
|
||||||
|
data class Multiple(val addresses: List<String>) : InteractionAddressType()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -101,9 +101,7 @@ internal class TokenDetailsTxHistoryItemFlowConverter(
|
||||||
) {
|
) {
|
||||||
val txContent = txHistoryItemState.state as TransactionState.Content
|
val txContent = txHistoryItemState.state as TransactionState.Content
|
||||||
txHistoryItemState.copy(
|
txHistoryItemState.copy(
|
||||||
state = txContent.copySealed(
|
state = txContent.copy(timestamp = txContent.timestamp.toTimeFormat()),
|
||||||
timestamp = txContent.timestamp.toTimeFormat(),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
txHistoryItemState
|
txHistoryItemState
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,9 @@ package com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.
|
||||||
|
|
||||||
import com.tangem.core.ui.components.transactions.state.TransactionState
|
import com.tangem.core.ui.components.transactions.state.TransactionState
|
||||||
import com.tangem.core.ui.extensions.TextReference
|
import com.tangem.core.ui.extensions.TextReference
|
||||||
|
import com.tangem.core.ui.extensions.resourceReference
|
||||||
|
import com.tangem.core.ui.extensions.stringReference
|
||||||
|
import com.tangem.core.ui.extensions.wrappedList
|
||||||
import com.tangem.core.ui.utils.DateTimeFormatters
|
import com.tangem.core.ui.utils.DateTimeFormatters
|
||||||
import com.tangem.domain.txhistory.models.TxHistoryItem
|
import com.tangem.domain.txhistory.models.TxHistoryItem
|
||||||
import com.tangem.feature.tokendetails.presentation.tokendetails.viewmodels.TokenDetailsClickIntents
|
import com.tangem.feature.tokendetails.presentation.tokendetails.viewmodels.TokenDetailsClickIntents
|
||||||
|
|
@ -22,121 +25,65 @@ internal class TokenDetailsTxHistoryToTransactionStateConverter(
|
||||||
return createTransactionStateItem(item = value)
|
return createTransactionStateItem(item = value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Finalize transaction types [REDACTED_JIRA]
|
|
||||||
@Suppress("LongMethod")
|
|
||||||
private fun createTransactionStateItem(item: TxHistoryItem): TransactionState {
|
private fun createTransactionStateItem(item: TxHistoryItem): TransactionState {
|
||||||
return when (val type = item.type) {
|
return TransactionState.Content(
|
||||||
TxHistoryItem.TransactionType.Transfer -> mapTransfer(item)
|
txHash = item.txHash,
|
||||||
TxHistoryItem.TransactionType.Approve -> mapApprove(item)
|
address = stringReference("mocked address"),
|
||||||
TxHistoryItem.TransactionType.Swap -> mapSwap(item)
|
amount = item.getAmount(),
|
||||||
TxHistoryItem.TransactionType.Deposit -> TransactionState.Custom(
|
timestamp = item.timestampInMillis.toTimeFormat(),
|
||||||
txHash = item.txHash,
|
status = item.status.tiUiStatus(),
|
||||||
address = item.direction.extractAddress(),
|
direction = item.extractDirection(),
|
||||||
amount = item.getAmount(),
|
iconRes = item.extractIcon(),
|
||||||
timestamp = item.timestampInMillis.toTimeFormat(),
|
title = item.extractTitle(),
|
||||||
status = item.status.tiUiStatus(),
|
subtitle = item.extractSubtitle(),
|
||||||
direction = item.direction.toUiDirection(),
|
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
||||||
title = TextReference.Str("Deposit"),
|
)
|
||||||
subtitle = item.direction.extractAddress(),
|
}
|
||||||
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
|
||||||
)
|
private fun TxHistoryItem.extractIcon(): Int = if (status == TxHistoryItem.TransactionStatus.Failed) {
|
||||||
TxHistoryItem.TransactionType.Submit -> TransactionState.Custom(
|
R.drawable.ic_close_24
|
||||||
txHash = item.txHash,
|
} else {
|
||||||
address = item.direction.extractAddress(),
|
when (type) {
|
||||||
amount = item.getAmount(),
|
is TxHistoryItem.TransactionType.Approve -> R.drawable.ic_doc_24
|
||||||
timestamp = item.timestampInMillis.toTimeFormat(),
|
is TxHistoryItem.TransactionType.Operation,
|
||||||
status = item.status.tiUiStatus(),
|
is TxHistoryItem.TransactionType.Swap,
|
||||||
direction = item.direction.toUiDirection(),
|
is TxHistoryItem.TransactionType.Transfer,
|
||||||
title = TextReference.Str("Submit"),
|
is TxHistoryItem.TransactionType.UnknownOperation,
|
||||||
subtitle = item.direction.extractAddress(),
|
-> if (isOutgoing) R.drawable.ic_arrow_up_24 else R.drawable.ic_arrow_down_24
|
||||||
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
|
||||||
)
|
|
||||||
TxHistoryItem.TransactionType.Supply -> TransactionState.Custom(
|
|
||||||
txHash = item.txHash,
|
|
||||||
address = item.direction.extractAddress(),
|
|
||||||
amount = item.getAmount(),
|
|
||||||
timestamp = item.timestampInMillis.toTimeFormat(),
|
|
||||||
status = item.status.tiUiStatus(),
|
|
||||||
direction = item.direction.toUiDirection(),
|
|
||||||
title = TextReference.Str("Supply"),
|
|
||||||
subtitle = item.direction.extractAddress(),
|
|
||||||
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
|
||||||
)
|
|
||||||
TxHistoryItem.TransactionType.Unoswap -> TransactionState.Custom(
|
|
||||||
txHash = item.txHash,
|
|
||||||
address = item.direction.extractAddress(),
|
|
||||||
amount = item.getAmount(),
|
|
||||||
timestamp = item.timestampInMillis.toTimeFormat(),
|
|
||||||
status = item.status.tiUiStatus(),
|
|
||||||
direction = item.direction.toUiDirection(),
|
|
||||||
title = TextReference.Str("Unoswap"),
|
|
||||||
subtitle = item.direction.extractAddress(),
|
|
||||||
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
|
||||||
)
|
|
||||||
TxHistoryItem.TransactionType.Withdraw -> TransactionState.Custom(
|
|
||||||
txHash = item.txHash,
|
|
||||||
address = item.direction.extractAddress(),
|
|
||||||
amount = item.getAmount(),
|
|
||||||
timestamp = item.timestampInMillis.toTimeFormat(),
|
|
||||||
status = item.status.tiUiStatus(),
|
|
||||||
direction = item.direction.toUiDirection(),
|
|
||||||
title = TextReference.Str("Withdraw"),
|
|
||||||
subtitle = item.direction.extractAddress(),
|
|
||||||
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
|
||||||
)
|
|
||||||
is TxHistoryItem.TransactionType.Custom -> TransactionState.Custom(
|
|
||||||
txHash = item.txHash,
|
|
||||||
address = item.direction.extractAddress(),
|
|
||||||
amount = item.getAmount(),
|
|
||||||
timestamp = item.timestampInMillis.toTimeFormat(),
|
|
||||||
status = item.status.tiUiStatus(),
|
|
||||||
direction = item.direction.toUiDirection(),
|
|
||||||
title = TextReference.Str(type.id),
|
|
||||||
subtitle = item.direction.extractAddress(),
|
|
||||||
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mapTransfer(item: TxHistoryItem): TransactionState {
|
private fun TxHistoryItem.extractTitle(): TextReference = when (val type = type) {
|
||||||
return TransactionState.Transfer(
|
is TxHistoryItem.TransactionType.Approve -> resourceReference(R.string.common_approval)
|
||||||
txHash = item.txHash,
|
is TxHistoryItem.TransactionType.Operation -> stringReference(type.name)
|
||||||
address = item.direction.extractAddress(),
|
is TxHistoryItem.TransactionType.Swap -> resourceReference(R.string.common_swap)
|
||||||
amount = item.getAmount(),
|
is TxHistoryItem.TransactionType.Transfer -> resourceReference(R.string.common_transfer)
|
||||||
timestamp = item.timestampInMillis.toTimeFormat(),
|
is TxHistoryItem.TransactionType.UnknownOperation -> resourceReference(R.string.transaction_history_operation)
|
||||||
status = item.status.tiUiStatus(),
|
|
||||||
direction = item.direction.toUiDirection(),
|
|
||||||
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mapApprove(item: TxHistoryItem): TransactionState {
|
private fun TxHistoryItem.extractSubtitle(): TextReference =
|
||||||
return TransactionState.Approve(
|
when (val interactionAddress = interactionAddressType) {
|
||||||
txHash = item.txHash,
|
is TxHistoryItem.InteractionAddressType.Contract -> resourceReference(
|
||||||
address = item.direction.extractAddress(),
|
id = R.string.transaction_history_contract_address,
|
||||||
amount = item.getAmount(),
|
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
|
||||||
timestamp = item.timestampInMillis.toTimeFormat(),
|
)
|
||||||
status = item.status.tiUiStatus(),
|
is TxHistoryItem.InteractionAddressType.Multiple -> resourceReference(
|
||||||
direction = item.direction.toUiDirection(),
|
id = if (isOutgoing) {
|
||||||
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
R.string.transaction_history_transaction_to_address
|
||||||
)
|
} else {
|
||||||
}
|
R.string.transaction_history_transaction_from_address
|
||||||
private fun mapSwap(item: TxHistoryItem): TransactionState {
|
},
|
||||||
return TransactionState.Swap(
|
formatArgs = wrappedList(resourceReference(R.string.transaction_history_multiple_addresses)),
|
||||||
txHash = item.txHash,
|
)
|
||||||
address = item.direction.extractAddress(),
|
is TxHistoryItem.InteractionAddressType.User -> resourceReference(
|
||||||
amount = item.getAmount(),
|
id = if (isOutgoing) {
|
||||||
timestamp = item.timestampInMillis.toTimeFormat(),
|
R.string.transaction_history_transaction_to_address
|
||||||
status = item.status.tiUiStatus(),
|
} else {
|
||||||
direction = item.direction.toUiDirection(),
|
R.string.transaction_history_transaction_from_address
|
||||||
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
},
|
||||||
)
|
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
|
||||||
}
|
)
|
||||||
|
}
|
||||||
private fun TxHistoryItem.TransactionDirection.extractAddress(): TextReference = when (val addr = address) {
|
|
||||||
TxHistoryItem.Address.Multiple -> TextReference.Res(R.string.transaction_history_multiple_addresses)
|
|
||||||
is TxHistoryItem.Address.Single -> TextReference.Str(addr.rawAddress.toBriefAddressFormat())
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun TxHistoryItem.TransactionStatus.tiUiStatus() = when (this) {
|
private fun TxHistoryItem.TransactionStatus.tiUiStatus() = when (this) {
|
||||||
TxHistoryItem.TransactionStatus.Confirmed -> TransactionState.Content.Status.Confirmed
|
TxHistoryItem.TransactionStatus.Confirmed -> TransactionState.Content.Status.Confirmed
|
||||||
|
|
@ -148,16 +95,11 @@ internal class TokenDetailsTxHistoryToTransactionStateConverter(
|
||||||
return DateTimeFormatters.formatTime(time = DateTime(this, DateTimeZone.getDefault()))
|
return DateTimeFormatters.formatTime(time = DateTime(this, DateTimeZone.getDefault()))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun TxHistoryItem.TransactionDirection.toUiDirection() = when (this) {
|
private fun TxHistoryItem.extractDirection() =
|
||||||
is TxHistoryItem.TransactionDirection.Incoming -> TransactionState.Content.Direction.INCOMING
|
if (isOutgoing) TransactionState.Content.Direction.OUTGOING else TransactionState.Content.Direction.INCOMING
|
||||||
is TxHistoryItem.TransactionDirection.Outgoing -> TransactionState.Content.Direction.OUTGOING
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun TxHistoryItem.getAmount(): String {
|
private fun TxHistoryItem.getAmount(): String {
|
||||||
val prefix = when (direction) {
|
val prefix = if (isOutgoing) "-" else "+"
|
||||||
is TxHistoryItem.TransactionDirection.Incoming -> "+"
|
|
||||||
is TxHistoryItem.TransactionDirection.Outgoing -> "-"
|
|
||||||
}
|
|
||||||
return prefix + amount.toFormattedCurrencyString(currency = symbol, decimals = decimals)
|
return prefix + amount.toFormattedCurrencyString(currency = symbol, decimals = decimals)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,11 @@
|
||||||
package com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.txhistory
|
package com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.txhistory
|
||||||
|
|
||||||
import com.tangem.core.ui.components.transactions.state.TransactionState
|
import com.tangem.core.ui.components.transactions.state.TransactionState
|
||||||
|
import com.tangem.core.ui.components.transactions.state.TransactionState.Content.Direction
|
||||||
import com.tangem.core.ui.extensions.TextReference
|
import com.tangem.core.ui.extensions.TextReference
|
||||||
|
import com.tangem.core.ui.extensions.resourceReference
|
||||||
|
import com.tangem.core.ui.extensions.stringReference
|
||||||
|
import com.tangem.core.ui.extensions.wrappedList
|
||||||
import com.tangem.domain.txhistory.models.TxHistoryItem
|
import com.tangem.domain.txhistory.models.TxHistoryItem
|
||||||
import com.tangem.feature.tokendetails.presentation.tokendetails.viewmodels.TokenDetailsClickIntents
|
import com.tangem.feature.tokendetails.presentation.tokendetails.viewmodels.TokenDetailsClickIntents
|
||||||
import com.tangem.features.tokendetails.impl.R
|
import com.tangem.features.tokendetails.impl.R
|
||||||
|
|
@ -19,116 +23,68 @@ internal class TokenDetailsTxHistoryTransactionStateConverter(
|
||||||
return createTransactionStateItem(item = value)
|
return createTransactionStateItem(item = value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Finalize transaction types [REDACTED_JIRA]
|
|
||||||
@Suppress("LongMethod")
|
@Suppress("LongMethod")
|
||||||
private fun createTransactionStateItem(item: TxHistoryItem): TransactionState {
|
private fun createTransactionStateItem(item: TxHistoryItem): TransactionState {
|
||||||
return when (val type = item.type) {
|
return TransactionState.Content(
|
||||||
TxHistoryItem.TransactionType.Transfer -> mapTransfer(item)
|
txHash = item.txHash,
|
||||||
TxHistoryItem.TransactionType.Approve -> mapApprove(item)
|
address = stringReference("mocked address"),
|
||||||
TxHistoryItem.TransactionType.Swap -> mapSwap(item)
|
amount = item.getAmount(),
|
||||||
TxHistoryItem.TransactionType.Deposit -> TransactionState.Custom(
|
timestamp = item.getRawTimestamp(),
|
||||||
txHash = item.txHash,
|
status = item.status.tiUiStatus(),
|
||||||
address = item.direction.extractAddress(),
|
direction = item.extractDirection(),
|
||||||
amount = item.getAmount(),
|
iconRes = item.extractIcon(),
|
||||||
timestamp = item.getRawTimestamp(),
|
title = item.extractTitle(),
|
||||||
status = item.status.tiUiStatus(),
|
subtitle = item.extractSubtitle(),
|
||||||
direction = item.direction.toUiDirection(),
|
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
||||||
title = TextReference.Str("Deposit"),
|
)
|
||||||
subtitle = item.direction.extractAddress(),
|
}
|
||||||
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
|
||||||
)
|
private fun TxHistoryItem.extractIcon(): Int = if (status == TxHistoryItem.TransactionStatus.Failed) {
|
||||||
TxHistoryItem.TransactionType.Submit -> TransactionState.Custom(
|
R.drawable.ic_close_24
|
||||||
txHash = item.txHash,
|
} else {
|
||||||
address = item.direction.extractAddress(),
|
when (type) {
|
||||||
amount = item.getAmount(),
|
is TxHistoryItem.TransactionType.Approve -> R.drawable.ic_doc_24
|
||||||
timestamp = item.getRawTimestamp(),
|
is TxHistoryItem.TransactionType.Operation,
|
||||||
status = item.status.tiUiStatus(),
|
is TxHistoryItem.TransactionType.Swap,
|
||||||
direction = item.direction.toUiDirection(),
|
is TxHistoryItem.TransactionType.Transfer,
|
||||||
title = TextReference.Str("Submit"),
|
is TxHistoryItem.TransactionType.UnknownOperation,
|
||||||
subtitle = item.direction.extractAddress(),
|
-> if (isOutgoing) R.drawable.ic_arrow_up_24 else R.drawable.ic_arrow_down_24
|
||||||
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
|
||||||
)
|
|
||||||
TxHistoryItem.TransactionType.Supply -> TransactionState.Custom(
|
|
||||||
txHash = item.txHash,
|
|
||||||
address = item.direction.extractAddress(),
|
|
||||||
amount = item.getAmount(),
|
|
||||||
timestamp = item.getRawTimestamp(),
|
|
||||||
status = item.status.tiUiStatus(),
|
|
||||||
direction = item.direction.toUiDirection(),
|
|
||||||
title = TextReference.Str("Supply"),
|
|
||||||
subtitle = item.direction.extractAddress(),
|
|
||||||
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
|
||||||
)
|
|
||||||
TxHistoryItem.TransactionType.Unoswap -> TransactionState.Custom(
|
|
||||||
txHash = item.txHash,
|
|
||||||
address = item.direction.extractAddress(),
|
|
||||||
amount = item.getAmount(),
|
|
||||||
timestamp = item.getRawTimestamp(),
|
|
||||||
status = item.status.tiUiStatus(),
|
|
||||||
direction = item.direction.toUiDirection(),
|
|
||||||
title = TextReference.Str("Unoswap"),
|
|
||||||
subtitle = item.direction.extractAddress(),
|
|
||||||
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
|
||||||
)
|
|
||||||
TxHistoryItem.TransactionType.Withdraw -> TransactionState.Custom(
|
|
||||||
txHash = item.txHash,
|
|
||||||
address = item.direction.extractAddress(),
|
|
||||||
amount = item.getAmount(),
|
|
||||||
timestamp = item.getRawTimestamp(),
|
|
||||||
status = item.status.tiUiStatus(),
|
|
||||||
direction = item.direction.toUiDirection(),
|
|
||||||
title = TextReference.Str("Withdraw"),
|
|
||||||
subtitle = item.direction.extractAddress(),
|
|
||||||
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
|
||||||
)
|
|
||||||
is TxHistoryItem.TransactionType.Custom -> TransactionState.Custom(
|
|
||||||
txHash = item.txHash,
|
|
||||||
address = item.direction.extractAddress(),
|
|
||||||
amount = item.getAmount(),
|
|
||||||
timestamp = item.getRawTimestamp(),
|
|
||||||
status = item.status.tiUiStatus(),
|
|
||||||
direction = item.direction.toUiDirection(),
|
|
||||||
title = TextReference.Str(type.id),
|
|
||||||
subtitle = item.direction.extractAddress(),
|
|
||||||
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mapTransfer(item: TxHistoryItem): TransactionState {
|
private fun TxHistoryItem.extractTitle(): TextReference = when (val type = type) {
|
||||||
return TransactionState.Transfer(
|
is TxHistoryItem.TransactionType.Approve -> resourceReference(R.string.common_approval)
|
||||||
txHash = item.txHash,
|
is TxHistoryItem.TransactionType.Operation -> stringReference(type.name)
|
||||||
address = item.direction.extractAddress(),
|
is TxHistoryItem.TransactionType.Swap -> resourceReference(R.string.common_swap)
|
||||||
amount = item.getAmount(),
|
is TxHistoryItem.TransactionType.Transfer -> resourceReference(R.string.common_transfer)
|
||||||
timestamp = item.getRawTimestamp(),
|
is TxHistoryItem.TransactionType.UnknownOperation -> resourceReference(R.string.transaction_history_operation)
|
||||||
status = item.status.tiUiStatus(),
|
|
||||||
direction = item.direction.toUiDirection(),
|
|
||||||
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mapApprove(item: TxHistoryItem): TransactionState {
|
private fun TxHistoryItem.extractSubtitle(): TextReference =
|
||||||
return TransactionState.Approve(
|
when (val interactionAddress = interactionAddressType) {
|
||||||
txHash = item.txHash,
|
is TxHistoryItem.InteractionAddressType.Contract -> resourceReference(
|
||||||
address = item.direction.extractAddress(),
|
id = R.string.transaction_history_contract_address,
|
||||||
amount = item.getAmount(),
|
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
|
||||||
timestamp = item.getRawTimestamp(),
|
)
|
||||||
status = item.status.tiUiStatus(),
|
is TxHistoryItem.InteractionAddressType.Multiple -> resourceReference(
|
||||||
direction = item.direction.toUiDirection(),
|
id = if (isOutgoing) {
|
||||||
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
R.string.transaction_history_transaction_to_address
|
||||||
)
|
} else {
|
||||||
}
|
R.string.transaction_history_transaction_from_address
|
||||||
private fun mapSwap(item: TxHistoryItem): TransactionState {
|
},
|
||||||
return TransactionState.Swap(
|
formatArgs = wrappedList(resourceReference(R.string.transaction_history_multiple_addresses)),
|
||||||
txHash = item.txHash,
|
)
|
||||||
address = item.direction.extractAddress(),
|
is TxHistoryItem.InteractionAddressType.User -> resourceReference(
|
||||||
amount = item.getAmount(),
|
id = if (isOutgoing) {
|
||||||
timestamp = item.getRawTimestamp(),
|
R.string.transaction_history_transaction_to_address
|
||||||
status = item.status.tiUiStatus(),
|
} else {
|
||||||
direction = item.direction.toUiDirection(),
|
R.string.transaction_history_transaction_from_address
|
||||||
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
},
|
||||||
)
|
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
|
||||||
}
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun TxHistoryItem.extractDirection() = if (isOutgoing) Direction.OUTGOING else Direction.INCOMING
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get timestamp without formatting.
|
* Get timestamp without formatting.
|
||||||
|
|
@ -138,27 +94,14 @@ internal class TokenDetailsTxHistoryTransactionStateConverter(
|
||||||
*/
|
*/
|
||||||
private fun TxHistoryItem.getRawTimestamp() = this.timestampInMillis.toString()
|
private fun TxHistoryItem.getRawTimestamp() = this.timestampInMillis.toString()
|
||||||
|
|
||||||
private fun TxHistoryItem.TransactionDirection.extractAddress(): TextReference = when (val addr = address) {
|
|
||||||
TxHistoryItem.Address.Multiple -> TextReference.Res(R.string.transaction_history_multiple_addresses)
|
|
||||||
is TxHistoryItem.Address.Single -> TextReference.Str(addr.rawAddress.toBriefAddressFormat())
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun TxHistoryItem.TransactionStatus.tiUiStatus() = when (this) {
|
private fun TxHistoryItem.TransactionStatus.tiUiStatus() = when (this) {
|
||||||
TxHistoryItem.TransactionStatus.Confirmed -> TransactionState.Content.Status.Confirmed
|
TxHistoryItem.TransactionStatus.Confirmed -> TransactionState.Content.Status.Confirmed
|
||||||
TxHistoryItem.TransactionStatus.Failed -> TransactionState.Content.Status.Failed
|
TxHistoryItem.TransactionStatus.Failed -> TransactionState.Content.Status.Failed
|
||||||
TxHistoryItem.TransactionStatus.Unconfirmed -> TransactionState.Content.Status.Unconfirmed
|
TxHistoryItem.TransactionStatus.Unconfirmed -> TransactionState.Content.Status.Unconfirmed
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun TxHistoryItem.TransactionDirection.toUiDirection() = when (this) {
|
|
||||||
is TxHistoryItem.TransactionDirection.Incoming -> TransactionState.Content.Direction.INCOMING
|
|
||||||
is TxHistoryItem.TransactionDirection.Outgoing -> TransactionState.Content.Direction.OUTGOING
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun TxHistoryItem.getAmount(): String {
|
private fun TxHistoryItem.getAmount(): String {
|
||||||
val prefix = when (direction) {
|
val prefix = if (isOutgoing) "-" else "+"
|
||||||
is TxHistoryItem.TransactionDirection.Incoming -> "+"
|
|
||||||
is TxHistoryItem.TransactionDirection.Outgoing -> "-"
|
|
||||||
}
|
|
||||||
return prefix + amount.toFormattedCurrencyString(currency = symbol, decimals = decimals)
|
return prefix + amount.toFormattedCurrencyString(currency = symbol, decimals = decimals)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -9,6 +9,7 @@ import com.tangem.core.ui.components.transactions.state.TransactionState
|
||||||
import com.tangem.core.ui.components.transactions.state.TxHistoryState
|
import com.tangem.core.ui.components.transactions.state.TxHistoryState
|
||||||
import com.tangem.core.ui.event.consumedEvent
|
import com.tangem.core.ui.event.consumedEvent
|
||||||
import com.tangem.core.ui.extensions.TextReference
|
import com.tangem.core.ui.extensions.TextReference
|
||||||
|
import com.tangem.core.ui.extensions.resourceReference
|
||||||
import com.tangem.core.ui.extensions.stringReference
|
import com.tangem.core.ui.extensions.stringReference
|
||||||
import com.tangem.core.ui.res.TangemColorPalette
|
import com.tangem.core.ui.res.TangemColorPalette
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
|
|
@ -417,25 +418,31 @@ internal object WalletPreviewData {
|
||||||
listOf(
|
listOf(
|
||||||
TxHistoryState.TxHistoryItemState.GroupTitle("Today"),
|
TxHistoryState.TxHistoryItemState.GroupTitle("Today"),
|
||||||
TxHistoryState.TxHistoryItemState.Transaction(
|
TxHistoryState.TxHistoryItemState.Transaction(
|
||||||
TransactionState.Transfer(
|
TransactionState.Content(
|
||||||
txHash = UUID.randomUUID().toString(),
|
txHash = UUID.randomUUID().toString(),
|
||||||
address = TextReference.Str("33BddS...ga2B"),
|
address = TextReference.Str("33BddS...ga2B"),
|
||||||
amount = "-0.500913 BTC",
|
amount = "-0.500913 BTC",
|
||||||
timestamp = "8:41",
|
timestamp = "8:41",
|
||||||
status = TransactionState.Content.Status.Unconfirmed,
|
status = TransactionState.Content.Status.Unconfirmed,
|
||||||
direction = TransactionState.Content.Direction.OUTGOING,
|
direction = TransactionState.Content.Direction.OUTGOING,
|
||||||
|
iconRes = com.tangem.core.ui.R.drawable.ic_arrow_up_24,
|
||||||
|
title = resourceReference(com.tangem.core.ui.R.string.common_transfer),
|
||||||
|
subtitle = TextReference.Str("33BddS...ga2B"),
|
||||||
onClick = {},
|
onClick = {},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
TxHistoryState.TxHistoryItemState.GroupTitle("Yesterday"),
|
TxHistoryState.TxHistoryItemState.GroupTitle("Yesterday"),
|
||||||
TxHistoryState.TxHistoryItemState.Transaction(
|
TxHistoryState.TxHistoryItemState.Transaction(
|
||||||
TransactionState.Transfer(
|
TransactionState.Content(
|
||||||
txHash = UUID.randomUUID().toString(),
|
txHash = UUID.randomUUID().toString(),
|
||||||
address = TextReference.Str("33BddS...ga2B"),
|
address = TextReference.Str("33BddS...ga2B"),
|
||||||
amount = "-0.500913 BTC",
|
amount = "-0.500913 BTC",
|
||||||
timestamp = "8:41",
|
timestamp = "8:41",
|
||||||
status = TransactionState.Content.Status.Confirmed,
|
status = TransactionState.Content.Status.Confirmed,
|
||||||
direction = TransactionState.Content.Direction.OUTGOING,
|
direction = TransactionState.Content.Direction.OUTGOING,
|
||||||
|
iconRes = com.tangem.core.ui.R.drawable.ic_arrow_up_24,
|
||||||
|
title = resourceReference(com.tangem.core.ui.R.string.common_transfer),
|
||||||
|
subtitle = TextReference.Str("33BddS...ga2B"),
|
||||||
onClick = {},
|
onClick = {},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -109,9 +109,7 @@ internal class WalletTxHistoryItemFlowConverter(
|
||||||
) {
|
) {
|
||||||
val txContent = txHistoryItemState.state as TransactionState.Content
|
val txContent = txHistoryItemState.state as TransactionState.Content
|
||||||
txHistoryItemState.copy(
|
txHistoryItemState.copy(
|
||||||
state = txContent.copySealed(
|
state = txContent.copy(timestamp = txContent.timestamp.toTimeFormat()),
|
||||||
timestamp = txContent.timestamp.toTimeFormat(),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
txHistoryItemState
|
txHistoryItemState
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,9 @@ package com.tangem.feature.wallet.presentation.wallet.state.factory.txhistory
|
||||||
|
|
||||||
import com.tangem.core.ui.components.transactions.state.TransactionState
|
import com.tangem.core.ui.components.transactions.state.TransactionState
|
||||||
import com.tangem.core.ui.extensions.TextReference
|
import com.tangem.core.ui.extensions.TextReference
|
||||||
|
import com.tangem.core.ui.extensions.resourceReference
|
||||||
|
import com.tangem.core.ui.extensions.stringReference
|
||||||
|
import com.tangem.core.ui.extensions.wrappedList
|
||||||
import com.tangem.domain.txhistory.models.TxHistoryItem
|
import com.tangem.domain.txhistory.models.TxHistoryItem
|
||||||
import com.tangem.feature.wallet.impl.R
|
import com.tangem.feature.wallet.impl.R
|
||||||
import com.tangem.feature.wallet.presentation.wallet.viewmodels.WalletClickIntents
|
import com.tangem.feature.wallet.presentation.wallet.viewmodels.WalletClickIntents
|
||||||
|
|
@ -19,116 +22,69 @@ internal class WalletTxHistoryTransactionStateConverter(
|
||||||
return createTransactionStateItem(item = value)
|
return createTransactionStateItem(item = value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Finalize transaction types [REDACTED_JIRA]
|
|
||||||
@Suppress("LongMethod")
|
@Suppress("LongMethod")
|
||||||
private fun createTransactionStateItem(item: TxHistoryItem): TransactionState {
|
private fun createTransactionStateItem(item: TxHistoryItem): TransactionState {
|
||||||
return when (val type = item.type) {
|
return TransactionState.Content(
|
||||||
TxHistoryItem.TransactionType.Transfer -> mapTransfer(item)
|
txHash = item.txHash,
|
||||||
TxHistoryItem.TransactionType.Approve -> mapApprove(item)
|
address = stringReference("mocked address"),
|
||||||
TxHistoryItem.TransactionType.Swap -> mapSwap(item)
|
amount = item.getAmount(),
|
||||||
TxHistoryItem.TransactionType.Deposit -> TransactionState.Custom(
|
timestamp = item.getRawTimestamp(),
|
||||||
txHash = item.txHash,
|
status = item.status.tiUiStatus(),
|
||||||
address = item.direction.extractAddress(),
|
direction = item.extractDirection(),
|
||||||
amount = item.getAmount(),
|
iconRes = item.extractIcon(),
|
||||||
timestamp = item.getRawTimestamp(),
|
title = item.extractTitle(),
|
||||||
status = item.status.tiUiStatus(),
|
subtitle = item.extractSubtitle(),
|
||||||
direction = item.direction.toUiDirection(),
|
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
||||||
title = TextReference.Str("Deposit"),
|
)
|
||||||
subtitle = item.direction.extractAddress(),
|
}
|
||||||
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
|
||||||
)
|
private fun TxHistoryItem.extractIcon(): Int = if (status == TxHistoryItem.TransactionStatus.Failed) {
|
||||||
TxHistoryItem.TransactionType.Submit -> TransactionState.Custom(
|
R.drawable.ic_close_24
|
||||||
txHash = item.txHash,
|
} else {
|
||||||
address = item.direction.extractAddress(),
|
when (type) {
|
||||||
amount = item.getAmount(),
|
is TxHistoryItem.TransactionType.Approve -> R.drawable.ic_doc_24
|
||||||
timestamp = item.getRawTimestamp(),
|
is TxHistoryItem.TransactionType.Operation,
|
||||||
status = item.status.tiUiStatus(),
|
is TxHistoryItem.TransactionType.Swap,
|
||||||
direction = item.direction.toUiDirection(),
|
is TxHistoryItem.TransactionType.Transfer,
|
||||||
title = TextReference.Str("Submit"),
|
is TxHistoryItem.TransactionType.UnknownOperation,
|
||||||
subtitle = item.direction.extractAddress(),
|
-> if (isOutgoing) R.drawable.ic_arrow_up_24 else R.drawable.ic_arrow_down_24
|
||||||
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
|
||||||
)
|
|
||||||
TxHistoryItem.TransactionType.Supply -> TransactionState.Custom(
|
|
||||||
txHash = item.txHash,
|
|
||||||
address = item.direction.extractAddress(),
|
|
||||||
amount = item.getAmount(),
|
|
||||||
timestamp = item.getRawTimestamp(),
|
|
||||||
status = item.status.tiUiStatus(),
|
|
||||||
direction = item.direction.toUiDirection(),
|
|
||||||
title = TextReference.Str("Supply"),
|
|
||||||
subtitle = item.direction.extractAddress(),
|
|
||||||
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
|
||||||
)
|
|
||||||
TxHistoryItem.TransactionType.Unoswap -> TransactionState.Custom(
|
|
||||||
txHash = item.txHash,
|
|
||||||
address = item.direction.extractAddress(),
|
|
||||||
amount = item.getAmount(),
|
|
||||||
timestamp = item.getRawTimestamp(),
|
|
||||||
status = item.status.tiUiStatus(),
|
|
||||||
direction = item.direction.toUiDirection(),
|
|
||||||
title = TextReference.Str("Unoswap"),
|
|
||||||
subtitle = item.direction.extractAddress(),
|
|
||||||
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
|
||||||
)
|
|
||||||
TxHistoryItem.TransactionType.Withdraw -> TransactionState.Custom(
|
|
||||||
txHash = item.txHash,
|
|
||||||
address = item.direction.extractAddress(),
|
|
||||||
amount = item.getAmount(),
|
|
||||||
timestamp = item.getRawTimestamp(),
|
|
||||||
status = item.status.tiUiStatus(),
|
|
||||||
direction = item.direction.toUiDirection(),
|
|
||||||
title = TextReference.Str("Withdraw"),
|
|
||||||
subtitle = item.direction.extractAddress(),
|
|
||||||
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
|
||||||
)
|
|
||||||
is TxHistoryItem.TransactionType.Custom -> TransactionState.Custom(
|
|
||||||
txHash = item.txHash,
|
|
||||||
address = item.direction.extractAddress(),
|
|
||||||
amount = item.getAmount(),
|
|
||||||
timestamp = item.getRawTimestamp(),
|
|
||||||
status = item.status.tiUiStatus(),
|
|
||||||
direction = item.direction.toUiDirection(),
|
|
||||||
title = TextReference.Str(type.id),
|
|
||||||
subtitle = item.direction.extractAddress(),
|
|
||||||
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mapTransfer(item: TxHistoryItem): TransactionState {
|
private fun TxHistoryItem.extractTitle(): TextReference = when (val type = type) {
|
||||||
return TransactionState.Transfer(
|
is TxHistoryItem.TransactionType.Approve -> resourceReference(R.string.common_approval)
|
||||||
txHash = item.txHash,
|
is TxHistoryItem.TransactionType.Operation -> stringReference(type.name)
|
||||||
address = item.direction.extractAddress(),
|
is TxHistoryItem.TransactionType.Swap -> resourceReference(R.string.common_swap)
|
||||||
amount = item.getAmount(),
|
is TxHistoryItem.TransactionType.Transfer -> resourceReference(R.string.common_transfer)
|
||||||
timestamp = item.getRawTimestamp(),
|
is TxHistoryItem.TransactionType.UnknownOperation -> resourceReference(R.string.transaction_history_operation)
|
||||||
status = item.status.tiUiStatus(),
|
|
||||||
direction = item.direction.toUiDirection(),
|
|
||||||
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mapApprove(item: TxHistoryItem): TransactionState {
|
private fun TxHistoryItem.extractSubtitle(): TextReference =
|
||||||
return TransactionState.Approve(
|
when (val interactionAddress = interactionAddressType) {
|
||||||
txHash = item.txHash,
|
is TxHistoryItem.InteractionAddressType.Contract -> resourceReference(
|
||||||
address = item.direction.extractAddress(),
|
id = R.string.transaction_history_contract_address,
|
||||||
amount = item.getAmount(),
|
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
|
||||||
timestamp = item.getRawTimestamp(),
|
)
|
||||||
status = item.status.tiUiStatus(),
|
is TxHistoryItem.InteractionAddressType.Multiple -> resourceReference(
|
||||||
direction = item.direction.toUiDirection(),
|
id = if (isOutgoing) {
|
||||||
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
R.string.transaction_history_transaction_to_address
|
||||||
)
|
} else {
|
||||||
}
|
R.string.transaction_history_transaction_from_address
|
||||||
private fun mapSwap(item: TxHistoryItem): TransactionState {
|
},
|
||||||
return TransactionState.Swap(
|
formatArgs = wrappedList(resourceReference(R.string.transaction_history_multiple_addresses)),
|
||||||
txHash = item.txHash,
|
)
|
||||||
address = item.direction.extractAddress(),
|
is TxHistoryItem.InteractionAddressType.User -> resourceReference(
|
||||||
amount = item.getAmount(),
|
id = if (isOutgoing) {
|
||||||
timestamp = item.getRawTimestamp(),
|
R.string.transaction_history_transaction_to_address
|
||||||
status = item.status.tiUiStatus(),
|
} else {
|
||||||
direction = item.direction.toUiDirection(),
|
R.string.transaction_history_transaction_from_address
|
||||||
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
},
|
||||||
)
|
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
|
||||||
}
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun TxHistoryItem.extractDirection() =
|
||||||
|
if (isOutgoing) TransactionState.Content.Direction.OUTGOING else TransactionState.Content.Direction.INCOMING
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get timestamp without formatting.
|
* Get timestamp without formatting.
|
||||||
|
|
@ -138,27 +94,14 @@ internal class WalletTxHistoryTransactionStateConverter(
|
||||||
*/
|
*/
|
||||||
private fun TxHistoryItem.getRawTimestamp() = this.timestampInMillis.toString()
|
private fun TxHistoryItem.getRawTimestamp() = this.timestampInMillis.toString()
|
||||||
|
|
||||||
private fun TxHistoryItem.TransactionDirection.extractAddress(): TextReference = when (val addr = address) {
|
|
||||||
TxHistoryItem.Address.Multiple -> TextReference.Res(R.string.transaction_history_multiple_addresses)
|
|
||||||
is TxHistoryItem.Address.Single -> TextReference.Str(addr.rawAddress.toBriefAddressFormat())
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun TxHistoryItem.TransactionStatus.tiUiStatus() = when (this) {
|
private fun TxHistoryItem.TransactionStatus.tiUiStatus() = when (this) {
|
||||||
TxHistoryItem.TransactionStatus.Confirmed -> TransactionState.Content.Status.Confirmed
|
TxHistoryItem.TransactionStatus.Confirmed -> TransactionState.Content.Status.Confirmed
|
||||||
TxHistoryItem.TransactionStatus.Failed -> TransactionState.Content.Status.Failed
|
TxHistoryItem.TransactionStatus.Failed -> TransactionState.Content.Status.Failed
|
||||||
TxHistoryItem.TransactionStatus.Unconfirmed -> TransactionState.Content.Status.Unconfirmed
|
TxHistoryItem.TransactionStatus.Unconfirmed -> TransactionState.Content.Status.Unconfirmed
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun TxHistoryItem.TransactionDirection.toUiDirection() = when (this) {
|
|
||||||
is TxHistoryItem.TransactionDirection.Incoming -> TransactionState.Content.Direction.INCOMING
|
|
||||||
is TxHistoryItem.TransactionDirection.Outgoing -> TransactionState.Content.Direction.OUTGOING
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun TxHistoryItem.getAmount(): String {
|
private fun TxHistoryItem.getAmount(): String {
|
||||||
val prefix = when (direction) {
|
val prefix = if (isOutgoing) "-" else "+"
|
||||||
is TxHistoryItem.TransactionDirection.Incoming -> "+"
|
|
||||||
is TxHistoryItem.TransactionDirection.Outgoing -> "-"
|
|
||||||
}
|
|
||||||
return prefix + amount.toFormattedCurrencyString(currency = symbol, decimals = decimals)
|
return prefix + amount.toFormattedCurrencyString(currency = symbol, decimals = decimals)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -83,8 +83,8 @@ spr-client = "3.6.2"
|
||||||
# endregion Other libraries
|
# endregion Other libraries
|
||||||
|
|
||||||
# region Tangem
|
# region Tangem
|
||||||
tangemBlockchainSdk = "release-app_5.0-363"
|
#tangemBlockchainSdk = "release-app_5.0-363"
|
||||||
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
|
tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
|
||||||
tangemCardSdk = "release-app_5.0-308"
|
tangemCardSdk = "release-app_5.0-308"
|
||||||
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds
|
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds
|
||||||
# endregion Tangem
|
# endregion Tangem
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue