Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/src/main/java/to/bitkit/services/LightningService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -311,10 +311,10 @@ class LightningService @Inject constructor(
return ServiceQueue.LDK.background {
if (sat != null) {
Logger.debug("Creating bolt11 for $sat sats")
node.bolt11Payment().receive(sat.millis, description, expirySecs)
node.bolt11Payment().receive(sat.millis, description.ifBlank { "Bitkit" }, expirySecs)
} else {
Logger.debug("Creating bolt11 for variable amount")
node.bolt11Payment().receiveVariableAmount(description, expirySecs)
node.bolt11Payment().receiveVariableAmount(description.ifBlank { "Bitkit" }, expirySecs)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
Expand Down Expand Up @@ -395,7 +396,14 @@ private fun CopyAddressCard(
.fillMaxWidth()
.padding(24.dp)
) {
Caption13Up(text = title, color = Colors.White64)
Row {
Caption13Up(text = title, color = Colors.White64)

Spacer(modifier = Modifier.width(3.dp))

val iconRes = if (type == CopyAddressType.ONCHAIN) R.drawable.ic_bitcoin else R.drawable.ic_lightning_alt
Icon(painter = painterResource(iconRes), contentDescription = null, tint = Colors.White64)
}
Spacer(modifier = Modifier.height(16.dp))
BodyS(text = address.truncate(32).uppercase())
Spacer(modifier = Modifier.height(16.dp))
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/to/bitkit/utils/Bip21Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ object Bip21Utils {
bitcoinAddress: String,
amountSats: ULong? = null,
label: String? = null,
message: String? = null,
message: String? = "Bitkit",
lightningInvoice: String? = null
): String {
val builder = StringBuilder("bitcoin:$bitcoinAddress")
Expand Down
12 changes: 8 additions & 4 deletions app/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ class WalletViewModel @Inject constructor(
}
}

updateBip21Invoice(description = "Bitkit")
updateBip21Invoice()
}

fun disconnectPeer(peer: LnPeer) {
Expand Down Expand Up @@ -307,7 +307,7 @@ class WalletViewModel @Inject constructor(

fun updateBip21Invoice(
amountSats: ULong? = null,
description: String
description: String = ""
) {
viewModelScope.launch(Dispatchers.IO) {
val hasChannels = lightningService.channels.hasChannels()
Expand All @@ -321,7 +321,7 @@ class WalletViewModel @Inject constructor(
val newBip21 = Bip21Utils.buildBip21Url(
bitcoinAddress = _onchainAddress,
amountSats = amountSats,
message = description.ifBlank { "Bitkit" },
message = description.ifBlank { DEFAULT_INVOICE_MESSAGE },
lightningInvoice = _bolt11
)
_bip21 = newBip21
Expand All @@ -336,7 +336,7 @@ class WalletViewModel @Inject constructor(
description: String,
expirySeconds: UInt = 86_400u, // 1 day
): String {
return lightningService.receive(amountSats, description, expirySeconds)
return lightningService.receive(amountSats, description.ifBlank { DEFAULT_INVOICE_MESSAGE }, expirySeconds)
}

fun openChannel() {
Expand Down Expand Up @@ -517,6 +517,10 @@ class WalletViewModel @Inject constructor(
}

private fun List<ChannelDetails>?.hasChannels() = this?.isNotEmpty() == true

private companion object {
const val DEFAULT_INVOICE_MESSAGE = "Bitkit"
}
}

// region state
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/res/drawable/ic_bitcoin.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="17dp"
android:viewportWidth="16"
android:viewportHeight="17">
<path
android:pathData="M13.05,7.128C13.27,5.657 12.15,4.866 10.618,4.339L11.115,2.346L9.902,2.044L9.418,3.984C9.099,3.905 8.772,3.83 8.446,3.755L8.933,1.802L7.721,1.5L7.224,3.492C6.96,3.432 6.701,3.373 6.449,3.31L6.45,3.304L4.778,2.886L4.455,4.182C4.455,4.182 5.355,4.388 5.336,4.401C5.827,4.524 5.916,4.849 5.901,5.106L5.335,7.377C5.369,7.385 5.413,7.397 5.461,7.417C5.421,7.407 5.378,7.396 5.333,7.385L4.54,10.565C4.48,10.715 4.327,10.939 3.984,10.853C3.996,10.871 3.102,10.633 3.102,10.633L2.5,12.022L4.078,12.415C4.372,12.489 4.66,12.566 4.943,12.638L4.442,14.654L5.653,14.956L6.15,12.962C6.482,13.052 6.803,13.135 7.117,13.213L6.622,15.198L7.835,15.5L8.337,13.488C10.406,13.88 11.961,13.722 12.616,11.851C13.143,10.345 12.59,9.476 11.501,8.909C12.294,8.726 12.891,8.205 13.05,7.128ZM10.279,11.015C9.904,12.521 7.368,11.707 6.545,11.502L7.211,8.832C8.033,9.037 10.67,9.444 10.279,11.015ZM10.653,7.107C10.312,8.477 8.201,7.781 7.516,7.61L8.12,5.188C8.804,5.359 11.01,5.677 10.653,7.107Z"
android:fillColor="#ffffff"
android:fillAlpha="0.64"/>
</vector>
10 changes: 10 additions & 0 deletions app/src/main/res/drawable/ic_lightning_alt.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:pathData="M3.998,9.234H7.694L5.759,14.232C5.485,14.919 6.225,15.287 6.698,14.726L12.659,7.643C12.771,7.504 12.833,7.372 12.833,7.221C12.833,6.956 12.622,6.763 12.336,6.763H8.64L10.575,1.765C10.842,1.078 10.108,0.717 9.635,1.271L3.674,8.354C3.556,8.493 3.5,8.626 3.5,8.776C3.5,9.042 3.712,9.234 3.998,9.234Z"
android:fillColor="#ffffff"
android:fillAlpha="0.64"/>
</vector>
18 changes: 9 additions & 9 deletions app/src/test/java/to/bitkit/utils/Bip21UrlBuilderTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,31 @@ class Bip21UrlBuilderTest {
@Test
fun `basic address without parameters`() {
val address = "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq"
val expected = "bitcoin:$address"
val expected = "bitcoin:$address?message=Bitkit"
Assert.assertEquals(expected, buildBip21Url(address))
}

@Test
fun `address with amount in sats`() {
val address = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
val amount = 100000uL // 0.001 BTC
val expected = "bitcoin:$address?amount=0.001"
val expected = "bitcoin:$address?amount=0.001&message=Bitkit"
Assert.assertEquals(expected, buildBip21Url(address, amount))
}

@Test
fun `amount with exact 1 BTC`() {
val address = "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq"
val amount = 100000000uL
val expected = "bitcoin:$address?amount=1"
val expected = "bitcoin:$address?amount=1&message=Bitkit"
Assert.assertEquals(expected, buildBip21Url(address, amount))
}

@Test
fun `amount with fractional sats rounds correctly`() {
val address = "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq"
val amount = 12345678uL
val expected = "bitcoin:$address?amount=0.12345678"
val expected = "bitcoin:$address?amount=0.12345678&message=Bitkit"
Assert.assertEquals(expected, buildBip21Url(address, amount))
}

Expand All @@ -64,7 +64,7 @@ class Bip21UrlBuilderTest {
fun `address with lightning parameter`() {
val address = "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq"
val invoice = "lnbc500n1p3k9v3pp5kzmj..."
val expected = "bitcoin:$address?lightning=${invoice.encodeToUrl()}"
val expected = "bitcoin:$address?message=Bitkit&lightning=${invoice.encodeToUrl()}"
Assert.assertEquals(expected, buildBip21Url(address, lightningInvoice = invoice))
}

Expand Down Expand Up @@ -105,23 +105,23 @@ class Bip21UrlBuilderTest {
fun `zero sats is handled correctly`() {
val address = "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq"
val amount = 0uL
val expected = "bitcoin:$address?amount=0"
val expected = "bitcoin:$address?amount=0&message=Bitkit"
Assert.assertEquals(expected, buildBip21Url(address, amount))
}

@Test
fun `maximum ULong value is handled correctly`() {
val address = "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq"
val amount = ULong.MAX_VALUE
val expected = "bitcoin:$address?amount=184467440737.09551615"
val expected = "bitcoin:$address?amount=184467440737.09551615&message=Bitkit"
Assert.assertEquals(expected, buildBip21Url(address, amount))
}

@Test
fun `lightning parameter without other parameters`() {
val address = "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq"
val invoice = "lnbc100n1p3k9v3pp5kzmj..."
val expected = "bitcoin:$address?lightning=${invoice.encodeToUrl()}"
val expected = "bitcoin:$address?message=Bitkit&lightning=${invoice.encodeToUrl()}"
Assert.assertEquals(expected, buildBip21Url(address, lightningInvoice = invoice))
}

Expand All @@ -130,7 +130,7 @@ class Bip21UrlBuilderTest {
val address = "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq"
val amount = 10000uL
val invoice = "lnbc100n1p3k9v3pp5kzmj..."
val expected = "bitcoin:$address?amount=0.0001&lightning=${invoice.encodeToUrl()}"
val expected = "bitcoin:$address?amount=0.0001&message=Bitkit&lightning=${invoice.encodeToUrl()}"
Assert.assertEquals(expected, buildBip21Url(address, amount, lightningInvoice = invoice))
}
}