Skip to content

Commit b0f5efb

Browse files
committed
Support subaddress
1 parent a91029c commit b0f5efb

File tree

59 files changed

+1280
-750
lines changed

Some content is hidden

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

59 files changed

+1280
-750
lines changed

app/src/main/AndroidManifest.xml

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@
1111
android:allowBackup="true"
1212
android:icon="@mipmap/ic_launcher"
1313
android:label="@string/app_name"
14+
android:networkSecurityConfig="@xml/network_security_config"
1415
android:roundIcon="@mipmap/ic_launcher_round"
1516
android:supportsRtl="false"
1617
android:theme="@style/AppTheme"
17-
android:networkSecurityConfig="@xml/network_security_config"
1818
tools:ignore="GoogleAppIndexingWarning">
1919
<activity
2020
android:name="SplashActivity"
@@ -36,10 +36,6 @@
3636
android:configChanges="orientation|keyboardHidden"
3737
android:screenOrientation="portrait"
3838
android:windowSoftInputMode="stateHidden|adjustResize" />
39-
<activity
40-
android:name=".feature.coin.SelectCoinActivity"
41-
android:configChanges="orientation|keyboardHidden"
42-
android:screenOrientation="portrait" />
4339
<activity
4440
android:name=".feature.generate.recovery.RecoveryWalletActivity"
4541
android:configChanges="orientation|keyboardHidden"
@@ -50,10 +46,6 @@
5046
android:configChanges="orientation|keyboardHidden"
5147
android:screenOrientation="portrait"
5248
android:windowSoftInputMode="stateHidden|adjustPan" />
53-
<activity
54-
android:name=".feature.setting.NodeSettingActivity"
55-
android:configChanges="orientation|keyboardHidden"
56-
android:screenOrientation="portrait" />
5749
<activity
5850
android:name=".feature.setting.NodeListActivity"
5951
android:configChanges="orientation|keyboardHidden"
@@ -67,11 +59,6 @@
6759
android:configChanges="orientation|keyboardHidden"
6860
android:screenOrientation="portrait"
6961
android:windowSoftInputMode="stateHidden|adjustResize" />
70-
<activity
71-
android:name=".feature.coin.SearchCoinActivity"
72-
android:configChanges="orientation|keyboardHidden"
73-
android:screenOrientation="portrait"
74-
android:windowSoftInputMode="stateHidden|adjustResize" />
7562
<activity
7663
android:name=".feature.address.ScanActivity"
7764
android:configChanges="orientation|keyboardHidden"
@@ -134,6 +121,10 @@
134121
android:name=".feature.setting.ContactUsActivity"
135122
android:configChanges="orientation|keyboardHidden"
136123
android:screenOrientation="portrait" />
124+
<activity
125+
android:name=".feature.wallet.AddressSettingActivity"
126+
android:configChanges="orientation|keyboardHidden"
127+
android:screenOrientation="portrait" />
137128
</application>
138129

139130
</manifest>

app/src/main/java/io/wookey/wallet/App.kt

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,23 @@ import android.app.Application
55
import android.content.Context
66
import android.content.res.Configuration
77
import android.os.Bundle
8-
import io.wookey.wallet.support.extensions.DelegatesExt
9-
import io.wookey.wallet.support.extensions.getLocale
10-
import io.wookey.wallet.support.extensions.getSystemDefaultLocale
11-
import io.wookey.wallet.support.extensions.setLocale
8+
import android.util.Log
9+
import io.wookey.wallet.support.VersionManager
10+
import io.wookey.wallet.support.extensions.*
11+
import kotlinx.coroutines.*
12+
import org.json.JSONObject
13+
import java.io.BufferedReader
14+
import java.io.InputStreamReader
15+
import java.net.HttpURLConnection
16+
import java.net.URL
1217
import java.util.*
1318

1419
class App : Application() {
1520

1621
companion object {
1722
var SYSTEM_DEFAULT_LOCALE: Locale by DelegatesExt.notNullSingleValue()
1823
var instance: App by DelegatesExt.notNullSingleValue()
24+
var newVersion = true
1925
}
2026

2127
override fun attachBaseContext(base: Context?) {
@@ -54,6 +60,8 @@ class App : Application() {
5460
}
5561

5662
})
63+
64+
VersionManager().getLatestReleases()
5765
}
5866

