From 792ca79ebeb8f02f6b1a73f5f96d3cf6724e3973 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 16 Dec 2019 14:40:19 +0300 Subject: [PATCH] Updated on 2026-08-14 --- blockchain/build.gradle | 7 ++- .../tangem/blockchain/common/Blockchain.kt | 28 ++++++---- .../com/tangem/blockchain/common/Wallet.kt | 12 ++-- .../tangem/blockchain/common/WalletManager.kt | 14 +++-- .../blockchain/common/WalletManagerFactory.kt | 54 ++++++++++++++++++ .../tangem/blockchain/eth/EthereumAddress.kt | 15 +++++ .../blockchain/eth/EthereumWalletManager.kt | 55 +++++++++++++++++++ .../tangem/blockchain/extensions/ByteArray.kt | 11 ++++ .../blockchain/wallets/CurrencyWallet.kt | 8 +-- 9 files changed, 176 insertions(+), 28 deletions(-) create mode 100644 blockchain/src/main/java/com/tangem/blockchain/common/WalletManagerFactory.kt create mode 100644 blockchain/src/main/java/com/tangem/blockchain/eth/EthereumAddress.kt create mode 100644 blockchain/src/main/java/com/tangem/blockchain/eth/EthereumWalletManager.kt create mode 100644 blockchain/src/main/java/com/tangem/blockchain/extensions/ByteArray.kt diff --git a/blockchain/build.gradle b/blockchain/build.gradle index 5864305e8f..2bd12af9e7 100644 --- a/blockchain/build.gradle +++ b/blockchain/build.gradle @@ -26,7 +26,7 @@ android { } dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) +// implementation fileTree(dir: 'libs', include: ['*.jar']) implementation project(':tangem-core') implementation project(':tangem-sdk') @@ -34,12 +34,13 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.core:core-ktx:1.1.0' - implementation 'com.squareup.retrofit2:retrofit:2.6.0' + implementation 'com.squareup.retrofit2:retrofit:2.6.2' implementation 'com.squareup.retrofit2:converter-moshi:2.6.0' implementation 'com.squareup.moshi:moshi:1.9.2' implementation 'org.bitcoinj:bitcoinj-core:0.15.2' - + implementation 'com.github.komputing:kethereum:0.79.5' + implementation 'com.github.stellar:java-stellar-sdk:0.11.0' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.5.2' androidTestImplementation 'androidx.test.ext:junit:1.1.1' diff --git a/blockchain/src/main/java/com/tangem/blockchain/common/Blockchain.kt b/blockchain/src/main/java/com/tangem/blockchain/common/Blockchain.kt index 6d9033458c..065f19f1d8 100644 --- a/blockchain/src/main/java/com/tangem/blockchain/common/Blockchain.kt +++ b/blockchain/src/main/java/com/tangem/blockchain/common/Blockchain.kt @@ -2,6 +2,10 @@ package com.tangem.blockchain.common import com.tangem.blockchain.bitcoin.BitcoinAddressFactory import com.tangem.blockchain.bitcoin.BitcoinAddressValidator +import com.tangem.blockchain.eth.EthereumAddressFactory +import com.tangem.blockchain.eth.EthereumAddressValidator +import com.tangem.blockchain.stellar.StellarAddressFactory +import com.tangem.blockchain.stellar.StellarAddressValidator import java.math.BigDecimal enum class Blockchain( @@ -31,12 +35,12 @@ enum class Blockchain( Unknown -> throw Exception("unsupported blockchain") Bitcoin -> BitcoinAddressFactory.makeAddress(cardPublicKey) BitcoinTestnet -> BitcoinAddressFactory.makeAddress(cardPublicKey, testNet = true) -// Ethereum -> EthereumAddressFactory.makeAddress(cardPublicKey) -// Rootstock -> RootstockAddressFactory.makeAddress(cardPublicKey) -// Cardano -> CardanoAddressFactory.makeAddress(cardPublicKey) -// Ripple -> RippleAddressFactory.makeAddress(cardPublicKey) -// Binance -> BinanceAddressFactory.makeAddress(cardPublicKey) -// Stellar -> StellarAddressFactory.makeAddress(cardPublicKey) + Ethereum -> EthereumAddressFactory.makeAddress(cardPublicKey) + Rootstock -> RootstockAddressFactory.makeAddress(cardPublicKey) + Cardano -> CardanoAddressFactory.makeAddress(cardPublicKey) + Ripple -> RippleAddressFactory.makeAddress(cardPublicKey) + Binance -> BinanceAddressFactory.makeAddress(cardPublicKey) + Stellar -> StellarAddressFactory.makeAddress(cardPublicKey) } } @@ -45,12 +49,12 @@ enum class Blockchain( Unknown -> throw Exception("unsupported blockchain") Bitcoin -> BitcoinAddressValidator.validate(address) BitcoinTestnet -> BitcoinAddressValidator.validate(address, testNet = true) -// Ethereum -> EthereumAddressValidator.validate(address) -// Rootstock -> RootstockAddressValidator.validate(address) -// Cardano -> CardanoAddressValidator.validate(address) -// Ripple -> RippleAddressValidator.validate(address) -// Binance -> BinanceAddressValidator.validate(address) -// Stellar -> StellarAddressValidator.validate(address) + Ethereum -> EthereumAddressValidator.validate(address) + Rootstock -> RootstockAddressValidator.validate(address) + Cardano -> CardanoAddressValidator.validate(address) + Ripple -> RippleAddressValidator.validate(address) + Binance -> BinanceAddressValidator.validate(address) + Stellar -> StellarAddressValidator.validate(address) } } diff --git a/blockchain/src/main/java/com/tangem/blockchain/common/Wallet.kt b/blockchain/src/main/java/com/tangem/blockchain/common/Wallet.kt index 73457822cc..ef9ab03b94 100644 --- a/blockchain/src/main/java/com/tangem/blockchain/common/Wallet.kt +++ b/blockchain/src/main/java/com/tangem/blockchain/common/Wallet.kt @@ -18,12 +18,14 @@ class WalletConfig( ) data class Amount( - val type: AmountType = AmountType.Coin, val currencySymbol: String, - val value: BigDecimal -) + val value: BigDecimal?, + val address: String, + val decimals: Int, + val type: AmountType = AmountType.Coin + ) -data class Transaction( +data class TransactionData( val amount: Amount, val fee: Amount?, val sourceAddress: String, @@ -34,6 +36,6 @@ enum class AmountType { Coin, Token, Reserve } enum class ValidationError { WrongAmount, WrongFee, WrongTotal } -interface TransactionValidator{ +interface TransactionValidator { fun validateTransaction(amount: Amount, fee: Amount?): EnumSet } \ No newline at end of file diff --git a/blockchain/src/main/java/com/tangem/blockchain/common/WalletManager.kt b/blockchain/src/main/java/com/tangem/blockchain/common/WalletManager.kt index 818a863eb3..610319380f 100644 --- a/blockchain/src/main/java/com/tangem/blockchain/common/WalletManager.kt +++ b/blockchain/src/main/java/com/tangem/blockchain/common/WalletManager.kt @@ -1,5 +1,8 @@ package com.tangem.blockchain.common +import com.tangem.commands.SignResponse +import com.tangem.tasks.TaskEvent + interface WalletManager { var wallet: Wallet val blockchain: Blockchain @@ -7,15 +10,18 @@ interface WalletManager { fun update() } -interface TransactionBuilder { - fun getEstimateSize(transaction: Transaction): Int +interface TransactionEstimator { + fun getEstimateSize(transactionData: TransactionData): Int } interface TransactionSender { - fun send(transaction: Transaction, signer: TransactionSigner) + fun send(transactionData: TransactionData, signer: TransactionSigner) } -interface TransactionSigner +interface TransactionSigner { + fun sign(hashes: Array, cardId: String, + callback: (result: TaskEvent) -> Unit) +} interface FeeProvider { fun getFee(amount: Amount, source: String, destination: String): List diff --git a/blockchain/src/main/java/com/tangem/blockchain/common/WalletManagerFactory.kt b/blockchain/src/main/java/com/tangem/blockchain/common/WalletManagerFactory.kt new file mode 100644 index 0000000000..33e0a0edb0 --- /dev/null +++ b/blockchain/src/main/java/com/tangem/blockchain/common/WalletManagerFactory.kt @@ -0,0 +1,54 @@ +package com.tangem.blockchain.common + +import com.tangem.blockchain.bitcoin.BitcoinWalletManager +import com.tangem.blockchain.eth.EthereumWalletManager +import com.tangem.blockchain.stellar.StellarWalletManager +import com.tangem.commands.Card + +object WalletManagerFactory { + + fun makeWalletManager(card: Card): WalletManager? { + val walletPublicKey = card.walletPublicKey ?: return null + val blockchainName = card.cardData?.blockchainName ?: return null + + when { + blockchainName.contains("btc") || blockchainName.contains("bitcoin") -> { + return BitcoinWalletManager( + cardId = card.cardId, + walletPublicKey = walletPublicKey, + walletConfig = WalletConfig(true, true), + isTestNet = blockchainName.contains("test")) + } + blockchainName.contains("eth") -> { + return EthereumWalletManager( + cardId = card.cardId, + walletPublicKey = walletPublicKey, + walletConfig = WalletConfig(true, true)) + } + blockchainName.contains("xlm") -> { + val token = getToken(card) + return StellarWalletManager( + cardId = card.cardId, + walletPublicKey = walletPublicKey, + walletConfig = WalletConfig(true, token == null), + token = token, + isTestNet = blockchainName.contains("test")) + } + else -> return null + } + } + + private fun getToken(card: Card): Token? { + val symbol = card.cardData?.tokenSymbol ?: return null + val contractAddress = card.cardData?.tokenContractAddress ?: return null + val decimals = card.cardData?.tokenDecimal ?: return null + return Token(symbol, contractAddress, decimals) + } +} + + +data class Token( + val symbol: String, + val contractAddress: String, + val decimals: Int +) \ No newline at end of file diff --git a/blockchain/src/main/java/com/tangem/blockchain/eth/EthereumAddress.kt b/blockchain/src/main/java/com/tangem/blockchain/eth/EthereumAddress.kt new file mode 100644 index 0000000000..f1d93046a1 --- /dev/null +++ b/blockchain/src/main/java/com/tangem/blockchain/eth/EthereumAddress.kt @@ -0,0 +1,15 @@ +package com.tangem.blockchain.eth + +import org.kethereum.crypto.toAddress +import org.kethereum.functions.isValid +import org.kethereum.model.Address +import org.kethereum.model.PublicKey + +object EthereumAddressFactory { + fun makeAddress(cardPublicKey: ByteArray, testNet: Boolean = false): String = + PublicKey(cardPublicKey).toAddress().hex +} + +object EthereumAddressValidator { + fun validate(address: String, testNet: Boolean = false): Boolean = Address(address).isValid() +} \ No newline at end of file diff --git a/blockchain/src/main/java/com/tangem/blockchain/eth/EthereumWalletManager.kt b/blockchain/src/main/java/com/tangem/blockchain/eth/EthereumWalletManager.kt new file mode 100644 index 0000000000..a84dc8e57b --- /dev/null +++ b/blockchain/src/main/java/com/tangem/blockchain/eth/EthereumWalletManager.kt @@ -0,0 +1,55 @@ +package com.tangem.blockchain.eth + +import com.tangem.blockchain.common.* +import com.tangem.blockchain.wallets.CurrencyWallet +import com.tangem.tasks.TaskEvent + +class EthereumWalletManager( + private val cardId: String, + private val walletPublicKey: ByteArray, + walletConfig: WalletConfig +) : WalletManager, + TransactionEstimator, + TransactionSender, + FeeProvider { + + override val blockchain: Blockchain = Blockchain.Ethereum + private val address = blockchain.makeAddress(walletPublicKey) + override var wallet: Wallet = CurrencyWallet(walletConfig, address) + + override fun update() { + + } + + override fun getEstimateSize(transactionData: TransactionData): Int { + + } + + override fun send(transactionData: TransactionData, signer: TransactionSigner) { + val builder = EthereumTransactionBuilder() + val hashes = builder.buildToSign(transactionData, walletPublicKey) + signer.sign(hashes.toTypedArray(), cardId) { + when (it) { + is TaskEvent.Event -> builder.buildToSend(transactionData, it.data.signature) + } + } + } + + override fun getFee(amount: Amount, source: String, destination: String): List { + + } + +} + + +class EthereumTransactionBuilder { + + + fun buildToSign(transactionData: TransactionData, publicKey: ByteArray): List { + + } + + fun buildToSend(transactionData: TransactionData, signature: ByteArray) { + + } +} diff --git a/blockchain/src/main/java/com/tangem/blockchain/extensions/ByteArray.kt b/blockchain/src/main/java/com/tangem/blockchain/extensions/ByteArray.kt new file mode 100644 index 0000000000..2619ca0184 --- /dev/null +++ b/blockchain/src/main/java/com/tangem/blockchain/extensions/ByteArray.kt @@ -0,0 +1,11 @@ +package com.tangem.blockchain.extensions + +import org.spongycastle.crypto.digests.RIPEMD160Digest + +fun ByteArray.calculateRipemd160(): ByteArray { + val digest = RIPEMD160Digest() + digest.update(this, 0, this.size) + val out = ByteArray(20) + digest.doFinal(out, 0) + return out +} \ No newline at end of file diff --git a/blockchain/src/main/java/com/tangem/blockchain/wallets/CurrencyWallet.kt b/blockchain/src/main/java/com/tangem/blockchain/wallets/CurrencyWallet.kt index a8b56cc042..a1e2bb544a 100644 --- a/blockchain/src/main/java/com/tangem/blockchain/wallets/CurrencyWallet.kt +++ b/blockchain/src/main/java/com/tangem/blockchain/wallets/CurrencyWallet.kt @@ -6,10 +6,10 @@ import java.util.* class CurrencyWallet( override val config: WalletConfig, override val address: String, - override val exploreUrl: String?, - override val shareUrl: String?, - val pendingTransactions: List = listOf(), - val balances: List = listOf(), + override val exploreUrl: String? = null, + override val shareUrl: String? = null, + val pendingTransactions: List = listOf(), + val balances: MutableList = mutableListOf(), val isTestnet: Boolean = false ) : Wallet, TransactionValidator {