Updated on 2026-08-14

This commit is contained in:
Tangem 2022-12-22 16:25:58 +03:00
parent 9cf90df510
commit 1c5519a702
19 changed files with 327 additions and 83 deletions

View file

@ -79,6 +79,7 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
tangemSdk = TangemSdk.init(this, TangemSdkManager.config)
tangemSdkManager = TangemSdkManager(tangemSdk, this)
appStateHolder.tangemSdkManager = tangemSdkManager
appStateHolder.tangemSdk = tangemSdk
backupService = BackupService.init(tangemSdk, this)
userWalletsListManager = UserWalletsListManager.provideBiometricImplementation(
context = applicationContext,

View file

@ -1,5 +1,6 @@
package com.tangem.tap.proxy
import com.tangem.TangemSdk
import com.tangem.domain.common.CardDTO
import com.tangem.domain.common.ScanResponse
import com.tangem.tap.common.redux.AppState
@ -7,18 +8,20 @@ import com.tangem.tap.domain.TangemSdkManager
import com.tangem.tap.domain.tokens.UserTokensRepository
import com.tangem.tap.features.wallet.redux.WalletState
import org.rekotlin.Store
import javax.inject.Inject
/**
* Holds objects from old modules, that missing in DI graph
* Object sets manually to use in new modules and [AppStateHolder] proxies its to DI
*/
class AppStateHolder {
class AppStateHolder @Inject constructor(){
var scanResponse: ScanResponse? = null
var walletState: WalletState? = null
var userTokensRepository: UserTokensRepository? = null
var mainStore: Store<AppState>? = null
var tangemSdkManager: TangemSdkManager? = null
var tangemSdk: TangemSdk? = null
fun getActualCard(): CardDTO? {
return scanResponse?.card

View file

@ -0,0 +1,133 @@
package com.tangem.tap.proxy
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.tangem.Message
import com.tangem.blockchain.common.Amount
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.BlockchainSdkError
import com.tangem.blockchain.common.Token
import com.tangem.blockchain.common.TransactionSender
import com.tangem.blockchain.common.TransactionSigner
import com.tangem.blockchain.common.WalletManager
import com.tangem.blockchain.extensions.SimpleResult
import com.tangem.common.core.TangemSdkError
import com.tangem.domain.common.extensions.fromNetworkId
import com.tangem.lib.crypto.TransactionManager
import com.tangem.lib.crypto.models.Currency
import com.tangem.lib.crypto.models.NativeToken
import com.tangem.lib.crypto.models.NonNativeToken
import com.tangem.lib.crypto.models.transactions.SendTxResult
import com.tangem.tap.common.redux.global.GlobalAction
import com.tangem.tap.domain.TangemSigner
import com.tangem.tap.domain.tokens.models.BlockchainNetwork
import com.tangem.tap.store
import com.tangem.tap.tangemSdk
import java.math.BigDecimal
class TransactionManagerImpl(
private val appStateHolder: AppStateHolder,
) : TransactionManager {
@Throws(IllegalStateException::class)
override suspend fun sendTransaction(
networkId: String,
amountToSend: BigDecimal,
currencyToSend: Currency,
feeAmount: BigDecimal,
destinationAddress: String,
dataToSign: String,
): SendTxResult {
val blockchain = requireNotNull(Blockchain.fromNetworkId(networkId)) { "blockchain not found" }
val walletManager = getActualWalletManager(blockchain)
val amount = when (currencyToSend) {
is NativeToken -> {
Amount(value = amountToSend, blockchain = blockchain)
}
is NonNativeToken -> {
Amount(
convertNonNativeToken(currencyToSend),
amountToSend,
)
}
}
val txData = walletManager.createTransaction(
amount = amount,
fee = Amount(value = feeAmount, blockchain = blockchain),
destination = destinationAddress,
).copy(hash = dataToSign)
val signer = transactionSigner(walletManager)
val sendResult = try {
(walletManager as TransactionSender).send(txData, signer)
} catch (ex: Exception) {
FirebaseCrashlytics.getInstance().recordException(ex)
return SendTxResult.UnknownError(ex)
}
return handleSendResult(sendResult)
}
private fun handleSendResult(result: SimpleResult): SendTxResult {
when (result) {
is SimpleResult.Success -> {
return SendTxResult.Success
}
is SimpleResult.Failure -> {
val error = (result.error as? BlockchainSdkError) ?: return SendTxResult.UnknownError()
when (error) {
is BlockchainSdkError.WrappedTangemError -> {
val tangemSdkError = (error.tangemError as? TangemSdkError)
?: return SendTxResult.UnknownError()
if (tangemSdkError is TangemSdkError.UserCancelled) return SendTxResult.UserCancelledError
return SendTxResult.TangemSdkError(tangemSdkError.code, tangemSdkError.cause)
}
else -> {
return SendTxResult.TangemSdkError(error.code, error.cause)
}
}
}
}
}
private fun transactionSigner(walletManager: WalletManager): TransactionSigner {
val actualCard = requireNotNull(appStateHolder.getActualCard()) { "no card found" }
return TangemSigner(
card = actualCard,
tangemSdk = tangemSdk,
initialMessage = Message("test transaction title", "test description"),
) { signResponse ->
store.dispatch(
GlobalAction.UpdateWalletSignedHashes(
walletSignedHashes = signResponse.totalSignedHashes,
walletPublicKey = walletManager.wallet.publicKey.seedKey,
remainingSignatures = signResponse.remainingSignatures,
),
)
}
}
private fun getActualWalletManager(blockchain: Blockchain): WalletManager {
val card = appStateHolder.getActualCard()
if (card != null) {
val blockchainNetwork = BlockchainNetwork(blockchain, card)
val walletManager = appStateHolder.walletState?.getWalletManager(blockchainNetwork)
if (walletManager != null) {
return walletManager
} else {
error("no wallet manager found")
}
} else {
error("card not found")
}
}
private fun convertNonNativeToken(token: NonNativeToken): Token {
return Token(
name = token.name,
symbol = token.symbol,
contractAddress = token.contractAddress,
decimals = token.decimalCount,
id = token.id,
)
}
}

View file

@ -2,9 +2,11 @@ package com.tangem.tap.proxy.di
import com.tangem.blockchain.common.WalletManagerFactory
import com.tangem.lib.crypto.DerivationManager
import com.tangem.lib.crypto.TransactionManager
import com.tangem.lib.crypto.UserWalletManager
import com.tangem.tap.proxy.AppStateHolder
import com.tangem.tap.proxy.DerivationManagerImpl
import com.tangem.tap.proxy.TransactionManagerImpl
import com.tangem.tap.proxy.UserWalletManagerImpl
import dagger.Module
import dagger.Provides
@ -31,6 +33,12 @@ class ProxyModule {
)
}
@Provides
@Singleton
fun provideTransactionManager(appStateHolder: AppStateHolder): TransactionManager {
return TransactionManagerImpl(appStateHolder)
}
@Provides
@Singleton
fun provideDerivationManager(appStateHolder: AppStateHolder): DerivationManager {