diff --git a/runtime/src/main/java/io/novafoundation/nova/runtime/multiNetwork/qr/BitcoinUriQrFormat.kt b/runtime/src/main/java/io/novafoundation/nova/runtime/multiNetwork/qr/BitcoinUriQrFormat.kt new file mode 100644 index 00000000..bf54d9eb --- /dev/null +++ b/runtime/src/main/java/io/novafoundation/nova/runtime/multiNetwork/qr/BitcoinUriQrFormat.kt @@ -0,0 +1,36 @@ +package io.novafoundation.nova.runtime.multiNetwork.qr + +import io.novasama.substrate_sdk_android.encrypt.qr.PublicQrFormat +import io.novasama.substrate_sdk_android.encrypt.qr.QrFormat + +private const val BITCOIN_URI_SCHEME = "bitcoin:" + +/** + * BIP21 URI (`bitcoin:
?amount=...&label=...`) - the standard QR payload most wallets/exchanges generate + * for a Bitcoin receive address. Neither `SubstrateQrFormat` (expects a `substrate:
:` triple) + * nor `AddressQrFormat` (treats the whole QR content as a bare address) recognize this, so scanning an external + * wallet's or exchange's BTC address QR failed outright with the generic "QR can't be decoded" error - confirmed + * live against a real BTC withdrawal QR. + */ +class BitcoinUriQrFormat( + private val addressValidator: (String) -> Boolean +) : PublicQrFormat { + + override fun encode(payload: PublicQrFormat.Payload): String { + return "$BITCOIN_URI_SCHEME${payload.address}" + } + + override fun decode(qrContent: String): PublicQrFormat.Payload { + if (!qrContent.startsWith(BITCOIN_URI_SCHEME, ignoreCase = true)) { + throw QrFormat.InvalidFormatException("Not a bitcoin: URI") + } + + val address = qrContent.substring(BITCOIN_URI_SCHEME.length).substringBefore('?') + + return if (addressValidator(address)) { + PublicQrFormat.Payload(address = address) + } else { + throw QrFormat.InvalidFormatException("Supplied bitcoin: URI has an invalid address") + } + } +} diff --git a/runtime/src/main/java/io/novafoundation/nova/runtime/multiNetwork/qr/MultiChainQrSharingFactory.kt b/runtime/src/main/java/io/novafoundation/nova/runtime/multiNetwork/qr/MultiChainQrSharingFactory.kt index ec55265b..c4561f61 100644 --- a/runtime/src/main/java/io/novafoundation/nova/runtime/multiNetwork/qr/MultiChainQrSharingFactory.kt +++ b/runtime/src/main/java/io/novafoundation/nova/runtime/multiNetwork/qr/MultiChainQrSharingFactory.kt @@ -8,10 +8,12 @@ class MultiChainQrSharingFactory { fun create(addressValidator: (String) -> Boolean): QrSharing { val substrateFormat = SubstrateQrFormat() + val bitcoinUriFormat = BitcoinUriQrFormat(addressValidator) val onlyAddressFormat = AddressQrFormat(addressValidator) val formats = listOf( substrateFormat, + bitcoinUriFormat, onlyAddressFormat )