mirror of
https://github.com/pezkuwichain/pezkuwi-wallet-android.git
synced 2026-07-22 21:55:53 +00:00
fix: recognize BIP21 bitcoin: URIs when scanning a QR code
Confirmed live: sending BTC back out via QR-scanning an external wallet's/ exchange's receive address failed with a generic "QR can't be decoded" error. Root cause: the QR decoder only ever recognized two shapes - substrate:<address>:<pubkey> triples and bare address strings - neither of which matches the bitcoin:<address>?amount=... BIP21 URI most wallets and exchanges generate for a BTC address. Adds BitcoinUriQrFormat, tried alongside the existing formats, that strips the scheme and query string before validating the address the normal way.
This commit is contained in:
+36
@@ -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:<address>?amount=...&label=...`) - the standard QR payload most wallets/exchanges generate
|
||||
* for a Bitcoin receive address. Neither `SubstrateQrFormat` (expects a `substrate:<address>:<pubkey>` 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")
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
@@ -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
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user