diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt index 933dda809..ebf820d76 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt @@ -195,7 +195,7 @@ fun uriToRoute( if (isWalletConnectRoute(uri)) { try { val url = UriParser(uri) - val nip47Uri = url.getQueryParameter("value") + val nip47Uri = url.getQueryParameter("value")?.firstOrNull() if (nip47Uri != null) { Nip47WalletConnect.parse(nip47Uri) return Route.Nip47NWCSetup(nip47Uri) diff --git a/quartz/src/appleMain/kotlin/com/vitorpamplona/quartz/utils/UriParser.apple.kt b/quartz/src/appleMain/kotlin/com/vitorpamplona/quartz/utils/UriParser.apple.kt index ba0890c38..d3348d221 100644 --- a/quartz/src/appleMain/kotlin/com/vitorpamplona/quartz/utils/UriParser.apple.kt +++ b/quartz/src/appleMain/kotlin/com/vitorpamplona/quartz/utils/UriParser.apple.kt @@ -45,9 +45,15 @@ actual class UriParser actual constructor( return queryItems.mapNotNull { (it as? NSURLQueryItem)?.name }.toSet() } - actual fun getQueryParameter(param: String): String? { + actual fun getQueryParameter(param: String): List? { 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 by lazy { diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip47WalletConnect/Nip47WalletConnect.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip47WalletConnect/Nip47WalletConnect.kt index 73a106017..ef7a07c42 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip47WalletConnect/Nip47WalletConnect.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip47WalletConnect/Nip47WalletConnect.kt @@ -63,10 +63,10 @@ class Nip47WalletConnect { 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 secret = url.getQueryParameter("secret") - val lud16 = url.getQueryParameter("lud16") + val secret = url.getQueryParameter("secret")?.firstOrNull() + val lud16 = url.getQueryParameter("lud16")?.firstOrNull() return Nip47URINorm(pubkeyHex, relayNorm, secret, lud16) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/UriParser.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/UriParser.kt index ebcb561a4..c78c932ef 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/UriParser.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/UriParser.kt @@ -33,7 +33,7 @@ expect class UriParser( fun queryParameterNames(): Set - fun getQueryParameter(param: String): String? + fun getQueryParameter(param: String): List? fun fragments(): Map } diff --git a/quartz/src/jvmAndroid/kotlin/com/vitorpamplona/quartz/utils/UriParser.jvmAndroid.kt b/quartz/src/jvmAndroid/kotlin/com/vitorpamplona/quartz/utils/UriParser.jvmAndroid.kt index 3e75d0dc8..ac6fbaef7 100644 --- a/quartz/src/jvmAndroid/kotlin/com/vitorpamplona/quartz/utils/UriParser.jvmAndroid.kt +++ b/quartz/src/jvmAndroid/kotlin/com/vitorpamplona/quartz/utils/UriParser.jvmAndroid.kt @@ -22,22 +22,32 @@ package com.vitorpamplona.quartz.utils import java.net.URI import java.net.URLDecoder +import kotlin.getValue actual class UriParser actual constructor( uri: String, ) { private val myUri = URI.create(uri) - private val queryParameters: Map by lazy { - myUri.query?.ifBlank { null }?.let { query -> - query.split('&').associate { paramValue -> + private val queryParameters: Map> by lazy { + myUri.rawQuery?.ifBlank { null }?.let { query -> + val params = mutableMapOf>() + + query.split('&').forEach { paramValue -> val parts = paramValue.split("=", limit = 2) + val currentValue = + params.getOrPut(parts[0]) { + mutableListOf() + } + if (parts.size == 2) { - parts[0] to URLDecoder.decode(parts[1], "UTF-8") + currentValue.add(URLDecoder.decode(parts[1], "UTF-8")) } else { - parts[0] to "" // Handle parameters without a value + currentValue.add("") } } + + params } ?: emptyMap() } @@ -67,7 +77,7 @@ actual class UriParser actual constructor( actual fun queryParameterNames(): Set = queryParameters.keys - actual fun getQueryParameter(param: String): String? = queryParameters[param] + actual fun getQueryParameter(param: String): List? = queryParameters[param] actual fun fragments(): Map = fragments } diff --git a/quartz/src/linuxMain/kotlin/com/vitorpamplona/quartz/utils/UriParser.linux.kt b/quartz/src/linuxMain/kotlin/com/vitorpamplona/quartz/utils/UriParser.linux.kt index dbbc792cc..5f5d9f0c2 100644 --- a/quartz/src/linuxMain/kotlin/com/vitorpamplona/quartz/utils/UriParser.linux.kt +++ b/quartz/src/linuxMain/kotlin/com/vitorpamplona/quartz/utils/UriParser.linux.kt @@ -125,20 +125,20 @@ actual class UriParser actual constructor( val query = parsedQuery ?: return emptySet() return query .split('&') - .mapNotNull { param -> + .map { param -> val eqIndex = param.indexOf('=') if (eqIndex >= 0) param.substring(0, eqIndex) else param }.toSet() } - actual fun getQueryParameter(param: String): String? { + actual fun getQueryParameter(param: String): List? { val query = parsedQuery ?: return null return query .split('&') - .firstOrNull { part -> + .filter { part -> val eqIndex = part.indexOf('=') if (eqIndex >= 0) part.substring(0, eqIndex) == param else part == param - }?.let { part -> + }.map { part -> val eqIndex = part.indexOf('=') if (eqIndex >= 0) part.substring(eqIndex + 1) else "" }