5967
}

app/src/main/java/io/wookey/wallet/MainActivity.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package io.wookey.wallet
33
import android.os.Bundle
44
import android.support.v4.app.Fragment
55
import android.support.v4.app.FragmentTransaction
6+
import android.view.View
67
import io.wookey.wallet.base.BaseActivity
78
import io.wookey.wallet.feature.asset.AssetFragment
89
import io.wookey.wallet.feature.setting.LanguageActivity
@@ -47,6 +48,16 @@ class MainActivity : BaseActivity() {
4748
}
4849
}
4950

51+
override fun onResume() {
52+
super.onResume()
53+
if (App.newVersion) {
54+
dot.visibility = View.VISIBLE
55+
dot.setImageDrawable(BackgroundHelper.getRedDotDrawable(this))
56+
} else {
57+
dot.visibility = View.GONE
58+
}
59+
}
60+
5061
private fun switchFragment(position: Int) {
5162
initSelected()
5263
val transaction = supportFragmentManager.beginTransaction()

app/src/main/java/io/wookey/wallet/core/XMRWalletController.kt

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import io.wookey.monero.data.Node
77
import io.wookey.monero.data.TxData
88
import io.wookey.monero.model.*
99
import io.wookey.monero.util.RestoreHeight
10+
import io.wookey.wallet.data.entity.SubAddress
1011
import org.json.JSONObject
1112
import java.io.*
1213
import java.net.HttpURLConnection
@@ -32,28 +33,33 @@ object XMRWalletController {
3233

3334
fun createWallet(aFile: File, password: String): io.wookey.wallet.data.entity.Wallet {
3435
val newWallet = WalletManager.getInstance()
35-
.createWallet(aFile, password, MNEMONIC_LANGUAGE)
36+
.createWallet(aFile, password, MNEMONIC_LANGUAGE)
3637
val success = newWallet.status == Wallet.Status.Status_Ok
3738
return close(success, newWallet)
3839
}
3940

40-
fun recoveryWallet(aFile: File, password: String, mnemonic: String, restoreHeight: Long): io.wookey.wallet.data.entity.Wallet {
41+
fun recoveryWallet(
42+
aFile: File,
43+
password: String,
44+
mnemonic: String,
45+
restoreHeight: Long
46+
): io.wookey.wallet.data.entity.Wallet {
4147
val newWallet = WalletManager.getInstance()
42-
.recoveryWallet(aFile, password, mnemonic, restoreHeight)
48+
.recoveryWallet(aFile, password, mnemonic, restoreHeight)
4349
val success = newWallet.status == Wallet.Status.Status_Ok
4450
return close(success, newWallet)
4551
}
4652

4753
fun createWalletWithKeys(
48-
aFile: File,
49-
password: String,
50-
restoreHeight: Long,
51-
address: String,
52-
viewKey: String,
53-
spendKey: String
54+
aFile: File,
55+
password: String,
56+
restoreHeight: Long,
57+
address: String,
58+
viewKey: String,
59+
spendKey: String
5460
): io.wookey.wallet.data.entity.Wallet {
5561
val newWallet = WalletManager.getInstance()
56-
.createWalletWithKeys(aFile, password, MNEMONIC_LANGUAGE, restoreHeight, address, viewKey, spendKey)
62+
.createWalletWithKeys(aFile, password, MNEMONIC_LANGUAGE, restoreHeight, address, viewKey, spendKey)
5763
val success = newWallet.status == Wallet.Status.Status_Ok
5864
return close(success, newWallet)
5965
}
@@ -86,7 +92,7 @@ object XMRWalletController {
8692
}
8793

8894
fun verifyWalletPasswordOnly(keyPath: String, password: String) =
89-
WalletManager.getInstance().verifyWalletPasswordOnly(keyPath, password)
95+
WalletManager.getInstance().verifyWalletPasswordOnly(keyPath, password)
9096

9197

9298
fun openWallet(path: String, password: String) {
@@ -287,11 +293,11 @@ object XMRWalletController {
287293
fun isPaymentIdValid(paymentId: String) = Wallet.isPaymentIdValid(paymentId)
288294

289295
fun createTransaction(
290-
isAll: Boolean = false,
291-
dstAddress: String,
292-
paymentId: String?,
293-
amount: String, mixinCount: Int = 10,
294-
priority: PendingTransaction.Priority = PendingTransaction.Priority.Priority_Default
296+
isAll: Boolean = false,
297+
dstAddress: String,
298+
paymentId: String?,
299+
amount: String, mixinCount: Int = 10,
300+
priority: PendingTransaction.Priority = PendingTransaction.Priority.Priority_Default
295301
) {
296302

297303
val wallet = getWallet() ?: throw IllegalStateException("wallet opened failed")
@@ -380,7 +386,7 @@ object XMRWalletController {
380386
var time = Long.MAX_VALUE
381387
val split = url.split(":")
382388
val connection = URL("http", split[0], split[1].toInt(), "json_rpc").openConnection() as? HttpURLConnection
383-
?: throw IllegalArgumentException("url is invalid")
389+
?: throw IllegalArgumentException("url is invalid")
384390
connection.connectTimeout = timeout
385391
connection.readTimeout = timeout
386392
connection.doInput = true
@@ -413,4 +419,18 @@ object XMRWalletController {
413419
connection.disconnect()
414420
return time
415421
}
422+
423+
fun addSubAddress(label: String) {
424+
getWallet()?.addSubaddress(label)
425+
getWallet()?.store()
426+
}
427+
428+
fun getSubAddresses(): List<SubAddress> {
429+
val list = getWallet()?.subaddresses ?: emptyList()
430+
val subAddress = mutableListOf<SubAddress>()
431+
list.forEach {
432+
subAddress.add(SubAddress(it.rowId, it.address, it.label))
433+
}
434+
return subAddress
435+
}
416436
}

app/src/main/java/io/wookey/wallet/data/dao/WalletDao.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,14 @@ interface WalletDao {
7979
@Query("SELECT * FROM wallets WHERE _id = :id")
8080
fun getWalletById(id: Int): Wallet?
8181

82+
/**
83+
* Select the wallet from the wallets table by id.
84+
*
85+
* @return wallet.
86+
*/
87+
@Query("SELECT * FROM wallets WHERE _id = :id")
88+
fun loadWalletById(id: Int): LiveData<Wallet>
89+
8290
/**
8391
* Select the active wallet from the wallets table.
8492
*
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package io.wookey.wallet.data.entity
2+
3+
import android.os.Parcelable
4+
import kotlinx.android.parcel.Parcelize
5+
6+
@Parcelize
7+
data class SubAddress @JvmOverloads constructor(var id: Int = 0, var address: String, var label: String) : Parcelable
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package io.wookey.wallet.dialog
2+
3+
import android.arch.lifecycle.Observer
4+
import android.arch.lifecycle.ViewModelProviders
5+
import android.os.Bundle
6+
import android.support.v4.app.DialogFragment
7+
import android.support.v4.app.FragmentManager
8+
import android.view.LayoutInflater
9+
import android.view.View
10+
import android.view.ViewGroup
11+
import android.view.WindowManager
12+
import io.wookey.wallet.R
13+
import io.wookey.wallet.support.BackgroundHelper
14+
import io.wookey.wallet.support.extensions.dp2px
15+
import io.wookey.wallet.support.extensions.hideKeyboard
16+
import io.wookey.wallet.support.extensions.screenWidth
17+
import io.wookey.wallet.support.extensions.toast
18+
import kotlinx.android.synthetic.main.dialog_sub_address_edit.*
19+
20+
class SubAddressEditDialog : DialogFragment() {
21+
22+
23+
private var cancelListener: (() -> Unit)? = null
24+
private var confirmListener: (() -> Unit)? = null
25+
26+
override fun onCreate(savedInstanceState: Bundle?) {
27+
super.onCreate(savedInstanceState)
28+
setStyle(STYLE_NO_TITLE, R.style.CustomDialog)
29+
isCancelable = false
30+
}
31+
32+
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
33+
return inflater.inflate(R.layout.dialog_sub_address_edit, container, false)
34+
}
35+
36+
override fun onActivityCreated(savedInstanceState: Bundle?) {
37+
super.onActivityCreated(savedInstanceState)
38+
39+
val viewModel = ViewModelProviders.of(this).get(SubAddressEditViewModel::class.java)
40+
41+
val layoutParams = editContainer.layoutParams
42+
layoutParams.width = (screenWidth() * 0.85).toInt()
43+
layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT
44+
45+
editContainer.background = BackgroundHelper.getBackground(context, R.color.color_FFFFFF, dp2px(5))
46+
addressTag.background = BackgroundHelper.getEditBackground(context)
47+
48+
confirm.background = BackgroundHelper.getButtonBackground(context)
49+
50+
confirm.setOnClickListener {
51+
val tag = addressTag.text.toString().trim()
52+
if (tag.isNullOrBlank()) {
53+
toast(R.string.address_tag_hint)
54+
} else {
55+
viewModel.addSubAddress(tag)
56+
}
57+
}
58+
59+
cancel.setOnClickListener {
60+
cancelListener?.invoke()
61+
hide()
62+
}
63+
64+
viewModel.showLoading.observe(this, Observer {
65+
confirm.visibility = View.GONE
66+
progressBar.visibility = View.VISIBLE
67+
})
68+
69+
viewModel.hideLoading.observe(this, Observer {
70+
confirm.visibility = View.VISIBLE
71+
progressBar.visibility = View.GONE
72+
})
73+
74+
viewModel.toastRes.observe(this, Observer { toast(it) })
75+
76+
viewModel.success.observe(this, Observer {
77+
confirmListener?.invoke()
78+
hide()
79+
})
80+
}
81+
82+
fun hide() {
83+
val activity = activity
84+
if (activity != null && !activity.isFinishing && !activity.isDestroyed) {
85+
addressTag?.hideKeyboard()
86+
dismiss()
87+
}
88+
}
89+
90+
companion object {
91+
private const val TAG = "SubAddressEditDialog"
92+
fun newInstance(): SubAddressEditDialog {
93+
val fragment = SubAddressEditDialog()
94+
return fragment
95+
}
96+
97+
fun display(fm: FragmentManager, cancelListener: (() -> Unit)? = null, confirmListener: (() -> Unit)?) {
98+
val ft = fm.beginTransaction()
99+
val prev = fm.findFragmentByTag(TAG)
100+
if (prev != null) {
101+
ft.remove(prev)
102+
}
103+
ft.addToBackStack(null)
104+
newInstance().apply {
105+
this.cancelListener = cancelListener
106+
this.confirmListener = confirmListener
107+
}.show(ft, TAG)
108+
}
109+
}
110+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package io.wookey.wallet.dialog
2+
3+
import android.arch.lifecycle.MutableLiveData
4+
import io.wookey.wallet.R
5+
import io.wookey.wallet.base.BaseViewModel
6+
import io.wookey.wallet.core.XMRWalletController
7+
import kotlinx.coroutines.Dispatchers
8+
import kotlinx.coroutines.launch
9+
import kotlinx.coroutines.withContext
10+
11+
class SubAddressEditViewModel : BaseViewModel() {
12+
val success = MutableLiveData<Boolean>()
13+
14+
val showLoading = MutableLiveData<Boolean>()
15+
val hideLoading = MutableLiveData<Boolean>()
16+
val toastRes = MutableLiveData<Int>()
17+
18+
fun addSubAddress(label: String) {
19+
showLoading.postValue(true)
20+
uiScope.launch {
21+
try {
22+
withContext(Dispatchers.IO) {
23+
XMRWalletController.addSubAddress(label)
24+
}
25+
hideLoading.postValue(true)
26+
success.postValue(true)
27+
} catch (e: Exception) {
28+
e.printStackTrace()
29+
hideLoading.postValue(true)
30+
toastRes.postValue(R.string.node_connect_failed)
31+
}
32+
}
33+
}
34+
}

0 commit comments

Comments
 (0)