From bfed277ea917eaa2813af71ef419eb9e32dcf955 Mon Sep 17 00:00:00 2001 From: Jon Staab Date: Fri, 4 Jul 2025 06:22:19 -0700 Subject: [PATCH] Add zaps --- package.json | 1 + pnpm-lock.yaml | Bin 336672 -> 337934 bytes src/app/commands.ts | 19 ++ src/app/components/ChannelMessage.svelte | 2 + .../components/ChannelMessageZapButton.svelte | 27 +++ src/app/components/ProfileLink.svelte | 5 +- src/app/components/ReactionSummary.svelte | 44 ++++- src/app/components/WalletConnect.svelte | 155 ++++++++++++++++ src/app/components/WalletDisconnect.svelte | 16 ++ src/app/components/Zap.svelte | 167 ++++++++++++++++++ src/app/state.ts | 36 +++- src/assets/icons/QR Code.svg | 11 ++ src/assets/icons/Wallet.svg | 6 + src/lib/components/EmojiButton.svelte | 2 +- src/lib/components/Icon.svelte | 4 + src/routes/settings/+layout.svelte | 5 + src/routes/settings/wallet/+page.svelte | 87 +++++++++ src/routes/spaces/[relay]/[room]/+page.svelte | 5 +- .../spaces/[relay]/calendar/+page.svelte | 6 +- src/routes/spaces/[relay]/chat/+page.svelte | 4 +- .../spaces/[relay]/threads/+page.svelte | 12 +- 21 files changed, 597 insertions(+), 17 deletions(-) create mode 100644 src/app/components/ChannelMessageZapButton.svelte create mode 100644 src/app/components/WalletConnect.svelte create mode 100644 src/app/components/WalletDisconnect.svelte create mode 100644 src/app/components/Zap.svelte create mode 100644 src/assets/icons/QR Code.svg create mode 100644 src/assets/icons/Wallet.svg create mode 100644 src/routes/settings/wallet/+page.svelte diff --git a/package.json b/package.json index f0861eb6..2695f0c6 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "@capacitor/keyboard": "^7.0.0", "@capacitor/push-notifications": "^7.0.1", "@capawesome/capacitor-badge": "^7.0.1", + "@getalby/sdk": "^5.1.0", "@poppanator/sveltekit-svg": "^4.2.1", "@sentry/browser": "^8.35.0", "@sveltejs/adapter-static": "^3.0.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8a9bb83774355010e342219ef0134a4e477a8b9a..e635e95506c816781e48585651a7e7148becfce2 100644 GIT binary patch delta 4327 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 diff --git a/src/app/commands.ts b/src/app/commands.ts index cb013437..173fa3b6 100644 --- a/src/app/commands.ts +++ b/src/app/commands.ts @@ -1,3 +1,4 @@ +import {nwc} from "@getalby/sdk" import * as nip19 from "nostr-tools/nip19" import {get} from "svelte/store" import {randomId, flatten, poll, uniq, equals, TIMEZONE, LOCALE} from "@welshman/lib" @@ -55,6 +56,8 @@ import { getThunkError, } from "@welshman/app" import { + wallet, + getWebLn, PROTECTED, userMembership, INDEXER_RELAYS, @@ -443,3 +446,19 @@ export const makeAlert = async (params: AlertParams) => { export const publishAlert = async (params: AlertParams) => publishThunk({event: await makeAlert(params), relays: [NOTIFIER_RELAY]}) + +export const payInvoice = async (invoice: string) => { + const $wallet = get(wallet) + + if (!$wallet) { + throw new Error("No wallet is connected") + } + + if ($wallet.type === "nwc") { + return new nwc.NWCClient($wallet.info).payInvoice({invoice}) + } else if ($wallet.type === "webln") { + return getWebLn() + .enable() + .then(() => getWebLn().sendPayment(invoice)) + } +} diff --git a/src/app/components/ChannelMessage.svelte b/src/app/components/ChannelMessage.svelte index fa03213e..1d9da7ce 100644 --- a/src/app/components/ChannelMessage.svelte +++ b/src/app/components/ChannelMessage.svelte @@ -11,6 +11,7 @@ import ThunkStatus from "@app/components/ThunkStatus.svelte" import ProfileDetail from "@app/components/ProfileDetail.svelte" import ReactionSummary from "@app/components/ReactionSummary.svelte" + import ChannelMessageZapButton from "@app/components/ChannelMessageZapButton.svelte" import ChannelMessageEmojiButton from "@app/components/ChannelMessageEmojiButton.svelte" import ChannelMessageMenuButton from "@app/components/ChannelMessageMenuButton.svelte" import ChannelMessageMenuMobile from "@app/components/ChannelMessageMenuMobile.svelte" @@ -94,6 +95,7 @@ +{/if} diff --git a/src/app/components/ProfileLink.svelte b/src/app/components/ProfileLink.svelte index 5279abae..b9cbd66d 100644 --- a/src/app/components/ProfileLink.svelte +++ b/src/app/components/ProfileLink.svelte @@ -9,14 +9,15 @@ type Props = { pubkey: string url?: string + class?: string unstyled?: boolean } - const {pubkey, url, unstyled}: Props = $props() + const {pubkey, url, unstyled, ...props}: Props = $props() const openProfile = () => pushModal(ProfileDetail, {pubkey, url}) - diff --git a/src/app/components/ReactionSummary.svelte b/src/app/components/ReactionSummary.svelte index 14fac6ed..e4e263f7 100644 --- a/src/app/components/ReactionSummary.svelte +++ b/src/app/components/ReactionSummary.svelte @@ -1,9 +1,10 @@ -{#if $reactions.length > 0 || $reports.length > 0} +{#if $reactions.length > 0 || $zaps.length || $reports.length > 0}
{#if url && $reports.length > 0} {/if} + {#each groupedZaps.entries() as [key, zaps]} + {@const amount = sum(zaps.map(zap => zap.invoiceAmount))} + {@const pubkeys = zaps.map(zap => zap.request.pubkey)} + {@const isOwn = $pubkey && pubkeys.includes($pubkey)} + {@const info = displayList(pubkeys.map(pubkey => displayProfileByPubkey(pubkey)))} + {@const tooltip = `${info} zapped`} + + {/each} {#each groupedReactions.entries() as [key, events]} {@const pubkeys = events.map(e => e.pubkey)} {@const isOwn = $pubkey && pubkeys.includes($pubkey)} diff --git a/src/app/components/WalletConnect.svelte b/src/app/components/WalletConnect.svelte new file mode 100644 index 00000000..b52385e0 --- /dev/null +++ b/src/app/components/WalletConnect.svelte @@ -0,0 +1,155 @@ + + +
+ + {#snippet title()} +
Connect a Wallet
+ {/snippet} + {#snippet info()} + Use Nostr Wallet Connect to send Bitcoin payments over Lightning. + {/snippet} +
+ {#if getWebLn()} + + Or + {/if} + + {#snippet label()} + Connection Secret* + {/snippet} + {#snippet input()} + + {/snippet} + {#snippet info()} + You can find this in any wallet that supports + Nostr Wallet Connect. + {/snippet} + + + + + +
diff --git a/src/app/components/WalletDisconnect.svelte b/src/app/components/WalletDisconnect.svelte new file mode 100644 index 00000000..16835d09 --- /dev/null +++ b/src/app/components/WalletDisconnect.svelte @@ -0,0 +1,16 @@ + + + diff --git a/src/app/components/Zap.svelte b/src/app/components/Zap.svelte new file mode 100644 index 00000000..3f4218ae --- /dev/null +++ b/src/app/components/Zap.svelte @@ -0,0 +1,167 @@ + + +
+ + {#snippet title()} +
Send a Zap
+ {/snippet} + {#snippet info()} +
To
+ {/snippet} +
+ + {#snippet label()} + Emoji Reaction + {/snippet} + {#snippet input()} +
+ + {content} + +
+ {/snippet} +
+ + {#snippet label()} + Amount + {/snippet} + {#snippet input()} +
+ +
+ {/snippet} +
+ + + + + +
diff --git a/src/app/state.ts b/src/app/state.ts index 57610a52..50010cc2 100644 --- a/src/app/state.ts +++ b/src/app/state.ts @@ -37,6 +37,7 @@ import { CLIENT_AUTH, AUTH_JOIN, REACTION, + ZAP_REQUEST, ZAP_RESPONSE, DIRECT_MESSAGE, DIRECT_MESSAGE_FILE, @@ -134,7 +135,7 @@ export const REACTION_KINDS = [REACTION, ZAP_RESPONSE] export const NIP46_PERMS = "nip44_encrypt,nip44_decrypt," + - [CLIENT_AUTH, AUTH_JOIN, MESSAGE, THREAD, COMMENT, ROOMS, WRAP, REACTION] + [CLIENT_AUTH, AUTH_JOIN, MESSAGE, THREAD, COMMENT, ROOMS, WRAP, REACTION, ZAP_REQUEST] .map(k => `sign_event:${k}`) .join(",") @@ -346,6 +347,39 @@ export const { load: makeOutboxLoader(SETTINGS), }) +// Wallets + +export type WebLNInfo = { + methods?: string[] + supports?: string[] + version?: string + node?: { + alias: string + } +} + +export type NWCInfo = { + lud16: string + secret: string + relayUrl: string + walletPubkey: string + nostrWalletConnectUrl: string +} + +export type Wallet = + | { + type: "webln" + info: WebLNInfo + } + | { + type: "nwc" + info: NWCInfo + } + +export const wallet = synced("wallet", undefined) + +export const getWebLn = () => (window as any).webln + // Alerts export type Alert = { diff --git a/src/assets/icons/QR Code.svg b/src/assets/icons/QR Code.svg new file mode 100644 index 00000000..6eb3412d --- /dev/null +++ b/src/assets/icons/QR Code.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/assets/icons/Wallet.svg b/src/assets/icons/Wallet.svg new file mode 100644 index 00000000..a8b57f70 --- /dev/null +++ b/src/assets/icons/Wallet.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/lib/components/EmojiButton.svelte b/src/lib/components/EmojiButton.svelte index 4e931f2f..714c3933 100644 --- a/src/lib/components/EmojiButton.svelte +++ b/src/lib/components/EmojiButton.svelte @@ -20,7 +20,7 @@ if (popover) { const {x, y, width, height} = popover.popper.getBoundingClientRect() - if (!between([x, x + width], clientX) || !between([y - 30, y + height + 30], clientY)) { + if (!between([x, x + width], clientX) || !between([y - 100, y + height + 100], clientY)) { popover.hide() } } diff --git a/src/lib/components/Icon.svelte b/src/lib/components/Icon.svelte index 39321de0..518986a0 100644 --- a/src/lib/components/Icon.svelte +++ b/src/lib/components/Icon.svelte @@ -68,6 +68,7 @@ import Pallete2 from "@assets/icons/Pallete 2.svg?dataurl" import Paperclip from "@assets/icons/Paperclip.svg?dataurl" import Plain from "@assets/icons/Plain.svg?dataurl" + import QRCode from "@assets/icons/QR Code.svg?dataurl" import QuestionSquare from "@assets/icons/Question Square.svg?dataurl" import RemoteControllerMinimalistic from "@assets/icons/Remote Controller Minimalistic.svg?dataurl" import Rocket2 from "@assets/icons/Rocket 2.svg?dataurl" @@ -90,6 +91,7 @@ import UserHeart from "@assets/icons/User Heart.svg?dataurl" import UserCircle from "@assets/icons/User Circle.svg?dataurl" import UserRounded from "@assets/icons/User Rounded.svg?dataurl" + import Wallet from "@assets/icons/Wallet.svg?dataurl" import Widget from "@assets/icons/Widget.svg?dataurl" import WidgetAdd from "@assets/icons/Widget Add.svg?dataurl" import WiFiRouterRound from "@assets/icons/Wi-Fi Router Round.svg?dataurl" @@ -168,6 +170,7 @@ "pallete-2": Pallete2, paperclip: Paperclip, plain: Plain, + "qr-code": QRCode, "question-square": QuestionSquare, reply: Reply, "remote-controller-minimalistic": RemoteControllerMinimalistic, @@ -190,6 +193,7 @@ "user-heart": UserHeart, "user-circle": UserCircle, "user-rounded": UserRounded, + wallet: Wallet, widget: Widget, "widget-add": WidgetAdd, "wifi-router-round": WiFiRouterRound, diff --git a/src/routes/settings/+layout.svelte b/src/routes/settings/+layout.svelte index 2f7f753c..00da258c 100644 --- a/src/routes/settings/+layout.svelte +++ b/src/routes/settings/+layout.svelte @@ -28,6 +28,11 @@ Profile
+
+ + Wallet + +
Relays diff --git a/src/routes/settings/wallet/+page.svelte b/src/routes/settings/wallet/+page.svelte new file mode 100644 index 00000000..15bd9300 --- /dev/null +++ b/src/routes/settings/wallet/+page.svelte @@ -0,0 +1,87 @@ + + +
+
+
+ + + Wallet + + {#if $wallet} +
+ + Connected +
+ {:else} + + {/if} +
+
+ {#if $wallet} + {#if $wallet?.type === "webln"} + {@const {node, version} = $wallet.info} +
+

+ Connected to {node?.alias || version || "unknown wallet"} + via {$wallet.type} +

+

+ Balance: + {#await getWebLn() + ?.enable() + .then(() => getWebLn().getBalance())} + + {:then res} + {new Intl.NumberFormat(LOCALE).format(res?.balance || 0)} + {:catch} + [unknown] + {/await} + sats +

+
+ {:else if $wallet.type === "nwc"} + {@const {lud16, relayUrl, nostrWalletConnectUrl} = $wallet.info} +
+

+ Connected to {lud16} via {displayRelayUrl(relayUrl)} +

+

+ Balance: + {#await new nwc.NWCClient({nostrWalletConnectUrl}).getBalance()} + + {:then res} + {new Intl.NumberFormat(LOCALE).format(res?.balance || 0)} + {:catch} + [unknown] + {/await} + sats +

+
+ {/if} + + {:else} +

No wallet connected

+ {/if} +
+
+
diff --git a/src/routes/spaces/[relay]/[room]/+page.svelte b/src/routes/spaces/[relay]/[room]/+page.svelte index 0555183a..5a3ff0f8 100644 --- a/src/routes/spaces/[relay]/[room]/+page.svelte +++ b/src/routes/spaces/[relay]/[room]/+page.svelte @@ -13,6 +13,7 @@ MESSAGE, DELETE, REACTION, + ZAP_RESPONSE, ROOM_ADD_USER, ROOM_REMOVE_USER, } from "@welshman/util" @@ -226,7 +227,9 @@ element: element!, relays: [url], feedFilters: [filter], - subscriptionFilters: [{kinds: [DELETE, REACTION, MESSAGE], "#h": [room], since: now()}], + subscriptionFilters: [ + {kinds: [DELETE, REACTION, ZAP_RESPONSE, MESSAGE], "#h": [room], since: now()}, + ], initialEvents: getEventsForUrl(url, [{...filter, limit: 20}]), onExhausted: () => { loadingEvents = false diff --git a/src/routes/spaces/[relay]/calendar/+page.svelte b/src/routes/spaces/[relay]/calendar/+page.svelte index 773d1a84..c07b739a 100644 --- a/src/routes/spaces/[relay]/calendar/+page.svelte +++ b/src/routes/spaces/[relay]/calendar/+page.svelte @@ -5,7 +5,7 @@ import {page} from "$app/stores" import {now, last, formatTimestampAsDate} from "@welshman/lib" import type {TrustedEvent} from "@welshman/util" - import {REACTION, DELETE, EVENT_TIME, getTagValue} from "@welshman/util" + import {REACTION, ZAP_RESPONSE, DELETE, EVENT_TIME, getTagValue} from "@welshman/util" import {fly} from "@lib/transition" import Icon from "@lib/components/Icon.svelte" import Button from "@lib/components/Button.svelte" @@ -93,7 +93,9 @@ onMount(() => { const feedFilters = [{kinds: [EVENT_TIME]}] - const subscriptionFilters = [{kinds: [DELETE, REACTION, EVENT_TIME], since: now()}] + const subscriptionFilters = [ + {kinds: [DELETE, REACTION, ZAP_RESPONSE, EVENT_TIME], since: now()}, + ] ;({events, cleanup} = makeCalendarFeed({ element: element!, diff --git a/src/routes/spaces/[relay]/chat/+page.svelte b/src/routes/spaces/[relay]/chat/+page.svelte index d5610946..183a1574 100644 --- a/src/routes/spaces/[relay]/chat/+page.svelte +++ b/src/routes/spaces/[relay]/chat/+page.svelte @@ -5,7 +5,7 @@ import type {Readable} from "svelte/store" import {now, formatTimestampAsDate} from "@welshman/lib" import type {TrustedEvent, EventContent} from "@welshman/util" - import {makeEvent, MESSAGE, DELETE, REACTION} from "@welshman/util" + import {makeEvent, MESSAGE, DELETE, REACTION, ZAP_RESPONSE} from "@welshman/util" import {pubkey, publishThunk} from "@welshman/app" import {slide, fade, fly} from "@lib/transition" import Icon from "@lib/components/Icon.svelte" @@ -174,7 +174,7 @@ element: element!, relays: [url], feedFilters: [filter], - subscriptionFilters: [{kinds: [DELETE, REACTION, MESSAGE], since: now()}], + subscriptionFilters: [{kinds: [DELETE, REACTION, ZAP_RESPONSE, MESSAGE], since: now()}], initialEvents: getEventsForUrl(url, [{...filter, limit: 20}]), onExhausted: () => { loadingEvents = false diff --git a/src/routes/spaces/[relay]/threads/+page.svelte b/src/routes/spaces/[relay]/threads/+page.svelte index 684144dd..695f35e8 100644 --- a/src/routes/spaces/[relay]/threads/+page.svelte +++ b/src/routes/spaces/[relay]/threads/+page.svelte @@ -3,7 +3,15 @@ import {page} from "$app/stores" import {sortBy, max, nthEq} from "@welshman/lib" import type {TrustedEvent} from "@welshman/util" - import {THREAD, REACTION, DELETE, COMMENT, getListTags, getPubkeyTagValues} from "@welshman/util" + import { + THREAD, + REACTION, + ZAP_RESPONSE, + DELETE, + COMMENT, + getListTags, + getPubkeyTagValues, + } from "@welshman/util" import {userMutes} from "@welshman/app" import {fly} from "@lib/transition" import Icon from "@lib/components/Icon.svelte" @@ -49,7 +57,7 @@ relays: [url], feedFilters: [{kinds: [THREAD, COMMENT]}], subscriptionFilters: [ - {kinds: [THREAD, REACTION, DELETE]}, + {kinds: [THREAD, REACTION, ZAP_RESPONSE, DELETE]}, {kinds: [COMMENT], "#K": [String(THREAD)]}, ], initialEvents: getEventsForUrl(url, [{kinds: [THREAD, COMMENT], limit: 10}]),