Skip to content

Commit

Permalink
Support subaddress
Browse files Browse the repository at this point in the history
  • Loading branch information
WooKeyWallet committed Jun 19, 2019
1 parent a91029c commit b0f5efb
Show file tree
Hide file tree
Showing 59 changed files with 1,280 additions and 750 deletions.
19 changes: 5 additions & 14 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="false"
android:theme="@style/AppTheme"
android:networkSecurityConfig="@xml/network_security_config"
tools:ignore="GoogleAppIndexingWarning">
<activity
android:name="SplashActivity"
Expand All @@ -36,10 +36,6 @@
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden|adjustResize" />
<activity
android:name=".feature.coin.SelectCoinActivity"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="portrait" />
<activity
android:name=".feature.generate.recovery.RecoveryWalletActivity"
android:configChanges="orientation|keyboardHidden"
Expand All @@ -50,10 +46,6 @@
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden|adjustPan" />
<activity
android:name=".feature.setting.NodeSettingActivity"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="portrait" />
<activity
android:name=".feature.setting.NodeListActivity"
android:configChanges="orientation|keyboardHidden"
Expand All @@ -67,11 +59,6 @@
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden|adjustResize" />
<activity
android:name=".feature.coin.SearchCoinActivity"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden|adjustResize" />
<activity
android:name=".feature.address.ScanActivity"
android:configChanges="orientation|keyboardHidden"
Expand Down Expand Up @@ -134,6 +121,10 @@
android:name=".feature.setting.ContactUsActivity"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="portrait" />
<activity
android:name=".feature.wallet.AddressSettingActivity"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="portrait" />
</application>

</manifest>
16 changes: 12 additions & 4 deletions app/src/main/java/io/wookey/wallet/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,23 @@ import android.app.Application
import android.content.Context
import android.content.res.Configuration
import android.os.Bundle
import io.wookey.wallet.support.extensions.DelegatesExt
import io.wookey.wallet.support.extensions.getLocale
import io.wookey.wallet.support.extensions.getSystemDefaultLocale
import io.wookey.wallet.support.extensions.setLocale
import android.util.Log
import io.wookey.wallet.support.VersionManager
import io.wookey.wallet.support.extensions.*
import kotlinx.coroutines.*
import org.json.JSONObject
import java.io.BufferedReader
import java.io.InputStreamReader
import java.net.HttpURLConnection
import java.net.URL
import java.util.*

class App : Application() {

companion object {
var SYSTEM_DEFAULT_LOCALE: Locale by DelegatesExt.notNullSingleValue()
var instance: App by DelegatesExt.notNullSingleValue()
var newVersion = true
}

override fun attachBaseContext(base: Context?) {
Expand Down Expand Up @@ -54,6 +60,8 @@ class App : Application() {
}

})

VersionManager().getLatestReleases()
}

}
11 changes: 11 additions & 0 deletions app/src/main/java/io/wookey/wallet/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package io.wookey.wallet
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentTransaction
import android.view.View
import io.wookey.wallet.base.BaseActivity
import io.wookey.wallet.feature.asset.AssetFragment
import io.wookey.wallet.feature.setting.LanguageActivity
Expand Down Expand Up @@ -47,6 +48,16 @@ class MainActivity : BaseActivity() {
}
}

override fun onResume() {
super.onResume()
if (App.newVersion) {
dot.visibility = View.VISIBLE
dot.setImageDrawable(BackgroundHelper.getRedDotDrawable(this))
} else {
dot.visibility = View.GONE
}
}

