diff --git a/src/assets/hands/handshake.png b/src/assets/hands/handshake.png new file mode 100644 index 0000000..6fccb36 Binary files /dev/null and b/src/assets/hands/handshake.png differ diff --git a/src/assets/hands/handsup.png b/src/assets/hands/handsup.png new file mode 100644 index 0000000..8e1cfa9 Binary files /dev/null and b/src/assets/hands/handsup.png differ diff --git a/src/assets/hands/nostr.png b/src/assets/hands/nostr.png new file mode 100644 index 0000000..792e552 Binary files /dev/null and b/src/assets/hands/nostr.png differ diff --git a/src/assets/hands/thumbsdown.png b/src/assets/hands/thumbsdown.png new file mode 100644 index 0000000..7510060 Binary files /dev/null and b/src/assets/hands/thumbsdown.png differ diff --git a/src/assets/handshake.png b/src/assets/handshake.png deleted file mode 100644 index 0f88f82..0000000 Binary files a/src/assets/handshake.png and /dev/null differ diff --git a/src/components/layout/FullscreenModal.tsx b/src/components/layout/FullscreenModal.tsx index cbffcb6..56a0f18 100644 --- a/src/components/layout/FullscreenModal.tsx +++ b/src/components/layout/FullscreenModal.tsx @@ -5,7 +5,7 @@ import { Button, LargeHeader, SmallHeader } from "~/components/layout"; import close from "~/assets/icons/close.svg"; const DIALOG_POSITIONER = "fixed inset-0 safe-top safe-bottom z-50" -const DIALOG_CONTENT = "h-full p-4 bg-gray/50 backdrop-blur-md bg-black/80" +const DIALOG_CONTENT = "h-full flex flex-col justify-between p-4 bg-gray/50 backdrop-blur-md bg-black/80" type FullscreenModalProps = { title: string, @@ -34,8 +34,10 @@ export function FullscreenModal(props: FullscreenModalProps) { {props.children} - +
+ +
diff --git a/src/routes/Send.tsx b/src/routes/Send.tsx index a6df2fe..2e49ebb 100644 --- a/src/routes/Send.tsx +++ b/src/routes/Send.tsx @@ -12,7 +12,8 @@ import { ParsedParams, toParsedParams } from "./Scanner"; import { showToast } from "~/components/Toaster"; import eify from "~/utils/eify"; import { FullscreenModal } from "~/components/layout/FullscreenModal"; -import handshake from "~/assets/handshake.png"; +import handshake from "~/assets/hands/handshake.png"; +import thumbsdown from "~/assets/hands/thumbsdown.png"; import mempoolTxUrl from "~/utils/mempoolTxUrl"; import { BackButton } from "~/components/layout/BackButton"; @@ -23,7 +24,8 @@ const PAYMENT_METHODS = [{ value: "lightning", label: "Lightning", caption: "Fas // const TEST_DEST = "bitcoin:tb1pdh43en28jmhnsrhxkusja46aufdlae5qnfrhucw5jvefw9flce3sdxfcwe?amount=0.00001&label=heyo&lightning=lntbs10u1pjrwrdedq8dpjhjmcnp4qd60w268ve0jencwzhz048ruprkxefhj0va2uspgj4q42azdg89uupp5gngy2pqte5q5uvnwcxwl2t8fsdlla5s6xl8aar4xcsvxeus2w2pqsp5n5jp3pz3vpu92p3uswttxmw79a5lc566herwh3f2amwz2sp6f9tq9qyysgqcqpcxqrpwugv5m534ww5ukcf6sdw2m75f2ntjfh3gzeqay649256yvtecgnhjyugf74zakaf56sdh66ec9fqep2kvu6xv09gcwkv36rrkm38ylqsgpw3yfjl" // const TEST_DEST_ADDRESS = "tb1pdh43en28jmhnsrhxkusja46aufdlae5qnfrhucw5jvefw9flce3sdxfcwe" -type SentDetails = { amount: bigint, destination: string, txid?: string } +// TODO: better success / fail type +type SentDetails = { amount?: bigint, destination?: string, txid?: string, failure_reason?: string } export default function Send() { const [state, actions] = useMegaStore(); @@ -155,10 +157,16 @@ export default function Send() { } else if (source() === "lightning" && nodePubkey()) { const nodes = await state.node_manager?.list_nodes(); const firstNode = nodes[0] as string || "" - const invoice = await state.node_manager?.keysend(firstNode, nodePubkey()!, amountSats()); - console.log(invoice?.value) - sentDetails.amount = amountSats(); - } else { + const payment = await state.node_manager?.keysend(firstNode, nodePubkey()!, amountSats()); + console.log(payment?.value) + + // TODO: handle timeouts + if (!payment?.paid) { + throw new Error("Keysend failed") + } else { + sentDetails.amount = amountSats(); + } + } else if (source() === "onchain" && address()) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const txid = await state.node_manager?.send_to_address(address()!, amountSats()); sentDetails.amount = amountSats(); @@ -170,7 +178,10 @@ export default function Send() { setSentDetails(sentDetails as SentDetails); clearAll(); } catch (e) { - showToast(eify(e)) + const error = eify(e) + setSentDetails({ failure_reason: error.message }); + // TODO: figure out ux of when we want to show toast vs error screen + // showToast(eify(e)) console.error(e); } finally { setSending(false); @@ -187,15 +198,29 @@ export default function Send() { Send Bitcoin - { if (!open) setSentDetails(undefined) }} onConfirm={() => setSentDetails(undefined)}> -
- party - - - - Mempool Link - - + { if (!open) setSentDetails(undefined) }} + onConfirm={() => setSentDetails(undefined)} + > +
+ + + thumbs down +

{sentDetails()?.failure_reason}

+
+ + handshake + + + + Mempool Link + + + +
@@ -229,7 +254,7 @@ export default function Send() {
-
+
{/* if the amount came with the invoice we can't allow setting it */} }>