Updated on 2026-08-14
This commit is contained in:
commit
0470e1f010
1144 changed files with 48463 additions and 11166 deletions
|
|
@ -18,11 +18,11 @@ data class TokenReceiveConfig(
|
|||
|
||||
@Serializable
|
||||
data class ReceiveAddressModel(
|
||||
val nameService: NameService,
|
||||
val displayType: DisplayType,
|
||||
val value: String,
|
||||
) {
|
||||
enum class NameService {
|
||||
Default, Legacy, Ens
|
||||
enum class DisplayType {
|
||||
Default, Legacy, Ens, Dynamic,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ data class AccountId private constructor(
|
|||
|
||||
companion object {
|
||||
|
||||
const val PaymentAccountIdPrefix = "payment_"
|
||||
|
||||
private val sha256Digest: MessageDigest by lazy { MessageDigest.getInstance("SHA-256") }
|
||||
private val hexRegex = Regex("^[a-fA-F0-9]{64}$")
|
||||
|
||||
|
|
@ -73,7 +75,7 @@ data class AccountId private constructor(
|
|||
}
|
||||
|
||||
fun forPaymentAccount(userWalletId: UserWalletId): AccountId {
|
||||
return AccountId(value = "payment_$userWalletId", userWalletId = userWalletId)
|
||||
return AccountId(value = "$PaymentAccountIdPrefix$userWalletId", userWalletId = userWalletId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
package com.tangem.domain.models.account
|
||||
|
||||
import arrow.core.Either
|
||||
import arrow.core.raise.either
|
||||
import arrow.core.raise.ensure
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
@ConsistentCopyVisibility
|
||||
data class CardDisplayName private constructor(val value: String) {
|
||||
|
||||
@Serializable
|
||||
sealed interface Error {
|
||||
@Serializable
|
||||
data object Empty : Error
|
||||
|
||||
@Serializable
|
||||
data object ExceedsMaxLength : Error
|
||||
|
||||
@Serializable
|
||||
data object InvalidCharacters : Error
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val MAX_LENGTH = 20
|
||||
private val allowedPattern = Regex("^[\\p{L}\\p{N} ]+$")
|
||||
|
||||
operator fun invoke(name: String): Either<Error, CardDisplayName> = either {
|
||||
val trimmed = name.trim()
|
||||
ensure(trimmed.isNotEmpty()) { Error.Empty }
|
||||
ensure(trimmed.length <= MAX_LENGTH) { Error.ExceedsMaxLength }
|
||||
ensure(allowedPattern.matches(trimmed)) { Error.InvalidCharacters }
|
||||
CardDisplayName(trimmed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,9 +2,15 @@ package com.tangem.domain.models.account
|
|||
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.TotalFiatBalance
|
||||
import com.tangem.domain.models.account.PaymentAccountStatusValue.Loaded
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.kyc.KycStatus
|
||||
import com.tangem.domain.models.network.NetworkAddress
|
||||
import com.tangem.domain.models.pay.TangemPayCard
|
||||
import com.tangem.domain.models.serialization.SerializedBigDecimal
|
||||
import kotlinx.serialization.Serializable
|
||||
import java.math.BigDecimal
|
||||
|
||||
/**
|
||||
* Represents the various states a payment account can have, encapsulating different information based on the state.
|
||||
|
|
@ -25,7 +31,6 @@ sealed class PaymentAccountStatusValue {
|
|||
is UnderReview,
|
||||
-> TotalFiatBalance.Loaded(amount = SerializedBigDecimal.ZERO, source = source)
|
||||
is Loading -> TotalFiatBalance.Loading
|
||||
is Locked -> TotalFiatBalance.Loaded(amount = fiatBalance.availableBalance, source = source)
|
||||
is Loaded -> TotalFiatBalance.Loaded(amount = fiatBalance.availableBalance, source = source)
|
||||
}
|
||||
|
||||
|
|
@ -38,7 +43,6 @@ sealed class PaymentAccountStatusValue {
|
|||
return when (this) {
|
||||
is IssuingCard -> copy(source = source)
|
||||
is Loaded -> copy(source = source)
|
||||
is Locked -> copy(source = source)
|
||||
is UnderReview -> copy(source = source)
|
||||
is Loading,
|
||||
is Empty,
|
||||
|
|
@ -88,57 +92,49 @@ sealed class PaymentAccountStatusValue {
|
|||
@Serializable
|
||||
data class IssuingCard(override val source: StatusSource) : PaymentAccountStatusValue()
|
||||
|
||||
/**
|
||||
* Represents a state where the payment account is locked.
|
||||
*
|
||||
* @property source The source of the status information.
|
||||
* @property customerId The unique identifier of the customer.
|
||||
* @property cardId The unique identifier of the card.
|
||||
* @property lastFourDigits The last four digits of the card number.
|
||||
* @property currencyCode The code of the currency.
|
||||
* @property depositAddress The address for deposits, if available.
|
||||
* @property isPinSet Indicates if the PIN is set for the card.
|
||||
* @property fiatBalance The fiat balance details.
|
||||
* @property cryptoBalance The crypto balance details.
|
||||
*/
|
||||
@Serializable
|
||||
data class Locked(
|
||||
override val source: StatusSource,
|
||||
val customerId: String,
|
||||
val cardId: String,
|
||||
val lastFourDigits: String,
|
||||
val currencyCode: String,
|
||||
val depositAddress: String?,
|
||||
val isPinSet: Boolean,
|
||||
val fiatBalance: FiatBalance,
|
||||
val cryptoBalance: CryptoBalance,
|
||||
) : PaymentAccountStatusValue()
|
||||
|
||||
/**
|
||||
* Represents a state where the payment account is successfully loaded with complete information.
|
||||
*
|
||||
* @property source The source of the status information.
|
||||
* @property customerId The unique identifier of the customer.
|
||||
* @property cardId The unique identifier of the card.
|
||||
* @property lastFourDigits The last four digits of the card number.
|
||||
* @property currencyCode The code of the currency.
|
||||
* @property depositAddress The address for deposits, if available.
|
||||
* @property isPinSet Indicates if the PIN is set for the card.
|
||||
* @property fiatBalance The fiat balance details.
|
||||
* @property cryptoBalance The crypto balance details.
|
||||
* @property cards The list of user's cards.
|
||||
*/
|
||||
@Serializable
|
||||
data class Loaded(
|
||||
override val source: StatusSource,
|
||||
val customerId: String,
|
||||
val cardId: String,
|
||||
val lastFourDigits: String,
|
||||
val currencyCode: String,
|
||||
val depositAddress: String?,
|
||||
val isPinSet: Boolean,
|
||||
val fiatBalance: FiatBalance,
|
||||
val cryptoBalance: CryptoBalance,
|
||||
) : PaymentAccountStatusValue()
|
||||
val cryptoCurrency: CryptoCurrency.Token,
|
||||
val cards: List<TangemPayCard>,
|
||||
) : PaymentAccountStatusValue() {
|
||||
val cryptoCurrencyStatus: CryptoCurrencyStatus = CryptoCurrencyStatus(
|
||||
currency = cryptoCurrency,
|
||||
value = CryptoCurrencyStatus.Loaded(
|
||||
amount = cryptoBalance.balance,
|
||||
fiatAmount = fiatBalance.availableBalance,
|
||||
fiatRate = BigDecimal.ONE,
|
||||
priceChange = BigDecimal.ZERO,
|
||||
networkAddress = NetworkAddress.Single(
|
||||
defaultAddress = NetworkAddress.Address(
|
||||
type = NetworkAddress.Address.Type.Primary,
|
||||
value = cryptoBalance.depositAddress,
|
||||
),
|
||||
),
|
||||
sources = CryptoCurrencyStatus.Sources(),
|
||||
pendingTransactions = emptySet(),
|
||||
stakingBalance = null,
|
||||
yieldSupplyStatus = null,
|
||||
hasCurrentNetworkTransactions = false,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
/** Represents an error state for the payment account status. */
|
||||
@Serializable
|
||||
|
|
@ -198,4 +194,10 @@ sealed class PaymentAccountStatusValue {
|
|||
val tokenContractAddress: String,
|
||||
val balance: SerializedBigDecimal,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun Loaded.hasCardWithId(cardId: String): Boolean = cards.any { it.id == cardId }
|
||||
|
||||
fun Loaded.findCardWithId(cardId: String): TangemPayCard? = cards.firstOrNull { it.id == cardId }
|
||||
|
||||
fun Loaded.requireCardWithId(cardId: String): TangemPayCard = requireNotNull(findCardWithId(cardId))
|
||||
|
|
@ -3,7 +3,7 @@ package com.tangem.domain.models.currency
|
|||
import java.math.BigDecimal
|
||||
|
||||
fun CryptoCurrency.Token.yieldSupplyKey(): String {
|
||||
return "${network.backendId}_$contractAddress"
|
||||
return "${network.rawId}_$contractAddress"
|
||||
}
|
||||
|
||||
fun CryptoCurrencyStatus.hasNotSuppliedAmount(): Boolean {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import kotlinx.serialization.Serializable
|
|||
* (e.g., ERC20, BEP20).
|
||||
*
|
||||
* @property id the unique identifier of the network
|
||||
* @property backendId the name of this network in the Tangem backend
|
||||
* @property name the human-readable name of the network, such as "Ethereum" or "Bitcoin"
|
||||
* @property currencySymbol the symbol of the currency associated with the network
|
||||
* @property derivationPath the path used to derive keys for this network
|
||||
|
|
@ -25,7 +24,6 @@ import kotlinx.serialization.Serializable
|
|||
@Serializable
|
||||
data class Network(
|
||||
val id: ID,
|
||||
val backendId: String,
|
||||
val name: String,
|
||||
val currencySymbol: String,
|
||||
val derivationPath: DerivationPath,
|
||||
|
|
@ -49,7 +47,7 @@ data class Network(
|
|||
/**
|
||||
* Represents a unique identifier for a blockchain network
|
||||
*
|
||||
* @property rawId raw network ID
|
||||
* @property rawId raw network ID (backend id)
|
||||
* @property derivationPath derivation path
|
||||
*/
|
||||
@Serializable
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
package com.tangem.domain.models.pay
|
||||
|
||||
import com.tangem.domain.models.account.CardDisplayName
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Represents a Tangem Pay card linked to a payment account.
|
||||
*
|
||||
* @property id unique card identifier assigned by the backend.
|
||||
* @property hasPinCode whether the card has a PIN code set.
|
||||
* @property displayName optional human-readable name assigned to the card; `null` if not set.
|
||||
* @property limit spending limit configuration for the card; `null` if not configured or not yet loaded.
|
||||
* @property isFrozen whether the card is currently frozen (blocked for payments).
|
||||
* @property lastDigits The last four digits of the card number.
|
||||
*/
|
||||
@Serializable
|
||||
data class TangemPayCard(
|
||||
@SerialName("id") val id: String,
|
||||
@SerialName("has_pin_code") val hasPinCode: Boolean,
|
||||
@SerialName("display_name") val displayName: CardDisplayName?,
|
||||
@SerialName("limit") val limit: TangemPayCardLimitData?,
|
||||
@SerialName("is_frozen") val isFrozen: Boolean,
|
||||
@SerialName("last_digits") val lastDigits: String,
|
||||
)
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package com.tangem.domain.models.pay
|
||||
|
||||
import com.tangem.domain.models.serialization.SerializedBigDecimal
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import java.util.Locale
|
||||
|
||||
@Serializable
|
||||
data class TangemPayCardLimit(
|
||||
@SerialName("amount") val amount: SerializedBigDecimal,
|
||||
@SerialName("period") val period: TangemPayCardLimitPeriod,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
enum class TangemPayCardLimitPeriod {
|
||||
@SerialName("DAY")
|
||||
DAY,
|
||||
|
||||
@SerialName("WEEK")
|
||||
WEEK,
|
||||
|
||||
@SerialName("MONTH")
|
||||
MONTH,
|
||||
|
||||
@SerialName("YEAR")
|
||||
YEAR,
|
||||
|
||||
@SerialName("ALL_TIME")
|
||||
ALL_TIME,
|
||||
|
||||
@SerialName("AUTHORIZATION")
|
||||
AUTHORIZATION,
|
||||
|
||||
@SerialName("UNKNOWN")
|
||||
UNKNOWN,
|
||||
;
|
||||
|
||||
companion object {
|
||||
fun fromString(value: String) = when (value.uppercase(Locale.US)) {
|
||||
"DAY" -> DAY
|
||||
"WEEK" -> WEEK
|
||||
"MONTH" -> MONTH
|
||||
"YEAR" -> YEAR
|
||||
"ALL_TIME" -> ALL_TIME
|
||||
"AUTHORIZATION" -> AUTHORIZATION
|
||||
else -> UNKNOWN
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.tangem.domain.models.pay
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class TangemPayCardLimitData(
|
||||
@SerialName("actual_card_limit") val actualCardLimit: TangemPayCardLimit?,
|
||||
@SerialName("admin_card_limit") val adminCardLimit: TangemPayCardLimit?,
|
||||
)
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.domain.models
|
||||
package com.tangem.domain.models.pay
|
||||
|
||||
enum class TangemPayEligibilityType {
|
||||
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.tangem.domain.models.pay
|
||||
|
||||
import java.math.BigDecimal
|
||||
|
||||
data class TangemPayReissueCardFee(
|
||||
val amount: BigDecimal,
|
||||
val currencyCode: String,
|
||||
)
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.tangem.domain.models.portfolio
|
||||
|
||||
import com.tangem.domain.models.account.AccountId
|
||||
import com.tangem.domain.models.account.AccountName
|
||||
import com.tangem.domain.models.account.CryptoPortfolioIcon
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
||||
data class UserAssetEntry(
|
||||
val userWalletId: UserWalletId,
|
||||
val userWalletName: String,
|
||||
val accountId: AccountId,
|
||||
val accountName: AccountName,
|
||||
val accountIcon: CryptoPortfolioIcon,
|
||||
val currencyStatus: CryptoCurrencyStatus,
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue