refactor: extract Bip21Parser and PaymentRecord.fromPayment
This commit is contained in:
@@ -175,6 +175,32 @@ data class PaymentRecord(
|
|||||||
val amountSat: Long get() = kotlin.math.abs(amountMsat) / 1000L
|
val amountSat: Long get() = kotlin.math.abs(amountMsat) / 1000L
|
||||||
val feeSat: Long get() = kotlin.math.abs(feeMsat) / 1000L
|
val feeSat: Long get() = kotlin.math.abs(feeMsat) / 1000L
|
||||||
val isOutgoing: Boolean get() = amountMsat < 0
|
val isOutgoing: Boolean get() = amountMsat < 0
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun fromPayment(
|
||||||
|
paymentHash : String,
|
||||||
|
amountSats : Long,
|
||||||
|
feeSats : Long?,
|
||||||
|
bolt11 : String?,
|
||||||
|
memo : String?,
|
||||||
|
pubkey : String?,
|
||||||
|
alias : String?,
|
||||||
|
): PaymentRecord = PaymentRecord(
|
||||||
|
paymentHash = paymentHash,
|
||||||
|
checkingId = paymentHash,
|
||||||
|
amountMsat = -(amountSats * 1_000L),
|
||||||
|
feeMsat = (feeSats ?: 0L) * 1_000L,
|
||||||
|
memo = memo,
|
||||||
|
time = (System.currentTimeMillis() / 1_000L).toString(),
|
||||||
|
status = "complete",
|
||||||
|
bolt11 = bolt11,
|
||||||
|
pending = false,
|
||||||
|
preimage = null,
|
||||||
|
extra = null,
|
||||||
|
pubkey = pubkey,
|
||||||
|
alias = alias,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class PaymentExtra(
|
data class PaymentExtra(
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import com.bitcointxoko.gudariwallet.data.WalletRepository
|
|||||||
import com.bitcointxoko.gudariwallet.ui.SendState
|
import com.bitcointxoko.gudariwallet.ui.SendState
|
||||||
import com.bitcointxoko.gudariwallet.ui.balance.BalanceViewModel
|
import com.bitcointxoko.gudariwallet.ui.balance.BalanceViewModel
|
||||||
import com.bitcointxoko.gudariwallet.util.BiometricHelper
|
import com.bitcointxoko.gudariwallet.util.BiometricHelper
|
||||||
|
import com.bitcointxoko.gudariwallet.util.Bip21Parser
|
||||||
import com.bitcointxoko.gudariwallet.util.LnurlMetadataParser
|
import com.bitcointxoko.gudariwallet.util.LnurlMetadataParser
|
||||||
import com.bitcointxoko.gudariwallet.util.RouteHintAnalyzer
|
import com.bitcointxoko.gudariwallet.util.RouteHintAnalyzer
|
||||||
import com.bitcointxoko.gudariwallet.util.SendInputDetector
|
import com.bitcointxoko.gudariwallet.util.SendInputDetector
|
||||||
@@ -163,7 +164,7 @@ class SendViewModel(
|
|||||||
amountSats = amountSats,
|
amountSats = amountSats,
|
||||||
feeSats = feeSats,
|
feeSats = feeSats,
|
||||||
paymentHash = paymentHash,
|
paymentHash = paymentHash,
|
||||||
pendingRecord = buildPendingRecord(paymentHash, amountSats, feeSats, bolt11, memo, pubkey, alias)
|
pendingRecord = PaymentRecord.fromPayment(paymentHash, amountSats, feeSats, bolt11, memo, pubkey, alias)
|
||||||
)
|
)
|
||||||
balanceVm.refreshBalance()
|
balanceVm.refreshBalance()
|
||||||
}
|
}
|
||||||
@@ -333,7 +334,7 @@ class SendViewModel(
|
|||||||
// ── Scan handlers ────────────────────────────────────────────────────────
|
// ── Scan handlers ────────────────────────────────────────────────────────
|
||||||
|
|
||||||
private fun handleBip21Scan(rawInput: String, strings: SendStrings) {
|
private fun handleBip21Scan(rawInput: String, strings: SendStrings) {
|
||||||
val params = parseBip21Params(rawInput)
|
val params = Bip21Parser.parseParams(rawInput)
|
||||||
val bolt11 = params["lightning"]
|
val bolt11 = params["lightning"]
|
||||||
val lnurl = params["lnurl"] ?: params["lnurlp"]
|
val lnurl = params["lnurl"] ?: params["lnurlp"]
|
||||||
when {
|
when {
|
||||||
@@ -520,42 +521,4 @@ class SendViewModel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseBip21Params(raw: String): Map<String, String> {
|
|
||||||
val query = raw.trim().substringAfter("?", missingDelimiterValue = "")
|
|
||||||
if (query.isBlank()) return emptyMap()
|
|
||||||
return query.split("&").mapNotNull { pair ->
|
|
||||||
val key = pair.substringBefore("=").takeIf { it.isNotBlank() } ?: return@mapNotNull null
|
|
||||||
val value = runCatching {
|
|
||||||
java.net.URLDecoder.decode(
|
|
||||||
pair.substringAfter("=", "").replace("+", " "), "UTF-8"
|
|
||||||
)
|
|
||||||
}.getOrDefault("")
|
|
||||||
key to value
|
|
||||||
}.toMap()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun buildPendingRecord(
|
|
||||||
paymentHash : String,
|
|
||||||
amountSats : Long,
|
|
||||||
feeSats : Long?,
|
|
||||||
bolt11 : String?,
|
|
||||||
memo : String?,
|
|
||||||
pubkey : String?,
|
|
||||||
alias : String?
|
|
||||||
): PaymentRecord = PaymentRecord(
|
|
||||||
paymentHash = paymentHash,
|
|
||||||
checkingId = paymentHash,
|
|
||||||
amountMsat = -(amountSats * 1_000L),
|
|
||||||
feeMsat = (feeSats ?: 0L) * 1_000L,
|
|
||||||
memo = memo,
|
|
||||||
time = (System.currentTimeMillis() / 1_000L).toString(),
|
|
||||||
status = "complete",
|
|
||||||
bolt11 = bolt11,
|
|
||||||
pending = false,
|
|
||||||
preimage = null,
|
|
||||||
extra = null,
|
|
||||||
pubkey = pubkey,
|
|
||||||
alias = alias
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package com.bitcointxoko.gudariwallet.util
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
|
|
||||||
|
object Bip21Parser {
|
||||||
|
/**
|
||||||
|
* Parses the query string from a BIP-21 URI.
|
||||||
|
* Input can be the full URI ("bitcoin:addr?amount=...") or just the query
|
||||||
|
* string ("amount=0.001&label=Foo"). Returns an empty map on malformed input.
|
||||||
|
*/
|
||||||
|
fun parseParams(raw: String): Map<String, String> {
|
||||||
|
val query = if ('?' in raw) raw.substringAfter('?') else raw
|
||||||
|
if (query.isBlank()) return emptyMap()
|
||||||
|
|
||||||
|
return query.split('&')
|
||||||
|
.mapNotNull { pair ->
|
||||||
|
val idx = pair.indexOf('=')
|
||||||
|
if (idx < 1) null
|
||||||
|
else pair.substring(0, idx) to
|
||||||
|
Uri.decode(pair.substring(idx + 1))
|
||||||
|
}
|
||||||
|
.toMap()
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user