Updated on 2026-08-14
This commit is contained in:
parent
328271bc26
commit
8b6944e3e4
31 changed files with 1464 additions and 818 deletions
|
|
@ -29,4 +29,6 @@ fun String.toQrCode(sizePx: Int = 256, paddingPx: Int = 0): Bitmap {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return bmp
|
return bmp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun String.capitalize(): String = replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it.toString() }
|
||||||
|
|
@ -59,11 +59,7 @@ object DateTimeFormatters {
|
||||||
DateTimeFormat.forPattern("dd.MM.yyyy HH:mm")
|
DateTimeFormat.forPattern("dd.MM.yyyy HH:mm")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun formatTime(formatter: DateTimeFormatter = timeFormatter, time: DateTime): String {
|
fun formatDate(date: DateTime, formatter: DateTimeFormatter = dateFormatter): String {
|
||||||
return formatter.print(time)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun formatDate(formatter: DateTimeFormatter = dateFormatter, date: DateTime): String {
|
|
||||||
return formatter.print(date)
|
return formatter.print(date)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -29,5 +29,5 @@ fun Long.toDateFormat(formatter: DateTimeFormatter = DateTimeFormatters.dateForm
|
||||||
* Returns formatted time according to [formatter].
|
* Returns formatted time according to [formatter].
|
||||||
*/
|
*/
|
||||||
fun Long.toTimeFormat(formatter: DateTimeFormatter = DateTimeFormatters.timeFormatter): String {
|
fun Long.toTimeFormat(formatter: DateTimeFormatter = DateTimeFormatters.timeFormatter): String {
|
||||||
return DateTimeFormatters.formatTime(formatter = formatter, time = DateTime(this, DateTimeZone.getDefault()))
|
return DateTimeFormatters.formatDate(date = DateTime(this, DateTimeZone.getDefault()), formatter = formatter)
|
||||||
}
|
}
|
||||||
|
|
@ -26,7 +26,7 @@ dependencies {
|
||||||
implementation(projects.domain.legacy)
|
implementation(projects.domain.legacy)
|
||||||
|
|
||||||
/** Project - Libs */
|
/** Project - Libs */
|
||||||
implementation(projects.libs.visa)
|
debugImplementation(projects.libs.visa)
|
||||||
|
|
||||||
/** Libs - Other */
|
/** Libs - Other */
|
||||||
implementation(deps.kotlin.coroutines)
|
implementation(deps.kotlin.coroutines)
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ internal class DefaultVisaRepository(
|
||||||
|
|
||||||
override suspend fun getVisaCurrency(userWalletId: UserWalletId, isRefresh: Boolean): VisaCurrency {
|
override suspend fun getVisaCurrency(userWalletId: UserWalletId, isRefresh: Boolean): VisaCurrency {
|
||||||
val address = makeAddress(userWalletId)
|
val address = makeAddress(userWalletId)
|
||||||
// val address = "0x143fe062a538176aa0bf162f13d390208f90898f" // for testing
|
// val address = "0x40d8194b7168723ece51fa34d16825c60ba03dfa" // for testing
|
||||||
|
|
||||||
fetchVisaCurrencyIfExpired(address, isRefresh)
|
fetchVisaCurrencyIfExpired(address, isRefresh)
|
||||||
|
|
||||||
|
|
@ -97,7 +97,7 @@ internal class DefaultVisaRepository(
|
||||||
): Flow<PagingData<VisaTxHistoryItem>> {
|
): Flow<PagingData<VisaTxHistoryItem>> {
|
||||||
val userWallet = findVisaUserWallet(userWalletId)
|
val userWallet = findVisaUserWallet(userWalletId)
|
||||||
val cardPubKey = getCardPubKey(userWallet).toHexString()
|
val cardPubKey = getCardPubKey(userWallet).toHexString()
|
||||||
// val cardPubKey = "03DEF02B1FECC8BD3CFD52CE93235194479E1DE931EF0F55DC194967E7CCC3D12C" // for testing
|
// val cardPubKey = "02C2BBA0DA1E066EA968C1EB129499F6DEBC5FD82D70D61DCAF691CDB69AF5D8B9" // for testing
|
||||||
val pager = Pager(
|
val pager = Pager(
|
||||||
config = PagingConfig(
|
config = PagingConfig(
|
||||||
pageSize = pageSize,
|
pageSize = pageSize,
|
||||||
|
|
@ -125,7 +125,7 @@ internal class DefaultVisaRepository(
|
||||||
return withContext(dispatchers.io) {
|
return withContext(dispatchers.io) {
|
||||||
val userWallet = findVisaUserWallet(userWalletId)
|
val userWallet = findVisaUserWallet(userWalletId)
|
||||||
val cardPubKey = getCardPubKey(userWallet).toHexString()
|
val cardPubKey = getCardPubKey(userWallet).toHexString()
|
||||||
// val cardPubKey = "03DEF02B1FECC8BD3CFD52CE93235194479E1DE931EF0F55DC194967E7CCC3D12C" // for testing
|
// val cardPubKey = "02C2BBA0DA1E066EA968C1EB129499F6DEBC5FD82D70D61DCAF691CDB69AF5D8B9" // for testing
|
||||||
val transaction = fetchedHistoryItems.value[cardPubKey]?.firstOrNull {
|
val transaction = fetchedHistoryItems.value[cardPubKey]?.firstOrNull {
|
||||||
it.transactionId.toString() == txId
|
it.transactionId.toString() == txId
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
package com.tangem.data.visa.di
|
||||||
|
|
||||||
|
import com.squareup.moshi.Moshi
|
||||||
|
import com.tangem.data.common.cache.CacheRegistry
|
||||||
|
import com.tangem.data.visa.BuildConfig
|
||||||
|
import com.tangem.data.visa.DefaultVisaRepository
|
||||||
|
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||||
|
import com.tangem.datasource.di.NetworkMoshi
|
||||||
|
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||||
|
import com.tangem.domain.visa.repository.VisaRepository
|
||||||
|
import com.tangem.lib.visa.VisaContractInfoProvider
|
||||||
|
import com.tangem.lib.visa.api.VisaApiBuilder
|
||||||
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
internal object ImplementedVisaDataModule {
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@ImplementedVisaRepository
|
||||||
|
fun provideVisaRepository(
|
||||||
|
@NetworkMoshi moshi: Moshi,
|
||||||
|
tangemTechApi: TangemTechApi,
|
||||||
|
cacheRegistry: CacheRegistry,
|
||||||
|
userWalletsStore: UserWalletsStore,
|
||||||
|
dispatchers: CoroutineDispatcherProvider,
|
||||||
|
): VisaRepository {
|
||||||
|
val contractInfoProvider = VisaContractInfoProvider.Builder(
|
||||||
|
isNetworkLoggingEnabled = BuildConfig.LOG_ENABLED,
|
||||||
|
dispatchers = dispatchers,
|
||||||
|
).build()
|
||||||
|
val visaApi = VisaApiBuilder(
|
||||||
|
useDevApi = true,
|
||||||
|
isNetworkLoggingEnabled = BuildConfig.LOG_ENABLED,
|
||||||
|
moshi = moshi,
|
||||||
|
).build()
|
||||||
|
|
||||||
|
return DefaultVisaRepository(
|
||||||
|
contractInfoProvider,
|
||||||
|
tangemTechApi,
|
||||||
|
visaApi,
|
||||||
|
cacheRegistry,
|
||||||
|
userWalletsStore,
|
||||||
|
dispatchers,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -17,6 +17,7 @@ internal class VisaCurrencyFactory {
|
||||||
} else {
|
} else {
|
||||||
balancesAndLimits.newLimits
|
balancesAndLimits.newLimits
|
||||||
}
|
}
|
||||||
|
val remainingOtpLimit = getRemainingOtp(currentLimit, now)
|
||||||
|
|
||||||
return VisaCurrency(
|
return VisaCurrency(
|
||||||
symbol = VisaConfig.TOKEN_SYMBOL,
|
symbol = VisaConfig.TOKEN_SYMBOL,
|
||||||
|
|
@ -35,8 +36,8 @@ internal class VisaCurrencyFactory {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
limits = VisaCurrency.Limits(
|
limits = VisaCurrency.Limits(
|
||||||
remainingOtp = getRemainingOtp(currentLimit, now),
|
remainingOtp = remainingOtpLimit,
|
||||||
remainingNoOtp = getRemainingNoOtp(currentLimit, now),
|
remainingNoOtp = minOf(remainingOtpLimit, getRemainingNoOtp(currentLimit, now)),
|
||||||
singleTransaction = currentLimit.singleTransactionLimit,
|
singleTransaction = currentLimit.singleTransactionLimit,
|
||||||
expirationDate = getLimitsExpirationDate(currentLimit, now),
|
expirationDate = getLimitsExpirationDate(currentLimit, now),
|
||||||
),
|
),
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.tangem.data.visa
|
||||||
|
|
||||||
|
import androidx.paging.PagingData
|
||||||
|
import com.tangem.domain.visa.model.VisaCurrency
|
||||||
|
import com.tangem.domain.visa.model.VisaTxDetails
|
||||||
|
import com.tangem.domain.visa.model.VisaTxHistoryItem
|
||||||
|
import com.tangem.domain.visa.repository.VisaRepository
|
||||||
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
internal class DummyVisaRepository : VisaRepository {
|
||||||
|
|
||||||
|
override suspend fun getVisaCurrency(userWalletId: UserWalletId, isRefresh: Boolean): VisaCurrency {
|
||||||
|
TODO("Not implemented for this build type")
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun getTxHistory(
|
||||||
|
userWalletId: UserWalletId,
|
||||||
|
pageSize: Int,
|
||||||
|
isRefresh: Boolean,
|
||||||
|
): Flow<PagingData<VisaTxHistoryItem>> {
|
||||||
|
TODO("Not implemented for this build type")
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun getTxDetails(userWalletId: UserWalletId, txId: String): VisaTxDetails {
|
||||||
|
TODO("Not implemented for this build type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
package com.tangem.data.visa.di
|
||||||
|
|
||||||
|
import javax.inject.Qualifier
|
||||||
|
|
||||||
|
@Qualifier
|
||||||
|
internal annotation class ImplementedVisaRepository
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.tangem.data.visa.di
|
||||||
|
|
||||||
|
import com.tangem.domain.visa.repository.VisaRepository
|
||||||
|
import dagger.BindsOptionalOf
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
internal interface ImplementedVisaRepositoryModule {
|
||||||
|
|
||||||
|
@BindsOptionalOf
|
||||||
|
@ImplementedVisaRepository
|
||||||
|
fun bindImplementedVisaRepository(): VisaRepository
|
||||||
|
}
|
||||||
|
|
@ -1,21 +1,14 @@
|
||||||
package com.tangem.data.visa.di
|
package com.tangem.data.visa.di
|
||||||
|
|
||||||
import com.squareup.moshi.Moshi
|
import com.tangem.data.visa.DummyVisaRepository
|
||||||
import com.tangem.data.common.cache.CacheRegistry
|
|
||||||
import com.tangem.data.visa.BuildConfig
|
|
||||||
import com.tangem.data.visa.DefaultVisaRepository
|
|
||||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
|
||||||
import com.tangem.datasource.di.NetworkMoshi
|
|
||||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
|
||||||
import com.tangem.domain.visa.repository.VisaRepository
|
import com.tangem.domain.visa.repository.VisaRepository
|
||||||
import com.tangem.lib.visa.VisaContractInfoProvider
|
|
||||||
import com.tangem.lib.visa.api.VisaApiBuilder
|
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
import dagger.hilt.components.SingletonComponent
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
import java.util.Optional
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
import kotlin.jvm.optionals.getOrNull
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
@InstallIn(SingletonComponent::class)
|
@InstallIn(SingletonComponent::class)
|
||||||
|
|
@ -24,29 +17,8 @@ internal object VisaDataModule {
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
fun provideVisaRepository(
|
fun provideVisaRepository(
|
||||||
@NetworkMoshi moshi: Moshi,
|
@ImplementedVisaRepository implementedVisaRepository: Optional<VisaRepository>,
|
||||||
tangemTechApi: TangemTechApi,
|
|
||||||
cacheRegistry: CacheRegistry,
|
|
||||||
userWalletsStore: UserWalletsStore,
|
|
||||||
dispatchers: CoroutineDispatcherProvider,
|
|
||||||
): VisaRepository {
|
): VisaRepository {
|
||||||
val contractInfoProvider = VisaContractInfoProvider.Builder(
|
return implementedVisaRepository.getOrNull() ?: DummyVisaRepository()
|
||||||
isNetworkLoggingEnabled = BuildConfig.LOG_ENABLED,
|
|
||||||
dispatchers = dispatchers,
|
|
||||||
).build()
|
|
||||||
val visaApi = VisaApiBuilder(
|
|
||||||
useDevApi = true,
|
|
||||||
isNetworkLoggingEnabled = BuildConfig.LOG_ENABLED,
|
|
||||||
moshi = moshi,
|
|
||||||
).build()
|
|
||||||
|
|
||||||
return DefaultVisaRepository(
|
|
||||||
contractInfoProvider,
|
|
||||||
tangemTechApi,
|
|
||||||
visaApi,
|
|
||||||
cacheRegistry,
|
|
||||||
userWalletsStore,
|
|
||||||
dispatchers,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -19,7 +19,7 @@ internal data class BalancesAndLimitsBottomSheetConfig(
|
||||||
|
|
||||||
data class Limit(
|
data class Limit(
|
||||||
val availableBy: String,
|
val availableBy: String,
|
||||||
val inStore: String,
|
val total: String,
|
||||||
val other: String,
|
val other: String,
|
||||||
val singleTransaction: String,
|
val singleTransaction: String,
|
||||||
val onInfoClick: () -> Unit,
|
val onInfoClick: () -> Unit,
|
||||||
|
|
|
||||||
|
|
@ -48,19 +48,32 @@ internal sealed interface WalletAlertState {
|
||||||
override val isWarningConfirmButton: Boolean = true
|
override val isWarningConfirmButton: Boolean = true
|
||||||
}
|
}
|
||||||
|
|
||||||
object WrongCardIsScanned : Basic() {
|
data class VisaLimitsInfo(
|
||||||
|
val totalLimit: String,
|
||||||
|
val otherLimit: String,
|
||||||
|
) : Basic() {
|
||||||
|
override val title: TextReference? = null
|
||||||
|
override val message: TextReference = stringReference(
|
||||||
|
value = "Limits are needed to control costs, improve security, manage risk. " +
|
||||||
|
"You can spend $totalLimit during the week for card payments in shops and " +
|
||||||
|
"$otherLimit for other transactions, e. g. subscriptions or debts.",
|
||||||
|
)
|
||||||
|
override val onConfirmClick: (() -> Unit)? = null
|
||||||
|
}
|
||||||
|
|
||||||
|
data object WrongCardIsScanned : Basic() {
|
||||||
override val title: TextReference = resourceReference(R.string.common_warning)
|
override val title: TextReference = resourceReference(R.string.common_warning)
|
||||||
override val message: TextReference = resourceReference(R.string.error_wrong_wallet_tapped)
|
override val message: TextReference = resourceReference(R.string.error_wrong_wallet_tapped)
|
||||||
override val onConfirmClick: (() -> Unit)? = null
|
override val onConfirmClick: (() -> Unit)? = null
|
||||||
}
|
}
|
||||||
|
|
||||||
object RescanWallets : Basic() {
|
data object RescanWallets : Basic() {
|
||||||
override val title: TextReference = resourceReference(R.string.common_attention)
|
override val title: TextReference = resourceReference(R.string.common_attention)
|
||||||
override val message: TextReference = resourceReference(R.string.key_invalidated_warning_description)
|
override val message: TextReference = resourceReference(R.string.key_invalidated_warning_description)
|
||||||
override val onConfirmClick: (() -> Unit)? = null
|
override val onConfirmClick: (() -> Unit)? = null
|
||||||
}
|
}
|
||||||
|
|
||||||
object VisaBalancesInfo : Basic() {
|
data object VisaBalancesInfo : Basic() {
|
||||||
override val title: TextReference? = null
|
override val title: TextReference? = null
|
||||||
override val message: TextReference = stringReference(
|
override val message: TextReference = stringReference(
|
||||||
value = "Available balance is actual funds available, considering pending transactions, " +
|
value = "Available balance is actual funds available, considering pending transactions, " +
|
||||||
|
|
@ -68,14 +81,4 @@ internal sealed interface WalletAlertState {
|
||||||
)
|
)
|
||||||
override val onConfirmClick: (() -> Unit)? = null
|
override val onConfirmClick: (() -> Unit)? = null
|
||||||
}
|
}
|
||||||
|
|
||||||
object VisaLimitsInfo : Basic() {
|
|
||||||
override val title: TextReference? = null
|
|
||||||
override val message: TextReference = stringReference(
|
|
||||||
value = "Limits are needed to control costs, improve security, manage risk. " +
|
|
||||||
"You can spend 1 000 USDT during the week for card payments in shops and " +
|
|
||||||
"100 USDT for other transactions, e. g. subscriptions or debts.",
|
|
||||||
)
|
|
||||||
override val onConfirmClick: (() -> Unit)? = null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -21,6 +21,9 @@ internal class BalancesAndLimitsBottomSheetConverter(
|
||||||
decimals = value.decimals,
|
decimals = value.decimals,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val otpLimit = value.limits.remainingOtp.let(::formatAmount)
|
||||||
|
val noOtpLimit = value.limits.remainingNoOtp.let(::formatAmount)
|
||||||
|
|
||||||
return BalancesAndLimitsBottomSheetConfig(
|
return BalancesAndLimitsBottomSheetConfig(
|
||||||
balance = BalancesAndLimitsBottomSheetConfig.Balance(
|
balance = BalancesAndLimitsBottomSheetConfig.Balance(
|
||||||
totalBalance = value.balances.total.let(::formatAmount),
|
totalBalance = value.balances.total.let(::formatAmount),
|
||||||
|
|
@ -33,10 +36,10 @@ internal class BalancesAndLimitsBottomSheetConverter(
|
||||||
),
|
),
|
||||||
limit = BalancesAndLimitsBottomSheetConfig.Limit(
|
limit = BalancesAndLimitsBottomSheetConfig.Limit(
|
||||||
availableBy = DateTimeFormatters.formatDate(date = value.limits.expirationDate),
|
availableBy = DateTimeFormatters.formatDate(date = value.limits.expirationDate),
|
||||||
inStore = value.limits.remainingOtp.let(::formatAmount),
|
total = otpLimit,
|
||||||
other = value.limits.remainingNoOtp.let(::formatAmount),
|
other = noOtpLimit,
|
||||||
singleTransaction = value.limits.singleTransaction.let(::formatAmount),
|
singleTransaction = value.limits.singleTransaction.let(::formatAmount),
|
||||||
onInfoClick = this::showLimitInfo,
|
onInfoClick = { showLimitInfo(otpLimit, noOtpLimit) },
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -45,7 +48,7 @@ internal class BalancesAndLimitsBottomSheetConverter(
|
||||||
eventSender.send(WalletEvent.ShowAlert(WalletAlertState.VisaBalancesInfo))
|
eventSender.send(WalletEvent.ShowAlert(WalletAlertState.VisaBalancesInfo))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showLimitInfo() {
|
private fun showLimitInfo(totalLimit: String, otherLimit: String) {
|
||||||
eventSender.send(WalletEvent.ShowAlert(WalletAlertState.VisaLimitsInfo))
|
eventSender.send(WalletEvent.ShowAlert(WalletAlertState.VisaLimitsInfo(totalLimit, otherLimit)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.tangem.feature.wallet.presentation.wallet.state.transformers.converter
|
package com.tangem.feature.wallet.presentation.wallet.state.transformers.converter
|
||||||
|
|
||||||
|
import com.tangem.core.ui.extensions.capitalize
|
||||||
import com.tangem.core.ui.utils.BigDecimalFormatter
|
import com.tangem.core.ui.utils.BigDecimalFormatter
|
||||||
import com.tangem.core.ui.utils.DateTimeFormatters
|
import com.tangem.core.ui.utils.DateTimeFormatters
|
||||||
import com.tangem.domain.visa.model.VisaCurrency
|
import com.tangem.domain.visa.model.VisaCurrency
|
||||||
|
|
@ -27,14 +28,14 @@ internal class VisaTxDetailsBottomSheetConverter(
|
||||||
private fun createTransaction(details: VisaTxDetails): VisaTxDetailsBottomSheetConfig.Transaction {
|
private fun createTransaction(details: VisaTxDetails): VisaTxDetailsBottomSheetConfig.Transaction {
|
||||||
return VisaTxDetailsBottomSheetConfig.Transaction(
|
return VisaTxDetailsBottomSheetConfig.Transaction(
|
||||||
id = details.id,
|
id = details.id,
|
||||||
type = details.type,
|
type = details.type.capitalize(),
|
||||||
status = details.status,
|
status = details.status.capitalize(),
|
||||||
blockchainAmount = formatNetworkAmount(details.blockchainAmount),
|
blockchainAmount = formatNetworkAmount(details.blockchainAmount),
|
||||||
blockchainFee = formatNetworkAmount(details.blockchainFee),
|
blockchainFee = formatNetworkAmount(details.blockchainFee),
|
||||||
transactionAmount = formatFiatAmount(details.transactionAmount, details.fiatCurrency),
|
transactionAmount = formatFiatAmount(details.transactionAmount, details.fiatCurrency),
|
||||||
transactionCurrencyCode = details.transactionCurrencyCode.toString(),
|
transactionCurrencyCode = details.transactionCurrencyCode.toString(),
|
||||||
merchantName = details.merchantName ?: UNKNOWN,
|
merchantName = details.merchantName?.capitalize() ?: UNKNOWN,
|
||||||
merchantCity = details.merchantCity ?: UNKNOWN,
|
merchantCity = details.merchantCity?.capitalize() ?: UNKNOWN,
|
||||||
merchantCountryCode = details.merchantCountryCode ?: UNKNOWN,
|
merchantCountryCode = details.merchantCountryCode ?: UNKNOWN,
|
||||||
merchantCategoryCode = details.merchantCategoryCode ?: UNKNOWN,
|
merchantCategoryCode = details.merchantCategoryCode ?: UNKNOWN,
|
||||||
)
|
)
|
||||||
|
|
@ -46,16 +47,16 @@ internal class VisaTxDetailsBottomSheetConverter(
|
||||||
|
|
||||||
return VisaTxDetailsBottomSheetConfig.Request(
|
return VisaTxDetailsBottomSheetConfig.Request(
|
||||||
id = request.id,
|
id = request.id,
|
||||||
type = request.requestType,
|
type = request.requestType.capitalize(),
|
||||||
status = request.requestStatus,
|
status = request.requestStatus.capitalize(),
|
||||||
blockchainAmount = formatNetworkAmount(request.blockchainAmount),
|
blockchainAmount = formatNetworkAmount(request.blockchainAmount),
|
||||||
blockchainFee = formatNetworkAmount(request.blockchainFee),
|
blockchainFee = formatNetworkAmount(request.blockchainFee),
|
||||||
transactionAmount = formatFiatAmount(request.transactionAmount, request.fiatCurrency),
|
transactionAmount = formatFiatAmount(request.transactionAmount, request.fiatCurrency),
|
||||||
currencyCode = request.billingCurrencyCode.toString(),
|
currencyCode = request.billingCurrencyCode.toString(),
|
||||||
errorCode = request.errorCode,
|
errorCode = request.errorCode,
|
||||||
date = DateTimeFormatters.formatDate(DateTimeFormatters.dateTimeFormatter, date = localDate),
|
date = DateTimeFormatters.formatDate(localDate, DateTimeFormatters.dateTimeFormatter),
|
||||||
txHash = request.txHash ?: UNKNOWN,
|
txHash = request.txHash ?: UNKNOWN,
|
||||||
txStatus = request.txStatus ?: UNKNOWN,
|
txStatus = request.txStatus?.capitalize() ?: UNKNOWN,
|
||||||
onExploreClick = if (exploreUrl != null) {
|
onExploreClick = if (exploreUrl != null) {
|
||||||
{ clickIntents.onExploreClick(exploreUrl) }
|
{ clickIntents.onExploreClick(exploreUrl) }
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.tangem.feature.wallet.presentation.wallet.state.transformers.converter
|
package com.tangem.feature.wallet.presentation.wallet.state.transformers.converter
|
||||||
|
|
||||||
import com.tangem.core.ui.components.transactions.state.TransactionState
|
import com.tangem.core.ui.components.transactions.state.TransactionState
|
||||||
|
import com.tangem.core.ui.extensions.capitalize
|
||||||
import com.tangem.core.ui.extensions.stringReference
|
import com.tangem.core.ui.extensions.stringReference
|
||||||
import com.tangem.core.ui.utils.BigDecimalFormatter
|
import com.tangem.core.ui.utils.BigDecimalFormatter
|
||||||
import com.tangem.core.ui.utils.DateTimeFormatters
|
import com.tangem.core.ui.utils.DateTimeFormatters
|
||||||
|
|
@ -18,8 +19,8 @@ internal class VisaTxHistoryItemStateConverter(
|
||||||
|
|
||||||
override fun convert(value: VisaTxHistoryItem): TransactionState {
|
override fun convert(value: VisaTxHistoryItem): TransactionState {
|
||||||
val localDate = value.date.withZone(DateTimeZone.getDefault())
|
val localDate = value.date.withZone(DateTimeZone.getDefault())
|
||||||
val time = DateTimeFormatters.formatTime(time = localDate)
|
val time = DateTimeFormatters.formatDate(localDate, DateTimeFormatters.timeFormatter)
|
||||||
val subtitle = "$time • ${value.status}"
|
val subtitle = "$time • ${value.status.capitalize()}"
|
||||||
|
|
||||||
return TransactionState.Content(
|
return TransactionState.Content(
|
||||||
txHash = value.id,
|
txHash = value.id,
|
||||||
|
|
@ -37,7 +38,7 @@ internal class VisaTxHistoryItemStateConverter(
|
||||||
status = TransactionState.Content.Status.Confirmed,
|
status = TransactionState.Content.Status.Confirmed,
|
||||||
direction = TransactionState.Content.Direction.INCOMING,
|
direction = TransactionState.Content.Direction.INCOMING,
|
||||||
iconRes = R.drawable.ic_arrow_up_24,
|
iconRes = R.drawable.ic_arrow_up_24,
|
||||||
title = stringReference(value = value.merchantName ?: "Unknown merchant"),
|
title = stringReference(value = value.merchantName?.capitalize() ?: "Unknown merchant"),
|
||||||
subtitle = stringReference(subtitle),
|
subtitle = stringReference(subtitle),
|
||||||
timestamp = localDate.millis,
|
timestamp = localDate.millis,
|
||||||
onClick = { clickIntents.onVisaTransactionClick(value.id) },
|
onClick = { clickIntents.onVisaTransactionClick(value.id) },
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ internal class VisaWalletSubscriber(
|
||||||
setLoadedCurrencyState(maybeCurrency)
|
setLoadedCurrencyState(maybeCurrency)
|
||||||
|
|
||||||
val currency = maybeCurrency.getOrElse {
|
val currency = maybeCurrency.getOrElse {
|
||||||
|
Timber.e(it, "Failed to load VISA currency")
|
||||||
setFailedTxHistoryState(it)
|
setFailedTxHistoryState(it)
|
||||||
return@flow
|
return@flow
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,10 @@ import androidx.compose.animation.AnimatedContent
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.lazy.LazyListScope
|
import androidx.compose.foundation.lazy.LazyListScope
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.Card
|
||||||
|
import androidx.compose.material3.CardDefaults
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
|
|
@ -60,7 +63,6 @@ private fun BalancesAndLimitsBlock(state: BalancesAndLimitsBlockState, modifier:
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
|
||||||
@Composable
|
@Composable
|
||||||
private inline fun ContentContainer(
|
private inline fun ContentContainer(
|
||||||
enabled: Boolean,
|
enabled: Boolean,
|
||||||
|
|
@ -147,7 +149,7 @@ private fun AvailableLimit(availableBalance: String, limitDays: Int, modifier: M
|
||||||
color = TangemTheme.colors.text.primary1,
|
color = TangemTheme.colors.text.primary1,
|
||||||
)
|
)
|
||||||
Text(
|
Text(
|
||||||
text = "available $limitDays-day limit",
|
text = "available for $limitDays day(s)",
|
||||||
style = TangemTheme.typography.body2,
|
style = TangemTheme.typography.body2,
|
||||||
color = TangemTheme.colors.text.tertiary,
|
color = TangemTheme.colors.text.tertiary,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -94,8 +94,8 @@ private fun LimitsBlock(limits: BalancesAndLimitsBottomSheetConfig.Limit, modifi
|
||||||
title = stringReference("Limits"),
|
title = stringReference("Limits"),
|
||||||
content = {
|
content = {
|
||||||
BlockItem(
|
BlockItem(
|
||||||
title = stringReference("In-store (otp)"),
|
title = stringReference("Total"),
|
||||||
value = limits.inStore,
|
value = limits.total,
|
||||||
)
|
)
|
||||||
BlockItem(
|
BlockItem(
|
||||||
title = stringReference("Other (no-otp)"),
|
title = stringReference("Other (no-otp)"),
|
||||||
|
|
@ -193,7 +193,7 @@ private class BalancesAndLimitsBottomSheetParameterProvider :
|
||||||
),
|
),
|
||||||
limit = BalancesAndLimitsBottomSheetConfig.Limit(
|
limit = BalancesAndLimitsBottomSheetConfig.Limit(
|
||||||
availableBy = "Nov, 11 USDT",
|
availableBy = "Nov, 11 USDT",
|
||||||
inStore = "563.00 USDT",
|
total = "563.00 USDT",
|
||||||
other = "100.00 USDT",
|
other = "100.00 USDT",
|
||||||
singleTransaction = "100.00 USDT",
|
singleTransaction = "100.00 USDT",
|
||||||
onInfoClick = {},
|
onInfoClick = {},
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,7 @@ package com.tangem.lib.visa;
|
||||||
|
|
||||||
import org.web3j.abi.EventEncoder;
|
import org.web3j.abi.EventEncoder;
|
||||||
import org.web3j.abi.TypeReference;
|
import org.web3j.abi.TypeReference;
|
||||||
import org.web3j.abi.datatypes.Address;
|
import org.web3j.abi.datatypes.*;
|
||||||
import org.web3j.abi.datatypes.Event;
|
|
||||||
import org.web3j.abi.datatypes.Function;
|
|
||||||
import org.web3j.abi.datatypes.Utf8String;
|
|
||||||
import org.web3j.abi.datatypes.generated.Uint256;
|
import org.web3j.abi.datatypes.generated.Uint256;
|
||||||
import org.web3j.abi.datatypes.generated.Uint8;
|
import org.web3j.abi.datatypes.generated.Uint8;
|
||||||
import org.web3j.crypto.Credentials;
|
import org.web3j.crypto.Credentials;
|
||||||
|
|
@ -32,10 +29,10 @@ import io.reactivex.Flowable;
|
||||||
* <p>Auto generated code.
|
* <p>Auto generated code.
|
||||||
* <p><strong>Do not modify!</strong>
|
* <p><strong>Do not modify!</strong>
|
||||||
* <p>Please use the <a href="https://docs.web3j.io/command_line.html">web3j command line tools</a>,
|
* <p>Please use the <a href="https://docs.web3j.io/command_line.html">web3j command line tools</a>,
|
||||||
* or the org.web3j.codegen.SolidityFunctionWrapperGenerator in the
|
* or the org.web3j.codegen.SolidityFunctionWrapperGenerator in the
|
||||||
* <a href="https://github.com/web3j/web3j/tree/master/codegen">codegen module</a> to update.
|
* <a href="https://github.com/web3j/web3j/tree/master/codegen">codegen module</a> to update.
|
||||||
*
|
*
|
||||||
* <p>Generated with web3j version 1.5.0.
|
* <p>Generated with web3j version 1.5.2.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
class ERC20 extends Contract {
|
class ERC20 extends Contract {
|
||||||
|
|
@ -113,6 +110,16 @@ class ERC20 extends Contract {
|
||||||
return typedResponse;
|
return typedResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public static ERC20 load(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
|
||||||
|
return new ERC20(contractAddress, web3j, credentials, gasPrice, gasLimit);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public static ERC20 load(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
|
||||||
|
return new ERC20(contractAddress, web3j, transactionManager, gasPrice, gasLimit);
|
||||||
|
}
|
||||||
|
|
||||||
public static List<TransferEventResponse> getTransferEvents(TransactionReceipt transactionReceipt) {
|
public static List<TransferEventResponse> getTransferEvents(TransactionReceipt transactionReceipt) {
|
||||||
List<EventValuesWithLog> valueList = staticExtractEventParametersWithLog(TRANSFER_EVENT, transactionReceipt);
|
List<EventValuesWithLog> valueList = staticExtractEventParametersWithLog(TRANSFER_EVENT, transactionReceipt);
|
||||||
ArrayList<TransferEventResponse> responses = new ArrayList<TransferEventResponse>(valueList.size());
|
ArrayList<TransferEventResponse> responses = new ArrayList<TransferEventResponse>(valueList.size());
|
||||||
|
|
@ -127,16 +134,6 @@ class ERC20 extends Contract {
|
||||||
return responses;
|
return responses;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public static ERC20 load(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
|
|
||||||
return new ERC20(contractAddress, web3j, credentials, gasPrice, gasLimit);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public static ERC20 load(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
|
|
||||||
return new ERC20(contractAddress, web3j, transactionManager, gasPrice, gasLimit);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TransferEventResponse getTransferEventFromLog(Log log) {
|
public static TransferEventResponse getTransferEventFromLog(Log log) {
|
||||||
EventValuesWithLog eventValues = staticExtractEventParametersWithLog(TRANSFER_EVENT, log);
|
EventValuesWithLog eventValues = staticExtractEventParametersWithLog(TRANSFER_EVENT, log);
|
||||||
TransferEventResponse typedResponse = new TransferEventResponse();
|
TransferEventResponse typedResponse = new TransferEventResponse();
|
||||||
|
|
@ -147,14 +144,6 @@ class ERC20 extends Contract {
|
||||||
return typedResponse;
|
return typedResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ERC20 load(String contractAddress, Web3j web3j, Credentials credentials, ContractGasProvider contractGasProvider) {
|
|
||||||
return new ERC20(contractAddress, web3j, credentials, contractGasProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ERC20 load(String contractAddress, Web3j web3j, TransactionManager transactionManager, ContractGasProvider contractGasProvider) {
|
|
||||||
return new ERC20(contractAddress, web3j, transactionManager, contractGasProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Flowable<TransferEventResponse> transferEventFlowable(EthFilter filter) {
|
public Flowable<TransferEventResponse> transferEventFlowable(EthFilter filter) {
|
||||||
return web3j.ethLogFlowable(filter).map(log -> getTransferEventFromLog(log));
|
return web3j.ethLogFlowable(filter).map(log -> getTransferEventFromLog(log));
|
||||||
}
|
}
|
||||||
|
|
@ -165,6 +154,14 @@ class ERC20 extends Contract {
|
||||||
return transferEventFlowable(filter);
|
return transferEventFlowable(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ERC20 load(String contractAddress, Web3j web3j, Credentials credentials, ContractGasProvider contractGasProvider) {
|
||||||
|
return new ERC20(contractAddress, web3j, credentials, contractGasProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ERC20 load(String contractAddress, Web3j web3j, TransactionManager transactionManager, ContractGasProvider contractGasProvider) {
|
||||||
|
return new ERC20(contractAddress, web3j, transactionManager, contractGasProvider);
|
||||||
|
}
|
||||||
|
|
||||||
public Flowable<ApprovalEventResponse> approvalEventFlowable(EthFilter filter) {
|
public Flowable<ApprovalEventResponse> approvalEventFlowable(EthFilter filter) {
|
||||||
return web3j.ethLogFlowable(filter).map(log -> getApprovalEventFromLog(log));
|
return web3j.ethLogFlowable(filter).map(log -> getApprovalEventFromLog(log));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -7,7 +7,6 @@ import com.tangem.lib.visa.model.VisaBalancesAndLimits.Limits
|
||||||
import com.tangem.lib.visa.utils.toBigDecimal
|
import com.tangem.lib.visa.utils.toBigDecimal
|
||||||
import com.tangem.lib.visa.utils.toInstant
|
import com.tangem.lib.visa.utils.toInstant
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import org.joda.time.Instant
|
import org.joda.time.Instant
|
||||||
import org.web3j.protocol.Web3j
|
import org.web3j.protocol.Web3j
|
||||||
import org.web3j.tx.TransactionManager
|
import org.web3j.tx.TransactionManager
|
||||||
|
|
@ -18,39 +17,40 @@ internal class DefaultVisaContractInfoProvider(
|
||||||
private val transactionManager: TransactionManager,
|
private val transactionManager: TransactionManager,
|
||||||
private val gasProvider: ContractGasProvider,
|
private val gasProvider: ContractGasProvider,
|
||||||
private val bridgeProcessorAddress: String,
|
private val bridgeProcessorAddress: String,
|
||||||
|
private val paymentAccountRegistryAddress: String,
|
||||||
private val dispatchers: CoroutineDispatcherProvider,
|
private val dispatchers: CoroutineDispatcherProvider,
|
||||||
) : VisaContractInfoProvider {
|
) : VisaContractInfoProvider {
|
||||||
|
|
||||||
override suspend fun getBalancesAndLimits(walletAddress: String): VisaBalancesAndLimits {
|
override suspend fun getBalancesAndLimits(walletAddress: String): VisaBalancesAndLimits {
|
||||||
return withContext(dispatchers.io) {
|
return parZip(
|
||||||
val tangemBridgeProcessor = TangemBridgeProcessor.load(
|
dispatchers.io,
|
||||||
/* contractAddress = */ bridgeProcessorAddress,
|
{ loadPaymentAccount(walletAddress) },
|
||||||
/* web3j = */ web3j,
|
{ loadPaymentTokenInfo() },
|
||||||
/* transactionManager = */ transactionManager,
|
{ paymentAccount, paymentToken ->
|
||||||
/* contractGasProvider = */ gasProvider,
|
fetchBalancesAndLimits(paymentAccount, paymentToken)
|
||||||
)
|
},
|
||||||
|
)
|
||||||
parZip(
|
|
||||||
dispatchers.io,
|
|
||||||
{ loadPaymentAccount(walletAddress, tangemBridgeProcessor) },
|
|
||||||
{ loadPaymentTokenInfo(tangemBridgeProcessor) },
|
|
||||||
{ paymentAccount, paymentToken ->
|
|
||||||
fetchBalancesAndLimits(paymentAccount, paymentToken)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadPaymentAccount(
|
private fun loadPaymentAccount(walletAddress: String): TangemPaymentAccount {
|
||||||
walletAddress: String,
|
val paymentAccountRegistry = TangemPaymentAccountRegistry.load(
|
||||||
tangemBridgeProcessor: TangemBridgeProcessor,
|
/* contractAddress = */ paymentAccountRegistryAddress,
|
||||||
): TangemPaymentAccount {
|
/* web3j = */ web3j,
|
||||||
val paymentAccountAddress = tangemBridgeProcessor.getPaymentAccount(walletAddress).send()
|
/* transactionManager = */ transactionManager,
|
||||||
|
/* contractGasProvider = */ gasProvider,
|
||||||
|
)
|
||||||
|
val paymentAccountAddress = paymentAccountRegistry.paymentAccountByCard(walletAddress).send()
|
||||||
|
|
||||||
return TangemPaymentAccount.load(paymentAccountAddress, web3j, transactionManager, gasProvider)
|
return TangemPaymentAccount.load(paymentAccountAddress, web3j, transactionManager, gasProvider)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadPaymentTokenInfo(tangemBridgeProcessor: TangemBridgeProcessor): PaymentTokenInfo {
|
private fun loadPaymentTokenInfo(): PaymentTokenInfo {
|
||||||
|
val tangemBridgeProcessor = TangemBridgeProcessor.load(
|
||||||
|
/* contractAddress = */ bridgeProcessorAddress,
|
||||||
|
/* web3j = */ web3j,
|
||||||
|
/* transactionManager = */ transactionManager,
|
||||||
|
/* contractGasProvider = */ gasProvider,
|
||||||
|
)
|
||||||
val paymentTokenContractAddress = tangemBridgeProcessor.paymentToken().send()
|
val paymentTokenContractAddress = tangemBridgeProcessor.paymentToken().send()
|
||||||
val paymentTokenContract = ERC20.load(paymentTokenContractAddress, web3j, transactionManager, gasProvider)
|
val paymentTokenContract = ERC20.load(paymentTokenContractAddress, web3j, transactionManager, gasProvider)
|
||||||
val paymentTokenDecimals = paymentTokenContract.decimals().send()
|
val paymentTokenDecimals = paymentTokenContract.decimals().send()
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ interface VisaContractInfoProvider {
|
||||||
private val dispatchers: CoroutineDispatcherProvider,
|
private val dispatchers: CoroutineDispatcherProvider,
|
||||||
private val baseUrl: String = VisaConfig.BASE_RPC_URL,
|
private val baseUrl: String = VisaConfig.BASE_RPC_URL,
|
||||||
private val bridgeProcessorAddress: String = VisaConfig.BRIDGE_PROCESSOR_CONTRACT_ADDRESS,
|
private val bridgeProcessorAddress: String = VisaConfig.BRIDGE_PROCESSOR_CONTRACT_ADDRESS,
|
||||||
|
private val paymentAccountRegistryAddress: String = VisaConfig.PAYMENT_ACCOUNT_REGISTRY_ADDRESS,
|
||||||
private val chainId: Long = VisaConfig.CHAIN_ID,
|
private val chainId: Long = VisaConfig.CHAIN_ID,
|
||||||
private val networkTimeoutSeconds: Long = VisaConfig.NETWORK_TIMEOUT_SECONDS,
|
private val networkTimeoutSeconds: Long = VisaConfig.NETWORK_TIMEOUT_SECONDS,
|
||||||
private val decimals: Int = VisaConfig.DECIMALS,
|
private val decimals: Int = VisaConfig.DECIMALS,
|
||||||
|
|
@ -45,6 +46,7 @@ interface VisaContractInfoProvider {
|
||||||
transactionManager = transactionManager,
|
transactionManager = transactionManager,
|
||||||
gasProvider = gasProvider,
|
gasProvider = gasProvider,
|
||||||
bridgeProcessorAddress = bridgeProcessorAddress,
|
bridgeProcessorAddress = bridgeProcessorAddress,
|
||||||
|
paymentAccountRegistryAddress = paymentAccountRegistryAddress,
|
||||||
dispatchers = dispatchers,
|
dispatchers = dispatchers,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,9 @@ package com.tangem.lib.visa.utils
|
||||||
|
|
||||||
internal object VisaConfig {
|
internal object VisaConfig {
|
||||||
|
|
||||||
const val BASE_RPC_URL = "https://rpc-mumbai.maticvigil.com/"
|
const val BASE_RPC_URL = "https://polygon-mumbai.g.alchemy.com/v2/_1qqjXgBC_IikaXChnna8KTcV2eMMIQG/"
|
||||||
const val BRIDGE_PROCESSOR_CONTRACT_ADDRESS = "0x62119697e78178512bfcc456ae6d1b7dee9fbaa6"
|
const val BRIDGE_PROCESSOR_CONTRACT_ADDRESS = "0xe32ecbbc1ec17fa9c160569cd613ad568ca50279"
|
||||||
|
const val PAYMENT_ACCOUNT_REGISTRY_ADDRESS = "0x3f4ae01073d1a9d5a92315fe118e57d1cdec7c44"
|
||||||
const val CHAIN_ID = 80_001L
|
const val CHAIN_ID = 80_001L
|
||||||
const val DECIMALS = 9
|
const val DECIMALS = 9
|
||||||
const val GAS_LIMIT = 500_000_000L
|
const val GAS_LIMIT = 500_000_000L
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue