Skip to content

Commit aa45bc7

Browse files
authored
Merge pull request #72 from horizontalsystems/merge-master
Merge master
2 parents 28ff3cd + d728423 commit aa45bc7

File tree

177 files changed

+5451
-2566
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

177 files changed

+5451
-2566
lines changed

app/build.gradle

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ apply plugin: 'kotlin-android'
33
apply plugin: 'kotlin-android-extensions'
44

55
android {
6-
compileSdkVersion 27
6+
compileSdkVersion 28
77
defaultConfig {
88
applicationId "io.horizontalsystems.ethereumkit"
99
minSdkVersion 23
10-
targetSdkVersion 27
10+
targetSdkVersion 28
1111
versionCode 1
1212
versionName "1.0"
1313
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
@@ -33,20 +33,26 @@ dependencies {
3333

3434
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
3535

36-
implementation 'com.android.support:appcompat-v7:27.1.1'
36+
implementation 'com.github.horizontalsystems:hd-wallet-kit-android:a3666d8'
37+
38+
implementation 'com.android.support:appcompat-v7:28.0.0'
3739
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
38-
implementation 'com.android.support:design:27.1.1'
40+
implementation 'com.android.support:design:28.0.0'
3941

40-
implementation 'io.reactivex.rxjava2:rxjava:2.2.0'
42+
implementation 'io.reactivex.rxjava2:rxjava:2.2.2'
4143
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
4244

4345
// ViewModel and LiveData
4446
implementation 'android.arch.lifecycle:extensions:1.1.1'
4547
kapt "android.arch.lifecycle:compiler:1.1.1"
4648

49+
// For debug
50+
implementation 'com.facebook.stetho:stetho:1.5.1'
51+
4752
testImplementation 'junit:junit:4.12'
4853
androidTestImplementation 'com.android.support.test:runner:1.0.2'
4954
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
5055

5156
implementation project(':ethereumkit')
57+
implementation project(':erc20kit')
5258
}

app/src/main/java/io/horizontalsystems/ethereumkit/sample/App.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package io.horizontalsystems.ethereumkit.sample
22

33
import android.app.Application
4+
import com.facebook.stetho.Stetho
45

56
class App : Application() {
67

78
override fun onCreate() {
89
super.onCreate()
910
instance = this
11+
12+
// Enable debug bridge
13+
Stetho.initializeWithDefaults(this)
1014
}
1115

1216
companion object {

app/src/main/java/io/horizontalsystems/ethereumkit/sample/BalanceFragment.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import android.view.View
99
import android.view.ViewGroup
1010
import android.widget.Button
1111
import android.widget.TextView
12-
import io.horizontalsystems.ethereumkit.EthereumKit
12+
import io.horizontalsystems.ethereumkit.core.EthereumKit
1313

1414
class BalanceFragment : Fragment() {
1515

@@ -21,6 +21,7 @@ class BalanceFragment : Fragment() {
2121
lateinit var kitStateValue: TextView
2222
lateinit var erc20StateValue: TextView
2323
lateinit var refreshButton: Button
24+
lateinit var clearButton: Button
2425

2526
override fun onCreate(savedInstanceState: Bundle?) {
2627
super.onCreate(savedInstanceState)
@@ -73,6 +74,7 @@ class BalanceFragment : Fragment() {
7374
balanceValue = view.findViewById(R.id.balanceValue)
7475
tokenBalanceValue = view.findViewById(R.id.tokenBalanceValue)
7576
refreshButton = view.findViewById(R.id.buttonRefresh)
77+
clearButton = view.findViewById(R.id.buttonClear)
7678
feeValue = view.findViewById(R.id.feeValue)
7779
lbhValue = view.findViewById(R.id.lbhValue)
7880
kitStateValue = view.findViewById(R.id.kitStateValue)
@@ -81,5 +83,9 @@ class BalanceFragment : Fragment() {
8183
refreshButton.setOnClickListener {
8284
viewModel.refresh()
8385
}
86+
87+
clearButton.setOnClickListener {
88+
viewModel.clear()
89+
}
8490
}
8591
}

app/src/main/java/io/horizontalsystems/ethereumkit/sample/MainViewModel.kt

Lines changed: 79 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@ package io.horizontalsystems.ethereumkit.sample
33
import android.arch.lifecycle.MutableLiveData
44
import android.arch.lifecycle.ViewModel
55
import android.util.Log
6-
import android.widget.Toast
7-
import io.horizontalsystems.ethereumkit.EthereumKit
8-
import io.horizontalsystems.ethereumkit.EthereumKit.SyncState
6+
import io.horizontalsystems.erc20kit.core.Erc20Kit
7+
import io.horizontalsystems.ethereumkit.core.EthereumKit
8+
import io.horizontalsystems.ethereumkit.core.EthereumKit.NetworkType
9+
import io.horizontalsystems.ethereumkit.core.EthereumKit.SyncState
910
import io.horizontalsystems.ethereumkit.sample.core.Erc20Adapter
1011
import io.horizontalsystems.ethereumkit.sample.core.EthereumAdapter
1112
import io.horizontalsystems.ethereumkit.sample.core.TransactionRecord
13+
import io.horizontalsystems.hdwalletkit.HDWallet
14+
import io.horizontalsystems.hdwalletkit.Mnemonic
1215
import io.reactivex.android.schedulers.AndroidSchedulers
1316
import io.reactivex.disposables.CompositeDisposable
1417
import java.math.BigDecimal
@@ -23,36 +26,43 @@ class MainViewModel : ViewModel() {
2326

2427
private val disposables = CompositeDisposable()
2528

26-
private var ethereumKit: EthereumKit
27-
private val erc20Adapter: Erc20Adapter
28-
private val ethereumAdapter: EthereumAdapter
29-
29+
private lateinit var ethereumKit: EthereumKit
30+
private lateinit var ethereumAdapter: EthereumAdapter
3031

32+
private lateinit var erc20Adapter: Erc20Adapter
3133

3234
val transactions = MutableLiveData<List<TransactionRecord>>()
3335
val balance = MutableLiveData<BigDecimal>()
3436
val fee = MutableLiveData<BigDecimal>()
35-
val lastBlockHeight = MutableLiveData<Int>()
37+
val lastBlockHeight = MutableLiveData<Long>()
3638
val etherState = MutableLiveData<SyncState>()
3739
val erc20State = MutableLiveData<SyncState>()
3840

3941
val erc20TokenBalance = MutableLiveData<BigDecimal>()
4042
val sendStatus = SingleLiveEvent<Throwable?>()
41-
val gasPriceInWei = 3000000000L
4243

4344

45+
val gasPrice: Long = 5_000_000_000
46+
4447
init {
48+
init()
49+
}
50+
51+
fun init() {
4552
// val words = "subway plate brick pattern inform used oblige identify cherry drop flush balance".split(" ")
4653
val words = "mom year father track attend frown loyal goddess crisp abandon juice roof".split(" ")
4754

48-
ethereumKit = EthereumKit.ethereumKit(App.instance, words, "unique-wallet-id", testMode, infuraKey = infuraKey, etherscanKey = etherscanKey)
49-
ethereumAdapter = EthereumAdapter(ethereumKit)
50-
erc20Adapter = Erc20Adapter(ethereumKit, contractAddress, contractDecimal)
55+
val seed = Mnemonic().toSeed(words)
56+
val hdWallet = HDWallet(seed, if (testMode) 1 else 60)
57+
val privateKey = hdWallet.privateKey(0, 0, true).privKey
58+
val nodePrivateKey = hdWallet.privateKey(102, 102, true).privKey
5159

52-
ethereumKit.start()
60+
ethereumKit = EthereumKit.getInstance(App.instance, privateKey, EthereumKit.SyncMode.ApiSyncMode(infuraKey, etherscanKey), NetworkType.Ropsten, "unique-wallet-id")
61+
ethereumAdapter = EthereumAdapter(ethereumKit)
5362

63+
erc20Adapter = Erc20Adapter(App.instance, ethereumKit, "Max Token", "MXT", contractAddress, contractDecimal)
5464

55-
fee.value = ethereumKit.fee(gasPriceInWei)
65+
fee.value = ethereumKit.fee(gasPrice)
5666
updateBalance()
5767
updateErc20Balance()
5868
updateState()
@@ -62,46 +72,54 @@ class MainViewModel : ViewModel() {
6272
//
6373
// Ethereum
6474
//
65-
ethereumAdapter.transactionSubject.subscribe {
66-
updateTransactions()
75+
76+
ethereumAdapter.lastBlockHeightFlowable.subscribe {
77+
updateLastBlockHeight()
6778
}.let {
6879
disposables.add(it)
6980
}
7081

71-
ethereumAdapter.balanceSubject.subscribe {
72-
updateBalance()
82+
ethereumAdapter.transactionsFlowable.subscribe {
83+
updateTransactions()
7384
}.let {
7485
disposables.add(it)
7586
}
7687

77-
ethereumAdapter.lastBlockHeightSubject.subscribe {
78-
updateLastBlockHeight()
88+
ethereumAdapter.balanceFlowable.subscribe {
89+
updateBalance()
7990
}.let {
8091
disposables.add(it)
8192
}
8293

83-
ethereumAdapter.syncStateUpdateSubject.subscribe {
94+
ethereumAdapter.syncStateFlowable.subscribe {
8495
updateState()
8596
}.let {
8697
disposables.add(it)
8798
}
8899

89-
erc20Adapter.syncStateUpdateSubject.subscribe {
90-
updateErc20State()
91-
}.let {
92-
disposables.add(it)
93-
}
94100

95101
//
96102
// ERC20
97103
//
98104

99-
erc20Adapter.balanceSubject.subscribe {
105+
erc20Adapter.transactionsFlowable.subscribe {
106+
updateErc20Transactions()
107+
}.let {
108+
disposables.add(it)
109+
}
110+
111+
erc20Adapter.balanceFlowable.subscribe {
100112
updateErc20Balance()
101113
}.let {
102114
disposables.add(it)
103115
}
104116

117+
erc20Adapter.syncStateFlowable.subscribe {
118+
updateErc20State()
119+
}.let {
120+
disposables.add(it)
121+
}
122+
105123
ethereumKit.start()
106124
}
107125

@@ -125,26 +143,53 @@ class MainViewModel : ViewModel() {
125143
erc20TokenBalance.postValue(erc20Adapter.balance)
126144
}
127145

146+
private fun updateTransactions() {
147+
ethereumAdapter.transactions()
148+
.observeOn(AndroidSchedulers.mainThread())
149+
.subscribe { list: List<TransactionRecord> ->
150+
transactions.value = list
151+
}.let {
152+
disposables.add(it)
153+
}
154+
}
155+
156+
private fun updateErc20Transactions() {
157+
erc20Adapter.transactions()
158+
.observeOn(AndroidSchedulers.mainThread())
159+
.subscribe { list: List<TransactionRecord> ->
160+
transactions.value = list
161+
}.let {
162+
disposables.add(it)
163+
}
164+
}
165+
166+
128167
//
129168
// Ethereum
130169
//
131170

132171
fun refresh() {
133-
ethereumKit.start()
134-
fee.postValue(ethereumKit.fee(gasPriceInWei))
172+
ethereumKit.refresh()
173+
fee.postValue(ethereumKit.fee(gasPrice))
174+
}
175+
176+
fun clear() {
177+
EthereumKit.clear(App.instance)
178+
Erc20Kit.clear(App.instance)
179+
init()
135180
}
136181

137182
fun receiveAddress(): String {
138183
return ethereumKit.receiveAddress
139184
}
140185

141186
fun send(address: String, amount: BigDecimal) {
142-
ethereumAdapter.sendSingle(address, amount)
187+
ethereumAdapter.send(address, amount)
143188
.subscribeOn(io.reactivex.schedulers.Schedulers.io())
144189
.observeOn(AndroidSchedulers.mainThread())
145190
.subscribe({
146191
//success
147-
Toast.makeText(App.instance, "Success", Toast.LENGTH_SHORT).show()
192+
sendStatus.value = null
148193
}, {
149194
Log.e("MainViewModel", "send failed ${it.message}")
150195
sendStatus.value = it
@@ -157,20 +202,20 @@ class MainViewModel : ViewModel() {
157202
//
158203

159204
fun sendERC20(address: String, amount: BigDecimal) {
160-
erc20Adapter.sendSingle(address, amount)
205+
erc20Adapter.send(address, amount)
161206
.subscribeOn(io.reactivex.schedulers.Schedulers.io())
162207
.observeOn(AndroidSchedulers.mainThread())
163208
.subscribe({
164209
//success
165-
Toast.makeText(App.instance, "Success", Toast.LENGTH_SHORT).show()
210+
sendStatus.value = null
166211
}, {
167212
Log.e("MainViewModel", "send failed ${it.message}")
168213
sendStatus.value = it
169214
})?.let { disposables.add(it) }
170215
}
171216

172217
fun filterTransactions(ethTx: Boolean) {
173-
val txMethod = if (ethTx) ethereumAdapter.transactionsSingle() else erc20Adapter.transactionsSingle()
218+
val txMethod = if (ethTx) ethereumAdapter.transactions() else erc20Adapter.transactions()
174219

175220
txMethod
176221
.observeOn(AndroidSchedulers.mainThread())
@@ -181,18 +226,4 @@ class MainViewModel : ViewModel() {
181226
}
182227
}
183228

184-
//
185-
// Private
186-
//
187-
188-
private fun updateTransactions() {
189-
ethereumAdapter.transactionsSingle()
190-
.observeOn(AndroidSchedulers.mainThread())
191-
.subscribe { list: List<TransactionRecord> ->
192-
transactions.value = list
193-
}.let {
194-
disposables.add(it)
195-
}
196-
}
197-
198229
}

app/src/main/java/io/horizontalsystems/ethereumkit/sample/SendReceiveFragment.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ class SendReceiveFragment : Fragment() {
3535
return inflater.inflate(R.layout.fragment_send_receive, null)
3636
}
3737

38-
3938
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
4039
super.onViewCreated(view, savedInstanceState)
4140

app/src/main/java/io/horizontalsystems/ethereumkit/sample/TransactionsFragment.kt

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import android.view.View
1212
import android.view.ViewGroup
1313
import android.widget.TextView
1414
import io.horizontalsystems.ethereumkit.sample.core.TransactionRecord
15+
import java.text.SimpleDateFormat
16+
import java.util.*
1517

1618
class TransactionsFragment : Fragment() {
1719

@@ -67,7 +69,7 @@ class TransactionsFragment : Fragment() {
6769

6870
class TransactionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
6971
var items = listOf<TransactionRecord>()
70-
var lastBlockHeight: Int = 0
72+
var lastBlockHeight: Long = 0
7173

7274
override fun getItemCount() = items.size
7375

@@ -84,14 +86,20 @@ class TransactionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
8486
class ViewHolderTransaction(private val containerView: View) : RecyclerView.ViewHolder(containerView) {
8587
private val summary = containerView.findViewById<TextView>(R.id.summary)!!
8688

87-
fun bind(tx: TransactionRecord, index: Int, lastBlockHeight: Int) {
89+
fun bind(tx: TransactionRecord, index: Int, lastBlockHeight: Long) {
8890
containerView.setBackgroundColor(if (index % 2 == 0)
8991
Color.parseColor("#dddddd") else
9092
Color.TRANSPARENT
9193
)
9294

95+
val format = SimpleDateFormat("dd-MM-yyyy HH:mm:ss")
96+
9397
var value = """
9498
- #$index
99+
- Tx Hash: ${tx.transactionHash}
100+
- Tx Index: ${tx.transactionIndex}
101+
- Inter Tx Index: ${tx.interTransactionIndex}
102+
- Time: ${format.format(Date(tx.timestamp * 1000))}
95103
- From: ${tx.from.address}
96104
- To: ${tx.to.address}
97105
- Amount: ${tx.amount.stripTrailingZeros()}
@@ -100,9 +108,6 @@ class ViewHolderTransaction(private val containerView: View) : RecyclerView.View
100108
if (lastBlockHeight > 0)
101109
value += "\n- Confirmations: ${tx.blockHeight?.let { lastBlockHeight - it } ?: 0}"
102110

103-
if (tx.contractAddress.isNotEmpty())
104-
value += "\n- Contract: ${tx.contractAddress}"
105-
106111
summary.text = value.trimIndent()
107112
}
108113
}

0 commit comments

Comments
 (0)