Add PQ spend source selection and live transaction fixes

This commit is contained in:
Vexta Project 2026-09-08 21:03:28 +00:00
commit d7fa096714
3 changed files with 88 additions and 15 deletions

View file

@ -23,8 +23,8 @@ android {
applicationId = "org.vextaproject.wallet" applicationId = "org.vextaproject.wallet"
minSdk = 26 minSdk = 26
targetSdk = 36 targetSdk = 36
versionCode = 38 versionCode = 39
versionName = "0.6.8" versionName = "0.7.0"
} }
signingConfigs { signingConfigs {

View file

@ -3627,7 +3627,7 @@ class WalletActivity : FragmentActivity() {
symbol = "↑", symbol = "↑",
label = "Send" label = "Send"
) { ) {
showSend(address) showSend()
} }
) )
@ -4915,12 +4915,12 @@ class WalletActivity : FragmentActivity() {
contactsDialog.show() contactsDialog.show()
} }
private fun showSend(fromAddress: String) { private fun showSend() {
mainWalletVisible = false mainWalletVisible = false
window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE) window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
val recipientInput = inputField( val recipientInput = inputField(
hint = "Recipient address (vtx1... or legacy V...)", hint = "Recipient Vexta address",
singleLine = false singleLine = false
) )
@ -4938,6 +4938,67 @@ class WalletActivity : FragmentActivity() {
"directly to the Vexta network." "directly to the Vexta network."
) )
var spendFromType: BlockScanner.AddressType? = null
fun selectedSpendableUtxos():
List<BlockScanner.SpendableUtxo> {
return if (spendFromType == null) {
latestSpendableUtxos
} else {
latestSpendableUtxos.filter {
it.addressType == spendFromType
}
}
}
lateinit var spendFromButton: Button
spendFromButton =
secondaryButton("Spend from: Any") {
val options =
arrayOf(
"Any",
"Standard",
"ML-DSA",
"SPHINCS+"
)
AlertDialog.Builder(this@WalletActivity)
.setTitle("Spend from")
.setItems(options) { _, which ->
spendFromType =
when (which) {
0 -> null
1 ->
BlockScanner.AddressType.STANDARD
2 ->
BlockScanner.AddressType.MLDSA
3 ->
BlockScanner.AddressType.SLHDSA
else -> null
}
spendFromButton.text =
"Spend from: ${options[which]}"
val available =
selectedSpendableUtxos()
.sumOf { it.value }
noteView.text =
"Selected source: ${options[which]}\n" +
"Available: " +
String.format(
java.util.Locale.US,
"%.8f VTX",
available.toDouble() /
100_000_000.0
)
}
.setNegativeButton("Cancel", null)
.show()
}
val content = baseLayout() val content = baseLayout()
content.addView(space(10)) content.addView(space(10))
content.addView(centeredLogo(72)) content.addView(centeredLogo(72))
@ -4948,9 +5009,9 @@ class WalletActivity : FragmentActivity() {
content.addView( content.addView(
card { card {
addView(sectionTitle("From")) addView(sectionTitle("Spend source"))
addView(space(10)) addView(space(10))
addView(infoBox(fromAddress, 15f, Gravity.CENTER)) addView(spendFromButton)
} }
) )
@ -5028,7 +5089,7 @@ class WalletActivity : FragmentActivity() {
try { try {
val maxSpend = val maxSpend =
VextaTransactionSender.calculateMaxSpend( VextaTransactionSender.calculateMaxSpend(
latestSpendableUtxos, selectedSpendableUtxos(),
latestChainHeight latestChainHeight
) )
@ -5126,11 +5187,14 @@ class WalletActivity : FragmentActivity() {
return@primaryButton return@primaryButton
} }
if (latestSpendableUtxos.isEmpty()) { val spendableUtxos =
selectedSpendableUtxos()
if (spendableUtxos.isEmpty()) {
Toast.makeText( Toast.makeText(
this@WalletActivity, this@WalletActivity,
"No verified spendable outputs are loaded. " + "No verified spendable outputs are available " +
"Return to the wallet and scan the blockchain.", "for the selected source.",
Toast.LENGTH_LONG Toast.LENGTH_LONG
).show() ).show()
return@primaryButton return@primaryButton
@ -5146,7 +5210,7 @@ class WalletActivity : FragmentActivity() {
.split(Regex("\\s+")) .split(Regex("\\s+"))
val privateKeysByIndex = val privateKeysByIndex =
latestSpendableUtxos spendableUtxos
.filter { .filter {
it.addressType == it.addressType ==
BlockScanner.AddressType.STANDARD BlockScanner.AddressType.STANDARD
@ -5168,7 +5232,7 @@ class WalletActivity : FragmentActivity() {
val transaction = val transaction =
try { try {
latestSpendableUtxos spendableUtxos
.filter { .filter {
it.addressType != it.addressType !=
BlockScanner.AddressType.STANDARD BlockScanner.AddressType.STANDARD
@ -5225,7 +5289,7 @@ class WalletActivity : FragmentActivity() {
VextaTransactionSender.createAndSign( VextaTransactionSender.createAndSign(
spendableUtxos = spendableUtxos =
latestSpendableUtxos, spendableUtxos,
recipientAddress = recipient, recipientAddress = recipient,
amountSatoshis = amountSatoshis, amountSatoshis = amountSatoshis,
privateKeysByIndex = privateKeysByIndex =

View file

@ -391,7 +391,16 @@ class WalletMonitoringService : Service() {
} }
.filter { it.netSatoshis != 0L } .filter { it.netSatoshis != 0L }
if (fullScanRequired) { val notificationsInitialized =
preferences.getBoolean(
PREF_TX_NOTIFICATIONS_INITIALIZED,
false
)
if (
fullScanRequired &&
!notificationsInitialized
) {
synchronizeKnownIncomingTransactions( synchronizeKnownIncomingTransactions(
mergedTransactions mergedTransactions
) )