From ad058d8301a40b9fd09ef48a0c981ee91493d241 Mon Sep 17 00:00:00 2001 From: Roland Bewick Date: Wed, 8 Jan 2025 21:32:50 +0700 Subject: [PATCH 1/2] feat: display metadata (POC) --- pages/Transaction.tsx | 35 ++++++- pages/Transactions.tsx | 166 +++++++++++++++++++--------------- pages/send/ConfirmPayment.tsx | 31 +++++-- pages/send/LNURLPay.tsx | 20 ++++ 4 files changed, 172 insertions(+), 80 deletions(-) diff --git a/pages/Transaction.tsx b/pages/Transaction.tsx index 29b6d98..a24fbc0 100644 --- a/pages/Transaction.tsx +++ b/pages/Transaction.tsx @@ -60,6 +60,15 @@ export function Transaction() { return parsedBoostagram; }, [transaction.metadata]); + // TODO: extract typings + // TODO: review "description" field + const metadata = transaction.metadata as + | { + payer_data?: { name?: string }; + recipient_data?: { identifier?: string; description?: string }; + } + | undefined; + return ( @@ -130,6 +139,18 @@ export function Transaction() { )} + {metadata?.recipient_data?.identifier && ( + + )} + {metadata?.payer_data?.name && ( + + )} {boostagram && } @@ -170,6 +196,13 @@ export function Transaction() { copy /> )} + {transaction.metadata && ( + + )} diff --git a/pages/Transactions.tsx b/pages/Transactions.tsx index b241eb6..8261550 100644 --- a/pages/Transactions.tsx +++ b/pages/Transactions.tsx @@ -110,83 +110,107 @@ export function Transactions() { setPage(page + 1); } }} - renderItem={({ item: transaction }) => ( - - router.navigate({ - pathname: "/transaction", - params: { transactionJSON: JSON.stringify(transaction) }, - }) - } - > - { + // TODO: extract typings + // TODO: review "description" field + const metadata = transaction.metadata as + | { + recipient_data?: { + identifier?: string; + description?: string; + }; + } + | undefined; + + return ( + + router.navigate({ + pathname: "/transaction", + params: { transactionJSON: JSON.stringify(transaction) }, + }) + } > - - {!( - transaction.state === "failed" || - transaction.state === "pending" - ) && ( - <> - {transaction.type === "incoming" && ( - - )} - {transaction.type === "outgoing" && ( - - )} - - )} - {transaction.state === "pending" && ( - + } - - - - - {transaction.type === "incoming" - ? "Received" - : transaction.state === "failed" - ? "Failed" - : transaction.state === "pending" - ? "Sending" - : "Sent"} + > + + {!( + transaction.state === "failed" || + transaction.state === "pending" + ) && ( + <> + {transaction.type === "incoming" && ( + + )} + {transaction.type === "outgoing" && ( + + )} + + )} + {transaction.state === "pending" && ( + + )} + {transaction.state === "failed" && ( + + )} + + + + + {transaction.type === "incoming" + ? "Received" + : transaction.state === "failed" + ? "Failed" + : transaction.state === "pending" + ? "Sending" + : "Sent"} + + + {dayjs + .unix( + transaction.settled_at || transaction.created_at, + ) + .fromNow()} + + + {(transaction.description || + metadata?.recipient_data?.description) && ( + + {transaction.description || + metadata?.recipient_data?.description} + + )} + + + + {transaction.type === "incoming" ? "+" : "-"}{" "} + {Math.floor(transaction.amount / 1000)} + + {" "} + sats + - - {dayjs - .unix(transaction.settled_at || transaction.created_at) - .fromNow()} + + {getFiatAmount && + getFiatAmount(Math.floor(transaction.amount / 1000))} - {transaction.description && ( - {transaction.description} - )} - - - {transaction.type === "incoming" ? "+" : "-"}{" "} - {Math.floor(transaction.amount / 1000)} - sats - - - {getFiatAmount && - getFiatAmount(Math.floor(transaction.amount / 1000))} - - - - - )} + + ); + }} /> ) : !transactionsLoaded ? ( diff --git a/pages/send/ConfirmPayment.tsx b/pages/send/ConfirmPayment.tsx index 836704b..649d0e2 100644 --- a/pages/send/ConfirmPayment.tsx +++ b/pages/send/ConfirmPayment.tsx @@ -18,14 +18,23 @@ import { useAppStore } from "~/lib/state/appStore"; export function ConfirmPayment() { const { data: transactions } = useTransactions(); - const { invoice, originalText, comment, successAction, amount } = - useLocalSearchParams() as { - invoice: string; - originalText: string; - comment: string; - successAction: string; - amount?: string; - }; + const { + invoice, + originalText, + comment, + successAction, + amount, + recipientDescription, + recipientIdentifier, + } = useLocalSearchParams() as { + invoice: string; + originalText: string; + comment: string; + successAction: string; + amount?: string; + recipientDescription?: string; + recipientIdentifier?: string; + }; const getFiatAmount = useGetFiatAmount(); const [isLoading, setLoading] = React.useState(false); const wallets = useAppStore((store) => store.wallets); @@ -45,6 +54,12 @@ export function ConfirmPayment() { const response = await nwcClient.payInvoice({ invoice, amount: amount ? amountToPaySats * 1000 : undefined, + metadata: { + recipient_data: { + identifier: recipientIdentifier, + description: recipientDescription, + }, + }, }); console.info("payInvoice Response", response); diff --git a/pages/send/LNURLPay.tsx b/pages/send/LNURLPay.tsx index 50bb0b9..0deb17c 100644 --- a/pages/send/LNURLPay.tsx +++ b/pages/send/LNURLPay.tsx @@ -52,6 +52,24 @@ export function LNURLPay() { if (comment) { callback.searchParams.append("comment", comment); } + let recipientDescription = ""; + try { + recipientDescription = + ( + JSON.parse(decodeURIComponent(lnurlDetails.metadata)) as string[][] + ).find((t) => t[0] === "text/plain")?.[1] || ""; + } catch (error) { + console.error("failed to parse recipient description", error); + } + let recipientIdentifier = ""; + try { + recipientIdentifier = + ( + JSON.parse(decodeURIComponent(lnurlDetails.metadata)) as string[][] + ).find((t) => t[0] === "text/identifier")?.[1] || ""; + } catch (error) { + console.error("failed to parse recipient identifier", error); + } //callback.searchParams.append("payerdata", JSON.stringify({ test: 1 })); const lnurlPayInfo = await lnurl.getPayRequest(callback.toString()); //console.log("Got pay request", lnurlPayInfo.pr); @@ -60,6 +78,8 @@ export function LNURLPay() { params: { invoice: lnurlPayInfo.pr, originalText, + recipientDescription, + recipientIdentifier, comment, successAction: lnurlPayInfo.successAction ? JSON.stringify(lnurlPayInfo.successAction) From 3a97b32f96dcf7236229a99602bede7a9431f020 Mon Sep 17 00:00:00 2001 From: Roland Bewick Date: Wed, 8 Jan 2025 22:02:53 +0700 Subject: [PATCH 2/2] chore: add comment metadata --- pages/Transaction.tsx | 7 +++++++ pages/send/ConfirmPayment.tsx | 1 + 2 files changed, 8 insertions(+) diff --git a/pages/Transaction.tsx b/pages/Transaction.tsx index a24fbc0..26d26ab 100644 --- a/pages/Transaction.tsx +++ b/pages/Transaction.tsx @@ -66,6 +66,7 @@ export function Transaction() { | { payer_data?: { name?: string }; recipient_data?: { identifier?: string; description?: string }; + comment?: string; } | undefined; @@ -166,6 +167,12 @@ export function Transaction() { "-" } /> + {metadata?.comment && ( + + )} {boostagram && } diff --git a/pages/send/ConfirmPayment.tsx b/pages/send/ConfirmPayment.tsx index 649d0e2..3400e69 100644 --- a/pages/send/ConfirmPayment.tsx +++ b/pages/send/ConfirmPayment.tsx @@ -59,6 +59,7 @@ export function ConfirmPayment() { identifier: recipientIdentifier, description: recipientDescription, }, + comment, }, });