aboutsummaryrefslogtreecommitdiffstats
path: root/routes/liquid/util/decrementacc.js
blob: eca785e0cbd740bf2355f2b339b8a5d4d1d16659 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
const btc = config.liquid.btcasset;

module.exports = async (user, transaction, limit, fee, assets, amount, address, memo, asset) => {
    let total = amount;

    if (asset === btc) {
        let covered = 0;
        let nonbtc = assets.filter(a => a !== btc);
        if (nonbtc.length === 1) {
            let faucet = await db.Account.findOne({
                where: {
                    asset: nonbtc[0],
                    user_id: null
                },
                lock: transaction.LOCK.UPDATE,
                transaction
            });

            if (faucet) {
                covered = faucet.balance;
                if (covered > fee) covered = fee;
                await faucet.decrement({balance: covered}, {transaction});
                await faucet.reload({transaction});
                await faucet.save({transaction});
            }
        }

        total += fee - covered;
    }

    if (limit && total > limit + fee)
        throw new Error("Tx amount exceeds authorized amount");

    if (asset !== btc || total) {
        l.info("creating liquid payment", user.username, asset, total, fee);

        let account = await db.Account.findOne({
            where: {
                user_id: user.id,
                asset,
                pubkey: null
            },
            lock: transaction.LOCK.UPDATE,
            order: [["balance", "DESC"]],
            transaction
        });

        if (total > account.balance) {
            l.warn("amount exceeds balance", {
                total,
                fee,
                balance: account.balance
            });
            throw new Error(
                `Insufficient funds, need ${total} ${
                    account.ticker === "BTC" ? "SAT" : account.ticker
                }, have ${account.balance}`
            );
        }

        await account.decrement({balance: total}, {transaction});
        await account.reload({transaction});

        let payment = {
            amount: -amount,
            account_id: account.id,
            fee,
            memo,
            user_id: user.id,
            rate: app.get("rates")[user.currency],
            currency: user.currency,
            address,
            confirmed: true,
            received: false,
            network: "liquid"
        };

        payment.account = account;
        return payment;
    }

    return null;
};