aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2024-08-23 23:53:29 -0700
committerAdam Soltys <[email protected]>2024-08-23 23:53:29 -0700
commit243f2b2f0f2da9735885978a6773b77a7bd139eb (patch)
tree7ee9ed6e90dd1417cb87f091c03148b7eb06011f
parent8d3fb861ef2a9e56fee6a0ab9c4c0e3c935305dc (diff)
downloadcoinos-ui-243f2b2f0f2da9735885978a6773b77a7bd139eb.tar.gz
coinos-ui-243f2b2f0f2da9735885978a6773b77a7bd139eb.zip
rename ecash routes
-rwxr-xr-xbun.lockbbin159617 -> 160396 bytes
-rw-r--r--package.json2
-rw-r--r--src/lib/parse.js15
-rw-r--r--src/lib/utils.js4
-rw-r--r--src/locales/en.json5
-rw-r--r--src/routes/(app)/[username]/invoice/[id]/+page.svelte2
-rw-r--r--src/routes/(app)/[username]/payments/[...page]/+page.server.js2
-rw-r--r--src/routes/(app)/ecash/[id]/+layout.server.js10
-rw-r--r--src/routes/(app)/ecash/[id]/+layout.svelte53
-rw-r--r--src/routes/(app)/ecash/[id]/+page.server.js25
-rw-r--r--src/routes/(app)/ecash/[id]/+page.svelte113
-rw-r--r--src/routes/(app)/ecash/[id]/swap/+page.server.ts3
-rw-r--r--src/routes/(app)/ecash/[id]/swap/+page.svelte5
-rw-r--r--src/routes/(app)/pay/[username]/[...amount]/+page.svelte2
-rw-r--r--src/routes/(app)/receive/[...token]/+page.server.js17
-rw-r--r--src/routes/(app)/receive/[...token]/+page.svelte (renamed from src/routes/(app)/voucher/[...token]/+page.svelte)0
-rw-r--r--src/routes/(app)/redeem/[redeemcode]/+page.server.js17
-rw-r--r--src/routes/(app)/redeem/[redeemcode]/+page.svelte4
-rw-r--r--src/routes/(app)/send/[...text]/+page.server.js8
-rw-r--r--src/routes/(app)/send/ecash/+page.server.js4
-rw-r--r--src/routes/(app)/voucher/[...token]/+page.server.js32
-rw-r--r--svelte.config.js8
-rw-r--r--tsconfig.json14
23 files changed, 181 insertions, 164 deletions
diff --git a/bun.lockb b/bun.lockb
index e263d1a0..4a816616 100755
--- a/bun.lockb
+++ b/bun.lockb
Binary files differ
diff --git a/package.json b/package.json
index 2210c9b7..d710f239 100644
--- a/package.json
+++ b/package.json
@@ -9,6 +9,7 @@
"@sveltejs/kit": "^2.5.22",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"@tailwindcss/line-clamp": "^0.4.2",
+ "@types/uuid": "^10.0.0",
"@zerodevx/svelte-toast": "^0.9.5",
"autoprefixer": "^10.4.13",
"bech32": "^2.0.0",
@@ -37,6 +38,7 @@
"sveltekit-i18n": "^2.2.2",
"tailwind-scrollbar": "^2.1.0",
"tailwindcss": "^3.2.4",
+ "typescript": "^5.5.4",
"uint8array-extras": "^1.0.0",
"unique-names-generator": "^4.7.1",
"uuid": "^9.0.0",
diff --git a/src/lib/parse.js b/src/lib/parse.js
index 3470fb52..09c6f320 100644
--- a/src/lib/parse.js
+++ b/src/lib/parse.js
@@ -57,18 +57,9 @@ export default async (t, host, cookies) => {
else if (id) redirect(307, `/send/${id}`);
}
- let claimed;
- if (t.toLowerCase().startsWith("cashu")) {
- try {
- claimed = await post(`/claim`, { token: t }, auth(cookies));
- claimed = { ok: true };
- } catch (e) {
- console.log(e);
- return e.message;
- }
- if (claimed.ok) {
- redirect(307, `/${cookies.get("username")}/payments`);
- }
+ if (t.startsWith("cashu")) {
+ let { id } = await post("/cash", { token: t }, auth);
+ redirect(307, `/ecash/${id}`);
}
// user
diff --git a/src/lib/utils.js b/src/lib/utils.js
index ac6e9216..d6238842 100644
--- a/src/lib/utils.js
+++ b/src/lib/utils.js
@@ -187,7 +187,7 @@ export let fd = async (req) => {
export let f = (s, currency) => {
try {
- return new Intl.NumberFormat("en-US", {
+ return new Intl.NumberFormat("en-US", {
style: "currency",
currency,
})
@@ -288,7 +288,7 @@ export let types = {
lightning: "lightning",
internal: "internal",
fund: "fund",
- ecash: "ecash"
+ ecash: "ecash",
};
export let ease = (t) =>
diff --git a/src/locales/en.json b/src/locales/en.json
index 01d5ebfc..ee2cf878 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -317,7 +317,7 @@
"takeFunds": "Take Funds",
"show": "Show",
"hide": "Hide",
- "voucher": "Redeem voucher",
+ "voucher": "Payment code",
"qr": "QR",
"copy": "Copy",
"copyLink": "Copy link",
@@ -325,7 +325,7 @@
"openLink": "Open wallet",
"setAmount": "Set amount",
"moreOptions": "More options",
- "redeemVoucher": "Ecash/lnurlw voucher",
+ "redeemVoucher": "Ecash or LNURLw",
"total": "Total",
"gainLoss": "Gain/Loss",
"presentValue": "Present Value",
@@ -367,6 +367,7 @@
"tapAnywhere": "Tap anywhere to continue",
"from": "from",
"redeem": "Redeem",
+ "swap": "Swap",
"redeemed": "Redeemed",
"redeemedBy": "Redeemed by",
"sendMessage": "Write a message...",
diff --git a/src/routes/(app)/[username]/invoice/[id]/+page.svelte b/src/routes/(app)/[username]/invoice/[id]/+page.svelte
index cdffd199..423fc719 100644
--- a/src/routes/(app)/[username]/invoice/[id]/+page.svelte
+++ b/src/routes/(app)/[username]/invoice/[id]/+page.svelte
@@ -292,7 +292,7 @@
{/if}
{#if user?.id === invoice?.user?.id}
- <a href={`/voucher`}>
+ <a href={`/receive`} class="block">
<button
class="flex gap-2 text-center break-all rounded-2xl hover:opacity-80 py-5 px-6 w-full mx-auto justify-center border text-xl whitespace-nowrap text-secondary"
>
diff --git a/src/routes/(app)/[username]/payments/[...page]/+page.server.js b/src/routes/(app)/[username]/payments/[...page]/+page.server.js
index de692a86..4a539e43 100644
--- a/src/routes/(app)/[username]/payments/[...page]/+page.server.js
+++ b/src/routes/(app)/[username]/payments/[...page]/+page.server.js
@@ -22,5 +22,5 @@ export async function load({ cookies, depends, params, request }) {
let { count, payments, incoming, outgoing } = await get(url, auth(cookies));
let pages = new Array(Math.ceil(count / limit));
- return { payments, page, pages, start, end, incoming, outgoing};
+ return { payments, page, pages, start, end, incoming, outgoing };
}
diff --git a/src/routes/(app)/ecash/[id]/+layout.server.js b/src/routes/(app)/ecash/[id]/+layout.server.js
new file mode 100644
index 00000000..0b8b2917
--- /dev/null
+++ b/src/routes/(app)/ecash/[id]/+layout.server.js
@@ -0,0 +1,10 @@
+import { auth, get } from "$lib/utils";
+import { fail, redirect } from "@sveltejs/kit";
+import parse from "$lib/parse";
+
+export async function load({ cookies, params, request, url }) {
+ let { id } = params;
+ let { token, status } = await get(`/cash/${id}`);
+ let { spent, total, mint, external } = status;
+ return { id, token, spent, total, mint, external };
+}
diff --git a/src/routes/(app)/ecash/[id]/+layout.svelte b/src/routes/(app)/ecash/[id]/+layout.svelte
new file mode 100644
index 00000000..d3c95e00
--- /dev/null
+++ b/src/routes/(app)/ecash/[id]/+layout.svelte
@@ -0,0 +1,53 @@
+<script>
+ import AppHeader from "$comp/AppHeader.svelte";
+ import { getDecodedToken } from "@cashu/cashu-ts";
+ import { copy, sats, f, s } from "$lib/utils";
+ import { t } from "$lib/translations";
+ import Icon from "$comp/Icon.svelte";
+
+ export let data;
+
+ let { id, rates, user, token, total, spent, external, mint } = data;
+ let currency = user?.currency || "USD";
+ let rate = rates[currency];
+
+ let amount = total - spent;
+
+ $: amountFiat = parseFloat(((amount * rate) / sats).toFixed(2));
+ $: spentFiat = parseFloat(((spent * rate) / sats).toFixed(2));
+</script>
+
+<div class="container px-4 max-w-lg mx-auto space-y-5 mt-20">
+ <h1 class="px-3 md:px-0 text-center text-3xl md:text-4xl font-semibold">
+ {$t("payments.ecash")}
+ </h1>
+
+ {#if amount > 0}
+ <div class="text-center font-bold text-2xl">
+ <div>
+ {f(amountFiat, currency)}
+ </div>
+ <div>
+ <span class="text-secondary font-normal text-xl"
+ >⚡️{`${s(amount)}`}</span
+ >
+ </div>
+ </div>
+ {/if}
+
+ {#if spent > 0}
+ <div class="text-center font-bold text-2xl">
+ <div>
+ {f(spentFiat, currency)}
+ <span class=" text-red-600">{$t("payments.spent")}</span>
+ </div>
+ <div>
+ <span class="text-secondary font-normal text-xl"
+ >⚡️{`${s(spent)}`}</span
+ >
+ </div>
+ </div>
+ {/if}
+
+ <slot />
+</div>
diff --git a/src/routes/(app)/ecash/[id]/+page.server.js b/src/routes/(app)/ecash/[id]/+page.server.js
index 421c8cb6..15511174 100644
--- a/src/routes/(app)/ecash/[id]/+page.server.js
+++ b/src/routes/(app)/ecash/[id]/+page.server.js
@@ -1,11 +1,18 @@
-import { auth, get } from "$lib/utils";
import { fail, redirect } from "@sveltejs/kit";
-import parse from "$lib/parse";
+import { auth, fd, post } from "$lib/utils";
-export async function load({ cookies, params, request, url }) {
- let { id } = params;
- let { token, status } = await get(`/cash/${id}`);
- let spent = parseInt(status.spent);
- let total = parseInt(status.total);
- return { id, token, spent, total };
-}
+export const actions = {
+ default: async ({ cookies, request }) => {
+ let { token } = await fd(request);
+ let claimed;
+ try {
+ claimed = await post(`/claim`, { token }, auth(cookies));
+ claimed = { ok: true };
+ } catch (e) {
+ return fail(400, { error: e.message });
+ }
+ if (claimed?.ok) {
+ redirect(307, `/${cookies.get("username")}/payments`);
+ }
+ },
+};
diff --git a/src/routes/(app)/ecash/[id]/+page.svelte b/src/routes/(app)/ecash/[id]/+page.svelte
index 18a1cba2..375f168a 100644
--- a/src/routes/(app)/ecash/[id]/+page.svelte
+++ b/src/routes/(app)/ecash/[id]/+page.svelte
@@ -1,95 +1,64 @@
<script>
- import AppHeader from "$comp/AppHeader.svelte";
- import { getDecodedToken } from "@cashu/cashu-ts";
+ import { enhance } from "$app/forms";
import { copy, sats, f, s } from "$lib/utils";
import { t } from "$lib/translations";
import Icon from "$comp/Icon.svelte";
import { page } from "$app/stores";
export let data;
-
- let { id, rates, user, token, total, spent } = data;
- let currency = user?.currency || "USD";
- let rate = rates[currency];
-
- let amount = total - spent;
+ export let form;
let link = $page.url.href;
-
- $: amountFiat = parseFloat(((amount * rate) / sats).toFixed(2));
- $: spentFiat = parseFloat(((spent * rate) / sats).toFixed(2));
+ let { id, total, token, external, spent } = data;
</script>
-<div class="container px-4 max-w-lg mx-auto space-y-5 mt-20">
- <h1 class="px-3 md:px-0 text-center text-3xl md:text-4xl font-semibold">
- {$t("payments.ecash")}
- </h1>
-
- {#if amount > 0}
- <div class="text-center font-bold text-2xl">
- <div>
- {f(amountFiat, currency)}
- </div>
- <div>
- <span class="text-secondary font-normal text-xl"
- >⚡️{`${s(amount)}`}</span
- >
- </div>
+{#if form?.error}
+ <div class="mb-5">
+ <div class="text-red-600">
+ {form.error === "default" ? $t("error.unrecognizedInput") : form.error}
</div>
- {/if}
-
- {#if spent > 0}
- <div class="text-center font-bold text-2xl">
- <div>
- {f(spentFiat, currency)}
- <span class=" text-red-600">{$t("payments.spent")}</span>
- </div>
- <div>
- <span class="text-secondary font-normal text-xl"
- >⚡️{`${s(spent)}`}</span
- >
- </div>
- </div>
- {/if}
-
- <div class="flex flex-wrap gap-2 text-xl">
- <button
- type="button"
- class="flex border rounded-2xl px-6 py-5 font-bold hover:opacity-80 w-full justify-center gap-2"
- on:click={() => copy(link)}
- >
- <Icon icon="link" style="w-8 my-auto" />
- <div class="my-auto">{$t("payments.copyLink")}</div>
- </button>
+ </div>
+{/if}
- <!-- TODO we need animated QR's -->
- <!-- <a href={`/qr/${encodeURIComponent(token)}`} class="contents"> -->
- <!-- <button -->
- <!-- type="button" -->
- <!-- class="flex border rounded-2xl px-6 py-5 font-bold hover:opacity-80 w-full justify-center gap-2" -->
- <!-- > -->
- <!-- <Icon icon="qr" style="w-8 my-auto invert" /> -->
- <!-- <div class="my-auto">{$t("payments.qr")}</div> -->
- <!-- </button> -->
- <!-- </a> -->
+<div class="flex flex-wrap gap-2 text-xl">
+ <button
+ type="button"
+ class="flex border rounded-2xl px-6 py-5 font-bold hover:opacity-80 w-full justify-center gap-2"
+ on:click={() => copy(link)}
+ >
+ <Icon icon="link" style="w-8 my-auto" />
+ <div class="my-auto">{$t("payments.copyLink")}</div>
+ </button>
- {#if spent < total}
- <a href={`/voucher/${id}`} class="contents">
+ {#if spent < total}
+ {#if external}
+ <a href={`/ecash/${id}/swap`} class="contents">
<button
- type="button"
+ type="submit"
class="flex border rounded-2xl px-6 py-5 font-bold hover:opacity-80 w-full justify-center gap-2"
>
<Icon icon="receive" style="w-8 my-auto" />
- <div class="my-auto">{$t("payments.redeem")}</div>
+ <div class="my-auto">{$t("payments.swap")}</div>
</button>
</a>
+ {:else}
+ <form method="POST" use:enhance class="w-full">
+ <input type="hidden" name="token" bind:value={token} />
+ <button
+ type="submit"
+ class="flex border rounded-2xl px-6 py-5 font-bold hover:opacity-80 w-full justify-center gap-2"
+ >
+ <Icon icon="receive" style="w-8 my-auto" />
+ <div class="my-auto">{$t("payments.redeem")}</div>
+ </button>
+ </form>
{/if}
+ {/if}
- <button
- class="border rounded-2xl px-6 py-5 w-full break-all text-xl hover:bg-slate-100"
- on:click={() => copy(token)}
- >
- {token}
- </button>
- </div>
+ <button
+ class="border rounded-2xl px-6 py-5 w-full break-all text-xl hover:bg-slate-100"
+ on:click={() => copy(token)}
+ >
+ {token}
+ </button>
</div>
diff --git a/src/routes/(app)/ecash/[id]/swap/+page.server.ts b/src/routes/(app)/ecash/[id]/swap/+page.server.ts
new file mode 100644
index 00000000..c8806bf0
--- /dev/null
+++ b/src/routes/(app)/ecash/[id]/swap/+page.server.ts
@@ -0,0 +1,3 @@
+ export async function load() {
+ return { test: 123 };
+}
diff --git a/src/routes/(app)/ecash/[id]/swap/+page.svelte b/src/routes/(app)/ecash/[id]/swap/+page.svelte
new file mode 100644
index 00000000..3df9504d
--- /dev/null
+++ b/src/routes/(app)/ecash/[id]/swap/+page.svelte
@@ -0,0 +1,5 @@
+<script>
+ export let data;
+</script>
+
+<div class="text-center">Support for swapping in cash from other mints is coming soon</div>
diff --git a/src/routes/(app)/pay/[username]/[...amount]/+page.svelte b/src/routes/(app)/pay/[username]/[...amount]/+page.svelte
index 1652952a..ffe6eac3 100644
--- a/src/routes/(app)/pay/[username]/[...amount]/+page.svelte
+++ b/src/routes/(app)/pay/[username]/[...amount]/+page.svelte
@@ -64,6 +64,8 @@
</div>
{/if}
+{rate}
+
<div class="container px-4 mt-20 max-w-xl mx-auto space-y-8">
<Numpad
bind:amount={a}
diff --git a/src/routes/(app)/receive/[...token]/+page.server.js b/src/routes/(app)/receive/[...token]/+page.server.js
new file mode 100644
index 00000000..30b42f32
--- /dev/null
+++ b/src/routes/(app)/receive/[...token]/+page.server.js
@@ -0,0 +1,17 @@
+import { auth, fd, get, post } from "$lib/utils";
+import { error, fail, redirect } from "@sveltejs/kit";
+import parse from "$lib/parse";
+
+export async function load({ cookies, params, parent, url }) {
+ let { user } = await parent();
+ if (!user) redirect(307, `/register?redirect=${url.pathname}`);
+ await parse(params.token, url.host, cookies);
+}
+
+export const actions = {
+ default: async ({ cookies, request, url }) => {
+ let { text } = await fd(request);
+ let msg = await parse(text, url.host, cookies);
+ return fail(400, { error: msg || "default" });
+ },
+};
diff --git a/src/routes/(app)/voucher/[...token]/+page.svelte b/src/routes/(app)/receive/[...token]/+page.svelte
index 2fd4b879..2fd4b879 100644
--- a/src/routes/(app)/voucher/[...token]/+page.svelte
+++ b/src/routes/(app)/receive/[...token]/+page.svelte
diff --git a/src/routes/(app)/redeem/[redeemcode]/+page.server.js b/src/routes/(app)/redeem/[redeemcode]/+page.server.js
deleted file mode 100644
index 25153533..00000000
--- a/src/routes/(app)/redeem/[redeemcode]/+page.server.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import { error, redirect } from "@sveltejs/kit";
-import { auth, post } from "$lib/utils";
-
-export async function load({ cookies, locals, params }) {
- let { user } = locals;
-
- if (user) {
- try {
- await post("/redeem", params, auth(cookies));
- } catch (e) {
- redirect(307, "/");
- }
- redirect(307, `/${user.username}/payments`);
- }
-
- redirect(307, "/login");
-}
diff --git a/src/routes/(app)/redeem/[redeemcode]/+page.svelte b/src/routes/(app)/redeem/[redeemcode]/+page.svelte
deleted file mode 100644
index b2fcf2f4..00000000
--- a/src/routes/(app)/redeem/[redeemcode]/+page.svelte
+++ /dev/null
@@ -1,4 +0,0 @@
-<script>
- import { loginRedirect } from "$lib/store";
- $loginRedirect = undefined;
-</script>
diff --git a/src/routes/(app)/send/[...text]/+page.server.js b/src/routes/(app)/send/[...text]/+page.server.js
index c1ba5945..ba5d6190 100644
--- a/src/routes/(app)/send/[...text]/+page.server.js
+++ b/src/routes/(app)/send/[...text]/+page.server.js
@@ -1,9 +1,10 @@
-import { auth, get } from "$lib/utils";
+import { auth, fd, get } from "$lib/utils";
import { fail, redirect } from "@sveltejs/kit";
import parse from "$lib/parse";
export async function load({ cookies, params, request, url }) {
let { text } = params;
+
await parse(text, url.host, cookies);
let contacts = await get("/contacts", auth(cookies));
return { contacts };
@@ -11,9 +12,8 @@ export async function load({ cookies, params, request, url }) {
export const actions = {
default: async ({ cookies, request, url }) => {
- const form = await request.formData();
- let t = form.get("text");
- let msg = await parse(t, url.host, cookies);
+ let { text } = await fd(request);
+ let msg = await parse(text, url.host, cookies);
return fail(400, { error: msg || "default" });
},
};
diff --git a/src/routes/(app)/send/ecash/+page.server.js b/src/routes/(app)/send/ecash/+page.server.js
index ed002ace..cef1ba78 100644
--- a/src/routes/(app)/send/ecash/+page.server.js
+++ b/src/routes/(app)/send/ecash/+page.server.js
@@ -1,11 +1,11 @@
-import { error, redirect } from "@sveltejs/kit";
+import { error, redirect, Cookies } from "@sveltejs/kit";
import { auth, post, fd } from "$lib/utils";
import { v4 } from "uuid";
export const actions = {
default: async ({ cookies, request }) => {
let id;
- let body = await fd(request);
+ let body = await fd(request);
try {
({ id } = await post("/mint", body, auth(cookies)));
diff --git a/src/routes/(app)/voucher/[...token]/+page.server.js b/src/routes/(app)/voucher/[...token]/+page.server.js
deleted file mode 100644
index cb04224e..00000000
--- a/src/routes/(app)/voucher/[...token]/+page.server.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import { validate } from "bitcoin-address-validation";
-import bip21 from "bip21";
-import { auth, get, isLiquid, post } from "$lib/utils";
-import { error, fail, redirect } from "@sveltejs/kit";
-import { PUBLIC_DOMAIN } from "$env/static/public";
-import parse from "$lib/parse";
-import { test } from "$lib/parse";
-
-export async function load({ cookies, params, parent, request, url }) {
- let { user } = await parent();
- if (!user) redirect(307, `/register?redirect=${url.pathname}`);
-
- let { token } = params;
- if (token && !token.startsWith("cashu"))
- ({ token } = await get(`/cash/${token}`));
- await parse(token, url.host, cookies);
-
- if (token) error(409, "Token could not be redeemed. Was it already spent?");
-}
-
-export const actions = {
- default: async ({ cookies, request, url }) => {
- const form = await request.formData();
- let t = form.get("text");
- if (t.startsWith("cashu")) {
- let { id } = await post("/cash", { token: t }, auth);
- redirect(307, `/ecash/${id}`);
- }
- let msg = await parse(t, url.host, cookies);
- return fail(400, { error: msg || "default" });
- },
-};
diff --git a/svelte.config.js b/svelte.config.js
index bc89e810..4b532ead 100644
--- a/svelte.config.js
+++ b/svelte.config.js
@@ -1,13 +1,9 @@
// import adapter from '@sveltejs/adapter-node';
import adapter from "svelte-adapter-bun";
-import preprocess from "svelte-preprocess";
+ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
const config = {
- preprocess: [
- preprocess({
- postcss: true,
- }),
- ],
+ preprocess: vitePreprocess(),
kit: {
adapter: adapter(),
csrf: {
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 00000000..03525465
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "extends": "./.svelte-kit/tsconfig.json",
+ "compilerOptions": {
+ "allowJs": true,
+ "checkJs": true,
+ "esModuleInterop": true,
+ "forceConsistentCasingInFileNames": true,
+ "resolveJsonModule": true,
+ "skipLibCheck": true,
+ "sourceMap": true,
+ "strict": true,
+ "moduleResolution": "bundler"
+ }
+}