Skip to content

Commit

Permalink
Implement support for Unified QRs for Bitcoin
Browse files Browse the repository at this point in the history
  • Loading branch information
AleksandarIlic committed Feb 15, 2024
1 parent f6cf8d9 commit 32f76de
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,19 +82,11 @@ class SendPaymentViewModel @Inject constructor(
val userId = activeAccountStore.activeUserId()
try {
when (text.parseRecipientType()) {
RecipientType.LnInvoice -> handleLnInvoiceText(userId = userId, text = text)
RecipientType.LnUrl -> handleLnUrlText(userId = userId, text = text)
RecipientType.LnAddress -> handleLightningAddressText(userId = userId, text = text)
RecipientType.LightningUri -> {
val path = text.split(":").last()
when {
path.isLightningAddress() -> handleLightningAddressText(userId = userId, text = path)
path.isLnUrl() -> handleLnUrlText(userId = userId, text = path)
path.isLnInvoice() -> handleLnInvoiceText(userId = userId, text = path)
}
}
RecipientType.BitcoinAddress -> handleBitcoinAddressText(text = text)
null -> Unit
RecipientType.LnInvoice -> handleLnInvoiceText(userId, text)
RecipientType.LnUrl -> handleLnUrlText(userId, text)
RecipientType.LnAddress -> handleLightningAddressText(userId, text)
RecipientType.BitcoinAddress, RecipientType.BitcoinAddressUri -> handleBitcoinText(text = text)
null -> Timber.w("Unknown text type. [text=$text]")
}
} catch (error: WssException) {
Timber.w(error)
Expand Down Expand Up @@ -161,7 +153,7 @@ class SendPaymentViewModel @Inject constructor(
}
}

private fun handleBitcoinAddressText(text: String) {
private fun handleBitcoinText(text: String) {
val btcInstructions = text.parseBitcoinPaymentInstructions()
if (btcInstructions != null) {
setEffect(
Expand All @@ -182,12 +174,29 @@ class SendPaymentViewModel @Inject constructor(
isLnInvoice() -> RecipientType.LnInvoice
isLnUrl() -> RecipientType.LnUrl
isLightningAddress() -> RecipientType.LnAddress
isLightningAddressUri() -> RecipientType.LightningUri
isBitcoinAddress() || isBitcoinAddressUri() -> RecipientType.BitcoinAddress
isLightningAddressUri() -> {
val path = this.split(":").last()
path.parseLightningRecipientType()
}

isBitcoinAddress() -> RecipientType.BitcoinAddress
isBitcoinAddressUri() -> {
val parsedBitcoinUri = this.parseBitcoinPaymentInstructions()
return parsedBitcoinUri?.lightning?.parseLightningRecipientType() ?: RecipientType.BitcoinAddressUri
}

else -> null
}
}

private fun String.parseLightningRecipientType(): RecipientType? =
when {
this.isLightningAddress() -> RecipientType.LnAddress
this.isLnUrl() -> RecipientType.LnUrl
this.isLnInvoice() -> RecipientType.LnInvoice
else -> null
}

private fun processProfileData(profileId: String) =
viewModelScope.launch {
val profileData = withContext(dispatchers.io()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ enum class RecipientType {
LnInvoice,
LnUrl,
LnAddress,
LightningUri,
BitcoinAddress,
BitcoinAddressUri,
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ package net.primal.android.wallet.utils

data class BitcoinPaymentInstruction(
val address: String,
val lightning: String? = null,
val amount: String? = null,
val label: String? = null,
) {
fun hasParams() = amount != null || label != null
fun hasParams() = amount != null || label != null || lightning != null
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,12 @@ fun String.parseBitcoinPaymentInstructions(): BitcoinPaymentInstruction? {
val labelParam = params?.find { it.startsWith("label") }
val label = labelParam?.split("=")?.lastOrNull()?.asUrlDecoded()

val lightningParam = params?.find { it.startsWith("lightning") }
val lightning = lightningParam?.split("=")?.lastOrNull()

BitcoinPaymentInstruction(
address = address,
lightning = lightning,
amount = amount,
label = label,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,4 +171,19 @@ class WalletStringUtilsTest {
amount = "1.23",
)
}

@Test
fun parseBitcoinPaymentInstruction_shouldReturnBtcAddressAndLightningAddressAndAmountAndLabelIfInputsAreValid() {
("bitcoin:bc1q99ygnq68xrvqd9up7vgapnytwmss4am6ytessw" +
"?lightning=$validLnInvoice" +
"&amount=1.234567" +
"&label=This+is+very+long+comment."
).parseBitcoinPaymentInstructions() shouldBe
BitcoinPaymentInstruction(
address = "bc1q99ygnq68xrvqd9up7vgapnytwmss4am6ytessw",
lightning = validLnInvoice,
amount = "1.234567",
label = "This is very long comment.",
)
}
}

0 comments on commit 32f76de

Please sign in to comment.