Uses the new nostrnwc deep link for connections

This commit is contained in:
Vitor Pamplona
2025-10-24 17:53:31 -04:00
parent a157c60697
commit 67e3b05a42
6 changed files with 71 additions and 28 deletions

View File

@@ -89,6 +89,7 @@
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="nostr" />
<data android:scheme="amethyst" />
</intent-filter>
<intent-filter android:label="Amethyst">
@@ -103,6 +104,7 @@
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="nostrwalletconnect" />
<data android:scheme="nostr+walletconnect" />
<data android:scheme="amethyst+walletconnect" />
</intent-filter>
<intent-filter android:label="New Post">

View File

@@ -50,6 +50,7 @@ import com.vitorpamplona.quartz.nip19Bech32.entities.NProfile
import com.vitorpamplona.quartz.nip19Bech32.entities.NPub
import com.vitorpamplona.quartz.nip47WalletConnect.Nip47WalletConnect
import com.vitorpamplona.quartz.utils.Log
import com.vitorpamplona.quartz.utils.UriParser
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
@@ -126,20 +127,28 @@ class MainActivity : AppCompatActivity() {
}
}
fun isNotificationRoute(uri: String) = uri.startsWith("notifications", true) || uri.startsWith("nostr:notifications", true)
fun isHashtagRoute(uri: String) = uri.startsWith("hashtag?id=") || uri.startsWith("nostr:hashtag?id=")
fun isWalletConnectRoute(uri: String) = uri.startsWith("dlnwc?value=") || uri.startsWith("amethyst+walletconnect:dlnwc?value=") || uri.startsWith("amethyst+walletconnect://dlnwc?value=")
fun uriToRoute(
uri: String?,
uri: String,
account: Account,
): Route? =
if (uri?.startsWith("notifications", true) == true || uri?.startsWith("nostr:notifications", true) == true) {
Route.Notification
} else {
if (uri?.startsWith("hashtag?id=") == true || uri?.startsWith("nostr:hashtag?id=") == true) {
Route.Hashtag(uri.removePrefix("nostr:").removePrefix("hashtag?id="))
} else {
): Route? {
if (isNotificationRoute(uri)) {
return Route.Notification
}
if (isHashtagRoute(uri)) {
return Route.Hashtag(uri.removePrefix("nostr:").removePrefix("hashtag?id="))
}
val nip19 = Nip19Parser.uriToRoute(uri)?.entity
if (nip19 != null) {
LocalCache.consume(nip19)
}
val route =
when (nip19) {
is NPub -> Route.Profile(nip19.hex)
is NProfile -> Route.Profile(nip19.hex)
@@ -175,14 +184,27 @@ fun uriToRoute(
else -> null
}
if (route != null) {
return route
}
?: try {
uri?.let {
Nip47WalletConnect.parse(it)
Route.Nip47NWCSetup(it)
}
if (isWalletConnectRoute(uri)) {
val url = UriParser(uri)
val nip47Uri = url.getQueryParameter("value")
if (nip47Uri != null) {
Nip47WalletConnect.parse(nip47Uri)
return Route.Nip47NWCSetup(nip47Uri)
}
}
try {
Nip47WalletConnect.parse(uri)
return Route.Nip47NWCSetup(uri)
} catch (e: Exception) {
if (e is CancellationException) throw e
null
}
}
return null
}

View File

@@ -46,6 +46,7 @@ import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Add
import androidx.compose.material.icons.outlined.ContentPaste
import androidx.compose.material.icons.outlined.Visibility
import androidx.compose.material.icons.outlined.VisibilityOff
@@ -328,14 +329,19 @@ fun UpdateZapAmountContent(
IconButton(
onClick = {
onClose()
runCatching { uri.openUri("https://nwc.getalby.com/apps/new?c=Amethyst") }
try {
uri.openUri("nostrnwc://connect?appname=Amethyst&appicon=https%3A%2F%2Fraw.githubusercontent.com%2Fvitorpamplona%2Famethyst%2Frefs%2Fheads%2Fmain%2Ficon.png&callback=amethyst%2Bwalletconnect%3A%2F%2Fdlnwc")
} catch (_: IllegalArgumentException) {
accountViewModel.toastManager.toast(R.string.couldnt_find_nwc_wallets, R.string.couldnt_find_nwc_wallets_description)
}
},
) {
Icon(
painter = painterRes(R.drawable.alby, 1),
contentDescription = stringRes(id = R.string.accessibility_navigate_to_alby),
imageVector = Icons.Outlined.Add,
contentDescription = stringRes(id = R.string.connect_to_new_nwc_wallet),
modifier = Size24Modifier,
tint = Color.Unspecified,
tint = MaterialTheme.colorScheme.primary,
)
}
@@ -352,7 +358,7 @@ fun UpdateZapAmountContent(
},
) {
Icon(
Icons.Outlined.ContentPaste,
imageVector = Icons.Outlined.ContentPaste,
contentDescription = stringRes(id = R.string.paste_from_clipboard),
modifier = Size24Modifier,
tint = MaterialTheme.colorScheme.primary,

View File

@@ -41,7 +41,9 @@ fun NIP19QrCodeScanner(
) {
SimpleQrCodeScanner {
try {
if (it != null) {
onScan(uriToRoute(it, accountViewModel.account))
}
} catch (e: Throwable) {
if (e is CancellationException) throw e
Log.e("NIP19 Scanner", "Error parsing $it", e)

View File

@@ -841,6 +841,17 @@
<string name="invalid_nip47_uri_title">Invalid NIP-47 URI</string>
<string name="invalid_nip47_uri_description">The URI %1$s is not a valid NIP-47 login URI.</string>
<string name="connect_to_new_nwc_wallet">Connect to new NWC wallet</string>
<string name="couldnt_find_nwc_wallets">Wallet not found</string>
<string name="couldnt_find_nwc_wallets_description">Amethyst couldn\'t find any wallet apps that support Nostr Wallet Connect (NWC).
\n\nWhat you can do:
\n\t1. Verify NWC Support: Double-check that your preferred wallet app is compatible with Nostr Wallet Connect.
\n\t2. Create Connection: Go to your wallet app and create a new NWC connection.
\n\t3. Link to Amethyst: Your wallet will usually give you three options:
\n\t\t3.1 Automatic Link: A button to automatically open and connect to Amethyst. If so, click that button, open Amethyst and hit save on the new screen.
\n\t\t3.2 Manual Link: A Connection URI you can copy and click the paste icon on this screen to directly input it.
\n\t\t3.3 QR Code: The wallet creates a QR code which you can read from the QR code button in this screen.
</string>
<string name="language_description">For the App\'s Interface</string>
<string name="theme_description">Dark, Light or System theme</string>

View File

@@ -38,7 +38,7 @@ class Nip47WalletConnect {
val url = UriParser(uri)
if (url.scheme() != "nostrwalletconnect" && url.scheme() != "nostr+walletconnect") {
if (url.scheme() != "nostrwalletconnect" && url.scheme() != "nostr+walletconnect" && url.scheme() != "amethyst+walletconnect") {
throw IllegalArgumentException("Not a Wallet Connect QR Code")
}