diff --git a/hooks/useTransactions.ts b/hooks/useTransactions.ts
index 993d17e..2fa3705 100644
--- a/hooks/useTransactions.ts
+++ b/hooks/useTransactions.ts
@@ -1,3 +1,7 @@
+import {
+ Nip47ListTransactionsRequest,
+ Nip47Transaction,
+} from "@getalby/sdk/dist/NWCClient";
import { useAppStore } from "lib/state/appStore";
import useSWR from "swr";
import { TRANSACTIONS_PAGE_SIZE } from "~/lib/constants";
@@ -15,11 +19,19 @@ const fetcher = async (...args: FetchArgs) => {
const page = +(transactionsUrl.searchParams.get("page") as string);
try {
- const transactions = await nwcClient.listTransactions({
- limit: TRANSACTIONS_PAGE_SIZE,
- offset: (page - 1) * TRANSACTIONS_PAGE_SIZE,
- });
- return transactions;
+ const transactions = await nwcClient.listTransactions(
+ {
+ limit: TRANSACTIONS_PAGE_SIZE,
+ offset: (page - 1) * TRANSACTIONS_PAGE_SIZE,
+ unpaid_outgoing: true,
+ } as Nip47ListTransactionsRequest /* TODO: remove cast once unpaid_outgoing or similar is part of spec/js-sdk */,
+ );
+ return transactions as {
+ // TODO: undo when JS SDK includes state property
+ transactions: (Nip47Transaction & {
+ state: "settled" | "pending" | "failed";
+ })[];
+ };
} catch (error) {
errorToast(error);
throw error;
diff --git a/pages/Transaction.tsx b/pages/Transaction.tsx
index 845f130..ec9ddb0 100644
--- a/pages/Transaction.tsx
+++ b/pages/Transaction.tsx
@@ -7,7 +7,7 @@ import { useLocalSearchParams } from "expo-router";
import React from "react";
import { ScrollView, TouchableOpacity, View } from "react-native";
import Toast from "react-native-toast-message";
-import { MoveDownLeft, MoveUpRight } from "~/components/Icons";
+import { MoveDownLeft, MoveUpRight, X } from "~/components/Icons";
import Screen from "~/components/Screen";
import { Text } from "~/components/ui/text";
import { useGetFiatAmount } from "~/hooks/useGetFiatAmount";
@@ -38,7 +38,10 @@ export function Transaction() {
const { transactionJSON } = useLocalSearchParams() as unknown as {
transactionJSON: string;
};
- const transaction: Nip47Transaction = JSON.parse(transactionJSON);
+ // TODO: undo when JS SDK includes state property
+ const transaction: Nip47Transaction & {
+ state: "settled" | "pending" | "failed";
+ } = JSON.parse(transactionJSON);
const getFiatAmount = useGetFiatAmount();
const boostagram = React.useMemo(() => {
@@ -64,18 +67,43 @@ export function Transaction() {
- {transaction.type === "incoming" && (
-
+ {transaction.state !== "failed" && (
+ <>
+ {transaction.type === "incoming" && (
+
+ )}
+ {transaction.type === "outgoing" && (
+
+ )}
+ >
)}
- {transaction.type === "outgoing" && (
-
+ {transaction.state === "failed" && (
+
)}
-
- {transaction.type === "incoming" ? "Received" : "Sent"}
+
+ {transaction.type === "incoming"
+ ? "Received"
+ : transaction.state === "failed"
+ ? "Failed"
+ : transaction.state === "pending"
+ ? "Sending"
+ : "Sent"}
@@ -104,7 +132,9 @@ export function Transaction() {
}
+ {transaction.state === "settled" &&
+ transaction.type === "outgoing" && (
+
+ )}
-
-
+ {transaction.state === "settled" && (
+
+ )}
diff --git a/pages/Transactions.tsx b/pages/Transactions.tsx
index ee16cb9..af13f41 100644
--- a/pages/Transactions.tsx
+++ b/pages/Transactions.tsx
@@ -26,7 +26,11 @@ export function Transactions() {
const [loadingNextPage, setLoadingNextPage] = React.useState(false);
const [transactionsLoaded, setTransactionsLoaded] = React.useState(false);
const [allTransactions, setAllTransactions] = React.useState<
- Nip47Transaction[]
+ //Nip47Transaction[]
+ // TODO: undo when JS SDK includes state property
+ (Nip47Transaction & {
+ state: "settled" | "pending" | "failed";
+ })[]
>([]);
const [refreshingTransactions, setRefreshingTransactions] =
React.useState(false);
@@ -116,26 +120,47 @@ export function Transactions() {
})
}
>
-
+
- {transaction.type === "incoming" && (
-
+ {transaction.state !== "failed" && (
+ <>
+ {transaction.type === "incoming" && (
+
+ )}
+ {transaction.type === "outgoing" && (
+
+ )}
+ >
)}
- {transaction.type === "outgoing" && (
-
+ {transaction.state === "failed" && (
+
)}
-
- {transaction.description
- ? transaction.description
- : transaction.type === "incoming"
+
+
+ {transaction.type === "incoming"
? "Received"
- : "Sent"}
-
-
- {dayjs.unix(transaction.settled_at).fromNow()}
-
+ : transaction.state === "failed"
+ ? "Failed"
+ : transaction.state === "pending"
+ ? "Sending"
+ : "Sent"}
+
+
+ {dayjs
+ .unix(transaction.settled_at || transaction.created_at)
+ .fromNow()}
+
+
+ {transaction.description && (
+ {transaction.description}
+ )}
+ {!transactions?.transactions.some(
+ (transaction) => transaction.state === "pending",
+ ) && (
+
+
+
+
+
+
+ One or more pending payments
+
+
+
+ Please check your transaction list before paying to ensure you
+ do not make a payment twice.
+
+
+
+
+ )}