diff --git a/app/build.gradle b/app/build.gradle index 2bf6a3d7..780590b0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -5,7 +5,7 @@ apply plugin: 'kotlin-android-extensions' android { compileSdkVersion 27 defaultConfig { - applicationId "io.horizontalsystems.ethereum.kit.android" + applicationId "io.horizontalsystems.ethereumkit" minSdkVersion 23 targetSdkVersion 27 versionCode 1 @@ -22,18 +22,26 @@ android { packagingOptions { exclude 'META-INF/rxjava.properties' } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } } dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation fileTree(include: ['*.jar'], dir: 'libs') + + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation 'com.android.support:appcompat-v7:27.1.1' implementation 'com.android.support.constraint:constraint-layout:1.1.3' implementation 'com.android.support:design:27.1.1' + implementation 'io.reactivex.rxjava2:rxjava:2.2.0' + implementation 'io.reactivex.rxjava2:rxandroid:2.0.2' + // ViewModel and LiveData - implementation "android.arch.lifecycle:extensions:1.1.1" + implementation 'android.arch.lifecycle:extensions:1.1.1' kapt "android.arch.lifecycle:compiler:1.1.1" testImplementation 'junit:junit:4.12' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a1fc3803..0d137944 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,12 +1,12 @@ - - \ No newline at end of file + diff --git a/app/src/main/java/io/horizontalsystems/ethereumkit/sample/App.kt b/app/src/main/java/io/horizontalsystems/ethereumkit/sample/App.kt index edfbd09b..55f37884 100644 --- a/app/src/main/java/io/horizontalsystems/ethereumkit/sample/App.kt +++ b/app/src/main/java/io/horizontalsystems/ethereumkit/sample/App.kt @@ -1,14 +1,17 @@ package io.horizontalsystems.ethereumkit.sample import android.app.Application -import io.horizontalsystems.ethereumkit.EthereumKit class App : Application() { override fun onCreate() { super.onCreate() + instance = this + } - EthereumKit.init(this) + companion object { + lateinit var instance: App + private set } } diff --git a/app/src/main/java/io/horizontalsystems/ethereumkit/sample/BalanceFragment.kt b/app/src/main/java/io/horizontalsystems/ethereumkit/sample/BalanceFragment.kt index 69c5263e..18ac98c5 100644 --- a/app/src/main/java/io/horizontalsystems/ethereumkit/sample/BalanceFragment.kt +++ b/app/src/main/java/io/horizontalsystems/ethereumkit/sample/BalanceFragment.kt @@ -10,15 +10,16 @@ import android.view.ViewGroup import android.widget.Button import android.widget.TextView import io.horizontalsystems.ethereumkit.EthereumKit -import io.horizontalsystems.ethereumkit.R class BalanceFragment : Fragment() { lateinit var viewModel: MainViewModel lateinit var balanceValue: TextView + lateinit var tokenBalanceValue: TextView lateinit var feeValue: TextView lateinit var lbhValue: TextView lateinit var kitStateValue: TextView + lateinit var erc20StateValue: TextView lateinit var refreshButton: Button override fun onCreate(savedInstanceState: Bundle?) { @@ -31,18 +32,31 @@ class BalanceFragment : Fragment() { balanceValue.text = (balance ?: 0).toString() }) + viewModel.erc20TokenBalance.observe(this, Observer { balance -> + tokenBalanceValue.text = (balance ?: 0).toString() + }) + viewModel.fee.observe(this, Observer { fee -> - feeValue.text = String.format("%f", fee) + feeValue.text = fee?.toPlainString() }) viewModel.lastBlockHeight.observe(this, Observer { lbh -> lbhValue.text = (lbh ?: 0).toString() }) - viewModel.kitState.observe(this, Observer { kitState -> + viewModel.etherState.observe(this, Observer { kitState -> kitStateValue.text = when (kitState) { - is EthereumKit.KitState.Synced -> "Synced" - is EthereumKit.KitState.Syncing -> "Syncing" - is EthereumKit.KitState.NotSynced -> "NotSynced" + is EthereumKit.SyncState.Synced -> "Synced" + is EthereumKit.SyncState.Syncing -> "Syncing" + is EthereumKit.SyncState.NotSynced -> "NotSynced" + else -> "null" + } + }) + + viewModel.erc20State.observe(this, Observer { kitState -> + erc20StateValue.text = when (kitState) { + is EthereumKit.SyncState.Synced -> "Synced" + is EthereumKit.SyncState.Syncing -> "Syncing" + is EthereumKit.SyncState.NotSynced -> "NotSynced" else -> "null" } }) @@ -57,10 +71,12 @@ class BalanceFragment : Fragment() { super.onViewCreated(view, savedInstanceState) balanceValue = view.findViewById(R.id.balanceValue) + tokenBalanceValue = view.findViewById(R.id.tokenBalanceValue) refreshButton = view.findViewById(R.id.buttonRefresh) feeValue = view.findViewById(R.id.feeValue) lbhValue = view.findViewById(R.id.lbhValue) kitStateValue = view.findViewById(R.id.kitStateValue) + erc20StateValue = view.findViewById(R.id.erc20StateValue) refreshButton.setOnClickListener { viewModel.refresh() diff --git a/app/src/main/java/io/horizontalsystems/ethereumkit/sample/MainActivity.kt b/app/src/main/java/io/horizontalsystems/ethereumkit/sample/MainActivity.kt index 5c4470ee..c18fdb64 100644 --- a/app/src/main/java/io/horizontalsystems/ethereumkit/sample/MainActivity.kt +++ b/app/src/main/java/io/horizontalsystems/ethereumkit/sample/MainActivity.kt @@ -5,7 +5,6 @@ import android.support.design.widget.BottomNavigationView import android.support.v4.app.Fragment import android.support.v7.app.AppCompatActivity import android.view.MenuItem -import io.horizontalsystems.ethereumkit.R class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemSelectedListener { diff --git a/app/src/main/java/io/horizontalsystems/ethereumkit/sample/MainViewModel.kt b/app/src/main/java/io/horizontalsystems/ethereumkit/sample/MainViewModel.kt index b7bb2249..627b089e 100644 --- a/app/src/main/java/io/horizontalsystems/ethereumkit/sample/MainViewModel.kt +++ b/app/src/main/java/io/horizontalsystems/ethereumkit/sample/MainViewModel.kt @@ -2,62 +2,196 @@ package io.horizontalsystems.ethereumkit.sample import android.arch.lifecycle.MutableLiveData import android.arch.lifecycle.ViewModel +import android.util.Log +import android.widget.Toast import io.horizontalsystems.ethereumkit.EthereumKit -import io.horizontalsystems.ethereumkit.EthereumKit.KitState -import io.horizontalsystems.ethereumkit.EthereumKit.NetworkType -import io.horizontalsystems.ethereumkit.models.Transaction +import io.horizontalsystems.ethereumkit.EthereumKit.SyncState +import io.horizontalsystems.ethereumkit.sample.core.Erc20Adapter +import io.horizontalsystems.ethereumkit.sample.core.EthereumAdapter +import io.horizontalsystems.ethereumkit.sample.core.TransactionRecord +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.CompositeDisposable +import java.math.BigDecimal -class MainViewModel : ViewModel(), EthereumKit.Listener { +class MainViewModel : ViewModel() { - val transactions = MutableLiveData>() - val balance = MutableLiveData() + private val infuraKey = "2a1306f1d12f4c109a4d4fb9be46b02e" + private val etherscanKey = "GKNHXT22ED7PRVCKZATFZQD1YI7FK9AAYE" + private val contractAddress = "0xF559862f9265756619d5523bBC4bd8422898e97d" + private val contractDecimal = 28 + private val testMode = true + + private val disposables = CompositeDisposable() + + private var ethereumKit: EthereumKit + private val erc20Adapter: Erc20Adapter + private val ethereumAdapter: EthereumAdapter + + + + val transactions = MutableLiveData>() + val balance = MutableLiveData() + val fee = MutableLiveData() val lastBlockHeight = MutableLiveData() - val fee = MutableLiveData() - val kitState = MutableLiveData() + val etherState = MutableLiveData() + val erc20State = MutableLiveData() + + val erc20TokenBalance = MutableLiveData() val sendStatus = SingleLiveEvent() - private var ethereumKit: EthereumKit init { - val words = listOf("subway", "plate", "brick", "pattern", "inform", "used", "oblige", "identify", "cherry", "drop", "flush", "balance") - ethereumKit = EthereumKit(words, NetworkType.Kovan) + // val words = "subway plate brick pattern inform used oblige identify cherry drop flush balance".split(" ") + val words = "mom year father track attend frown loyal goddess crisp abandon juice roof".split(" ") + + ethereumKit = EthereumKit.ethereumKit(App.instance, words, "unique-wallet-id", testMode, infuraKey = infuraKey, etherscanKey = etherscanKey) + ethereumAdapter = EthereumAdapter(ethereumKit) + erc20Adapter = Erc20Adapter(ethereumKit, contractAddress, contractDecimal) + + ethereumKit.start() - ethereumKit.listener = this - transactions.value = ethereumKit.transactions - balance.value = ethereumKit.balance fee.value = ethereumKit.fee() + updateBalance() + updateErc20Balance() + updateState() + updateErc20State() + updateLastBlockHeight() + + // + // Ethereum + // + ethereumAdapter.transactionSubject.subscribe { + updateTransactions() + }.let { + disposables.add(it) + } + + ethereumAdapter.balanceSubject.subscribe { + updateBalance() + }.let { + disposables.add(it) + } + + ethereumAdapter.lastBlockHeightSubject.subscribe { + updateLastBlockHeight() + }.let { + disposables.add(it) + } + + ethereumAdapter.syncStateUpdateSubject.subscribe { + updateState() + }.let { + disposables.add(it) + } + + erc20Adapter.syncStateUpdateSubject.subscribe { + updateErc20State() + }.let { + disposables.add(it) + } + + // + // ERC20 + // + + erc20Adapter.balanceSubject.subscribe { + updateErc20Balance() + }.let { + disposables.add(it) + } + ethereumKit.start() } + private fun updateLastBlockHeight() { + lastBlockHeight.postValue(ethereumKit.lastBlockHeight) + } + + private fun updateState() { + etherState.postValue(ethereumAdapter.syncState) + } + + private fun updateErc20State() { + erc20State.postValue(erc20Adapter.syncState) + } + + private fun updateBalance() { + balance.postValue(ethereumAdapter.balance) + } + + private fun updateErc20Balance() { + erc20TokenBalance.postValue(erc20Adapter.balance) + } + + // + // Ethereum + // + fun refresh() { - ethereumKit.refresh() + ethereumKit.start() fee.postValue(ethereumKit.fee()) } fun receiveAddress(): String { - return ethereumKit.receiveAddress() + return ethereumKit.receiveAddress } - fun send(address: String, amount: Double) { - ethereumKit.send(address, amount) { error -> - sendStatus.value = error - } - } + fun send(address: String, amount: BigDecimal) { + ethereumAdapter.sendSingle(address, amount) + .subscribeOn(io.reactivex.schedulers.Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ + //success + Toast.makeText(App.instance, "Success", Toast.LENGTH_SHORT).show() + }, { + Log.e("MainViewModel", "send failed ${it.message}") + sendStatus.value = it + })?.let { disposables.add(it) } - override fun transactionsUpdated(inserted: List, updated: List, deleted: List) { - transactions.postValue(ethereumKit.transactions) } - override fun balanceUpdated(balance: Double) { - this.balance.postValue(balance) + // + // ERC20 + // + + fun sendERC20(address: String, amount: BigDecimal) { + erc20Adapter.sendSingle(address, amount) + .subscribeOn(io.reactivex.schedulers.Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ + //success + Toast.makeText(App.instance, "Success", Toast.LENGTH_SHORT).show() + }, { + Log.e("MainViewModel", "send failed ${it.message}") + sendStatus.value = it + })?.let { disposables.add(it) } } - override fun lastBlockHeightUpdated(height: Int) { - this.lastBlockHeight.postValue(height) + fun filterTransactions(ethTx: Boolean) { + val txMethod = if (ethTx) ethereumAdapter.transactionsSingle() else erc20Adapter.transactionsSingle() + + txMethod + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { txList: List -> + transactions.value = txList + }.let { + disposables.add(it) + } } - override fun onKitStateUpdate(state: KitState) { - this.kitState.postValue(state) + // + // Private + // + + private fun updateTransactions() { + ethereumAdapter.transactionsSingle() + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { list: List -> + transactions.value = list + }.let { + disposables.add(it) + } } + } diff --git a/app/src/main/java/io/horizontalsystems/ethereumkit/sample/SendReceiveFragment.kt b/app/src/main/java/io/horizontalsystems/ethereumkit/sample/SendReceiveFragment.kt index fc385190..993b3609 100644 --- a/app/src/main/java/io/horizontalsystems/ethereumkit/sample/SendReceiveFragment.kt +++ b/app/src/main/java/io/horizontalsystems/ethereumkit/sample/SendReceiveFragment.kt @@ -11,7 +11,6 @@ import android.widget.Button import android.widget.EditText import android.widget.TextView import android.widget.Toast -import io.horizontalsystems.ethereumkit.R class SendReceiveFragment : Fragment() { @@ -19,6 +18,7 @@ class SendReceiveFragment : Fragment() { private lateinit var receiveAddressButton: Button private lateinit var receiveAddressText: TextView + private lateinit var sendToken: Button private lateinit var sendButton: Button private lateinit var sendAmount: EditText private lateinit var sendAddress: EditText @@ -49,12 +49,19 @@ class SendReceiveFragment : Fragment() { sendAmount = view.findViewById(R.id.sendAmount) sendButton = view.findViewById(R.id.sendButton) sendButton.setOnClickListener { - if (sendAddress.text.isEmpty()) { - sendAddress.error = "Send address cannot be blank" - } else if (sendAmount.text.isEmpty()) { - sendAmount.error = "Send amount cannot be blank" - } else { - viewModel.send(sendAddress.text.toString(), sendAmount.text.toString().toDouble()) + when { + sendAddress.text.isEmpty() -> sendAddress.error = "Send address cannot be blank" + sendAmount.text.isEmpty() -> sendAmount.error = "Send amount cannot be blank" + else -> viewModel.send(sendAddress.text.toString(), sendAmount.text.toString().toBigDecimal()) + } + } + + sendToken = view.findViewById(R.id.sendToken) + sendToken.setOnClickListener { + when { + sendAddress.text.isEmpty() -> sendAddress.error = "Send address cannot be blank" + sendAmount.text.isEmpty() -> sendAmount.error = "Send amount cannot be blank" + else -> viewModel.sendERC20(sendAddress.text.toString(), sendAmount.text.toString().toBigDecimal()) } } diff --git a/app/src/main/java/io/horizontalsystems/ethereumkit/sample/TransactionsFragment.kt b/app/src/main/java/io/horizontalsystems/ethereumkit/sample/TransactionsFragment.kt index 77c62dca..652a1e26 100644 --- a/app/src/main/java/io/horizontalsystems/ethereumkit/sample/TransactionsFragment.kt +++ b/app/src/main/java/io/horizontalsystems/ethereumkit/sample/TransactionsFragment.kt @@ -2,6 +2,7 @@ package io.horizontalsystems.ethereumkit.sample import android.arch.lifecycle.Observer import android.arch.lifecycle.ViewModelProviders +import android.graphics.Color import android.os.Bundle import android.support.v4.app.Fragment import android.support.v7.widget.LinearLayoutManager @@ -10,13 +11,13 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView -import io.horizontalsystems.ethereumkit.R -import io.horizontalsystems.ethereumkit.models.Transaction +import io.horizontalsystems.ethereumkit.sample.core.TransactionRecord class TransactionsFragment : Fragment() { private lateinit var viewModel: MainViewModel private lateinit var transactionsRecyclerView: RecyclerView + private val transactionsAdapter = TransactionsAdapter() override fun onCreate(savedInstanceState: Bundle?) { @@ -25,12 +26,18 @@ class TransactionsFragment : Fragment() { activity?.let { viewModel = ViewModelProviders.of(it).get(MainViewModel::class.java) - viewModel.transactions.observe(this, Observer { - it?.let { transactions -> + viewModel.transactions.observe(this, Observer { txs -> + txs?.let { transactions -> transactionsAdapter.items = transactions transactionsAdapter.notifyDataSetChanged() } }) + + viewModel.lastBlockHeight.observe(this, Observer { height -> + height?.let { + transactionsAdapter.lastBlockHeight = height + } + }) } } @@ -44,11 +51,23 @@ class TransactionsFragment : Fragment() { transactionsRecyclerView = view.findViewById(R.id.transactions) transactionsRecyclerView.adapter = transactionsAdapter transactionsRecyclerView.layoutManager = LinearLayoutManager(context) + + val ethFilter = view.findViewById(R.id.ethFilter) + val tokenFilter = view.findViewById(R.id.tokenFilter) + + ethFilter.setOnClickListener { + viewModel.filterTransactions(true) + } + + tokenFilter.setOnClickListener { + viewModel.filterTransactions(false) + } } } class TransactionsAdapter : RecyclerView.Adapter() { - var items = listOf() + var items = listOf() + var lastBlockHeight: Int = 0 override fun getItemCount() = items.size @@ -57,15 +76,33 @@ class TransactionsAdapter : RecyclerView.Adapter() { override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { when (holder) { - is ViewHolderTransaction -> holder.bind(items[position], itemCount - position) + is ViewHolderTransaction -> holder.bind(items[position], itemCount - position, lastBlockHeight) } } } -class ViewHolderTransaction(val containerView: View) : RecyclerView.ViewHolder(containerView) { +class ViewHolderTransaction(private val containerView: View) : RecyclerView.ViewHolder(containerView) { private val summary = containerView.findViewById(R.id.summary)!! - fun bind(transactionInfo: Transaction, index: Int) { - summary.text = "#${index} - #${transactionInfo.blockNumber} - From: ${transactionInfo.from}, To: ${transactionInfo.to}, Amount: ${transactionInfo.value}" + fun bind(tx: TransactionRecord, index: Int, lastBlockHeight: Int) { + containerView.setBackgroundColor(if (index % 2 == 0) + Color.parseColor("#dddddd") else + Color.TRANSPARENT + ) + + var value = """ + - #$index + - From: ${tx.from.address} + - To: ${tx.to.address} + - Amount: ${tx.amount.stripTrailingZeros()} + """ + + if (lastBlockHeight > 0) + value += "\n- Confirmations: ${tx.blockHeight?.let { lastBlockHeight - it } ?: 0}" + + if (tx.contractAddress.isNotEmpty()) + value += "\n- Contract: ${tx.contractAddress}" + + summary.text = value.trimIndent() } } diff --git a/app/src/main/java/io/horizontalsystems/ethereumkit/sample/core/BaseAdapter.kt b/app/src/main/java/io/horizontalsystems/ethereumkit/sample/core/BaseAdapter.kt new file mode 100644 index 00000000..5bfb55a6 --- /dev/null +++ b/app/src/main/java/io/horizontalsystems/ethereumkit/sample/core/BaseAdapter.kt @@ -0,0 +1,95 @@ +package io.horizontalsystems.ethereumkit.sample.core + +import io.horizontalsystems.ethereumkit.EthereumKit +import io.horizontalsystems.ethereumkit.models.EthereumTransaction +import io.reactivex.Single +import io.reactivex.subjects.PublishSubject +import java.math.BigDecimal + +open class BaseAdapter(val ethereumKit: EthereumKit, val decimal: Int) : EthereumKit.Listener { + + val transactionSubject = PublishSubject.create() + val balanceSubject = PublishSubject.create() + val lastBlockHeightSubject = PublishSubject.create() + val syncStateUpdateSubject = PublishSubject.create() + + open val syncState: EthereumKit.SyncState = EthereumKit.SyncState.NotSynced + + fun transactionRecord(transaction: EthereumTransaction): TransactionRecord { + val mineAddress = ethereumKit.receiveAddress + + val from = TransactionAddress(transaction.from, transaction.from == mineAddress) + + val to = TransactionAddress(transaction.to, transaction.to == mineAddress) + + var amount: BigDecimal = BigDecimal.valueOf(0.0) + + transaction.value.toBigDecimalOrNull()?.let { + amount = it.movePointLeft(decimal) + if (from.mine) { + amount = -amount + } + } + + return TransactionRecord( + transactionHash = transaction.hash, + blockHeight = transaction.blockNumber, + amount = amount, + timestamp = transaction.timeStamp, + from = from, + to = to, + contractAddress = transaction.contractAddress + ) + } + + val balance: BigDecimal + get() { + balanceString?.toBigDecimalOrNull()?.let { + val converted = it.movePointLeft(decimal) + return converted.stripTrailingZeros() + } + + return BigDecimal.ZERO + } + + open val balanceString: String? + get() { + return null + } + + open fun sendSingle(address: String, amount: BigDecimal): Single { + val poweredDecimal = amount.scaleByPowerOfTen(decimal) + val noScaleDecimal = poweredDecimal.setScale(0) + + return sendSingle(address, noScaleDecimal.toPlainString()) + } + + open fun sendSingle(address: String, amount: String): Single { + return Single.just(Unit) + } + + open fun transactionsSingle(hashFrom: String? = null, limit: Int? = null): Single> { + return transactionsObservable(hashFrom, limit) + .map { list -> list.map { transactionRecord(it) } } + } + + open fun transactionsObservable(hashFrom: String? = null, limit: Int? = null): Single> { + return Single.just(listOf()) + } + + override fun onTransactionsUpdate(transactions: List) { + transactionSubject.onNext(Unit) + } + + override fun onBalanceUpdate() { + balanceSubject.onNext(Unit) + } + + override fun onLastBlockHeightUpdate() { + lastBlockHeightSubject.onNext(Unit) + } + + override fun onSyncStateUpdate() { + syncStateUpdateSubject.onNext(Unit) + } +} diff --git a/app/src/main/java/io/horizontalsystems/ethereumkit/sample/core/Erc20Adapter.kt b/app/src/main/java/io/horizontalsystems/ethereumkit/sample/core/Erc20Adapter.kt new file mode 100644 index 00000000..9472bc59 --- /dev/null +++ b/app/src/main/java/io/horizontalsystems/ethereumkit/sample/core/Erc20Adapter.kt @@ -0,0 +1,31 @@ +package io.horizontalsystems.ethereumkit.sample.core + +import io.horizontalsystems.ethereumkit.EthereumKit +import io.horizontalsystems.ethereumkit.models.EthereumTransaction +import io.reactivex.Single + +class Erc20Adapter(ethereumKit: EthereumKit, private val contractAddress: String, decimal: Int): BaseAdapter(ethereumKit, decimal) { + + init { + ethereumKit.register(contractAddress, this) + } + + override val syncState: EthereumKit.SyncState + get() = ethereumKit.syncStateErc20(contractAddress) + + + override val balanceString: String? + get() = ethereumKit.balanceERC20(contractAddress) + + override fun sendSingle(address: String, amount: String): Single { + return ethereumKit.sendERC20( + toAddress = address, + contractAddress = contractAddress, + amount = amount).map { Unit } + } + + override fun transactionsObservable(hashFrom: String?, limit: Int?): Single> { + return ethereumKit.transactionsERC20(contractAddress, hashFrom, limit) + } + +} diff --git a/app/src/main/java/io/horizontalsystems/ethereumkit/sample/core/EthereumAdapter.kt b/app/src/main/java/io/horizontalsystems/ethereumkit/sample/core/EthereumAdapter.kt new file mode 100644 index 00000000..76771d52 --- /dev/null +++ b/app/src/main/java/io/horizontalsystems/ethereumkit/sample/core/EthereumAdapter.kt @@ -0,0 +1,27 @@ +package io.horizontalsystems.ethereumkit.sample.core + +import io.horizontalsystems.ethereumkit.EthereumKit +import io.horizontalsystems.ethereumkit.models.EthereumTransaction +import io.reactivex.Single + +class EthereumAdapter(ethereumKit: EthereumKit): BaseAdapter(ethereumKit, 18) { + + init { + ethereumKit.listener = this + } + + override val syncState: EthereumKit.SyncState + get() = ethereumKit.syncState + + override val balanceString: String? + get() = ethereumKit.balance + + override fun sendSingle(address: String, amount: String): Single { + return ethereumKit.send(address, amount).map { Unit } + } + + override fun transactionsObservable(hashFrom: String?, limit: Int?): Single> { + return ethereumKit.transactions(hashFrom, limit) + } + +} diff --git a/app/src/main/java/io/horizontalsystems/ethereumkit/sample/core/TransactionRecord.kt b/app/src/main/java/io/horizontalsystems/ethereumkit/sample/core/TransactionRecord.kt new file mode 100644 index 00000000..64774bb4 --- /dev/null +++ b/app/src/main/java/io/horizontalsystems/ethereumkit/sample/core/TransactionRecord.kt @@ -0,0 +1,14 @@ +package io.horizontalsystems.ethereumkit.sample.core + +import java.math.BigDecimal + +class TransactionRecord ( + val transactionHash: String, + val blockHeight: Long?, + val amount: BigDecimal, + val timestamp: Long, + var from: TransactionAddress, + var to: TransactionAddress, + val contractAddress: String) + +class TransactionAddress (val address: String, val mine: Boolean) diff --git a/app/src/main/res/layout/fragment_balance.xml b/app/src/main/res/layout/fragment_balance.xml index 067fae90..23e2b595 100644 --- a/app/src/main/res/layout/fragment_balance.xml +++ b/app/src/main/res/layout/fragment_balance.xml @@ -1,11 +1,10 @@ - -