aboutsummaryrefslogtreecommitdiffstats
path: root/routes
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2025-07-17 16:16:56 -0700
committerAdam Soltys <[email protected]>2025-07-17 16:16:56 -0700
commit8fae698d9ce0f318481ab739a63ea0a580372f86 (patch)
treef8be08e1f3c72d39087ed753811f7655787c7dc7 /routes
parent161678b774cee184fdb5afcf84686639acb7a5e2 (diff)
downloadcoinos-server-8fae698d9ce0f318481ab739a63ea0a580372f86.tar.gz
coinos-server-8fae698d9ce0f318481ab739a63ea0a580372f86.zip
square endpoints
Diffstat (limited to 'routes')
-rw-r--r--routes/invoices.ts1
-rw-r--r--routes/square.ts89
2 files changed, 90 insertions, 0 deletions
diff --git a/routes/invoices.ts b/routes/invoices.ts
index ecac713c..6c2f713d 100644
--- a/routes/invoices.ts
+++ b/routes/invoices.ts
@@ -28,6 +28,7 @@ export default {
if (body.user) user = body.user;
if (req.user.username === user.username) invoice.own = true;
+ else invoice.own = false;
try {
const result = await generate({ invoice, user });
diff --git a/routes/square.ts b/routes/square.ts
new file mode 100644
index 00000000..f7902e11
--- /dev/null
+++ b/routes/square.ts
@@ -0,0 +1,89 @@
+import * as crypto from "crypto";
+import config from "$config";
+import { db, g, s } from "$lib/db";
+import { generate } from "$lib/invoices";
+import { SATS, bail, getUser } from "$lib/utils";
+import { sha256 } from "@noble/hashes/sha256";
+import { utf8ToBytes } from "@noble/hashes/utils";
+import { base64urlnopad as base64 } from "@scure/base";
+import { SquareClient } from "square";
+
+const { scopes, url, appId, environment } = config.square;
+
+export default {
+ async connect(req, res) {
+ const { user } = req;
+
+ if (await db.exists(`${user.id}:square`)) {
+ return res.send("connected");
+ }
+
+ const codeVerifier = base64.encode(crypto.randomBytes(32));
+ await s(`${user.id}:codeVerifier`, codeVerifier);
+
+ const challenge = base64.encode(sha256(utf8ToBytes(codeVerifier)));
+
+ const state = base64.encode(crypto.randomBytes(12));
+ const scope = scopes.join("+");
+
+ res.send(
+ `${url}oauth2/authorize?client_id=${appId}&session=false&scope=${scope}&state=${state}&code_challenge=${challenge}`,
+ );
+ },
+
+ async auth(req, res) {
+ const { user } = req;
+
+ const codeVerifier = await g(`${user.id}:codeVerifier`);
+
+ const client = new SquareClient({
+ environment,
+ });
+
+ const { code } = req.query;
+
+ try {
+ const result = await client.oAuth.obtainToken({
+ code,
+ clientId: appId,
+ grantType: "authorization_code",
+ codeVerifier,
+ });
+
+ await s(`${user.id}:square`, result);
+ await s(result.merchantId, user.id);
+ res.send({});
+ } catch (e) {
+ console.log(e);
+ }
+ },
+
+ async payment(req, res) {
+ try {
+ const { body } = req;
+ const { data, type, merchant_id } = body;
+ const { payment } = data.object;
+
+ if (type === "payment.created" && payment.source_type === "CASH") {
+ const {
+ amount_money: { amount, currency },
+ } = payment;
+ const rates = await g("rates");
+ const rate = rates[currency];
+ const uid = await g(merchant_id);
+ const user = await getUser(uid);
+ const invoice = {
+ amount: Math.round(((amount / 100) * SATS) / rate),
+ own: true,
+ type: "lightning",
+ };
+
+ await generate({ invoice, user });
+ }
+
+ res.send({});
+ } catch (e) {
+ bail(res, e.message);
+ }
+ },
+};