Commit e017761b authored by pokkst's avatar pokkst

Allow for users to spend from certain UTXOs.

parent 4709ba02
......@@ -218,6 +218,10 @@ class MainActivity : AppCompatActivity() {
this.uiHelper.receiveWindow.visibility == View.VISIBLE -> this.uiHelper.receiveWindow.visibility = View.GONE
this.uiHelper.receiveWindowSLP.visibility == View.VISIBLE -> this.uiHelper.receiveWindowSLP.visibility = View.GONE
this.uiHelper.txInfo.visibility == View.VISIBLE -> this.uiHelper.txInfo.visibility = View.GONE
this.uiHelper.utxosScreen.visibility == View.VISIBLE -> {
this.walletHelper.selectedUtxos = ArrayList()
this.uiHelper.utxosScreen.visibility = View.GONE
}
this.uiHelper.encryptScreen.visibility == View.VISIBLE -> {
WalletHelper.encrypted = false
this.uiHelper.encryptWalletSwitch.isChecked = WalletHelper.encrypted
......
......@@ -10,10 +10,13 @@ import app.crescentcash.src.ui.UIHelper
import app.crescentcash.src.utils.Constants
import app.crescentcash.src.wallet.WalletHelper
import com.google.common.base.Splitter
import org.bitcoinj.core.Address
import org.bitcoinj.core.AddressFactory
import org.bitcoinj.core.ECKey
import org.bitcoinj.crypto.MnemonicCode
import org.bitcoinj.crypto.MnemonicException
import org.bitcoinj.wallet.DeterministicSeed
import org.bitcoinj.wallet.Wallet
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
......@@ -245,9 +248,48 @@ class NetHelper {
if (length == 12) {
val walletHelper = MainActivity.INSTANCE.walletHelper
walletHelper.setupSLPWallet(seedStr, true)
MainActivity.INSTANCE.prefs.edit().putBoolean("isNewUser", false).apply()
walletHelper.setupWalletKit(seed, cashAcctName, true)
val tempWallet = Wallet.fromSeed(walletHelper.parameters, seed)
try {
val cashAcctAddress = org.bitcoinj.net.NetHelper().getCashAccountAddress(walletHelper.parameters, cashAcctName)
val cashAcctEmoji = getCashAccountEmoji(cashAcctName)
println(cashAcctAddress)
var accountAddress: Address? = null
if (Address.isValidCashAddr(walletHelper.parameters, cashAcctAddress)) {
accountAddress = AddressFactory.create().getAddress(walletHelper.parameters, cashAcctAddress)
} else if (Address.isValidLegacyAddress(walletHelper.parameters, cashAcctAddress)) {
accountAddress = Address.fromBase58(walletHelper.parameters, cashAcctAddress)
} else {
uiHelper.showToastMessage("No address found!")
}
if (accountAddress != null) {
val isAddressMine = tempWallet.isPubKeyHashMine(accountAddress.hash160)
if (isAddressMine) {
walletHelper.setupSLPWallet(seedStr, true)
walletHelper.setupWalletKit(seed, cashAcctName, true)
val pref = MainActivity.INSTANCE.prefs.edit()
pref.putString("cashAccount", cashAcctName)
pref.putString("cashEmoji", cashAcctEmoji)
pref.putBoolean("isNewUser", false)
pref.apply()
MainActivity.INSTANCE.runOnUiThread {
uiHelper.restore_wallet.visibility = View.GONE
uiHelper.displayDownloadContent(true)
uiHelper.myEmoji.text = cashAcctEmoji
uiHelper.showToastMessage("Verified!")
uiHelper.refresh()
}
} else {
MainActivity.INSTANCE.runOnUiThread { uiHelper.showToastMessage("This is not your Cash Account!") }
}
}
} catch (e: NullPointerException) {
MainActivity.INSTANCE.runOnUiThread { uiHelper.showToastMessage("Cash Account not found.") }
}
uiHelper.showToastMessage("Verifying user...")
}
} else {
......
......@@ -24,6 +24,7 @@ import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.*
import androidx.annotation.UiThread
import androidx.core.view.get
import androidx.core.widget.addTextChangedListener
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import app.crescentcash.src.MainActivity
......@@ -109,6 +110,7 @@ class UIHelper {
private val btnScanSigToVerify: ImageView
var newCashAcctName: EditText
private val registerCashAcctBtn: Button
private val btnShowUtxos: Button
/////WALLET SETTINGS SCREEN
/////RECEIVE BITCOIN STUFF
......@@ -196,6 +198,9 @@ class UIHelper {
var opReturnText: EditText
var opReturnBox: LinearLayout
var allowLegacyP2SHSwitch: Switch
var utxosScreen: FrameLayout
private val utxoListView: NonScrollListView
private val btnSendUtxos: FloatingActionButton
var emojis = intArrayOf(128123, 128018, 128021, 128008, 128014, 128004, 128022, 128016, 128042, 128024, 128000, 128007, 128063, 129415, 128019, 128039, 129414, 129417, 128034, 128013, 128031, 128025, 128012, 129419, 128029, 128030, 128375, 127803, 127794, 127796, 127797, 127809, 127808, 127815, 127817, 127819, 127820, 127822, 127826, 127827, 129373, 129381, 129365, 127805, 127798, 127812, 129472, 129370, 129408, 127850, 127874, 127853, 127968, 128663, 128690, 9973, 9992, 128641, 128640, 8986, 9728, 11088, 127752, 9730, 127880, 127872, 9917, 9824, 9829, 9830, 9827, 128083, 128081, 127913, 128276, 127925, 127908, 127911, 127928, 127930, 129345, 128269, 128367, 128161, 128214, 9993, 128230, 9999, 128188, 128203, 9986, 128273, 128274, 128296, 128295, 9878, 9775, 128681, 128099, 127838)
......@@ -210,6 +215,8 @@ class UIHelper {
val amount: String
get() = amountText.text.toString()
val utxoMap = ArrayList<Map<String, TransactionOutput>>()
init {
val mainActivity = MainActivity.INSTANCE
......@@ -338,6 +345,10 @@ class UIHelper {
opReturnText = mainActivity.findViewById(R.id.opReturnText)
opReturnBox = mainActivity.findViewById(R.id.opReturnBox)
allowLegacyP2SHSwitch = mainActivity.findViewById(R.id.allowLegacyP2SHSwitch)
utxosScreen = mainActivity.findViewById(R.id.utxoWindow)
utxoListView = mainActivity.findViewById(R.id.utxoListView)
btnShowUtxos = mainActivity.findViewById(R.id.btnShowUtxos)
btnSendUtxos = mainActivity.findViewById(R.id.btnSendUtxos)
this.initListeners()
}
......@@ -639,6 +650,30 @@ class UIHelper {
newCashAcctName.text = null
}
}
this.utxoListView.choiceMode = ListView.CHOICE_MODE_MULTIPLE
this.utxoListView.setOnItemClickListener { parent, view, position, id ->
val cell: CheckedTextView = utxoListView[position].findViewById(R.id.text1)
cell.isChecked = !cell.isChecked
val utxo = utxoMap[position]["utxo"]
println("Selected utxo: $utxo")
if(cell.isChecked) {
MainActivity.INSTANCE.walletHelper.selectedUtxos.add(utxo!!)
} else {
MainActivity.INSTANCE.walletHelper.selectedUtxos.remove(utxo)
}
println(MainActivity.INSTANCE.walletHelper.selectedUtxos.toString())
}
this.btnShowUtxos.setOnClickListener {
utxosScreen.visibility = View.VISIBLE
setUtxoList(MainActivity.INSTANCE.walletHelper.wallet)
}
this.btnSendUtxos.setOnClickListener {
this.utxosScreen.visibility = View.GONE
this.advancedSettings.visibility = View.GONE
this.walletSettings.visibility = View.GONE
this.displaySendWindow()
}
}
private fun verify(address: String, signature: String, message: String) {
......@@ -1045,6 +1080,12 @@ class UIHelper {
if (srlHistory.isRefreshing) srlHistory.isRefreshing = false
}
private fun setUtxoList(wallet: Wallet) {
setUtxoListView(wallet)
//if (srlUtxo.isRefreshing) srlHistory.isRefreshing = false
}
fun clearSend() {
this.setSendButtonsActive()
this.displayRecipientAddress(null)
......@@ -1052,6 +1093,7 @@ class UIHelper {
this.opReturnText.text = null
this.slpRecipientAddress.text = null
this.slpAmount.text = null
MainActivity.INSTANCE.walletHelper.selectedUtxos = ArrayList()
MainActivity.INSTANCE.walletHelper.currentTokenId = ""
MainActivity.INSTANCE.walletHelper.currentTokenPosition = 0
setSLPList()
......@@ -1428,6 +1470,59 @@ class UIHelper {
}
}
private fun setUtxoListView(wallet: Wallet?) {
if (wallet != null) {
val utxos = wallet.utxos
utxoMap.clear()
for (x in 0 until utxos.size) {
val utxo = utxos[x]
val utxoMapped = HashMap<String, TransactionOutput>()
utxoMapped["utxo"] = utxo
utxoMap.add(utxoMapped)
}
if(utxoMap.size > 0) {
val itemsAdapter = object : SimpleAdapter(MainActivity.INSTANCE, utxoMap, R.layout.utxo_cell, null, null) {
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
// Get the Item from ListView
val view = LayoutInflater.from(MainActivity.INSTANCE).inflate(R.layout.utxo_cell, null)
val utxo = utxoMap[position]["utxo"]
// Initialize a TextView for ListView each Item
val hash = view.findViewById(R.id.text1) as CheckedTextView
val amountView = view.findViewById(R.id.utxoAmount) as TextView
val amount = utxo!!.value.toPlainString()
val txHash = utxo.parentTransactionHash.toString()
val index = utxo.index
hash.text = "$txHash:$index"
amountView.text = amount
// Set the text color of TextView (ListView Item)
if (nightModeEnabled) {
hash.setTextColor(Color.WHITE)
amountView.setTextColor(Color.GRAY)
} else {
hash.setTextColor(Color.BLACK)
}
hash.ellipsize = TextUtils.TruncateAt.MIDDLE
hash.maxLines = 1
hash.isSingleLine = true
// Generate ListView Item using TextView
return view
}
}
MainActivity.INSTANCE.runOnUiThread { utxoListView.adapter = itemsAdapter }
} else {
MainActivity.INSTANCE.findViewById<TextView>(R.id.no_utxo_text).visibility = View.VISIBLE
MainActivity.INSTANCE.findViewById<SwipeRefreshLayout>(R.id.srlUtxos).visibility = View.GONE
}
}
}
private fun formatBalance(amount: Double, pattern: String): String {
val formatter = DecimalFormat(pattern, DecimalFormatSymbols(Locale.US))
val formattedStr = formatter.format(amount)
......
......@@ -88,6 +88,7 @@ class WalletHelper {
var torProxy: Proxy? = null
var aesKey: KeyParameter? = null
lateinit var currentEcKey: ECKey
var selectedUtxos: ArrayList<TransactionOutput> = ArrayList()
val wallet: Wallet
get() = walletKit!!.wallet()
......@@ -157,50 +158,6 @@ class WalletHelper {
}
if (verifyingRestore) {
try {
val cashAcctAddress = org.bitcoinj.net.NetHelper().getCashAccountAddress(parameters, cashAcctName)
val cashAcctEmoji = netHelper.getCashAccountEmoji(cashAcctName)
println(cashAcctAddress)
var accountAddress: Address? = null
if (Address.isValidCashAddr(parameters, cashAcctAddress)) {
accountAddress = AddressFactory.create().getAddress(MainActivity.INSTANCE.walletHelper.parameters, cashAcctAddress)
} else if (Address.isValidLegacyAddress(parameters, cashAcctAddress)) {
accountAddress = Address.fromBase58(MainActivity.INSTANCE.walletHelper.parameters, cashAcctAddress)
} else {
uiHelper.showToastMessage("No address found!")
}
if (accountAddress != null) {
val isAddressMine = isAddressMine(accountAddress.toString())
if (isAddressMine) {
val pref = MainActivity.INSTANCE.prefs.edit()
pref.putString("cashAccount", cashAcctName)
pref.putString("cashEmoji", cashAcctEmoji)
pref.putBoolean("isNewUser", false)
pref.apply()
MainActivity.INSTANCE.runOnUiThread {
uiHelper.restore_wallet.visibility = View.GONE
uiHelper.displayDownloadContent(true)
uiHelper.myEmoji.text = cashAcctEmoji
uiHelper.showToastMessage("Verified!")
uiHelper.refresh()
}
} else {
walletKit!!.stopAsync()
walletKit = null
MainActivity.INSTANCE.runOnUiThread { uiHelper.showToastMessage("This is not your Cash Account!") }
}
}
} catch (e: NullPointerException) {
if (walletKit != null) {
walletKit!!.stopAsync()
walletKit = null
}
MainActivity.INSTANCE.runOnUiThread { uiHelper.showToastMessage("Cash Account not found.") }
}
} else {
val hasSLPWallet = MainActivity.INSTANCE.prefs.getBoolean("hasSLPWallet", false)
......@@ -486,6 +443,7 @@ class WalletHelper {
req.ensureMinRequiredFee = false
req.aesKey = aesKey
req.utxos = selectedUtxos
req.feePerKb = Coin.valueOf(java.lang.Long.parseLong(1.toString() + "") * 1000L)
if (addOpReturn) {
......
......@@ -50,6 +50,10 @@
android:layout_height="match_parent"
android:visibility="gone" />
<include
layout="@layout/utxos"
android:visibility="gone" />
<include
layout="@layout/manage_key_screen"
android:visibility="gone" />
......
......@@ -37,6 +37,24 @@
android:layout_margin="20dp"
android:orientation="vertical">
<TextView
android:id="@+id/textView3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="5dp"
android:text="Keys"
android:textColor="?attr/textColor"
android:textColorHighlight="@color/colorAccentDark"
android:textIsSelectable="true"
android:textSize="25sp"
android:textStyle="bold" />
<Space
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="10dp" />
<Button
android:id="@+id/btnShowAddresses"
android:layout_width="match_parent"
......@@ -63,6 +81,49 @@
android:layout_height="wrap_content"
android:minHeight="10dp" />
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="5dp"
android:text="UTXOs"
android:textColor="?attr/textColor"
android:textColorHighlight="@color/colorAccentDark"
android:textIsSelectable="true"
android:textSize="25sp"
android:textStyle="bold" />
<Space
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="10dp" />
<Button
android:id="@+id/btnShowUtxos"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bch_wallet_button"
android:text="View UTXOs"
android:textAllCaps="false"
android:textColor="?attr/buttonTextOnWhite" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="5dp"
android:text="View, and select UTXOs here to spend from"
android:textColor="?attr/textColor"
android:textColorHighlight="@color/colorAccentDark"
android:textIsSelectable="true"
android:textSize="16sp" />
<Space
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="10dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
......
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<CheckedTextView
android:id="@+id/text1"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeightSmall"
android:checkMark="?android:attr/listChoiceIndicatorMultiple"
android:gravity="center_vertical"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:textAppearance="?android:attr/textAppearanceListItemSmall" />
<TextView
android:id="@+id/utxoAmount"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:text="TextView" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/utxoWindow"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_weight="1"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:text="UTXOs"
android:textColor="?attr/textColor"
android:textSize="40sp"
android:textStyle="bold" />
<Space
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#353535"
android:minHeight="30dp" />
</LinearLayout>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/srlUtxos"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/backgroundColor"
android:visibility="visible">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@null"
android:isScrollContainer="false">
<app.crescentcash.src.ui.NonScrollListView
android:id="@+id/utxoListView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</ScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<TextView
android:id="@+id/no_utxo_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="75dp"
android:text="This wallet has no UTXOs. :("
android:textSize="16sp"
android:visibility="gone" />
</LinearLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/btnSendUtxos"
android:layout_width="60dp"
android:layout_height="60dp"
app:fabCustomSize="60dp"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
app:srcCompat="@drawable/send"
android:backgroundTint="#22cc76"
android:tint="?attr/buttonTextOnWhite"/>
</FrameLayout>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment