diff --git a/app.json b/app.json
index f6caee7..8e70276 100644
--- a/app.json
+++ b/app.json
@@ -3,7 +3,7 @@
"name": "Alby Go",
"slug": "alby-mobile",
"version": "1.7.2",
- "scheme": ["lightning", "bitcoin", "alby"],
+ "scheme": ["lightning", "bitcoin", "alby", "nostr+walletconnect"],
"orientation": "portrait",
"icon": "./assets/icon.png",
"userInterfaceStyle": "automatic",
diff --git a/lib/link.ts b/lib/link.ts
index aa5db1f..5dfcb05 100644
--- a/lib/link.ts
+++ b/lib/link.ts
@@ -2,7 +2,12 @@ import { router } from "expo-router";
import { BOLT11_REGEX } from "./constants";
import { lnurl as lnurlLib } from "./lnurl";
-const SUPPORTED_SCHEMES = ["lightning:", "bitcoin:", "alby:"];
+const SUPPORTED_SCHEMES = [
+ "lightning:",
+ "bitcoin:",
+ "alby:",
+ "nostr+walletconnect:",
+];
// Register exp scheme for testing during development
// https://docs.expo.dev/guides/linking/#creating-urls
@@ -22,6 +27,19 @@ export const handleLink = async (url: string) => {
if (SUPPORTED_SCHEMES.indexOf(parsedUrl.protocol) > -1) {
let { username, hostname, protocol, pathname, search } = parsedUrl;
+ if (parsedUrl.protocol === "nostr+walletconnect:") {
+ if (router.canDismiss()) {
+ router.dismissAll();
+ }
+ console.info("Navigating to wallet setup");
+ router.push({
+ pathname: "/settings/wallets/setup",
+ params: {
+ nwcUrl: protocol + hostname + search,
+ },
+ });
+ return;
+ }
if (parsedUrl.protocol === "exp:") {
if (!parsedUrl.pathname) {
diff --git a/pages/Transaction.tsx b/pages/Transaction.tsx
index 8ee19dd..ee9918e 100644
--- a/pages/Transaction.tsx
+++ b/pages/Transaction.tsx
@@ -24,11 +24,11 @@ type Boostagram = {
name: string;
podcast: string;
url: string;
- episode?: string;
- itemID?: string;
- ts?: string;
+ episode?: string | number;
+ itemID?: string | number;
+ ts?: string | number;
message?: string;
- sender_id: string;
+ sender_id: string | number;
sender_name: string;
time: string;
action: string;
@@ -204,40 +204,30 @@ function TransactionDetailRow(props: {
}
function PodcastingInfo({ boost }: { boost: Boostagram }) {
+ const renderDetail = (title: string, content: any) => {
+ if (content === 0 || !!content) {
+ return ;
+ }
+ return null;
+ };
return (
<>
- {boost.message && (
-
- )}
- {boost.podcast && (
-
- )}
- {boost.episode && (
-
- )}
- {boost.action && (
-
- )}
- {boost.ts && (
-
- )}
- {boost.value_msat_total && (
-
- )}
- {boost.sender_name && (
-
- )}
- {boost.app_name && (
-
+ {renderDetail("Message", boost.message)}
+ {renderDetail("Podcast", boost.podcast)}
+ {renderDetail("Episode", boost.episode)}
+ {renderDetail("Action", boost.action)}
+ {renderDetail("Timestamp", boost.ts)}
+ {renderDetail(
+ "Total amount",
+ boost.value_msat_total
+ ? Math.floor(boost.value_msat_total / 1000) +
+ (Math.floor(boost.value_msat_total / 1000) === 1
+ ? " sat"
+ : " sats")
+ : null,
)}
+ {renderDetail("Sender", boost.sender_name)}
+ {renderDetail("App", boost.app_name)}
>
);
}
-
-export default PodcastingInfo;
diff --git a/pages/settings/Wallets.tsx b/pages/settings/Wallets.tsx
index 9fcd21b..1901068 100644
--- a/pages/settings/Wallets.tsx
+++ b/pages/settings/Wallets.tsx
@@ -14,76 +14,71 @@ export function Wallets() {
const selectedWalletId = useAppStore((store) => store.selectedWalletId);
const wallets = useAppStore((store) => store.wallets);
return (
- <>
-
-
-
- {
- const active = item.index === selectedWalletId;
+
+
+
+ {
+ const active = item.index === selectedWalletId;
- return (
- {
- if (item.index !== selectedWalletId) {
- useAppStore.getState().setSelectedWalletId(item.index);
- router.dismissAll();
- router.navigate("/");
- Toast.show({
- type: "success",
- text1: `Switched wallet to ${item.item.name || DEFAULT_WALLET_NAME}`,
- position: "top",
- });
- }
- }}
- className={cn(
- "flex flex-row items-center justify-between p-6 rounded-2xl border-2",
- active ? "border-primary" : "border-transparent",
- )}
- >
-
-
-
- {item.item.name || DEFAULT_WALLET_NAME}
-
-
- {active && (
-
-
-
-
-
- )}
-
- );
- }}
- />
-
-
-
-
+ return (
+ {
+ if (item.index !== selectedWalletId) {
+ useAppStore.getState().setSelectedWalletId(item.index);
+ router.dismissAll();
+ router.navigate("/");
+ Toast.show({
+ type: "success",
+ text1: `Switched wallet to ${item.item.name || DEFAULT_WALLET_NAME}`,
+ position: "top",
+ });
+ }
+ }}
+ className={cn(
+ "flex flex-row items-center justify-between p-6 rounded-2xl border-2",
+ active ? "border-primary" : "border-transparent",
+ )}
+ >
+
+
+
+ {item.item.name || DEFAULT_WALLET_NAME}
+
+
+ {active && (
+
+
+
+
+
+ )}
+
+ );
+ }}
+ />
- >
+
+
+
+
);
}
diff --git a/pages/settings/wallets/SetupWallet.tsx b/pages/settings/wallets/SetupWallet.tsx
index 6da0cfb..bf39d1c 100644
--- a/pages/settings/wallets/SetupWallet.tsx
+++ b/pages/settings/wallets/SetupWallet.tsx
@@ -1,7 +1,7 @@
import { nwc } from "@getalby/sdk";
import { Nip47Capability } from "@getalby/sdk/dist/NWCClient";
import * as Clipboard from "expo-clipboard";
-import { router } from "expo-router";
+import { router, useLocalSearchParams } from "expo-router";
import { useAppStore } from "lib/state/appStore";
import React from "react";
import { Pressable, TouchableOpacity, View } from "react-native";
@@ -28,6 +28,9 @@ import { REQUIRED_CAPABILITIES } from "~/lib/constants";
import { errorToast } from "~/lib/errorToast";
export function SetupWallet() {
+ const { nwcUrl: nwcUrlFromSchemeLink } = useLocalSearchParams<{
+ nwcUrl: string;
+ }>();
const wallets = useAppStore((store) => store.wallets);
const walletIdWithConnection = wallets.findIndex(
(wallet) => wallet.nostrWalletConnectUrl,
@@ -39,6 +42,7 @@ export function SetupWallet() {
const [capabilities, setCapabilities] =
React.useState();
const [name, setName] = React.useState("");
+ const [startScanning, setStartScanning] = React.useState(false);
const handleScanned = (data: string) => {
return connect(data);
@@ -56,47 +60,55 @@ export function SetupWallet() {
connect(nostrWalletConnectUrl);
}
- async function connect(nostrWalletConnectUrl: string) {
- try {
- setConnecting(true);
- // make sure connection is valid
- const nwcClient = new nwc.NWCClient({
- nostrWalletConnectUrl,
- });
- const info = await nwcClient.getInfo();
- const capabilities = [...info.methods] as Nip47Capability[];
- if (info.notifications?.length) {
- capabilities.push("notifications");
- }
- if (
- !REQUIRED_CAPABILITIES.every((capability) =>
- capabilities.includes(capability),
- )
- ) {
- const missing = REQUIRED_CAPABILITIES.filter(
- (capability) => !capabilities.includes(capability),
- );
- throw new Error(`Missing required capabilities: ${missing.join(", ")}`);
- }
+ const connect = React.useCallback(
+ async (nostrWalletConnectUrl: string): Promise => {
+ try {
+ setConnecting(true);
+ // make sure connection is valid
+ const nwcClient = new nwc.NWCClient({
+ nostrWalletConnectUrl,
+ });
+ const info = await nwcClient.getInfo();
+ const capabilities = [...info.methods] as Nip47Capability[];
+ if (info.notifications?.length) {
+ capabilities.push("notifications");
+ }
+ if (
+ !REQUIRED_CAPABILITIES.every((capability) =>
+ capabilities.includes(capability),
+ )
+ ) {
+ const missing = REQUIRED_CAPABILITIES.filter(
+ (capability) => !capabilities.includes(capability),
+ );
+ throw new Error(
+ `Missing required capabilities: ${missing.join(", ")}`,
+ );
+ }
- console.info("NWC connected", info);
+ console.info("NWC connected", info);
- setNostrWalletConnectUrl(nostrWalletConnectUrl);
- setCapabilities(capabilities);
- setName(nwcClient.lud16 || "");
+ setNostrWalletConnectUrl(nostrWalletConnectUrl);
+ setCapabilities(capabilities);
+ setName(nwcClient.lud16 || "");
- Toast.show({
- type: "success",
- text1: "Connection successful",
- text2: "Please set your wallet name to finish",
- position: "top",
- });
- } catch (error) {
- console.error(error);
- errorToast(error);
- }
- setConnecting(false);
- }
+ Toast.show({
+ type: "success",
+ text1: "Connection successful",
+ text2: "Please set your wallet name to finish",
+ position: "top",
+ });
+ setConnecting(false);
+ return true;
+ } catch (error) {
+ console.error(error);
+ errorToast(error);
+ }
+ setConnecting(false);
+ return false;
+ },
+ [],
+ );
const addWallet = () => {
if (!nostrWalletConnectUrl) {
@@ -125,6 +137,22 @@ export function SetupWallet() {
router.navigate("/");
};
+ React.useEffect(() => {
+ if (nwcUrlFromSchemeLink) {
+ (async () => {
+ const result = await connect(nwcUrlFromSchemeLink);
+ // Delay the camera to show the error message
+ if (!result) {
+ setTimeout(() => {
+ setStartScanning(true);
+ }, 2000);
+ }
+ })();
+ } else {
+ setStartScanning(true);
+ }
+ }, [connect, nwcUrlFromSchemeLink]);
+
return (
<>
) : !nostrWalletConnectUrl ? (
<>
-
+