aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-02-13 21:07:55 -0800
committerAdam Soltys <[email protected]>2026-02-13 21:08:04 -0800
commitc7c6ee7ba59467b8ddcfe8196b4f7586a864f3c0 (patch)
treefccdf94755fb1b91c1de65e9d18f2f94742ebe09 /lib
parentb2b9fe837db7308285909ec1b374546194405d00 (diff)
downloadcoinos-server-c7c6ee7ba59467b8ddcfe8196b4f7586a864f3c0.tar.gz
coinos-server-c7c6ee7ba59467b8ddcfe8196b4f7586a864f3c0.zip
account level currency and autowithdraw settings
Diffstat (limited to 'lib')
-rw-r--r--lib/invoices.ts5
-rw-r--r--lib/migrate.ts40
-rw-r--r--lib/payments.ts26
3 files changed, 63 insertions, 8 deletions
diff --git a/lib/invoices.ts b/lib/invoices.ts
index e6b6e146..bf6c511e 100644
--- a/lib/invoices.ts
+++ b/lib/invoices.ts
@@ -52,7 +52,10 @@ export const generate = async ({ invoice, user }) => {
aid = account.id;
const rates = await g("rates");
- if (!currency) currency = user.currency;
+ if (!currency) {
+ const acct = aid ? await g(`account:${aid}`) : null;
+ currency = acct?.currency || user.currency;
+ }
if (!rate) rate = rates[currency];
if (fiat) amount = Math.round((SATS * fiat) / rate);
if (amount < 0) fail("invalid amount");
diff --git a/lib/migrate.ts b/lib/migrate.ts
index 4b64bee5..d0e38276 100644
--- a/lib/migrate.ts
+++ b/lib/migrate.ts
@@ -136,4 +136,44 @@ export const migrateToMicrosats = async () => {
return count;
};
+export const migrateAutowithdraw = async () => {
+ const migrated = await db.get("autowithdraw:migrated");
+ if (migrated) return 0;
+
+ let count = 0;
+
+ for await (const k of db.scanIterator({ MATCH: "user:*" })) {
+ try {
+ const raw = await db.get(k);
+ if (!raw || !raw.startsWith("{")) continue;
+
+ const user = JSON.parse(raw);
+ if (!user.id || !user.autowithdraw) continue;
+
+ const accountIds = await db.lRange(`${user.id}:accounts`, 0, -1);
+
+ for (const aid of accountIds) {
+ const account = await g(`account:${aid}`);
+ if (!account) continue;
+ if (account.seed || account.type === "ark") continue;
+ if (account.autowithdraw) continue;
+
+ account.autowithdraw = true;
+ account.threshold = account.threshold ?? user.threshold;
+ account.reserve = account.reserve ?? user.reserve;
+ account.destination = account.destination ?? user.destination;
+
+ await s(`account:${aid}`, account);
+ count++;
+ }
+ } catch (e) {
+ warn("autowithdraw migration error", k, e.message);
+ }
+ }
+
+ await db.set("autowithdraw:migrated", Date.now().toString());
+ l(`Migrated autowithdraw to ${count} accounts`);
+ return count;
+};
+
export default migrate;
diff --git a/lib/payments.ts b/lib/payments.ts
index 3b6a4a86..e1254bad 100644
--- a/lib/payments.ts
+++ b/lib/payments.ts
@@ -166,8 +166,10 @@ export const debit = async ({
}
let ref;
- const { id: uid, currency } = user;
+ const { id: uid } = user;
if (!aid) aid = uid;
+ const debitAccount = aid && aid !== uid ? await g(`account:${aid}`) : null;
+ const currency = debitAccount?.currency || user.currency;
const rates = await g("rates");
if (!rate) rate = rates[currency];
@@ -293,7 +295,9 @@ export const credit = async ({
if (type === PaymentType.internal) amount += tip;
const user = await getUser(inv.uid);
- const { id: uid, currency } = user;
+ const { id: uid } = user;
+ const creditAccount = aid && aid !== uid ? await g(`account:${aid}`) : null;
+ const currency = creditAccount?.currency || user.currency;
const rates = await g("rates");
let rate = rates[currency];
@@ -373,7 +377,14 @@ export const credit = async ({
};
export const completePayment = async (inv, p, user) => {
- const { id, autowithdraw, threshold, reserve, destination, username } = user;
+ const { id, username } = user;
+ const aid = p.aid || id;
+ const account = aid !== id ? await g(`account:${aid}`) : null;
+ const autowithdraw = account?.autowithdraw;
+ const threshold = account?.threshold ?? user.threshold;
+ const reserve = account?.reserve ?? user.reserve;
+ const destination = account?.destination ?? user.destination;
+
let withdrawal;
if (p.confirmed) {
if (inv.forward && !inv.forwarded) {
@@ -399,11 +410,11 @@ export const completePayment = async (inv, p, user) => {
} else if (autowithdraw && p.type !== "ark") {
try {
const to = destination.trim();
- const balance = await getBalance(id);
+ const balance = await getBalance(aid);
const amount = balance - reserve;
if (balance > threshold) {
l("initiating autowithdrawal", amount, to, balance, threshold);
- const w = await pay({ amount, to, user });
+ const w = await pay({ aid, amount, to, user });
withdrawal = {
amount: fmt(-w.amount),
link: link(w.id),
@@ -1239,9 +1250,10 @@ export const importAccountHistory = async (account) => {
const total = confirmedUtxos.reduce((sum, u) => sum + u.value, 0);
const rates = await g("rates");
- let rate = rates[user.currency];
+ const currency = account.currency || user.currency;
+ let rate = rates[currency];
if (!rate) await sleep(1000);
- rate = rate || rates[user.currency];
+ rate = rate || rates[currency];
for (const u of confirmedUtxos) {
const existing = await getPayment(`${u.txid}:${u.vout}`);