diff --git a/blockchain-demo/.gitignore b/blockchain-demo/.gitignore
new file mode 100644
index 0000000000..796b96d1c4
--- /dev/null
+++ b/blockchain-demo/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/blockchain-demo/build.gradle b/blockchain-demo/build.gradle
new file mode 100644
index 0000000000..6567a8b453
--- /dev/null
+++ b/blockchain-demo/build.gradle
@@ -0,0 +1,63 @@
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-android-extensions'
+apply plugin: 'kotlin-kapt'
+
+android {
+ compileSdkVersion 29
+ buildToolsVersion "29.0.2"
+
+
+ defaultConfig {
+ applicationId "com.example.blockchain_demo"
+ minSdkVersion 21
+ targetSdkVersion 29
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = '1.8'
+ }
+
+ packagingOptions {
+ exclude 'lib/x86_64/darwin/libscrypt.dylib'
+ exclude 'lib/x86_64/freebsd/libscrypt.so'
+ exclude 'lib/x86_64/linux/libscrypt.so'
+ }
+
+ viewBinding {
+ enabled = true
+ }
+}
+
+dependencies {
+ implementation project(':tangem-core')
+ implementation project(':tangem-sdk')
+ implementation project(':blockchain')
+
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$versions.kotlin"
+ implementation 'androidx.appcompat:appcompat:1.1.0'
+ implementation 'androidx.core:core-ktx:1.2.0'
+ implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'com.google.android.material:material:1.1.0'
+ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.3'
+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.3.3"
+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3"
+ testImplementation 'junit:junit:4.12'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.1'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
+}
diff --git a/blockchain-demo/proguard-rules.pro b/blockchain-demo/proguard-rules.pro
new file mode 100644
index 0000000000..f1b424510d
--- /dev/null
+++ b/blockchain-demo/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-demo/src/androidTest/java/com/tangem/blockchain_demo/ExampleInstrumentedTest.kt b/blockchain-demo/src/androidTest/java/com/tangem/blockchain_demo/ExampleInstrumentedTest.kt
new file mode 100644
index 0000000000..2a03ebc11f
--- /dev/null
+++ b/blockchain-demo/src/androidTest/java/com/tangem/blockchain_demo/ExampleInstrumentedTest.kt
@@ -0,0 +1,22 @@
+package com.tangem.blockchain_demo
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.platform.app.InstrumentationRegistry
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+@RunWith(AndroidJUnit4::class)
+class ExampleInstrumentedTest {
+ @Test
+ fun useAppContext() {
+ // Context of the app under test.
+ val appContext = InstrumentationRegistry.getInstrumentation().targetContext
+ assertEquals("com.example.blockchain_demo", appContext.packageName)
+ }
+}
\ No newline at end of file
diff --git a/blockchain-demo/src/main/AndroidManifest.xml b/blockchain-demo/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..9d092d68db
--- /dev/null
+++ b/blockchain-demo/src/main/AndroidManifest.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/blockchain-demo/src/main/java/com/tangem/blockchain_demo/BlockchainDemoActivity.kt b/blockchain-demo/src/main/java/com/tangem/blockchain_demo/BlockchainDemoActivity.kt
new file mode 100644
index 0000000000..0028ee31c5
--- /dev/null
+++ b/blockchain-demo/src/main/java/com/tangem/blockchain_demo/BlockchainDemoActivity.kt
@@ -0,0 +1,188 @@
+package com.tangem.blockchain_demo
+
+import android.os.Bundle
+import android.text.Editable
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import com.tangem.CardManager
+import com.tangem.blockchain.common.*
+import com.tangem.blockchain.common.extensions.Result
+import com.tangem.blockchain.common.extensions.Signer
+import com.tangem.blockchain.common.extensions.SimpleResult
+import com.tangem.blockchain_demo.databinding.ActivityBlockchainDemoBinding
+import com.tangem.commands.Card
+import com.tangem.tangem_sdk_new.extensions.init
+import com.tangem.tasks.ScanEvent
+import com.tangem.tasks.TaskError
+import com.tangem.tasks.TaskEvent
+import kotlinx.coroutines.*
+import java.math.BigDecimal
+import kotlin.coroutines.CoroutineContext
+
+class BlockchainDemoActivity : AppCompatActivity() {
+
+ private lateinit var cardManager: CardManager
+ private lateinit var signer: TransactionSigner
+ private lateinit var card: Card
+ private lateinit var walletManager: WalletManager
+ private var issuerDataCounter: Int = 1
+
+ private lateinit var fee: BigDecimal
+
+ private lateinit var binding: ActivityBlockchainDemoBinding
+
+ private val parentJob = Job()
+ private val exceptionHandler = CoroutineExceptionHandler { _, throwable ->
+ handleError(throwable.localizedMessage)
+ }
+ private val coroutineContext: CoroutineContext
+ get() = parentJob + Dispatchers.IO + exceptionHandler
+ private val scope = CoroutineScope(coroutineContext)
+
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ binding = ActivityBlockchainDemoBinding.inflate(layoutInflater)
+ val view = binding.root
+ setContentView(view)
+
+ cardManager = CardManager.init(this)
+ signer = Signer(cardManager)
+
+ binding.btnScan.setOnClickListener { scan() }
+
+ binding.btnCheckFee.setOnClickListener { requestFee() }
+
+ binding.btnSend.setOnClickListener { send() }
+ }
+
+
+ private fun scan() {
+ cardManager.scanCard { taskEvent ->
+ when (taskEvent) {
+ is TaskEvent.Event -> {
+ when (taskEvent.data) {
+ is ScanEvent.OnReadEvent -> {
+ card = (taskEvent.data as ScanEvent.OnReadEvent).card
+ walletManager = WalletManagerFactory.makeWalletManager(card)!!
+ getInfo()
+ }
+ }
+ }
+ is TaskEvent.Completion -> {
+ if (taskEvent.error != null) {
+ if (taskEvent.error !is TaskError.UserCancelled) {
+ handleError(taskEvent.error.toString())
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private fun getInfo() {
+ scope.launch {
+ walletManager.update()
+ withContext(Dispatchers.Main) {
+ binding.tvBalance.text =
+ "${walletManager.wallet.balances[AmountType.Coin]?.value
+ ?: "error"} ${walletManager.blockchain.currency}"
+ val token = walletManager.wallet.balances[AmountType.Token]
+ if (token != null) {
+ binding.tvBalance.text = token.currencySymbol + " " + token.value
+ binding.etSumToSend.text = Editable.Factory.getInstance().newEditable(
+ token.value.toString()
+ )
+ } else {
+ binding.etSumToSend.text =
+ Editable.Factory.getInstance().newEditable(
+ walletManager.wallet.balances[AmountType.Coin]?.value.toString()
+ )
+ }
+ binding.btnCheckFee.isEnabled = true
+ }
+ }
+ }
+
+ private fun requestFee() {
+ if (binding.etReceiverAddress.text.isBlank()) {
+ Toast.makeText(this, "Please enter receiver address", Toast.LENGTH_LONG).show()
+ return
+ } else if (binding.etSumToSend.text.isBlank()) {
+ Toast.makeText(this, "Choose sum to send", Toast.LENGTH_LONG).show()
+ return
+ }
+
+ scope.launch {
+ val feeResult = (walletManager as FeeProvider).getFee(
+ walletManager.wallet.balances[AmountType.Token]
+ ?: walletManager.wallet.balances[AmountType.Coin]!!,
+ binding.etReceiverAddress.text.toString())
+ withContext(Dispatchers.Main) {
+ when (feeResult) {
+ is Result.Failure -> {
+ handleError(feeResult.error?.localizedMessage ?: "Error")
+ }
+ is Result.Success -> {
+ binding.btnSend.isEnabled = true
+ val fees = feeResult.data
+ if (fees.size == 1) {
+ binding.tvFee.text = fees[0].value.toString()
+ fee = fees[0].value ?: BigDecimal(0)
+ } else {
+ binding.tvFee.text = fees[0].value.toString() + "\n" +
+ fees[1].value.toString() + "\n" +
+ fees[2].value.toString()
+ fee = fees[1].value ?: BigDecimal(0)
+
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private fun send() {
+ scope.launch {
+ val result = (walletManager as TransactionSender).send(
+ formTransactionData(),
+ signer)
+ withContext(Dispatchers.Main) {
+ when (result) {
+ is SimpleResult.Failure -> {
+ handleError(result.error?.localizedMessage ?: "Error")
+ }
+ is SimpleResult.Success -> {
+ binding.tvFee.text = "Success"
+ }
+ }
+ }
+ }
+ }
+
+ private fun formTransactionData(): TransactionData {
+ val amount = if (walletManager.wallet.balances[AmountType.Token] != null) {
+ walletManager.wallet.balances[AmountType.Token]!!
+ } else {
+ walletManager.wallet.balances[AmountType.Coin]!!.copy(
+ value = binding.etSumToSend.text.toString().toBigDecimal() - fee
+ )
+ }
+ return TransactionData(
+ amount,
+ walletManager.wallet.balances[AmountType.Coin]!!.copy(value = fee),
+ walletManager.wallet.balances[AmountType.Coin]!!.address!!,
+ binding.etReceiverAddress.text.toString()
+ )
+ }
+
+ private fun handleError(error: String?) {
+ Toast.makeText(this, error, Toast.LENGTH_LONG).show()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ scope.cancel()
+ }
+}
\ No newline at end of file
diff --git a/blockchain-demo/src/main/res/drawable-v24/ic_launcher_foreground.xml b/blockchain-demo/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000000..1f6bb29060
--- /dev/null
+++ b/blockchain-demo/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/blockchain-demo/src/main/res/drawable/ic_launcher_background.xml b/blockchain-demo/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000000..0d025f9bf6
--- /dev/null
+++ b/blockchain-demo/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/blockchain-demo/src/main/res/layout/activity_blockchain_demo.xml b/blockchain-demo/src/main/res/layout/activity_blockchain_demo.xml
new file mode 100644
index 0000000000..faa8ad1d9e
--- /dev/null
+++ b/blockchain-demo/src/main/res/layout/activity_blockchain_demo.xml
@@ -0,0 +1,96 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/blockchain-demo/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/blockchain-demo/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000000..eca70cfe52
--- /dev/null
+++ b/blockchain-demo/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/blockchain-demo/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/blockchain-demo/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000000..eca70cfe52
--- /dev/null
+++ b/blockchain-demo/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/blockchain-demo/src/main/res/mipmap-hdpi/ic_launcher.png b/blockchain-demo/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000000..898f3ed59a
Binary files /dev/null and b/blockchain-demo/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/blockchain-demo/src/main/res/mipmap-hdpi/ic_launcher_round.png b/blockchain-demo/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000000..dffca3601e
Binary files /dev/null and b/blockchain-demo/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/blockchain-demo/src/main/res/mipmap-mdpi/ic_launcher.png b/blockchain-demo/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000000..64ba76f75e
Binary files /dev/null and b/blockchain-demo/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/blockchain-demo/src/main/res/mipmap-mdpi/ic_launcher_round.png b/blockchain-demo/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000000..dae5e08234
Binary files /dev/null and b/blockchain-demo/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/blockchain-demo/src/main/res/mipmap-xhdpi/ic_launcher.png b/blockchain-demo/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000000..e5ed46597e
Binary files /dev/null and b/blockchain-demo/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/blockchain-demo/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/blockchain-demo/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000000..14ed0af350
Binary files /dev/null and b/blockchain-demo/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/blockchain-demo/src/main/res/mipmap-xxhdpi/ic_launcher.png b/blockchain-demo/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000000..b0907cac3b
Binary files /dev/null and b/blockchain-demo/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/blockchain-demo/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/blockchain-demo/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000000..d8ae031549
Binary files /dev/null and b/blockchain-demo/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/blockchain-demo/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/blockchain-demo/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000000..2c18de9e66
Binary files /dev/null and b/blockchain-demo/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/blockchain-demo/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/blockchain-demo/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000000..beed3cdd2c
Binary files /dev/null and b/blockchain-demo/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/blockchain-demo/src/main/res/values/colors.xml b/blockchain-demo/src/main/res/values/colors.xml
new file mode 100644
index 0000000000..1f9a3ff55b
--- /dev/null
+++ b/blockchain-demo/src/main/res/values/colors.xml
@@ -0,0 +1,7 @@
+
+
+ #527Aff
+ #027AFF
+ #027AFF
+ #4f98c0
+
diff --git a/blockchain-demo/src/main/res/values/strings.xml b/blockchain-demo/src/main/res/values/strings.xml
new file mode 100644
index 0000000000..556392ebfb
--- /dev/null
+++ b/blockchain-demo/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ Blockchain Demo
+
diff --git a/blockchain-demo/src/main/res/values/styles.xml b/blockchain-demo/src/main/res/values/styles.xml
new file mode 100644
index 0000000000..5885930df6
--- /dev/null
+++ b/blockchain-demo/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
diff --git a/blockchain-demo/src/main/res/xml/nfc_tech_filter.xml b/blockchain-demo/src/main/res/xml/nfc_tech_filter.xml
new file mode 100644
index 0000000000..1773c9e9b4
--- /dev/null
+++ b/blockchain-demo/src/main/res/xml/nfc_tech_filter.xml
@@ -0,0 +1,8 @@
+
+
+
+ android.nfc.tech.IsoDep
+ android.nfc.tech.Ndef
+ android.nfc.tech.NfcV
+
+
\ No newline at end of file
diff --git a/blockchain-demo/src/test/java/com/tangem/blockchain_demo/ExampleUnitTest.kt b/blockchain-demo/src/test/java/com/tangem/blockchain_demo/ExampleUnitTest.kt
new file mode 100644
index 0000000000..76ebdca6b1
--- /dev/null
+++ b/blockchain-demo/src/test/java/com/tangem/blockchain_demo/ExampleUnitTest.kt
@@ -0,0 +1,16 @@
+package com.tangem.blockchain_demo
+
+import org.junit.Assert.assertEquals
+import org.junit.Test
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+class ExampleUnitTest {
+ @Test
+ fun addition_isCorrect() {
+ assertEquals(4, 2 + 2)
+ }
+}
\ No newline at end of file
diff --git a/blockchain/build.gradle b/blockchain/build.gradle
index ad3b46b318..1c30f07eaa 100644
--- a/blockchain/build.gradle
+++ b/blockchain/build.gradle
@@ -2,6 +2,7 @@ apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
+
android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
@@ -24,6 +25,13 @@ android {
}
}
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = '1.8'
+ }
}
dependencies {
@@ -33,11 +41,12 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$versions.kotlin"
implementation 'androidx.appcompat:appcompat:1.1.0'
- implementation 'androidx.core:core-ktx:1.1.0'
+ implementation 'androidx.core:core-ktx:1.2.0'
implementation 'com.squareup.retrofit2:retrofit:2.7.0'
implementation 'com.squareup.retrofit2:converter-moshi:2.6.0'
implementation 'com.squareup.moshi:moshi:1.9.2'
+ implementation "com.squareup.moshi:moshi-kotlin:1.9.2"
kapt("com.squareup.moshi:moshi-kotlin-codegen:1.9.2")
implementation 'com.squareup.okhttp3:logging-interceptor:4.2.2'
@@ -45,21 +54,21 @@ dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.3.3"
implementation 'org.bitcoinj:bitcoinj-core:0.15.2'
- implementation 'com.github.stellar:java-stellar-sdk:0.13.0'
+ implementation 'com.github.stellar:java-stellar-sdk:0.14.0'
implementation "com.madgag.spongycastle:core:1.58.0.0"
implementation "com.madgag.spongycastle:prov:1.58.0.0"
- ext.kethereum_version = '0.79.5'
- implementation "com.github.walleth.kethereum:functions:$kethereum_version"
+ ext.kethereum_version = '0.81.2'
+ implementation "com.github.walleth.kethereum:extensions_kotlin:$kethereum_version"
+ implementation "com.github.walleth.kethereum:extensions_transactions:$kethereum_version"
+ implementation "com.github.walleth.kethereum:erc55:$kethereum_version"
implementation "com.github.walleth.kethereum:keccak_shortcut:$kethereum_version"
implementation "com.github.walleth.kethereum:wallet:$kethereum_version"
implementation "com.github.walleth.kethereum:crypto_impl_spongycastle:$kethereum_version"
implementation "com.github.walleth.kethereum:crypto:$kethereum_version"
implementation "com.github.walleth.kethereum:crypto_api:$kethereum_version"
implementation "com.github.walleth.kethereum:model:$kethereum_version"
- implementation 'com.github.komputing.khex:core:1.0.0-RC6'
- implementation 'com.github.komputing.khex:extensions:1.0.0-RC6'
implementation 'co.nstant.in:cbor:0.8'
diff --git a/blockchain/src/main/java/com/tangem/blockchain/bitcoin/BitcoinTransactionBuilder.kt b/blockchain/src/main/java/com/tangem/blockchain/bitcoin/BitcoinTransactionBuilder.kt
index d066fa259e..664c45fa0d 100644
--- a/blockchain/src/main/java/com/tangem/blockchain/bitcoin/BitcoinTransactionBuilder.kt
+++ b/blockchain/src/main/java/com/tangem/blockchain/bitcoin/BitcoinTransactionBuilder.kt
@@ -2,7 +2,6 @@ package com.tangem.blockchain.bitcoin
import com.tangem.blockchain.common.TransactionData
import com.tangem.blockchain.common.extensions.Result
-import com.tangem.blockchain.common.extensions.toCanonicalised
import org.bitcoinj.core.*
import org.bitcoinj.crypto.TransactionSignature
import org.bitcoinj.script.Script
diff --git a/blockchain/src/main/java/com/tangem/blockchain/bitcoin/BitcoinWalletManager.kt b/blockchain/src/main/java/com/tangem/blockchain/bitcoin/BitcoinWalletManager.kt
index a1779ce5ae..58ae155e27 100644
--- a/blockchain/src/main/java/com/tangem/blockchain/bitcoin/BitcoinWalletManager.kt
+++ b/blockchain/src/main/java/com/tangem/blockchain/bitcoin/BitcoinWalletManager.kt
@@ -15,7 +15,7 @@ import java.math.BigDecimal
class BitcoinWalletManager(
private val cardId: String,
private val walletPublicKey: ByteArray,
- walletConfig: WalletConfig,
+ override var wallet: CurrencyWallet,
isTestNet: Boolean = false
) : WalletManager,
TransactionSender,
@@ -23,11 +23,13 @@ class BitcoinWalletManager(
override val blockchain = if (isTestNet) Blockchain.BitcoinTestnet else Blockchain.Bitcoin
private val address = blockchain.makeAddress(walletPublicKey)
- private val currencyWallet = CurrencyWallet(walletConfig, address)
- override var wallet: Wallet = currencyWallet
private val transactionBuilder = BitcoinTransactionBuilder(isTestNet)
private val networkManager = BitcoinNetworkManager(isTestNet)
+ init {
+ wallet.balances[AmountType.Coin] = Amount(null, blockchain)
+ }
+
override suspend fun update() {
val response = networkManager.getInfo(address)
when (response) {
@@ -38,23 +40,24 @@ class BitcoinWalletManager(
private fun updateWallet(response: BitcoinAddressResponse) {
Log.d(this::class.java.simpleName, "Balance is ${response.balance}")
- currencyWallet.balances[AmountType.Coin]?.value = response.balance
+ wallet.balances[AmountType.Coin]?.value = response.balance
transactionBuilder.unspentOutputs = response.unspentTransactions
if (response.hasUnconfirmed) {
- if (currencyWallet.pendingTransactions.isEmpty()) {
- currencyWallet.pendingTransactions.add(TransactionData(
+ if (wallet.pendingTransactions.isEmpty()) {
+ wallet.pendingTransactions.add(TransactionData(
Amount(blockchain.currency, decimals = blockchain.decimals),
null,
"unknown",
- currencyWallet.address))
+ wallet.address))
}
} else {
- currencyWallet.pendingTransactions.clear()
+ wallet.pendingTransactions.clear()
}
}
private fun updateError(error: Throwable?) {
Log.e(this::class.java.simpleName, error?.message ?: "")
+ if (error != null) throw error
}
override suspend fun send(transactionData: TransactionData, signer: TransactionSigner): SimpleResult {
@@ -73,7 +76,7 @@ class BitcoinWalletManager(
}
}
- override suspend fun getFee(amount: Amount, source: String, destination: String): Result> {
+ override suspend fun getFee(amount: Amount, destination: String): Result> {
when (val result = networkManager.getFee()) {
is Result.Failure -> return result
is Result.Success -> {
diff --git a/blockchain/src/main/java/com/tangem/blockchain/cardano/CardanoWalletManager.kt b/blockchain/src/main/java/com/tangem/blockchain/cardano/CardanoWalletManager.kt
index e5c7b71a70..edf2acefbb 100644
--- a/blockchain/src/main/java/com/tangem/blockchain/cardano/CardanoWalletManager.kt
+++ b/blockchain/src/main/java/com/tangem/blockchain/cardano/CardanoWalletManager.kt
@@ -1,6 +1,5 @@
package com.tangem.blockchain.cardano
-import android.util.Base64
import android.util.Log
import com.tangem.blockchain.cardano.network.CardanoAddressResponse
import com.tangem.blockchain.cardano.network.CardanoNetworkManager
@@ -10,20 +9,17 @@ import com.tangem.blockchain.common.extensions.SimpleResult
import com.tangem.blockchain.common.extensions.encodeBase64NoWrap
import com.tangem.blockchain.wallets.CurrencyWallet
import com.tangem.tasks.TaskEvent
-import java.math.BigDecimal
class CardanoWalletManager(
private val cardId: String,
private val walletPublicKey: ByteArray,
- walletConfig: WalletConfig
+ override var wallet: CurrencyWallet
) : WalletManager,
TransactionSender,
FeeProvider {
override val blockchain = Blockchain.Cardano
private val address = blockchain.makeAddress(walletPublicKey)
- private val currencyWallet = CurrencyWallet(walletConfig, address)
- override var wallet: Wallet = currencyWallet
private val transactionBuilder = CardanoTransactionBuilder()
private val networkManager = CardanoNetworkManager()
@@ -37,13 +33,14 @@ class CardanoWalletManager(
private fun updateWallet(response: CardanoAddressResponse) {
Log.d(this::class.java.simpleName, "Balance is ${response.balance.toString()}")
- currencyWallet.balances[AmountType.Coin]?.value =
+ wallet.balances[AmountType.Coin]?.value =
response.balance.toBigDecimal().movePointLeft(blockchain.decimals.toInt())
transactionBuilder.unspentOutputs = response.unspentOutputs
}
private fun updateError(error: Throwable?) {
Log.e(this::class.java.simpleName, error?.message ?: "")
+ if (error != null) throw error
}
override suspend fun send(transactionData: TransactionData, signer: TransactionSigner): SimpleResult {
@@ -58,13 +55,13 @@ class CardanoWalletManager(
}
}
- override suspend fun getFee(amount: Amount, source: String, destination: String): Result> {
+ override suspend fun getFee(amount: Amount, destination: String): Result> {
val a = 0.155381
val b = 0.000043946
val size = transactionBuilder.getEstimateSize(
- TransactionData(amount, null, source, destination), walletPublicKey
+ TransactionData(amount, null, address, destination), walletPublicKey
)
val fee = (a + b * size).toBigDecimal()
- return Result.Success(listOf(Amount(blockchain.currency, fee, source, blockchain.decimals)))
+ return Result.Success(listOf(Amount(blockchain.currency, fee, address, blockchain.decimals)))
}
}
\ No newline at end of file
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 ac90c477bd..37333c2768 100644
--- a/blockchain/src/main/java/com/tangem/blockchain/common/Blockchain.kt
+++ b/blockchain/src/main/java/com/tangem/blockchain/common/Blockchain.kt
@@ -2,13 +2,15 @@ package com.tangem.blockchain.common
import com.tangem.blockchain.bitcoin.BitcoinAddressFactory
import com.tangem.blockchain.bitcoin.BitcoinAddressValidator
-import com.tangem.blockchain.ethereum.EthereumAddressFactory
-import com.tangem.blockchain.ethereum.EthereumAddressValidator
import com.tangem.blockchain.cardano.CardanoAddressFactory
import com.tangem.blockchain.cardano.CardanoAddressValidator
+import com.tangem.blockchain.ethereum.EthereumAddressFactory
+import com.tangem.blockchain.ethereum.EthereumAddressValidator
+
import com.tangem.blockchain.stellar.StellarAddressFactory
import com.tangem.blockchain.xrp.XrpAddressFactory
import com.tangem.blockchain.xrp.XrpAddressValidator
+
import java.math.BigDecimal
enum class Blockchain(
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 68f9855e05..6cca63b075 100644
--- a/blockchain/src/main/java/com/tangem/blockchain/common/Wallet.kt
+++ b/blockchain/src/main/java/com/tangem/blockchain/common/Wallet.kt
@@ -30,6 +30,9 @@ data class Amount(
address: String? = null,
type: AmountType = AmountType.Coin
) : this(blockchain.currency, value, address, blockchain.decimals, type)
+
+ constructor(token: Token, value: BigDecimal? = null) :
+ this(token.symbol, value, token.contractAddress, token.decimals, AmountType.Token)
}
data class TransactionData(
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 967385e85b..c39d9b6c0e 100644
--- a/blockchain/src/main/java/com/tangem/blockchain/common/WalletManager.kt
+++ b/blockchain/src/main/java/com/tangem/blockchain/common/WalletManager.kt
@@ -2,12 +2,12 @@ package com.tangem.blockchain.common
import com.tangem.blockchain.common.extensions.Result
import com.tangem.blockchain.common.extensions.SimpleResult
+import com.tangem.blockchain.wallets.CurrencyWallet
import com.tangem.commands.SignResponse
import com.tangem.tasks.TaskEvent
-import kotlinx.coroutines.flow.Flow
interface WalletManager {
- var wallet: Wallet
+ var wallet: CurrencyWallet
val blockchain: Blockchain
suspend fun update()
@@ -22,5 +22,5 @@ interface TransactionSigner {
}
interface FeeProvider {
- suspend fun getFee(amount: Amount, source: String, destination: String): Result>
+ suspend fun getFee(amount: Amount, destination: String): Result>
}
\ No newline at end of file
diff --git a/blockchain/src/main/java/com/tangem/blockchain/common/WalletManagerFactory.kt b/blockchain/src/main/java/com/tangem/blockchain/common/WalletManagerFactory.kt
index 90d8b57cf9..6c9b4105f8 100644
--- a/blockchain/src/main/java/com/tangem/blockchain/common/WalletManagerFactory.kt
+++ b/blockchain/src/main/java/com/tangem/blockchain/common/WalletManagerFactory.kt
@@ -1,10 +1,12 @@
package com.tangem.blockchain.common
import com.tangem.blockchain.bitcoin.BitcoinWalletManager
+import com.tangem.blockchain.cardano.CardanoWalletManager
import com.tangem.blockchain.ethereum.Chain
import com.tangem.blockchain.ethereum.EthereumWalletManager
-import com.tangem.blockchain.cardano.CardanoWalletManager
+
import com.tangem.blockchain.stellar.StellarWalletManager
+import com.tangem.blockchain.wallets.CurrencyWallet
import com.tangem.blockchain.xrp.XrpWalletManager
import com.tangem.commands.Card
@@ -13,53 +15,56 @@ object WalletManagerFactory {
fun makeWalletManager(card: Card): WalletManager? {
val walletPublicKey: ByteArray = card.walletPublicKey ?: return null
val blockchainName: String = card.cardData?.blockchainName ?: return null
+ val blockchain = Blockchain.fromId(blockchainName)
- when {
- blockchainName == Blockchain.Bitcoin.id -> {
+ val token = getToken(card)
+ val wallet = CurrencyWallet.newInstance(blockchain, blockchain.makeAddress(walletPublicKey), token)
+
+
+ when (blockchain) {
+ Blockchain.Bitcoin -> {
return BitcoinWalletManager(
cardId = card.cardId,
walletPublicKey = walletPublicKey,
- walletConfig = WalletConfig(true, true)
+ wallet = wallet
)
}
- blockchainName == Blockchain.BitcoinTestnet.id -> {
+ Blockchain.BitcoinTestnet -> {
return BitcoinWalletManager(
cardId = card.cardId,
walletPublicKey = walletPublicKey,
- walletConfig = WalletConfig(true, true),
+ wallet = wallet,
isTestNet = true
)
}
- blockchainName == Blockchain.Ethereum.id -> {
+ Blockchain.Ethereum -> {
val chain = Chain.Mainnet
return EthereumWalletManager(
cardId = card.cardId,
walletPublicKey = walletPublicKey,
- walletConfig = WalletConfig(true, true),
+ wallet = wallet,
chain = chain
)
}
- blockchainName == Blockchain.Stellar.id -> {
- val token = getToken(card)
+ Blockchain.Stellar -> {
return StellarWalletManager(
cardId = card.cardId,
walletPublicKey = walletPublicKey,
- walletConfig = WalletConfig(true, token == null),
- token = token
+ wallet = wallet
)
}
- blockchainName == Blockchain.Cardano.id -> {
+ Blockchain.Cardano -> {
return CardanoWalletManager(
cardId = card.cardId,
walletPublicKey = walletPublicKey,
- walletConfig = WalletConfig(false, true)
+ wallet = wallet
)
}
- blockchainName == Blockchain.XRP.id -> {
+ Blockchain.XRP -> {
return XrpWalletManager(
cardId = card.cardId,
walletPublicKey = walletPublicKey,
- walletConfig = WalletConfig(true, true)
+ wallet = wallet
)
}
else -> return null
diff --git a/blockchain/src/main/java/com/tangem/blockchain/common/extensions/Coroutines.kt b/blockchain/src/main/java/com/tangem/blockchain/common/extensions/Coroutines.kt
index 03d2b2f009..cdf9edd92e 100644
--- a/blockchain/src/main/java/com/tangem/blockchain/common/extensions/Coroutines.kt
+++ b/blockchain/src/main/java/com/tangem/blockchain/common/extensions/Coroutines.kt
@@ -4,12 +4,11 @@ import com.tangem.CardManager
import com.tangem.blockchain.common.TransactionSigner
import com.tangem.commands.SignResponse
import com.tangem.tasks.TaskEvent
-import kotlinx.coroutines.*
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.flow
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.suspendCancellableCoroutine
import java.io.IOException
import kotlin.coroutines.resume
-import kotlin.coroutines.suspendCoroutine
+
suspend fun retryIO(
times: Int = 3,
@@ -56,11 +55,11 @@ sealed class SimpleResult {
}
class Signer(private val cardManager: CardManager) : TransactionSigner {
- override suspend fun sign(hashes: Array, cardId: String): TaskEvent = coroutineScope {
- async {
- suspendCancellableCoroutine> { continuation ->
- cardManager.sign(hashes, cardId) { if (continuation.isActive) continuation.resume(it) }
+ override suspend fun sign(hashes: Array, cardId: String): TaskEvent =
+ suspendCancellableCoroutine { continuation ->
+ cardManager.sign(hashes, cardId) { result ->
+ if (continuation.isActive) continuation.resume(result)
+ }
}
- }.await()
- }
}
+
diff --git a/blockchain/src/main/java/com/tangem/blockchain/common/network/RetrofitBuilder.kt b/blockchain/src/main/java/com/tangem/blockchain/common/network/RetrofitBuilder.kt
index 9834fc8cb9..afcffa0bfb 100644
--- a/blockchain/src/main/java/com/tangem/blockchain/common/network/RetrofitBuilder.kt
+++ b/blockchain/src/main/java/com/tangem/blockchain/common/network/RetrofitBuilder.kt
@@ -1,5 +1,7 @@
package com.tangem.blockchain.common.network
+import com.squareup.moshi.Moshi
+import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import com.tangem.blockchain.BuildConfig
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
@@ -18,11 +20,16 @@ private fun createHttpLoggingInterceptor(): HttpLoggingInterceptor {
return logging
}
+private val moshi: Moshi by lazy {
+ Moshi.Builder()
+ .add(KotlinJsonAdapterFactory())
+ .build()
+}
fun createRetrofitInstance(baseUrl: String): Retrofit =
Retrofit.Builder()
.baseUrl(baseUrl)
- .addConverterFactory(MoshiConverterFactory.create())
+ .addConverterFactory(MoshiConverterFactory.create(moshi))
.client(okHttpClient)
.build()
diff --git a/blockchain/src/main/java/com/tangem/blockchain/ethereum/EthereumAddress.kt b/blockchain/src/main/java/com/tangem/blockchain/ethereum/EthereumAddress.kt
index 200a1ca465..a301ee7e1c 100644
--- a/blockchain/src/main/java/com/tangem/blockchain/ethereum/EthereumAddress.kt
+++ b/blockchain/src/main/java/com/tangem/blockchain/ethereum/EthereumAddress.kt
@@ -1,7 +1,7 @@
package com.tangem.blockchain.ethereum
import org.kethereum.crypto.toAddress
-import org.kethereum.functions.isValid
+import org.kethereum.erc55.isValid
import org.kethereum.model.Address
import org.kethereum.model.PublicKey
diff --git a/blockchain/src/main/java/com/tangem/blockchain/ethereum/EthereumWalletManager.kt b/blockchain/src/main/java/com/tangem/blockchain/ethereum/EthereumWalletManager.kt
index e7bad943ba..d7c26e526e 100644
--- a/blockchain/src/main/java/com/tangem/blockchain/ethereum/EthereumWalletManager.kt
+++ b/blockchain/src/main/java/com/tangem/blockchain/ethereum/EthereumWalletManager.kt
@@ -1,6 +1,8 @@
package com.tangem.blockchain.ethereum
+import android.util.Log
import com.tangem.blockchain.common.*
+import com.tangem.blockchain.common.Token
import com.tangem.blockchain.common.extensions.Result
import com.tangem.blockchain.common.extensions.SimpleResult
import com.tangem.blockchain.ethereum.network.EthereumNetworkManager
@@ -12,7 +14,7 @@ import org.kethereum.DEFAULT_GAS_LIMIT
import org.kethereum.crypto.api.ec.ECDSASignature
import org.kethereum.crypto.determineRecId
import org.kethereum.crypto.impl.ec.canonicalise
-import org.kethereum.functions.encodeRLP
+import org.kethereum.extensions.transactions.encodeRLP
import org.kethereum.keccakshortcut.keccak
import org.kethereum.model.*
import java.math.BigDecimal
@@ -22,22 +24,32 @@ class EthereumWalletManager(
private val cardId: String,
private val walletPublicKey: ByteArray,
chain: Chain,
- walletConfig: WalletConfig
+ token: Token? = null,
+ override var wallet: CurrencyWallet
) : WalletManager,
TransactionSender,
FeeProvider {
override val blockchain: Blockchain = Blockchain.Ethereum
private val address = blockchain.makeAddress(walletPublicKey)
- private val currencyWallet = CurrencyWallet(walletConfig, address)
- override var wallet: Wallet = currencyWallet
private val builder = EthereumTransactionBuilder(chain)
private val networkManager = EthereumNetworkManager()
private var pendingTxCount = -1L
private var txCount = -1L
+ init {
+ if (token != null) wallet.balances[AmountType.Token] =
+ Amount(
+ token.symbol,
+ null,
+ token.contractAddress,
+ token.decimals,
+ AmountType.Token)
+ wallet.balances[AmountType.Coin] = Amount(null, blockchain)
+ }
+
override suspend fun update() {
- val result = networkManager.getInfo(address, currencyWallet.balances[AmountType.Token]?.address)
+ val result = networkManager.getInfo(address, wallet.balances[AmountType.Token]?.address)
when (result) {
is Result.Failure -> updateError(result.error)
is Result.Success -> updateWallet(result.data)
@@ -45,23 +57,24 @@ class EthereumWalletManager(
}
private fun updateWallet(data: EthereumResponse) {
- currencyWallet.balances[AmountType.Coin]?.value = data.balance
- currencyWallet.balances[AmountType.Token]?.value = data.tokenBalance
+ wallet.balances[AmountType.Coin]?.value = data.balance
+ wallet.balances[AmountType.Token]?.value = data.tokenBalance
txCount = data.txCount
pendingTxCount = data.pendingTxCount
if (txCount == pendingTxCount) {
- currencyWallet.pendingTransactions.forEach { it.status = TransactionStatus.Confirmed }
- } else if (currencyWallet.pendingTransactions.isEmpty()) {
- currencyWallet.pendingTransactions.add(TransactionData(
+ wallet.pendingTransactions.forEach { it.status = TransactionStatus.Confirmed }
+ } else if (wallet.pendingTransactions.isEmpty()) {
+ wallet.pendingTransactions.add(TransactionData(
Amount(blockchain.currency, decimals = blockchain.decimals),
null,
"unknown",
- currencyWallet.address))
+ wallet.address))
}
}
private fun updateError(error: Throwable?) {
-
+ Log.e(this::class.java.simpleName, error?.message ?: "")
+ if (error != null) throw error
}
override suspend fun send(transactionData: TransactionData, signer: TransactionSigner): SimpleResult {
@@ -76,7 +89,7 @@ class EthereumWalletManager(
}
}
- override suspend fun getFee(amount: Amount, source: String, destination: String): Result> {
+ override suspend fun getFee(amount: Amount, destination: String): Result> {
val result = networkManager.getFee(getGasLimit(amount).value)
when (result) {
is Result.Success -> {
diff --git a/blockchain/src/main/java/com/tangem/blockchain/ethereum/network/EthereumNetworkManager.kt b/blockchain/src/main/java/com/tangem/blockchain/ethereum/network/EthereumNetworkManager.kt
index c141f51aef..b7318ba032 100644
--- a/blockchain/src/main/java/com/tangem/blockchain/ethereum/network/EthereumNetworkManager.kt
+++ b/blockchain/src/main/java/com/tangem/blockchain/ethereum/network/EthereumNetworkManager.kt
@@ -12,7 +12,6 @@ import kotlinx.coroutines.coroutineScope
import org.kethereum.ETH_IN_WEI
import java.math.BigDecimal
import java.math.BigInteger
-import java.math.RoundingMode
class EthereumNetworkManager {
diff --git a/blockchain/src/main/java/com/tangem/blockchain/stellar/StellarNetworkManager.kt b/blockchain/src/main/java/com/tangem/blockchain/stellar/StellarNetworkManager.kt
index 87102f42e6..85e5cfbd04 100644
--- a/blockchain/src/main/java/com/tangem/blockchain/stellar/StellarNetworkManager.kt
+++ b/blockchain/src/main/java/com/tangem/blockchain/stellar/StellarNetworkManager.kt
@@ -54,7 +54,7 @@ class StellarNetworkManager(isTestNet: Boolean) {
coroutineScope {
val accountResponseDefered = async(Dispatchers.IO) { stellarServer.accounts().account(accountId) }
val ledgerResponseDeferred = async(Dispatchers.IO) {
- val latestLedger: Int = stellarServer.root().coreLatestLedger
+ val latestLedger: Int = stellarServer.root().historyLatestLedger
stellarServer.ledgers().ledger(latestLedger.toLong())
}
@@ -67,7 +67,7 @@ class StellarNetworkManager(isTestNet: Boolean) {
null
} else {
accountResponse.balances
- .find { it.assetType != "native" && it.assetCode == assetCode }
+ .find { it.assetType != "native" && it.assetIssuer == assetCode }
?.balance?.toBigDecimal()
?: return@coroutineScope Result.Failure(Exception("Stellar Balance not found"))
}
diff --git a/blockchain/src/main/java/com/tangem/blockchain/stellar/StellarWalletManager.kt b/blockchain/src/main/java/com/tangem/blockchain/stellar/StellarWalletManager.kt
index a8b02ccf97..e65278fa35 100644
--- a/blockchain/src/main/java/com/tangem/blockchain/stellar/StellarWalletManager.kt
+++ b/blockchain/src/main/java/com/tangem/blockchain/stellar/StellarWalletManager.kt
@@ -1,5 +1,6 @@
package com.tangem.blockchain.stellar
+import android.util.Log
import com.tangem.blockchain.common.*
import com.tangem.blockchain.common.extensions.Result
import com.tangem.blockchain.common.extensions.SimpleResult
@@ -11,8 +12,7 @@ import java.util.*
class StellarWalletManager(
private val cardId: String,
walletPublicKey: ByteArray,
- walletConfig: WalletConfig,
- token: Token? = null,
+ override var wallet: CurrencyWallet,
isTestNet: Boolean = false
) : WalletManager,
TransactionSender,
@@ -20,26 +20,14 @@ class StellarWalletManager(
override val blockchain: Blockchain = Blockchain.Stellar
private val address = blockchain.makeAddress(walletPublicKey)
- private val currencyWallet = CurrencyWallet(walletConfig, address)
- override var wallet: Wallet = currencyWallet
private val networkManager = StellarNetworkManager(isTestNet)
private val builder = StellarTransactionBuilder(networkManager, walletPublicKey)
private var baseFee = BASE_FEE
private var baseReserve = BASE_RESERVE
private var sequence = 0L
- init {
- if (token != null) currencyWallet.balances[AmountType.Token] =
- Amount(
- token.symbol,
- null,
- token.contractAddress,
- token.decimals,
- AmountType.Token)
- }
-
override suspend fun update() {
- val result = networkManager.getInfo(address, currencyWallet.balances[AmountType.Token]?.address)
+ val result = networkManager.getInfo(address, wallet.balances[AmountType.Token]?.address)
when (result) {
is Result.Failure -> updateError(result.error)
is Result.Success -> updateWallet(result.data)
@@ -47,15 +35,15 @@ class StellarWalletManager(
}
private fun updateWallet(data: StellarResponse) {
- currencyWallet.balances[AmountType.Coin]?.value = data.balance
- currencyWallet.balances[AmountType.Token]?.value = data.assetBalance
- currencyWallet.balances[AmountType.Reserve]?.value = data.baseReserve
+ wallet.balances[AmountType.Coin]?.value = data.balance
+ wallet.balances[AmountType.Token]?.value = data.assetBalance
+ wallet.balances[AmountType.Reserve]?.value = data.baseReserve
sequence = data.sequence
baseFee = data.baseFee
baseReserve = data.baseReserve
val currentTime = Calendar.getInstance().timeInMillis
- currencyWallet.pendingTransactions.forEach { transaction ->
+ wallet.pendingTransactions.forEach { transaction ->
if (transaction.date?.timeInMillis ?: 0 - currentTime > 10) {
transaction.status = TransactionStatus.Confirmed
}
@@ -63,7 +51,8 @@ class StellarWalletManager(
}
private fun updateError(error: Throwable?) {
-
+ Log.e(this::class.java.simpleName, error?.message ?: "")
+ if (error != null) throw error
}
override suspend fun send(transactionData: TransactionData, signer: TransactionSigner): SimpleResult {
@@ -77,7 +66,7 @@ class StellarWalletManager(
}
}
- override suspend fun getFee(amount: Amount, source: String, destination: String): Result> {
+ override suspend fun getFee(amount: Amount, destination: String): Result> {
return Result.Success(listOf(
Amount(baseFee, blockchain)
))
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 218964d51c..e308ac49e0 100644
--- a/blockchain/src/main/java/com/tangem/blockchain/wallets/CurrencyWallet.kt
+++ b/blockchain/src/main/java/com/tangem/blockchain/wallets/CurrencyWallet.kt
@@ -4,17 +4,63 @@ import com.tangem.blockchain.common.*
import java.util.*
class CurrencyWallet(
- override val config: WalletConfig,
- override val address: String,
- override val exploreUrl: String? = null,
- override val shareUrl: String? = null,
- val pendingTransactions: MutableList = mutableListOf(),
- val balances: MutableMap = mutableMapOf(),
- val isTestnet: Boolean = false
+ val blockchain: Blockchain,
+ address: String,
+ override val config: WalletConfig
) : Wallet, TransactionValidator {
+ override val exploreUrl: String? = null
+ override val shareUrl: String? = null
+ override val address: String
+ get() = balances[AmountType.Coin]!!.address!!
+
+ val pendingTransactions: MutableList = mutableListOf()
+ val balances: MutableMap = mutableMapOf()
+
+ init {
+ addAmount(Amount(null, blockchain, address))
+ }
override fun validateTransaction(amount: Amount, fee: Amount?): EnumSet {
TODO("not implemented")
}
+
+ fun addAmount(amount: Amount) {
+ balances[amount.type] = amount
+ }
+
+ fun addPendingTransaction(transaction: TransactionData) {
+ pendingTransactions.add(transaction.copy(date = Calendar.getInstance()))
+ }
+
+ companion object {
+ fun newInstance(blockchain: Blockchain, address: String, token: Token?): CurrencyWallet {
+
+ return when (blockchain) {
+ Blockchain.Bitcoin, Blockchain.XRP -> {
+ val config = WalletConfig(true, true)
+ CurrencyWallet(blockchain, address, config)
+ }
+ Blockchain.Cardano -> {
+ val config = WalletConfig(false, true)
+ CurrencyWallet(blockchain, address, config)
+ }
+ Blockchain.Ethereum -> {
+ val config = WalletConfig(true, token == null)
+ val wallet = CurrencyWallet(blockchain, address, config)
+ if (token != null) wallet.addAmount(Amount(token))
+ wallet
+ }
+ Blockchain.Stellar -> {
+ val config = WalletConfig(false, token == null)
+ val wallet = CurrencyWallet(blockchain, address, config)
+ if (token != null) wallet.addAmount(Amount(token))
+ wallet.addAmount(Amount(null, blockchain, address, AmountType.Reserve))
+ wallet
+ }
+ else -> throw Exception("Unsupported blockchain")
+ }
+
+ }
+ }
}
\ No newline at end of file
diff --git a/blockchain/src/main/java/com/tangem/blockchain/xrp/XrpWalletManager.kt b/blockchain/src/main/java/com/tangem/blockchain/xrp/XrpWalletManager.kt
index f2ea7fa7d3..bba2e26427 100644
--- a/blockchain/src/main/java/com/tangem/blockchain/xrp/XrpWalletManager.kt
+++ b/blockchain/src/main/java/com/tangem/blockchain/xrp/XrpWalletManager.kt
@@ -12,18 +12,21 @@ import com.tangem.tasks.TaskEvent
class XrpWalletManager(
private val cardId: String,
private val walletPublicKey: ByteArray,
- walletConfig: WalletConfig
+ override var wallet: CurrencyWallet
) : WalletManager,
TransactionSender,
FeeProvider {
override val blockchain = Blockchain.XRP
private val address = blockchain.makeAddress(walletPublicKey)
- private val currencyWallet = CurrencyWallet(walletConfig, address)
- override var wallet: Wallet = currencyWallet
private val transactionBuilder = XrpTransactionBuilder(walletPublicKey)
private val networkManager = XrpNetworkManager()
+ init {
+ wallet.balances[AmountType.Coin] = Amount(null, blockchain)
+ wallet.balances[AmountType.Reserve] = Amount(null, blockchain, type = AmountType.Reserve)
+ }
+
override suspend fun update() {
val result = networkManager.getInfo(address)
when (result) {
@@ -34,30 +37,31 @@ class XrpWalletManager(
private fun updateWallet(response: XrpInfoResponse) {
Log.d(this::class.java.simpleName, "Balance is ${response.balance}")
- currencyWallet.balances[AmountType.Reserve]?.value = response.reserveBase
+ wallet.balances[AmountType.Reserve]?.value = response.reserveBase
if (!response.accountFound) {
updateError(Exception("Account not found")) //TODO rework, add reserve
return
}
- currencyWallet.balances[AmountType.Coin]?.value = response.balance - response.reserveBase
+ wallet.balances[AmountType.Coin]?.value = response.balance - response.reserveBase
transactionBuilder.sequence = response.sequence
if (response.hasUnconfirmed) {
- if (currencyWallet.pendingTransactions.isEmpty()) {
- currencyWallet.pendingTransactions.add(TransactionData(
+ if (wallet.pendingTransactions.isEmpty()) {
+ wallet.pendingTransactions.add(TransactionData(
Amount(blockchain.currency, decimals = blockchain.decimals),
null,
"unknown",
- currencyWallet.address))
+ wallet.address))
}
} else {
- currencyWallet.pendingTransactions.clear()
+ wallet.pendingTransactions.clear()
}
}
private fun updateError(error: Throwable?) {
Log.e(this::class.java.simpleName, error?.message ?: "")
+ if (error != null) throw error
}
override suspend fun send(transactionData: TransactionData, signer: TransactionSigner): SimpleResult {
@@ -72,7 +76,7 @@ class XrpWalletManager(
}
}
- override suspend fun getFee(amount: Amount, source: String, destination: String): Result> {
+ override suspend fun getFee(amount: Amount, destination: String): Result> {
val result = networkManager.getFee()
when (result) {
is Result.Failure -> return result
diff --git a/blockchain/src/main/java/com/tangem/blockchain/xrp/network/XrpNetworkManager.kt b/blockchain/src/main/java/com/tangem/blockchain/xrp/network/XrpNetworkManager.kt
index c7aa738a23..8066fe1bea 100644
--- a/blockchain/src/main/java/com/tangem/blockchain/xrp/network/XrpNetworkManager.kt
+++ b/blockchain/src/main/java/com/tangem/blockchain/xrp/network/XrpNetworkManager.kt
@@ -1,6 +1,5 @@
package com.tangem.blockchain.xrp.network
-import com.tangem.blockchain.bitcoin.network.BitcoinFee
import com.tangem.blockchain.common.extensions.Result
import com.tangem.blockchain.common.extensions.SimpleResult
import com.tangem.blockchain.common.network.API_RIPPLED
diff --git a/blockchain/src/main/java/com/tangem/blockchain/xrp/network/rippled/RippledProvider.kt b/blockchain/src/main/java/com/tangem/blockchain/xrp/network/rippled/RippledProvider.kt
index ee0c499ce0..73e67cd19c 100644
--- a/blockchain/src/main/java/com/tangem/blockchain/xrp/network/rippled/RippledProvider.kt
+++ b/blockchain/src/main/java/com/tangem/blockchain/xrp/network/rippled/RippledProvider.kt
@@ -8,7 +8,6 @@ import com.tangem.blockchain.xrp.network.XrpFeeResponse
import com.tangem.blockchain.xrp.network.XrpInfoResponse
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
-import java.math.BigDecimal
class RippledProvider(private val api: RippledApi) {
private val decimals = Blockchain.XRP.decimals.toInt()