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 feeSat: Long get() = kotlin.math.abs(feeMsat) / 1000L
|
||||
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(
|
||||
|
||||
@@ -13,6 +13,7 @@ import com.bitcointxoko.gudariwallet.data.WalletRepository
|
||||
import com.bitcointxoko.gudariwallet.ui.SendState
|
||||
import com.bitcointxoko.gudariwallet.ui.balance.BalanceViewModel
|
||||
import com.bitcointxoko.gudariwallet.util.BiometricHelper
|
||||
import com.bitcointxoko.gudariwallet.util.Bip21Parser
|
||||
import com.bitcointxoko.gudariwallet.util.LnurlMetadataParser
|
||||
import com.bitcointxoko.gudariwallet.util.RouteHintAnalyzer
|
||||
import com.bitcointxoko.gudariwallet.util.SendInputDetector
|
||||
@@ -163,7 +164,7 @@ class SendViewModel(
|
||||
amountSats = amountSats,
|
||||
feeSats = feeSats,
|
||||
paymentHash = paymentHash,
|
||||
pendingRecord = buildPendingRecord(paymentHash, amountSats, feeSats, bolt11, memo, pubkey, alias)
|
||||
pendingRecord = PaymentRecord.fromPayment(paymentHash, amountSats, feeSats, bolt11, memo, pubkey, alias)
|
||||
)
|
||||
balanceVm.refreshBalance()
|
||||
}
|
||||
@@ -333,7 +334,7 @@ class SendViewModel(
|
||||
// ── Scan handlers ────────────────────────────────────────────────────────
|
||||
|
||||
private fun handleBip21Scan(rawInput: String, strings: SendStrings) {
|
||||
val params = parseBip21Params(rawInput)
|
||||
val params = Bip21Parser.parseParams(rawInput)
|
||||
val bolt11 = params["lightning"]
|
||||
val lnurl = params["lnurl"] ?: params["lnurlp"]
|
||||
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