private fun switchFragment(position: Int) {
initSelected()
val transaction = supportFragmentManager.beginTransaction()
Expand Down
54 changes: 37 additions & 17 deletions app/src/main/java/io/wookey/wallet/core/XMRWalletController.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import io.wookey.monero.data.Node
import io.wookey.monero.data.TxData
import io.wookey.monero.model.*
import io.wookey.monero.util.RestoreHeight
import io.wookey.wallet.data.entity.SubAddress
import org.json.JSONObject
import java.io.*
import java.net.HttpURLConnection
Expand All @@ -32,28 +33,33 @@ object XMRWalletController {

fun createWallet(aFile: File, password: String): io.wookey.wallet.data.entity.Wallet {
val newWallet = WalletManager.getInstance()
.createWallet(aFile, password, MNEMONIC_LANGUAGE)
.createWallet(aFile, password, MNEMONIC_LANGUAGE)
val success = newWallet.status == Wallet.Status.Status_Ok
return close(success, newWallet)
}

fun recoveryWallet(aFile: File, password: String, mnemonic: String, restoreHeight: Long): io.wookey.wallet.data.entity.Wallet {
fun recoveryWallet(
aFile: File,
password: String,
mnemonic: String,
restoreHeight: Long
): io.wookey.wallet.data.entity.Wallet {
val newWallet = WalletManager.getInstance()
.recoveryWallet(aFile, password, mnemonic, restoreHeight)
.recoveryWallet(aFile, password, mnemonic, restoreHeight)
val success = newWallet.status == Wallet.Status.Status_Ok
return close(success, newWallet)
}

fun createWalletWithKeys(
aFile: File,
password: String,
restoreHeight: Long,
address: String,
viewKey: String,
spendKey: String
aFile: File,
password: String,
restoreHeight: Long,
address: String,
viewKey: String,
spendKey: String
): io.wookey.wallet.data.entity.Wallet {
val newWallet = WalletManager.getInstance()
.createWalletWithKeys(aFile, password, MNEMONIC_LANGUAGE, restoreHeight, address, viewKey, spendKey)
.createWalletWithKeys(aFile, password, MNEMONIC_LANGUAGE, restoreHeight, address, viewKey, spendKey)
val success = newWallet.status == Wallet.Status.Status_Ok
return close(success, newWallet)
}
Expand Down Expand Up @@ -86,7 +92,7 @@ object XMRWalletController {
}

fun verifyWalletPasswordOnly(keyPath: String, password: String) =
WalletManager.getInstance().verifyWalletPasswordOnly(keyPath, password)
WalletManager.getInstance().verifyWalletPasswordOnly(keyPath, password)


fun openWallet(path: String, password: String) {
Expand Down Expand Up @@ -287,11 +293,11 @@ object XMRWalletController {
fun isPaymentIdValid(paymentId: String) = Wallet.isPaymentIdValid(paymentId)

fun createTransaction(
isAll: Boolean = false,
dstAddress: String,
paymentId: String?,
amount: String, mixinCount: Int = 10,
priority: PendingTransaction.Priority = PendingTransaction.Priority.Priority_Default
isAll: Boolean = false,
dstAddress: String,
paymentId: String?,
amount: String, mixinCount: Int = 10,
priority: PendingTransaction.Priority = PendingTransaction.Priority.Priority_Default
) {

val wallet = getWallet() ?: throw IllegalStateException("wallet opened failed")
Expand Down Expand Up @@ -380,7 +386,7 @@ object XMRWalletController {
var time = Long.MAX_VALUE
val split = url.split(":")
val connection = URL("http", split[0], split[1].toInt(), "json_rpc").openConnection() as? HttpURLConnection
?: throw IllegalArgumentException("url is invalid")
?: throw IllegalArgumentException("url is invalid")
connection.connectTimeout = timeout
connection.readTimeout = timeout
connection.doInput = true
Expand Down Expand Up @@ -413,4 +419,18 @@ object XMRWalletController {
connection.disconnect()
return time
}

fun addSubAddress(label: String) {
getWallet()?.addSubaddress(label)
getWallet()?.store()
}

fun getSubAddresses(): List<SubAddress> {
val list = getWallet()?.subaddresses ?: emptyList()
val subAddress = mutableListOf<SubAddress>()
list.forEach {
subAddress.add(SubAddress(it.rowId, it.address, it.label))
}
return subAddress
}
}
8 changes: 8 additions & 0 deletions app/src/main/java/io/wookey/wallet/data/dao/WalletDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ interface WalletDao {
@Query("SELECT * FROM wallets WHERE _id = :id")
fun getWalletById(id: Int): Wallet?

/**
* Select the wallet from the wallets table by id.
*
* @return wallet.
*/
@Query("SELECT * FROM wallets WHERE _id = :id")
fun loadWalletById(id: Int): LiveData<Wallet>

/**
* Select the active wallet from the wallets table.
*
Expand Down
7 changes: 7 additions & 0 deletions app/src/main/java/io/wookey/wallet/data/entity/SubAddress.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.wookey.wallet.data.entity

import android.os.Parcelable
import kotlinx.android.parcel.Parcelize

@Parcelize
data class SubAddress @JvmOverloads constructor(var id: Int = 0, var address: String, var label: String) : Parcelable
110 changes: 110 additions & 0 deletions app/src/main/java/io/wookey/wallet/dialog/SubAddressEditDialog.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package io.wookey.wallet.dialog

import android.arch.lifecycle.Observer
import android.arch.lifecycle.ViewModelProviders
import android.os.Bundle
import android.support.v4.app.DialogFragment
import android.support.v4.app.FragmentManager
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import io.wookey.wallet.R
import io.wookey.wallet.support.BackgroundHelper
import io.wookey.wallet.support.extensions.dp2px
import io.wookey.wallet.support.extensions.hideKeyboard
import io.wookey.wallet.support.extensions.screenWidth
import io.wookey.wallet.support.extensions.toast
import kotlinx.android.synthetic.main.dialog_sub_address_edit.*

class SubAddressEditDialog : DialogFragment() {


private var cancelListener: (() -> Unit)? = null
private var confirmListener: (() -> Unit)? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, R.style.CustomDialog)
isCancelable = false
}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.dialog_sub_address_edit, container, false)
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)

val viewModel = ViewModelProviders.of(this).get(SubAddressEditViewModel::class.java)

val layoutParams = editContainer.layoutParams
layoutParams.width = (screenWidth() * 0.85).toInt()
layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT

editContainer.background = BackgroundHelper.getBackground(context, R.color.color_FFFFFF, dp2px(5))
addressTag.background = BackgroundHelper.getEditBackground(context)

confirm.background = BackgroundHelper.getButtonBackground(context)

confirm.setOnClickListener {
val tag = addressTag.text.toString().trim()
if (tag.isNullOrBlank()) {
toast(R.string.address_tag_hint)
} else {
viewModel.addSubAddress(tag)
}
}

cancel.setOnClickListener {
cancelListener?.invoke()
hide()
}

viewModel.showLoading.observe(this, Observer {
confirm.visibility = View.GONE
progressBar.visibility = View.VISIBLE
})

viewModel.hideLoading.observe(this, Observer {
confirm.visibility = View.VISIBLE
progressBar.visibility = View.GONE
})

viewModel.toastRes.observe(this, Observer { toast(it) })

viewModel.success.observe(this, Observer {
confirmListener?.invoke()
hide()
})
}

fun hide() {
val activity = activity
if (activity != null && !activity.isFinishing && !activity.isDestroyed) {
addressTag?.hideKeyboard()
dismiss()
}
}

companion object {
private const val TAG = "SubAddressEditDialog"
fun newInstance(): SubAddressEditDialog {
val fragment = SubAddressEditDialog()
return fragment
}

fun display(fm: FragmentManager, cancelListener: (() -> Unit)? = null, confirmListener: (() -> Unit)?) {
val ft = fm.beginTransaction()
val prev = fm.findFragmentByTag(TAG)
if (prev != null) {
ft.remove(prev)
}
ft.addToBackStack(null)
newInstance().apply {
this.cancelListener = cancelListener
this.confirmListener = confirmListener
}.show(ft, TAG)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package io.wookey.wallet.dialog

import android.arch.lifecycle.MutableLiveData
import io.wookey.wallet.R
import io.wookey.wallet.base.BaseViewModel
import io.wookey.wallet.core.XMRWalletController
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

class SubAddressEditViewModel : BaseViewModel() {
val success = MutableLiveData<Boolean>()

val showLoading = MutableLiveData<Boolean>()
val hideLoading = MutableLiveData<Boolean>()
val toastRes = MutableLiveData<Int>()

fun addSubAddress(label: String) {
showLoading.postValue(true)
uiScope.launch {
try {
withContext(Dispatchers.IO) {
XMRWalletController.addSubAddress(label)
}
hideLoading.postValue(true)
success.postValue(true)
} catch (e: Exception) {
e.printStackTrace()
hideLoading.postValue(true)
toastRes.postValue(R.string.node_connect_failed)
}
}
}
}
Loading

0 comments on commit b0f5efb

Please sign in to comment.