diff options
Diffstat (limited to 'src/routes/(app)/settings')
| -rw-r--r-- | src/routes/(app)/settings/nostr/+page.server.ts | 8 | ||||
| -rw-r--r-- | src/routes/(app)/settings/nostr/+page.svelte | 78 |
2 files changed, 83 insertions, 3 deletions
diff --git a/src/routes/(app)/settings/nostr/+page.server.ts b/src/routes/(app)/settings/nostr/+page.server.ts index 1767ebaf..84b3fa27 100644 --- a/src/routes/(app)/settings/nostr/+page.server.ts +++ b/src/routes/(app)/settings/nostr/+page.server.ts @@ -4,7 +4,13 @@ import { auth, get } from "$lib/utils"; export const load = async ({ cookies }) => { const { challenge } = await get("/challenge"); const apps = await get("/apps", auth(cookies)); - return { apps, challenge }; + + let offer; + try { + ({ hash: offer } = await get("/offer", auth(cookies))); + } catch (e) {} + + return { apps, challenge, offer }; }; export const actions = { diff --git a/src/routes/(app)/settings/nostr/+page.svelte b/src/routes/(app)/settings/nostr/+page.svelte index 7168f4f7..5ba5f636 100644 --- a/src/routes/(app)/settings/nostr/+page.svelte +++ b/src/routes/(app)/settings/nostr/+page.svelte @@ -1,7 +1,7 @@ <script> import { untrack } from "svelte"; import { browser } from "$app/environment"; - import { getNsec } from "$lib/nostr"; + import { getNsec, send, sign } from "$lib/nostr"; import { page } from "$app/stores"; import { tick } from "svelte"; import { t } from "$lib/translations"; @@ -13,7 +13,7 @@ import { signer, save } from "$lib/store"; let { data } = $props(); - let { apps, challenge, user } = $derived(data); + let { apps, challenge, offer, user } = $derived(data); let npub = $state(untrack(() => user.npub)); let extensionAvailable = $derived(browser && window.nostr); let { locale } = $derived(user); @@ -41,6 +41,33 @@ await tick(); $save.click(); }; + + let publishing = $state(), + published = $state(); + + // Kind 10058 is the NIP-177 BOLT12 offer list — publishing it lets nostr + // clients (Amethyst v1.13+) zap this user over BOLT12. Replaceable event, + // so republishing just updates it. + let publishOffer = async () => { + try { + publishing = true; + let event = { + kind: 10058, + content: "", + created_at: Math.round(Date.now() / 1000), + tags: [["offer", offer]], + }; + + event = await sign(event, user); + await send(event); + published = true; + } catch (e) { + console.log(e); + fail($t("user.settings.offerPublishFailed")); + } finally { + publishing = false; + } + }; </script> <input type="hidden" name="challenge" value={challenge} /> @@ -145,6 +172,53 @@ </div> </div> +{#if offer} + <div class="space-y-2"> + <h2 class="text-2xl font-bold mb-2"> + {$t("user.settings.bolt12Offer")} + </h2> + <p class="text-secondary mb-4"> + {$t("user.settings.bolt12OfferDescription")} + </p> + + <div class="break-all text-secondary">{offer}</div> + + <div class="flex my-auto gap-1"> + <button + type="button" + class="my-auto btn btn-circle !w-auto grow" + onclick={() => copy(offer)} + aria-label="Copy" + ><iconify-icon noobserver icon="ph:copy-bold" width="32" + ></iconify-icon> {$t("accounts.copy")}</button + > + + <a + href={`/qr/${encodeURIComponent(offer)}`} + class="my-auto btn btn-circle !w-auto grow" + aria-label="QR" + > + <iconify-icon noobserver icon="ph:qr-code-bold" width="32" + ></iconify-icon> + {$t("accounts.qr")} + </a> + + <button + type="button" + class="my-auto btn btn-circle !w-auto grow" + onclick={publishOffer} + disabled={publishing} + aria-label="Publish" + ><iconify-icon noobserver icon="ph:megaphone-bold" width="32" + ></iconify-icon> + {published + ? $t("user.settings.offerPublished") + : $t("user.settings.publishOffer")}</button + > + </div> + </div> +{/if} + {#if revealNwc} <div class="break-all grow"> {nwc} |
