aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2024-09-05 12:12:39 -0700
committerAdam Soltys <[email protected]>2024-09-05 12:12:39 -0700
commitac63d9cb30690f335616aa046e2b6512b05ecb44 (patch)
tree654bedd4409fb3298d042141cc3d23c130ab29f2
parent33d67e431416ea8b69b424e7d043ef63953c355a (diff)
downloadcoinos-server-ac63d9cb30690f335616aa046e2b6512b05ecb44.tar.gz
coinos-server-ac63d9cb30690f335616aa046e2b6512b05ecb44.zip
update sample config
-rw-r--r--compose.yml.sample2
-rw-r--r--config.ts.sample5
-rw-r--r--lib/invoices.ts11
-rw-r--r--lib/payments.ts58
-rw-r--r--routes/invoices.ts2
-rw-r--r--routes/payments.ts16
6 files changed, 61 insertions, 33 deletions
diff --git a/compose.yml.sample b/compose.yml.sample
index 2fc90b1b..a64cd650 100644
--- a/compose.yml.sample
+++ b/compose.yml.sample
@@ -16,7 +16,7 @@ services:
- '3119:3119'
volumes:
- .aws/:/root/.aws
- - ./:/app
+ - ./:/home/bun/app
- ./logs:/logs
restart: always
bc:
diff --git a/config.ts.sample b/config.ts.sample
index d5726fc4..5cc25dff 100644
--- a/config.ts.sample
+++ b/config.ts.sample
@@ -28,8 +28,9 @@ export default {
port: 7040,
btc: "5ac9f65c0efcc4775e0baec4ec03abdde22473cd3cf33c0419ca290e0751b225"
},
- lightning: "/app/data/lightning/regtest/lightning-rpc"
+ lightning: "/home/bun/app/data/lightning/regtest/lightning-rpc"
fee: 0.001,
adminpass: "pwa",
- support: "[email protected]"
+ support: "[email protected]",
+ nostrKey: "nsec13wekuqstlsyfrzm369yh6vjaphslq5pq9kze74acqqynjm8lvpms4qzsx9",
};
diff --git a/lib/invoices.ts b/lib/invoices.ts
index ee0eb73d..1532271e 100644
--- a/lib/invoices.ts
+++ b/lib/invoices.ts
@@ -1,8 +1,10 @@
+import config from "$config";
import { emit } from "$lib/sockets";
import { db, g, s } from "$lib/db";
import { getUser, bip21, fail, SATS } from "$lib/utils";
import { types } from "$lib/payments";
import { v4 } from "uuid";
+import rpc from "$lib/rpc";
import bc_ from "$lib/bitcoin";
import lq_ from "$lib/liquid";
@@ -14,6 +16,7 @@ let lq = lq_ as any;
export let generate = async ({ invoice, user, sender = undefined }) => {
let {
bolt11,
+ account,
currency,
expiry,
fiat,
@@ -49,7 +52,12 @@ export let generate = async ({ invoice, user, sender = undefined }) => {
let id = v4();
let hash, text;
- if (type === types.lightning) {
+
+ if (account) {
+ bc = rpc({...config.bitcoin, wallet: account });
+ hash = await bc.getNewAddress();
+ text = bip21(hash, invoice);
+ } else if (type === types.lightning) {
let r;
if (bolt11) {
let { id: nodeid } = await ln.getinfo();
@@ -84,6 +92,7 @@ export let generate = async ({ invoice, user, sender = undefined }) => {
invoice = {
amount,
+ account,
created: Date.now(),
currency,
hash,
diff --git a/lib/payments.ts b/lib/payments.ts
index 797b3a97..93727285 100644
--- a/lib/payments.ts
+++ b/lib/payments.ts
@@ -21,11 +21,16 @@ import got from "got";
import { mqtt1, mqtt2 } from "$lib/mqtt";
import { mail, templates } from "$lib/mail";
import api from "$lib/api";
+import rpc from "$lib/rpc";
+import { bech32 } from "bech32";
-import lq from "$lib/liquid";
-import bc from "$lib/bitcoin";
+import bc_ from "$lib/bitcoin";
+import lq_ from "$lib/liquid";
import ln from "$lib/ln";
+let bc = bc_ as any;
+let lq = lq_ as any;
+
let { URL } = process.env;
export let types = {
@@ -41,10 +46,10 @@ export let debit = async ({
hash,
amount,
fee = 0,
- memo,
+ memo = undefined,
user,
type = types.internal,
- rate,
+ rate = undefined,
}) => {
amount = parseInt(amount);
if (type !== types.internal && (await g("freeze")))
@@ -53,8 +58,8 @@ export let debit = async ({
// fail(`⚡️${amount} exceeds max withdrawal of ⚡️1,000,000`);
let ref;
let { id: uid, currency } = user;
-
- let rates = await g('rates');
+
+ let rates = await g("rates");
if (!rate) rate = rates[currency];
let invoice = await getInvoice(hash);
@@ -81,7 +86,9 @@ export let debit = async ({
if (!amount || amount < 0) fail("Amount must be greater than zero");
- let ourfee = [types.bitcoin, types.liquid, types.lightning].includes(type)
+ let ourfee: any = [types.bitcoin, types.liquid, types.lightning].includes(
+ type,
+ )
? Math.round((amount + fee + tip) * config.fee)
: 0;
@@ -102,6 +109,7 @@ export let debit = async ({
amount: -amount,
fee,
hash,
+ hex: undefined,
ourfee,
memo,
iid,
@@ -145,14 +153,13 @@ export let credit = async (hash, amount, memo, ref, type = types.internal) => {
let user = await g(`user:${inv.uid}`);
let { id: uid, currency, username } = user;
- let rates = await g('rates');
+ let rates = await g("rates");
let rate = rates[currency];
if (!rate) await sleep(1000);
rate = rates[currency];
- let equivalentRate =
- inv.rate * (rates[currency] / rates[inv.currency]);
+ let equivalentRate = inv.rate * (rates[currency] / rates[inv.currency]);
if (Math.abs(inv.rate / rates[inv.currency] - 1) < 0.01) {
rate = equivalentRate;
@@ -165,7 +172,7 @@ export let credit = async (hash, amount, memo, ref, type = types.internal) => {
id,
iid: inv.id,
hash,
- amount: parseInt(amount - tip),
+ amount: amount - tip,
uid,
rate,
currency,
@@ -175,6 +182,7 @@ export let credit = async (hash, amount, memo, ref, type = types.internal) => {
type,
confirmed: true,
created: Date.now(),
+ items: [],
};
if ([types.bitcoin, types.liquid].includes(type)) inv.pending += amount;
@@ -303,15 +311,15 @@ let pay = async ({ amount, to, user }) => {
lnurl = `https://${domain}/.well-known/lnurlp/${name}`;
} else if (to.startsWith("lnurl")) {
lnurl = Buffer.from(
- bech32.fromWords(bech32.decode(text, 20000).words),
+ bech32.fromWords(bech32.decode(to, 20000).words),
).toString();
}
let maxfee = getMaxFee(amount);
if (lnurl) {
amount -= maxfee;
- let { callback } = await got(lnurl).json();
- ({ pr } = await got(`${callback}?amount=${amount * 1000}`).json());
+ let { callback } = (await got(lnurl).json()) as any;
+ ({ pr } = (await got(`${callback}?amount=${amount * 1000}`).json()) as any);
} else if (to.startsWith("ln")) {
amount -= maxfee;
pr = to;
@@ -345,7 +353,7 @@ export let sendOnchain = async (params) => {
if (!hex) ({ hex } = await build(params));
let { tx, type } = await decode(hex);
- let node = getNode(type);
+ let node = await getNode(type);
let { txid } = tx;
try {
@@ -449,7 +457,13 @@ let getMaxFee = (n) =>
let checking = {};
let inflight = {};
-export let sendLightning = async ({ user, pr, amount, maxfee, memo }) => {
+export let sendLightning = async ({
+ user,
+ pr,
+ amount,
+ maxfee,
+ memo = undefined,
+}) => {
try {
if (inflight[user.id]) fail("payment in flight");
inflight[user.id] = true;
@@ -463,7 +477,7 @@ export let sendLightning = async ({ user, pr, amount, maxfee, memo }) => {
}
let total = amount;
- let { amount_msat, payment_hash } = await ln.decode(pr);
+ let { amount_msat } = await ln.decode(pr);
if (amount_msat) total = Math.round(amount_msat / 1000);
maxfee = parseInt(maxfee) || getMaxFee(total);
@@ -566,9 +580,11 @@ export let sendLightning = async ({ user, pr, amount, maxfee, memo }) => {
}
};
-export let getNode = (type) => {
+export let getNode = async (type, wallet = undefined) => {
if (type === types.bitcoin) return bc;
else if (type === types.liquid) return lq;
+ else if ((await g(`${wallet}:balance`)) !== null)
+ return rpc({ ...config.bitcoin, wallet });
else fail("unrecognized transaction type");
};
@@ -589,11 +605,13 @@ let getAddressType = async (a) => {
export let build = async ({ amount, address, feeRate, user, subtract }) => {
let type = await getAddressType(address);
- let node = getNode(type);
+ let node = await getNode(type);
amount = parseInt(amount);
if (amount < 0) fail("invalid amount");
- let fees = await fetch(`${api[type]}/fees/recommended`).then((r) => r.json());
+ let fees: any = await fetch(`${api[type]}/fees/recommended`).then((r) =>
+ r.json(),
+ );
if (!feeRate) {
feeRate = fees.halfHourFee;
diff --git a/routes/invoices.ts b/routes/invoices.ts
index 5e786dd7..77ff2ac1 100644
--- a/routes/invoices.ts
+++ b/routes/invoices.ts
@@ -5,7 +5,7 @@ import { bail, pick } from "$lib/utils";
export default {
async get(req, res) {
let {
- params: { id },
+ params: { id },
} = req;
let invoice = await g(`invoice:${id}`);
if (typeof invoice === "string") invoice = await g(`invoice:${invoice}`);
diff --git a/routes/payments.ts b/routes/payments.ts
index 38215832..9ebc0062 100644
--- a/routes/payments.ts
+++ b/routes/payments.ts
@@ -4,7 +4,7 @@ import { generate } from "$lib/invoices";
import { v4 } from "uuid";
import { db, g, s, t } from "$lib/db";
import { l, err, warn } from "$lib/logging";
-import { bail, fail, getInvoice, btc, sats, SATS, getUser } from "$lib/utils";
+import { bail, fail, getInvoice, sats, SATS, getUser } from "$lib/utils";
import { requirePin } from "$lib/auth";
import {
completePayment,
@@ -253,7 +253,7 @@ export default {
} = req;
try {
- let node = getNode(type);
+ let node = await getNode(type, wallet);
if (wallet === config.bitcoin.wallet || wallet === config.liquid.wallet) {
let { confirmations, details } = await node.getTransaction(txid);
@@ -400,16 +400,16 @@ export default {
await requirePin({ body, user });
let [username, domain] = lnaddress.split("@");
- let { minSendable, maxSendable, callback, metadata } = await got(
+ let { minSendable, maxSendable, callback, metadata } = (await got(
`https://${domain}/.well-known/lnurlp/${username}`,
- ).json();
+ ).json()) as any;
let memo = metadata["text/plain"] || "";
if (amount * 1000 < minSendable || amount * 1000 > maxSendable)
fail("amount out of range");
- let r = await got(`${callback}?amount=${amount * 1000}`).json();
- if (r.reason) fail(r.rason);
+ let r: any = await got(`${callback}?amount=${amount * 1000}`).json();
+ if (r.reason) fail(r.reason);
let { pr } = r;
let p = await sendLightning({ user, pr, amount, maxfee, memo });
@@ -445,9 +445,9 @@ export default {
if (p.uid !== user.id) fail("unauthorized");
let { tx, type } = await decode(p.hex);
- let node = getNode(type);
+ let node = await getNode(type);
- let fees = await fetch(`${api[type]}/fees/recommended`).then((r) =>
+ let fees: any = await fetch(`${api[type]}/fees/recommended`).then((r) =>
r.json(),
);