From 2a408a3a7486464296e4e7f996fc2140a664d407 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Wed, 26 Nov 2025 10:56:20 -0800 Subject: ark --- index.ts | 2 ++ lib/db.ts | 2 +- lib/invoices.ts | 15 ++++++++++-- lib/types.ts | 1 + routes/invoices.ts | 4 +++- routes/payments.ts | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 87 insertions(+), 4 deletions(-) diff --git a/index.ts b/index.ts index 44d91d93..faab936d 100644 --- a/index.ts +++ b/index.ts @@ -89,6 +89,7 @@ app.post("/gateway", payments.gateway); app.post("/replace", auth, payments.replace); app.get("/decode/:bolt11", payments.decode); app.post("/fetchinvoice", payments.fetchinvoice); +app.post("/ark/receive", auth, payments.arkReceive); app.get("/square/connect", auth, square.connect); app.get("/square/auth", auth, square.auth); @@ -108,6 +109,7 @@ app.post("/freeze", payments.freeze); app.post("/confirm", payments.confirm); app.post("/bitcoin/fee", auth, payments.fee); app.post("/bitcoin/send", auth, payments.send); +app.post("/ark/send", auth, payments.ark); app.get("/account/:id", auth, users.account); app.post("/account/:id", auth, users.updateAccount); diff --git a/lib/db.ts b/lib/db.ts index 12e89757..91770824 100644 --- a/lib/db.ts +++ b/lib/db.ts @@ -1,7 +1,7 @@ import config from "$config"; +import { err, warn } from "$lib/logging"; import { fail, sleep } from "$lib/utils"; import { createClient, defineScript } from "redis"; -import { warn, err } from "$lib/logging"; const DEBIT = ` local balanceKey = KEYS[1] diff --git a/lib/invoices.ts b/lib/invoices.ts index ad0b604e..9666d217 100644 --- a/lib/invoices.ts +++ b/lib/invoices.ts @@ -22,6 +22,7 @@ export const generate = async ({ invoice, user }) => { expiry, fiat, id, + hash, tip, amount, items = [], @@ -59,11 +60,21 @@ export const generate = async ({ invoice, user }) => { if (!id) id = v4(); - let hash; let text; let paymentHash; - if (type === PaymentType.lightning) { + if (account.seed) { + if (type !== PaymentType.ark) { + type = PaymentType.bitcoin; + const node = rpc({ ...config[type], wallet: aid }); + hash = await node.getNewAddress({ address_type }); + text = bip21(hash, invoice); + + ({ hdkeypath: path } = await node.getAddressInfo(hash)); + } else { + text = hash; + } + } else if (type === PaymentType.lightning) { let r; if (bolt11) { const { id: nodeid } = await ln.getinfo(); diff --git a/lib/types.ts b/lib/types.ts index e878dfb8..ad58bf38 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -46,6 +46,7 @@ export interface User { } export enum PaymentType { + ark = "ark", internal = "internal", bitcoin = "bitcoin", lightning = "lightning", diff --git a/routes/invoices.ts b/routes/invoices.ts index a18f4263..63338621 100644 --- a/routes/invoices.ts +++ b/routes/invoices.ts @@ -4,6 +4,7 @@ import { generate } from "$lib/invoices"; import { err } from "$lib/logging"; import { bail, fail, fields, getInvoice, getUser } from "$lib/utils"; import rpc from "@coinos/rpc"; +import { v4 } from "uuid"; export default { async get(req, res) { @@ -53,7 +54,7 @@ export default { try { const { id } = req.params; const { body } = req; - const { tip, webhook, secret } = body.invoice; + const { tip, webhook, secret, received } = body.invoice; if (tip < 0) fail("Invalid tip"); @@ -69,6 +70,7 @@ export default { } invoice = await generate({ invoice, user }); + await s(`invoice:${id}`, invoice); res.send(invoice); diff --git a/routes/payments.ts b/routes/payments.ts index a640d8e2..cfbae56b 100644 --- a/routes/payments.ts +++ b/routes/payments.ts @@ -749,4 +749,71 @@ export default { bail(res, e.message); } }, + + async ark(req, res) { + const { user } = req; + const { amount, hash, aid } = req.body; + + const { currency } = user; + const rates = await g("rates"); + const rate = rates[currency]; + const p = { + id: v4(), + aid, + amount: -amount, + hash, + confirmed: true, + rate, + currency, + type: PaymentType.ark, + created: Date.now(), + }; + + res.send(p); + }, + + async arkReceive(req, res) { + try { + const { body, user } = req; + const { iid, amount } = body; + const { id: uid } = user; + + if (amount <= 0) fail("Invalid amount"); + + const invoice = await getInvoice(iid); + if (invoice.uid !== user?.id) fail("Unauthorized"); + invoice.received += amount; + + const { aid, type, currency } = invoice; + const rates = await g("rates"); + const rate = rates[currency]; + + const p = { + id: v4(), + aid: aid, + iid, + amount, + hash, + confirmed: true, + rate, + currency, + type, + uid, + created: Date.now(), + }; + + const m = await db.multi(); + m.set(`invoice:${invoice.id}`, JSON.stringify(invoice)) + .set(`payment:${p.id}`, JSON.stringify(p)) + .lPush(`${aid || uid}:payments`, p.id) + .set(`${aid || uid}:payments:last`, p.created) + .exec(); + + await completePayment(invoice, p, user); + + res.send(p); + } catch (e) { + bail(res, e.message); + } + }, }; -- cgit v1.2.3