Fixes Wallet import encoding bug

This commit is contained in:
Vitor Pamplona
2026-03-31 19:10:15 -04:00
parent 69099728b2
commit 48d90a8252
6 changed files with 33 additions and 17 deletions
@@ -195,7 +195,7 @@ fun uriToRoute(
if (isWalletConnectRoute(uri)) { if (isWalletConnectRoute(uri)) {
try { try {
val url = UriParser(uri) val url = UriParser(uri)
val nip47Uri = url.getQueryParameter("value") val nip47Uri = url.getQueryParameter("value")?.firstOrNull()
if (nip47Uri != null) { if (nip47Uri != null) {
Nip47WalletConnect.parse(nip47Uri) Nip47WalletConnect.parse(nip47Uri)
return Route.Nip47NWCSetup(nip47Uri) return Route.Nip47NWCSetup(nip47Uri)
@@ -45,9 +45,15 @@ actual class UriParser actual constructor(
return queryItems.mapNotNull { (it as? NSURLQueryItem)?.name }.toSet() return queryItems.mapNotNull { (it as? NSURLQueryItem)?.name }.toSet()
} }
actual fun getQueryParameter(param: String): String? { actual fun getQueryParameter(param: String): List<String>? {
val queryItems = nsUrlComponents.queryItems ?: return null val queryItems = nsUrlComponents.queryItems ?: return null
return (queryItems.firstOrNull { (it as? NSURLQueryItem)?.name == param } as? NSURLQueryItem)?.value return queryItems.mapNotNull {
if ((it as? NSURLQueryItem)?.name == param) {
it.value
} else {
null
}
}
} }
val fragments: Map<String, String> by lazy { val fragments: Map<String, String> by lazy {
@@ -63,10 +63,10 @@ class Nip47WalletConnect {
throw IllegalArgumentException("Hostname is not a valid Nostr Pubkey") throw IllegalArgumentException("Hostname is not a valid Nostr Pubkey")
} }
val relay = url.getQueryParameter("relay") ?: throw IllegalArgumentException("Relay cannot be null") val relay = url.getQueryParameter("relay")?.firstOrNull() ?: throw IllegalArgumentException("Relay cannot be null")
val relayNorm = RelayUrlNormalizer.normalizeOrNull(relay) ?: throw IllegalArgumentException("Invalid relay Url") val relayNorm = RelayUrlNormalizer.normalizeOrNull(relay) ?: throw IllegalArgumentException("Invalid relay Url")
val secret = url.getQueryParameter("secret") val secret = url.getQueryParameter("secret")?.firstOrNull()
val lud16 = url.getQueryParameter("lud16") val lud16 = url.getQueryParameter("lud16")?.firstOrNull()
return Nip47URINorm(pubkeyHex, relayNorm, secret, lud16) return Nip47URINorm(pubkeyHex, relayNorm, secret, lud16)
} }
@@ -33,7 +33,7 @@ expect class UriParser(
fun queryParameterNames(): Set<String> fun queryParameterNames(): Set<String>
fun getQueryParameter(param: String): String? fun getQueryParameter(param: String): List<String>?
fun fragments(): Map<String, String> fun fragments(): Map<String, String>
} }
@@ -22,22 +22,32 @@ package com.vitorpamplona.quartz.utils
import java.net.URI import java.net.URI
import java.net.URLDecoder import java.net.URLDecoder
import kotlin.getValue
actual class UriParser actual constructor( actual class UriParser actual constructor(
uri: String, uri: String,
) { ) {
private val myUri = URI.create(uri) private val myUri = URI.create(uri)
private val queryParameters: Map<String, String> by lazy { private val queryParameters: Map<String, List<String>> by lazy {
myUri.query?.ifBlank { null }?.let { query -> myUri.rawQuery?.ifBlank { null }?.let { query ->
query.split('&').associate { paramValue -> val params = mutableMapOf<String, MutableList<String>>()
query.split('&').forEach { paramValue ->
val parts = paramValue.split("=", limit = 2) val parts = paramValue.split("=", limit = 2)
val currentValue =
params.getOrPut(parts[0]) {
mutableListOf()
}
if (parts.size == 2) { if (parts.size == 2) {
parts[0] to URLDecoder.decode(parts[1], "UTF-8") currentValue.add(URLDecoder.decode(parts[1], "UTF-8"))
} else { } else {
parts[0] to "" // Handle parameters without a value currentValue.add("")
} }
} }
params
} ?: emptyMap() } ?: emptyMap()
} }
@@ -67,7 +77,7 @@ actual class UriParser actual constructor(
actual fun queryParameterNames(): Set<String> = queryParameters.keys actual fun queryParameterNames(): Set<String> = queryParameters.keys
actual fun getQueryParameter(param: String): String? = queryParameters[param] actual fun getQueryParameter(param: String): List<String>? = queryParameters[param]
actual fun fragments(): Map<String, String> = fragments actual fun fragments(): Map<String, String> = fragments
} }
@@ -125,20 +125,20 @@ actual class UriParser actual constructor(
val query = parsedQuery ?: return emptySet() val query = parsedQuery ?: return emptySet()
return query return query
.split('&') .split('&')
.mapNotNull { param -> .map { param ->
val eqIndex = param.indexOf('=') val eqIndex = param.indexOf('=')
if (eqIndex >= 0) param.substring(0, eqIndex) else param if (eqIndex >= 0) param.substring(0, eqIndex) else param
}.toSet() }.toSet()
} }
actual fun getQueryParameter(param: String): String? { actual fun getQueryParameter(param: String): List<String>? {
val query = parsedQuery ?: return null val query = parsedQuery ?: return null
return query return query
.split('&') .split('&')
.firstOrNull { part -> .filter { part ->
val eqIndex = part.indexOf('=') val eqIndex = part.indexOf('=')
if (eqIndex >= 0) part.substring(0, eqIndex) == param else part == param if (eqIndex >= 0) part.substring(0, eqIndex) == param else part == param
}?.let { part -> }.map { part ->
val eqIndex = part.indexOf('=') val eqIndex = part.indexOf('=')
if (eqIndex >= 0) part.substring(eqIndex + 1) else "" if (eqIndex >= 0) part.substring(eqIndex + 1) else ""
} }