Updated on 2026-08-14
This commit is contained in:
commit
87c43ab20f
83 changed files with 988 additions and 141 deletions
|
|
@ -108,10 +108,10 @@ repositories {
|
|||
dependencies {
|
||||
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.aar"))))
|
||||
implementation(project(":domain"))
|
||||
implementation(project(":network"))
|
||||
implementation(project(":common"))
|
||||
implementation(project(":core:res"))
|
||||
implementation(project(":core:ui"))
|
||||
implementation(project(":core:datasource"))
|
||||
implementation(project(":core:utils"))
|
||||
implementation(project(":libs:crypto"))
|
||||
implementation(project(":libs:auth"))
|
||||
|
|
@ -120,6 +120,9 @@ dependencies {
|
|||
implementation(project(":features:referral:presentation"))
|
||||
implementation(project(":features:referral:domain"))
|
||||
implementation(project(":features:referral:data"))
|
||||
implementation(project(":features:swap:presentation"))
|
||||
implementation(project(":features:swap:domain"))
|
||||
implementation(project(":features:swap:data"))
|
||||
|
||||
/** AndroidX libraries */
|
||||
implementation(AndroidX.coreKtx)
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit bfc2bf8157089bce6b44779bdae66df2c920de70
|
||||
Subproject commit 897f0f7c402fd53c5ee1fa4ab601ecd4e43ff389
|
||||
|
|
@ -11,9 +11,9 @@ import com.tangem.blockchain.common.BlockchainSdkConfig
|
|||
import com.tangem.blockchain.common.WalletManagerFactory
|
||||
import com.tangem.blockchain.network.BlockchainSdkRetrofitBuilder
|
||||
import com.tangem.common.json.MoshiJsonConverter
|
||||
import com.tangem.datasource.api.common.MoshiConverter
|
||||
import com.tangem.domain.DomainLayer
|
||||
import com.tangem.domain.common.LogConfig
|
||||
import com.tangem.network.common.MoshiConverter
|
||||
import com.tangem.tap.common.AndroidAssetReader
|
||||
import com.tangem.tap.common.AssetReader
|
||||
import com.tangem.tap.common.analytics.Analytics
|
||||
|
|
@ -156,6 +156,7 @@ class TapApplication : Application(), ImageLoaderFactory {
|
|||
appStateHolder.userTokensRepository = userTokensRepository
|
||||
}
|
||||
|
||||
//todo refactor: move to datasource and provide via DI
|
||||
private fun initMoshiConverter() {
|
||||
fun appAdapters(): List<Any> = listOf(
|
||||
BigDecimalAdapter(),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package com.tangem.tap.domain
|
|||
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.domain.common.ThrottlerWithValues
|
||||
import com.tangem.network.api.tangemTech.TangemTechService
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechService
|
||||
import com.tangem.tap.features.wallet.models.Currency
|
||||
import com.tangem.tap.store
|
||||
import java.math.BigDecimal
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package com.tangem.tap.domain
|
|||
|
||||
import androidx.annotation.StringRes
|
||||
import com.tangem.common.core.TangemError
|
||||
import com.tangem.network.api.tangemTech.TangemTechError
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechError
|
||||
import com.tangem.wallet.R
|
||||
|
||||
interface TapErrors
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package com.tangem.tap.domain.tokens
|
|||
import com.squareup.moshi.JsonClass
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.domain.common.extensions.fromNetworkId
|
||||
import com.tangem.network.api.tangemTech.CoinsResponse
|
||||
import com.tangem.datasource.api.tangemTech.CoinsResponse
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class CurrencyFromJson(
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ import com.tangem.blockchain.common.Blockchain
|
|||
import com.tangem.common.services.Result
|
||||
import com.tangem.domain.common.extensions.getListOfCoins
|
||||
import com.tangem.domain.common.extensions.toNetworkId
|
||||
import com.tangem.network.api.tangemTech.CoinsResponse
|
||||
import com.tangem.network.api.tangemTech.TangemTechService
|
||||
import com.tangem.network.common.MoshiConverter
|
||||
import com.tangem.datasource.api.tangemTech.CoinsResponse
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechService
|
||||
import com.tangem.datasource.api.common.MoshiConverter
|
||||
import com.tangem.tap.common.AssetReader
|
||||
|
||||
class LoadAvailableCoinsService(
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import com.tangem.blockchain.common.DerivationStyle
|
|||
import com.tangem.common.services.Result
|
||||
import com.tangem.domain.common.extensions.getTokens
|
||||
import com.tangem.domain.common.extensions.toNetworkId
|
||||
import com.tangem.network.api.tangemTech.TangemTechService
|
||||
import com.tangem.network.common.MoshiConverter
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechService
|
||||
import com.tangem.datasource.api.common.MoshiConverter
|
||||
import com.tangem.tap.common.FileReader
|
||||
import com.tangem.tap.domain.tokens.models.BlockchainNetwork
|
||||
import com.tangem.tap.domain.tokens.models.TokenDao
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ package com.tangem.tap.domain.tokens
|
|||
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.network.api.tangemTech.TangemTechService
|
||||
import com.tangem.network.api.tangemTech.UserTokensResponse
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechService
|
||||
import com.tangem.datasource.api.tangemTech.UserTokensResponse
|
||||
import com.tangem.tap.domain.NoDataError
|
||||
|
||||
class UserTokensNetworkService(private val tangemTechService: TangemTechService) {
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@ package com.tangem.tap.domain.tokens
|
|||
import android.content.Context
|
||||
import com.tangem.blockchain.common.DerivationStyle
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechService
|
||||
import com.tangem.datasource.api.tangemTech.UserTokensResponse
|
||||
import com.tangem.domain.common.CardDTO
|
||||
import com.tangem.domain.common.util.userWalletId
|
||||
import com.tangem.network.api.tangemTech.TangemTechService
|
||||
import com.tangem.network.api.tangemTech.UserTokensResponse
|
||||
import com.tangem.tap.common.AndroidFileReader
|
||||
import com.tangem.tap.domain.NoDataError
|
||||
import com.tangem.tap.domain.tokens.models.BlockchainNetwork
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ package com.tangem.tap.domain.tokens
|
|||
|
||||
import com.squareup.moshi.JsonAdapter
|
||||
import com.tangem.Log
|
||||
import com.tangem.datasource.api.tangemTech.UserTokensResponse
|
||||
import com.tangem.datasource.api.common.MoshiConverter
|
||||
import com.tangem.domain.common.CardDTO
|
||||
import com.tangem.network.api.tangemTech.UserTokensResponse
|
||||
import com.tangem.network.common.MoshiConverter
|
||||
import com.tangem.tap.common.FileReader
|
||||
import com.tangem.tap.features.wallet.models.Currency
|
||||
import com.tangem.tap.features.wallet.models.toCurrencies
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import com.tangem.common.extensions.hexToBytes
|
|||
import com.tangem.common.extensions.toHexString
|
||||
import com.tangem.domain.common.CardDTO
|
||||
import com.tangem.domain.common.ScanResponse
|
||||
import com.tangem.network.common.MoshiConverter
|
||||
import com.tangem.datasource.api.common.MoshiConverter
|
||||
import com.tangem.operations.wallet.CreateWalletResponse
|
||||
import com.tangem.tap.common.AssetReader
|
||||
import com.tangem.tap.tangemSdkManager
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package com.tangem.tap.domain.walletStores.repository.di
|
||||
|
||||
import com.tangem.blockchain.common.WalletManagerFactory
|
||||
import com.tangem.network.api.tangemTech.TangemTechService
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechService
|
||||
import com.tangem.tap.domain.walletStores.repository.WalletAmountsRepository
|
||||
import com.tangem.tap.domain.walletStores.repository.WalletManagersRepository
|
||||
import com.tangem.tap.domain.walletStores.repository.WalletStoresRepository
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ import com.tangem.common.flatMap
|
|||
import com.tangem.common.flatMapOnFailure
|
||||
import com.tangem.common.map
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechService
|
||||
import com.tangem.domain.common.ScanResponse
|
||||
import com.tangem.domain.common.util.UserWalletId
|
||||
import com.tangem.network.api.tangemTech.TangemTechService
|
||||
import com.tangem.tap.common.entities.FiatCurrency
|
||||
import com.tangem.tap.common.extensions.replaceByOrAdd
|
||||
import com.tangem.tap.domain.model.UserWallet
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import com.squareup.moshi.JsonClass
|
|||
import com.squareup.moshi.Types
|
||||
import com.tangem.common.extensions.hexToBytes
|
||||
import com.tangem.common.extensions.toHexString
|
||||
import com.tangem.network.common.MoshiConverter
|
||||
import com.tangem.datasource.api.common.MoshiConverter
|
||||
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectSession
|
||||
import com.tangem.tap.features.details.redux.walletconnect.WalletForSession
|
||||
import com.trustwallet.walletconnect.models.WCPeerMeta
|
||||
|
|
@ -18,7 +18,7 @@ import java.nio.charset.Charset
|
|||
class WalletConnectRepository(val context: Application) {
|
||||
private val moshi = MoshiConverter.defaultMoshi()
|
||||
private val walletConnectAdapter: JsonAdapter<List<SessionDao>> = moshi.adapter(
|
||||
Types.newParameterizedType(List::class.java, SessionDao::class.java)
|
||||
Types.newParameterizedType(List::class.java, SessionDao::class.java),
|
||||
)
|
||||
|
||||
fun saveSession(session: WalletConnectSession) {
|
||||
|
|
@ -76,7 +76,6 @@ class WalletConnectRepository(val context: Application) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class SessionDao(
|
||||
val peerId: String,
|
||||
|
|
@ -91,7 +90,7 @@ data class SessionDao(
|
|||
remotePeerId = remotePeerId,
|
||||
wallet = wallet,
|
||||
session = session,
|
||||
peerMeta = peerMeta
|
||||
peerMeta = peerMeta,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -102,7 +101,7 @@ data class SessionDao(
|
|||
remotePeerId = session.remotePeerId,
|
||||
wallet = session.wallet,
|
||||
session = session.session,
|
||||
peerMeta = session.peerMeta
|
||||
peerMeta = session.peerMeta,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,13 +12,13 @@ import com.tangem.common.extensions.isZero
|
|||
import com.tangem.common.services.Result
|
||||
import com.tangem.domain.common.extensions.successOr
|
||||
import com.tangem.domain.common.util.UserWalletId
|
||||
import com.tangem.network.api.paymentology.AttestationResponse
|
||||
import com.tangem.network.api.paymentology.PaymentologyApiService
|
||||
import com.tangem.network.api.paymentology.RegisterKYCRequest
|
||||
import com.tangem.network.api.paymentology.RegisterWalletRequest
|
||||
import com.tangem.network.api.paymentology.RegisterWalletResponse
|
||||
import com.tangem.network.api.paymentology.RegistrationResponse
|
||||
import com.tangem.network.api.paymentology.tryExtractError
|
||||
import com.tangem.datasource.api.paymentology.AttestationResponse
|
||||
import com.tangem.datasource.api.paymentology.PaymentologyApiService
|
||||
import com.tangem.datasource.api.paymentology.RegisterKYCRequest
|
||||
import com.tangem.datasource.api.paymentology.RegisterWalletRequest
|
||||
import com.tangem.datasource.api.paymentology.RegisterWalletResponse
|
||||
import com.tangem.datasource.api.paymentology.RegistrationResponse
|
||||
import com.tangem.datasource.api.paymentology.tryExtractError
|
||||
import com.tangem.operations.attestation.AttestWalletKeyResponse
|
||||
import com.tangem.tap.common.extensions.safeUpdate
|
||||
import com.tangem.tap.domain.getFirstToken
|
||||
|
|
@ -152,12 +152,13 @@ class SaltPayActivationManager(
|
|||
)
|
||||
}
|
||||
|
||||
private fun makeRegisterKYCRequest(): RegisterKYCRequest = RegisterKYCRequest(
|
||||
cardId = cardId,
|
||||
publicKey = cardPublicKey,
|
||||
kycProvider = "UTORG",
|
||||
kycRefId = kycUrlProvider.kycRefId,
|
||||
)
|
||||
private fun makeRegisterKYCRequest(): RegisterKYCRequest =
|
||||
RegisterKYCRequest(
|
||||
cardId = cardId,
|
||||
publicKey = cardPublicKey,
|
||||
kycProvider = "UTORG",
|
||||
kycRefId = kycUrlProvider.kycRefId,
|
||||
)
|
||||
|
||||
companion object {
|
||||
fun stub(): SaltPayActivationManager = SaltPayActivationManager(
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import com.tangem.common.extensions.guard
|
|||
import com.tangem.common.services.Result
|
||||
import com.tangem.domain.common.extensions.successOr
|
||||
import com.tangem.domain.common.extensions.withMainContext
|
||||
import com.tangem.network.api.paymentology.KYCStatus
|
||||
import com.tangem.network.api.paymentology.RegistrationResponse
|
||||
import com.tangem.datasource.api.paymentology.KYCStatus
|
||||
import com.tangem.datasource.api.paymentology.RegistrationResponse
|
||||
import com.tangem.tap.common.analytics.Analytics
|
||||
import com.tangem.tap.common.analytics.events.Onboarding
|
||||
import com.tangem.tap.common.extensions.dispatchDebugErrorNotification
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import com.tangem.blockchain.common.WalletManagerFactory
|
|||
import com.tangem.common.extensions.guard
|
||||
import com.tangem.domain.common.SaltPayWorkaround
|
||||
import com.tangem.domain.common.ScanResponse
|
||||
import com.tangem.network.api.paymentology.PaymentologyApiService
|
||||
import com.tangem.datasource.api.paymentology.PaymentologyApiService
|
||||
import com.tangem.tap.common.toggleWidget.WidgetState
|
||||
import com.tangem.tap.domain.extensions.makeSaltPayWalletManager
|
||||
import com.tangem.tap.features.onboarding.products.wallet.saltPay.GnosisRegistrator
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import com.tangem.domain.common.extensions.fromNetworkId
|
|||
import com.tangem.domain.common.extensions.toCoinId
|
||||
import com.tangem.domain.common.extensions.toNetworkId
|
||||
import com.tangem.domain.features.addCustomToken.CustomCurrency
|
||||
import com.tangem.network.api.tangemTech.TokenResponse
|
||||
import com.tangem.datasource.api.tangemTech.TokenResponse
|
||||
import com.tangem.tap.common.redux.global.CryptoCurrencyName
|
||||
import com.tangem.tap.domain.tokens.models.BlockchainNetwork
|
||||
import com.tangem.tap.features.tokens.redux.TokenWithBlockchain
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
package com.tangem.tap.features.wallet.redux.middlewares
|
||||
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.network.api.tangemTech.CurrenciesResponse
|
||||
import com.tangem.network.api.tangemTech.TangemTechService
|
||||
import com.tangem.datasource.api.tangemTech.CurrenciesResponse
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechService
|
||||
import com.tangem.tap.common.analytics.Analytics
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||
import com.tangem.tap.common.analytics.events.MainScreen
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import com.tangem.common.extensions.calculateSha512
|
|||
import com.tangem.common.extensions.toHexString
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.common.services.performRequest
|
||||
import com.tangem.network.common.createRetrofitInstance
|
||||
import com.tangem.datasource.api.common.createRetrofitInstance
|
||||
import com.tangem.tap.common.redux.global.CryptoCurrencyName
|
||||
import com.tangem.tap.features.wallet.models.Currency
|
||||
import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import com.tangem.blockchain.common.Blockchain
|
|||
import com.tangem.common.services.Result
|
||||
import com.tangem.common.services.performRequest
|
||||
import com.tangem.domain.common.extensions.withIOContext
|
||||
import com.tangem.network.common.createRetrofitInstance
|
||||
import com.tangem.datasource.api.common.createRetrofitInstance
|
||||
import com.tangem.tap.common.extensions.urlEncode
|
||||
import com.tangem.tap.common.redux.global.CryptoCurrencyName
|
||||
import com.tangem.tap.features.wallet.models.Currency
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package com.tangem.tap.network.payid
|
|||
import com.squareup.moshi.JsonClass
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.common.services.performRequest
|
||||
import com.tangem.network.common.createRetrofitInstance
|
||||
import com.tangem.datasource.api.common.createRetrofitInstance
|
||||
import retrofit2.Retrofit
|
||||
|
||||
class PayIdService {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package com.tangem.tap.network.payid
|
|||
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.common.services.performRequest
|
||||
import com.tangem.network.common.createRetrofitInstance
|
||||
import com.tangem.datasource.api.common.createRetrofitInstance
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package com.tangem.tap.persistence
|
|||
import android.content.SharedPreferences
|
||||
import androidx.core.content.edit
|
||||
import com.tangem.common.json.MoshiJsonConverter
|
||||
import com.tangem.network.api.tangemTech.CurrenciesResponse
|
||||
import com.tangem.datasource.api.tangemTech.CurrenciesResponse
|
||||
import com.tangem.tap.common.entities.FiatCurrency
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import android.app.Application
|
|||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import androidx.core.content.edit
|
||||
import com.tangem.network.common.MoshiConverter
|
||||
import com.tangem.datasource.api.common.MoshiConverter
|
||||
import java.util.*
|
||||
|
||||
class PreferencesStorage(applicationContext: Application) {
|
||||
|
|
|
|||
|
|
@ -42,6 +42,9 @@ dependencies {
|
|||
/** Project */
|
||||
implementation(project(":libs:auth"))
|
||||
|
||||
/** Tangem libraries */
|
||||
implementation(Tangem.cardCore)
|
||||
|
||||
/** DI */
|
||||
implementation(Library.hilt)
|
||||
kapt(Library.hiltKapt)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.network.common
|
||||
package com.tangem.datasource.api.common
|
||||
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.Response
|
||||
|
|
@ -7,7 +7,7 @@ import okhttp3.Response
|
|||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
open class AddHeaderInterceptor(
|
||||
private val headers: Map<String, String>
|
||||
private val headers: Map<String, String>,
|
||||
) : Interceptor {
|
||||
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
|
|
@ -21,10 +21,10 @@ open class AddHeaderInterceptor(
|
|||
}
|
||||
}
|
||||
|
||||
class CacheControlHttpInterceptor(maxAgeSeconds: Int) : AddHeaderInterceptor(mapOf(
|
||||
"Cache-Control" to "max-age=$maxAgeSeconds",
|
||||
))
|
||||
class CacheControlHttpInterceptor(maxAgeSeconds: Int) : AddHeaderInterceptor(
|
||||
mapOf("Cache-Control" to "max-age=$maxAgeSeconds"),
|
||||
)
|
||||
|
||||
class CardPublicKeyHttpInterceptor(cardPublicKeyHex: String) : AddHeaderInterceptor(mapOf(
|
||||
"card_public_key" to cardPublicKeyHex,
|
||||
))
|
||||
class CardPublicKeyHttpInterceptor(cardPublicKeyHex: String) : AddHeaderInterceptor(
|
||||
mapOf("card_public_key" to cardPublicKeyHex),
|
||||
)
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.network.common
|
||||
package com.tangem.datasource.api.common
|
||||
|
||||
import com.squareup.moshi.JsonAdapter
|
||||
import com.squareup.moshi.Moshi
|
||||
|
|
@ -9,8 +9,10 @@ import retrofit2.converter.moshi.MoshiConverterFactory
|
|||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
//todo needs to be refactored
|
||||
object MoshiConverter {
|
||||
|
||||
//todo refactor: provide via DI
|
||||
var INSTANCE = MoshiJsonConverter()
|
||||
private set
|
||||
|
||||
|
|
@ -23,7 +25,9 @@ object MoshiConverter {
|
|||
|
||||
fun createFactory(moshi: Moshi = INSTANCE.moshi): Converter.Factory = MoshiConverterFactory.create(moshi)
|
||||
|
||||
//todo provide via DI using quealifiers
|
||||
fun defaultMoshi(): Moshi = INSTANCE.moshi
|
||||
|
||||
//todo provide via DI using quealifiers
|
||||
fun sdkMoshi(): Moshi = MoshiJsonConverter.INSTANCE.moshi
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.network.common
|
||||
package com.tangem.datasource.api.common
|
||||
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.OkHttpClient
|
||||
|
|
@ -0,0 +1,200 @@
|
|||
package com.tangem.datasource.api.oneinch
|
||||
|
||||
import com.tangem.datasource.api.oneinch.models.AllowanceResponse
|
||||
import com.tangem.datasource.api.oneinch.models.ApproveCalldataResponse
|
||||
import com.tangem.datasource.api.oneinch.models.ApproveSpenderResponse
|
||||
import com.tangem.datasource.api.oneinch.models.ProtocolsResponse
|
||||
import com.tangem.datasource.api.oneinch.models.QuoteResponse
|
||||
import com.tangem.datasource.api.oneinch.models.StatusResponse
|
||||
import com.tangem.datasource.api.oneinch.models.SwapResponse
|
||||
import com.tangem.datasource.api.oneinch.models.TokensResponse
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Query
|
||||
|
||||
interface OneInchApi {
|
||||
|
||||
/**
|
||||
* Healthcheck return 200 if service is available
|
||||
*
|
||||
* @return [StatusResponse]
|
||||
*/
|
||||
@GET("healthcheck")
|
||||
suspend fun healthcheck(): StatusResponse
|
||||
|
||||
//region Approve
|
||||
/**
|
||||
* Address of the 1inch router that must be trusted to spend funds for the exchange
|
||||
*
|
||||
* @return [ApproveSpenderResponse]
|
||||
*/
|
||||
@GET("approve/spender")
|
||||
suspend fun approveSpender(): ApproveSpenderResponse
|
||||
|
||||
/**
|
||||
* Generate data for calling the contract in order to allow the 1inch router to spend funds
|
||||
*
|
||||
* @param tokenAddress Token address you want to exchange
|
||||
* @param amount The number of tokens that the 1inch router is allowed to spend.
|
||||
* If not specified, it will be allowed to spend an infinite amount of tokens.
|
||||
*
|
||||
* @return [ApproveCalldataResponse] Transaction body to allow the exchange with the 1inch router
|
||||
*/
|
||||
@GET("approve/transaction")
|
||||
suspend fun approveTransaction(
|
||||
@Query("tokenAddress") tokenAddress: String,
|
||||
@Query("amount") amount: String? = null,
|
||||
): ApproveCalldataResponse
|
||||
|
||||
/**
|
||||
* Get the number of tokens that the 1inch router is allowed to spend
|
||||
*
|
||||
* @param tokenAddress Token address you want to exchange
|
||||
* @param walletAddress Wallet address for which you want to check
|
||||
*
|
||||
* @return [AllowanceResponse]
|
||||
*/
|
||||
@GET("approve/allowance")
|
||||
suspend fun approveAllowance(
|
||||
@Query("tokenAddress") tokenAddress: String,
|
||||
@Query("walletAddress") walletAddress: String,
|
||||
): AllowanceResponse
|
||||
//endregion Approve
|
||||
|
||||
//region Info
|
||||
/**
|
||||
* List of tokens that are available for swap in the 1inch Aggregation protocol
|
||||
*
|
||||
* @return [TokensResponse]
|
||||
*/
|
||||
@GET("tokens")
|
||||
suspend fun tokensAvailable(): TokensResponse
|
||||
|
||||
/**
|
||||
* List of liquidity sources that are available for routing in the 1inch Aggregation protocol
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@GET("liquidity-sources")
|
||||
suspend fun liquiditySources(): ProtocolsResponse
|
||||
//endregion Info
|
||||
|
||||
//region Swap
|
||||
/**
|
||||
* Find the best quote to exchange via 1inch router
|
||||
*
|
||||
* @param fromTokenAddress Example : 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE
|
||||
* @param toTokenAddress Example : 0x111111111117dc0aa78b770fa6a738034120c302
|
||||
* @param amount amount of a token to sell, set in minimal divisible units e.g.:
|
||||
* 1.00 DAI set as 1000000000000000000
|
||||
* 51.03 USDC set as 51030000
|
||||
*
|
||||
* @param protocols default: all
|
||||
* @param fee this percentage of fromTokenAddress token amount will be sent to referrerAddress,
|
||||
* the rest will be used as input for a swap
|
||||
* Min: 0; max: 3; Max: 0; max: 3; default: 0; !should be the same for quote and swap!
|
||||
*
|
||||
* @param gasLimit maximum amount of gas for a swap;
|
||||
* @param connectorTokens token-connectors can be specified via this parameter.
|
||||
* The more is set — the longer route estimation will take.
|
||||
* If not set, default token-connectors will be usedmax: 5; !should be the same for quote and swap!
|
||||
*
|
||||
* @param complexityLevel maximum number of token-connectors to be used in a transaction.
|
||||
* The more is used — the longer route estimation will take
|
||||
* min: 0; max: 3; default: 2; !should be the same for quote and swap!
|
||||
*
|
||||
* @param mainRouteParts default: 10; max: 50 !should be the same for quote and swap!
|
||||
* @param parts limit maximum number of parts each main route parts can be split into;
|
||||
* should be the same for a quote and swap
|
||||
* default: 20; max: 100
|
||||
*
|
||||
* @param gasPrice 1inch takes in account gas expenses to determine exchange route.
|
||||
* It is important to use the same gas price on the quote and swap methods.
|
||||
* Gas price set in wei: 12.5 GWEI set as 12500000000
|
||||
* default: fast from network
|
||||
*
|
||||
* @return [QuoteResponse]
|
||||
*/
|
||||
suspend fun quote(
|
||||
@Query("fromTokenAddress") fromTokenAddress: String,
|
||||
@Query("toTokenAddress") toTokenAddress: String,
|
||||
@Query("amount") amount: String,
|
||||
@Query("protocols") protocols: String? = null,
|
||||
@Query("fee") fee: String? = null,
|
||||
@Query("gasLimit") gasLimit: String? = null,
|
||||
@Query("connectorTokens") connectorTokens: String? = null,
|
||||
@Query("complexityLevel") complexityLevel: String? = null,
|
||||
@Query("mainRouteParts") mainRouteParts: String? = null,
|
||||
@Query("parts") parts: String? = null,
|
||||
@Query("gasPrice") gasPrice: String? = null,
|
||||
): QuoteResponse
|
||||
|
||||
/**
|
||||
* Generate data for calling the 1inch router for exchange
|
||||
*
|
||||
* @param fromTokenAddress Example : 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE
|
||||
* @param toTokenAddress Example : 0x111111111117dc0aa78b770fa6a738034120c302
|
||||
* @param amount amount of a token to sell, set in minimal divisible units e.g.:
|
||||
* 1.00 DAI set as 1000000000000000000
|
||||
* 51.03 USDC set as 51030000
|
||||
*
|
||||
* @param fromAddress The address that calls the 1inch contract
|
||||
* @param slippage limit of price slippage you are willing to accept in percentage, may be set with decimals.
|
||||
* &slippage=0.5 means 0.5% slippage is acceptable. Low values increase chances that transaction will fail,
|
||||
* high values increase chances of front running. min: 0; max: 50;
|
||||
*
|
||||
* @param protocols default: all
|
||||
* @param destinationAddress Receiver of destination currency. default: fromAddress
|
||||
* @param fee this percentage of fromTokenAddress token amount will be sent to referrerAddress,
|
||||
* the rest will be used as input for a swap
|
||||
* Min: 0; max: 3; Max: 0; max: 3; default: 0; !should be the same for quote and swap!
|
||||
*
|
||||
* @param permit https://eips.ethereum.org/EIPS/eip-2612
|
||||
* @param compatibilityMode Allows to build calldata without optimized routers
|
||||
* @param burnChi If true, CHI will be burned from fromAddress to compensate gas.
|
||||
* Check CHI balance and allowance before turning that on. CHI should be approved for the spender address
|
||||
*
|
||||
* @param connectorTokens token-connectors can be specified via this parameter.
|
||||
* The more is set — the longer route estimation will take.
|
||||
* If not set, default token-connectors will be usedmax: 5; !should be the same for quote and swap!
|
||||
*
|
||||
* @param complexityLevel maximum number of token-connectors to be used in a transaction.
|
||||
* The more is used — the longer route estimation will take
|
||||
* min: 0; max: 3; default: 2; !should be the same for quote and swap!
|
||||
*
|
||||
* @param mainRouteParts default: 10; max: 50 !should be the same for quote and swap!
|
||||
* @param parts limit maximum number of parts each main route parts can be split into;
|
||||
* should be the same for a quote and swap
|
||||
* default: 20; max: 100
|
||||
*
|
||||
* @param gasLimit maximum amount of gas for a swap;
|
||||
* @param gasPrice 1inch takes in account gas expenses to determine exchange route.
|
||||
* It is important to use the same gas price on the quote and swap methods.
|
||||
* Gas price set in wei: 12.5 GWEI set as 12500000000
|
||||
* default: fast from network
|
||||
*
|
||||
* @return [SwapResponse]
|
||||
*/
|
||||
suspend fun swap(
|
||||
@Query("fromTokenAddress") fromTokenAddress: String,
|
||||
@Query("toTokenAddress") toTokenAddress: String,
|
||||
@Query("amount") amount: String,
|
||||
@Query("fromAddress") fromAddress: String,
|
||||
@Query("slippage") slippage: Int,
|
||||
@Query("protocols") protocols: String? = null,
|
||||
@Query("destReceiver") destinationAddress: String? = null,
|
||||
@Query("referrerAddress") referrerAddress: String? = null,
|
||||
@Query("fee") fee: String? = null,
|
||||
@Query("disableEstimate") disableEstimate: Boolean? = null,
|
||||
@Query("permit") permit: String? = null,
|
||||
@Query("compatibilityMode") compatibilityMode: Boolean? = null,
|
||||
@Query("burnChi") burnChi: Boolean? = null,
|
||||
@Query("allowPartialFill") allowPartialFill: Boolean? = null,
|
||||
@Query("parts") parts: String? = null,
|
||||
@Query("mainRouteParts") mainRouteParts: String? = null,
|
||||
@Query("connectorTokens") connectorTokens: String? = null,
|
||||
@Query("complexityLevel") complexityLevel: String? = null,
|
||||
@Query("gasLimit") gasLimit: String? = null,
|
||||
@Query("gasPrice") gasPrice: String? = null,
|
||||
): SwapResponse
|
||||
//endregion Swap
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package com.tangem.datasource.api.oneinch.models
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
data class AllowanceResponse(
|
||||
@Json(name = "allowance") val allowance: String,
|
||||
)
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package com.tangem.datasource.api.oneinch.models
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
/**
|
||||
* Approve calldata response
|
||||
*
|
||||
* @property data The encoded data to call the approve method on the swapped token contract
|
||||
* @property gasPrice Gas price for fast transaction processing
|
||||
* @property toAddress Token address that will be allowed to exchange through 1inch router
|
||||
* @property value Native token value in WEI (for approve is always 0)
|
||||
*/
|
||||
data class ApproveCalldataResponse(
|
||||
@Json(name = "data") val data: String,
|
||||
@Json(name = "gasPrice") val gasPrice: String,
|
||||
@Json(name = "to") val toAddress: String,
|
||||
@Json(name = "value") val value: String,
|
||||
)
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.tangem.datasource.api.oneinch.models
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
/**
|
||||
* Approve spender response
|
||||
*
|
||||
* @property address Address of the 1inch router that must be trusted to spend funds for the exchange
|
||||
*/
|
||||
data class ApproveSpenderResponse(
|
||||
@Json(name = "address") val address: String,
|
||||
)
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.tangem.datasource.api.oneinch.models
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
/**
|
||||
* Path view dto
|
||||
*/
|
||||
data class PathViewDto(
|
||||
@Json(name = "name") val name: String,
|
||||
@Json(name = "part") val part: Int,
|
||||
@Json(name = "fromTokenAddress") val fromTokenAddress: String,
|
||||
@Json(name = "toTokenAddress") val toTokenAddress: String,
|
||||
)
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package com.tangem.datasource.api.oneinch.models
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
/**
|
||||
* Protocols response
|
||||
*
|
||||
* @property protocols List of protocols that are available for routing in the 1inch Aggregation protocol
|
||||
*/
|
||||
data class ProtocolsResponse(
|
||||
@Json(name = "protocols") val protocols: List<ProtocolImageDto>,
|
||||
)
|
||||
|
||||
/**
|
||||
* Protocol image
|
||||
*
|
||||
* @property id Protocol id
|
||||
* @property title Protocol title
|
||||
* @property image Protocol logo image
|
||||
* @property imageColor Protocol logo image in color
|
||||
*/
|
||||
data class ProtocolImageDto(
|
||||
@Json(name = "id") val id: String,
|
||||
@Json(name = "title") val title: String,
|
||||
@Json(name = "img") val image: String,
|
||||
@Json(name = "img_color") val imageColor: String,
|
||||
)
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package com.tangem.datasource.api.oneinch.models
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
/**
|
||||
* Quote response
|
||||
*
|
||||
* @property fromToken Source token info
|
||||
* @property toToken Destination token info
|
||||
* @property toTokenAmount Expected amount of destination token
|
||||
* @property fromTokenAmount Amount of source token
|
||||
* @property protocols Selected protocols in a path
|
||||
* @property estimatedGas gas fee
|
||||
*/
|
||||
data class QuoteResponse(
|
||||
@Json(name = "fromToken") val fromToken: TokenOneInchDto,
|
||||
@Json(name = "toToken") val toToken: TokenOneInchDto,
|
||||
@Json(name = "toTokenAmount") val toTokenAmount: String,
|
||||
@Json(name = "fromTokenAmount") val fromTokenAmount: String,
|
||||
@Json(name = "protocols") val protocols: List<PathViewDto>,
|
||||
@Json(name = "estimatedGas") val estimatedGas: Int,
|
||||
)
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.tangem.datasource.api.oneinch.models
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
data class StatusResponse(
|
||||
@Json(name = "status") val status: String,
|
||||
@Json(name = "provider") val provider: String,
|
||||
)
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package com.tangem.datasource.api.oneinch.models
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
/**
|
||||
* Swap error dto
|
||||
*
|
||||
* One of the following errors:
|
||||
*
|
||||
* -Insufficient liquidity
|
||||
* -Cannot estimate
|
||||
* -You may not have enough ETH balance for gas fee
|
||||
* -FromTokenAddress cannot be equals to toTokenAddress
|
||||
* -Cannot estimate. Don't forget about miner fee. Try to leave the buffer of ETH for gas
|
||||
* -Not enough balance
|
||||
* -Not enough allowance
|
||||
*
|
||||
* @property statusCode HTTP code
|
||||
* @property error Error code description
|
||||
* @property description Error description (one of the following)
|
||||
* @property requestId Request id
|
||||
* @property meta Meta information
|
||||
* @constructor Create empty Swap error dto
|
||||
*/
|
||||
data class SwapErrorDto(
|
||||
@Json(name = "statusCode") val statusCode: Int,
|
||||
@Json(name = "error") val error: String,
|
||||
@Json(name = "description") val description: String,
|
||||
@Json(name = "requestId") val requestId: String,
|
||||
@Json(name = "meta") val meta: List<NestErrorMeta>,
|
||||
)
|
||||
|
||||
/**
|
||||
* Nest error meta
|
||||
*
|
||||
* @property type Type of field
|
||||
* @property value Value of field
|
||||
*/
|
||||
data class NestErrorMeta(
|
||||
@Json(name = "type") val type: String,
|
||||
@Json(name = "value") val value: String,
|
||||
)
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.tangem.datasource.api.oneinch.models
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
data class SwapResponse(
|
||||
@Json(name = "fromToken") val fromToken: TokenOneInchDto,
|
||||
@Json(name = "toToken") val toToken: TokenOneInchDto,
|
||||
@Json(name = "toTokenAmount") val toTokenAmount: String,
|
||||
@Json(name = "fromTokenAmount") val fromTokenAmount: String,
|
||||
@Json(name = "protocols") val protocols: List<PathViewDto>,
|
||||
@Json(name = "transaction") val transaction: TransactionDto,
|
||||
)
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.tangem.datasource.api.oneinch.models
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
/**
|
||||
* Token one inch
|
||||
*
|
||||
* @property symbol token symbol
|
||||
* @property name token name
|
||||
* @property address token address
|
||||
* @property decimals token decimals
|
||||
* @property logoURI token logo image url
|
||||
*/
|
||||
data class TokenOneInchDto(
|
||||
@Json(name = "symbol") val symbol: String,
|
||||
@Json(name = "name") val name: String,
|
||||
@Json(name = "address") val address: String,
|
||||
@Json(name = "decimals") val decimals: Int,
|
||||
@Json(name = "logoURI") val logoURI: String,
|
||||
)
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.tangem.datasource.api.oneinch.models
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
/**
|
||||
* Tokens response
|
||||
*
|
||||
* @property tokens List of supported tokens
|
||||
*/
|
||||
data class TokensResponse(
|
||||
@Json(name = "tokens") val tokens: Map<String, TokenOneInchDto>,
|
||||
)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.tangem.datasource.api.oneinch.models
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
/**
|
||||
* Transaction dto
|
||||
*
|
||||
* @property fromAddress transactions will be sent from this address
|
||||
* @property toAddress transactions will be sent to our(1inch) contract address
|
||||
* @property data The encoded data to call the approve method on the swapped token contract
|
||||
* @property value Native token value in WEI (for approve is always 0)
|
||||
* @property gasPrice maximum amount of gas for a swap default: 11500000; max: 11500000
|
||||
* @property gas estimated amount of the gas limit, increase this value by 25%
|
||||
* @constructor Create empty Transaction dto
|
||||
*/
|
||||
data class TransactionDto(
|
||||
@Json(name = "from") val fromAddress: String,
|
||||
@Json(name = "to") val toAddress: String,
|
||||
@Json(name = "data") val data: String,
|
||||
@Json(name = "value") val value: String,
|
||||
@Json(name = "gasPrice") val gasPrice: String,
|
||||
@Json(name = "gas") val gas: String,
|
||||
)
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.network.api.paymentology
|
||||
package com.tangem.datasource.api.paymentology
|
||||
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.Headers
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
package com.tangem.network.api.paymentology
|
||||
package com.tangem.datasource.api.paymentology
|
||||
|
||||
import com.tangem.common.extensions.toHexString
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.common.services.performRequest
|
||||
import com.tangem.network.common.MoshiConverter
|
||||
import com.tangem.network.common.createRetrofitInstance
|
||||
import com.tangem.datasource.api.common.MoshiConverter
|
||||
import com.tangem.datasource.api.common.createRetrofitInstance
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.network.api.paymentology
|
||||
package com.tangem.datasource.api.paymentology
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.network.api.paymentology
|
||||
package com.tangem.datasource.api.paymentology
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.tangem.common.extensions.calculateHashCode
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.network.api.tangemTech
|
||||
package com.tangem.datasource.api.tangemTech
|
||||
|
||||
import java.math.BigDecimal
|
||||
|
||||
|
|
@ -11,7 +11,7 @@ sealed interface TangemTechResponse : HttpResponse
|
|||
data class CoinsResponse(
|
||||
val imageHost: String?,
|
||||
val coins: List<Coin>,
|
||||
val total: Int
|
||||
val total: Int,
|
||||
) : TangemTechResponse {
|
||||
|
||||
data class Coin(
|
||||
|
|
@ -19,13 +19,14 @@ data class CoinsResponse(
|
|||
val name: String,
|
||||
val symbol: String,
|
||||
val active: Boolean,
|
||||
val networks: List<Network> = listOf()
|
||||
val networks: List<Network> = listOf(),
|
||||
) : TangemTechResponse {
|
||||
|
||||
data class Network(
|
||||
val networkId: String,
|
||||
val contractAddress: String? = null,
|
||||
val decimalCount: BigDecimal? = null,
|
||||
val exchangeable: Boolean? = false,
|
||||
) : TangemTechResponse
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.network.api.tangemTech
|
||||
package com.tangem.datasource.api.tangemTech
|
||||
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.GET
|
||||
|
|
@ -14,11 +14,12 @@ interface TangemTechApi {
|
|||
@GET("coins")
|
||||
suspend fun coins(
|
||||
@Query("contractAddress") contractAddress: String? = null,
|
||||
@Query("exchangeable") exchangeable: Boolean? = false,
|
||||
@Query("networkIds") networkIds: String? = null,
|
||||
@Query("active") active: Boolean? = null,
|
||||
@Query("searchText") searchText: String? = null,
|
||||
@Query("offset") offset: Int? = null,
|
||||
@Query("limit") limit: Int? = null
|
||||
@Query("limit") limit: Int? = null,
|
||||
): CoinsResponse
|
||||
|
||||
@GET("rates")
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
package com.tangem.network.api.tangemTech
|
||||
package com.tangem.datasource.api.tangemTech
|
||||
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.common.services.performRequest
|
||||
import com.tangem.network.common.AddHeaderInterceptor
|
||||
import com.tangem.network.common.CacheControlHttpInterceptor
|
||||
import com.tangem.network.common.createRetrofitInstance
|
||||
import com.tangem.datasource.api.common.AddHeaderInterceptor
|
||||
import com.tangem.datasource.api.common.CacheControlHttpInterceptor
|
||||
import com.tangem.datasource.api.common.createRetrofitInstance
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
|
|
@ -3,7 +3,10 @@ package com.tangem.datasource.di
|
|||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
|
||||
import com.tangem.datasource.api.AuthHeaderInterceptor
|
||||
import com.tangem.datasource.api.oneinch.OneInchApi
|
||||
import com.tangem.datasource.api.referral.ReferralApi
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.datasource.di.qualifiers.OneInchEthereum
|
||||
import com.tangem.lib.auth.AuthProvider
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
|
|
@ -19,6 +22,33 @@ import javax.inject.Singleton
|
|||
@InstallIn(SingletonComponent::class)
|
||||
class NetworkModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideTangemTechApi(okHttpClient: OkHttpClient): TangemTechApi {
|
||||
return Retrofit.Builder()
|
||||
.addConverterFactory(
|
||||
MoshiConverterFactory.create(),
|
||||
)
|
||||
.baseUrl(DEV_TANGEM_TECH_BASE_URL)
|
||||
.client(okHttpClient)
|
||||
.build()
|
||||
.create(TangemTechApi::class.java)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@OneInchEthereum
|
||||
fun provideOneInchEthereumApi(): OneInchApi {
|
||||
return Retrofit.Builder()
|
||||
.addConverterFactory(
|
||||
MoshiConverterFactory.create(),
|
||||
)
|
||||
.baseUrl(ONE_INCH_ETHER_BASE_URL)
|
||||
.client(OkHttpClient())
|
||||
.build()
|
||||
.create(OneInchApi::class.java)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideReferralApi(okHttpClient: OkHttpClient): ReferralApi {
|
||||
|
|
@ -30,7 +60,7 @@ class NetworkModule {
|
|||
.build(),
|
||||
),
|
||||
)
|
||||
.baseUrl(PROD_REFERRAL_BASE_URL)
|
||||
.baseUrl(DEV_TANGEM_TECH_BASE_URL)
|
||||
.client(okHttpClient)
|
||||
.build()
|
||||
.create(ReferralApi::class.java)
|
||||
|
|
@ -48,6 +78,8 @@ class NetworkModule {
|
|||
}
|
||||
|
||||
private companion object {
|
||||
const val PROD_REFERRAL_BASE_URL = "https://devapi.tangem-tech.com/v1/"//"https://api.tangem-tech.com/v1/"
|
||||
const val PROD_TANGEM_TECH_BASE_URL = "https://api.tangem-tech.com/v1/"
|
||||
const val DEV_TANGEM_TECH_BASE_URL = "https://devapi.tangem-tech.com/v1/"
|
||||
const val ONE_INCH_ETHER_BASE_URL = ""
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package com.tangem.datasource.di.qualifiers
|
||||
|
||||
import javax.inject.Qualifier
|
||||
|
||||
@Qualifier
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
annotation class OneInchEthereum
|
||||
|
||||
@Qualifier
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
annotation class OneInchBinance
|
||||
|
||||
@Qualifier
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
annotation class OneInchOptimism
|
||||
|
|
@ -71,7 +71,7 @@ android {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":network"))
|
||||
implementation(project(":core:datasource"))
|
||||
implementation(project(":common"))
|
||||
|
||||
/** Tangem libraries */
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package com.tangem.domain
|
||||
|
||||
import com.tangem.common.extensions.VoidCallback
|
||||
import com.tangem.network.api.tangemTech.CoinsResponse
|
||||
import com.tangem.datasource.api.tangemTech.CoinsResponse
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
package com.tangem.domain.common.extensions
|
||||
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.network.api.tangemTech.CoinsResponse
|
||||
import com.tangem.network.api.tangemTech.TangemTechService
|
||||
import com.tangem.datasource.api.tangemTech.CoinsResponse
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechService
|
||||
|
||||
suspend fun TangemTechService.getTokens(
|
||||
contractAddress: String,
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ package com.tangem.domain.features.addCustomToken
|
|||
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.domain.common.extensions.getTokens
|
||||
import com.tangem.network.api.tangemTech.CoinsResponse
|
||||
import com.tangem.network.api.tangemTech.TangemTechService
|
||||
import com.tangem.datasource.api.tangemTech.CoinsResponse
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechService
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import com.tangem.domain.common.form.Field
|
|||
import com.tangem.domain.common.form.FieldId
|
||||
import com.tangem.domain.features.addCustomToken.CustomCurrency
|
||||
import com.tangem.domain.features.addCustomToken.CustomTokenFieldId
|
||||
import com.tangem.network.api.tangemTech.CoinsResponse
|
||||
import com.tangem.datasource.api.tangemTech.CoinsResponse
|
||||
import org.rekotlin.Action
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ import com.tangem.domain.redux.domainStore
|
|||
import com.tangem.domain.redux.extensions.dispatchOnMain
|
||||
import com.tangem.domain.redux.global.DomainGlobalAction
|
||||
import com.tangem.domain.redux.global.DomainGlobalState
|
||||
import com.tangem.network.api.tangemTech.CoinsResponse
|
||||
import com.tangem.datasource.api.tangemTech.CoinsResponse
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ import com.tangem.domain.features.addCustomToken.TokenDerivationPathField
|
|||
import com.tangem.domain.features.addCustomToken.TokenField
|
||||
import com.tangem.domain.redux.DomainState
|
||||
import com.tangem.domain.redux.state.StringActionStateConverter
|
||||
import com.tangem.network.api.tangemTech.CoinsResponse
|
||||
import com.tangem.datasource.api.tangemTech.CoinsResponse
|
||||
import org.rekotlin.Action
|
||||
import org.rekotlin.StateType
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import com.tangem.common.extensions.toHexString
|
|||
import com.tangem.domain.redux.BaseStoreHub
|
||||
import com.tangem.domain.redux.DomainState
|
||||
import com.tangem.domain.redux.ReStoreReducer
|
||||
import com.tangem.network.common.CardPublicKeyHttpInterceptor
|
||||
import com.tangem.datasource.api.common.CardPublicKeyHttpInterceptor
|
||||
import org.rekotlin.Action
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ package com.tangem.domain.redux.global
|
|||
import com.tangem.domain.DomainDialog
|
||||
import com.tangem.domain.common.LogConfig
|
||||
import com.tangem.domain.common.ScanResponse
|
||||
import com.tangem.network.api.paymentology.PaymentologyApiService
|
||||
import com.tangem.network.api.tangemTech.TangemTechService
|
||||
import com.tangem.datasource.api.paymentology.PaymentologyApiService
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechService
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
|
|
@ -19,6 +19,8 @@ data class DomainGlobalState(
|
|||
)
|
||||
|
||||
data class NetworkServices(
|
||||
val tangemTechService: TangemTechService = TangemTechService(LogConfig.network.tangemTechService),
|
||||
val paymentologyService: PaymentologyApiService = PaymentologyApiService(LogConfig.network.paymentologyApiService),
|
||||
val tangemTechService: TangemTechService = TangemTechService(
|
||||
LogConfig.network.tangemTechService),
|
||||
val paymentologyService: PaymentologyApiService = PaymentologyApiService(
|
||||
LogConfig.network.paymentologyApiService),
|
||||
)
|
||||
|
|
|
|||
37
features/swap/data/build.gradle.kts
Normal file
37
features/swap/data/build.gradle.kts
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
plugins {
|
||||
id("com.android.library")
|
||||
kotlin("android")
|
||||
kotlin("kapt")
|
||||
id("com.google.dagger.hilt.android")
|
||||
}
|
||||
|
||||
android {
|
||||
|
||||
defaultConfig {
|
||||
compileSdk = AppConfig.compileSdkVersion
|
||||
minSdk = AppConfig.minSdkVersion
|
||||
targetSdk = AppConfig.targetSdkVersion
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = JavaVersion.VERSION_1_8.toString()
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
isCoreLibraryDesugaringEnabled = false
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
/** Project*/
|
||||
implementation(project(":core:datasource"))
|
||||
implementation(project(":core:utils"))
|
||||
implementation(project(":features:swap:domain"))
|
||||
|
||||
/** DI */
|
||||
implementation(Library.hilt)
|
||||
kapt(Library.hiltKapt)
|
||||
}
|
||||
2
features/swap/data/src/main/AndroidManifest.xml
Normal file
2
features/swap/data/src/main/AndroidManifest.xml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest package="com.tangem.feature.swap.data" />
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
package com.tangem.feature.swap
|
||||
|
||||
import com.tangem.datasource.api.oneinch.OneInchApi
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.feature.swap.converters.ApproveConverter
|
||||
import com.tangem.feature.swap.converters.QuotesConverter
|
||||
import com.tangem.feature.swap.converters.SwapConverter
|
||||
import com.tangem.feature.swap.converters.TokensConverter
|
||||
import com.tangem.feature.swap.domain.SwapRepository
|
||||
import com.tangem.feature.swap.domain.models.ApproveModel
|
||||
import com.tangem.feature.swap.domain.models.Currency
|
||||
import com.tangem.feature.swap.domain.models.QuoteModel
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.withContext
|
||||
import javax.inject.Inject
|
||||
|
||||
class SwapRepositoryImpl @Inject constructor(
|
||||
private val tangemTechApi: TangemTechApi,
|
||||
private val oneInchApi: OneInchApi,
|
||||
private val tokensConverter: TokensConverter,
|
||||
private val quotesConverter: QuotesConverter,
|
||||
private val swapConverter: SwapConverter,
|
||||
private val approveConverter: ApproveConverter,
|
||||
private val coroutineDispatcher: CoroutineDispatcherProvider,
|
||||
) : SwapRepository {
|
||||
|
||||
override suspend fun getExchangeableTokens(networkId: String): List<Currency> {
|
||||
return withContext(coroutineDispatcher.io) {
|
||||
tokensConverter.convertList(tangemTechApi.coins(exchangeable = true, networkIds = networkId).coins)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun findBestQuote(fromTokenAddress: String, toTokenAddress: String, amount: String): QuoteModel {
|
||||
return withContext(coroutineDispatcher.io) {
|
||||
quotesConverter.convert(
|
||||
oneInchApi.quote(
|
||||
fromTokenAddress = fromTokenAddress,
|
||||
toTokenAddress = toTokenAddress,
|
||||
amount = amount,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun addressForTrust(): String {
|
||||
return withContext(coroutineDispatcher.io) {
|
||||
oneInchApi.approveSpender().address
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun dataToApprove(tokenAddress: String, amount: String): ApproveModel {
|
||||
return withContext(coroutineDispatcher.io) {
|
||||
approveConverter.convert(oneInchApi.approveTransaction(tokenAddress, amount))
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun checkTokensSpendAllowance(tokenAddress: String, walletAddress: String): String {
|
||||
return withContext(coroutineDispatcher.io) {
|
||||
oneInchApi.approveAllowance(tokenAddress, walletAddress).allowance
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun prepareSwapTransaction(
|
||||
fromTokenAddress: String,
|
||||
toTokenAddress: String,
|
||||
amount: String,
|
||||
fromAddress: String,
|
||||
slippage: Int,
|
||||
) {
|
||||
return withContext(coroutineDispatcher.io) {
|
||||
swapConverter.convert(
|
||||
oneInchApi.swap(
|
||||
fromTokenAddress = fromTokenAddress,
|
||||
toTokenAddress = toTokenAddress,
|
||||
amount = amount,
|
||||
fromAddress = fromAddress,
|
||||
slippage = slippage,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package com.tangem.feature.swap.converters
|
||||
|
||||
import com.tangem.datasource.api.oneinch.models.ApproveCalldataResponse
|
||||
import com.tangem.feature.swap.domain.models.ApproveModel
|
||||
import com.tangem.utils.converter.Converter
|
||||
import javax.inject.Inject
|
||||
|
||||
class ApproveConverter @Inject constructor() : Converter<ApproveCalldataResponse, ApproveModel> {
|
||||
|
||||
override fun convert(value: ApproveCalldataResponse): ApproveModel {
|
||||
return ApproveModel(
|
||||
data = value.data,
|
||||
gasPrice = value.gasPrice,
|
||||
toAddress = value.toAddress,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.tangem.feature.swap.converters
|
||||
|
||||
import com.tangem.datasource.api.oneinch.models.QuoteResponse
|
||||
import com.tangem.feature.swap.domain.models.QuoteModel
|
||||
import com.tangem.utils.converter.Converter
|
||||
|
||||
class QuotesConverter : Converter<QuoteResponse, QuoteModel> {
|
||||
|
||||
override fun convert(value: QuoteResponse): QuoteModel {
|
||||
return QuoteModel(
|
||||
fromTokenAmount = value.fromTokenAmount,
|
||||
toTokenAmount = value.toTokenAmount,
|
||||
estimatedGas = value.estimatedGas,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.tangem.feature.swap.converters
|
||||
|
||||
import com.tangem.datasource.api.oneinch.models.SwapResponse
|
||||
import com.tangem.feature.swap.domain.models.SwapTransactionModel
|
||||
import com.tangem.utils.converter.Converter
|
||||
import javax.inject.Inject
|
||||
|
||||
class SwapConverter @Inject constructor() : Converter<SwapResponse, SwapTransactionModel> {
|
||||
|
||||
override fun convert(value: SwapResponse): SwapTransactionModel {
|
||||
return SwapTransactionModel(
|
||||
fromTokenAddress = value.fromToken.address,
|
||||
toTokenAddress = value.toToken.address,
|
||||
toTokenAmount = value.fromTokenAmount,
|
||||
fromTokenAmount = value.toTokenAmount,
|
||||
fromWalletAddress = value.transaction.fromAddress,
|
||||
toWalletAddress = value.transaction.toAddress,
|
||||
data = value.transaction.data,
|
||||
value = value.transaction.value,
|
||||
gasPrice = value.transaction.gasPrice,
|
||||
gas = value.transaction.gas,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package com.tangem.feature.swap.converters
|
||||
|
||||
import com.tangem.datasource.api.tangemTech.CoinsResponse
|
||||
import com.tangem.feature.swap.domain.models.Currency
|
||||
import com.tangem.utils.converter.Converter
|
||||
import javax.inject.Inject
|
||||
|
||||
class TokensConverter @Inject constructor() : Converter<CoinsResponse.Coin, Currency> {
|
||||
|
||||
override fun convert(value: CoinsResponse.Coin): Currency {
|
||||
val network = value.networks.first()
|
||||
return if (network.contractAddress != null && network.decimalCount != null) {
|
||||
Currency.NonNativeToken(
|
||||
id = value.id,
|
||||
name = value.name,
|
||||
symbol = value.symbol,
|
||||
networkId = network.networkId,
|
||||
contractAddress = network.contractAddress!!,
|
||||
decimalCount = network.decimalCount!!.intValueExact(),
|
||||
logoUrl = "",//todo add logo
|
||||
)
|
||||
} else {
|
||||
Currency.NativeToken(
|
||||
id = value.id,
|
||||
name = value.name,
|
||||
symbol = value.symbol,
|
||||
networkId = network.networkId,
|
||||
logoUrl = "", //todo add logo
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
1
features/swap/domain/.gitignore
vendored
Normal file
1
features/swap/domain/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/build
|
||||
9
features/swap/domain/build.gradle.kts
Normal file
9
features/swap/domain/build.gradle.kts
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
plugins {
|
||||
id("java-library")
|
||||
id("org.jetbrains.kotlin.jvm")
|
||||
}
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
package com.tangem.feature.swap.domain
|
||||
|
||||
interface SwapInteractor {
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package com.tangem.feature.swap.domain
|
||||
|
||||
import com.tangem.feature.swap.domain.models.ApproveModel
|
||||
import com.tangem.feature.swap.domain.models.Currency
|
||||
import com.tangem.feature.swap.domain.models.QuoteModel
|
||||
|
||||
interface SwapRepository {
|
||||
|
||||
suspend fun getExchangeableTokens(networkId: String): List<Currency>
|
||||
|
||||
suspend fun findBestQuote(
|
||||
fromTokenAddress: String,
|
||||
toTokenAddress: String,
|
||||
amount: String,
|
||||
): QuoteModel
|
||||
|
||||
/**
|
||||
* Returns address of 1inch router that must be trusted
|
||||
*
|
||||
* @return address
|
||||
*/
|
||||
suspend fun addressForTrust(): String
|
||||
|
||||
/**
|
||||
* Generate "data" for calling contract in order to allow 1inch spend funds
|
||||
*
|
||||
* @param tokenAddress token you want to exchange
|
||||
* @param amount number of tokens is allowed. By default infinite
|
||||
*/
|
||||
suspend fun dataToApprove(
|
||||
tokenAddress: String,
|
||||
amount: String,
|
||||
): ApproveModel
|
||||
|
||||
/**
|
||||
* Get the number of tokens that the 1inch router is allowed to spend
|
||||
*
|
||||
* @param tokenAddress Token address you want to exchange
|
||||
* @param walletAddress address for which you want to check
|
||||
*
|
||||
* @return amount of tokens allowed to spend
|
||||
*/
|
||||
suspend fun checkTokensSpendAllowance(tokenAddress: String, walletAddress: String): String
|
||||
|
||||
suspend fun prepareSwapTransaction(
|
||||
fromTokenAddress: String,
|
||||
toTokenAddress: String,
|
||||
amount: String,
|
||||
fromAddress: String,
|
||||
slippage: Int,
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package com.tangem.feature.swap.domain.models
|
||||
|
||||
/**
|
||||
* Approve model
|
||||
*
|
||||
* @property data The encoded data to call the approve method on the swapped token contract
|
||||
* @property gasPrice Gas price for fast transaction processing
|
||||
* @property toAddress Token address that will be allowed to exchange through 1inch router
|
||||
*/
|
||||
data class ApproveModel(
|
||||
val data: String,
|
||||
val gasPrice: String,
|
||||
val toAddress: String,
|
||||
)
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package com.tangem.feature.swap.domain.models
|
||||
|
||||
sealed class Currency(
|
||||
open val id: String,
|
||||
open val name: String,
|
||||
open val symbol: String,
|
||||
open val networkId: String,
|
||||
open val logoUrl: String,
|
||||
) {
|
||||
|
||||
data class NativeToken(
|
||||
override val id: String,
|
||||
override val name: String,
|
||||
override val symbol: String,
|
||||
override val networkId: String,
|
||||
override val logoUrl: String,
|
||||
) : Currency(id, name, symbol, networkId, logoUrl)
|
||||
|
||||
data class NonNativeToken(
|
||||
override val id: String,
|
||||
override val name: String,
|
||||
override val symbol: String,
|
||||
override val networkId: String,
|
||||
override val logoUrl: String,
|
||||
val contractAddress: String,
|
||||
val decimalCount: Int,
|
||||
) : Currency(id, name, symbol, networkId, logoUrl)
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package com.tangem.feature.swap.domain.models
|
||||
|
||||
data class QuoteModel(
|
||||
val fromTokenAmount: String,
|
||||
val toTokenAmount: String,
|
||||
val estimatedGas: Int
|
||||
)
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package com.tangem.feature.swap.domain.models
|
||||
|
||||
/**
|
||||
* Swap transaction model
|
||||
*
|
||||
* @property fromTokenAddress token from which want to convert
|
||||
* @property toTokenAddress token to want to convert
|
||||
* @property toTokenAmount amount "target" token
|
||||
* @property fromTokenAmount amount "initial" token
|
||||
* @property fromWalletAddress wallet from address (transactions will be sent from this address)
|
||||
* @property toWalletAddress transactions will be sent to our(1inch) contract address
|
||||
* @property data The encoded data to call the approve method on the swapped token contract
|
||||
* @property value Native token value in WEI (for approve is always 0)
|
||||
* @property gasPrice maximum amount of gas for a swap default: 11500000; max: 11500000
|
||||
* @property gas estimated amount of the gas limit, increase this value by 25%
|
||||
* @constructor Create empty Swap transaction model
|
||||
*/
|
||||
data class SwapTransactionModel(
|
||||
val fromTokenAddress: String,
|
||||
val toTokenAddress: String,
|
||||
val toTokenAmount: String,
|
||||
val fromTokenAmount: String,
|
||||
val fromWalletAddress: String,
|
||||
val toWalletAddress: String,
|
||||
val data: String,
|
||||
val value: String,
|
||||
val gasPrice: String,
|
||||
val gas: String,
|
||||
)
|
||||
1
features/swap/presentation/.gitignore
vendored
Normal file
1
features/swap/presentation/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/build
|
||||
59
features/swap/presentation/build.gradle.kts
Normal file
59
features/swap/presentation/build.gradle.kts
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
plugins {
|
||||
id("com.android.library")
|
||||
kotlin("android")
|
||||
kotlin("kapt")
|
||||
id("com.google.dagger.hilt.android")
|
||||
}
|
||||
|
||||
android {
|
||||
|
||||
defaultConfig {
|
||||
compileSdk = AppConfig.compileSdkVersion
|
||||
minSdk = AppConfig.minSdkVersion
|
||||
targetSdk = AppConfig.targetSdkVersion
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = JavaVersion.VERSION_1_8.toString()
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
isCoreLibraryDesugaringEnabled = false
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
compose = true
|
||||
}
|
||||
|
||||
composeOptions {
|
||||
kotlinCompilerExtensionVersion = Versions.compose
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
/** Core modules */
|
||||
implementation(project(":core:utils"))
|
||||
implementation(project(":core:ui"))
|
||||
|
||||
/** AndroidX */
|
||||
implementation(AndroidX.appCompat)
|
||||
implementation(AndroidX.fragmentKtx)
|
||||
implementation(AndroidX.lifecycleViewModelKtx)
|
||||
|
||||
/** Compose */
|
||||
implementation(Compose.foundation)
|
||||
implementation(Compose.material)
|
||||
implementation(Compose.uiTooling)
|
||||
|
||||
/** Domain */
|
||||
implementation(project(":features:swap:domain"))
|
||||
|
||||
/** Other libraries */
|
||||
implementation(Library.composeShimmer)
|
||||
|
||||
/** DI */
|
||||
implementation(Library.hilt)
|
||||
kapt(Library.hiltKapt)
|
||||
}
|
||||
2
features/swap/presentation/src/main/AndroidManifest.xml
Normal file
2
features/swap/presentation/src/main/AndroidManifest.xml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest package="com.tangem.feature.swap.presentation" />
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
plugins {
|
||||
id("java-library")
|
||||
id("org.jetbrains.kotlin.jvm")
|
||||
}
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":common"))
|
||||
|
||||
/** Tangem libraries */
|
||||
implementation(Tangem.cardCore)
|
||||
|
||||
/** Other libraries */
|
||||
implementation(Library.retrofit)
|
||||
implementation(Library.retrofitMoshiConverter)
|
||||
implementation(Library.moshi)
|
||||
implementation(Library.moshiKotlin)
|
||||
implementation(Library.okHttp)
|
||||
implementation(Library.okHttpLogging)
|
||||
implementation(Library.timber)
|
||||
implementation(Library.coroutine)
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
package com.tangem.network.common
|
||||
|
||||
import com.tangem.common.module.ModuleError
|
||||
import com.tangem.common.module.ModuleErrorCode
|
||||
import com.tangem.common.module.ModuleMessage
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
sealed interface NetworkModuleMessage : ModuleMessage
|
||||
|
||||
sealed class NetworkError(
|
||||
subCode: Int,
|
||||
override val message: String,
|
||||
override val data: Any?,
|
||||
) : NetworkModuleMessage, ModuleError() {
|
||||
override val code: Int = ModuleErrorCode.NETWORK + subCode
|
||||
|
||||
companion object {
|
||||
// base code used for all error in the module
|
||||
// const val CODE_ANY_OTHER = 100..199, 200..299
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
include(":app")
|
||||
include(":domain")
|
||||
include(":network")
|
||||
include(":common")
|
||||
|
||||
// region Core modules
|
||||
|
|
@ -19,4 +18,7 @@ include(":libs:auth")
|
|||
include(":features:referral:data")
|
||||
include(":features:referral:domain")
|
||||
include(":features:referral:presentation")
|
||||
include(":features:swap:data")
|
||||
include(":features:swap:domain")
|
||||
include(":features:swap:presentation")
|
||||
// endregion Feature modules
|
||||
Loading…
Add table
Add a link
Reference in a new issue