aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2025-07-07 22:34:27 -0700
committerAdam Soltys <[email protected]>2025-07-07 22:34:27 -0700
commit209b1e64f1c4dda16a50e57c6570a3a35953085d (patch)
tree4e8b260e5b8f832b03dd41f17f65b42aba58f268 /src
parent1b1718a4b64275bac8e1fe519d33c67e3a95f2c5 (diff)
downloadcoinos-ui-209b1e64f1c4dda16a50e57c6570a3a35953085d.tar.gz
coinos-ui-209b1e64f1c4dda16a50e57c6570a3a35953085d.zip
fund sweep
Diffstat (limited to 'src')
-rw-r--r--src/lib/random.ts20
-rw-r--r--src/lib/utils.ts32
-rw-r--r--src/locales/en.json1
-rw-r--r--src/routes/(app)/fund/[id]/+page.svelte8
-rw-r--r--src/routes/(app)/fund/[id]/sweep/+page.server.ts24
-rw-r--r--src/routes/(app)/fund/[id]/sweep/+page.svelte8
-rw-r--r--src/routes/(app)/send/[...text]/+page.svelte27
-rw-r--r--src/routes/(static)/register/+page.server.ts38
8 files changed, 101 insertions, 57 deletions
diff --git a/src/lib/random.ts b/src/lib/random.ts
new file mode 100644
index 00000000..36dde0cc
--- /dev/null
+++ b/src/lib/random.ts
@@ -0,0 +1,20 @@
+import {
+ NumberDictionary,
+ animals,
+ colors,
+ uniqueNamesGenerator,
+} from "unique-names-generator";
+
+export const randomName = () =>
+ uniqueNamesGenerator({
+ dictionaries: [animals, NumberDictionary.generate({ min: 10, max: 99 })],
+ length: 2,
+ separator: "",
+ });
+
+export const randomPassword = () =>
+ uniqueNamesGenerator({
+ dictionaries: [colors, NumberDictionary.generate({ min: 100, max: 999 })],
+ length: 2,
+ separator: "",
+ });
diff --git a/src/lib/utils.ts b/src/lib/utils.ts
index 2e1bb840..31d93fde 100644
--- a/src/lib/utils.ts
+++ b/src/lib/utils.ts
@@ -3,6 +3,7 @@ import { goto } from "$app/navigation";
import { page } from "$app/stores";
import { PUBLIC_COINOS_NETWORK, PUBLIC_COINOS_URL } from "$env/static/public";
import { bytesToHex } from "@noble/hashes/utils";
+import { fail as svelteFail, redirect } from "@sveltejs/kit";
import { toast } from "@zerodevx/svelte-toast";
import {
differenceInDays,
@@ -456,3 +457,34 @@ export const ago = (t) => {
const days = differenceInDays(now, date);
return `${days}d`;
};
+
+export const register = async (user, ip, cookies, loginRedirect) => {
+ let error;
+
+ let sk;
+ try {
+ ({ sk } = await post("/register", { user }, { "cf-connecting-ip": ip }));
+ } catch (e) {
+ ({ message: error } = e as Error);
+ }
+
+ try {
+ await login(user, cookies, ip);
+ error = null;
+ } catch (e) {
+ const { message } = e as Error;
+ error ||= message;
+ }
+
+ const expires = new Date();
+ expires.setSeconds(expires.getSeconds() + 21000000);
+ cookies.set("sk", sk, {
+ path: "/",
+ expires,
+ httpOnly: false,
+ sameSite: "lax",
+ });
+
+ if (error) return svelteFail(400, { error });
+ redirect(303, loginRedirect || `/${user.username}`);
+};
diff --git a/src/locales/en.json b/src/locales/en.json
index fa3ad96d..43967158 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -398,6 +398,7 @@
}
},
"payments": {
+ "sweep": "Sweep link",
"lockedBalance": "Locked balance",
"insufficientFunds": "Insufficient funds",
"pending": "Pending",
diff --git a/src/routes/(app)/fund/[id]/+page.svelte b/src/routes/(app)/fund/[id]/+page.svelte
index f1a1838e..614616af 100644
--- a/src/routes/(app)/fund/[id]/+page.svelte
+++ b/src/routes/(app)/fund/[id]/+page.svelte
@@ -111,6 +111,14 @@
></iconify-icon>
<div class="my-auto">{$t("payments.shareLink")}</div>
</a>
+ <button
+ on:click={() => copy(`${$page.url.href}/sweep`)}
+ class="btn !w-auto grow"
+ >
+ <iconify-icon noobserver icon="ph:copy-bold" width="32"
+ ></iconify-icon>
+ <div class="my-auto">{$t("payments.sweep")}</div>
+ </button>
<!-- <a href={`/qr/${lnurlw}`} class="btn !w-auto grow"> -->
<!-- <iconify-icon -->
<!-- noobserver -->
diff --git a/src/routes/(app)/fund/[id]/sweep/+page.server.ts b/src/routes/(app)/fund/[id]/sweep/+page.server.ts
index 5bb42fa4..3e0b8dad 100644
--- a/src/routes/(app)/fund/[id]/sweep/+page.server.ts
+++ b/src/routes/(app)/fund/[id]/sweep/+page.server.ts
@@ -1,13 +1,27 @@
-import { get, auth, post } from "$lib/utils";
+import { randomName, randomPassword } from "$lib/random";
+import getRates from "$lib/rates";
+import { auth, get, post, register } from "$lib/utils";
import { redirect } from "@sveltejs/kit";
-export async function load({ cookies, params, parent }) {
- const { user } = await parent();
+export async function load({ cookies, request, params, parent }) {
+ let { user } = await parent();
const { id } = params;
const { amount } = await get(`/fund/${id}`);
+ const rates = await getRates();
+ const rate = rates[user?.currency || "USD"];
if (!amount) redirect(307, `/fund/${id}`);
- if (!user) redirect(307, `/register?redirect=/fund/${id}/sweep`);
+ if (!user) {
+ const ip = request.headers.get("cf-connecting-ip");
+
+ user = {
+ username: randomName(),
+ password: randomPassword(),
+ };
+
+ await register(user, ip, cookies, `/fund/${id}/sweep`);
+ }
+
await post("/take", { amount, id }, auth(cookies));
- return { amount, id };
+ return { amount, id, rate, rates };
}
diff --git a/src/routes/(app)/fund/[id]/sweep/+page.svelte b/src/routes/(app)/fund/[id]/sweep/+page.svelte
index cd89f6ae..0523b85a 100644
--- a/src/routes/(app)/fund/[id]/sweep/+page.svelte
+++ b/src/routes/(app)/fund/[id]/sweep/+page.svelte
@@ -12,12 +12,6 @@
</script>
<div class="container px-4 max-w-xl mx-auto mt-10 space-y-5 text-center">
- <div class="w-full flex">
- <a href="/" class="mx-auto">
- <Icon icon="logo" />
- </a>
- </div>
-
<div class="flex w-full py-5 max-w-[200px] mx-auto" in:scale={{ start: 0.5 }}>
<Icon icon="check" style="mx-auto" />
</div>
@@ -32,7 +26,7 @@
</h3>
</div>
-<a href={`/payments`}>
+<a href={`/${user.username}`}>
<div class="opacity-0 w-screen h-screen fixed top-0 left-0 z-50"></div>
</a>
diff --git a/src/routes/(app)/send/[...text]/+page.svelte b/src/routes/(app)/send/[...text]/+page.svelte
index 183b4b51..e5c77647 100644
--- a/src/routes/(app)/send/[...text]/+page.svelte
+++ b/src/routes/(app)/send/[...text]/+page.svelte
@@ -73,18 +73,7 @@
</div>
</div>
{/if}
-
- <textarea
- use:focus
- name="text"
- placeholder={$t("user.send.placeholder")}
- onkeypress={keypress}
- class="w-full p-4 border rounded-xl h-32 text-xl"
- bind:value={text}
- onpaste={() => (pasted = true)}
- autocapitalize="none"
- ></textarea>
-
+
<div class="flex gap-2">
<a href="/scan" class="contents">
<button type="button" class="btn !w-auto flex-grow">
@@ -101,6 +90,18 @@
</button>
</div>
+ <textarea
+ use:focus
+ name="text"
+ placeholder={$t("user.send.placeholder")}
+ onkeypress={keypress}
+ class="w-full p-4 border rounded-xl h-32 text-xl"
+ bind:value={text}
+ onpaste={() => (pasted = true)}
+ autocapitalize="none"
+ ></textarea>
+
+
<button bind:this={el} type="submit" class="btn btn-accent">
<iconify-icon noobserver icon="ph:paper-plane-right-bold" width="32"
></iconify-icon>
@@ -152,7 +153,7 @@
</div>
{/if}
- {#if !loaded}
+ {#if !loaded && contacts.length > 0}
<button onclick={loadMore} type="button" class="btn"
>{$t("user.loadMore")}</button
>
diff --git a/src/routes/(static)/register/+page.server.ts b/src/routes/(static)/register/+page.server.ts
index 2c2807bd..8c6d6a8d 100644
--- a/src/routes/(static)/register/+page.server.ts
+++ b/src/routes/(static)/register/+page.server.ts
@@ -1,5 +1,5 @@
-import { fd, get, login, post } from "$lib/utils";
-import { fail, redirect } from "@sveltejs/kit";
+import { fd, get, register } from "$lib/utils";
+import { redirect } from "@sveltejs/kit";
export const load = async ({ parent }) => {
const { user } = await parent();
@@ -14,39 +14,13 @@ export const load = async ({ parent }) => {
export const actions = {
default: async ({ cookies, request }) => {
const ip = request.headers.get("cf-connecting-ip");
-
const form = await fd(request);
- let { picture, username, password, pubkey, loginRedirect } = form;
- const user = { picture, username, password, pubkey };
- let error;
-
+ const { picture, username, password } = form;
+ let { loginRedirect } = form;
if (loginRedirect === "undefined") loginRedirect = undefined;
- let sk;
- try {
- ({ sk } = await post("/register", { user }, { "cf-connecting-ip": ip }));
- } catch (e) {
- ({ message: error } = e as Error);
- }
-
- try {
- await login(user, cookies, ip);
- error = null;
- } catch (e) {
- const { message } = e as Error;
- error ||= message;
- }
-
- const expires = new Date();
- expires.setSeconds(expires.getSeconds() + 21000000);
- cookies.set("sk", sk, {
- path: "/",
- expires,
- httpOnly: false,
- sameSite: "lax",
- });
-
- if (error) return fail(400, { error });
+ const user = { picture, username, password };
+ await register(user, ip, cookies, loginRedirect);
redirect(303, loginRedirect || `/${user.username}`);
},
};