diff --git a/blockchain/.gitignore b/blockchain/.gitignore new file mode 100644 index 0000000000..796b96d1c4 --- /dev/null +++ b/blockchain/.gitignore @@ -0,0 +1 @@ +/build diff --git a/blockchain/build.gradle b/blockchain/build.gradle new file mode 100644 index 0000000000..5864305e8f --- /dev/null +++ b/blockchain/build.gradle @@ -0,0 +1,47 @@ +apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-android-extensions' +android { + compileSdkVersion 29 + buildToolsVersion "29.0.0" + + + defaultConfig { + minSdkVersion 21 + targetSdkVersion 29 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles 'consumer-rules.pro' + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation project(':tangem-core') + implementation project(':tangem-sdk') + + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + 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:converter-moshi:2.6.0' + implementation 'com.squareup.moshi:moshi:1.9.2' + + implementation 'org.bitcoinj:bitcoinj-core:0.15.2' + + + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.5.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' +} diff --git a/blockchain/proguard-rules.pro b/blockchain/proguard-rules.pro new file mode 100644 index 0000000000..f1b424510d --- /dev/null +++ b/blockchain/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/blockchain/src/main/AndroidManifest.xml b/blockchain/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..83f5f31450 --- /dev/null +++ b/blockchain/src/main/AndroidManifest.xml @@ -0,0 +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 new file mode 100644 index 0000000000..6d9033458c --- /dev/null +++ b/blockchain/src/main/java/com/tangem/blockchain/common/Blockchain.kt @@ -0,0 +1,64 @@ +package com.tangem.blockchain.common + +import com.tangem.blockchain.bitcoin.BitcoinAddressFactory +import com.tangem.blockchain.bitcoin.BitcoinAddressValidator +import java.math.BigDecimal + +enum class Blockchain( + val id: String, + val currency: String, + val decimals: Byte, + val fullName: String, + val pendingTransactionTimeout: Int) { + Unknown("", "", 0, "", 0), + Bitcoin("", "", 8, "", 0), + BitcoinTestnet("", "", 8, "", 0), + Ethereum("", "", 18, "", 0), + Rootstock("", "", 18, "", 0), + Cardano("", "", 6, "", 0), + Ripple("", "", 6, "", 0), + Binance("", "", 8, "", 0), + Stellar("", "", 7, "", 0); + + fun roundingMode(): Int = when (this) { + Bitcoin, Ethereum, Rootstock, Binance -> BigDecimal.ROUND_DOWN + Cardano -> BigDecimal.ROUND_UP + else -> BigDecimal.ROUND_HALF_UP + } + + fun makeAddress(cardPublicKey: ByteArray): String { + return when (this) { + 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) + } + } + + fun validateAddress(address: String): Boolean { + return when (this) { + 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) + } + } + + companion object { + private val values = values() + fun fromId(id: String): Blockchain = values.find { it.id == id } ?: Unknown + fun fromName(name: String): Blockchain = values.find { it.name == name } ?: Unknown + fun fromCurrency(currency: String): Blockchain = values.find { it.currency == currency } + ?: Unknown + } +} diff --git a/blockchain/src/main/java/com/tangem/blockchain/common/Wallet.kt b/blockchain/src/main/java/com/tangem/blockchain/common/Wallet.kt new file mode 100644 index 0000000000..73457822cc --- /dev/null +++ b/blockchain/src/main/java/com/tangem/blockchain/common/Wallet.kt @@ -0,0 +1,39 @@ +package com.tangem.blockchain.common + +import java.math.BigDecimal +import java.util.* + +interface Wallet { + val config: WalletConfig + val address: String + val exploreUrl: String? + val shareUrl: String? +} + +class WalletConfig( + val allowFeeSelection: Boolean, + val allowFeeInclusion: Boolean, + var allowExtract: Boolean = false, + var allowLoad: Boolean = false +) + +data class Amount( + val type: AmountType = AmountType.Coin, + val currencySymbol: String, + val value: BigDecimal +) + +data class Transaction( + val amount: Amount, + val fee: Amount?, + val sourceAddress: String, + val destinationAddress: String +) + +enum class AmountType { Coin, Token, Reserve } + +enum class ValidationError { WrongAmount, WrongFee, WrongTotal } + +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 new file mode 100644 index 0000000000..818a863eb3 --- /dev/null +++ b/blockchain/src/main/java/com/tangem/blockchain/common/WalletManager.kt @@ -0,0 +1,22 @@ +package com.tangem.blockchain.common + +interface WalletManager { + var wallet: Wallet + val blockchain: Blockchain + + fun update() +} + +interface TransactionBuilder { + fun getEstimateSize(transaction: Transaction): Int +} + +interface TransactionSender { + fun send(transaction: Transaction, signer: TransactionSigner) +} + +interface TransactionSigner + +interface FeeProvider { + fun getFee(amount: Amount, source: String, destination: String): List +} \ 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 new file mode 100644 index 0000000000..a8b56cc042 --- /dev/null +++ b/blockchain/src/main/java/com/tangem/blockchain/wallets/CurrencyWallet.kt @@ -0,0 +1,20 @@ +package com.tangem.blockchain.wallets + +import com.tangem.blockchain.common.* +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(), + val isTestnet: Boolean = false +) : Wallet, TransactionValidator { + + + override fun validateTransaction(amount: Amount, fee: Amount?): EnumSet { + TODO("not implemented") + } +} \ No newline at end of file diff --git a/blockchain/src/main/res/values/strings.xml b/blockchain/src/main/res/values/strings.xml new file mode 100644 index 0000000000..4b289d3aaa --- /dev/null +++ b/blockchain/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + Blockchain +