aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/nostr.ts10
-rw-r--r--src/lib/parse.ts9
-rw-r--r--src/lib/server/ip.ts2
-rw-r--r--src/lib/utils.ts38
4 files changed, 51 insertions, 8 deletions
diff --git a/src/lib/nostr.ts b/src/lib/nostr.ts
index 6a8b179a..beebba02 100644
--- a/src/lib/nostr.ts
+++ b/src/lib/nostr.ts
@@ -117,8 +117,14 @@ export const sign = async (event, user) => {
eventToSign.set(event);
let unsubscribe;
- const { method, params } = await new Promise((r) => {
- unsubscribe = $signer.subscribe((v) => v?.ready && r(v));
+ const { method, params } = await new Promise((r, j) => {
+ unsubscribe = $signer.subscribe((v) => {
+ if (v === "cancel") {
+ j("cancelled");
+ $signer.set(undefined);
+ }
+ v?.ready && r(v);
+ });
});
await unsubscribe();
const signedEvent = await signingMethods[method](event, params);
diff --git a/src/lib/parse.ts b/src/lib/parse.ts
index 9c18504a..6ff4556c 100644
--- a/src/lib/parse.ts
+++ b/src/lib/parse.ts
@@ -1,10 +1,10 @@
import { PUBLIC_DOMAIN } from "$env/static/public";
import { decode } from "$lib/bip21";
-import { get, isLiquid, post, sats } from "$lib/utils";
+import { auth, get, isLiquid, post, sats } from "$lib/utils";
import { redirect } from "@sveltejs/kit";
import { validate } from "bitcoin-address-validation";
-export default async (s, host) => {
+export default async (s, host, cookies) => {
if (!s) return;
let t = s.trim();
let amount;
@@ -58,7 +58,10 @@ export default async (s, host) => {
if (t.toLowerCase().startsWith("lnurl")) redirect(307, `/ln/${t}`);
if (t.includes(":")) t = t.split(":")[1];
- if (t.toLowerCase().startsWith("ln")) {
+ if (t.toLowerCase().startsWith("lnr")) {
+ const { iid } = await post("/sendinvoice", { invreq: t }, auth(cookies));
+ invoice = { id: iid };
+ } else if (t.toLowerCase().startsWith("ln")) {
try {
invoice = await get(`/invoice/${t}`);
if (invoice.user.username === "mint") throw new Error("mint payment");
diff --git a/src/lib/server/ip.ts b/src/lib/server/ip.ts
new file mode 100644
index 00000000..cfd933ac
--- /dev/null
+++ b/src/lib/server/ip.ts
@@ -0,0 +1,2 @@
+import { AsyncLocalStorage } from "node:async_hooks";
+export const ipStore = new AsyncLocalStorage<string>();
diff --git a/src/lib/utils.ts b/src/lib/utils.ts
index 28a219e1..b981a4d4 100644
--- a/src/lib/utils.ts
+++ b/src/lib/utils.ts
@@ -21,11 +21,22 @@ export function scroll(section: any) {
const base = browser ? "" : PUBLIC_COINOS_URL;
+let getIp: (() => string | undefined) | undefined;
+
+export const setIpGetter = (fn: () => string | undefined) => {
+ getIp = fn;
+};
+
+const ipHeaders = (): Record<string, string> => {
+ const ip = getIp?.();
+ return ip ? { "cf-connecting-ip": ip } : {};
+};
+
export const punk = (k: string) =>
`${Math.floor((parseInt(k.slice(-2), 16) / 256) * 64) + 1}.webp`;
export const g = (url: string, fetch: any, headers: object) =>
- fetch(base + url, { headers })
+ fetch(base + url, { headers: { ...ipHeaders(), ...headers } })
.then((r: Response) => r.text())
.then((body: string) => {
try {
@@ -36,7 +47,7 @@ export const g = (url: string, fetch: any, headers: object) =>
});
export const get = (url: string, headers = {}) => {
- return fetch(base + url, { headers })
+ return fetch(base + url, { headers: { ...ipHeaders(), ...headers } })
.then(async (r) => {
if (r.ok) return r.text();
throw new Error(await r.text());
@@ -58,6 +69,7 @@ export const post = async (
headers = {
"content-type": "application/json",
accept: "application/json",
+ ...ipHeaders(),
...headers,
};
@@ -148,7 +160,13 @@ export const info = (m: string) => {
};
export const login = async (
- user: { username: string; password: string },
+ user: {
+ username: string;
+ password: string;
+ token?: string;
+ challenge?: string;
+ recaptcha?: string;
+ },
cookies,
ip: string,
) => {
@@ -193,6 +211,20 @@ export const auth = (cookies) => ({
authorization: `Bearer ${cookies.get("token")}`,
});
+export const isInvalidTokenError = (e: unknown) => {
+ const message = (e as Error)?.message || "";
+ if (!message) return false;
+ const normalized = message.toLowerCase();
+ return (
+ normalized.includes("jwt") ||
+ normalized.includes("invalid token") ||
+ normalized.includes("token expired") ||
+ normalized.includes("expired token") ||
+ normalized.includes("unauthorized") ||
+ normalized.includes("not authorized")
+ );
+};
+
export const btc = (fiat: number, rate: number): number =>
Math.round((fiat * sats) / rate);